Issues (104)

src/Orm/DataMappers/UserGroupSqlDataMapper.php (5 issues)

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