FileCategorySqlDataMapper   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 297
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 123
c 2
b 0
f 0
dl 0
loc 297
rs 10
wmc 19

13 Methods

Rating   Name   Duplication   Size   Complexity  
A deleteUserGroups() 0 12 1
A getUserGroups() 0 12 3
A delete() 0 20 1
A getAll() 0 7 1
A getByUserGroupId() 0 11 1
A addUserGroups() 0 20 2
A getById() 0 11 1
A getPage() 0 23 4
A loadEntity() 0 10 1
A add() 0 22 1
A joinUserGroups() 0 9 1
A getBaseQuery() 0 17 1
A update() 0 26 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Files\Orm\DataMappers;
6
7
use AbterPhp\Admin\Domain\Entities\UserGroup;
8
use AbterPhp\Admin\Orm\DataMappers\IdGeneratorUserTrait;
9
use AbterPhp\Files\Domain\Entities\FileCategory as Entity;
10
use Opulence\Orm\DataMappers\SqlDataMapper;
11
use Opulence\QueryBuilders\Expression;
12
use Opulence\QueryBuilders\MySql\QueryBuilder;
13
use Opulence\QueryBuilders\MySql\SelectQuery;
14
15
/** @phan-file-suppress PhanTypeMismatchArgument */
16
class FileCategorySqlDataMapper extends SqlDataMapper implements IFileCategoryDataMapper
17
{
18
    use IdGeneratorUserTrait;
19
20
    const USER_GROUP_IDS = 'user_group_ids';
21
22
    /**
23
     * @param Entity $entity
24
     */
25
    public function add($entity)
26
    {
27
        assert($entity instanceof Entity, new \InvalidArgumentException());
28
29
        $query = (new QueryBuilder())
30
            ->insert(
31
                'file_categories',
32
                [
33
                    'id'         => [$entity->getId(), \PDO::PARAM_STR],
34
                    'identifier' => [$entity->getIdentifier(), \PDO::PARAM_STR],
35
                    'name'       => [$entity->getName(), \PDO::PARAM_STR],
36
                    'is_public'  => [$entity->isPublic(), \PDO::PARAM_BOOL],
37
                ]
38
            );
39
40
        $sql = $query->getSql();
41
42
        $statement = $this->writeConnection->prepare($sql);
43
        $statement->bindValues($query->getParameters());
44
        $statement->execute();
45
46
        $this->addUserGroups($entity);
47
    }
48
49
    /**
50
     * @param Entity $entity
51
     *
52
     * @throws \Opulence\QueryBuilders\InvalidQueryException
53
     */
54
    public function delete($entity)
55
    {
56
        assert($entity instanceof Entity, new \InvalidArgumentException());
57
58
        $query = (new QueryBuilder())
59
            ->update(
60
                'file_categories',
61
                'file_categories',
62
                ['deleted_at' => new Expression('NOW()')]
63
            )
64
            ->where('id = ?')
65
            ->addUnnamedPlaceholderValue($entity->getId(), \PDO::PARAM_STR);
66
67
        $sql = $query->getSql();
68
69
        $statement = $this->writeConnection->prepare($sql);
70
        $statement->bindValues($query->getParameters());
71
        $statement->execute();
72
73
        $this->deleteUserGroups($entity);
74
    }
75
76
    /**
77
     * @return Entity[]
78
     * @throws \Opulence\Orm\OrmException
79
     */
80
    public function getAll(): array
81
    {
82
        $query = $this->getBaseQuery();
83
84
        $sql = $query->getSql();
85
86
        return $this->read($sql, [], 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...
87
    }
88
89
    /**
90
     * @param int      $limitFrom
91
     * @param int      $pageSize
92
     * @param string[] $orders
93
     * @param array    $conditions
94
     * @param array    $params
95
     *
96
     * @return Entity[]
97
     * @throws \Opulence\Orm\OrmException
98
     */
99
    public function getPage(int $limitFrom, int $pageSize, array $orders, array $conditions, array $params): array
100
    {
101
        $query = $this->getBaseQuery()
102
            ->limit($pageSize)
103
            ->offset($limitFrom);
104
105
        if (!$orders) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $orders of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
106
            $query->orderBy('fc.name ASC');
107
        }
108
        foreach ($orders as $order) {
109
            $query->addOrderBy($order);
110
        }
111
112
        foreach ($conditions as $condition) {
113
            $query->andWhere($condition);
114
        }
115
116
        $replaceCount = 1;
117
118
        $sql = $query->getSql();
119
        $sql = str_replace('SELECT', 'SELECT SQL_CALC_FOUND_ROWS', $sql, $replaceCount);
120
121
        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...
122
    }
123
124
    /**
125
     * @param string $id
126
     *
127
     * @return Entity
128
     * @throws \Opulence\Orm\OrmException
129
     */
130
    public function getById($id)
131
    {
132
        $query = $this->getBaseQuery()->andWhere('fc.id = :file_category_id');
133
134
        $parameters = [
135
            'file_category_id' => [$id, \PDO::PARAM_STR],
136
        ];
137
138
        $sql = $query->getSql();
139
140
        return $this->read($sql, $parameters, 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\Files\Domain\Entities\FileCategory.
Loading history...
141
    }
142
143
    /**
144
     * @param string $userGroupId
145
     *
146
     * @return Entity[]
147
     * @throws \Opulence\Orm\OrmException
148
     */
149
    public function getByUserGroupId(string $userGroupId): array
150
    {
151
        $query = $this->getBaseQuery();
152
        $query = $this->joinUserGroups($query);
153
        $query = $query->andWhere('ugfc2.user_group_id = :user_group_id');
154
155
        $parameters = ['ugfc2.user_group_id' => [$userGroupId, \PDO::PARAM_STR]];
156
157
        $sql = $query->getSql();
158
159
        return $this->read($sql, $parameters, 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...
160
    }
161
162
    /**
163
     * @param Entity $entity
164
     *
165
     * @throws \Opulence\QueryBuilders\InvalidQueryException
166
     */
167
    public function update($entity)
168
    {
169
        assert($entity instanceof Entity, new \InvalidArgumentException());
170
171
        $query = (new QueryBuilder())
172
            ->update(
173
                'file_categories',
174
                'file_categories',
175
                [
176
                    'identifier' => [$entity->getIdentifier(), \PDO::PARAM_STR],
177
                    'name'       => [$entity->getName(), \PDO::PARAM_STR],
178
                    'is_public'  => [$entity->isPublic(), \PDO::PARAM_BOOL],
179
                ]
180
            )
181
            ->where('id = ?')
182
            ->andWhere('deleted_at IS NULL')
183
            ->addUnnamedPlaceholderValue($entity->getId(), \PDO::PARAM_STR);
184
185
        $sql = $query->getSql();
186
187
        $statement = $this->writeConnection->prepare($sql);
188
        $statement->bindValues($query->getParameters());
189
        $statement->execute();
190
191
        $this->deleteUserGroups($entity);
192
        $this->addUserGroups($entity);
193
    }
194
195
    /**
196
     * @param Entity $entity
197
     *
198
     * @throws \Opulence\QueryBuilders\InvalidQueryException
199
     */
200
    protected function deleteUserGroups(Entity $entity)
201
    {
202
        $query = (new QueryBuilder())
203
            ->delete('user_groups_file_categories')
204
            ->where('file_category_id = ?')
205
            ->addUnnamedPlaceholderValue($entity->getId(), \PDO::PARAM_STR);
206
207
        $sql = $query->getSql();
208
209
        $statement = $this->writeConnection->prepare($sql);
210
        $statement->bindValues($query->getParameters());
211
        $statement->execute();
212
    }
213
214
    /**
215
     * @param Entity $entity
216
     */
217
    protected function addUserGroups(Entity $entity)
218
    {
219
        $idGenerator = $this->getIdGenerator();
220
221
        foreach ($entity->getUserGroups() as $userGroup) {
222
            $query = (new QueryBuilder())
223
                ->insert(
224
                    'user_groups_file_categories',
225
                    [
226
                        'id'               => [$idGenerator->generate($userGroup), \PDO::PARAM_STR],
227
                        'user_group_id'    => [$userGroup->getId(), \PDO::PARAM_STR],
228
                        'file_category_id' => [$entity->getId(), \PDO::PARAM_STR],
229
                    ]
230
                );
231
232
            $sql = $query->getSql();
233
234
            $statement = $this->writeConnection->prepare($sql);
235
            $statement->bindValues($query->getParameters());
236
            $statement->execute();
237
        }
238
    }
239
240
    /**
241
     * @param array $hash
242
     *
243
     * @return Entity
244
     */
245
    protected function loadEntity(array $hash)
246
    {
247
        $userGroups = $this->getUserGroups($hash);
248
249
        return new Entity(
250
            $hash['id'],
251
            $hash['identifier'],
252
            $hash['name'],
253
            (bool)$hash['is_public'],
254
            $userGroups
255
        );
256
    }
257
258
    /**
259
     * @param array $hash
260
     *
261
     * @return array
262
     */
263
    private function getUserGroups(array $hash): array
264
    {
265
        if (empty($hash[static::USER_GROUP_IDS])) {
266
            return [];
267
        }
268
269
        $userGroups = [];
270
        foreach (explode(',', $hash[static::USER_GROUP_IDS]) as $id) {
271
            $userGroups[] = new UserGroup((string)$id, '', '');
272
        }
273
274
        return $userGroups;
275
    }
276
277
    /**
278
     * @return SelectQuery
279
     */
280
    private function getBaseQuery(): SelectQuery
281
    {
282
        /** @var SelectQuery $query */
283
        $query = (new QueryBuilder())
284
            ->select(
285
                'fc.id',
286
                'fc.identifier',
287
                'fc.name',
288
                'fc.is_public',
289
                'GROUP_CONCAT(ugfc.user_group_id) AS user_group_ids'
290
            )
291
            ->from('file_categories', 'fc')
292
            ->leftJoin('user_groups_file_categories', 'ugfc', 'ugfc.file_category_id = fc.id')
293
            ->where('fc.deleted_at IS NULL')
294
            ->groupBy('fc.id');
295
296
        return $query;
297
    }
298
299
    /**
300
     * @param SelectQuery $query
301
     *
302
     * @return SelectQuery
303
     */
304
    private function joinUserGroups(SelectQuery $query): SelectQuery
305
    {
306
        $query->innerJoin(
307
            'user_groups_file_categories',
308
            'ugfc2',
309
            'fc.id = ugfc2.file_category_id'
310
        );
311
312
        return $query;
313
    }
314
}
315