Passed
Push — master ( 7ba2cb...1d30f9 )
by Peter
02:20
created

UserApiKeyGroupSqlDataMapper::addAdminResources()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 13
dl 0
loc 21
rs 9.8333
c 0
b 0
f 0
cc 2
nc 2
nop 1
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\UserApiKey as Entity;
9
use AbterPhp\Framework\Orm\DataMappers\IdGeneratorUserTrait;
10
use Opulence\Orm\DataMappers\SqlDataMapper;
11
use Opulence\QueryBuilders\MySql\QueryBuilder;
12
use Opulence\QueryBuilders\MySql\SelectQuery;
13
14
class UserApiKeyGroupSqlDataMapper extends SqlDataMapper implements IUserApiKeyDataMapper
15
{
16
    const ADMIN_RESOURCE_IDS = 'admin_resource_ids';
17
18
    use IdGeneratorUserTrait;
19
20
    /**
21
     * @param Entity $entity
22
     */
23
    public function add($entity)
24
    {
25
        if (!($entity instanceof Entity)) {
0 ignored issues
show
introduced by
$entity is always a sub-type of AbterPhp\Admin\Domain\Entities\UserApiKey.
Loading history...
26
            throw new \InvalidArgumentException(__CLASS__ . ':' . __FUNCTION__ . ' expects a User Api Key entity.');
27
        }
28
29
        $query = (new QueryBuilder())
30
            ->insert(
31
                'user_api_keys',
32
                [
33
                    'id'          => [$entity->getId(), \PDO::PARAM_STR],
34
                    'user_id'     => [$entity->getUserId(), \PDO::PARAM_STR],
35
                    'description' => [$entity->getDescription(), \PDO::PARAM_STR],
36
                ]
37
            );
38
39
        $sql    = $query->getSql();
40
        $params = $query->getParameters();
41
42
        $statement = $this->writeConnection->prepare($sql);
43
        $statement->bindValues($params);
44
        $statement->execute();
45
46
        $this->addAdminResources($entity);
47
    }
48
49
    /**
50
     * @param Entity $entity
51
     */
52
    public function delete($entity)
53
    {
54
        if (!($entity instanceof Entity)) {
0 ignored issues
show
introduced by
$entity is always a sub-type of AbterPhp\Admin\Domain\Entities\UserApiKey.
Loading history...
55
            throw new \InvalidArgumentException(__CLASS__ . ':' . __FUNCTION__ . ' expects a User Api Key entity.');
56
        }
57
58
        $this->deleteAdminResources($entity);
59
60
        $query = (new QueryBuilder())
61
            ->update('user_api_keys', 'user_api_keys', ['deleted' => [1, \PDO::PARAM_INT]])
62
            ->where('id = ?')
63
            ->addUnnamedPlaceholderValue($entity->getId(), \PDO::PARAM_STR);
64
65
        $statement = $this->writeConnection->prepare($query->getSql());
66
        $statement->bindValues($query->getParameters());
67
        $statement->execute();
68
    }
69
70
    /**
71
     * @return array
72
     */
73
    public function getAll(): array
74
    {
75
        $query = $this->getBaseQuery();
76
77
        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...
78
    }
79
80
    /**
81
     * @param int      $limitFrom
82
     * @param int      $pageSize
83
     * @param string[] $orders
84
     * @param array    $conditions
85
     * @param array    $params
86
     *
87
     * @return Entity[]
88
     */
89
    public function getPage(int $limitFrom, int $pageSize, array $orders, array $conditions, array $params): array
90
    {
91
        $query = $this->getBaseQuery()
92
            ->limit($pageSize)
93
            ->offset($limitFrom);
94
95
        foreach ($orders as $order) {
96
            $query->addOrderBy($order);
97
        }
98
99
        foreach ($conditions as $condition) {
100
            $query->andWhere($condition);
101
        }
102
103
        $replaceCount = 1;
104
105
        $sql = $query->getSql();
106
        $sql = str_replace('SELECT', 'SELECT SQL_CALC_FOUND_ROWS', $sql, $replaceCount);
107
108
        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...
109
    }
110
111
    /**
112
     * @param int|string $id
113
     *
114
     * @return Entity|null
115
     */
116
    public function getById($id)
117
    {
118
        $query = $this->getBaseQuery()->andWhere('uak.id = :user_api_key_id');
119
120
        $parameters = [
121
            'user_api_key_id' => [$id, \PDO::PARAM_STR],
122
        ];
123
124
        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\UserApiKey|null.
Loading history...
125
    }
126
127
    /**
128
     * @param Entity $entity
129
     */
130
    public function update($entity)
131
    {
132
        if (!($entity instanceof Entity)) {
0 ignored issues
show
introduced by
$entity is always a sub-type of AbterPhp\Admin\Domain\Entities\UserApiKey.
Loading history...
133
            throw new \InvalidArgumentException(__CLASS__ . ':' . __FUNCTION__ . ' expects a User Api Key entity.');
134
        }
135
136
        $query = (new QueryBuilder())
137
            ->update(
138
                'user_api_keys',
139
                'user_api_keys',
140
                [
141
                    'description' => [$entity->getDescription(), \PDO::PARAM_STR],
142
                ]
143
            )
144
            ->where('id = ?')
145
            ->andWhere('deleted = 0')
146
            ->addUnnamedPlaceholderValue($entity->getId(), \PDO::PARAM_STR);
147
148
        $statement = $this->writeConnection->prepare($query->getSql());
149
        $statement->bindValues($query->getParameters());
150
        $statement->execute();
151
152
        $this->deleteAdminResources($entity);
153
        $this->addAdminResources($entity);
154
    }
155
156
    /**
157
     * @param array $hash
158
     *
159
     * @return Entity
160
     */
161
    protected function loadEntity(array $hash)
162
    {
163
        $adminResources = $this->loadAdminResources($hash);
164
165
        return new Entity(
166
            $hash['id'],
167
            $hash['user_id'],
168
            $hash['description'],
169
            $adminResources
170
        );
171
    }
172
173
    /**
174
     * @param array $hash
175
     *
176
     * @return array
177
     */
178
    protected function loadAdminResources(array $hash): array
179
    {
180
        if (empty($hash['admin_resource_ids'])) {
181
            return [];
182
        }
183
184
        $adminResourceIds         = explode(',', $hash['admin_resource_ids']);
185
        $adminResourceIdentifiers = explode(',', $hash['admin_resource_identifiers']);
186
187
        $adminResources = [];
188
        foreach ($adminResourceIds as $idx => $adminResourceId) {
189
            $adminResources[] = new AdminResource($adminResourceId, $adminResourceIdentifiers[$idx]);
190
        }
191
192
        return $adminResources;
193
    }
194
195
    /**
196
     * @return SelectQuery
197
     */
198
    private function getBaseQuery(): SelectQuery
199
    {
200
        /** @var SelectQuery $query */
201
        $query = (new QueryBuilder())
202
            ->select(
203
                'uak.id',
204
                'uak.user_id',
205
                'uak.description',
206
                'GROUP_CONCAT(ar.id) AS admin_resource_ids',
207
                'GROUP_CONCAT(ar.identifier) AS admin_resource_identifiers'
208
            )
209
            ->from('user_api_keys', 'uak')
210
            ->leftJoin('user_api_keys_admin_resources', 'uakar', 'uakar.user_api_key_id = uak.id')
211
            ->leftJoin('admin_resources', 'ar', 'uakar.admin_resource_id = ar.id')
212
            ->where('uak.deleted = 0')
213
            ->groupBy('uak.id');
214
215
        return $query;
216
    }
217
218
    /**
219
     * @param Entity $entity
220
     */
221
    protected function deleteAdminResources(Entity $entity)
222
    {
223
        $query = (new QueryBuilder())
224
            ->delete('user_api_keys_admin_resources')
225
            ->where('user_api_key_id = ?')
226
            ->addUnnamedPlaceholderValue($entity->getId(), \PDO::PARAM_STR);
227
228
        $sql    = $query->getSql();
229
        $params = $query->getParameters();
230
231
        $statement = $this->writeConnection->prepare($sql);
232
        $statement->bindValues($params);
233
        $statement->execute();
234
    }
235
236
    /**
237
     * @param Entity $entity
238
     */
239
    protected function addAdminResources(Entity $entity)
240
    {
241
        $idGenerator = $this->getIdGenerator();
242
243
        foreach ($entity->getAdminResources() as $adminResource) {
244
            $query = (new QueryBuilder())
245
                ->insert(
246
                    'user_api_keys_admin_resources',
247
                    [
248
                        'id'                => [$idGenerator->generate($entity), \PDO::PARAM_STR],
249
                        'user_api_key_id'   => [$entity->getId(), \PDO::PARAM_STR],
250
                        'admin_resource_id' => [$adminResource->getId(), \PDO::PARAM_STR],
251
                    ]
252
                );
253
254
            $sql    = $query->getSql();
255
            $params = $query->getParameters();
256
257
            $statement = $this->writeConnection->prepare($sql);
258
            $statement->bindValues($params);
259
            $statement->execute();
260
        }
261
    }
262
}
263