Passed
Push — master ( e8e348...b64209 )
by Peter
02:18
created

PageCategorySqlDataMapper::deleteUserGroups()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 1
dl 0
loc 12
rs 10
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\Admin\Orm\DataMappers\IdGeneratorUserTrait;
9
use AbterPhp\Framework\Domain\Entities\IStringerEntity;
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
/** @phan-file-suppress PhanTypeMismatchArgument */
16
17
class PageCategorySqlDataMapper extends SqlDataMapper implements IPageCategoryDataMapper
18
{
19
    const USER_GROUP_IDS = 'user_group_ids';
20
21
    use IdGeneratorUserTrait;
22
23
    /**
24
     * @param IStringerEntity $entity
25
     */
26
    public function add($entity)
27
    {
28
        assert($entity instanceof Entity, new \InvalidArgumentException());
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 IStringerEntity $entity
45
     */
46
    public function delete($entity)
47
    {
48
        assert($entity instanceof Entity, new \InvalidArgumentException());
49
50
        $query = (new QueryBuilder())
51
            ->update('page_categories', 'page_categories', ['deleted' => [1, \PDO::PARAM_INT]])
52
            ->where('id = ?')
53
            ->addUnnamedPlaceholderValue($entity->getId(), \PDO::PARAM_STR);
54
55
        $sql    = $query->getSql();
56
        $params = $query->getParameters();
57
58
        $statement = $this->writeConnection->prepare($sql);
59
        $statement->bindValues($params);
60
        $statement->execute();
61
62
        $this->deleteUserGroups($entity);
63
    }
64
65
    /**
66
     * @return Entity[]
67
     */
68
    public function getAll(): array
69
    {
70
        $query = $this->getBaseQuery();
71
72
        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...
73
    }
74
75
    /**
76
     * @param int      $limitFrom
77
     * @param int      $pageSize
78
     * @param string[] $orders
79
     * @param array    $conditions
80
     * @param array    $params
81
     *
82
     * @return Entity[]
83
     */
84
    public function getPage(int $limitFrom, int $pageSize, array $orders, array $conditions, array $params): array
85
    {
86
        $query = $this->getBaseQuery()
87
            ->limit($pageSize)
88
            ->offset($limitFrom);
89
90
        foreach ($orders as $order) {
91
            $query->addOrderBy($order);
92
        }
93
94
        foreach ($conditions as $condition) {
95
            $query->andWhere($condition);
96
        }
97
98
        $replaceCount = 1;
99
100
        $sql = $query->getSql();
101
        $sql = str_replace('SELECT', 'SELECT SQL_CALC_FOUND_ROWS', $sql, $replaceCount);
102
103
        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...
104
    }
105
106
    /**
107
     * @param int|string $id
108
     *
109
     * @return Entity|null
110
     */
111
    public function getById($id)
112
    {
113
        $query = $this->getBaseQuery()->andWhere('pc.id = :category_id');
114
115
        $sql    = $query->getSql();
116
        $params = [
117
            'category_id' => [$id, \PDO::PARAM_STR],
118
        ];
119
120
121
        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...
122
    }
123
124
    /**
125
     * @param string $identifier
126
     *
127
     * @return Entity|null
128
     * @throws \Opulence\Orm\OrmException
129
     */
130
    public function getByIdentifier(string $identifier): ?Entity
131
    {
132
        $query = $this->getBaseQuery()->andWhere('identifier = :identifier');
133
134
        $sql    = $query->getSql();
135
        $params = [
136
            'identifier' => $identifier,
137
        ];
138
139
        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...
140
    }
141
142
    /**
143
     * @param IStringerEntity $entity
144
     */
145
    public function update($entity)
146
    {
147
        assert($entity instanceof Entity, new \InvalidArgumentException());
148
149
        $columnNamesToValues = $this->getColumnNamesToValues($entity, false);
150
151
        $query = (new QueryBuilder())
152
            ->update('page_categories', 'page_categories', $columnNamesToValues)
153
            ->where('id = ?')
154
            ->andWhere('deleted = 0')
155
            ->addUnnamedPlaceholderValue($entity->getId(), \PDO::PARAM_STR);
156
157
        $sql    = $query->getSql();
158
        $params = $query->getParameters();
159
160
        $statement = $this->writeConnection->prepare($sql);
161
        $statement->bindValues($params);
162
        $statement->execute();
163
164
        $this->deleteUserGroups($entity);
165
        $this->addUserGroups($entity);
166
    }
167
168
    /**
169
     * @param Entity $entity
170
     * @param bool   $create
171
     *
172
     * @return array
173
     */
174
    protected function getColumnNamesToValues(Entity $entity, bool $create): array
175
    {
176
        $columnNamesToValues = [
177
            'name'       => [$entity->getName(), \PDO::PARAM_STR],
178
            'identifier' => [$entity->getIdentifier(), \PDO::PARAM_STR],
179
        ];
180
181
        if ($create) {
182
            $columnNamesToValues = array_merge(['id' => [$entity->getId(), \PDO::PARAM_STR]], $columnNamesToValues);
183
        }
184
185
        return $columnNamesToValues;
186
    }
187
188
    /**
189
     * @param Entity $entity
190
     */
191
    protected function deleteUserGroups(Entity $entity)
192
    {
193
        $query = (new QueryBuilder())
194
            ->delete('user_groups_page_categories')
195
            ->where('page_category_id = ?')
196
            ->addUnnamedPlaceholderValue($entity->getId(), \PDO::PARAM_STR);
197
198
        $sql = $query->getSql();
199
200
        $statement = $this->writeConnection->prepare($sql);
201
        $statement->bindValues($query->getParameters());
202
        $statement->execute();
203
    }
204
205
    /**
206
     * @param Entity $entity
207
     */
208
    protected function addUserGroups(Entity $entity)
209
    {
210
        $idGenerator = $this->getIdGenerator();
211
212
        foreach ($entity->getUserGroups() as $userGroup) {
213
            $query = (new QueryBuilder())
214
                ->insert(
215
                    'user_groups_page_categories',
216
                    [
217
                        'id'               => [$idGenerator->generate($userGroup), \PDO::PARAM_STR],
218
                        'user_group_id'    => [$userGroup->getId(), \PDO::PARAM_STR],
219
                        'page_category_id' => [$entity->getId(), \PDO::PARAM_STR],
220
                    ]
221
                );
222
223
            $sql = $query->getSql();
224
225
            $statement = $this->writeConnection->prepare($sql);
226
            $statement->bindValues($query->getParameters());
227
            $statement->execute();
228
        }
229
    }
230
231
    /**
232
     * @param array $hash
233
     *
234
     * @return Entity
235
     */
236
    protected function loadEntity(array $hash)
237
    {
238
        $userGroups = $this->loadUserGroups($hash);
239
240
        return new Entity(
241
            $hash['id'],
242
            $hash['name'],
243
            $hash['identifier'],
244
            $userGroups
245
        );
246
    }
247
248
    /**
249
     * @param array $hash
250
     *
251
     * @return array
252
     */
253
    private function loadUserGroups(array $hash): array
254
    {
255
        if (empty($hash[static::USER_GROUP_IDS])) {
256
            return [];
257
        }
258
259
        $userGroups = [];
260
        foreach (explode(',', $hash[static::USER_GROUP_IDS]) as $id) {
261
            $userGroups[] = new UserGroup((string)$id, '', '');
262
        }
263
264
        return $userGroups;
265
    }
266
267
    /**
268
     * @return SelectQuery
269
     */
270
    private function getBaseQuery()
271
    {
272
        /** @var SelectQuery $query */
273
        $query = (new QueryBuilder())
274
            ->select(
275
                'pc.id',
276
                'pc.name',
277
                'pc.identifier',
278
                'GROUP_CONCAT(ugpc.user_group_id) AS user_group_ids'
279
            )
280
            ->from('page_categories', 'pc')
281
            ->leftJoin('user_groups_page_categories', 'ugpc', 'ugpc.page_category_id = pc.id')
282
            ->where('pc.deleted = 0')
283
            ->groupBy('pc.id');
284
285
        return $query;
286
    }
287
}
288