ArchiveRepository::prepareDataReader()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Blog\Archive;
6
7
use App\Blog\Entity\Post;
8
use App\Blog\Post\PostRepository;
9
use Cycle\Database\DatabaseInterface;
0 ignored issues
show
Bug introduced by
The type Cycle\Database\DatabaseInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Cycle\Database\Driver\DriverInterface;
0 ignored issues
show
Bug introduced by
The type Cycle\Database\Driver\DriverInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Cycle\Database\Driver\SQLite\SQLiteDriver;
0 ignored issues
show
Bug introduced by
The type Cycle\Database\Driver\SQLite\SQLiteDriver was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Cycle\Database\Injection\Fragment;
0 ignored issues
show
Bug introduced by
The type Cycle\Database\Injection\Fragment was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use Cycle\Database\Injection\FragmentInterface;
0 ignored issues
show
Bug introduced by
The type Cycle\Database\Injection\FragmentInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use Cycle\Database\Query\SelectQuery;
0 ignored issues
show
Bug introduced by
The type Cycle\Database\Query\SelectQuery was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use Cycle\ORM\ORMInterface;
0 ignored issues
show
Bug introduced by
The type Cycle\ORM\ORMInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use Cycle\ORM\Select;
0 ignored issues
show
Bug introduced by
The type Cycle\ORM\Select was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use DateTimeImmutable;
18
use Yiisoft\Data\Cycle\Reader\EntityReader;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Data\Cycle\Reader\EntityReader was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use Yiisoft\Data\Reader\DataReaderInterface;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Data\Reader\DataReaderInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use Yiisoft\Data\Reader\Sort;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Data\Reader\Sort was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
22
/**
23
 * This repository is not associated with Post entity.
24
 */
25
final class ArchiveRepository
26
{
27
    private PostRepository $postRepo;
28
29
    public function __construct(ORMInterface $orm)
30
    {
31
        /** @var PostRepository $postRepo */
32
        $postRepo = $orm->getRepository(Post::class);
33
        $this->postRepo = $postRepo;
34
    }
35
36
    public function select(): Select
37
    {
38
        return $this->postRepo->select();
39
    }
40
41
    public function getMonthlyArchive(int $year, int $month): DataReaderInterface
42
    {
43
        $begin = (new DateTimeImmutable())
44
            ->setDate($year, $month, 1)
45
            ->setTime(0, 0, 0);
46
        $end = $begin
47
            ->setDate($year, $month + 1, 1)
48
            ->setTime(0, 0, -1);
49
50
        $query = $this
51
            ->select()
52
            ->andWhere('published_at', 'between', $begin, $end)
53
            ->load(['user', 'tags']);
54
55
        return $this->prepareDataReader($query);
56
    }
57
58
    public function getYearlyArchive(int $year): DataReaderInterface
59
    {
60
        $begin = (new DateTimeImmutable())
61
            ->setDate($year, 1, 1)
62
            ->setTime(0, 0, 0);
63
        $end = $begin
64
            ->setDate($year + 1, 1, 1)
65
            ->setTime(0, 0, -1);
66
67
        $query = $this
68
            ->select()
69
            ->andWhere('published_at', 'between', $begin, $end)
70
            ->load('user', ['method' => Select::SINGLE_QUERY])
71
            ->orderBy(['published_at' => 'asc']);
72
73
        return $this->prepareDataReader($query);
74
    }
75
76
    /**
77
     * @return DataReaderInterface Collection of Array('Count' => '123', 'Month' => '8', 'Year' => '2019') on read
78
     */
79
    public function getFullArchive(): DataReaderInterface
80
    {
81
        $sort = Sort::only(['year', 'month', 'count'])->withOrder(['year' => 'desc', 'month' => 'desc']);
82
83
        $query = $this
84
            ->select()
85
            ->buildQuery()
86
            ->columns([
87
                'count(post.id) count',
88
                $this->extractFromDateColumn('month'),
89
                $this->extractFromDateColumn('year'),
90
            ])
91
            ->groupBy('year, month');
92
93
        return (new EntityReader($query))->withSort($sort);
94
    }
95
96
    /**
97
     * @param string $attr Can be 'day', 'month' or 'year'
98
     *
99
     * @return FragmentInterface
100
     */
101
    private function extractFromDateColumn(string $attr): FragmentInterface
102
    {
103
        $driver = $this->getDriver();
104
        $wrappedField = $driver
105
            ->getQueryCompiler()
106
            ->quoteIdentifier($attr);
107
        if ($driver instanceof SQLiteDriver) {
108
            $str = ['year' => '%Y', 'month' => '%m', 'day' => '%d'][$attr];
109
110
            return new Fragment("strftime('$str', post.published_at) $wrappedField");
111
        }
112
113
        return new Fragment("extract($attr from post.published_at) $wrappedField");
114
    }
115
116
    private function getDriver(): DriverInterface
117
    {
118
        return $this
119
            ->select()
120
            ->getBuilder()
121
            ->getLoader()
122
            ->getSource()
123
            ->getDatabase()
124
            ->getDriver(DatabaseInterface::READ);
125
    }
126
127
    /**
128
     * @psalm-suppress UndefinedDocblockClass
129
     *
130
     * @param Select|SelectQuery $query
131
     *
132
     * @return EntityReader
133
     */
134
    private function prepareDataReader($query): EntityReader
135
    {
136
        return (new EntityReader($query))->withSort(Sort::only(['published_at'])->withOrder(['published_at' => 'desc']));
137
    }
138
}
139