diff --git a/.gitignore b/.gitignore index e900d66..d0a344f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ composer.lock .DS_Store Thumbs.db .env + +_ide_helper.php +storage/debugbar/ diff --git a/Blog/Category/Category.php b/Blog/Category/Category.php deleted file mode 100644 index a9961e8..0000000 --- a/Blog/Category/Category.php +++ /dev/null @@ -1,42 +0,0 @@ -name = $name; - $this->slug = Str::slug($name); - } - - public function getSlug() - { - return $this->slug; - } - - public function getName() - { - return $this->name; - } - - /** - * Compare if two categories are identical. - * - * @param Category $category - * - * @return bool - */ - public function matches(Category $category) - { - return $category->getSlug() === $this->getSlug(); - } -} diff --git a/Blog/Page/Page.php b/Blog/Page/Page.php deleted file mode 100644 index a632498..0000000 --- a/Blog/Page/Page.php +++ /dev/null @@ -1,149 +0,0 @@ -id; - } - - /** - * Creates a new Page. - * - * @param String $slug URL safe identifier - * @param $title - * @param String $html HTML for the page - * @param Bool $isVisible Whether or not the page is accessible for logged out users. - * - * @return Page - */ - public static function create($slug, $title, $html, $isVisible) - { - $page = new self(); - $page->title = $title; - $page->slug = $slug; - $page->html = $html; - $page->isVisible = (bool)$isVisible; - $page->setCreatedAt(); - return $page; - } - - /** - * Updates the slug and/or html of an existing page. - * - * @param String $slug URL safe identifier - * @param String $title - * @param String $html HTML for the page - */ - public function update($slug, $title, $html) - { - $this->slug = $slug; - $this->title = $title; - $this->html = $html; - } - - /** - * Change the visibility of a page to publicly visible - */ - public function publish() - { - $this->isVisible = true; - } - - /** - * Change the visibility of a page to publicly invisible - */ - public function unpublish() - { - $this->isVisible = false; - } - - /** - * Determine if the current page has been published. - * @return bool - */ - public function isPublished() - { - return (bool)$this->isVisible; - } - - /** - * Set the time the Page was created at - * - * @param \DateTimeInterface|NULL $dt If null current time is used - */ - public function setCreatedAt(\DateTimeInterface $dt = null) - { - $dt = $dt ?: new \DateTime(); - $this->createdAt = $dt; - } - - /** - * Set the time the Page was updated at - * - * @param \DateTimeInterface|NULL $dt If null current time is used - */ - public function setUpdatedAt(\DateTimeInterface $dt = null) - { - $dt = $dt ?: new \DateTime(); - $this->updatedAt = $dt; - } - - /** - * @return String - */ - public function getSlug() - { - return $this->slug; - } - - /** - * @return String - */ - public function getHtml() - { - return $this->html; - } - - /** - * @return string - */ - public function getTitle() - { - return $this->title; - } - - /** - * @return \DateTimeInterface - */ - public function getUpdatedAt() - { - return $this->updatedAt; - } -} diff --git a/Blog/Page/PageRepository.php b/Blog/Page/PageRepository.php deleted file mode 100644 index 2e79bb0..0000000 --- a/Blog/Page/PageRepository.php +++ /dev/null @@ -1,88 +0,0 @@ -repository = $repository; - } - - /** - * @param Page $page Page to save - * @param Bool $flush Automatically flush the changes to the persistent store - * - * @return void - */ - public function save(Page $page, $flush = true) - { - $dm = $this->repository->getDocumentManager(); - $dm->persist($page); - - if ($flush) { - $dm->flush($page); - } - } - - /** - * Deletes a page from the remote datastore. - * - * @param Page $page Page to delete - * @param Bool $flush Automatically flush the changes to the persistent store - */ - public function delete(Page $page, $flush = true) - { - $dm = $this->repository->getDocumentManager(); - $dm->remove($page); - - if ($flush) { - $dm->flush(); - } - } - - /** - * Find a given page by its slug. - * - * @param String $slug Unique URL safe identifier - * @param Bool $onlyVisible Whether to only return publicy visible slugs - * - * @return Page|null - */ - public function findBySlug($slug, $onlyVisible) - { - $queryBuilder = $this->repository->createQueryBuilder() - ->field('slug')->equals($slug); - - if ($onlyVisible) { - $queryBuilder->field('isVisible')->equals(true); - } - - return $queryBuilder->getQuery()->execute()->getSingleResult(); - } - - /** - * A list pages. - * - * @param int $pageSize Number of pages to return - * @param int $skip Number of pages to skip - * - * @return Page[]|Cursor - */ - public function listPages($pageSize, $skip, $orderColumn = 'createdAt') - { - return $this->repository->createQueryBuilder() - ->limit($pageSize) - ->skip($skip) - ->sort($orderColumn, -1) - ->getQuery() - ->execute(); - } -} diff --git a/Blog/Page/Service/CreatePageService.php b/Blog/Page/Service/CreatePageService.php deleted file mode 100644 index 85505e9..0000000 --- a/Blog/Page/Service/CreatePageService.php +++ /dev/null @@ -1,43 +0,0 @@ -pageRepository = $pageRepository; - $this->validator = $validator; - } - - /** - * Creates a new Page and saves it to the database. - * - * @param String $slug URL safe unique identifier for the page - * @param $title - * @param String $html HTML to generate on the page - * @param Bool $isVisible Flag to determine if page can be viewed by logged out users - * - * @return Page - * @throws ValidationException - */ - public function create($slug, $title, $html, $isVisible) - { - $this->validator->validate($slug, $title, $html); - $page = Page::create($slug, $title, $html, $isVisible); - $this->pageRepository->save($page, true); - - return $page; - } -} diff --git a/Blog/Page/Service/PagePublisherService.php b/Blog/Page/Service/PagePublisherService.php deleted file mode 100644 index f813055..0000000 --- a/Blog/Page/Service/PagePublisherService.php +++ /dev/null @@ -1,32 +0,0 @@ -repository = $repository; - } - - public function publish(Page $page) - { - $page->publish(); - $this->repository->save($page, true); - } - - public function unpublish(Page $page) - { - $page->unpublish(); - $this->repository->save($page, true); - } -} diff --git a/Blog/Page/Service/UpdatePageService.php b/Blog/Page/Service/UpdatePageService.php deleted file mode 100644 index 859b7bc..0000000 --- a/Blog/Page/Service/UpdatePageService.php +++ /dev/null @@ -1,45 +0,0 @@ -pageRepository = $pageRepository; - $this->validator = $validator; - } - - /** - * Updates an existing page - * - * @param Page $page The page the data will be attached too. - * @param String $title - * @param String $slug URL safe unique identifier for the page - * @param String $html HTML to generate on the page - * @param Bool $isVisible Flag to determine if page can be viewed by logged out users - * - * @return Page - * @throws ValidationException - */ - public function update(Page $page, $title, $slug, $html, $isVisible) - { - $this->validator->validate($page, $slug, $title, $html); - $page->update($slug, $title, $html); - $isVisible ? $page->publish() : $page->unpublish(); - $this->pageRepository->save($page, true); - - return $page; - } -} diff --git a/Blog/Page/Service/Validator/NewPageValidator.php b/Blog/Page/Service/Validator/NewPageValidator.php deleted file mode 100644 index 043e651..0000000 --- a/Blog/Page/Service/Validator/NewPageValidator.php +++ /dev/null @@ -1,46 +0,0 @@ -factory = $factory; - } - - /** - * Validates the data for a new page - * - * @param string $slug - * @param $title - * @param string $html HTML of the page - * - * @return bool True if data passed validation - * @throws ValidationException - */ - public function validate($slug, $title, $html) - { - $validation = $this->factory->make(compact('slug', 'title', 'html'), [ - 'title' => 'required', - 'slug' => 'required|unique:Page,slug', - 'html' => 'required' - ]); - - if ($validation->fails()) { - throw new ValidationException($validation->errors()); - } - - return true; - } -} diff --git a/Blog/Page/Service/Validator/UpdatePageValidator.php b/Blog/Page/Service/Validator/UpdatePageValidator.php deleted file mode 100644 index 2e4c746..0000000 --- a/Blog/Page/Service/Validator/UpdatePageValidator.php +++ /dev/null @@ -1,47 +0,0 @@ -factory = $factory; - } - - /** - * Validates the data for a new page - * - * @param Page $page - * @param string $slug - * @param $title - * @param string $html HTML of the page - * - * @return bool True if data passed validation - * @throws ValidationException - */ - public function validate(Page $page, $slug, $title, $html) - { - $validation = $this->factory->make(compact('slug', 'html', 'title'), [ - 'title' => 'required', - 'slug' => "required|unique:Pages,slug,{$page->getId()}", - 'html' => 'required' - ]); - - if ($validation->fails()) { - throw new ValidationException($validation->errors()); - } - - return true; - } -} diff --git a/Blog/Post/Post.php b/Blog/Post/Post.php deleted file mode 100644 index 1b83259..0000000 --- a/Blog/Post/Post.php +++ /dev/null @@ -1,175 +0,0 @@ -categories = new ArrayCollection(); - $this->updatedAt = new \DateTime(); - } - - /** - * @return \Baileylo\Blog\Category\Category[]|ArrayCollection - */ - public function getCategories() - { - return $this->categories; - } - - /** - * @return string|null - */ - public function getDescription() - { - return $this->description; - } - - /** - * @return string|null - */ - public function getHtml() - { - return $this->html; - } - - /** - * @return string|null - */ - public function getMarkdown() - { - return $this->markdown; - } - - /** - * @return \DateTimeInterface|null - */ - public function getPublishDate() - { - return $this->publishDate; - } - - /** - * @return string|null - */ - public function getSlug() - { - return $this->slug; - } - - /** - * @return string|null - */ - public function getTitle() - { - return $this->title; - } - - public function setSlug($slug) - { - $this->slug = $slug; - } - - /** - * @param string $title - * @param string $description - * @param string $body - * @param Markdown $converter - */ - public function update($title, $description, $body, Markdown $converter) - { - $this->title = $title; - $this->description = $description; - $this->markdown = $body; - $this->html = $converter->toHtml($body); - } - - public function addCategory(Category $category) - { - if (!$this->categories->contains($category)) { - $this->categories[] = $category; - } - } - - /** - * Changes the state of the post to published. - * @param \DateTimeInterface $date - */ - public function publish(\DateTimeInterface $date) - { - $this->publishDate = $date; - } - - /** - * Makes a post unpublished - */ - public function unpublish() - { - $this->publishDate = null; - } - - /** - * Determine if a post is published. - * - * @return bool - */ - public function isPublished() - { - return !is_null($this->publishDate) && $this->publishDate <= new \DateTime(); - } - - /** - * @return \DateTime - */ - public function getUpdatedAt() - { - return is_null($this->updatedAt) ? $this->publishDate : $this->updatedAt; - } - - /** - * Sets the time that this Post was last updated at. - * - * @param \DateTime $updatedAt Time when the Post was last updated, if null will use current time. - */ - public function setUpdatedAt($updatedAt = null) - { - if (is_null($updatedAt)) { - $updatedAt = new \DateTime; - } - - $this->updatedAt = $updatedAt; - } -} diff --git a/Blog/Post/PostRepository.php b/Blog/Post/PostRepository.php deleted file mode 100644 index ef37178..0000000 --- a/Blog/Post/PostRepository.php +++ /dev/null @@ -1,84 +0,0 @@ -repository = $repository; - } - - /** - * @param Post $post Post to save - * @param Bool $flush Automatically flush the changes to the persistent store - * - * @return void - */ - public function save(Post $post, $flush = true) - { - $dm = $this->repository->getDocumentManager(); - $dm->persist($post); - - if ($flush) { - $dm->flush($post); - } - } - - /** - * Deletes a post from the remote datastore. - * - * @param Post $post Post to delete - * @param Bool $flush Automatically flush the changes to the persistent store - */ - public function delete(Post $post, $flush = true) - { - $dm = $this->repository->getDocumentManager(); - $dm->remove($post); - - if ($flush) { - $dm->flush(); - } - } - - - /** - * @param String $slug URL Slug - * - * @return Post|null - */ - public function findUnpublishedArticle($slug) - { - return $this->repository->createQueryBuilder() - ->field('slug')->equals($slug) - ->field('publishDate')->exists(false) - ->limit(1) - ->getQuery()->execute()->getSingleResult(); - } - - /** - * @param String $slug URL Slug - * - * @return Post|null - */ - public function findBySlug($slug) - { - return $this->repository->createQueryBuilder() - ->field('slug')->equals($slug) - ->limit(1) - ->getQuery()->execute()->getSingleResult(); - } - - /** - * @param String $slug URL slug - * @param \DateTimeInterface $dateTime Date of publication - * - * @return mixed - */ - public function findPublishedArticle($slug, \DateTimeInterface $dateTime) - { - return $this->repository->createQueryBuilder() - ->field('slug')->equals($slug) - ->field('publishDate')->lte(new \DateTime('now')) - ->limit(1) - ->getQuery()->getSingleResult(); - } - - /** - * A list of recently published posts. - * - * @param int $pageSize Number of posts to return - * @param int $skip Number of posts to skip - * - * @return \Baileylo\Blog\Post\Post[]|Cursor - */ - public function findRecentPosts($pageSize, $skip) - { - return $this->repository->createQueryBuilder() - ->field('publishDate')->lte(new \DateTime('now')) - ->limit($pageSize) - ->skip($skip) - ->sort('publishDate', -1) - ->getQuery() - ->execute(); - } - - /** - * A list of recently published posts. - * - * @param string $categorySlug - * @param int $pageSize Number of posts to return - * @param int $skip Number of posts to skip - * - * @return Post[]|Cursor - */ - public function findRecentPostsByCategory($categorySlug, $pageSize, $skip) - { - return $this->repository->createQueryBuilder() - ->field('publishDate')->lte(new \DateTime('now')) - ->field('categories.slug')->equals($categorySlug) - ->limit($pageSize) - ->skip($skip) - ->sort('publishDate', -1) - ->getQuery() - ->execute(); - } - - - /** - * Find all pips irregardless of their publish state - * - * @param int $pageSize - * @param int $skip - * - * @return \Baileylo\Blog\Post\Post[] - */ - public function findUnpublishedPosts($pageSize, $skip) - { - $qb = $this->repository->createQueryBuilder(); - - return $qb->addOr($qb->expr()->field('publishDate')->exists(false)) - ->addOr($qb->expr()->field('publishDate')->gte(new \DateTime('now'))) - ->sort('publishDate', -1) - ->limit($pageSize) - ->skip($skip) - ->getQuery() - ->execute(); - } - - /** - * @param bool $excludeUnpublished - * - * @return \DateTime|Null - */ - public function getLastUpdatedDate($excludeUnpublished = true) - { - $query = $this->repository->createQueryBuilder(); - - if ($excludeUnpublished) { - $query->field('publishDate')->lte(new \DateTime('now')); - } - - $post = $query->getQuery()->getSingleResult(); - if (!$post) { - return null; - } - - return $post->getUpdatedAt(); - } -} diff --git a/Blog/Post/Service/Delete/DeleteService.php b/Blog/Post/Service/Delete/DeleteService.php deleted file mode 100644 index 26aff9e..0000000 --- a/Blog/Post/Service/Delete/DeleteService.php +++ /dev/null @@ -1,21 +0,0 @@ -postRepo = $postRepository; - } - - public function delete(Post $post) - { - $this->postRepo->delete($post); - - return true; - } -} diff --git a/Blog/Post/Service/PostPersistService.php b/Blog/Post/Service/PostPersistService.php deleted file mode 100644 index 469a371..0000000 --- a/Blog/Post/Service/PostPersistService.php +++ /dev/null @@ -1,24 +0,0 @@ -postRepo = $postRepo; - } - - public function handle(Post $post, array $data = []) - { - $this->postRepo->save($post); - - return new ServiceResponse($post); - } -} diff --git a/Blog/Post/Service/PostService.php b/Blog/Post/Service/PostService.php deleted file mode 100644 index 4abe5ab..0000000 --- a/Blog/Post/Service/PostService.php +++ /dev/null @@ -1,17 +0,0 @@ -postRepository = $postRepository; - } - - public function publish(Post $post, \DateTime $publishDate) - { - $post->publish($publishDate); - $this->postRepository->save($post); - } -} diff --git a/Blog/Post/Service/PublishService.php b/Blog/Post/Service/PublishService.php deleted file mode 100644 index afb043f..0000000 --- a/Blog/Post/Service/PublishService.php +++ /dev/null @@ -1,42 +0,0 @@ -innerService = $innerService; - } - - /** - * @param Post $post - * @param array $data Optional - list of new data points - * - * @return ServiceResponse - */ - public function handle(Post $post, array $data = []) - { - if (isset($data['isPublished'])) { - $this->updatePublishStatus($post, $data['isPublished']); - } - - return $this->innerService->handle($post, $data); - } - - public function updatePublishStatus(Post $post, $isPublished) { - if ($isPublished === 'yes') { - $post->publish(new \DateTime('now')); - return; - } - - if ($isPublished === 'no') { - $post->unpublish(); - } - } -} diff --git a/Blog/Post/Service/ServiceResponse.php b/Blog/Post/Service/ServiceResponse.php deleted file mode 100644 index b4b8897..0000000 --- a/Blog/Post/Service/ServiceResponse.php +++ /dev/null @@ -1,37 +0,0 @@ -post = $post; - $this->errors = is_null($failure) ? new MessageBag() : $failure->getErrors(); - } - - public function getPost() - { - return $this->post; - } - - public function hasErrors() - { - return $this->errors->any(); - } - - public function getErrors() - { - return $this->errors; - } -} diff --git a/Blog/Post/Service/ServiceStack.php b/Blog/Post/Service/ServiceStack.php deleted file mode 100644 index f67c4c9..0000000 --- a/Blog/Post/Service/ServiceStack.php +++ /dev/null @@ -1,45 +0,0 @@ -specs = new \SplStack(); - } - - public function push(/*$kernelClass, $args...*/) - { - if (func_num_args() === 0) { - throw new \InvalidArgumentException("Missing argument(s) when calling push"); - } - - $spec = func_get_args(); - $this->specs->push($spec); - - return $this; - } - - public function resolve(PostService $service) - { - $middlewares = array($service); - - foreach ($this->specs as $spec) { - $args = $spec; - $serviceClass = array_shift($args); - - - array_unshift($args, $service); - - $reflection = new \ReflectionClass($serviceClass); - $service = $reflection->newInstanceArgs($args); - - array_unshift($middlewares, $service); - } - - return new StackedService($service, $middlewares); - } -} diff --git a/Blog/Post/Service/SlugService.php b/Blog/Post/Service/SlugService.php deleted file mode 100644 index 7dd6d68..0000000 --- a/Blog/Post/Service/SlugService.php +++ /dev/null @@ -1,31 +0,0 @@ -innerService = $innerService; - } - - /** - * @param Post $post - * @param array $data Optional - list of new data points - * - * @return ServiceResponse - */ - public function handle(Post $post, array $data = []) - { - $post->setSlug(Str::slug($data['title'])); - - return $this->innerService->handle($post, $data); - } -} diff --git a/Blog/Post/Service/StackedService.php b/Blog/Post/Service/StackedService.php deleted file mode 100644 index 0890764..0000000 --- a/Blog/Post/Service/StackedService.php +++ /dev/null @@ -1,20 +0,0 @@ -innerService = $innerService; - } - - public function handle(Post $post, array $data = []) - { - return $this->innerService->handle($post, $data); - } -} diff --git a/Blog/Post/Service/Unpublish/UnpublishService.php b/Blog/Post/Service/Unpublish/UnpublishService.php deleted file mode 100644 index 7eaf046..0000000 --- a/Blog/Post/Service/Unpublish/UnpublishService.php +++ /dev/null @@ -1,23 +0,0 @@ -postRepository = $postRepository; - } - - public function unpublish(Post $post) - { - $post->unpublish(); - $this->postRepository->save($post); - } -} diff --git a/Blog/Post/Service/UpdateService.php b/Blog/Post/Service/UpdateService.php deleted file mode 100644 index 0684805..0000000 --- a/Blog/Post/Service/UpdateService.php +++ /dev/null @@ -1,45 +0,0 @@ -innerService = $innerService; - $this->converter = $converter; - } - - /** - * @param Post $post - * @param array $data Optional - list of new data points - * - * @return ServiceResponse - */ - public function handle(Post $post, array $data = []) - { - $post->update($data['title'], $data['description'], $data['body'], $this->converter); - - $categoryNames = array_unique( - array_map(function ($categoryName) { - return trim($categoryName); - }, explode(',', $data['categories'])) - ); - - $post->getCategories()->clear(); - foreach ($categoryNames as $categoryName) { - $post->addCategory(new Category($categoryName)); - } - - return $this->innerService->handle($post, $data); - } -} diff --git a/Blog/Post/Service/ValidationService.php b/Blog/Post/Service/ValidationService.php deleted file mode 100644 index f41944f..0000000 --- a/Blog/Post/Service/ValidationService.php +++ /dev/null @@ -1,43 +0,0 @@ -innerService = $innerService; - $this->validator = $validator; - } - - /** - * @param Post $post - * @param array $data Optional - list of new data points - * - * @return ServiceResponse - */ - public function handle(Post $post, array $data = []) - { - $validation = $this->validator->validate($data); - - if ($validation->getErrors()->any()) { - return new ServiceResponse($post, $validation); - } - - return $this->innerService->handle($post, $data); - } -} - diff --git a/Blog/ServiceProvider/MarkdownServiceProvider.php b/Blog/ServiceProvider/MarkdownServiceProvider.php deleted file mode 100644 index a9da3d1..0000000 --- a/Blog/ServiceProvider/MarkdownServiceProvider.php +++ /dev/null @@ -1,21 +0,0 @@ -app->singleton(Markdown\Markdown::class, function ($app) { - return $app[Markdown\CommonMarkBridge::class]; - }); - } -} diff --git a/Blog/ServiceProvider/RepositoryServiceProvider.php b/Blog/ServiceProvider/RepositoryServiceProvider.php deleted file mode 100644 index d406300..0000000 --- a/Blog/ServiceProvider/RepositoryServiceProvider.php +++ /dev/null @@ -1,36 +0,0 @@ -app->singleton(UserRepository::class, function ($app) { - return $app[DocumentManager::class]->getRepository(User::class); - }); - - $this->app->singleton(PostRepository::class, function ($app) { - return new DoctrineODM($app[DocumentManager::class]->getRepository(Post::class)); - }); - - $this->app->singleton(PageRepository::class, function ($app) { - return new PageRepository($app[DocumentManager::class]->getRepository(Page::class)); - }); - } -} diff --git a/Blog/ServiceProvider/UserProviderServiceProvider.php b/Blog/ServiceProvider/UserProviderServiceProvider.php deleted file mode 100644 index 46062cb..0000000 --- a/Blog/ServiceProvider/UserProviderServiceProvider.php +++ /dev/null @@ -1,35 +0,0 @@ -app[AuthManager::class]->extend('blog', function ($app) { - return new UserProvider( - $app[UserRepository::class], - $app[Dispatcher::class], - $app[Hasher::class] - ); - }); - } -} diff --git a/Blog/Site/Site.php b/Blog/Site/Site.php deleted file mode 100644 index e13e507..0000000 --- a/Blog/Site/Site.php +++ /dev/null @@ -1,74 +0,0 @@ -lastModified = $lastModified; - $this->lastModifiedPost = $lastModifiedPost; - $this->title = $title; - $this->subHead = $subHead; - $this->gaId = $gaId; - } - - /** - * @return \DateTime - */ - public function getLastModified() - { - return $this->lastModified; - } - - /** - * @return string - */ - public function getTitle() - { - return $this->title; - } - - /** - * @return string - */ - public function getSubHead() - { - return $this->subHead; - } - - public function getFeedLastModified() - { - return max($this->lastModified, $this->lastModifiedPost); - } - - /** - * @return String - */ - public function getGAId() - { - return $this->gaId; - } -} diff --git a/Blog/Storage/Hydrators/BaileyloBlogCategoryCategoryHydrator.php b/Blog/Storage/Hydrators/BaileyloBlogCategoryCategoryHydrator.php deleted file mode 100644 index 7867392..0000000 --- a/Blog/Storage/Hydrators/BaileyloBlogCategoryCategoryHydrator.php +++ /dev/null @@ -1,47 +0,0 @@ -dm = $dm; - $this->unitOfWork = $uow; - $this->class = $class; - } - - public function hydrate($document, $data, array $hints = array()) - { - $hydratedData = array(); - - /** @Field(type="string") */ - if (isset($data['slug'])) { - $value = $data['slug']; - $return = (string) $value; - $this->class->reflFields['slug']->setValue($document, $return); - $hydratedData['slug'] = $return; - } - - /** @Field(type="string") */ - if (isset($data['name'])) { - $value = $data['name']; - $return = (string) $value; - $this->class->reflFields['name']->setValue($document, $return); - $hydratedData['name'] = $return; - } - return $hydratedData; - } -} \ No newline at end of file diff --git a/Blog/Storage/Hydrators/BaileyloBlogPagePageHydrator.php b/Blog/Storage/Hydrators/BaileyloBlogPagePageHydrator.php deleted file mode 100644 index d02ca32..0000000 --- a/Blog/Storage/Hydrators/BaileyloBlogPagePageHydrator.php +++ /dev/null @@ -1,87 +0,0 @@ -dm = $dm; - $this->unitOfWork = $uow; - $this->class = $class; - } - - public function hydrate($document, $data, array $hints = array()) - { - $hydratedData = array(); - - /** @Field(type="id") */ - if (isset($data['_id'])) { - $value = $data['_id']; - $return = $value instanceof \MongoId ? (string) $value : $value; - $this->class->reflFields['id']->setValue($document, $return); - $hydratedData['id'] = $return; - } - - /** @Field(type="boolean") */ - if (isset($data['isVisible'])) { - $value = $data['isVisible']; - $return = (bool) $value; - $this->class->reflFields['isVisible']->setValue($document, $return); - $hydratedData['isVisible'] = $return; - } - - /** @Field(type="date") */ - if (isset($data['createdAt'])) { - $value = $data['createdAt']; - if ($value instanceof \MongoDate) { $return = new \DateTime(); $return->setTimestamp($value->sec); } elseif (is_numeric($value)) { $return = new \DateTime(); $return->setTimestamp($value); } elseif ($value instanceof \DateTime) { $return = $value; } else { $return = new \DateTime($value); } - $this->class->reflFields['createdAt']->setValue($document, clone $return); - $hydratedData['createdAt'] = $return; - } - - /** @Field(type="date") */ - if (isset($data['updatedAt'])) { - $value = $data['updatedAt']; - if ($value instanceof \MongoDate) { $return = new \DateTime(); $return->setTimestamp($value->sec); } elseif (is_numeric($value)) { $return = new \DateTime(); $return->setTimestamp($value); } elseif ($value instanceof \DateTime) { $return = $value; } else { $return = new \DateTime($value); } - $this->class->reflFields['updatedAt']->setValue($document, clone $return); - $hydratedData['updatedAt'] = $return; - } - - /** @Field(type="string") */ - if (isset($data['title'])) { - $value = $data['title']; - $return = (string) $value; - $this->class->reflFields['title']->setValue($document, $return); - $hydratedData['title'] = $return; - } - - /** @Field(type="string") */ - if (isset($data['slug'])) { - $value = $data['slug']; - $return = (string) $value; - $this->class->reflFields['slug']->setValue($document, $return); - $hydratedData['slug'] = $return; - } - - /** @Field(type="string") */ - if (isset($data['html'])) { - $value = $data['html']; - $return = (string) $value; - $this->class->reflFields['html']->setValue($document, $return); - $hydratedData['html'] = $return; - } - return $hydratedData; - } -} \ No newline at end of file diff --git a/Blog/Storage/Hydrators/BaileyloBlogPostPostHydrator.php b/Blog/Storage/Hydrators/BaileyloBlogPostPostHydrator.php deleted file mode 100644 index dd2f673..0000000 --- a/Blog/Storage/Hydrators/BaileyloBlogPostPostHydrator.php +++ /dev/null @@ -1,107 +0,0 @@ -dm = $dm; - $this->unitOfWork = $uow; - $this->class = $class; - } - - public function hydrate($document, $data, array $hints = array()) - { - $hydratedData = array(); - - /** @Field(type="id") */ - if (isset($data['_id'])) { - $value = $data['_id']; - $return = $value instanceof \MongoId ? (string) $value : $value; - $this->class->reflFields['id']->setValue($document, $return); - $hydratedData['id'] = $return; - } - - /** @Field(type="date") */ - if (isset($data['publishDate'])) { - $value = $data['publishDate']; - if ($value instanceof \MongoDate) { $return = new \DateTime(); $return->setTimestamp($value->sec); } elseif (is_numeric($value)) { $return = new \DateTime(); $return->setTimestamp($value); } elseif ($value instanceof \DateTime) { $return = $value; } else { $return = new \DateTime($value); } - $this->class->reflFields['publishDate']->setValue($document, clone $return); - $hydratedData['publishDate'] = $return; - } - - /** @Field(type="date") */ - if (isset($data['updatedAt'])) { - $value = $data['updatedAt']; - if ($value instanceof \MongoDate) { $return = new \DateTime(); $return->setTimestamp($value->sec); } elseif (is_numeric($value)) { $return = new \DateTime(); $return->setTimestamp($value); } elseif ($value instanceof \DateTime) { $return = $value; } else { $return = new \DateTime($value); } - $this->class->reflFields['updatedAt']->setValue($document, clone $return); - $hydratedData['updatedAt'] = $return; - } - - /** @Field(type="string") */ - if (isset($data['slug'])) { - $value = $data['slug']; - $return = (string) $value; - $this->class->reflFields['slug']->setValue($document, $return); - $hydratedData['slug'] = $return; - } - - /** @Field(type="string") */ - if (isset($data['title'])) { - $value = $data['title']; - $return = (string) $value; - $this->class->reflFields['title']->setValue($document, $return); - $hydratedData['title'] = $return; - } - - /** @Field(type="string") */ - if (isset($data['description'])) { - $value = $data['description']; - $return = (string) $value; - $this->class->reflFields['description']->setValue($document, $return); - $hydratedData['description'] = $return; - } - - /** @Field(type="string") */ - if (isset($data['markdown'])) { - $value = $data['markdown']; - $return = (string) $value; - $this->class->reflFields['markdown']->setValue($document, $return); - $hydratedData['markdown'] = $return; - } - - /** @Field(type="string") */ - if (isset($data['html'])) { - $value = $data['html']; - $return = (string) $value; - $this->class->reflFields['html']->setValue($document, $return); - $hydratedData['html'] = $return; - } - - /** @Many */ - $mongoData = isset($data['categories']) ? $data['categories'] : null; - $return = new \Doctrine\ODM\MongoDB\PersistentCollection(new \Doctrine\Common\Collections\ArrayCollection(), $this->dm, $this->unitOfWork); - $return->setHints($hints); - $return->setOwner($document, $this->class->fieldMappings['categories']); - $return->setInitialized(false); - if ($mongoData) { - $return->setMongoData($mongoData); - } - $this->class->reflFields['categories']->setValue($document, $return); - $hydratedData['categories'] = $return; - return $hydratedData; - } -} \ No newline at end of file diff --git a/Blog/Storage/Hydrators/BaileyloBlogUserUserHydrator.php b/Blog/Storage/Hydrators/BaileyloBlogUserUserHydrator.php deleted file mode 100644 index 896d72a..0000000 --- a/Blog/Storage/Hydrators/BaileyloBlogUserUserHydrator.php +++ /dev/null @@ -1,79 +0,0 @@ -dm = $dm; - $this->unitOfWork = $uow; - $this->class = $class; - } - - public function hydrate($document, $data, array $hints = array()) - { - $hydratedData = array(); - - /** @Field(type="id") */ - if (isset($data['_id'])) { - $value = $data['_id']; - $return = $value instanceof \MongoId ? (string) $value : $value; - $this->class->reflFields['id']->setValue($document, $return); - $hydratedData['id'] = $return; - } - - /** @Field(type="string") */ - if (isset($data['name'])) { - $value = $data['name']; - $return = (string) $value; - $this->class->reflFields['name']->setValue($document, $return); - $hydratedData['name'] = $return; - } - - /** @Field(type="string") */ - if (isset($data['slug'])) { - $value = $data['slug']; - $return = (string) $value; - $this->class->reflFields['slug']->setValue($document, $return); - $hydratedData['slug'] = $return; - } - - /** @Field(type="string") */ - if (isset($data['email'])) { - $value = $data['email']; - $return = (string) $value; - $this->class->reflFields['email']->setValue($document, $return); - $hydratedData['email'] = $return; - } - - /** @Field(type="string") */ - if (isset($data['password'])) { - $value = $data['password']; - $return = (string) $value; - $this->class->reflFields['password']->setValue($document, $return); - $hydratedData['password'] = $return; - } - - /** @Field(type="string") */ - if (isset($data['rememberToken'])) { - $value = $data['rememberToken']; - $return = (string) $value; - $this->class->reflFields['rememberToken']->setValue($document, $return); - $hydratedData['rememberToken'] = $return; - } - return $hydratedData; - } -} \ No newline at end of file diff --git a/Blog/User/Events/UpdateRememberToken.php b/Blog/User/Events/UpdateRememberToken.php deleted file mode 100644 index 51efee9..0000000 --- a/Blog/User/Events/UpdateRememberToken.php +++ /dev/null @@ -1,40 +0,0 @@ -user = $user; - $this->token = $token; - } - - /** - * @return string - */ - public function getToken() - { - return $this->token; - } - - /** - * @return UserInterface - */ - public function getUser() - { - return $this->user; - } -} diff --git a/Blog/User/Repository/DoctrineODM.php b/Blog/User/Repository/DoctrineODM.php deleted file mode 100644 index 6587d1a..0000000 --- a/Blog/User/Repository/DoctrineODM.php +++ /dev/null @@ -1,66 +0,0 @@ -find($identifier); - } - - /** - * Retrieve User by their token(generated password) and UUID. - * - * @param String $identifier User's UUID - * @param String $token User's auto-generated token - * - * @return null|User - */ - public function findByToken($identifier, $token) - { - return $this->findOneBy([ - '_id' => $identifier, - 'rememberToken' => $token - ]); - } - - /** - * Retrieve a user by their email address, this is used for lgoin - * - * @param String $email - * - * @return null|User - */ - public function findByEmail($email) - { - return $this->findOneByEmail($email); - } - - /** - * Persists a user to the database - * - * @param User $user - * @param Bool $flush - * - * @return void - */ - public function save(User $user, $flush = true) - { - $dm = $this->getDocumentManager(); - $dm->persist($user); - - if ($flush) { - $dm->flush($user); - } - } -} diff --git a/Blog/User/Service/UserService.php b/Blog/User/Service/UserService.php deleted file mode 100644 index 6e508ba..0000000 --- a/Blog/User/Service/UserService.php +++ /dev/null @@ -1,34 +0,0 @@ -userRepository = $userRepository; - $this->hasher = $hasher; - } - - public function updatePassword(User $user, $newPassword) - { - $user->changePassword($this->hasher, $newPassword); - $this->userRepository->save($user); - } - - public function updateData(User $user, $name, $email) - { - $user->update($name, $email); - $this->userRepository->save($user); - } -} diff --git a/Blog/User/User.php b/Blog/User/User.php deleted file mode 100644 index d00313e..0000000 --- a/Blog/User/User.php +++ /dev/null @@ -1,146 +0,0 @@ -update($name, $email); - $user->password = $passwordHash; - - $user->slug = Str::slug($name); - - return $user; - } - - /** - * Updates the name and/or email for the given user. - * - * @param String $name - * @param String $email - */ - public function update($name, $email) - { - $this->name = $name; - $this->email = $email; - } - - /** - * @return \MongoId|String - */ - public function getId() - { - return $this->id; - } - - /** - * Updates and hashes a user's password - * - * @param Hasher $hasher Object used to hash password - * @param String $password - */ - public function changePassword(Hasher $hasher, $password) - { - $this->password = $hasher->make($password); - } - - /** - * @return string - */ - public function getSlug() - { - return $this->slug; - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * @return String - */ - public function getEmail() - { - return $this->email; - } - - /** - * Get the unique identifier for the user. - * - * @return String|\MongoId - */ - public function getAuthIdentifier() - { - return $this->id; - } - - /** - * Get the token value for the "remember me" session. - * - * @return string - */ - public function getRememberToken() - { - return $this->rememberToken; - } - - /** - * Set the token value for the "remember me" session. - * - * @param string $value - * - * @return void - */ - public function setRememberToken($value) - { - $this->rememberToken = $value; - } - - /** - * Get the column name for the "remember me" token. - * - * @return string - */ - public function getRememberTokenName() - { - throw new \BadMethodCallException(__FUNCTION__ . ' should never be called'); - } -} diff --git a/Blog/User/UserProvider.php b/Blog/User/UserProvider.php deleted file mode 100644 index 4e5eb28..0000000 --- a/Blog/User/UserProvider.php +++ /dev/null @@ -1,101 +0,0 @@ -repository = $userRepo; - $this->dispatcher = $dispatcher; - $this->hasher = $hasher; - } - - /** - * Retrieve a user by their unique identifier. - * - * @param mixed $identifier - * - * @return Authenticatable|null - */ - public function retrieveById($identifier) - { - return $this->repository->findById($identifier); - } - - /** - * Retrieve a user by by their unique identifier and "remember me" token. - * - * @param mixed $identifier - * @param string $token - * - * @return Authenticatable|null - */ - public function retrieveByToken($identifier, $token) - { - return $this->repository->findByToken($identifier, $token); - } - - /** - * Update the "remember me" token for the given user in storage. - * - * @param Authenticatable $user - * @param string $token - * - * @return void - */ - public function updateRememberToken(Authenticatable $user, $token) - { - $this->dispatcher->fire(new UpdateRememberMeToken($user, $token)); - } - - /** - * Retrieve a user by the given credentials. - * - * @param array $credentials - * - * @return Authenticatable|null - */ - public function retrieveByCredentials(array $credentials) - { - if (!isset($credentials['login'])) { - return null; - } - - return $this->repository->findByEmail($credentials['login']); - } - - /** - * Validate a user against the given credentials. - * - * @param Authenticatable $user - * @param array $credentials - * - * @return bool - */ - public function validateCredentials(Authenticatable $user, array $credentials) - { - $plain = $credentials['password']; - - return $this->hasher->check($plain, $user->getAuthPassword()); - } -} diff --git a/Blog/User/UserRepository.php b/Blog/User/UserRepository.php deleted file mode 100644 index 6d22a30..0000000 --- a/Blog/User/UserRepository.php +++ /dev/null @@ -1,43 +0,0 @@ -errors = $errors; - } - - /** - * @return MessageBag - */ - public function getErrors() - { - return $this->errors; - } -} - diff --git a/Blog/Validation/ValidationResponse.php b/Blog/Validation/ValidationResponse.php deleted file mode 100644 index 22a3de0..0000000 --- a/Blog/Validation/ValidationResponse.php +++ /dev/null @@ -1,13 +0,0 @@ -open($options); - - $buttonAttr = ['type' => 'submit']; - if(isset($options['title'])) { - $buttonAttr['title'] = $options['title']; - } - - $body = $this->button($text, $buttonAttr); - $close = $this->close(); - - return "{$open}{$body}{$close}"; - } -} diff --git a/Core/Laravel/Html/HtmlServiceProvider.php b/Core/Laravel/Html/HtmlServiceProvider.php deleted file mode 100644 index 478579b..0000000 --- a/Core/Laravel/Html/HtmlServiceProvider.php +++ /dev/null @@ -1,17 +0,0 @@ -app->bindShared('form', function($app) - { - - $form = new FormBuilder($app['html'], $app['url'], $app['session.store']->getToken()); - - return $form->setSessionStore($app['session.store']); - }); - } -} diff --git a/Core/Laravel/Renderable.php b/Core/Laravel/Renderable.php deleted file mode 100644 index a0d295f..0000000 --- a/Core/Laravel/Renderable.php +++ /dev/null @@ -1,15 +0,0 @@ -db = $db; - } - - /** - * Count the number of objects in a collection having the given value. - * - * @param string $collection - * @param string $column - * @param string $value - * @param int $excludeId - * @param string $idColumn - * @param array $extra - * - * @return int - */ - public function getCount($collection, $column, $value, $excludeId = null, $idColumn = null, array $extra = array()) - { - $query = [$column => $value]; - - if ($excludeId) { - $idColumn = is_null($idColumn) ? '_id' : $idColumn; - $excludeId = $this->isIdColumn($idColumn) ? $this->toMongoId($excludeId) : $excludeId; - $query[$idColumn] = ['$ne' => $excludeId]; - } - - return $this->count($collection, $this->addExtras($query, $extra)); - } - - /** - * Count the number of objects in a collection with the given values. - * - * @param string $collection - * @param string $column - * @param array $values - * @param array $extra - * - * @return int - */ - public function getMultiCount($collection, $column, array $values, array $extra = array()) - { - if ($this->isIdColumn($column)) { - $values = $this->toMongoIds($values); - } - - return $this->count($collection, $this->addExtras([$column => $values], $extra)); - } - - private function count($collection, $query) - { - return $this->db->selectCollection($collection)->count($query); - } - - private function addExtras(array $query, array $extras) - { - foreach($extras as $column => $value) { - if ($this->isIdColumn($column)) { - $value = $this->toMongoId($value); - } - - $query[$column] = $value; - } - - return $query; - } - - private function isIdColumn($column) - { - return $column === '_id'; - } - - private function toMongoIds(array $values) - { - return array_map(function ($id) { - return $this->toMongoId($id); - }, $values); - } - - private function toMongoId($value) - { - if ($value instanceof \MongoId) { - return $value; - } - - return new \MongoId($value); - } -} diff --git a/Core/Laravel/Validation/Mongo/MongoValidationServiceProvider.php b/Core/Laravel/Validation/Mongo/MongoValidationServiceProvider.php deleted file mode 100644 index cb09ab4..0000000 --- a/Core/Laravel/Validation/Mongo/MongoValidationServiceProvider.php +++ /dev/null @@ -1,17 +0,0 @@ -app->bindShared('validation.presence', function($app) - { - return new MongoPresenceVerifier($app['mongodb.database']); - }); - } - -} diff --git a/Core/Laravel/Validation/MongoValidation.php b/Core/Laravel/Validation/MongoValidation.php deleted file mode 100644 index 6e813b7..0000000 --- a/Core/Laravel/Validation/MongoValidation.php +++ /dev/null @@ -1,8 +0,0 @@ -errors = $errors; - } - - /** - * @return MessageBag - */ - public function getErrors() - { - return $this->errors; - } -} diff --git a/Core/Markdown/CommonMarkBridge.php b/Core/Markdown/CommonMarkBridge.php deleted file mode 100644 index 495d958..0000000 --- a/Core/Markdown/CommonMarkBridge.php +++ /dev/null @@ -1,31 +0,0 @@ -converter = $converter; - } - - /** - * Converts a string of markdown into HTML. - * - * @param String $markdown - * - * @return string - */ - public function toHtml($markdown) - { - return $this->converter->convertToHtml($markdown); - } -} diff --git a/Core/Markdown/Markdown.php b/Core/Markdown/Markdown.php deleted file mode 100644 index 400f13e..0000000 --- a/Core/Markdown/Markdown.php +++ /dev/null @@ -1,16 +0,0 @@ -app->singleton('doctrine.odm.configuration', function ($app) { - $configs = $app['config']['doctrine']; - - $configuration = new Configuration(); - $configuration->setProxyDir($configs['proxy']['dir']); - $configuration->setProxyNamespace($configs['proxy']['namespace']); - $configuration->setHydratorDir($configs['hydrator']['dir']); - $configuration->setHydratorNamespace($configs['hydrator']['namespace']); - $configuration->setMetadataDriverImpl(new YamlDriver( - $configs['metadata']['dir'], - $configs['metadata']['extension'] - )); - - $configuration->setDefaultDB($app['config']['database.mongodb.collection']); - - return $configuration; - }); - - $this->app->singleton('doctrine.odm.connection', function ($app) { - return new Connection( - $app['mongodb.connection'], - [], - $app['doctrine.odm.configuration'] - ); - }); - - $this->app->singleton('mongodb.connection', function ($app) { - $config = $app['config']['database.mongodb']; - $options = array_filter($config['options']); - - $server = rtrim("{$config['host']}/{$config['collection']}", '/'); - - return new \MongoClient($server, $options); - }); - - $this->app->singleton('mongodb.database', function ($app) { - return $app['mongodb.connection']->{$app['config']['database.mongodb.collection']}; - }); - - $this->app->singleton(DocumentManager::class, function ($app) { - return DocumentManager::create( - $app['doctrine.odm.connection'], - $app['doctrine.odm.configuration'] - ); - }); - } -} diff --git a/Core/Mongo/YamlDriver.php b/Core/Mongo/YamlDriver.php deleted file mode 100644 index bcaa983..0000000 --- a/Core/Mongo/YamlDriver.php +++ /dev/null @@ -1,19 +0,0 @@ -freshTimestamp(); + + if (! $this->isDirty(static::UPDATED_AT)) { + $this->setUpdatedAt($time); + } + } + + /** + * @return bool + */ + public function getIsPublishedAttribute() + { + return $this->published_at && $this->published_at <= new \DateTime(); + } + + public function user() + { + return $this->belongsTo(User::class); + } + + public static function getResolver() + { + return self::$resolver; + } + /** + * Find a post by its slug + * + * @param string $slug The post's slug + * @param array $relationships A list of relationships to eager load. + * + * @return bool|Post|Page + */ + public static function findBySlug($slug, array $relationships = ['user']) + { + if (get_called_class() === __CLASS__) { + return Post::findBySlug($slug, $relationships) ?: Page::findBySlug($slug, $relationships); + } + + /** @var static $article */ + $article = self::whereSlug($slug)->first(); + if (!$article) { + return false; + } + + if ($relationships) { + $article->load($relationships); + } + + return $article; + } +} diff --git a/app/Article/Page.php b/app/Article/Page.php new file mode 100644 index 0000000..31775b8 --- /dev/null +++ b/app/Article/Page.php @@ -0,0 +1,55 @@ + 'page']; + + /** + * The attributes that are mass assignable. + * + * @var array + */ + protected $fillable = ['title', 'slug', 'markdown', 'html', 'template']; + + /** + * The "booting" method of the model. + * + * @return void + */ + public static function boot() + { + parent::boot(); + + static::addGlobalScope(new PageScope); + } + + /** + * Pages are published by default. + * + * @return bool + */ + public function getIsPublishedAttribute() + { + return true; + } +} diff --git a/app/Article/PageScope.php b/app/Article/PageScope.php new file mode 100644 index 0000000..84b5b4e --- /dev/null +++ b/app/Article/PageScope.php @@ -0,0 +1,24 @@ +where('type', 'page'); + } +} diff --git a/app/Article/Post.php b/app/Article/Post.php new file mode 100644 index 0000000..93247a0 --- /dev/null +++ b/app/Article/Post.php @@ -0,0 +1,64 @@ + 'post']; + + /** + * The "booting" method of the model. + * + * @return void + */ + public static function boot() + { + parent::boot(); + + static::addGlobalScope(new PostScope); + } + + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany + */ + public function categories() + { + return $this->belongsToMany(Category::class); + } + + public function scopePublished($query) + { + return $query->where('published_at', '<=', new \DateTime()) + ->orderBy('published_at', 'desc'); + } + + public function scopeUnpublished($query) + { + return $query->where('published_at', '>', new \DateTime()) + ->orWhere('published_at', null) + ->orderBy('published_at', 'desc'); + } +} diff --git a/app/Article/PostScope.php b/app/Article/PostScope.php new file mode 100644 index 0000000..250938c --- /dev/null +++ b/app/Article/PostScope.php @@ -0,0 +1,24 @@ +where('type', 'post'); + } +} diff --git a/app/Category.php b/app/Category.php new file mode 100644 index 0000000..c7da735 --- /dev/null +++ b/app/Category.php @@ -0,0 +1,44 @@ +belongsToMany(Post::class); + } +} diff --git a/app/Commands/Command.php b/app/Commands/Command.php deleted file mode 100644 index 018bc21..0000000 --- a/app/Commands/Command.php +++ /dev/null @@ -1,7 +0,0 @@ -comment(PHP_EOL.Inspiring::quote().PHP_EOL); - } + /** + * The console command description. + * + * @var string + */ + protected $description = 'Display an inspiring quote'; + /** + * Execute the console command. + * + * @return mixed + */ + public function handle() + { + $this->comment(PHP_EOL.Inspiring::quote().PHP_EOL); + } } diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 0c088c8..71c519d 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -1,29 +1,30 @@ -command('inspire') - ->hourly(); - } +class Kernel extends ConsoleKernel +{ + /** + * The Artisan commands provided by your application. + * + * @var array + */ + protected $commands = [ + // Commands\Inspire::class, + ]; + /** + * Define the application's command schedule. + * + * @param \Illuminate\Console\Scheduling\Schedule $schedule + * @return void + */ + protected function schedule(Schedule $schedule) + { + // $schedule->command('inspire') + // ->hourly(); + } } diff --git a/app/Events/Event.php b/app/Events/Event.php index d59f769..ba2f888 100644 --- a/app/Events/Event.php +++ b/app/Events/Event.php @@ -1,7 +1,8 @@ -user = $user; - $this->newToken = $newToken; - } - - /** - * @return Authenticatable - */ - public function getUser() - { - return $this->user; - } - - /** - * @return string - */ - public function getNewToken() - { - return $this->newToken; - } - -} diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 342c258..53617ef 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -1,18 +1,26 @@ -isHttpException($e)) { - return $this->renderHttpException($e); - } - - return response(view('errors.default'), [], 500); + return parent::render($request, $e); } - } diff --git a/app/Handlers/Commands/.gitkeep b/app/Handlers/Commands/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/app/Handlers/Events/.gitkeep b/app/Handlers/Events/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/app/Http/Controllers/Admin/ImportHandler.php b/app/Http/Controllers/Admin/ImportHandler.php deleted file mode 100644 index bae597c..0000000 --- a/app/Http/Controllers/Admin/ImportHandler.php +++ /dev/null @@ -1,65 +0,0 @@ -request = $request; - $this->redirector = $redirector; - } - - public function import() - { - $xmlDump = $this->request->file('xml'); - - $xml = simplexml_load_file($xmlDump->getPathname(), 'SimpleXMLElement', LIBXML_NOCDATA); - - $dm = app(DocumentManager::class); - - foreach ($xml->xpath('/rss/channel/item') as $result) { - if (trim(($result->xpath('wp:status')[0])) !== 'publish') { - continue; - } - - $post = new Post(); - - $post->update( - trim($result->title), - trim($result->description), - (string)(new \HTML_To_Markdown(trim(htmlentities($result->xpath('content:encoded')[0])))), - app(Markdown::class) - ); - - $post->setSlug(trim(($result->xpath('wp:post_name')[0]))); - - foreach((array)$result->category as $index => $category) { - if (!is_numeric($index)) continue; - - $post->addCategory(new Category($category)); - } - - $post->setUpdatedAt(new \DateTime((string)$result->pubDate)); - $post->publish($post->getUpdatedAt()); - $dm->persist($post); - } - - $dm->flush(); - return $this->redirector->route('admin'); - } -} diff --git a/app/Http/Controllers/Admin/ImportView.php b/app/Http/Controllers/Admin/ImportView.php deleted file mode 100644 index 5b63658..0000000 --- a/app/Http/Controllers/Admin/ImportView.php +++ /dev/null @@ -1,16 +0,0 @@ -viewFactory()->make('admin.import'); - } -} diff --git a/app/Http/Controllers/Admin/ListUnpublishedPosts.php b/app/Http/Controllers/Admin/ListUnpublishedPosts.php deleted file mode 100644 index c2ce518..0000000 --- a/app/Http/Controllers/Admin/ListUnpublishedPosts.php +++ /dev/null @@ -1,49 +0,0 @@ -postRepo = $postRepo; - $this->urlGenerator = $urlGenerator; - } - - public function view($page = 1) - { - $posts = $this->postRepo->findUnpublishedPosts(self::PAGE_SIZE, $page);; - - $pagination = new LengthAwareRoutePaginator( - $posts->toArray(), - $posts->count(), - self::PAGE_SIZE, - 'admin.unpublished', - $this->urlGenerator, - $page - ); - - return $this->viewFactory()->make('admin.list-unpublished', compact('posts', 'pagination')); - } -} diff --git a/app/Http/Controllers/Admin/ListView.php b/app/Http/Controllers/Admin/ListView.php deleted file mode 100644 index cbf2556..0000000 --- a/app/Http/Controllers/Admin/ListView.php +++ /dev/null @@ -1,46 +0,0 @@ -postRepo = $postRepo; - $this->urlGenerator = $urlGenerator; - } - - public function view($page = 1) - { - $publishedPosts = $this->postRepo->findRecentPosts(self::PUBLISHED_PAGE_SIZE, ($page - 1) * self::PUBLISHED_PAGE_SIZE); - $unpublishedPosts = $this->postRepo->findUnpublishedPosts(5, 0); - - $pagination = new LengthAwareRoutePaginator($publishedPosts->toArray(), $publishedPosts->count(), self::PUBLISHED_PAGE_SIZE, 'admin', $this->urlGenerator, $page); - - - return $this->viewFactory()->make('admin.list', compact('publishedPosts', 'unpublishedPosts', 'pagination')); - } -} diff --git a/app/Http/Controllers/ArticleController.php b/app/Http/Controllers/ArticleController.php new file mode 100644 index 0000000..3572d54 --- /dev/null +++ b/app/Http/Controllers/ArticleController.php @@ -0,0 +1,95 @@ +responseFactory->view($this->templates['create'], [ + 'templates' => $templateProvider->getTemplates() + ]); + } + + /** + * @param Article $article The article it populate + * @param CommonMarkConverter $converter Library used to convert markdown to HTML + * @param array $data Request that contains the data + * + * @return Article + */ + protected function updateArticle(Article $article, CommonMarkConverter $converter, array $data) + { + $article->fill([ + 'slug' => $data['slug'], + 'title' => $data['title'], + 'template' => $data['template'], + ]); + + if (isset($data['description'])) { + $article->description = $data['description']; + } + + $body = $data['body']; + $article->is_html = !isset($data['is_markdown']); + if ($article->is_html) { + $article->html = $body; + $article->markdown = ''; + } else { + $article->markdown = $body; + $article->html = $converter->convertToHtml($body); + } + + return $article; + } + + /** + * Remove the specified resource from storage. + * + * @param string $post + * @return \Illuminate\Http\Response + */ + public function destroy($post) + { + $this->findBySlug($post)->delete(); + + return $this->responseFactory->redirectToRoute($this->redirects['destroy']); + } + + /** + * Find article by slug. + * + * @param string $slug + * @param array $relationships + * + * @return Article + * @throws NotFoundHttpException + */ + protected function findBySlug($slug, array $relationships = []) + { + $article = Article::findBySlug($slug, $relationships); + if (!$article) { + throw new NotFoundHttpException(); + } + + return $article; + } +} diff --git a/app/Http/Controllers/Auth/AuthController.php b/app/Http/Controllers/Auth/AuthController.php index 4ad5c58..725d97e 100644 --- a/app/Http/Controllers/Auth/AuthController.php +++ b/app/Http/Controllers/Auth/AuthController.php @@ -1,38 +1,83 @@ -auth = $auth; - $this->registrar = $registrar; - - $this->middleware('guest', ['except' => 'getLogout']); - } +class AuthController extends Controller +{ + protected $loginView = 'auth.login'; + + /* + |-------------------------------------------------------------------------- + | Registration & Login Controller + |-------------------------------------------------------------------------- + | + | This controller handles the registration of new users, as well as the + | authentication of existing users. By default, this controller uses + | a simple trait to add these behaviors. Why don't you explore it? + | + */ + + use AuthenticatesAndRegistersUsers, ThrottlesLogins; + + /** + * Where to redirect users after login / registration. + * + * @var string + */ + protected $redirectTo = '/'; + + protected $redirectAfterLogout = ''; + + /** + * Create a new authentication controller instance. + * + * @return void + */ + public function __construct(ResponseFactory $responseFactory, UrlGenerator $urlGenerator) + { + parent::__construct($responseFactory); + + $this->redirectAfterLogout = $urlGenerator->route('home'); + + $this->middleware($this->guestMiddleware(), ['except' => 'logout']); + } + + /** + * Get a validator for an incoming registration request. + * + * @param array $data + * @return \Illuminate\Contracts\Validation\Validator + */ + protected function validator(array $data) + { + return Validator::make($data, [ + 'name' => 'required|max:255', + 'email' => 'required|email|max:255|unique:users', + 'password' => 'required|min:6|confirmed', + ]); + } + /** + * Create a new user instance after a valid registration. + * + * @param array $data + * @return User + */ + protected function create(array $data) + { + return User::create([ + 'name' => $data['name'], + 'email' => $data['email'], + 'password' => bcrypt($data['password']), + ]); + } } diff --git a/app/Http/Controllers/Auth/AuthValidator.php b/app/Http/Controllers/Auth/AuthValidator.php deleted file mode 100644 index cc726aa..0000000 --- a/app/Http/Controllers/Auth/AuthValidator.php +++ /dev/null @@ -1,41 +0,0 @@ -factory = $factory; - $this->auth = $auth; - } - - public function validate($data) - { - $validators = $this->factory->make($data, [ - 'login' => 'required', - 'password' => 'required' - ]); - - if ($validators->fails()) { - return new ValidationResponse($validators->messages()); - } - - if (!$this->auth->attempt($data)) { - return new ValidationResponse(new MessageBag(['login' => 'Invalid login password combination'])); - } - - return true; - } -} diff --git a/app/Http/Controllers/Auth/LoginHandler.php b/app/Http/Controllers/Auth/LoginHandler.php deleted file mode 100644 index 8bd10e5..0000000 --- a/app/Http/Controllers/Auth/LoginHandler.php +++ /dev/null @@ -1,42 +0,0 @@ -validator = $validator; - $this->redirector = $redirector; - $this->request = $request; - } - - public function handle() - { - $data = $this->request->only('login', 'password'); - - $isValid = $this->validator->validate($data); - if ($isValid instanceof ValidationResponse) { - return $this->redirector->back()->withErrors($isValid->getErrors())->withInput($data); - } - - return $this->redirector->intended('admin'); - } -} diff --git a/app/Http/Controllers/Auth/LoginView.php b/app/Http/Controllers/Auth/LoginView.php deleted file mode 100644 index 782f756..0000000 --- a/app/Http/Controllers/Auth/LoginView.php +++ /dev/null @@ -1,16 +0,0 @@ -viewFactory()->make('auth.login'); - } -} diff --git a/app/Http/Controllers/Auth/LogoutHandler.php b/app/Http/Controllers/Auth/LogoutHandler.php deleted file mode 100644 index bfeba89..0000000 --- a/app/Http/Controllers/Auth/LogoutHandler.php +++ /dev/null @@ -1,27 +0,0 @@ -auth = $auth; - $this->redirector = $redirector; - } - - public function logout() - { - $this->auth->logout(); - return $this->redirector->route('home'); - } -} diff --git a/app/Http/Controllers/Auth/PasswordController.php b/app/Http/Controllers/Auth/PasswordController.php index 3106193..1ceed97 100644 --- a/app/Http/Controllers/Auth/PasswordController.php +++ b/app/Http/Controllers/Auth/PasswordController.php @@ -1,38 +1,32 @@ -auth = $auth; - $this->passwords = $passwords; +class PasswordController extends Controller +{ + /* + |-------------------------------------------------------------------------- + | Password Reset Controller + |-------------------------------------------------------------------------- + | + | This controller is responsible for handling password reset requests + | and uses a simple trait to include this behavior. You're free to + | explore this trait and override any methods you wish to tweak. + | + */ - $this->middleware('guest'); - } + use ResetsPasswords; + /** + * Create a new password controller instance. + * + * @return void + */ + public function __construct() + { + $this->middleware('guest'); + } } diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 27b3f45..1c1a7e3 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -1,11 +1,22 @@ -responseFactory = $responseFactory; + } } diff --git a/app/Http/Controllers/Feed/Atom.php b/app/Http/Controllers/Feed/Atom.php deleted file mode 100644 index 10416a0..0000000 --- a/app/Http/Controllers/Feed/Atom.php +++ /dev/null @@ -1,36 +0,0 @@ -postRepository = $postRepo; - $this->site = $site; - } - - public function feed() - { - $posts = $this->postRepository->findRecentPosts(20, 0)->toArray(false); - $site = $this->site; - - $content = $this->viewFactory()->make('feeds.atom', compact('posts', 'site')); - - return new AtomResponse($content); - } -} diff --git a/app/Http/Controllers/Home/View.php b/app/Http/Controllers/Home/View.php deleted file mode 100644 index 06f1e6f..0000000 --- a/app/Http/Controllers/Home/View.php +++ /dev/null @@ -1,38 +0,0 @@ -postRepository = $postRepository; - $this->urlGenerator = $urlGenerator; - } - - public function view($page = 1) - { - /** @var \Doctrine\ODM\MongoDB\Cursor $posts */ - $posts = $this->postRepository->findRecentPosts(self::PAGE_SIZE, ($page - 1) * self::PAGE_SIZE); - $pagination = new RoutePaginator($posts, self::PAGE_SIZE, 'home', $this->urlGenerator, $page); - - return $this->viewFactory()->make('home.list', compact('posts', 'pagination')); - } -} diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php deleted file mode 100644 index c7ca983..0000000 --- a/app/Http/Controllers/HomeController.php +++ /dev/null @@ -1,36 +0,0 @@ -middleware('auth'); - } - - /** - * Show the application dashboard to the user. - * - * @return Response - */ - public function index() - { - return view('home'); - } - -} diff --git a/app/Http/Controllers/Page/Create/Handler.php b/app/Http/Controllers/Page/Create/Handler.php deleted file mode 100644 index 6f5a34b..0000000 --- a/app/Http/Controllers/Page/Create/Handler.php +++ /dev/null @@ -1,42 +0,0 @@ -request = $request; - $this->service = $service; - $this->redirector = $redirector; - } - - public function handleForm() - { - extract($this->request->only('slug', 'page', 'title', 'isPublished')); - - try { - $page = $this->service->create($slug, $title, $page, $isPublished); - } catch (ValidationException $e) { - return $this->redirector->back()->withInput()->withErrors($e->getErrors()); - } - - return $this->redirector->route('page.permalink', [$page->getSlug()]); - } -} diff --git a/app/Http/Controllers/Page/Create/View.php b/app/Http/Controllers/Page/Create/View.php deleted file mode 100644 index 384e6d2..0000000 --- a/app/Http/Controllers/Page/Create/View.php +++ /dev/null @@ -1,16 +0,0 @@ -viewFactory()->make('page.create.create'); - } -} diff --git a/app/Http/Controllers/Page/View/ListView.php b/app/Http/Controllers/Page/View/ListView.php deleted file mode 100644 index 80ffdcd..0000000 --- a/app/Http/Controllers/Page/View/ListView.php +++ /dev/null @@ -1,44 +0,0 @@ -pageRepository = $pageRepository; - $this->urlGenerator = $urlGenerator; - } - - public function view($page = 1) - { - $offset = ($page - 1) * self::PAGE_SIZE; - $pages = $this->pageRepository->listPages(self::PAGE_SIZE, $offset); - $pagination = new LengthAwareRoutePaginator( - $pages->toArray(), - $pages->count(), - self::PAGE_SIZE, - 'admin.pages', - $this->urlGenerator, - $page - ); - - return $this->viewFactory()->make('page.list.list', compact('pages', 'pagination')); - } -} diff --git a/app/Http/Controllers/PageController.php b/app/Http/Controllers/PageController.php new file mode 100644 index 0000000..57164e5 --- /dev/null +++ b/app/Http/Controllers/PageController.php @@ -0,0 +1,108 @@ + 'pages.create' + ]; + + protected $redirects = [ + 'destroy' => 'page.index' + ]; + + /** + * Display a listing of the resource. + * + * @return \Illuminate\Http\Response + */ + public function index() + { + return $this->responseFactory->view('pages.index', [ + 'pages' => Page::paginate() + ]); + } + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param CommonMarkConverter $converter + * + * @return \Illuminate\Http\Response + */ + public function store(Request $request, CommonMarkConverter $converter) + { + $this->validate($request, [ + 'title' => 'required|string|between:3,255', + 'slug' => 'required|between:2,255,alpha_dash|unique:posts,slug', + 'template' => 'required|string|template', + 'description' => 'string|min:50', + 'body' => 'string|min:50', + 'markdown' => 'string' + ]); + + $pageData = $request->only('title', 'slug', 'template', 'body', 'is_markdown'); + $page = $this->updateArticle(new Page, $converter, $pageData); + + $page->save(); + + return $this->responseFactory->redirectToRoute('page.edit', $page->slug) + ->with('save.status', 'created'); + } + + /** + * Show the form for editing the specified resource. + * + * @param TemplateProvider $templateProvider + * @param string $slug + * + * @return \Illuminate\Http\Response + */ + public function edit(TemplateProvider $templateProvider, $slug) + { + return $this->responseFactory->view('pages.edit', [ + 'page' => $this->findBySlug($slug), + 'status' => session('save.status', false), + 'templates' => $templateProvider->getTemplates() + ]); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param CommonMarkConverter $converter + * @param string $slug + * + * @return \Illuminate\Http\Response + */ + public function update(Request $request, CommonMarkConverter $converter, $slug) + { + $page = $this->findBySlug($slug); + + $this->validate($request, [ + 'title' => 'required|string|between:3,255', + 'slug' => "required|between:2,255,alpha_dash|unique:posts,slug,{$page->id}", + 'template' => 'required|string|template', + 'description' => 'string|min:50', + 'body' => 'string|min:50', + 'markdown' => 'string' + ]); + + $data = $request->only('slug', 'title', 'template', 'is_markdown', 'body', 'description'); + $page = $this->updateArticle($page, $converter, $data); + + $page->save(); + + return $this->responseFactory->redirectToRoute('page.edit', $page->slug) + ->with('save.status', 'updated'); + } +} diff --git a/app/Http/Controllers/Post/Create/CreatePostHandler.php b/app/Http/Controllers/Post/Create/CreatePostHandler.php deleted file mode 100644 index 98eca6a..0000000 --- a/app/Http/Controllers/Post/Create/CreatePostHandler.php +++ /dev/null @@ -1,43 +0,0 @@ -request = $request; - $this->redirector = $redirector; - $this->creationService = $creationService; - } - - public function handle() - { - $post = new Post(); - $data = $this->request->only('title', 'description', 'categories', 'body', 'isPublished'); - - $response = $this->creationService->handle($post, $data); - - if ($response->hasErrors()) { - return $this->redirector->back()->withInput()->withErrors($response->getErrors()); - } - - return $this->redirector->route('post.permalink', [$response->getPost()->getSlug()]); - } -} diff --git a/app/Http/Controllers/Post/Create/Validator.php b/app/Http/Controllers/Post/Create/Validator.php deleted file mode 100644 index 2b41477..0000000 --- a/app/Http/Controllers/Post/Create/Validator.php +++ /dev/null @@ -1,34 +0,0 @@ -factory = $factory; - } - - public function validate($data) - { - $validators = $this->factory->make($data, [ - 'title' => 'required|min:5', - 'categories' => 'required', - 'description' => 'required', - 'body' => 'required', - 'isPublished' => 'required' - ]); - - if ($validators->fails()) { - return new ValidationResponse($validators->messages()); - } - - return true; - } -} diff --git a/app/Http/Controllers/Post/Create/View.php b/app/Http/Controllers/Post/Create/View.php deleted file mode 100644 index 4e05921..0000000 --- a/app/Http/Controllers/Post/Create/View.php +++ /dev/null @@ -1,16 +0,0 @@ -viewFactory()->make('post.create'); - } -} diff --git a/app/Http/Controllers/Post/Listings/CategoryView.php b/app/Http/Controllers/Post/Listings/CategoryView.php deleted file mode 100644 index 398bc0c..0000000 --- a/app/Http/Controllers/Post/Listings/CategoryView.php +++ /dev/null @@ -1,78 +0,0 @@ -postRepository = $postRepository; - $this->urlGenerator = $urlGenerator; - } - public function category(Category $category, $page = 1) - { - $posts = $this->postRepository->findRecentPostsByCategory( - $category->getSlug(), - self::PAGE_SIZE, - ( $page - 1) * self::PAGE_SIZE - ); - - $category = $this->resolveCategory($category, $posts->getNext()); - $posts->reset(); - - $pagination = new LengthAwareRoutePaginator( - $posts->toArray(), - $posts->count(), - self::PAGE_SIZE, - 'category', - $this->urlGenerator, - $page, - [$category->getSlug()] - ); - - return $this->viewFactory()->make('home.list', compact('posts', 'pagination', 'category')); - } - - /** - * Determine the correct name of the Category. - * Since the $category is populated only by slug, the name may be incorrect. Loop through the categories on the first - * post until we find a matching category, then return that category. - * - * @param Category $category - * @param Post $post - * - * @return Category - */ - private function resolveCategory(Category $category, Post $post = null) - { - if (is_null($post)) { - return $category; - } - - foreach($post->getCategories() as $postCategory) { - if ($postCategory->matches($category)) { - return $postCategory; - } - } - - return $category; - } -} diff --git a/app/Http/Controllers/PostController.php b/app/Http/Controllers/PostController.php new file mode 100644 index 0000000..fe15f7a --- /dev/null +++ b/app/Http/Controllers/PostController.php @@ -0,0 +1,214 @@ + 'post.create' + ]; + + protected $redirects = [ + 'destroy' => 'admin' + ]; + + /** + * Display a listing of the resource. + * + * @return \Illuminate\Http\Response + */ + public function index() + { + return $this->responseFactory->view('post.list', [ + 'posts' => Post::published()->simplePaginate(25) + ]); + } + + /** + * Shows posts separated out by their publish date + */ + public function overview() + { + return $this->responseFactory->view('post.overview', [ + 'published' => Post::published()->paginate(25), + 'pending' => Post::unpublished()->limit(25)->get(), + ]); + } + + public function category($slug) + { + /** @var Category $category */ + $category = Category::find($slug); + if (!$category) { + throw new NotFoundHttpException; + } + + return $this->responseFactory->view('post.list', [ + 'category' => $category, + 'posts' => $category->posts()->published()->simplePaginate() + ]); + } + + public function feed() + { + $posts = Post::published(10)->get(); + $last_updated = $posts->reduce(function ($carry, Post $post) { + $date = $post->updated_at ?: $post->published_at; + if (!$carry || $date > $carry) { + return $date; + } + + return $carry; + }, null); + + return $this->responseFactory->view('post.feed', ['posts' => $posts, 'last_updated' => $last_updated], 200, [ + 'Content-Type' => 'application/atom+xml; charset=UTF-8' + ]); + } + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param CommonMarkConverter $converter + * + * @return \Illuminate\Http\Response + */ + public function store(Request $request, CommonMarkConverter $converter) + { + $this->validate($request, $this->getValidationRules(new Post, $request)); + + /** @var \App\User $user */ + $user = $request->user(); + + // Add the timestamp to the slug if the slug is already in use. + $slug = str_slug($request->input('title')); + if (Post::findBySlug($slug, [])) { + $slug .= '-' . time(); + } + + $postData = $request->only('title', 'description', 'template', 'body', 'is_markdown'); + + /** @var Post $post */ + $post = $this->updateArticle(new Post, $converter, $postData + ['slug' => $slug]); + + if ($request->input('isPublished') === 'yes') { + $post->published_at = new \DateTime('-5 seconds'); + } + + $user->posts()->save($post); + + $post->categories()->attach( + $this->getCategories($request->input('categories')) + ); + + return $this->responseFactory->redirectToRoute('resource', $post->slug); + } + + private function getCategories($categories) + { + $category_data = Collection::make(explode(',', $categories)) + ->filter() + ->map(function ($category) { + $category = trim($category); + return ['slug' => str_slug($category), 'name' => $category]; + }); + + /** @var Collection $persisted_categories */ + $persisted_categories = Category::whereIn('slug', $category_data->pluck('slug'))->get()->keyBy('slug'); + + foreach ($category_data as $data) { + if (!isset($persisted_categories[$data['slug']])) { + $persisted_categories->push(Category::create($data)); + } + } + + return $persisted_categories; + } + + /** + * Show the form for editing the specified resource. + * + * @param TemplateProvider $template + * @param string $post + * + * @return \Illuminate\Http\Response + */ + public function edit(TemplateProvider $template, $post) + { + return $this->responseFactory->view('post.edit', [ + 'post' => $this->findBySlug($post, ['categories']), + 'status' => session('save.status', false), + 'templates' => $template->getTemplates() + ]); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param CommonMarkConverter $converter + * @param string $post + * + * @return \Illuminate\Http\Response + */ + public function update(Request $request, CommonMarkConverter $converter, $post) + { + /** @var Post $post */ + $post = $this->findBySlug($post); + + $this->validate($request, $this->getValidationRules($post, $request)); + + $data = $request->only('title', 'template', 'is_markdown', 'body', 'description'); + $data['slug'] = $post->slug; + + $post = $this->updateArticle($post, $converter, $data); + + if (!$post->is_published && $request->input('isPublished') === 'yes') { + $post->published_at = new \DateTime('-5 seconds'); + } + + $post->save(); + + $post->categories()->sync( + $this->getCategories($request->input('categories'))->pluck('slug')->toArray() + ); + $save_status = $post->wasRecentlyCreated && !$post->is_published ? 'created' : 'updated'; + return $this->responseFactory + ->redirectToRoute('post.edit', $post->slug) + ->with('save.status', $save_status); + } + + private function getValidationRules(Post $post, Request $request) + { + if ($post->is_published || $request->input('isPublished') === 'yes') { + return [ + 'title' => 'required|string|between:3,255', + 'categories' => 'string', + 'template' => 'required|string|template', + 'description' => 'required|string|min:50', + 'body' => 'required|string|min:50', + 'markdown' => 'string' + ]; + } + + return [ + 'title' => 'required|string|between:3,255', + 'categories' => 'string', + 'template' => 'required|string|template', + 'description' => 'string|min:50', + 'body' => 'string|min:50', + 'markdown' => 'string' + ]; + } +} diff --git a/app/Http/Controllers/Resource/Delete.php b/app/Http/Controllers/Resource/Delete.php deleted file mode 100644 index 493d5b6..0000000 --- a/app/Http/Controllers/Resource/Delete.php +++ /dev/null @@ -1,44 +0,0 @@ -redirector = $redirector; - $this->pageRepo = $pageRepo; - $this->postRepo = $postRepo; - } - - public function delete($resource) - { - return $resource instanceof Page ? $this->deletePage($resource) : $this->deletePost($resource); - } - - private function deletePost(Post $post) - { - $this->postRepo->delete($post); - return $this->redirector->back()->with('action', 'Post deleted'); - } - - private function deletePage(Page $page) - { - $this->pageRepo->delete($page); - return $this->redirector->back()->with('action', 'Page deleted'); - } -} diff --git a/app/Http/Controllers/Resource/Edit.php b/app/Http/Controllers/Resource/Edit.php deleted file mode 100644 index 95ff007..0000000 --- a/app/Http/Controllers/Resource/Edit.php +++ /dev/null @@ -1,42 +0,0 @@ -session = $session; - } - - public function view($resource) - { - return $resource instanceof Page ? $this->renderEditPage($resource) : $this->renderEditPost($resource); - } - - public function renderEditPage(Page $page) - { - return $this->viewFactory() - ->make('page.edit.edit', compact('page')); - } - - public function renderEditPost(Post $post) - { - $postUpdated = $this->session->has('postUpdated'); - $postPublished = $this->session->has('postPublished'); - - return $this->viewFactory() - ->make('post.edit.edit', compact('post', 'postUpdated', 'postPublished')); - } -} diff --git a/app/Http/Controllers/Resource/EditHandler.php b/app/Http/Controllers/Resource/EditHandler.php deleted file mode 100644 index 53085ff..0000000 --- a/app/Http/Controllers/Resource/EditHandler.php +++ /dev/null @@ -1,69 +0,0 @@ -redirector = $redirector; - $this->request = $request; - $this->postService = $postService; - $this->pageService = $pageService; - } - - public function handle($resource) - { - $handler = $resource instanceof Page ? 'editPage' : 'editPost'; - return $this->$handler($resource); - } - - private function editPost(Post $post) - { - $response = $this->postService->handle($post, $this->request->all()); - - if ($response->hasErrors()) { - return $this->redirector->back()->withInput()->withErrors($response->getErrors()); - } - - return $this->redirector->back()->with('postUpdated', true); - } - - private function editPage(Page $page) - { - $title = $this->request->get('title'); - $slug = $this->request->get('slug'); - $html = trim($this->request->get('html')); - - try { - $this->pageService->update($page, $title, $slug, $html, $page->isPublished()); - } catch (ValidationException $e) { - return $this->redirector->back()->withInput()->withErrors($e->getErrors()); - } - - return $this->redirector->back()->with('action', 'Page updated'); - } -} diff --git a/app/Http/Controllers/Resource/Publish.php b/app/Http/Controllers/Resource/Publish.php deleted file mode 100644 index e880ff6..0000000 --- a/app/Http/Controllers/Resource/Publish.php +++ /dev/null @@ -1,52 +0,0 @@ -redirector = $redirector; - $this->postPublisher = $postPublisher; - $this->pagePublisher = $pagePublisher; - } - - public function publish($resource) - { - $handler = $resource instanceof Page ? 'publishPage' : 'publishPost'; - return $this->$handler($resource); - } - - private function publishPost(Post $post) - { - $this->postPublisher->publish($post, new \DateTime('-5 seconds')); - return $this->redirector->back()->with('postPublished', true); - } - - private function publishPage(Page $page) - { - $this->pagePublisher->publish($page); - return $this->redirector->back()->with('action', 'Page updated'); - } -} diff --git a/app/Http/Controllers/Resource/Unpublish.php b/app/Http/Controllers/Resource/Unpublish.php deleted file mode 100644 index 7e5677d..0000000 --- a/app/Http/Controllers/Resource/Unpublish.php +++ /dev/null @@ -1,49 +0,0 @@ -redirector = $redirector; - $this->postPublisher = $postPublisher; - $this->pagePublisher = $pagePublisher; - } - - public function unpublish($resource) - { - $handler = $resource instanceof Page ? 'unpublishPage' : 'unpublishPost'; - return $this->$handler($resource); - } - - private function unpublishPost(Post $post) - { - $this->postPublisher->back($post, new \DateTime('-5 seconds')); - return $this->redirector->back()->with('postPublished', true); - } - - private function unpublishPage(Page $page) - { - $this->pagePublisher->unpublish($page); - return $this->redirector->back()->with('action', 'Page updated'); - } -} diff --git a/app/Http/Controllers/Resource/View.php b/app/Http/Controllers/Resource/View.php deleted file mode 100644 index 563f19d..0000000 --- a/app/Http/Controllers/Resource/View.php +++ /dev/null @@ -1,28 +0,0 @@ -renderPage($resource) : $this->renderPost($resource); - } - - protected function renderPage(Page $page) - { - return $this->viewFactory()->make('page.view.view', compact('page')); - } - - protected function renderPost(Post $post) - { - return $this->viewFactory()->make('post.permalink', compact('post')); - } -} diff --git a/app/Http/Controllers/ResourceController.php b/app/Http/Controllers/ResourceController.php new file mode 100644 index 0000000..7c586fd --- /dev/null +++ b/app/Http/Controllers/ResourceController.php @@ -0,0 +1,28 @@ +is_published && !\Auth::check()) { + throw new NotFoundHttpException; + } + + return $this->responseFactory->view("post.templates.{$article->template}", [ + 'article' => $article + ]); + } +} diff --git a/app/Http/Controllers/User/Settings/PasswordHandler.php b/app/Http/Controllers/User/Settings/PasswordHandler.php deleted file mode 100644 index f7ec981..0000000 --- a/app/Http/Controllers/User/Settings/PasswordHandler.php +++ /dev/null @@ -1,61 +0,0 @@ -auth = $auth; - $this->request = $request; - $this->redirector = $redirector; - $this->userService = $userService; - $this->session = $session; - } - - public function handleForm() - { - $data = $this->request->only('password', 'confirm'); - - /** @var \Illuminate\Validation\Validator $validator */ - $validator = Validator::make($data, [ - 'password' => 'required|min:8', - 'confirm' => 'required|same:password' - ]); - - if ($validator->fails()) { - $this->redirector->back()->withErrors($validator->errors(), 'password')->withInput(); - } - - $this->userService->updatePassword(\Auth::user(), $data['password']); - - $this->session->flash('passwordUpdated', true); - $this->session->regenerate(true); - - return $this->redirector->back(); - } -} diff --git a/app/Http/Controllers/User/Settings/SettingsHandler.php b/app/Http/Controllers/User/Settings/SettingsHandler.php deleted file mode 100644 index 5796f01..0000000 --- a/app/Http/Controllers/User/Settings/SettingsHandler.php +++ /dev/null @@ -1,65 +0,0 @@ -request = $request; - $this->redirector = $redirector; - $this->userService = $userService; - $this->session = $session; - } - - public function handleForm() - { - $data = $this->request->only('name', 'email'); - - /** @var \Illuminate\Validation\Validator $validator */ - $validator = Validator::make($data, [ - 'name' => 'required|min:2', - 'email' => 'required|email|unique:User:email:' . $this->request->user()->getId() - ]); - - if ($validator->fails()) { - return $this->redirector->back()->withErrors($validator->errors(), 'settings')->withInput(); - } - - $this->userService->updateData($this->request->user(), $data['name'], $data['email']); - - $this->session->flash('settingsUpdated', true); - - return $this->redirector->back(); - } -} diff --git a/app/Http/Controllers/User/Settings/SettingsView.php b/app/Http/Controllers/User/Settings/SettingsView.php deleted file mode 100644 index c3ed24e..0000000 --- a/app/Http/Controllers/User/Settings/SettingsView.php +++ /dev/null @@ -1,36 +0,0 @@ -auth = $auth; - $this->session = $session; - } - - public function view() - { - $data = [ - 'user' => $this->auth->user(), - 'passwordUpdated' => $this->session->pull('passwordUpdated'), - 'settingsUpdated' => $this->session->pull('settingsUpdated') - ]; - - return $this->viewFactory()->make('user.settings', $data); - } -} diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php new file mode 100644 index 0000000..ad98712 --- /dev/null +++ b/app/Http/Controllers/UserController.php @@ -0,0 +1,38 @@ +responseFactory->view('users.settings', ['user' => $user]); + } + + public function update(Request $request) + { + $this->validate($request, [ + 'name' => 'required|between:2,255', + 'email' => "required|email|unique:users,email,{$request->user()->id}", + 'password' => 'min:8' + ]); + + /** @var \App\User $user */ + $user = $request->user(); + $user->fill($request->only('name', 'email')); + + if ($request->has('password')) { + $user->password = bcrypt($request->input('password')); + } + + $user->save(); + + Auth::guard()->login($user); + + return $this->responseFactory->redirectToRoute('settings'); + } +} diff --git a/app/Http/Controllers/WelcomeController.php b/app/Http/Controllers/WelcomeController.php index 8a5ac6d..06a6273 100644 --- a/app/Http/Controllers/WelcomeController.php +++ b/app/Http/Controllers/WelcomeController.php @@ -1,36 +1,13 @@ -middleware('guest'); - } - - /** - * Show the application welcome screen to the user. - * - * @return Response - */ - public function index() - { - return view('welcome'); - } +use Illuminate\Routing\ResponseFactory; +class WelcomeController extends Controller +{ + public function welcome(ResponseFactory $responseFactory) + { + return $responseFactory->view('welcome'); + } } diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 0a2addc..f0d8083 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -1,32 +1,52 @@ - [ + \App\Http\Middleware\EncryptCookies::class, + \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, + \Illuminate\Session\Middleware\StartSession::class, + \Illuminate\View\Middleware\ShareErrorsFromSession::class, + \App\Http\Middleware\VerifyCsrfToken::class, + ], - /** - * The application's route middleware. - * - * @var array - */ - protected $routeMiddleware = [ - 'auth' => 'App\Http\Middleware\Authenticate', - 'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth', - 'guest' => 'App\Http\Middleware\RedirectIfAuthenticated', - ]; + 'api' => [ + 'throttle:60,1', + ], + ]; + /** + * The application's route middleware. + * + * These middleware may be assigned to groups or used individually. + * + * @var array + */ + protected $routeMiddleware = [ + 'auth' => \App\Http\Middleware\Authenticate::class, + 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, + 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, + 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, + ]; } diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php index 6f47eb9..67abcae 100644 --- a/app/Http/Middleware/Authenticate.php +++ b/app/Http/Middleware/Authenticate.php @@ -1,53 +1,30 @@ -auth = $auth; - $this->redirector = $redirector; - } - /** * Handle an incoming request. * - * @param \Illuminate\Http\Request $request - * @param \Closure $next - * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @param string|null $guard * @return mixed */ - public function handle($request, Closure $next) + public function handle($request, Closure $next, $guard = null) { - if (!$this->auth->guest()) { - return $next($request); - } - - if ($request->ajax()) { - return new Response('Unauthorized.', 401); + if (Auth::guard($guard)->guest()) { + if ($request->ajax() || $request->wantsJson()) { + return response('Unauthorized.', 401); + } else { + return redirect()->guest('login'); + } } - return $this->redirector->guest('login'); + return $next($request); } - } diff --git a/app/Http/Middleware/EncryptCookies.php b/app/Http/Middleware/EncryptCookies.php new file mode 100644 index 0000000..3aa15f8 --- /dev/null +++ b/app/Http/Middleware/EncryptCookies.php @@ -0,0 +1,17 @@ +auth = $auth; - } - - /** - * Handle an incoming request. - * - * @param \Illuminate\Http\Request $request - * @param \Closure $next - * @return mixed - */ - public function handle($request, Closure $next) - { - if ($this->auth->check()) - { - return new RedirectResponse(url('/home')); - } +use Closure; +use Illuminate\Support\Facades\Auth; - return $next($request); - } +class RedirectIfAuthenticated +{ + /** + * Handle an incoming request. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @param string|null $guard + * @return mixed + */ + public function handle($request, Closure $next, $guard = null) + { + if (Auth::guard($guard)->check()) { + return redirect('/'); + } + return $next($request); + } } diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index 750a39b..a2c3541 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -1,20 +1,17 @@ - 'application/atom+xml; charset=UTF-8'] - ); - } -} diff --git a/app/Http/routes.php b/app/Http/routes.php index 312f53f..0f0c1db 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -1,82 +1,36 @@ 'Home\View@view', 'as' => 'home']); -Route::get('page/{page}', ['uses' => 'Home\View@view', 'as' => 'home.paginated']); - -// Paginated Filtered Category Page -Route::get('category/{category}', ['uses' => 'Post\Listings\CategoryView@category', 'as' => 'category']); -Route::get('category/{category}/{page}', ['uses' => 'Post\Listings\CategoryView@category', 'as' => 'category.paginated']); - -// Login Page -Route::get('login', ['uses' => 'Auth\LoginView@view', 'before' => 'forceSSL']); -Route::post('login', ['uses' => 'Auth\LoginHandler@handle', 'before' => 'forceSSL']); - -// Logout page -Route::get('logout', ['uses' => 'Auth\LogoutHandler@logout', 'as' => 'logout']); - -Route::get('feed', [ - 'uses' => 'Feed\Atom@feed', - 'before' => 'beforeAtomCache', - 'after' => 'afterAtomCache', - 'as' => 'feed.atom' -]); - -Route::group(['middleware' => 'auth'], function () { - - Route::get('/import', ['uses' => 'Admin\ImportView@view', 'as' => 'import']); - Route::post('/import', ['uses' => 'Admin\ImportHandler@import']); - - // Settings Routes - Route::get('/settings', ['uses' => 'User\Settings\SettingsView@view', 'as' => 'settings', 'before' => 'forceSSL']); - - // Generic Admin Page - Route::get('/admin/', ['uses' => 'Admin\ListView@view', 'as' => 'admin']); - Route::get('/admin/{page}', ['uses' => 'Admin\ListView@view', 'as' => 'admin.paginated']); - - Route::get('/admin/pages/', ['uses' => 'Page\View\ListView@view', 'as' => 'admin.pages']); - Route::get('/admin/pages/{page}', ['uses' => 'Page\View\ListView@view', 'as' => 'admin.pages.paginated']); - - Route::get('/admin/posts/unpublished', ['uses' => 'Admin\ListUnpublishedPosts@view', 'as' => 'admin.unpublished']); - Route::get('/admin/posts/unpublished/{page}', ['uses' => 'Admin\ListUnpublishedPosts@view', 'as' => 'admin.unpublished.paginated']); - - Route::get('/write', ['uses' => 'Post\Create\View@view', 'as' => 'admin.post.create']); - Route::get('/write/page', ['uses' => 'Page\Create\View@view', 'as' => 'admin.page.create']); - - // Edit - Route::get('{slug}/edit', ['uses' => 'Resource\Edit@view', 'as' => 'page.edit']); - Route::get('{slug}/edit', ['uses' => 'Resource\Edit@view', 'as' => 'post.edit']); - - // Delete Page Or Post - Route::delete('{slug}', ['uses' => 'Resource\Delete@delete', 'as' => 'page.delete']); - Route::delete('{slug}', ['uses' => 'Resource\Delete@delete', 'as' => 'post.delete']); - - // Handle Edits to Page - Route::put('{slug}/edit', ['uses' => 'Resource\EditHandler@handle']); - Route::post('{slug}/edit', ['uses' => 'Resource\EditHandler@handle']); - - // Create Page/Slug - Route::post('/write', ['uses' => 'Post\Create\CreatePostHandler@handle']); - Route::post('/write/page', ['uses' => 'Page\Create\Handler@handleForm', 'as' => 'admin.page.create']); - - // Publish / Unpublish Page - Route::put('{slug}/publish', ['uses' => 'Resource\Publish@publish', 'as' => 'post.publish']); - Route::put('{slug}/publish', ['uses' => 'Resource\Publish@publish', 'as' => 'page.publish']); - - Route::patch('{slug}/unpublish', ['uses' => 'Resource\Unpublish@unpublish', 'as' => 'post.unpublish']); - Route::patch('{slug}/unpublish', ['uses' => 'Resource\Unpublish@unpublish', 'as' => 'page.unpublish']); - - Route::put('/settings', ['uses' => 'User\Settings\SettingsHandler@handleForm', 'before' => 'forceSSL']); - Route::put('/update-password', ['uses' => 'User\Settings\PasswordHandler@handleForm', 'as' => 'passwordHandler']); +/* +|-------------------------------------------------------------------------- +| Routes File +|-------------------------------------------------------------------------- +| +| Here is where you will register all of the routes in an application. +| It's a breeze. Simply tell Laravel the URIs it should respond to +| and give it the controller to call when that URI is requested. +| +*/ + +use Illuminate\Routing\Router; + +Route::group(['middleware' => ['web']], function (Router $router) { + $router->get('', ['as' => 'home', 'uses' => 'PostController@index']); + + $router->get('category/{category}', ['as' => 'category', 'uses' => 'PostController@category']); + + $router->get('login', ['as' => 'login', 'uses' => 'Auth\\AuthController@getLogin']); + $router->post('login', 'Auth\\AuthController@login'); + $router->get('logout', ['as' => 'logout', 'uses' => 'Auth\\AuthController@logout']); + + $router->group(['middleware' => ['auth']], function (Router $router) { + $router->get('admin', ['as' => 'admin', 'uses' => 'PostController@overview']); + $router->get('settings', ['as' => 'settings', 'uses' => 'UserController@edit']); + $router->put('settings', ['uses' => 'UserController@update']); + $router->resource('post', 'PostController', ['except' => ['show']]); + $router->resource('page', 'PageController', ['except' => ['show']]); + }); + + $router->get('feed', ['as' => 'feed', 'uses' => 'PostController@feed']); + + $router->get('{slug}', ['as' => 'resource', 'uses' => 'ResourceController@find']); }); - -Route::get('{date}/{slug}', ['before' => 'postUrlRedirect']); - -// View -Route::get('{slug}', ['uses' => 'Resource\View@view', 'as' => 'page.permalink', 'before' => 'unpublishedResource|beforeResourceCache', 'after' => 'afterResourceCache']); -Route::get('{slug}', ['uses' => 'Resource\View@view', 'as' => 'post.permalink', 'before' => 'unpublishedResource|beforeResourceCache', 'after' => 'afterResourceCache']); - - diff --git a/app/Jobs/Job.php b/app/Jobs/Job.php new file mode 100644 index 0000000..55ece29 --- /dev/null +++ b/app/Jobs/Job.php @@ -0,0 +1,21 @@ +items = $items instanceof Collection ? $items : Collection::make($items); - $this->lastPage = (int) ceil($total / $perPage); - $this->perPage = $perPage; - $this->total = $total; - $this->currentPage = $this->setCurrentPage($currentPage, $total); - $this->routeName = $routeName; - $this->urlGenerator = $urlGenerator; - $this->routeParameters = $routeParameters; - } - - protected function getRouteName($page) - { - if ($page > 1) { - return $this->routeName . '.paginated'; - } - - return $this->routeName; - } - - /** - * Get a URL for a given page number. - * - * @param int $page - * - * @return string - */ - public function url($page) - { - if (!$page) { - $page = 1; - } - - $routeParameters = $this->routeParameters; - - if ($page > 1) { // if $page == 1 don't add it to url - $routeParameters = $page; - } - - return $this->urlGenerator->route($this->getRouteName($page), $routeParameters); - } - - /** - * Render the paginator using the given presenter. - * - * @param \Illuminate\Contracts\Pagination\Presenter|null $presenter - * - * @return string - */ - public function render(Presenter $presenter = null) - { - $presenter = $presenter ?: new FullPresenter($this); - - return $presenter->render(); - } -} diff --git a/app/Pagination/Presenter/SimplePresenter.php b/app/Pagination/Presenter/SimplePresenter.php deleted file mode 100644 index a15625e..0000000 --- a/app/Pagination/Presenter/SimplePresenter.php +++ /dev/null @@ -1,136 +0,0 @@ -hasPages()) - { - $html = << -
- %s -
-
- %s -
- -
-
- %s -
-
- %s -
-
-HTML; - return sprintf( - $html, - $this->getPreviousButton('Newer', 'Newer'), - $this->getNextButton('Older', 'Older'), - $this->getPreviousButton('Newer', 'Newer', 'expand'), - $this->getNextButton('Older', 'Older', 'expand') - ); - } - - return ''; - } - - /** - * Get HTML wrapper for disabled text. - * - * @param string $text - * @return string - */ - protected function getDisabledTextWrapper($text) - { - return ''; - } - - /** - * Get HTML wrapper for an available page link. - * - * @param string $url - * @param int $page - * @param string|null $rel - * @param string $class List of classes to attach to the link - * - * @return string - */ - protected function getAvailablePageWrapper($url, $page, $rel = null, $class = '') - { - $rel = is_null($rel) ? '' : ' rel="'.$rel.'"'; - - return ''.$page.''; - } - - /** - * Get the previous page pagination element. - * - * @param string $text - * @param String $rel The relative text for the link - * @param string $class list of classes to attach to the link - * @return string - */ - protected function getPreviousButton($text = '«', $rel = 'prev', $class = '') - { - // If the current page is less than or equal to one, it means we can't go any - // further back in the pages, so we will render a disabled previous button - // when that is the case. Otherwise, we will give it an active "status". - if ($this->paginator->currentPage() <= 1) - { - return $this->getDisabledTextWrapper($text, $class); - } - - $url = $this->paginator->url( - $this->paginator->currentPage() - 1 - ); - - return $this->getPageLinkWrapper($url, $text, 'prev', $class); - } - - /** - * Get the next page pagination element. - * - * @param string $text - * @param string $class list of classes to attach to the link - * @return string - */ - protected function getNextButton($text = '»', $class = '') - { - // If the current page is greater than or equal to the last page, it means we - // can't go any further into the pages, as we're already on this last page - // that is available, so we will make it the "next" link style disabled. - if ( ! $this->paginator->hasMorePages()) - { - return $this->getDisabledTextWrapper($text, $class); - } - - $url = $this->paginator->url($this->paginator->currentPage() + 1); - - return $this->getPageLinkWrapper($url, $text, 'next', $class); - } - - /** - * Get HTML wrapper for a page link. - * - * @param string $url - * @param int $page - * @param string|null $rel - * @param string $class list of classes to attach to the link - * @return string - */ - protected function getPageLinkWrapper($url, $page, $rel = null, $class = '') - { - return $this->getAvailablePageWrapper($url, $page, $rel, $class); - } -} diff --git a/app/Pagination/RoutePaginator.php b/app/Pagination/RoutePaginator.php deleted file mode 100644 index ab82ca0..0000000 --- a/app/Pagination/RoutePaginator.php +++ /dev/null @@ -1,95 +0,0 @@ -items = $items instanceof Collection ? $items : Collection::make($items); - $this->perPage = $perPage; - $this->currentPage = $this->setCurrentPage($currentPage); - $this->routeName = $routeName; - $this->urlGenerator = $urlGenerator; - $this->routeParameters = $routeParameters; - - $this->checkForMorePages(); - } - - protected function getRouteName($page) - { - if ($page > 1) { - return $this->routeName . '.paginated'; - } - - return $this->routeName; - } - - /** - * Get a URL for a given page number. - * - * @param int $page - * - * @return string - */ - public function url($page) - { - if (!$page) { - $page = 1; - } - - $routeParameters = $this->routeParameters; - - if ($page > 1) { // if $page == 1 don't add it to url - $routeParameters = $page; - } - - return $this->urlGenerator->route($this->getRouteName($page), $routeParameters); - } - - /** - * Render the paginator using the given presenter. - * - * @param \Illuminate\Contracts\Pagination\Presenter|null $presenter - * - * @return string - */ - public function render(Presenter $presenter = null) - { - $presenter = $presenter ?: new FullPresenter($this); - - return $presenter->render(); - } -} diff --git a/app/Policies/.gitkeep b/app/Policies/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/app/Policies/.gitkeep @@ -0,0 +1 @@ + diff --git a/app/Post/CreatePostService.php b/app/Post/CreatePostService.php deleted file mode 100644 index a9888fd..0000000 --- a/app/Post/CreatePostService.php +++ /dev/null @@ -1,17 +0,0 @@ -innerService = $innerService; - } - - public function handle(Post $post, array $data = []) - { - return $this->innerService->handle($post, $data); - } - -} diff --git a/app/Post/UpdatePostService.php b/app/Post/UpdatePostService.php deleted file mode 100644 index 78e9e68..0000000 --- a/app/Post/UpdatePostService.php +++ /dev/null @@ -1,17 +0,0 @@ -factory = $factory; - } - - public function validate($data) - { - $validators = $this->factory->make($data, [ - 'title' => 'required|min:5', - 'categories' => 'required', - 'description' => 'required', - 'body' => 'required' - ]); - - return new ValidationResponse($validators->messages()); - } -} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index ff9d6f6..44d2788 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -1,34 +1,49 @@ -extend('template', Validators\Template::class . '@validate'); + } - /** - * Register any application services. - * - * This service provider is a great spot to register your various container - * bindings with the application. As you can see, we are registering our - * "Registrar" implementation here. You can add your own bindings too! - * - * @return void - */ - public function register() - { - $this->app->bind( - 'Illuminate\Contracts\Auth\Registrar', - 'App\Services\Registrar' - ); - } + /** + * Register any application services. + * + * @return void + */ + public function register() + { + if ($this->app->environment('local')) { + $this->app->register(IdeHelperServiceProvider::class); + $this->app->register(\Barryvdh\Debugbar\ServiceProvider::class); + } + $this->app->bind(TemplateProvider::class, function () { + return $this->app->build(TemplateProvider::class, [ + 'templateDirectory' => resource_path('views/post/templates') + ]); + }); + } } diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php new file mode 100644 index 0000000..57d88ea --- /dev/null +++ b/app/Providers/AuthServiceProvider.php @@ -0,0 +1,31 @@ + 'App\Policies\ModelPolicy', + ]; + + /** + * Register any application authentication / authorization services. + * + * @param \Illuminate\Contracts\Auth\Access\Gate $gate + * @return void + */ + public function boot(GateContract $gate) + { + $this->registerPolicies($gate); + + // + } +} diff --git a/app/Providers/BusServiceProvider.php b/app/Providers/BusServiceProvider.php deleted file mode 100644 index f0d9be6..0000000 --- a/app/Providers/BusServiceProvider.php +++ /dev/null @@ -1,34 +0,0 @@ -mapUsing(function($command) - { - return Dispatcher::simpleMapping( - $command, 'App\Commands', 'App\Handlers\Commands' - ); - }); - } - - /** - * Register any application services. - * - * @return void - */ - public function register() - { - // - } - -} diff --git a/app/Providers/ConfigServiceProvider.php b/app/Providers/ConfigServiceProvider.php deleted file mode 100644 index 06e5799..0000000 --- a/app/Providers/ConfigServiceProvider.php +++ /dev/null @@ -1,23 +0,0 @@ - [ - 'EventListener', - ], - ]; - - /** - * Register any other events for your application. - * - * @param \Illuminate\Contracts\Events\Dispatcher $events - * @return void - */ - public function boot(DispatcherContract $events) - { - parent::boot($events); +class EventServiceProvider extends ServiceProvider +{ + /** + * The event listener mappings for the application. + * + * @var array + */ + protected $listen = [ + 'App\Events\SomeEvent' => [ + 'App\Listeners\EventListener', + ], + ]; - // - } + /** + * Register any other events for your application. + * + * @param \Illuminate\Contracts\Events\Dispatcher $events + * @return void + */ + public function boot(DispatcherContract $events) + { + parent::boot($events); + // + } } diff --git a/app/Providers/PostServicesServiceProvider.php b/app/Providers/PostServicesServiceProvider.php deleted file mode 100644 index 0b1d3b4..0000000 --- a/app/Providers/PostServicesServiceProvider.php +++ /dev/null @@ -1,55 +0,0 @@ -app->bind(UpdatePostService::class, function ($app) { - $stack = new ServiceStack(); - $stack->push(ValidationService::class, $app[GenericValidator::class]); - $stack->push(UpdateService::class, $app[Markdown::class]); - $stack->push(PublishService::class); - return new StackedService( - $stack->resolve(new PostPersistService($app[PostRepository::class])) - ); - }); - - $this->app->bind(CreatePostService::class, function ($app) { - $stack = new ServiceStack(); - $stack->push(ValidationService::class, $app[GenericValidator::class]); - $stack->push(UpdateService::class, $app[Markdown::class]); - $stack->push(SlugService::class); - $stack->push(PublishService::class); - return new StackedService( - $stack->resolve(new PostPersistService($app[PostRepository::class])) - ); - }); - } - - public function provides() - { - return [UpdatePostService::class, CreatePostService::class]; - } -} diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index afa34c8..d50b1c0 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -1,44 +1,44 @@ -group(['namespace' => $this->namespace], function($router) - { - require app_path('Http/routes.php'); - }); - } + parent::boot($router); + } + /** + * Define the routes for the application. + * + * @param \Illuminate\Routing\Router $router + * @return void + */ + public function map(Router $router) + { + $router->group(['namespace' => $this->namespace], function ($router) { + require app_path('Http/routes.php'); + }); + } } diff --git a/app/Providers/SiteServiceProvider.php b/app/Providers/SiteServiceProvider.php deleted file mode 100644 index 791c97e..0000000 --- a/app/Providers/SiteServiceProvider.php +++ /dev/null @@ -1,31 +0,0 @@ -app->bind(Site::class, function ($app) { - $updatedDate = $app[PostRepository::class]->getLastUpdatedDate(); - - return new Site( - $app['config']['site.lastModified'], - is_null($updatedDate) ? $app['config']['site.lastModified'] : $updatedDate, - $app['config']['site.title'], - $app['config']['site.subHead'], - $app['config']['services.google-analytics.id'] - ); - }); - } -} diff --git a/app/Routing/CategoryResolver.php b/app/Routing/CategoryResolver.php deleted file mode 100644 index fd17214..0000000 --- a/app/Routing/CategoryResolver.php +++ /dev/null @@ -1,14 +0,0 @@ -site = $site; - } - - public function filter(Route $route, Request $request, Response $response) - { - $response->setLastModified($this->site->getFeedLastModified()); - $response->setVary('Accept-Encoding'); - $response->setPublic(); - $response->setMaxAge(self::ONE_DAY); - - return $response; - } -} diff --git a/app/Routing/Filter/After/ResourceHttpCacheFilter.php b/app/Routing/Filter/After/ResourceHttpCacheFilter.php deleted file mode 100644 index 1933c9d..0000000 --- a/app/Routing/Filter/After/ResourceHttpCacheFilter.php +++ /dev/null @@ -1,39 +0,0 @@ -auth = $authManager; - } - - public function filter(Route $route, Request $request, Response $response) - { - if ($this->auth->check()) { - // If the user is logged in, don't cache. - return $response; - } - - /** @var \Baileylo\Blog\Post\Post|\Baileylo\Blog\Page\Page $post */ - $post = $route->getParameter('slug'); - - $response->setLastModified($post->getUpdatedAt()); - $response->setVary('Accept-Encoding'); - $response->setPublic(); - $response->setMaxAge(self::ONE_DAY); - - return $response; - } -} diff --git a/app/Routing/Filter/Before/AtomCacheFilter.php b/app/Routing/Filter/Before/AtomCacheFilter.php deleted file mode 100644 index 5c54471..0000000 --- a/app/Routing/Filter/Before/AtomCacheFilter.php +++ /dev/null @@ -1,30 +0,0 @@ -site = $site; - } - - public function filter(Route $route, Request $request) - { - $response = new Response(); - $response->setLastModified($this->site->getFeedLastModified()); - $response->setPublic(); - - if ($response->isNotModified($request)) { - return $response; - } - } -} diff --git a/app/Routing/Filter/Before/ForceSSLFilter.php b/app/Routing/Filter/Before/ForceSSLFilter.php deleted file mode 100644 index 670e46f..0000000 --- a/app/Routing/Filter/Before/ForceSSLFilter.php +++ /dev/null @@ -1,30 +0,0 @@ -redirector = $redirector; - $this->config = $config; - } - - public function filter(Route $route, Request $request) - { - if ($this->config['app.https'] && !$request->isSecure()) { - return $this->redirector->secure($request->path()); - } - } -} diff --git a/app/Routing/Filter/Before/LowerCaseUrlsFilter.php b/app/Routing/Filter/Before/LowerCaseUrlsFilter.php deleted file mode 100644 index b9470bc..0000000 --- a/app/Routing/Filter/Before/LowerCaseUrlsFilter.php +++ /dev/null @@ -1,34 +0,0 @@ -redirector = $redirector; - } - - public function filter(Request $request) - { - $path = $request->getPathInfo(); - if (!preg_match('/[A-Z]/', $path)) { - // No Upper case letters, so do nothing. - return; - } - - if ($request->method() === 'GET') { - $path = strtolower($path); - return $this->redirector->to($path, 301); - } - - throw new NotFoundHttpException; - } -} diff --git a/app/Routing/Filter/Before/PostUrlRedirect.php b/app/Routing/Filter/Before/PostUrlRedirect.php deleted file mode 100644 index 45919b3..0000000 --- a/app/Routing/Filter/Before/PostUrlRedirect.php +++ /dev/null @@ -1,34 +0,0 @@ -redirector = $redirector; - $this->urlGenerator = $urlGenerator; - } - - public function filter(Route $route, Request $request) - { - $url = $this->urlGenerator->route( - 'post.permalink', - [$route->getParameter('slug')->getSlug()] - ); - - return $this->redirector->to($url, 301); - } -} diff --git a/app/Routing/Filter/Before/ResourceHttpCacheFilter.php b/app/Routing/Filter/Before/ResourceHttpCacheFilter.php deleted file mode 100644 index b64aac4..0000000 --- a/app/Routing/Filter/Before/ResourceHttpCacheFilter.php +++ /dev/null @@ -1,42 +0,0 @@ -auth = $authManager; - $this->site = $site; - } - - public function filter(Route $route, Request $request) - { - if ($this->auth->check()) { - return; - } - - /** @var \Baileylo\Blog\Post\Post|\Baileylo\Blog\Page\Page $post */ - $post = $route->getParameter('slug'); - - $response = new Response(); - $response->setLastModified($post->getUpdatedAt()); - $response->setPublic(); - - if ($response->isNotModified($request)) { - return $response; - } - } -} diff --git a/app/Routing/Filter/Before/UnpublishedResourceAccessFilter.php b/app/Routing/Filter/Before/UnpublishedResourceAccessFilter.php deleted file mode 100644 index 4971b47..0000000 --- a/app/Routing/Filter/Before/UnpublishedResourceAccessFilter.php +++ /dev/null @@ -1,37 +0,0 @@ -manager = $manager; - $this->redirector = $redirector; - } - - public function filter(Route $route) - { - /** @var Page|Post $page */ - $page = $route->getParameter('slug'); - if ($this->manager->guest() && !$page->isPublished()) { - throw new NotFoundHttpException; - } - } -} diff --git a/app/Routing/Filter/RoutingFilterServiceProvider.php b/app/Routing/Filter/RoutingFilterServiceProvider.php deleted file mode 100644 index 0ef9349..0000000 --- a/app/Routing/Filter/RoutingFilterServiceProvider.php +++ /dev/null @@ -1,28 +0,0 @@ -app['router']; - $router->filter('beforeAtomCache', Before\AtomCacheFilter::class); - $router->filter('beforeResourceCache', Before\ResourceHttpCacheFilter::class); - $router->filter('afterAtomCache', After\AtomCacheFilter::class); - $router->filter('afterResourceCache', After\ResourceHttpCacheFilter::class); - $router->filter('postUrlRedirect', Before\PostUrlRedirect::class); - - $router->filter('forceSSL', Before\ForceSSLFilter::class); - $router->filter('unpublishedResource', Before\UnpublishedResourceAccessFilter::class); - - $router->before(Before\LowerCaseUrlsFilter::class); - } -} diff --git a/app/Routing/ResourceResolver.php b/app/Routing/ResourceResolver.php deleted file mode 100644 index 1c38d19..0000000 --- a/app/Routing/ResourceResolver.php +++ /dev/null @@ -1,47 +0,0 @@ -pageRepo = $pageRepo; - $this->postRepo = $postRepo; - } - - public function resource($slug) - { - $post = $this->getPost($slug); - if ($post) { - return $post; - } - - $page = $this->getPage($slug); - if ($page) { - return $page; - } - - throw new NotFoundHttpException; - } - - private function getPost($slug) - { - return $this->postRepo->findBySlug($slug); - } - - private function getPage($slug) - { - return $this->pageRepo->findBySlug($slug, false); - } -} diff --git a/app/Routing/RouteBindingServiceProvider.php b/app/Routing/RouteBindingServiceProvider.php deleted file mode 100644 index b501e31..0000000 --- a/app/Routing/RouteBindingServiceProvider.php +++ /dev/null @@ -1,22 +0,0 @@ -app['router']; - - $router->bind('category', CategoryResolver::class . '@category'); - $router->bind('slug', ResourceResolver::class . '@resource'); - } -} diff --git a/app/Pagination/Presenter/FullPresenter.php b/app/Services/Pagination/FoundationFourPresenter.php similarity index 90% rename from app/Pagination/Presenter/FullPresenter.php rename to app/Services/Pagination/FoundationFourPresenter.php index 632fe0e..2dde0de 100644 --- a/app/Pagination/Presenter/FullPresenter.php +++ b/app/Services/Pagination/FoundationFourPresenter.php @@ -1,10 +1,10 @@ '.$text.''; } - } diff --git a/app/Services/Registrar.php b/app/Services/Registrar.php deleted file mode 100644 index 1035468..0000000 --- a/app/Services/Registrar.php +++ /dev/null @@ -1,39 +0,0 @@ - 'required|max:255', - 'email' => 'required|email|max:255|unique:users', - 'password' => 'required|confirmed|min:6', - ]); - } - - /** - * Create a new user instance after a valid registration. - * - * @param array $data - * @return User - */ - public function create(array $data) - { - return User::create([ - 'name' => $data['name'], - 'email' => $data['email'], - 'password' => bcrypt($data['password']), - ]); - } - -} diff --git a/app/Services/Template/TemplateProvider.php b/app/Services/Template/TemplateProvider.php new file mode 100644 index 0000000..658e662 --- /dev/null +++ b/app/Services/Template/TemplateProvider.php @@ -0,0 +1,36 @@ +fileFinder = $fileFinder; + $this->templateDirectory = $templateDirectory; + } + + public function getTemplates() + { + $files = $this->fileFinder->files() + ->in($this->templateDirectory) + ->name('*.blade.php'); + + $templates = []; + foreach($files as $file) { + /** @var \SplFileInfo $file */ + $templates[] = $file->getBasename('.blade.php'); + } + + return $templates; + } +} diff --git a/app/User.php b/app/User.php index 2dae847..64c5f53 100644 --- a/app/User.php +++ b/app/User.php @@ -1,34 +1,40 @@ -hasMany(Post::class); + } } diff --git a/app/User/Validation/PasswordValidator.php b/app/User/Validation/PasswordValidator.php deleted file mode 100644 index 623bbc5..0000000 --- a/app/User/Validation/PasswordValidator.php +++ /dev/null @@ -1,28 +0,0 @@ -factory = $factory; - } - - public function validate($data) - { - $validators = $this->factory->make($data, [ - 'password' => 'required|min:5', - 'categories' => 'required', - 'description' => 'required', - 'body' => 'required' - ]); - - return new ValidationResponse($validators->messages()); - } -} diff --git a/app/Validators/Template.php b/app/Validators/Template.php new file mode 100644 index 0000000..8f40e99 --- /dev/null +++ b/app/Validators/Template.php @@ -0,0 +1,21 @@ +templateProvider = $templateProvider; + } + + public function validate($attributes, $value) + { + return is_string($value) && in_array($value, $this->templateProvider->getTemplates()); + } +} diff --git a/app/View/Composer/SiteComposer.php b/app/View/Composer/SiteComposer.php deleted file mode 100644 index 7d4aa17..0000000 --- a/app/View/Composer/SiteComposer.php +++ /dev/null @@ -1,24 +0,0 @@ -site = $site; - } - - public function compose($view) - { - return $view->with('site', $this->site); - } -} diff --git a/app/View/ViewServiceProvider.php b/app/View/ViewServiceProvider.php deleted file mode 100644 index 1e500fb..0000000 --- a/app/View/ViewServiceProvider.php +++ /dev/null @@ -1,29 +0,0 @@ -app['view']; - - - $view->composer('*', SiteComposer::class); - } -} diff --git a/artisan b/artisan old mode 100755 new mode 100644 index eb5e2bb..df630d0 --- a/artisan +++ b/artisan @@ -28,11 +28,11 @@ $app = require_once __DIR__.'/bootstrap/app.php'; | */ -$kernel = $app->make('Illuminate\Contracts\Console\Kernel'); +$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class); $status = $kernel->handle( - $input = new Symfony\Component\Console\Input\ArgvInput, - new Symfony\Component\Console\Output\ConsoleOutput + $input = new Symfony\Component\Console\Input\ArgvInput, + new Symfony\Component\Console\Output\ConsoleOutput ); /* diff --git a/bootstrap/app.php b/bootstrap/app.php index f50a3f7..f2801ad 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -12,7 +12,7 @@ */ $app = new Illuminate\Foundation\Application( - realpath(__DIR__.'/../') + realpath(__DIR__.'/../') ); /* @@ -27,18 +27,18 @@ */ $app->singleton( - 'Illuminate\Contracts\Http\Kernel', - 'App\Http\Kernel' + Illuminate\Contracts\Http\Kernel::class, + App\Http\Kernel::class ); $app->singleton( - 'Illuminate\Contracts\Console\Kernel', - 'App\Console\Kernel' + Illuminate\Contracts\Console\Kernel::class, + App\Console\Kernel::class ); $app->singleton( - 'Illuminate\Contracts\Debug\ExceptionHandler', - 'App\Exceptions\Handler' + Illuminate\Contracts\Debug\ExceptionHandler::class, + App\Exceptions\Handler::class ); /* diff --git a/bootstrap/autoload.php b/bootstrap/autoload.php index f2a9d56..3830137 100644 --- a/bootstrap/autoload.php +++ b/bootstrap/autoload.php @@ -27,9 +27,8 @@ | */ -$compiledPath = __DIR__.'/../storage/framework/compiled.php'; +$compiledPath = __DIR__.'/cache/compiled.php'; -if (file_exists($compiledPath)) -{ - require $compiledPath; +if (file_exists($compiledPath)) { + require $compiledPath; } diff --git a/bootstrap/cache/.gitignore b/bootstrap/cache/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/bootstrap/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/composer.json b/composer.json index 83588e6..1667b02 100644 --- a/composer.json +++ b/composer.json @@ -1,57 +1,53 @@ { - "name": "laravel/laravel", - "description": "The Laravel Framework.", - "keywords": [ - "framework", - "laravel" - ], - "license": "MIT", - "type": "project", - "require": { - "laravel/framework": "5.0.*", - "doctrine/mongodb-odm": "~1.0.0-BETA11@dev", - "ext-yaml": "~1.1", - "league/commonmark": "~0.6@dev", - "phpunit/phpunit": "~4.", - "nickcernis/html-to-markdown": "dev-master", - "fzaninotto/faker": "~1.4", - "illuminate/html": "~5.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0", - "phpspec/phpspec": "~2.1" - }, - "autoload": { - "classmap": [ - "database" - ], - "psr-4": { - "App\\": "app/", - "Baileylo\\BlogApp\\": "app", - "Baileylo\\Blog\\": "Blog", - "Baileylo\\Core\\": "Core" + "name": "laravel/laravel", + "description": "The Laravel Framework.", + "keywords": ["framework", "laravel"], + "license": "MIT", + "type": "project", + "require": { + "php": ">=5.5.9", + "laravel/framework": "5.2.*", + "barryvdh/laravel-ide-helper": "^2.1", + "barryvdh/laravel-debugbar": "^2.2", + "league/commonmark": "^0.11" + }, + "require-dev": { + "fzaninotto/faker": "~1.4", + "mockery/mockery": "0.9.*", + "phpunit/phpunit": "~4.0", + "symfony/css-selector": "2.8.*|3.0.*", + "symfony/dom-crawler": "2.8.*|3.0.*" + }, + "autoload": { + "classmap": [ + "database" + ], + "psr-4": { + "App\\": "app/" + } + }, + "autoload-dev": { + "classmap": [ + "tests/TestCase.php" + ] + }, + "scripts": { + "post-root-package-install": [ + "php -r \"copy('.env.example', '.env');\"" + ], + "post-create-project-cmd": [ + "php artisan key:generate" + ], + "post-install-cmd": [ + "php artisan clear-compiled", + "php artisan optimize" + ], + "post-update-cmd": [ + "php artisan clear-compiled", + "php artisan optimize" + ] + }, + "config": { + "preferred-install": "dist" } - }, - "autoload-dev": { - "classmap": [ - "tests/TestCase.php" - ] - }, - "scripts": { - "post-install-cmd": [ - "php artisan clear-compiled", - "php artisan optimize" - ], - "post-update-cmd": [ - "php artisan clear-compiled", - "php artisan optimize" - ], - "post-create-project-cmd": [ - "php -r \"copy('.env.example', '.env');\"", - "php artisan key:generate" - ] - }, - "config": { - "preferred-install": "dist" - } } diff --git a/config/app.php b/config/app.php index 9619adf..4fc7a63 100644 --- a/config/app.php +++ b/config/app.php @@ -1,20 +1,20 @@ env('APP_ENV', 'production'), + /* |-------------------------------------------------------------------------- | Application Debug Mode @@ -26,7 +26,8 @@ | */ - 'debug' => env('APP_DEBUG'), + 'debug' => env('APP_DEBUG', false), + /* |-------------------------------------------------------------------------- | Application URL @@ -38,7 +39,8 @@ | */ - 'url' => 'http://localhost', + 'url' => env('APP_URL', 'http://localhost'), + /* |-------------------------------------------------------------------------- | Application Timezone @@ -51,6 +53,7 @@ */ 'timezone' => 'UTC', + /* |-------------------------------------------------------------------------- | Application Locale Configuration @@ -63,6 +66,7 @@ */ 'locale' => 'en', + /* |-------------------------------------------------------------------------- | Application Fallback Locale @@ -75,6 +79,7 @@ */ 'fallback_locale' => 'en', + /* |-------------------------------------------------------------------------- | Encryption Key @@ -86,8 +91,10 @@ | */ - 'key' => env('APP_KEY', 'SomeRandomString'), - 'cipher' => MCRYPT_RIJNDAEL_128, + 'key' => env('APP_KEY'), + + 'cipher' => 'AES-256-CBC', + /* |-------------------------------------------------------------------------- | Logging Configuration @@ -101,7 +108,8 @@ | */ - 'log' => 'daily', + 'log' => env('APP_LOG', 'single'), + /* |-------------------------------------------------------------------------- | Autoloaded Service Providers @@ -118,53 +126,38 @@ /* * Laravel Framework Service Providers... */ - 'Illuminate\Foundation\Providers\ArtisanServiceProvider', - 'Illuminate\Auth\AuthServiceProvider', - 'Illuminate\Bus\BusServiceProvider', - 'Illuminate\Cache\CacheServiceProvider', - 'Illuminate\Foundation\Providers\ConsoleSupportServiceProvider', - 'Illuminate\Routing\ControllerServiceProvider', - 'Illuminate\Cookie\CookieServiceProvider', - 'Illuminate\Database\DatabaseServiceProvider', - 'Illuminate\Encryption\EncryptionServiceProvider', - 'Illuminate\Filesystem\FilesystemServiceProvider', - 'Illuminate\Foundation\Providers\FoundationServiceProvider', - 'Illuminate\Hashing\HashServiceProvider', - 'Illuminate\Mail\MailServiceProvider', - 'Illuminate\Pagination\PaginationServiceProvider', - 'Illuminate\Pipeline\PipelineServiceProvider', - 'Illuminate\Queue\QueueServiceProvider', - 'Illuminate\Redis\RedisServiceProvider', - 'Illuminate\Auth\Passwords\PasswordResetServiceProvider', - 'Illuminate\Session\SessionServiceProvider', - 'Illuminate\Translation\TranslationServiceProvider', - 'Illuminate\Validation\ValidationServiceProvider', - 'Illuminate\View\ViewServiceProvider', - - HtmlServiceProvider::class, - MongoValidationServiceProvider::class, - - SiteServiceProvider::class, - - ViewServiceProvider::class, - - RoutingFilterServiceProvider::class, - PostServicesServiceProvider::class, - MongoODMServiceProvider::class, - MarkdownServiceProvider::class, - UserProviderServiceProvider::class, - RepositoryServiceProvider::class, - RouteBindingServiceProvider::class, + Illuminate\Auth\AuthServiceProvider::class, + Illuminate\Broadcasting\BroadcastServiceProvider::class, + Illuminate\Bus\BusServiceProvider::class, + Illuminate\Cache\CacheServiceProvider::class, + Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, + Illuminate\Cookie\CookieServiceProvider::class, + Illuminate\Database\DatabaseServiceProvider::class, + Illuminate\Encryption\EncryptionServiceProvider::class, + Illuminate\Filesystem\FilesystemServiceProvider::class, + Illuminate\Foundation\Providers\FoundationServiceProvider::class, + Illuminate\Hashing\HashServiceProvider::class, + Illuminate\Mail\MailServiceProvider::class, + Illuminate\Pagination\PaginationServiceProvider::class, + Illuminate\Pipeline\PipelineServiceProvider::class, + Illuminate\Queue\QueueServiceProvider::class, + Illuminate\Redis\RedisServiceProvider::class, + Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, + Illuminate\Session\SessionServiceProvider::class, + Illuminate\Translation\TranslationServiceProvider::class, + Illuminate\Validation\ValidationServiceProvider::class, + Illuminate\View\ViewServiceProvider::class, + /* * Application Service Providers... */ - 'App\Providers\AppServiceProvider', - 'App\Providers\BusServiceProvider', - 'App\Providers\ConfigServiceProvider', - 'App\Providers\EventServiceProvider', - 'App\Providers\RouteServiceProvider', + App\Providers\AppServiceProvider::class, + App\Providers\AuthServiceProvider::class, + App\Providers\EventServiceProvider::class, + App\Providers\RouteServiceProvider::class, ], + /* |-------------------------------------------------------------------------- | Class Aliases @@ -178,41 +171,37 @@ 'aliases' => [ - 'App' => 'Illuminate\Support\Facades\App', - 'Artisan' => 'Illuminate\Support\Facades\Artisan', - 'Auth' => 'Illuminate\Support\Facades\Auth', - 'Blade' => 'Illuminate\Support\Facades\Blade', - 'Bus' => 'Illuminate\Support\Facades\Bus', - 'Cache' => 'Illuminate\Support\Facades\Cache', - 'Config' => 'Illuminate\Support\Facades\Config', - 'Cookie' => 'Illuminate\Support\Facades\Cookie', - 'Crypt' => 'Illuminate\Support\Facades\Crypt', - 'DB' => 'Illuminate\Support\Facades\DB', - 'Eloquent' => 'Illuminate\Database\Eloquent\Model', - 'Event' => 'Illuminate\Support\Facades\Event', - 'File' => 'Illuminate\Support\Facades\File', - 'Hash' => 'Illuminate\Support\Facades\Hash', - 'Input' => 'Illuminate\Support\Facades\Input', - 'Inspiring' => 'Illuminate\Foundation\Inspiring', - 'Lang' => 'Illuminate\Support\Facades\Lang', - 'Log' => 'Illuminate\Support\Facades\Log', - 'Mail' => 'Illuminate\Support\Facades\Mail', - 'Password' => 'Illuminate\Support\Facades\Password', - 'Queue' => 'Illuminate\Support\Facades\Queue', - 'Redirect' => 'Illuminate\Support\Facades\Redirect', - 'Redis' => 'Illuminate\Support\Facades\Redis', - 'Request' => 'Illuminate\Support\Facades\Request', - 'Response' => 'Illuminate\Support\Facades\Response', - 'Route' => 'Illuminate\Support\Facades\Route', - 'Schema' => 'Illuminate\Support\Facades\Schema', - 'Session' => 'Illuminate\Support\Facades\Session', - 'Storage' => 'Illuminate\Support\Facades\Storage', - 'URL' => 'Illuminate\Support\Facades\URL', - 'Validator' => 'Illuminate\Support\Facades\Validator', - 'View' => 'Illuminate\Support\Facades\View', - - 'Form' => 'Illuminate\Html\FormFacade', - 'Html' => 'Illuminate\Html\HtmlFacade' + 'App' => Illuminate\Support\Facades\App::class, + 'Artisan' => Illuminate\Support\Facades\Artisan::class, + 'Auth' => Illuminate\Support\Facades\Auth::class, + 'Blade' => Illuminate\Support\Facades\Blade::class, + 'Cache' => Illuminate\Support\Facades\Cache::class, + 'Config' => Illuminate\Support\Facades\Config::class, + 'Cookie' => Illuminate\Support\Facades\Cookie::class, + 'Crypt' => Illuminate\Support\Facades\Crypt::class, + 'DB' => Illuminate\Support\Facades\DB::class, + 'Eloquent' => Illuminate\Database\Eloquent\Model::class, + 'Event' => Illuminate\Support\Facades\Event::class, + 'File' => Illuminate\Support\Facades\File::class, + 'Gate' => Illuminate\Support\Facades\Gate::class, + 'Hash' => Illuminate\Support\Facades\Hash::class, + 'Lang' => Illuminate\Support\Facades\Lang::class, + 'Log' => Illuminate\Support\Facades\Log::class, + 'Mail' => Illuminate\Support\Facades\Mail::class, + 'Password' => Illuminate\Support\Facades\Password::class, + 'Queue' => Illuminate\Support\Facades\Queue::class, + 'Redirect' => Illuminate\Support\Facades\Redirect::class, + 'Redis' => Illuminate\Support\Facades\Redis::class, + 'Request' => Illuminate\Support\Facades\Request::class, + 'Response' => Illuminate\Support\Facades\Response::class, + 'Route' => Illuminate\Support\Facades\Route::class, + 'Schema' => Illuminate\Support\Facades\Schema::class, + 'Session' => Illuminate\Support\Facades\Session::class, + 'Storage' => Illuminate\Support\Facades\Storage::class, + 'URL' => Illuminate\Support\Facades\URL::class, + 'Validator' => Illuminate\Support\Facades\Validator::class, + 'View' => Illuminate\Support\Facades\View::class, + ], ]; diff --git a/config/auth.php b/config/auth.php index 7f3fa17..3fa7f49 100644 --- a/config/auth.php +++ b/config/auth.php @@ -2,66 +2,106 @@ return [ - /* - |-------------------------------------------------------------------------- - | Default Authentication Driver - |-------------------------------------------------------------------------- - | - | This option controls the authentication driver that will be utilized. - | This driver manages the retrieval and authentication of the users - | attempting to get access to protected areas of your application. - | - | Supported: "database", "eloquent" - | - */ + /* + |-------------------------------------------------------------------------- + | Authentication Defaults + |-------------------------------------------------------------------------- + | + | This option controls the default authentication "guard" and password + | reset options for your application. You may change these defaults + | as required, but they're a perfect start for most applications. + | + */ - 'driver' => 'blog', + 'defaults' => [ + 'guard' => 'web', + 'passwords' => 'users', + ], - /* - |-------------------------------------------------------------------------- - | Authentication Model - |-------------------------------------------------------------------------- - | - | When using the "Eloquent" authentication driver, we need to know which - | Eloquent model should be used to retrieve your users. Of course, it - | is often just the "User" model but you may use whatever you like. - | - */ + /* + |-------------------------------------------------------------------------- + | Authentication Guards + |-------------------------------------------------------------------------- + | + | Next, you may define every authentication guard for your application. + | Of course, a great default configuration has been defined for you + | here which uses session storage and the Eloquent user provider. + | + | All authentication drivers have a user provider. This defines how the + | users are actually retrieved out of your database or other storage + | mechanisms used by this application to persist your user's data. + | + | Supported: "session", "token" + | + */ - 'model' => 'App\User', + 'guards' => [ + 'web' => [ + 'driver' => 'session', + 'provider' => 'users', + ], - /* - |-------------------------------------------------------------------------- - | Authentication Table - |-------------------------------------------------------------------------- - | - | When using the "Database" authentication driver, we need to know which - | table should be used to retrieve your users. We have chosen a basic - | default value but you may easily change it to any table you like. - | - */ + 'api' => [ + 'driver' => 'token', + 'provider' => 'users', + ], + ], - 'table' => 'users', + /* + |-------------------------------------------------------------------------- + | User Providers + |-------------------------------------------------------------------------- + | + | All authentication drivers have a user provider. This defines how the + | users are actually retrieved out of your database or other storage + | mechanisms used by this application to persist your user's data. + | + | If you have multiple user tables or models you may configure multiple + | sources which represent each model / table. These sources may then + | be assigned to any extra authentication guards you have defined. + | + | Supported: "database", "eloquent" + | + */ - /* - |-------------------------------------------------------------------------- - | Password Reset Settings - |-------------------------------------------------------------------------- - | - | Here you may set the options for resetting passwords including the view - | that is your password reset e-mail. You can also set the name of the - | table that maintains all of the reset tokens for your application. - | - | The expire time is the number of minutes that the reset token should be - | considered valid. This security feature keeps tokens short-lived so - | they have less time to be guessed. You may change this as needed. - | - */ + 'providers' => [ + 'users' => [ + 'driver' => 'eloquent', + 'model' => App\User::class, + ], - 'password' => [ - 'email' => 'emails.password', - 'table' => 'password_resets', - 'expire' => 60, - ], + // 'users' => [ + // 'driver' => 'database', + // 'table' => 'users', + // ], + ], + + /* + |-------------------------------------------------------------------------- + | Resetting Passwords + |-------------------------------------------------------------------------- + | + | Here you may set the options for resetting passwords including the view + | that is your password reset e-mail. You may also set the name of the + | table that maintains all of the reset tokens for your application. + | + | You may specify multiple password reset configurations if you have more + | than one user table or model in the application and you want to have + | separate password reset settings based on the specific user types. + | + | The expire time is the number of minutes that the reset token should be + | considered valid. This security feature keeps tokens short-lived so + | they have less time to be guessed. You may change this as needed. + | + */ + + 'passwords' => [ + 'users' => [ + 'provider' => 'users', + 'email' => 'auth.emails.password', + 'table' => 'password_resets', + 'expire' => 60, + ], + ], ]; diff --git a/config/broadcasting.php b/config/broadcasting.php new file mode 100644 index 0000000..abaaac3 --- /dev/null +++ b/config/broadcasting.php @@ -0,0 +1,52 @@ + env('BROADCAST_DRIVER', 'pusher'), + + /* + |-------------------------------------------------------------------------- + | Broadcast Connections + |-------------------------------------------------------------------------- + | + | Here you may define all of the broadcast connections that will be used + | to broadcast events to other systems or over websockets. Samples of + | each available type of connection are provided inside this array. + | + */ + + 'connections' => [ + + 'pusher' => [ + 'driver' => 'pusher', + 'key' => env('PUSHER_KEY'), + 'secret' => env('PUSHER_SECRET'), + 'app_id' => env('PUSHER_APP_ID'), + 'options' => [ + // + ], + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default', + ], + + 'log' => [ + 'driver' => 'log', + ], + + ], + +]; diff --git a/config/cache.php b/config/cache.php index 9ddd5f3..3ffa840 100644 --- a/config/cache.php +++ b/config/cache.php @@ -2,78 +2,80 @@ return [ - /* - |-------------------------------------------------------------------------- - | Default Cache Store - |-------------------------------------------------------------------------- - | - | This option controls the default cache connection that gets used while - | using this caching library. This connection is used when another is - | not explicitly specified when executing a given caching function. - | - */ + /* + |-------------------------------------------------------------------------- + | Default Cache Store + |-------------------------------------------------------------------------- + | + | This option controls the default cache connection that gets used while + | using this caching library. This connection is used when another is + | not explicitly specified when executing a given caching function. + | + */ - 'default' => env('CACHE_DRIVER', 'file'), + 'default' => env('CACHE_DRIVER', 'file'), - /* - |-------------------------------------------------------------------------- - | Cache Stores - |-------------------------------------------------------------------------- - | - | Here you may define all of the cache "stores" for your application as - | well as their drivers. You may even define multiple stores for the - | same cache driver to group types of items stored in your caches. - | - */ + /* + |-------------------------------------------------------------------------- + | Cache Stores + |-------------------------------------------------------------------------- + | + | Here you may define all of the cache "stores" for your application as + | well as their drivers. You may even define multiple stores for the + | same cache driver to group types of items stored in your caches. + | + */ - 'stores' => [ + 'stores' => [ - 'apc' => [ - 'driver' => 'apc' - ], + 'apc' => [ + 'driver' => 'apc', + ], - 'array' => [ - 'driver' => 'array' - ], + 'array' => [ + 'driver' => 'array', + ], - 'database' => [ - 'driver' => 'database', - 'table' => 'cache', - 'connection' => null, - ], + 'database' => [ + 'driver' => 'database', + 'table' => 'cache', + 'connection' => null, + ], - 'file' => [ - 'driver' => 'file', - 'path' => storage_path().'/framework/cache', - ], + 'file' => [ + 'driver' => 'file', + 'path' => storage_path('framework/cache'), + ], - 'memcached' => [ - 'driver' => 'memcached', - 'servers' => [ - [ - 'host' => '127.0.0.1', 'port' => 11211, 'weight' => 100 - ], - ], - ], + 'memcached' => [ + 'driver' => 'memcached', + 'servers' => [ + [ + 'host' => env('MEMCACHED_HOST', '127.0.0.1'), + 'port' => env('MEMCACHED_PORT', 11211), + 'weight' => 100, + ], + ], + ], - 'redis' => [ - 'driver' => 'redis', - 'connection' => 'default', - ], + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default', + ], - ], + ], - /* - |-------------------------------------------------------------------------- - | Cache Key Prefix - |-------------------------------------------------------------------------- - | - | When utilizing a RAM based store such as APC or Memcached, there might - | be other applications utilizing the same cache. So, we'll specify a - | value to get prefixed to all our keys so we can avoid collisions. - | - */ + /* + |-------------------------------------------------------------------------- + | Cache Key Prefix + |-------------------------------------------------------------------------- + | + | When utilizing a RAM based store such as APC or Memcached, there might + | be other applications utilizing the same cache. So, we'll specify a + | value to get prefixed to all our keys so we can avoid collisions. + | + */ - 'prefix' => 'laravel', + 'prefix' => 'laravel', ]; diff --git a/config/compile.php b/config/compile.php index 3a002fc..04807ea 100644 --- a/config/compile.php +++ b/config/compile.php @@ -2,40 +2,34 @@ return [ - /* - |-------------------------------------------------------------------------- - | Additional Compiled Classes - |-------------------------------------------------------------------------- - | - | Here you may specify additional classes to include in the compiled file - | generated by the `artisan optimize` command. These should be classes - | that are included on basically every request into the application. - | - */ - - 'files' => [ - - realpath(__DIR__.'/../app/Providers/AppServiceProvider.php'), - realpath(__DIR__.'/../app/Providers/BusServiceProvider.php'), - realpath(__DIR__.'/../app/Providers/ConfigServiceProvider.php'), - realpath(__DIR__.'/../app/Providers/EventServiceProvider.php'), - realpath(__DIR__.'/../app/Providers/RouteServiceProvider.php'), - - ], - - /* - |-------------------------------------------------------------------------- - | Compiled File Providers - |-------------------------------------------------------------------------- - | - | Here you may list service providers which define a "compiles" function - | that returns additional files that should be compiled, providing an - | easy way to get common files from any packages you are utilizing. - | - */ - - 'providers' => [ - // - ], + /* + |-------------------------------------------------------------------------- + | Additional Compiled Classes + |-------------------------------------------------------------------------- + | + | Here you may specify additional classes to include in the compiled file + | generated by the `artisan optimize` command. These should be classes + | that are included on basically every request into the application. + | + */ + + 'files' => [ + // + ], + + /* + |-------------------------------------------------------------------------- + | Compiled File Providers + |-------------------------------------------------------------------------- + | + | Here you may list service providers which define a "compiles" function + | that returns additional files that should be compiled, providing an + | easy way to get common files from any packages you are utilizing. + | + */ + + 'providers' => [ + // + ], ]; diff --git a/config/database.php b/config/database.php index 8e2c92d..def1e56 100644 --- a/config/database.php +++ b/config/database.php @@ -1,13 +1,120 @@ [ - 'host' => env('MONGO_HOST', 'mongodb://localhost:27017'), - 'collection' => env('MONGO_COLLECTION', 'blog'), - 'options' => [ - 'password' => env('MONGO_PASSWORD', ''), - 'username' => env('MONGO_USER', '') - ] - ] + + /* + |-------------------------------------------------------------------------- + | PDO Fetch Style + |-------------------------------------------------------------------------- + | + | By default, database results will be returned as instances of the PHP + | stdClass object; however, you may desire to retrieve records in an + | array format for simplicity. Here you can tweak the fetch style. + | + */ + + 'fetch' => PDO::FETCH_CLASS, + + /* + |-------------------------------------------------------------------------- + | Default Database Connection Name + |-------------------------------------------------------------------------- + | + | Here you may specify which of the database connections below you wish + | to use as your default connection for all database work. Of course + | you may use many connections at once using the Database library. + | + */ + + 'default' => env('DB_CONNECTION', 'mysql'), + + /* + |-------------------------------------------------------------------------- + | Database Connections + |-------------------------------------------------------------------------- + | + | Here are each of the database connections setup for your application. + | Of course, examples of configuring each database platform that is + | supported by Laravel is shown below to make development simple. + | + | + | All database work in Laravel is done through the PHP PDO facilities + | so make sure you have the driver for your particular database of + | choice installed on your machine before you begin development. + | + */ + + 'connections' => [ + + 'sqlite' => [ + 'driver' => 'sqlite', + 'database' => database_path('database.sqlite'), + 'prefix' => '', + ], + + 'mysql' => [ + 'driver' => 'mysql', + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => 'utf8', + 'collation' => 'utf8_unicode_ci', + 'prefix' => '', + 'strict' => false, + 'engine' => null, + ], + + 'pgsql' => [ + 'driver' => 'pgsql', + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', '5432'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => 'utf8', + 'prefix' => '', + 'schema' => 'public', + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Migration Repository Table + |-------------------------------------------------------------------------- + | + | This table keeps track of all the migrations that have already run for + | your application. Using this information, we can determine which of + | the migrations on disk haven't actually been run in the database. + | + */ + + 'migrations' => 'migrations', + + /* + |-------------------------------------------------------------------------- + | Redis Databases + |-------------------------------------------------------------------------- + | + | Redis is an open source, fast, and advanced key-value store that also + | provides a richer set of commands than a typical key-value systems + | such as APC or Memcached. Laravel makes it easy to dig right in. + | + */ + + 'redis' => [ + + 'cluster' => false, + + 'default' => [ + 'host' => env('REDIS_HOST', 'localhost'), + 'password' => env('REDIS_PASSWORD', null), + 'port' => env('REDIS_PORT', 6379), + 'database' => 0, + ], + + ], ]; diff --git a/config/doctrine.php b/config/doctrine.php deleted file mode 100644 index 3534667..0000000 --- a/config/doctrine.php +++ /dev/null @@ -1,18 +0,0 @@ - [ - 'dir' => base_path('/Blog/Storage/proxy'), - 'namespace' => 'Baileylo\Blog\Storage\Proxy' - ], - - 'hydrator' => [ - 'dir' => base_path('/Blog/Storage/Hydrators'), - 'namespace' => 'Baileylo\Blog\Storage\Hydrators' - ], - - 'metadata' => [ - 'dir' => base_path('/Blog/config'), - 'extension' => '.yml' - ] -]; diff --git a/config/filesystems.php b/config/filesystems.php index ad8228f..75b5002 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -2,69 +2,66 @@ return [ - /* - |-------------------------------------------------------------------------- - | Default Filesystem Disk - |-------------------------------------------------------------------------- - | - | Here you may specify the default filesystem disk that should be used - | by the framework. A "local" driver, as well as a variety of cloud - | based drivers are available for your choosing. Just store away! - | - | Supported: "local", "s3", "rackspace" - | - */ + /* + |-------------------------------------------------------------------------- + | Default Filesystem Disk + |-------------------------------------------------------------------------- + | + | Here you may specify the default filesystem disk that should be used + | by the framework. A "local" driver, as well as a variety of cloud + | based drivers are available for your choosing. Just store away! + | + | Supported: "local", "ftp", "s3", "rackspace" + | + */ - 'default' => 'local', + 'default' => 'local', - /* - |-------------------------------------------------------------------------- - | Default Cloud Filesystem Disk - |-------------------------------------------------------------------------- - | - | Many applications store files both locally and in the cloud. For this - | reason, you may specify a default "cloud" driver here. This driver - | will be bound as the Cloud disk implementation in the container. - | - */ + /* + |-------------------------------------------------------------------------- + | Default Cloud Filesystem Disk + |-------------------------------------------------------------------------- + | + | Many applications store files both locally and in the cloud. For this + | reason, you may specify a default "cloud" driver here. This driver + | will be bound as the Cloud disk implementation in the container. + | + */ - 'cloud' => 's3', + 'cloud' => 's3', - /* - |-------------------------------------------------------------------------- - | Filesystem Disks - |-------------------------------------------------------------------------- - | - | Here you may configure as many filesystem "disks" as you wish, and you - | may even configure multiple disks of the same driver. Defaults have - | been setup for each driver as an example of the required options. - | - */ + /* + |-------------------------------------------------------------------------- + | Filesystem Disks + |-------------------------------------------------------------------------- + | + | Here you may configure as many filesystem "disks" as you wish, and you + | may even configure multiple disks of the same driver. Defaults have + | been setup for each driver as an example of the required options. + | + */ - 'disks' => [ + 'disks' => [ - 'local' => [ - 'driver' => 'local', - 'root' => storage_path().'/app', - ], + 'local' => [ + 'driver' => 'local', + 'root' => storage_path('app'), + ], - 's3' => [ - 'driver' => 's3', - 'key' => 'your-key', - 'secret' => 'your-secret', - 'region' => 'your-region', - 'bucket' => 'your-bucket', - ], + 'public' => [ + 'driver' => 'local', + 'root' => storage_path('app/public'), + 'visibility' => 'public', + ], - 'rackspace' => [ - 'driver' => 'rackspace', - 'username' => 'your-username', - 'key' => 'your-key', - 'container' => 'your-container', - 'endpoint' => 'https://identity.api.rackspacecloud.com/v2.0/', - 'region' => 'IAD', - ], + 's3' => [ + 'driver' => 's3', + 'key' => 'your-key', + 'secret' => 'your-secret', + 'region' => 'your-region', + 'bucket' => 'your-bucket', + ], - ], + ], ]; diff --git a/config/mail.php b/config/mail.php index 6f9c954..a076588 100644 --- a/config/mail.php +++ b/config/mail.php @@ -2,123 +2,111 @@ return [ - /* - |-------------------------------------------------------------------------- - | Mail Driver - |-------------------------------------------------------------------------- - | - | Laravel supports both SMTP and PHP's "mail" function as drivers for the - | sending of e-mail. You may specify which one you're using throughout - | your application here. By default, Laravel is setup for SMTP mail. - | - | Supported: "smtp", "mail", "sendmail", "mailgun", "mandrill", "log" - | - */ - - 'driver' => 'smtp', - - /* - |-------------------------------------------------------------------------- - | SMTP Host Address - |-------------------------------------------------------------------------- - | - | Here you may provide the host address of the SMTP server used by your - | applications. A default option is provided that is compatible with - | the Mailgun mail service which will provide reliable deliveries. - | - */ - - 'host' => 'smtp.mailgun.org', - - /* - |-------------------------------------------------------------------------- - | SMTP Host Port - |-------------------------------------------------------------------------- - | - | This is the SMTP port used by your application to deliver e-mails to - | users of the application. Like the host we have set this value to - | stay compatible with the Mailgun e-mail application by default. - | - */ - - 'port' => 587, - - /* - |-------------------------------------------------------------------------- - | Global "From" Address - |-------------------------------------------------------------------------- - | - | You may wish for all e-mails sent by your application to be sent from - | the same address. Here, you may specify a name and address that is - | used globally for all e-mails that are sent by your application. - | - */ - - 'from' => ['address' => null, 'name' => null], - - /* - |-------------------------------------------------------------------------- - | E-Mail Encryption Protocol - |-------------------------------------------------------------------------- - | - | Here you may specify the encryption protocol that should be used when - | the application send e-mail messages. A sensible default using the - | transport layer security protocol should provide great security. - | - */ - - 'encryption' => 'tls', - - /* - |-------------------------------------------------------------------------- - | SMTP Server Username - |-------------------------------------------------------------------------- - | - | If your SMTP server requires a username for authentication, you should - | set it here. This will get used to authenticate with your server on - | connection. You may also set the "password" value below this one. - | - */ - - 'username' => null, - - /* - |-------------------------------------------------------------------------- - | SMTP Server Password - |-------------------------------------------------------------------------- - | - | Here you may set the password required by your SMTP server to send out - | messages from your application. This will be given to the server on - | connection so that the application will be able to send messages. - | - */ - - 'password' => null, - - /* - |-------------------------------------------------------------------------- - | Sendmail System Path - |-------------------------------------------------------------------------- - | - | When using the "sendmail" driver to send e-mails, we will need to know - | the path to where Sendmail lives on this server. A default path has - | been provided here, which will work well on most of your systems. - | - */ - - 'sendmail' => '/usr/sbin/sendmail -bs', - - /* - |-------------------------------------------------------------------------- - | Mail "Pretend" - |-------------------------------------------------------------------------- - | - | When this option is enabled, e-mail will not actually be sent over the - | web and will instead be written to your application's logs files so - | you may inspect the message. This is great for local development. - | - */ - - 'pretend' => false, + /* + |-------------------------------------------------------------------------- + | Mail Driver + |-------------------------------------------------------------------------- + | + | Laravel supports both SMTP and PHP's "mail" function as drivers for the + | sending of e-mail. You may specify which one you're using throughout + | your application here. By default, Laravel is setup for SMTP mail. + | + | Supported: "smtp", "mail", "sendmail", "mailgun", "mandrill", + | "ses", "sparkpost", "log" + | + */ + + 'driver' => env('MAIL_DRIVER', 'smtp'), + + /* + |-------------------------------------------------------------------------- + | SMTP Host Address + |-------------------------------------------------------------------------- + | + | Here you may provide the host address of the SMTP server used by your + | applications. A default option is provided that is compatible with + | the Mailgun mail service which will provide reliable deliveries. + | + */ + + 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), + + /* + |-------------------------------------------------------------------------- + | SMTP Host Port + |-------------------------------------------------------------------------- + | + | This is the SMTP port used by your application to deliver e-mails to + | users of the application. Like the host we have set this value to + | stay compatible with the Mailgun e-mail application by default. + | + */ + + 'port' => env('MAIL_PORT', 587), + + /* + |-------------------------------------------------------------------------- + | Global "From" Address + |-------------------------------------------------------------------------- + | + | You may wish for all e-mails sent by your application to be sent from + | the same address. Here, you may specify a name and address that is + | used globally for all e-mails that are sent by your application. + | + */ + + 'from' => ['address' => null, 'name' => null], + + /* + |-------------------------------------------------------------------------- + | E-Mail Encryption Protocol + |-------------------------------------------------------------------------- + | + | Here you may specify the encryption protocol that should be used when + | the application send e-mail messages. A sensible default using the + | transport layer security protocol should provide great security. + | + */ + + 'encryption' => env('MAIL_ENCRYPTION', 'tls'), + + /* + |-------------------------------------------------------------------------- + | SMTP Server Username + |-------------------------------------------------------------------------- + | + | If your SMTP server requires a username for authentication, you should + | set it here. This will get used to authenticate with your server on + | connection. You may also set the "password" value below this one. + | + */ + + 'username' => env('MAIL_USERNAME'), + + /* + |-------------------------------------------------------------------------- + | SMTP Server Password + |-------------------------------------------------------------------------- + | + | Here you may set the password required by your SMTP server to send out + | messages from your application. This will be given to the server on + | connection so that the application will be able to send messages. + | + */ + + 'password' => env('MAIL_PASSWORD'), + + /* + |-------------------------------------------------------------------------- + | Sendmail System Path + |-------------------------------------------------------------------------- + | + | When using the "sendmail" driver to send e-mails, we will need to know + | the path to where Sendmail lives on this server. A default path has + | been provided here, which will work well on most of your systems. + | + */ + + 'sendmail' => '/usr/sbin/sendmail -bs', ]; diff --git a/config/queue.php b/config/queue.php old mode 100755 new mode 100644 index 9c39a13..a2f3888 --- a/config/queue.php +++ b/config/queue.php @@ -2,91 +2,85 @@ return [ - /* - |-------------------------------------------------------------------------- - | Default Queue Driver - |-------------------------------------------------------------------------- - | - | The Laravel queue API supports a variety of back-ends via an unified - | API, giving you convenient access to each back-end using the same - | syntax for each one. Here you may set the default queue driver. - | - | Supported: "null", "sync", "database", "beanstalkd", - | "sqs", "iron", "redis" - | - */ + /* + |-------------------------------------------------------------------------- + | Default Queue Driver + |-------------------------------------------------------------------------- + | + | The Laravel queue API supports a variety of back-ends via an unified + | API, giving you convenient access to each back-end using the same + | syntax for each one. Here you may set the default queue driver. + | + | Supported: "null", "sync", "database", "beanstalkd", + | "sqs", "redis" + | + */ - 'default' => env('QUEUE_DRIVER', 'sync'), + 'default' => env('QUEUE_DRIVER', 'sync'), - /* - |-------------------------------------------------------------------------- - | Queue Connections - |-------------------------------------------------------------------------- - | - | Here you may configure the connection information for each server that - | is used by your application. A default configuration has been added - | for each back-end shipped with Laravel. You are free to add more. - | - */ + /* + |-------------------------------------------------------------------------- + | Queue Connections + |-------------------------------------------------------------------------- + | + | Here you may configure the connection information for each server that + | is used by your application. A default configuration has been added + | for each back-end shipped with Laravel. You are free to add more. + | + */ - 'connections' => [ + 'connections' => [ - 'sync' => [ - 'driver' => 'sync', - ], + 'sync' => [ + 'driver' => 'sync', + ], - 'database' => [ - 'driver' => 'database', - 'table' => 'jobs', - 'queue' => 'default', - 'expire' => 60, - ], + 'database' => [ + 'driver' => 'database', + 'table' => 'jobs', + 'queue' => 'default', + 'expire' => 60, + ], - 'beanstalkd' => [ - 'driver' => 'beanstalkd', - 'host' => 'localhost', - 'queue' => 'default', - 'ttr' => 60, - ], + 'beanstalkd' => [ + 'driver' => 'beanstalkd', + 'host' => 'localhost', + 'queue' => 'default', + 'ttr' => 60, + ], - 'sqs' => [ - 'driver' => 'sqs', - 'key' => 'your-public-key', - 'secret' => 'your-secret-key', - 'queue' => 'your-queue-url', - 'region' => 'us-east-1', - ], + 'sqs' => [ + 'driver' => 'sqs', + 'key' => 'your-public-key', + 'secret' => 'your-secret-key', + 'prefix' => 'https://sqs.us-east-1.amazonaws.com/your-account-id', + 'queue' => 'your-queue-name', + 'region' => 'us-east-1', + ], - 'iron' => [ - 'driver' => 'iron', - 'host' => 'mq-aws-us-east-1.iron.io', - 'token' => 'your-token', - 'project' => 'your-project-id', - 'queue' => 'your-queue-name', - 'encrypt' => true, - ], + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default', + 'queue' => 'default', + 'expire' => 60, + ], - 'redis' => [ - 'driver' => 'redis', - 'queue' => 'default', - 'expire' => 60, - ], + ], - ], + /* + |-------------------------------------------------------------------------- + | Failed Queue Jobs + |-------------------------------------------------------------------------- + | + | These options configure the behavior of failed queue job logging so you + | can control which database and table are used to store the jobs that + | have failed. You may change them to any database / table you wish. + | + */ - /* - |-------------------------------------------------------------------------- - | Failed Queue Jobs - |-------------------------------------------------------------------------- - | - | These options configure the behavior of failed queue job logging so you - | can control which database and table are used to store the jobs that - | have failed. You may change them to any database / table you wish. - | - */ - - 'failed' => [ - 'database' => 'mysql', 'table' => 'failed_jobs', - ], + 'failed' => [ + 'database' => env('DB_CONNECTION', 'mysql'), + 'table' => 'failed_jobs', + ], ]; diff --git a/config/services.php b/config/services.php index 2781994..287b118 100644 --- a/config/services.php +++ b/config/services.php @@ -15,24 +15,24 @@ */ 'mailgun' => [ - 'domain' => '', - 'secret' => '', - ], - 'mandrill' => [ - 'secret' => '', + 'domain' => env('MAILGUN_DOMAIN'), + 'secret' => env('MAILGUN_SECRET'), ], + 'ses' => [ - 'key' => '', - 'secret' => '', + 'key' => env('SES_KEY'), + 'secret' => env('SES_SECRET'), 'region' => 'us-east-1', ], - 'stripe' => [ - 'model' => 'User', - 'secret' => '', + + 'sparkpost' => [ + 'secret' => env('SPARKPOST_SECRET'), ], - 'google-analytics' => [ - 'id' => env('GA_ID') - ] + 'stripe' => [ + 'model' => App\User::class, + 'key' => env('STRIPE_KEY'), + 'secret' => env('STRIPE_SECRET'), + ], ]; diff --git a/config/session.php b/config/session.php index 47470fa..b501055 100644 --- a/config/session.php +++ b/config/session.php @@ -2,152 +2,165 @@ return [ - /* - |-------------------------------------------------------------------------- - | Default Session Driver - |-------------------------------------------------------------------------- - | - | This option controls the default session "driver" that will be used on - | requests. By default, we will use the lightweight native driver but - | you may specify any of the other wonderful drivers provided here. - | - | Supported: "file", "cookie", "database", "apc", - | "memcached", "redis", "array" - | - */ - - 'driver' => env('SESSION_DRIVER', 'file'), - - /* - |-------------------------------------------------------------------------- - | Session Lifetime - |-------------------------------------------------------------------------- - | - | Here you may specify the number of minutes that you wish the session - | to be allowed to remain idle before it expires. If you want them - | to immediately expire on the browser closing, set that option. - | - */ - - 'lifetime' => 120, - - 'expire_on_close' => false, - - /* - |-------------------------------------------------------------------------- - | Session Encryption - |-------------------------------------------------------------------------- - | - | This option allows you to easily specify that all of your session data - | should be encrypted before it is stored. All encryption will be run - | automatically by Laravel and you can use the Session like normal. - | - */ - - 'encrypt' => false, - - /* - |-------------------------------------------------------------------------- - | Session File Location - |-------------------------------------------------------------------------- - | - | When using the native session driver, we need a location where session - | files may be stored. A default has been set for you but a different - | location may be specified. This is only needed for file sessions. - | - */ - - 'files' => storage_path().'/framework/sessions', - - /* - |-------------------------------------------------------------------------- - | Session Database Connection - |-------------------------------------------------------------------------- - | - | When using the "database" or "redis" session drivers, you may specify a - | connection that should be used to manage these sessions. This should - | correspond to a connection in your database configuration options. - | - */ - - 'connection' => null, - - /* - |-------------------------------------------------------------------------- - | Session Database Table - |-------------------------------------------------------------------------- - | - | When using the "database" session driver, you may specify the table we - | should use to manage the sessions. Of course, a sensible default is - | provided for you; however, you are free to change this as needed. - | - */ - - 'table' => 'sessions', - - /* - |-------------------------------------------------------------------------- - | Session Sweeping Lottery - |-------------------------------------------------------------------------- - | - | Some session drivers must manually sweep their storage location to get - | rid of old sessions from storage. Here are the chances that it will - | happen on a given request. By default, the odds are 2 out of 100. - | - */ - - 'lottery' => [2, 100], - - /* - |-------------------------------------------------------------------------- - | Session Cookie Name - |-------------------------------------------------------------------------- - | - | Here you may change the name of the cookie used to identify a session - | instance by ID. The name specified here will get used every time a - | new session cookie is created by the framework for every driver. - | - */ - - 'cookie' => 'laravel_session', - - /* - |-------------------------------------------------------------------------- - | Session Cookie Path - |-------------------------------------------------------------------------- - | - | The session cookie path determines the path for which the cookie will - | be regarded as available. Typically, this will be the root path of - | your application but you are free to change this when necessary. - | - */ - - 'path' => '/', - - /* - |-------------------------------------------------------------------------- - | Session Cookie Domain - |-------------------------------------------------------------------------- - | - | Here you may change the domain of the cookie used to identify a session - | in your application. This will determine which domains the cookie is - | available to in your application. A sensible default has been set. - | - */ - - 'domain' => null, - - /* - |-------------------------------------------------------------------------- - | HTTPS Only Cookies - |-------------------------------------------------------------------------- - | - | By setting this option to true, session cookies will only be sent back - | to the server if the browser has a HTTPS connection. This will keep - | the cookie from being sent to you if it can not be done securely. - | - */ - - 'secure' => false, + /* + |-------------------------------------------------------------------------- + | Default Session Driver + |-------------------------------------------------------------------------- + | + | This option controls the default session "driver" that will be used on + | requests. By default, we will use the lightweight native driver but + | you may specify any of the other wonderful drivers provided here. + | + | Supported: "file", "cookie", "database", "apc", + | "memcached", "redis", "array" + | + */ + + 'driver' => env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => 120, + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ + + 'cookie' => 'laravel_session', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => null, + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => false, + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + 'http_only' => true, ]; diff --git a/config/site.php b/config/site.php deleted file mode 100644 index 408a367..0000000 --- a/config/site.php +++ /dev/null @@ -1,7 +0,0 @@ - new \DateTime(), - 'title' => 'Infectious Learning', - 'subHead' => 'Adventures in web development' -]; diff --git a/config/view.php b/config/view.php index 88fc534..e193ab6 100644 --- a/config/view.php +++ b/config/view.php @@ -2,32 +2,32 @@ return [ - /* - |-------------------------------------------------------------------------- - | View Storage Paths - |-------------------------------------------------------------------------- - | - | Most templating systems load templates from disk. Here you may specify - | an array of paths that should be checked for your views. Of course - | the usual Laravel view path has already been registered for you. - | - */ + /* + |-------------------------------------------------------------------------- + | View Storage Paths + |-------------------------------------------------------------------------- + | + | Most templating systems load templates from disk. Here you may specify + | an array of paths that should be checked for your views. Of course + | the usual Laravel view path has already been registered for you. + | + */ - 'paths' => [ - realpath(base_path('resources/views')) - ], + 'paths' => [ + realpath(base_path('resources/views')), + ], - /* - |-------------------------------------------------------------------------- - | Compiled View Path - |-------------------------------------------------------------------------- - | - | This option determines where all the compiled Blade templates will be - | stored for your application. Typically, this is within the storage - | directory. However, as usual, you are free to change this value. - | - */ + /* + |-------------------------------------------------------------------------- + | Compiled View Path + |-------------------------------------------------------------------------- + | + | This option determines where all the compiled Blade templates will be + | stored for your application. Typically, this is within the storage + | directory. However, as usual, you are free to change this value. + | + */ - 'compiled' => realpath(storage_path().'/framework/views'), + 'compiled' => realpath(storage_path('framework/views')), ]; diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php new file mode 100644 index 0000000..b462c29 --- /dev/null +++ b/database/factories/ModelFactory.php @@ -0,0 +1,33 @@ +define(App\User::class, function (Faker\Generator $faker) { + return [ + 'name' => $faker->name, + 'email' => $faker->safeEmail, + 'password' => bcrypt(str_random(10)), + 'remember_token' => str_random(10), + ]; +}); + +$factory->define(\App\Article\Post::class, function (Faker\Generator $faker) { + $body = $faker->paragraphs(3, true); + return [ + 'published_at' => $faker->dateTimeBetween('-6 years', '+2 weeks'), + 'slug' => $faker->slug, + 'title' => $faker->sentence, + 'description' => $faker->paragraph, + 'markdown' => $body, + 'html' => $body, + ]; +}); diff --git a/database/migrations/.gitkeep b/database/migrations/.gitkeep index e69de29..8b13789 100644 --- a/database/migrations/.gitkeep +++ b/database/migrations/.gitkeep @@ -0,0 +1 @@ + diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index 36a1db9..59aa01a 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -3,34 +3,32 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; -class CreateUsersTable extends Migration { - - /** - * Run the migrations. - * - * @return void - */ - public function up() - { - Schema::create('users', function(Blueprint $table) - { - $table->increments('id'); - $table->string('name'); - $table->string('email')->unique(); - $table->string('password', 60); - $table->rememberToken(); - $table->timestamps(); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('users'); - } +class CreateUsersTable extends Migration +{ + /** + * Run the migrations. + * + * @return void + */ + public function up() + { + Schema::create('users', function (Blueprint $table) { + $table->increments('id'); + $table->string('name'); + $table->string('email')->unique(); + $table->string('password'); + $table->rememberToken(); + $table->timestamps(); + }); + } + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('users'); + } } diff --git a/database/migrations/2014_10_12_100000_create_password_resets_table.php b/database/migrations/2014_10_12_100000_create_password_resets_table.php index 679df38..00057f9 100644 --- a/database/migrations/2014_10_12_100000_create_password_resets_table.php +++ b/database/migrations/2014_10_12_100000_create_password_resets_table.php @@ -3,31 +3,29 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; -class CreatePasswordResetsTable extends Migration { - - /** - * Run the migrations. - * - * @return void - */ - public function up() - { - Schema::create('password_resets', function(Blueprint $table) - { - $table->string('email')->index(); - $table->string('token')->index(); - $table->timestamp('created_at'); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('password_resets'); - } +class CreatePasswordResetsTable extends Migration +{ + /** + * Run the migrations. + * + * @return void + */ + public function up() + { + Schema::create('password_resets', function (Blueprint $table) { + $table->string('email')->index(); + $table->string('token')->index(); + $table->timestamp('created_at'); + }); + } + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('password_resets'); + } } diff --git a/database/migrations/2016_03_23_051921_create_posts_table.php b/database/migrations/2016_03_23_051921_create_posts_table.php new file mode 100644 index 0000000..1db5136 --- /dev/null +++ b/database/migrations/2016_03_23_051921_create_posts_table.php @@ -0,0 +1,42 @@ +increments('id'); + $table->integer('user_id')->unsigned(); + $table->enum('type', ['page', 'post'])->default('page'); + $table->string('slug'); + $table->string('title'); + $table->text('description'); + $table->text('markdown'); + $table->text('html'); + $table->boolean('is_html')->default(true); + $table->string('template'); + $table->dateTime('published_at')->nullable(); + $table->dateTime('updated_at')->nullable(); + + $table->unique('slug'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('posts'); + } +} diff --git a/database/migrations/2016_03_23_051924_create_categories_table.php b/database/migrations/2016_03_23_051924_create_categories_table.php new file mode 100644 index 0000000..8b2316f --- /dev/null +++ b/database/migrations/2016_03_23_051924_create_categories_table.php @@ -0,0 +1,31 @@ +primary('slug'); + $table->string('slug'); + $table->string('name'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('categories'); + } +} diff --git a/database/migrations/2016_03_23_052426_category_posts_table.php b/database/migrations/2016_03_23_052426_category_posts_table.php new file mode 100644 index 0000000..33bfd3c --- /dev/null +++ b/database/migrations/2016_03_23_052426_category_posts_table.php @@ -0,0 +1,31 @@ +string('category_id'); + $table->integer('post_id')->unsigned(); + $table->primary(['post_id', 'category_id']); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('category_posts'); + } +} diff --git a/database/seeds/.gitkeep b/database/seeds/.gitkeep index e69de29..8b13789 100644 --- a/database/seeds/.gitkeep +++ b/database/seeds/.gitkeep @@ -0,0 +1 @@ + diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index b3c69b5..bbe2d03 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -1,20 +1,24 @@ call('UserTableSeeder'); - } +class DatabaseSeeder extends Seeder +{ + /** + * Run the database seeds. + * + * @return void + */ + public function run() + { + factory(App\User::class)->create([ + 'name' => 'Logan Bailey', + 'email' => 'logan@logansbailey.com', + 'password' => password_hash('password', PASSWORD_DEFAULT), + ])->each(function (App\User $user) { + factory(\App\Article\Post::class)->times(50)->create([ + 'user_id' => $user->id + ]); + }); + } } diff --git a/database/seeds/PostSeeder.php b/database/seeds/PostSeeder.php deleted file mode 100644 index 9257b18..0000000 --- a/database/seeds/PostSeeder.php +++ /dev/null @@ -1,72 +0,0 @@ -faker = \Faker\Factory::create(); - $this->dm = $this->container[DocumentManager::class]; - $this->converter = $this->container[Markdown::class]; - - foreach($this->faker->words(15) as $categoryName) { - $this->categories[] = new Category($categoryName); - } - - foreach(range(0, 100000) as $count) { - echo 'Creating post ' . $count . PHP_EOL; - $this->dm->persist($this->createPost($count)); - - if ($count % 1000) { - $this->dm->flush(); - $this->dm->clear(); - } - } - - $this->dm->flush(); - } - - public function createPost($count) - { - $post = new Post(); - $post->update( - $this->faker->catchPhrase, - implode("\n", $this->faker->sentences(3)), - implode("\n", $this->faker->paragraphs(3)), - $this->converter - ); - - $post->setSlug(Str::slug($post->getTitle()) ."-b-{$count}"); - $post->publish($this->faker->dateTimeBetween('-5 years', 'now')); - - foreach(range(0, rand(1, 4)) as $size) { - $categories = $this->categories; - shuffle($categories); - $categories = array_slice($categories, 0, $size); - foreach($categories as $category) { - $post->addCategory($category); - } - } - - return $post; - } -} diff --git a/gulpfile.js b/gulpfile.js index 7cf6267..dc6f1eb 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -6,11 +6,11 @@ var elixir = require('laravel-elixir'); |-------------------------------------------------------------------------- | | Elixir provides a clean, fluent API for defining some basic Gulp tasks - | for your Laravel application. By default, we are compiling the Less + | for your Laravel application. By default, we are compiling the Sass | file for our application, as well as publishing vendor resources. | */ elixir(function(mix) { - mix.less('app.less'); + mix.sass('app.scss'); }); diff --git a/package.json b/package.json index f45052a..460ee90 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,10 @@ { + "private": true, "devDependencies": { - "gulp": "^3.8.8", - "laravel-elixir": "*" + "gulp": "^3.8.8" + }, + "dependencies": { + "laravel-elixir": "^4.0.0", + "bootstrap-sass": "^3.0.0" } } diff --git a/phpspec.yml b/phpspec.yml deleted file mode 100644 index eb57939..0000000 --- a/phpspec.yml +++ /dev/null @@ -1,5 +0,0 @@ -suites: - main: - namespace: App - psr4_prefix: App - src_path: app \ No newline at end of file diff --git a/phpunit.xml b/phpunit.xml index 08522be..cc0841c 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -7,16 +7,21 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="false" - syntaxCheck="false"> + stopOnFailure="false"> ./tests/ + + + app/ + + + diff --git a/public/.htaccess b/public/.htaccess index 77827ae..903f639 100644 --- a/public/.htaccess +++ b/public/.htaccess @@ -5,11 +5,16 @@ RewriteEngine On - # Redirect Trailing Slashes... + # Redirect Trailing Slashes If Not A Folder... + RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)/$ /$1 [L,R=301] # Handle Front Controller... RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] + + # Handle Authorization Header + RewriteCond %{HTTP:Authorization} . + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] diff --git a/readme.md b/readme.md index a4d8d55..98f4daa 100644 --- a/readme.md +++ b/readme.md @@ -1,23 +1,9 @@ -## Laravel PHP Framework +# OpenPub V2 -[![Build Status](https://travis-ci.org/laravel/framework.svg)](https://travis-ci.org/laravel/framework) -[![Total Downloads](https://poser.pugx.org/laravel/framework/downloads.svg)](https://packagist.org/packages/laravel/framework) -[![Latest Stable Version](https://poser.pugx.org/laravel/framework/v/stable.svg)](https://packagist.org/packages/laravel/framework) -[![Latest Unstable Version](https://poser.pugx.org/laravel/framework/v/unstable.svg)](https://packagist.org/packages/laravel/framework) -[![License](https://poser.pugx.org/laravel/framework/license.svg)](https://packagist.org/packages/laravel/framework) +OpenPub is a markdown based blogging system. -Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable, creative experience to be truly fulfilling. Laravel attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as authentication, routing, sessions, queueing, and caching. - -Laravel is accessible, yet powerful, providing powerful tools needed for large, robust applications. A superb inversion of control container, expressive migration system, and tightly integrated unit testing support give you the tools you need to build any application with which you are tasked. - -## Official Documentation - -Documentation for the framework can be found on the [Laravel website](http://laravel.com/docs). - -## Contributing - -Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](http://laravel.com/docs/contributions). - -### License - -The Laravel framework is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT) +The original version of OpenPub was too experimental in the way it +handled everything. This made the code base difficult if not unpleasant +to work with. My goal of OpenPub 2 is to continue developing of an +easy and expendable blogging platform, but to build features that won't +inhibit adoption and future development. \ No newline at end of file diff --git a/resources/assets/less/app.less b/resources/assets/less/app.less deleted file mode 100644 index 99be076..0000000 --- a/resources/assets/less/app.less +++ /dev/null @@ -1,8 +0,0 @@ -@import "bootstrap/bootstrap"; - -@btn-font-weight: 300; -@font-family-sans-serif: "Roboto", Helvetica, Arial, sans-serif; - -body, label, .checkbox label { - font-weight: 300; -} diff --git a/resources/assets/less/bootstrap/alerts.less b/resources/assets/less/bootstrap/alerts.less deleted file mode 100755 index df070b8..0000000 --- a/resources/assets/less/bootstrap/alerts.less +++ /dev/null @@ -1,68 +0,0 @@ -// -// Alerts -// -------------------------------------------------- - - -// Base styles -// ------------------------- - -.alert { - padding: @alert-padding; - margin-bottom: @line-height-computed; - border: 1px solid transparent; - border-radius: @alert-border-radius; - - // Headings for larger alerts - h4 { - margin-top: 0; - // Specified for the h4 to prevent conflicts of changing @headings-color - color: inherit; - } - // Provide class for links that match alerts - .alert-link { - font-weight: @alert-link-font-weight; - } - - // Improve alignment and spacing of inner content - > p, - > ul { - margin-bottom: 0; - } - > p + p { - margin-top: 5px; - } -} - -// Dismissible alerts -// -// Expand the right padding and account for the close button's positioning. - -.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0. -.alert-dismissible { - padding-right: (@alert-padding + 20); - - // Adjust close link position - .close { - position: relative; - top: -2px; - right: -21px; - color: inherit; - } -} - -// Alternate styles -// -// Generate contextual modifier classes for colorizing the alert. - -.alert-success { - .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text); -} -.alert-info { - .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text); -} -.alert-warning { - .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text); -} -.alert-danger { - .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text); -} diff --git a/resources/assets/less/bootstrap/badges.less b/resources/assets/less/bootstrap/badges.less deleted file mode 100755 index b27c405..0000000 --- a/resources/assets/less/bootstrap/badges.less +++ /dev/null @@ -1,61 +0,0 @@ -// -// Badges -// -------------------------------------------------- - - -// Base class -.badge { - display: inline-block; - min-width: 10px; - padding: 3px 7px; - font-size: @font-size-small; - font-weight: @badge-font-weight; - color: @badge-color; - line-height: @badge-line-height; - vertical-align: baseline; - white-space: nowrap; - text-align: center; - background-color: @badge-bg; - border-radius: @badge-border-radius; - - // Empty badges collapse automatically (not available in IE8) - &:empty { - display: none; - } - - // Quick fix for badges in buttons - .btn & { - position: relative; - top: -1px; - } - .btn-xs & { - top: 0; - padding: 1px 5px; - } - - // Hover state, but only for links - a& { - &:hover, - &:focus { - color: @badge-link-hover-color; - text-decoration: none; - cursor: pointer; - } - } - - // Account for badges in navs - .list-group-item.active > &, - .nav-pills > .active > a > & { - color: @badge-active-color; - background-color: @badge-active-bg; - } - .list-group-item > & { - float: right; - } - .list-group-item > & + & { - margin-right: 5px; - } - .nav-pills > li > a > & { - margin-left: 3px; - } -} diff --git a/resources/assets/less/bootstrap/bootstrap.less b/resources/assets/less/bootstrap/bootstrap.less deleted file mode 100755 index 61b7747..0000000 --- a/resources/assets/less/bootstrap/bootstrap.less +++ /dev/null @@ -1,50 +0,0 @@ -// Core variables and mixins -@import "variables.less"; -@import "mixins.less"; - -// Reset and dependencies -@import "normalize.less"; -@import "print.less"; -@import "glyphicons.less"; - -// Core CSS -@import "scaffolding.less"; -@import "type.less"; -@import "code.less"; -@import "grid.less"; -@import "tables.less"; -@import "forms.less"; -@import "buttons.less"; - -// Components -@import "component-animations.less"; -@import "dropdowns.less"; -@import "button-groups.less"; -@import "input-groups.less"; -@import "navs.less"; -@import "navbar.less"; -@import "breadcrumbs.less"; -@import "pagination.less"; -@import "pager.less"; -@import "labels.less"; -@import "badges.less"; -@import "jumbotron.less"; -@import "thumbnails.less"; -@import "alerts.less"; -@import "progress-bars.less"; -@import "media.less"; -@import "list-group.less"; -@import "panels.less"; -@import "responsive-embed.less"; -@import "wells.less"; -@import "close.less"; - -// Components w/ JavaScript -@import "modals.less"; -@import "tooltip.less"; -@import "popovers.less"; -@import "carousel.less"; - -// Utility classes -@import "utilities.less"; -@import "responsive-utilities.less"; diff --git a/resources/assets/less/bootstrap/breadcrumbs.less b/resources/assets/less/bootstrap/breadcrumbs.less deleted file mode 100755 index cb01d50..0000000 --- a/resources/assets/less/bootstrap/breadcrumbs.less +++ /dev/null @@ -1,26 +0,0 @@ -// -// Breadcrumbs -// -------------------------------------------------- - - -.breadcrumb { - padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal; - margin-bottom: @line-height-computed; - list-style: none; - background-color: @breadcrumb-bg; - border-radius: @border-radius-base; - - > li { - display: inline-block; - - + li:before { - content: "@{breadcrumb-separator}\00a0"; // Unicode space added since inline-block means non-collapsing white-space - padding: 0 5px; - color: @breadcrumb-color; - } - } - - > .active { - color: @breadcrumb-active-color; - } -} diff --git a/resources/assets/less/bootstrap/button-groups.less b/resources/assets/less/bootstrap/button-groups.less deleted file mode 100755 index f84febb..0000000 --- a/resources/assets/less/bootstrap/button-groups.less +++ /dev/null @@ -1,243 +0,0 @@ -// -// Button groups -// -------------------------------------------------- - -// Make the div behave like a button -.btn-group, -.btn-group-vertical { - position: relative; - display: inline-block; - vertical-align: middle; // match .btn alignment given font-size hack above - > .btn { - position: relative; - float: left; - // Bring the "active" button to the front - &:hover, - &:focus, - &:active, - &.active { - z-index: 2; - } - } -} - -// Prevent double borders when buttons are next to each other -.btn-group { - .btn + .btn, - .btn + .btn-group, - .btn-group + .btn, - .btn-group + .btn-group { - margin-left: -1px; - } -} - -// Optional: Group multiple button groups together for a toolbar -.btn-toolbar { - margin-left: -5px; // Offset the first child's margin - &:extend(.clearfix all); - - .btn-group, - .input-group { - float: left; - } - > .btn, - > .btn-group, - > .input-group { - margin-left: 5px; - } -} - -.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { - border-radius: 0; -} - -// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match -.btn-group > .btn:first-child { - margin-left: 0; - &:not(:last-child):not(.dropdown-toggle) { - .border-right-radius(0); - } -} -// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it -.btn-group > .btn:last-child:not(:first-child), -.btn-group > .dropdown-toggle:not(:first-child) { - .border-left-radius(0); -} - -// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group) -.btn-group > .btn-group { - float: left; -} -.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { - border-radius: 0; -} -.btn-group > .btn-group:first-child { - > .btn:last-child, - > .dropdown-toggle { - .border-right-radius(0); - } -} -.btn-group > .btn-group:last-child > .btn:first-child { - .border-left-radius(0); -} - -// On active and open, don't show outline -.btn-group .dropdown-toggle:active, -.btn-group.open .dropdown-toggle { - outline: 0; -} - - -// Sizing -// -// Remix the default button sizing classes into new ones for easier manipulation. - -.btn-group-xs > .btn { &:extend(.btn-xs); } -.btn-group-sm > .btn { &:extend(.btn-sm); } -.btn-group-lg > .btn { &:extend(.btn-lg); } - - -// Split button dropdowns -// ---------------------- - -// Give the line between buttons some depth -.btn-group > .btn + .dropdown-toggle { - padding-left: 8px; - padding-right: 8px; -} -.btn-group > .btn-lg + .dropdown-toggle { - padding-left: 12px; - padding-right: 12px; -} - -// The clickable button for toggling the menu -// Remove the gradient and set the same inset shadow as the :active state -.btn-group.open .dropdown-toggle { - .box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); - - // Show no shadow for `.btn-link` since it has no other button styles. - &.btn-link { - .box-shadow(none); - } -} - - -// Reposition the caret -.btn .caret { - margin-left: 0; -} -// Carets in other button sizes -.btn-lg .caret { - border-width: @caret-width-large @caret-width-large 0; - border-bottom-width: 0; -} -// Upside down carets for .dropup -.dropup .btn-lg .caret { - border-width: 0 @caret-width-large @caret-width-large; -} - - -// Vertical button groups -// ---------------------- - -.btn-group-vertical { - > .btn, - > .btn-group, - > .btn-group > .btn { - display: block; - float: none; - width: 100%; - max-width: 100%; - } - - // Clear floats so dropdown menus can be properly placed - > .btn-group { - &:extend(.clearfix all); - > .btn { - float: none; - } - } - - > .btn + .btn, - > .btn + .btn-group, - > .btn-group + .btn, - > .btn-group + .btn-group { - margin-top: -1px; - margin-left: 0; - } -} - -.btn-group-vertical > .btn { - &:not(:first-child):not(:last-child) { - border-radius: 0; - } - &:first-child:not(:last-child) { - border-top-right-radius: @border-radius-base; - .border-bottom-radius(0); - } - &:last-child:not(:first-child) { - border-bottom-left-radius: @border-radius-base; - .border-top-radius(0); - } -} -.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { - border-radius: 0; -} -.btn-group-vertical > .btn-group:first-child:not(:last-child) { - > .btn:last-child, - > .dropdown-toggle { - .border-bottom-radius(0); - } -} -.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { - .border-top-radius(0); -} - - -// Justified button groups -// ---------------------- - -.btn-group-justified { - display: table; - width: 100%; - table-layout: fixed; - border-collapse: separate; - > .btn, - > .btn-group { - float: none; - display: table-cell; - width: 1%; - } - > .btn-group .btn { - width: 100%; - } - - > .btn-group .dropdown-menu { - left: auto; - } -} - - -// Checkbox and radio options -// -// In order to support the browser's form validation feedback, powered by the -// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use -// `display: none;` or `visibility: hidden;` as that also hides the popover. -// Simply visually hiding the inputs via `opacity` would leave them clickable in -// certain cases which is prevented by using `clip` and `pointer-events`. -// This way, we ensure a DOM element is visible to position the popover from. -// -// See https://github.com/twbs/bootstrap/pull/12794 and -// https://github.com/twbs/bootstrap/pull/14559 for more information. - -[data-toggle="buttons"] { - > .btn, - > .btn-group > .btn { - input[type="radio"], - input[type="checkbox"] { - position: absolute; - clip: rect(0,0,0,0); - pointer-events: none; - } - } -} diff --git a/resources/assets/less/bootstrap/buttons.less b/resources/assets/less/bootstrap/buttons.less deleted file mode 100755 index 40553c6..0000000 --- a/resources/assets/less/bootstrap/buttons.less +++ /dev/null @@ -1,160 +0,0 @@ -// -// Buttons -// -------------------------------------------------- - - -// Base styles -// -------------------------------------------------- - -.btn { - display: inline-block; - margin-bottom: 0; // For input.btn - font-weight: @btn-font-weight; - text-align: center; - vertical-align: middle; - touch-action: manipulation; - cursor: pointer; - background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 - border: 1px solid transparent; - white-space: nowrap; - .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @border-radius-base); - .user-select(none); - - &, - &:active, - &.active { - &:focus, - &.focus { - .tab-focus(); - } - } - - &:hover, - &:focus, - &.focus { - color: @btn-default-color; - text-decoration: none; - } - - &:active, - &.active { - outline: 0; - background-image: none; - .box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); - } - - &.disabled, - &[disabled], - fieldset[disabled] & { - cursor: @cursor-disabled; - pointer-events: none; // Future-proof disabling of clicks - .opacity(.65); - .box-shadow(none); - } -} - - -// Alternate buttons -// -------------------------------------------------- - -.btn-default { - .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border); -} -.btn-primary { - .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border); -} -// Success appears as green -.btn-success { - .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border); -} -// Info appears as blue-green -.btn-info { - .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border); -} -// Warning appears as orange -.btn-warning { - .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border); -} -// Danger and error appear as red -.btn-danger { - .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border); -} - - -// Link buttons -// ------------------------- - -// Make a button look and behave like a link -.btn-link { - color: @link-color; - font-weight: normal; - border-radius: 0; - - &, - &:active, - &.active, - &[disabled], - fieldset[disabled] & { - background-color: transparent; - .box-shadow(none); - } - &, - &:hover, - &:focus, - &:active { - border-color: transparent; - } - &:hover, - &:focus { - color: @link-hover-color; - text-decoration: underline; - background-color: transparent; - } - &[disabled], - fieldset[disabled] & { - &:hover, - &:focus { - color: @btn-link-disabled-color; - text-decoration: none; - } - } -} - - -// Button Sizes -// -------------------------------------------------- - -.btn-lg { - // line-height: ensure even-numbered height of button next to large input - .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large); -} -.btn-sm { - // line-height: ensure proper height of button next to small input - .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small); -} -.btn-xs { - .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @border-radius-small); -} - - -// Block button -// -------------------------------------------------- - -.btn-block { - display: block; - width: 100%; -} - -// Vertically space out multiple block buttons -.btn-block + .btn-block { - margin-top: 5px; -} - -// Specificity overrides -input[type="submit"], -input[type="reset"], -input[type="button"] { - &.btn-block { - width: 100%; - } -} diff --git a/resources/assets/less/bootstrap/carousel.less b/resources/assets/less/bootstrap/carousel.less deleted file mode 100755 index 5724d8a..0000000 --- a/resources/assets/less/bootstrap/carousel.less +++ /dev/null @@ -1,267 +0,0 @@ -// -// Carousel -// -------------------------------------------------- - - -// Wrapper for the slide container and indicators -.carousel { - position: relative; -} - -.carousel-inner { - position: relative; - overflow: hidden; - width: 100%; - - > .item { - display: none; - position: relative; - .transition(.6s ease-in-out left); - - // Account for jankitude on images - > img, - > a > img { - &:extend(.img-responsive); - line-height: 1; - } - - // WebKit CSS3 transforms for supported devices - @media all and (transform-3d), (-webkit-transform-3d) { - transition: transform .6s ease-in-out; - backface-visibility: hidden; - perspective: 1000; - - &.next, - &.active.right { - transform: translate3d(100%, 0, 0); - left: 0; - } - &.prev, - &.active.left { - transform: translate3d(-100%, 0, 0); - left: 0; - } - &.next.left, - &.prev.right, - &.active { - transform: translate3d(0, 0, 0); - left: 0; - } - } - } - - > .active, - > .next, - > .prev { - display: block; - } - - > .active { - left: 0; - } - - > .next, - > .prev { - position: absolute; - top: 0; - width: 100%; - } - - > .next { - left: 100%; - } - > .prev { - left: -100%; - } - > .next.left, - > .prev.right { - left: 0; - } - - > .active.left { - left: -100%; - } - > .active.right { - left: 100%; - } - -} - -// Left/right controls for nav -// --------------------------- - -.carousel-control { - position: absolute; - top: 0; - left: 0; - bottom: 0; - width: @carousel-control-width; - .opacity(@carousel-control-opacity); - font-size: @carousel-control-font-size; - color: @carousel-control-color; - text-align: center; - text-shadow: @carousel-text-shadow; - // We can't have this transition here because WebKit cancels the carousel - // animation if you trip this while in the middle of another animation. - - // Set gradients for backgrounds - &.left { - #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001)); - } - &.right { - left: auto; - right: 0; - #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5)); - } - - // Hover/focus state - &:hover, - &:focus { - outline: 0; - color: @carousel-control-color; - text-decoration: none; - .opacity(.9); - } - - // Toggles - .icon-prev, - .icon-next, - .glyphicon-chevron-left, - .glyphicon-chevron-right { - position: absolute; - top: 50%; - z-index: 5; - display: inline-block; - } - .icon-prev, - .glyphicon-chevron-left { - left: 50%; - margin-left: -10px; - } - .icon-next, - .glyphicon-chevron-right { - right: 50%; - margin-right: -10px; - } - .icon-prev, - .icon-next { - width: 20px; - height: 20px; - margin-top: -10px; - font-family: serif; - } - - - .icon-prev { - &:before { - content: '\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039) - } - } - .icon-next { - &:before { - content: '\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A) - } - } -} - -// Optional indicator pips -// -// Add an unordered list with the following class and add a list item for each -// slide your carousel holds. - -.carousel-indicators { - position: absolute; - bottom: 10px; - left: 50%; - z-index: 15; - width: 60%; - margin-left: -30%; - padding-left: 0; - list-style: none; - text-align: center; - - li { - display: inline-block; - width: 10px; - height: 10px; - margin: 1px; - text-indent: -999px; - border: 1px solid @carousel-indicator-border-color; - border-radius: 10px; - cursor: pointer; - - // IE8-9 hack for event handling - // - // Internet Explorer 8-9 does not support clicks on elements without a set - // `background-color`. We cannot use `filter` since that's not viewed as a - // background color by the browser. Thus, a hack is needed. - // - // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we - // set alpha transparency for the best results possible. - background-color: #000 \9; // IE8 - background-color: rgba(0,0,0,0); // IE9 - } - .active { - margin: 0; - width: 12px; - height: 12px; - background-color: @carousel-indicator-active-bg; - } -} - -// Optional captions -// ----------------------------- -// Hidden by default for smaller viewports -.carousel-caption { - position: absolute; - left: 15%; - right: 15%; - bottom: 20px; - z-index: 10; - padding-top: 20px; - padding-bottom: 20px; - color: @carousel-caption-color; - text-align: center; - text-shadow: @carousel-text-shadow; - & .btn { - text-shadow: none; // No shadow for button elements in carousel-caption - } -} - - -// Scale up controls for tablets and up -@media screen and (min-width: @screen-sm-min) { - - // Scale up the controls a smidge - .carousel-control { - .glyphicon-chevron-left, - .glyphicon-chevron-right, - .icon-prev, - .icon-next { - width: 30px; - height: 30px; - margin-top: -15px; - font-size: 30px; - } - .glyphicon-chevron-left, - .icon-prev { - margin-left: -15px; - } - .glyphicon-chevron-right, - .icon-next { - margin-right: -15px; - } - } - - // Show and left align the captions - .carousel-caption { - left: 20%; - right: 20%; - padding-bottom: 30px; - } - - // Move up the indicators - .carousel-indicators { - bottom: 20px; - } -} diff --git a/resources/assets/less/bootstrap/close.less b/resources/assets/less/bootstrap/close.less deleted file mode 100755 index 9b4e74f..0000000 --- a/resources/assets/less/bootstrap/close.less +++ /dev/null @@ -1,33 +0,0 @@ -// -// Close icons -// -------------------------------------------------- - - -.close { - float: right; - font-size: (@font-size-base * 1.5); - font-weight: @close-font-weight; - line-height: 1; - color: @close-color; - text-shadow: @close-text-shadow; - .opacity(.2); - - &:hover, - &:focus { - color: @close-color; - text-decoration: none; - cursor: pointer; - .opacity(.5); - } - - // Additional properties for button version - // iOS requires the button element instead of an anchor tag. - // If you want the anchor version, it requires `href="#"`. - button& { - padding: 0; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; - } -} diff --git a/resources/assets/less/bootstrap/code.less b/resources/assets/less/bootstrap/code.less deleted file mode 100755 index a08b4d4..0000000 --- a/resources/assets/less/bootstrap/code.less +++ /dev/null @@ -1,69 +0,0 @@ -// -// Code (inline and block) -// -------------------------------------------------- - - -// Inline and block code styles -code, -kbd, -pre, -samp { - font-family: @font-family-monospace; -} - -// Inline code -code { - padding: 2px 4px; - font-size: 90%; - color: @code-color; - background-color: @code-bg; - border-radius: @border-radius-base; -} - -// User input typically entered via keyboard -kbd { - padding: 2px 4px; - font-size: 90%; - color: @kbd-color; - background-color: @kbd-bg; - border-radius: @border-radius-small; - box-shadow: inset 0 -1px 0 rgba(0,0,0,.25); - - kbd { - padding: 0; - font-size: 100%; - font-weight: bold; - box-shadow: none; - } -} - -// Blocks of code -pre { - display: block; - padding: ((@line-height-computed - 1) / 2); - margin: 0 0 (@line-height-computed / 2); - font-size: (@font-size-base - 1); // 14px to 13px - line-height: @line-height-base; - word-break: break-all; - word-wrap: break-word; - color: @pre-color; - background-color: @pre-bg; - border: 1px solid @pre-border-color; - border-radius: @border-radius-base; - - // Account for some code outputs that place code tags in pre tags - code { - padding: 0; - font-size: inherit; - color: inherit; - white-space: pre-wrap; - background-color: transparent; - border-radius: 0; - } -} - -// Enable scrollable blocks of code -.pre-scrollable { - max-height: @pre-scrollable-max-height; - overflow-y: scroll; -} diff --git a/resources/assets/less/bootstrap/component-animations.less b/resources/assets/less/bootstrap/component-animations.less deleted file mode 100755 index 967715d..0000000 --- a/resources/assets/less/bootstrap/component-animations.less +++ /dev/null @@ -1,34 +0,0 @@ -// -// Component animations -// -------------------------------------------------- - -// Heads up! -// -// We don't use the `.opacity()` mixin here since it causes a bug with text -// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552. - -.fade { - opacity: 0; - .transition(opacity .15s linear); - &.in { - opacity: 1; - } -} - -.collapse { - display: none; - visibility: hidden; - - &.in { display: block; visibility: visible; } - tr&.in { display: table-row; } - tbody&.in { display: table-row-group; } -} - -.collapsing { - position: relative; - height: 0; - overflow: hidden; - .transition-property(~"height, visibility"); - .transition-duration(.35s); - .transition-timing-function(ease); -} diff --git a/resources/assets/less/bootstrap/dropdowns.less b/resources/assets/less/bootstrap/dropdowns.less deleted file mode 100755 index 84a48c1..0000000 --- a/resources/assets/less/bootstrap/dropdowns.less +++ /dev/null @@ -1,213 +0,0 @@ -// -// Dropdown menus -// -------------------------------------------------- - - -// Dropdown arrow/caret -.caret { - display: inline-block; - width: 0; - height: 0; - margin-left: 2px; - vertical-align: middle; - border-top: @caret-width-base solid; - border-right: @caret-width-base solid transparent; - border-left: @caret-width-base solid transparent; -} - -// The dropdown wrapper (div) -.dropdown { - position: relative; -} - -// Prevent the focus on the dropdown toggle when closing dropdowns -.dropdown-toggle:focus { - outline: 0; -} - -// The dropdown menu (ul) -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: @zindex-dropdown; - display: none; // none by default, but block on "open" of the menu - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; // override default ul - list-style: none; - font-size: @font-size-base; - text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer) - background-color: @dropdown-bg; - border: 1px solid @dropdown-fallback-border; // IE8 fallback - border: 1px solid @dropdown-border; - border-radius: @border-radius-base; - .box-shadow(0 6px 12px rgba(0,0,0,.175)); - background-clip: padding-box; - - // Aligns the dropdown menu to right - // - // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]` - &.pull-right { - right: 0; - left: auto; - } - - // Dividers (basically an hr) within the dropdown - .divider { - .nav-divider(@dropdown-divider-bg); - } - - // Links within the dropdown menu - > li > a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: @line-height-base; - color: @dropdown-link-color; - white-space: nowrap; // prevent links from randomly breaking onto new lines - } -} - -// Hover/Focus state -.dropdown-menu > li > a { - &:hover, - &:focus { - text-decoration: none; - color: @dropdown-link-hover-color; - background-color: @dropdown-link-hover-bg; - } -} - -// Active state -.dropdown-menu > .active > a { - &, - &:hover, - &:focus { - color: @dropdown-link-active-color; - text-decoration: none; - outline: 0; - background-color: @dropdown-link-active-bg; - } -} - -// Disabled state -// -// Gray out text and ensure the hover/focus state remains gray - -.dropdown-menu > .disabled > a { - &, - &:hover, - &:focus { - color: @dropdown-link-disabled-color; - } - - // Nuke hover/focus effects - &:hover, - &:focus { - text-decoration: none; - background-color: transparent; - background-image: none; // Remove CSS gradient - .reset-filter(); - cursor: @cursor-disabled; - } -} - -// Open state for the dropdown -.open { - // Show the menu - > .dropdown-menu { - display: block; - } - - // Remove the outline when :focus is triggered - > a { - outline: 0; - } -} - -// Menu positioning -// -// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown -// menu with the parent. -.dropdown-menu-right { - left: auto; // Reset the default from `.dropdown-menu` - right: 0; -} -// With v3, we enabled auto-flipping if you have a dropdown within a right -// aligned nav component. To enable the undoing of that, we provide an override -// to restore the default dropdown menu alignment. -// -// This is only for left-aligning a dropdown menu within a `.navbar-right` or -// `.pull-right` nav component. -.dropdown-menu-left { - left: 0; - right: auto; -} - -// Dropdown section headers -.dropdown-header { - display: block; - padding: 3px 20px; - font-size: @font-size-small; - line-height: @line-height-base; - color: @dropdown-header-color; - white-space: nowrap; // as with > li > a -} - -// Backdrop to catch body clicks on mobile, etc. -.dropdown-backdrop { - position: fixed; - left: 0; - right: 0; - bottom: 0; - top: 0; - z-index: (@zindex-dropdown - 10); -} - -// Right aligned dropdowns -.pull-right > .dropdown-menu { - right: 0; - left: auto; -} - -// Allow for dropdowns to go bottom up (aka, dropup-menu) -// -// Just add .dropup after the standard .dropdown class and you're set, bro. -// TODO: abstract this so that the navbar fixed styles are not placed here? - -.dropup, -.navbar-fixed-bottom .dropdown { - // Reverse the caret - .caret { - border-top: 0; - border-bottom: @caret-width-base solid; - content: ""; - } - // Different positioning for bottom up menu - .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 1px; - } -} - - -// Component alignment -// -// Reiterate per navbar.less and the modified component alignment there. - -@media (min-width: @grid-float-breakpoint) { - .navbar-right { - .dropdown-menu { - .dropdown-menu-right(); - } - // Necessary for overrides of the default right aligned menu. - // Will remove come v4 in all likelihood. - .dropdown-menu-left { - .dropdown-menu-left(); - } - } -} diff --git a/resources/assets/less/bootstrap/forms.less b/resources/assets/less/bootstrap/forms.less deleted file mode 100755 index 1bcc2b6..0000000 --- a/resources/assets/less/bootstrap/forms.less +++ /dev/null @@ -1,546 +0,0 @@ -// -// Forms -// -------------------------------------------------- - - -// Normalize non-controls -// -// Restyle and baseline non-control form elements. - -fieldset { - padding: 0; - margin: 0; - border: 0; - // Chrome and Firefox set a `min-width: min-content;` on fieldsets, - // so we reset that to ensure it behaves more like a standard block element. - // See https://github.com/twbs/bootstrap/issues/12359. - min-width: 0; -} - -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: @line-height-computed; - font-size: (@font-size-base * 1.5); - line-height: inherit; - color: @legend-color; - border: 0; - border-bottom: 1px solid @legend-border-color; -} - -label { - display: inline-block; - max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141) - margin-bottom: 5px; - font-weight: bold; -} - - -// Normalize form controls -// -// While most of our form styles require extra classes, some basic normalization -// is required to ensure optimum display with or without those classes to better -// address browser inconsistencies. - -// Override content-box in Normalize (* isn't specific enough) -input[type="search"] { - .box-sizing(border-box); -} - -// Position radios and checkboxes better -input[type="radio"], -input[type="checkbox"] { - margin: 4px 0 0; - margin-top: 1px \9; // IE8-9 - line-height: normal; -} - -// Set the height of file controls to match text inputs -input[type="file"] { - display: block; -} - -// Make range inputs behave like textual form controls -input[type="range"] { - display: block; - width: 100%; -} - -// Make multiple select elements height not fixed -select[multiple], -select[size] { - height: auto; -} - -// Focus for file, radio, and checkbox -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - .tab-focus(); -} - -// Adjust output element -output { - display: block; - padding-top: (@padding-base-vertical + 1); - font-size: @font-size-base; - line-height: @line-height-base; - color: @input-color; -} - - -// Common form controls -// -// Shared size and type resets for form controls. Apply `.form-control` to any -// of the following form controls: -// -// select -// textarea -// input[type="text"] -// input[type="password"] -// input[type="datetime"] -// input[type="datetime-local"] -// input[type="date"] -// input[type="month"] -// input[type="time"] -// input[type="week"] -// input[type="number"] -// input[type="email"] -// input[type="url"] -// input[type="search"] -// input[type="tel"] -// input[type="color"] - -.form-control { - display: block; - width: 100%; - height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border) - padding: @padding-base-vertical @padding-base-horizontal; - font-size: @font-size-base; - line-height: @line-height-base; - color: @input-color; - background-color: @input-bg; - background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 - border: 1px solid @input-border; - border-radius: @input-border-radius; - .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); - .transition(~"border-color ease-in-out .15s, box-shadow ease-in-out .15s"); - - // Customize the `:focus` state to imitate native WebKit styles. - .form-control-focus(); - - // Placeholder - .placeholder(); - - // Disabled and read-only inputs - // - // HTML5 says that controls under a fieldset > legend:first-child won't be - // disabled if the fieldset is disabled. Due to implementation difficulty, we - // don't honor that edge case; we style them as disabled anyway. - &[disabled], - &[readonly], - fieldset[disabled] & { - cursor: @cursor-disabled; - background-color: @input-bg-disabled; - opacity: 1; // iOS fix for unreadable disabled content - } - - // Reset height for `textarea`s - textarea& { - height: auto; - } -} - - -// Search inputs in iOS -// -// This overrides the extra rounded corners on search inputs in iOS so that our -// `.form-control` class can properly style them. Note that this cannot simply -// be added to `.form-control` as it's not specific enough. For details, see -// https://github.com/twbs/bootstrap/issues/11586. - -input[type="search"] { - -webkit-appearance: none; -} - - -// Special styles for iOS temporal inputs -// -// In Mobile Safari, setting `display: block` on temporal inputs causes the -// text within the input to become vertically misaligned. As a workaround, we -// set a pixel line-height that matches the given height of the input, but only -// for Safari. - -@media screen and (-webkit-min-device-pixel-ratio: 0) { - input[type="date"], - input[type="time"], - input[type="datetime-local"], - input[type="month"] { - line-height: @input-height-base; - } - input[type="date"].input-sm, - input[type="time"].input-sm, - input[type="datetime-local"].input-sm, - input[type="month"].input-sm { - line-height: @input-height-small; - } - input[type="date"].input-lg, - input[type="time"].input-lg, - input[type="datetime-local"].input-lg, - input[type="month"].input-lg { - line-height: @input-height-large; - } -} - - -// Form groups -// -// Designed to help with the organization and spacing of vertical forms. For -// horizontal forms, use the predefined grid classes. - -.form-group { - margin-bottom: 15px; -} - - -// Checkboxes and radios -// -// Indent the labels to position radios/checkboxes as hanging controls. - -.radio, -.checkbox { - position: relative; - display: block; - margin-top: 10px; - margin-bottom: 10px; - - label { - min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text - padding-left: 20px; - margin-bottom: 0; - font-weight: normal; - cursor: pointer; - } -} -.radio input[type="radio"], -.radio-inline input[type="radio"], -.checkbox input[type="checkbox"], -.checkbox-inline input[type="checkbox"] { - position: absolute; - margin-left: -20px; - margin-top: 4px \9; -} - -.radio + .radio, -.checkbox + .checkbox { - margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing -} - -// Radios and checkboxes on same line -.radio-inline, -.checkbox-inline { - display: inline-block; - padding-left: 20px; - margin-bottom: 0; - vertical-align: middle; - font-weight: normal; - cursor: pointer; -} -.radio-inline + .radio-inline, -.checkbox-inline + .checkbox-inline { - margin-top: 0; - margin-left: 10px; // space out consecutive inline controls -} - -// Apply same disabled cursor tweak as for inputs -// Some special care is needed because