Skip to content

Commit dce1717

Browse files
committed
author page, left sidebar added in templates
1 parent 8473b88 commit dce1717

29 files changed

Lines changed: 470 additions & 88 deletions

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@
6060
},
6161
"autoload-dev": {
6262
"psr-4": {
63-
"LightTest\\Unit\\": "test/Unit/"
63+
"LightTest\\Unit\\": "test/Unit/",
64+
"LightTest\\Common\\": "test/Common/"
6465
}
6566
},
6667
"scripts": {

src/App/src/ConfigProvider.php

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Doctrine\ORM\EntityManager;
88
use Doctrine\ORM\EntityManagerInterface;
9+
use Doctrine\ORM\Mapping\EntityListenerResolver as EntityListenerResolverInterface;
910
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
1011
use Doctrine\Persistence\Mapping\Driver\MappingDriverChain;
1112
use Dot\Cache\Adapter\ArrayAdapter;
@@ -40,6 +41,7 @@
4041
* },
4142
* configuration: array{
4243
* orm_default: array{
44+
* entity_listener_resolver: class-string<EntityListenerResolverInterface>,
4345
* result_cache: non-empty-string,
4446
* metadata_cache: non-empty-string,
4547
* query_cache: non-empty-string,
@@ -149,13 +151,12 @@ private function getDoctrineConfig(): array
149151
],
150152
'configuration' => [
151153
'orm_default' => [
152-
'entity_listener_resolver' => EntityListenerResolver::class,
153-
'result_cache' => 'filesystem',
154-
'metadata_cache' => 'filesystem',
155-
'query_cache' => 'filesystem',
156-
'hydration_cache' => 'array',
157-
'typed_field_mapper' => null,
158-
'second_level_cache' => [
154+
'result_cache' => 'filesystem',
155+
'metadata_cache' => 'filesystem',
156+
'query_cache' => 'filesystem',
157+
'hydration_cache' => 'array',
158+
'typed_field_mapper' => null,
159+
'second_level_cache' => [
159160
'enabled' => true,
160161
'default_lifetime' => 3600,
161162
'default_lock_lifetime' => 60,

src/Blog/src/ConfigProvider.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,20 @@
66

77
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
88
use Light\Blog\DBAL\Types\PostStatusEnumType;
9+
use Light\Blog\Factory\Author\AuthorResourceHandlerFactory;
10+
use Light\Blog\Factory\Author\AuthorResourceRepositoryFactory;
911
use Light\Blog\Factory\Category\CategoryCollectionHandlerFactory;
1012
use Light\Blog\Factory\Category\CategoryCollectionRepositoryFactory;
1113
use Light\Blog\Factory\Category\CategoryResourceHandlerFactory;
1214
use Light\Blog\Factory\Post\PostCollectionHandlerFactory;
1315
use Light\Blog\Factory\Post\PostCollectionRepositoryFactory;
1416
use Light\Blog\Factory\Post\PostResourceHandlerFactory;
17+
use Light\Blog\Handler\GetAuthorResourceHandler;
1518
use Light\Blog\Handler\GetCategoryCollectionHandler;
1619
use Light\Blog\Handler\GetCategoryResourceHandler;
1720
use Light\Blog\Handler\GetPostCollectionHandler;
1821
use Light\Blog\Handler\GetPostResourceHandler;
22+
use Light\Blog\Repository\AuthorRepository;
1923
use Light\Blog\Repository\CategoryRepository;
2024
use Light\Blog\Repository\PostRepository;
2125
use Mezzio\Application;
@@ -58,6 +62,8 @@ private function getDependencies(): array
5862
PostRepository::class => PostCollectionRepositoryFactory::class,
5963
GetPostResourceHandler::class => PostResourceHandlerFactory::class,
6064
GetCategoryResourceHandler::class => CategoryResourceHandlerFactory::class,
65+
AuthorRepository::class => AuthorResourceRepositoryFactory::class,
66+
GetAuthorResourceHandler::class => AuthorResourceHandlerFactory::class,
6167
],
6268
];
6369
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Light\Blog\Factory\Author;
6+
7+
use Light\Blog\Handler\GetAuthorResourceHandler;
8+
use Light\Blog\Repository\AuthorRepository;
9+
use Light\Blog\Repository\CategoryRepository;
10+
use Light\Blog\Repository\PostRepository;
11+
use Mezzio\Template\TemplateRendererInterface;
12+
use Psr\Container\ContainerExceptionInterface;
13+
use Psr\Container\ContainerInterface;
14+
use Psr\Container\NotFoundExceptionInterface;
15+
16+
use function assert;
17+
18+
class AuthorResourceHandlerFactory
19+
{
20+
/**
21+
* @throws ContainerExceptionInterface
22+
* @throws NotFoundExceptionInterface
23+
*/
24+
public function __invoke(ContainerInterface $container, string $requestedName): GetAuthorResourceHandler
25+
{
26+
$repository = $container->get(AuthorRepository::class);
27+
$template = $container->get(TemplateRendererInterface::class);
28+
$postRepository = $container->get(PostRepository::class);
29+
$categoryRepository = $container->get(CategoryRepository::class);
30+
31+
assert($repository instanceof AuthorRepository);
32+
assert($template instanceof TemplateRendererInterface);
33+
assert($postRepository instanceof PostRepository);
34+
35+
return new GetAuthorResourceHandler($template, $repository, $postRepository, $categoryRepository);
36+
}
37+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Light\Blog\Factory\Author;
6+
7+
use Doctrine\ORM\EntityManager;
8+
use Light\Blog\Entity\Author;
9+
use Light\Blog\Repository\AuthorRepository;
10+
use Psr\Container\ContainerExceptionInterface;
11+
use Psr\Container\ContainerInterface;
12+
use Psr\Container\NotFoundExceptionInterface;
13+
14+
use function assert;
15+
16+
class AuthorResourceRepositoryFactory
17+
{
18+
/**
19+
* @throws ContainerExceptionInterface
20+
* @throws NotFoundExceptionInterface
21+
*/
22+
public function __invoke(ContainerInterface $container): AuthorRepository
23+
{
24+
$entityManager = $container->get(EntityManager::class);
25+
26+
$repository = $entityManager->getRepository(Author::class);
27+
assert($repository instanceof AuthorRepository);
28+
29+
return $repository;
30+
}
31+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Light\Blog\Handler;
6+
7+
use Laminas\Diactoros\Response\HtmlResponse;
8+
use Light\App\Helper\Paginator;
9+
use Light\Blog\Repository\AuthorRepository;
10+
use Light\Blog\Repository\CategoryRepository;
11+
use Light\Blog\Repository\PostRepository;
12+
use Mezzio\Template\TemplateRendererInterface;
13+
use Psr\Http\Message\ResponseInterface;
14+
use Psr\Http\Message\ServerRequestInterface;
15+
use Psr\Http\Server\RequestHandlerInterface;
16+
17+
class GetAuthorResourceHandler implements RequestHandlerInterface
18+
{
19+
public function __construct(
20+
protected TemplateRendererInterface $template,
21+
protected AuthorRepository $authorRepository,
22+
protected PostRepository $postRepository,
23+
protected CategoryRepository $categoryRepository,
24+
) {
25+
}
26+
27+
public function handle(ServerRequestInterface $request): ResponseInterface
28+
{
29+
$authorSlug = $request->getAttribute('slug');
30+
$author = $this->authorRepository->getAuthorResource($authorSlug);
31+
$categories = $this->categoryRepository->getCategories();
32+
if (! $author) {
33+
return new HtmlResponse('Author not found', 404);
34+
}
35+
36+
$queryParams = $request->getQueryParams();
37+
$params = Paginator::getParams($queryParams, 'posts.postDate');
38+
$data = Paginator::wrapper(
39+
$this->postRepository->getArticleByAuthor($author, $params),
40+
$params
41+
);
42+
$authorPost = $this->postRepository->getArticleByAuthor($author, $params);
43+
44+
return new HtmlResponse(
45+
$this->template->render('page::author-resource', [
46+
'author' => $author,
47+
'categories' => $categories,
48+
'data' => $data,
49+
])
50+
);
51+
}
52+
}

src/Blog/src/Handler/GetCategoryResourceHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface
2727
return new HtmlResponse('Category not found', 404);
2828
}
2929
$categories = $this->categoryRepository->getCategories();
30-
$categoryArticles = $this->categoryRepository->getCategoryArticles($category);
30+
$categoryArticles = $this->categoryRepository->getCategoryPost($category);
3131
return new HtmlResponse(
3232
$this->template->render('page::category-resource', [
3333
'categories' => $categories,

src/Blog/src/Repository/AuthorRepository.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,23 @@ class AuthorRepository extends AbstractRepository
1212
/**
1313
* @return array<Author>
1414
*/
15-
public function getCategories(): array
15+
public function getAuthor(): array
1616
{
1717
$qb = $this->getQueryBuilder()
18-
->select('authors.name, authors.slug')
18+
->select('author.name, author.slug')
1919
->from(Author::class, 'authors');
2020

2121
return $qb->getQuery()->getResult();
2222
}
23+
24+
public function getAuthorResource(string $slug): ?Author
25+
{
26+
$qb = $this->getQueryBuilder()
27+
->select('author')
28+
->from(Author::class, 'author')
29+
->where('author.slug = :slug')
30+
->setParameter('slug', $slug);
31+
32+
return $qb->getQuery()->getOneOrNullResult();
33+
}
2334
}

src/Blog/src/Repository/CategoryRepository.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ public function getCategories(): array
1818
{
1919
$qb = $this->getQueryBuilder()
2020
->select('categories.name, categories.slug')
21-
->from(Category::class, 'categories');
22-
21+
->from(Category::class, 'categories')
22+
->where('categories.isVisible = :visible')
23+
->setParameter('visible', true);
2324
return $qb->getQuery()->getResult();
2425
}
2526

@@ -37,13 +38,14 @@ public function getCategoryResource(string $slug): ?Category
3738
/**
3839
* @return array<Post>
3940
*/
40-
public function getCategoryArticles(Category $category): array
41+
public function getCategoryPost(Category $category): array
4142
{
4243
$qb = $this->getQueryBuilder()
4344
->select('articles')
4445
->from(Post::class, 'articles')
4546
->where('articles.category = :category')
4647
->andWhere('articles.status = :published')
48+
->orderBy('articles.postDate', 'DESC')
4749
->setParameter('published', PostStatusEnum::Published)
4850
->setParameter('category', $category);
4951

src/Blog/src/Repository/PostRepository.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Doctrine\ORM\Tools\Pagination\Paginator as DoctrinePaginator;
88
use Light\App\Repository\AbstractRepository;
9+
use Light\Blog\Entity\Author;
910
use Light\Blog\Entity\Post;
1011
use Light\Blog\Enum\PostStatusEnum;
1112

@@ -22,7 +23,7 @@ public function getArticles(array $params): DoctrinePaginator
2223
->leftJoin('articles.category', 'category')
2324
->where('articles.status = :published')
2425
->setParameter('published', PostStatusEnum::Published)
25-
->orderBy($params['sort'], $params['dir'])
26+
->orderBy('articles.postDate', $params['dir'])
2627
->setFirstResult($params['offset'])
2728
->setMaxResults($params['limit']);
2829

@@ -41,4 +42,21 @@ public function getArticleResource(string $slug): ?Post
4142

4243
return $qb->getQuery()->getOneOrNullResult();
4344
}
45+
46+
/**
47+
* @return Post[]
48+
*/
49+
public function getArticleByAuthor(Author $author, array $params): DoctrinePaginator
50+
{
51+
$qb = $this->getQueryBuilder()
52+
->select('posts')
53+
->from(Post::class, 'posts')
54+
->where('posts.author = :author')
55+
->setParameter('author', $author)
56+
->orderBy('posts.postDate', $params['dir'])
57+
->setFirstResult($params['offset'])
58+
->setMaxResults($params['limit']);
59+
60+
return new DoctrinePaginator($qb->getQuery());
61+
}
4462
}

0 commit comments

Comments
 (0)