Passed
Push — master ( 5047e3...b9f250 )
by Peter
02:23
created

PageCategorySqlDataMapper::getBaseQuery()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 10
nc 1
nop 0
dl 0
loc 15
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Website\Orm\DataMappers;
6
7
use AbterPhp\Admin\Domain\Entities\UserGroup;
8
use AbterPhp\Framework\Orm\DataMappers\IdGeneratorUserTrait;
9
use AbterPhp\Website\Domain\Entities\PageCategory;
10
use AbterPhp\Website\Domain\Entities\PageCategory as Entity;
11
use Opulence\Orm\DataMappers\SqlDataMapper;
12
use Opulence\QueryBuilders\MySql\QueryBuilder;
13
use Opulence\QueryBuilders\MySql\SelectQuery;
14
15
class PageCategorySqlDataMapper extends SqlDataMapper implements IPageCategoryDataMapper
16
{
17
    const USER_GROUP_IDS = 'user_group_ids';
18
19
    use IdGeneratorUserTrait;
20
21
    /**
22
     * @param Entity $entity
23
     */
24
    public function add($entity)
25
    {
26
        if (!($entity instanceof Entity)) {
0 ignored issues
show
introduced by
$entity is always a sub-type of AbterPhp\Website\Domain\Entities\PageCategory.
Loading history...
27
            throw new \InvalidArgumentException(__CLASS__ . ':' . __FUNCTION__ . ' expects a Page Category entity.');
28
        }
29
30
        $data  = $this->getColumnNamesToValues($entity, true);
31
        $query = (new QueryBuilder())->insert('page_categories', $data);
32
33
        $sql    = $query->getSql();
34
        $params = $query->getParameters();
35
36
        $statement = $this->writeConnection->prepare($sql);
37
        $statement->bindValues($params);
38
        $statement->execute();
39
40
        $this->addUserGroups($entity);
41
    }
42
43
    /**
44
     * @param Entity $entity
45
     */
46
    public function delete($entity)
47
    {
48
        if (!($entity instanceof Entity)) {
0 ignored issues
show
introduced by
$entity is always a sub-type of AbterPhp\Website\Domain\Entities\PageCategory.
Loading history...
49
            throw new \InvalidArgumentException(__CLASS__ . ':' . __FUNCTION__ . ' expects a Page Category entity.');
50
        }
51
52
        $query = (new QueryBuilder())
53
            ->update('page_categories', 'page_categories', ['deleted' => [1, \PDO::PARAM_INT]])
54
            ->where('id = ?')
55
            ->addUnnamedPlaceholderValue($entity->getId(), \PDO::PARAM_STR);
56
57
        $sql    = $query->getSql();
58
        $params = $query->getParameters();
59
60
        $statement = $this->writeConnection->prepare($sql);
61
        $statement->bindValues($params);
62
        $statement->execute();
63
64
        $this->deleteUserGroups($entity);
65
    }
66
67
    /**
68
     * @return Entity[]
69
     */
70
    public function getAll(): array
71
    {
72
        $query = $this->getBaseQuery();
73
74
        return $this->read($query->getSql(), [], self::VALUE_TYPE_ARRAY);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->read($quer...self::VALUE_TYPE_ARRAY) could return the type null which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
75
    }
76
77
    /**
78
     * @param int      $limitFrom
79
     * @param int      $pageSize
80
     * @param string[] $orders
81
     * @param array    $conditions
82
     * @param array    $params
83
     *
84
     * @return Entity[]
85
     */
86
    public function getPage(int $limitFrom, int $pageSize, array $orders, array $conditions, array $params): array
87
    {
88
        $query = $this->getBaseQuery()
89
            ->limit($pageSize)
90
            ->offset($limitFrom);
91
92
        foreach ($orders as $order) {
93
            $query->addOrderBy($order);
94
        }
95
96
        foreach ($conditions as $condition) {
97
            $query->andWhere($condition);
98
        }
99
100
        $replaceCount = 1;
101
102
        $sql = $query->getSql();
103
        $sql = str_replace('SELECT', 'SELECT SQL_CALC_FOUND_ROWS', $sql, $replaceCount);
104
105
        return $this->read($sql, $params, self::VALUE_TYPE_ARRAY);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->read($sql,...self::VALUE_TYPE_ARRAY) could return the type null which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
106
    }
107
108
    /**
109
     * @param int|string $id
110
     *
111
     * @return Entity|null
112
     */
113
    public function getById($id)
114
    {
115
        $query = $this->getBaseQuery()->andWhere('pc.id = :category_id');
116
117
        $sql    = $query->getSql();
118
        $params = [
119
            'category_id' => [$id, \PDO::PARAM_STR],
120
        ];
121
122
123
        return $this->read($sql, $params, self::VALUE_TYPE_ENTITY, true);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->read($sql,...ALUE_TYPE_ENTITY, true) also could return the type array which is incompatible with the documented return type AbterPhp\Website\Domain\Entities\PageCategory|null.
Loading history...
124
    }
125
126
    /**
127
     * @param string $identifier
128
     *
129
     * @return Entity|null
130
     * @throws \Opulence\Orm\OrmException
131
     */
132
    public function getByIdentifier(string $identifier): ?Entity
133
    {
134
        $query = $this->getBaseQuery()->andWhere('identifier = :identifier');
135
136
        $sql    = $query->getSql();
137
        $params = [
138
            'identifier' => $identifier,
139
        ];
140
141
        return $this->read($sql, $params, self::VALUE_TYPE_ENTITY, true);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->read($sql,...ALUE_TYPE_ENTITY, true) could return the type array which is incompatible with the type-hinted return AbterPhp\Website\Domain\Entities\PageCategory|null. Consider adding an additional type-check to rule them out.
Loading history...
142
    }
143
144
    /**
145
     * @param Entity $entity
146
     */
147
    public function update($entity)
148
    {
149
        if (!($entity instanceof Entity)) {
0 ignored issues
show
introduced by
$entity is always a sub-type of AbterPhp\Website\Domain\Entities\PageCategory.
Loading history...
150
            throw new \InvalidArgumentException(__CLASS__ . ':' . __FUNCTION__ . ' expects a Page Category entity.');
151
        }
152
153
        $columnNamesToValues = $this->getColumnNamesToValues($entity, false);
154
155
        $query = (new QueryBuilder())
156
            ->update('page_categories', 'page_categories', $columnNamesToValues)
157
            ->where('id = ?')
158
            ->andWhere('deleted = 0')
159
            ->addUnnamedPlaceholderValue($entity->getId(), \PDO::PARAM_STR);
160
161
        $sql    = $query->getSql();
162
        $params = $query->getParameters();
163
164
        $statement = $this->writeConnection->prepare($sql);
165
        $statement->bindValues($params);
166
        $statement->execute();
167
168
        $this->deleteUserGroups($entity);
169
        $this->addUserGroups($entity);
170
    }
171
172
    /**
173
     * @param Entity $entity
174
     * @param bool   $create
175
     *
176
     * @return array
177
     */
178
    protected function getColumnNamesToValues(Entity $entity, bool $create): array
179
    {
180
        $columnNamesToValues = [
181
            'name'       => [$entity->getName(), \PDO::PARAM_STR],
182
            'identifier' => [$entity->getIdentifier(), \PDO::PARAM_STR],
183
        ];
184
185
        if ($create) {
186
            $columnNamesToValues = array_merge(['id' => [$entity->getId(), \PDO::PARAM_STR]], $columnNamesToValues);
187
        }
188
189
        return $columnNamesToValues;
190
    }
191
192
    /**
193
     * @param PageCategory $entity
194
     */
195
    protected function deleteUserGroups(Entity $entity)
196
    {
197
        $query = (new QueryBuilder())
198
            ->delete('user_groups_page_categories')
199
            ->where('page_category_id = ?')
200
            ->addUnnamedPlaceholderValue($entity->getId(), \PDO::PARAM_STR);
201
202
        $sql = $query->getSql();
203
204
        $statement = $this->writeConnection->prepare($sql);
205
        $statement->bindValues($query->getParameters());
206
        $statement->execute();
207
    }
208
209
    /**
210
     * @param Entity $entity
211
     */
212
    protected function addUserGroups(Entity $entity)
213
    {
214
        $idGenerator = $this->getIdGenerator();
215
216
        foreach ($entity->getUserGroups() as $userGroup) {
217
            $query = (new QueryBuilder())
218
                ->insert(
219
                    'user_groups_page_categories',
220
                    [
221
                        'id'               => [$idGenerator->generate($userGroup), \PDO::PARAM_STR],
222
                        'user_group_id'    => [$userGroup->getId(), \PDO::PARAM_STR],
223
                        'page_category_id' => [$entity->getId(), \PDO::PARAM_STR],
224
                    ]
225
                );
226
227
            $sql = $query->getSql();
228
229
            $statement = $this->writeConnection->prepare($sql);
230
            $statement->bindValues($query->getParameters());
231
            $statement->execute();
232
        }
233
    }
234
235
    /**
236
     * @param array $hash
237
     *
238
     * @return Entity
239
     */
240
    protected function loadEntity(array $hash)
241
    {
242
        $userGroups = $this->getUserGroups($hash);
243
244
        return new Entity(
245
            $hash['id'],
246
            $hash['name'],
247
            $hash['identifier'],
248
            $userGroups
249
        );
250
    }
251
252
    /**
253
     * @param array $hash
254
     *
255
     * @return array
256
     */
257
    private function getUserGroups(array $hash): array
258
    {
259
        if (empty($hash[static::USER_GROUP_IDS])) {
260
            return [];
261
        }
262
263
        if (is_array($hash[static::USER_GROUP_IDS])) {
264
            return $hash[static::USER_GROUP_IDS];
265
        }
266
267
        $userGroups = [];
268
        foreach (explode(',', $hash[static::USER_GROUP_IDS]) as $id) {
269
            $userGroups[] = new UserGroup((string)$id, '', '');
270
        }
271
272
        return $userGroups;
273
    }
274
275
    /**
276
     * @return SelectQuery
277
     */
278
    private function getBaseQuery()
279
    {
280
        /** @var SelectQuery $query */
281
        $query = (new QueryBuilder())
282
            ->select(
283
                'pc.id',
284
                'pc.name',
285
                'pc.identifier',
286
                'GROUP_CONCAT(ugpc.user_group_id) AS user_group_ids'
287
            )
288
            ->from('page_categories', 'pc')
289
            ->leftJoin('user_groups_page_categories', 'ugpc', 'ugpc.page_category_id = pc.id')
290
            ->where('pc.deleted = 0');
291
292
        return $query;
293
    }
294
}
295