Test Failed
Pull Request — master (#494)
by
unknown
03:32
created

PostRepository   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 73
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 30
dl 0
loc 73
rs 10
c 0
b 0
f 0
wmc 8

8 Methods

Rating   Name   Duplication   Size   Complexity  
A fullPostPage() 0 11 1
A findBySlug() 0 6 1
A save() 0 3 1
A getMaxUpdatedAt() 0 5 1
A __construct() 0 3 1
A findByTag() 0 7 1
A prepareDataReader() 0 5 1
A findAllPreloaded() 0 6 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Modules\Blog\Post;
6
7
use App\Modules\Blog\Entity\Post;
8
use Cycle\ORM\Select;
9
use DateTimeImmutable;
10
use DateTimeInterface;
11
use Throwable;
12
use Yiisoft\Data\Reader\DataReaderInterface;
13
use Yiisoft\Data\Reader\Sort;
14
use Yiisoft\Yii\Cycle\Data\Reader\EntityReader;
15
use Yiisoft\Yii\Cycle\Data\Writer\EntityWriter;
16
17
final class PostRepository extends Select\Repository
18
{
19
    public function __construct(private EntityWriter $entityWriter, Select $select)
20
    {
21
        parent::__construct($select);
22
    }
23
24
    /**
25
     * Get posts without filter with preloaded Users and Tags
26
     *
27
     * @psalm-return DataReaderInterface<int, Post>
28
     */
29
    public function findAllPreloaded(): DataReaderInterface
30
    {
31
        $query = $this
32
            ->select()
33
            ->load(['user', 'tags']);
34
        return $this->prepareDataReader($query);
35
    }
36
37
    /**
38
     * @psalm-return DataReaderInterface<int, Post>
39
     */
40
    public function findByTag($tagId): DataReaderInterface
41
    {
42
        $query = $this
43
            ->select()
44
            ->where(['tags.id' => $tagId])
45
            ->load('user', ['method' => Select::SINGLE_QUERY]);
46
        return $this->prepareDataReader($query);
47
    }
48
49
    public function fullPostPage(string $slug): ?Post
50
    {
51
        $query = $this
52
            ->select()
53
            ->where(['slug' => $slug])
54
            ->load('user', ['method' => Select::SINGLE_QUERY])
55
            ->load(['tags'])
56
            // force loading in single query with comments
57
            ->load('comments.user', ['method' => Select::SINGLE_QUERY])
58
            ->load('comments', ['method' => Select::OUTER_QUERY]);
59
        return  $query->fetchOne();
60
    }
61
62
    public function getMaxUpdatedAt(): DateTimeInterface
63
    {
64
        return new DateTimeImmutable($this
65
                ->select()
66
                ->max('updated_at') ?? 'now');
67
    }
68
69
    public function findBySlug(string $slug): ?Post
70
    {
71
        return $this
72
            ->select()
73
            ->where(['slug' => $slug])
74
            ->fetchOne();
75
    }
76
77
    /**
78
     * @throws Throwable
79
     */
80
    public function save(Post $post): void
81
    {
82
        $this->entityWriter->write([$post]);
83
    }
84
85
    private function prepareDataReader($query): EntityReader
86
    {
87
        return (new EntityReader($query))->withSort(
88
            Sort::only(['id', 'title', 'public', 'updated_at', 'published_at', 'user_id'])
89
                ->withOrder(['published_at' => 'desc'])
90
        );
91
    }
92
}
93