Passed
Push — master ( 3e7efc...fe1a66 )
by Alexander
01:49
created

Repository::aggregateMax()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php declare(strict_types=1);
2
3
namespace Indigerd\Repository;
4
5
use Indigerd\Hydrator\Hydrator;
6
use Indigerd\Hydrator\Strategy\ObjectStrategy;
7
use Indigerd\Repository\Exception\InsertException;
8
use Indigerd\Repository\Exception\InvalidModelClassException;
9
use Indigerd\Repository\Exception\NotFoundException;
10
use Indigerd\Repository\Relation\Relation;
11
use Indigerd\Repository\Relation\RelationCollection;
12
use Indigerd\Repository\TableGateway\TableGatewayInterface;
13
14
class Repository implements RepositoryInterface
15
{
16
    protected $tableGateway;
17
18
    protected $hydrator;
19
20
    protected $modelClass;
21
22
    protected $relationCollection;
23
24 17
    public function __construct(
25
        TableGatewayInterface $tableGateway,
26
        Hydrator $hydrator,
27
        string $modelClass,
28
        RelationCollection $relationCollection = null
29
    ) {
30 17
        $this->tableGateway = $tableGateway;
31 17
        $this->hydrator = $hydrator;
32 17
        $this->modelClass = $modelClass;
33 17
        $this->relationCollection = $relationCollection;
34 17
    }
35
36 1
    protected function getRelation($name): Relation
37
    {
38 1
        if (\is_null($this->relationCollection)) {
39
            throw new \InvalidArgumentException("Relation $name do not exist");
40
        }
41 1
        $relation = $this->relationCollection->getRelationByProperty($name);
42 1
        if (!($relation instanceof Relation)) {
43
            throw new \InvalidArgumentException("Relation $name do not exist");
44
        }
45 1
        return $relation;
46
    }
47
48 1
    protected function normalizeResultSet(array $data, array $relations): array
49
    {
50
        /**
51
         * @var string $property
52
         * @var Relation $relation
53
         */
54 1
        foreach ($relations as $property => $relation) {
55 1
            $relationData = [];
56 1
            foreach ($data as $field => $value) {
57 1
                if (\strpos($field, $relation->getRelatedCollection() . '_relation_') === 0) {
58
                    $fieldName = \str_replace($relation->getRelatedCollection() . '_relation_', '', $field);
59 1
                    $relationData[$fieldName] = $value;
60
                }
61
            }
62 1
            $data[$property] = $relationData;
63
        }
64 1
        return $data;
65
    }
66
67 1
    protected function applyRelationStrategies(array $relations)
68
    {
69
        /**
70
         * @var string $property
71
         * @var Relation $relation
72
         */
73 1
        foreach ($relations as $property => $relation) {
74 1
            $this->hydrator->addStrategy($property, new ObjectStrategy($this->hydrator, $relation->getRelatedModel()));
75
        }
76 1
    }
77
78 2
    public function findOne(array $conditions = [], array $with = []): object
79
    {
80 2
        $relations = [];
81 2
        foreach ($with as $relationName) {
82 1
            $relations[$relationName] = $this->getRelation($relationName);
83
        }
84 2
        $data = $this->tableGateway->queryOne($conditions, $relations);
85 2
        if (!\is_array($data)) {
86 1
            throw new NotFoundException();
87
        }
88 1
        if (!empty($relations)) {
89 1
            $data = $this->normalizeResultSet($data, $relations);
90 1
            $this->applyRelationStrategies($relations);
91
        }
92 1
        $result = $this->hydrator->hydrate($this->modelClass, $data);
93 1
        return $result;
94
    }
95
96 1
    public function findAll(array $conditions = [], array $order = [], int $limit = 0, int $offset = 0, array $with = []): array
97
    {
98 1
        $result = [];
99 1
        $relations = [];
100 1
        foreach ($with as $relationName) {
101
            $relations[$relationName] = $this->getRelation($relationName);
102
        }
103 1
        if (!empty($relations)) {
104
            $this->applyRelationStrategies($relations);
105
        }
106 1
        $data = $this->tableGateway->queryAll($conditions, $order, $limit, $offset, $relations);
107 1
        foreach ($data as $row) {
108 1
            if (!empty($relations)) {
109
                $row = $this->normalizeResultSet($row, $relations);
110
            }
111 1
            $result[] = $this->hydrator->hydrate($this->modelClass, $row);
112
        }
113 1
        return $result;
114
    }
115
116 1
    public function aggregate(string $expression, array $conditions): string
117
    {
118 1
        return $this->tableGateway->aggregate($expression, $conditions);
119
    }
120
121 1
    public function aggregateCount(string $field = '', array $conditions = []): string
122
    {
123 1
        return $this->tableGateway->aggregateCount($field, $conditions);
124
    }
125
126 1
    public function aggregateSum(string $field, array $conditions): string
127
    {
128 1
        return $this->tableGateway->aggregateSum($field, $conditions);
129
    }
130
131 1
    public function aggregateAverage(string $field, array $conditions): string
132
    {
133 1
        return $this->tableGateway->aggregateAverage($field, $conditions);
134
    }
135
136 1
    public function aggregateMin(string $field, array $conditions): string
137
    {
138 1
        return $this->tableGateway->aggregateMin($field, $conditions);
139
    }
140
141 1
    public function aggregateMax(string $field, array $conditions): string
142
    {
143 1
        return $this->tableGateway->aggregateMax($field, $conditions);
144
    }
145
146 4
    protected function validateModelClass(object $model)
147
    {
148 4
        if (!($model instanceof $this->modelClass)) {
149 1
            throw new InvalidModelClassException('Invalid model class: ' . get_class($model) . '. Expected ' . $this->modelClass);
150
        }
151 3
    }
152
153 1
    public function insert(object $model): void
154
    {
155 1
        $this->validateModelClass($model);
156 1
        $data = $this->hydrator->extract($model);
157 1
        $primaryKeys = $this->tableGateway->insert($data);
158 1
        if (!\is_array($primaryKeys)) {
159
            throw new InsertException($data);
160
        }
161 1
        $this->hydrator->hydrate($model, $primaryKeys);
162 1
    }
163
164 1
    public function update(object $model): void
165
    {
166 1
        $this->validateModelClass($model);
167 1
        $data = $this->hydrator->extract($model);
168 1
        $this->tableGateway->updateOne($data);
169 1
    }
170
171 2
    public function delete(object $model): void
172
    {
173 2
        $this->validateModelClass($model);
174 1
        $data = $this->hydrator->extract($model);
175 1
        $this->tableGateway->deleteOne($data);
176 1
    }
177
178 1
    public function updateAll(array $data, array $conditions): int
179
    {
180 1
        return $this->tableGateway->updateAll($data, $conditions);
181
    }
182
183 1
    public function deleteAll(array $conditions): int
184
    {
185 1
        return $this->tableGateway->deleteAll($conditions);
186
    }
187
188
    /**
189
     * @param array $data
190
     * @return object
191
     */
192 1
    public function create(array $data = []): object
193
    {
194 1
        return $this->hydrator->hydrate($this->modelClass, $data);
195
    }
196
197
    /**
198
     * @param object $entity
199
     * @param array $data
200
     */
201 1
    public function populate(object $entity, array $data): void
202
    {
203 1
        $this->hydrator->hydrate($entity, $data);
204 1
    }
205
}
206