FileSqlDataMapper::getAll()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 7
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Files\Orm\DataMappers;
6
7
use AbterPhp\Files\Domain\Entities\File as Entity;
8
use AbterPhp\Files\Domain\Entities\FileCategory;
9
use Opulence\Orm\DataMappers\SqlDataMapper;
10
use Opulence\QueryBuilders\Conditions\ConditionFactory;
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 FileSqlDataMapper extends SqlDataMapper implements IFileDataMapper
17
{
18
    /**
19
     * @param Entity $entity
20
     */
21
    public function add($entity)
22
    {
23
        assert($entity instanceof Entity, new \InvalidArgumentException());
24
25
        $query = (new QueryBuilder())
26
            ->insert(
27
                'files',
28
                [
29
                    'id'               => [$entity->getId(), \PDO::PARAM_STR],
30
                    'filesystem_name'  => [$entity->getFilesystemName(), \PDO::PARAM_STR],
31
                    'public_name'      => [$entity->getPublicName(), \PDO::PARAM_STR],
32
                    'mime'             => [$entity->getMime(), \PDO::PARAM_STR],
33
                    'description'      => [$entity->getDescription(), \PDO::PARAM_STR],
34
                    'file_category_id' => [$entity->getCategory()->getId(), \PDO::PARAM_STR],
35
                    'uploaded_at'      => [$entity->getUploadedAt()->format(Entity::DATE_FORMAT), \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
47
    /**
48
     * @param Entity $entity
49
     *
50
     * @throws \Opulence\QueryBuilders\InvalidQueryException
51
     */
52
    public function delete($entity)
53
    {
54
        assert($entity instanceof Entity, new \InvalidArgumentException());
55
56
        $query = (new QueryBuilder())
57
            ->update('files', 'files', ['deleted_at' => new Expression('NOW()')])
58
            ->where('id = ?')
59
            ->addUnnamedPlaceholderValue($entity->getId(), \PDO::PARAM_STR);
60
61
        $sql    = $query->getSql();
62
        $params = $query->getParameters();
63
64
        $statement = $this->writeConnection->prepare($sql);
65
        $statement->bindValues($params);
66
        $statement->execute();
67
    }
68
69
    /**
70
     * @return Entity[]
71
     * @throws \Opulence\Orm\OrmException
72
     */
73
    public function getAll(): array
74
    {
75
        $query = $this->getBaseQuery();
76
77
        $sql = $query->getSql();
78
79
        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...
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 \Opulence\Orm\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('files.public_name 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
121
     * @throws \Opulence\Orm\OrmException
122
     */
123
    public function getById($id)
124
    {
125
        $query = $this->getBaseQuery()->andWhere('files.id = :file_id');
126
127
        $params = [
128
            'file_id' => [$id, \PDO::PARAM_STR],
129
        ];
130
        $sql    = $query->getSql();
131
132
        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\Files\Domain\Entities\File.
Loading history...
133
    }
134
135
    /**
136
     * @param string $filesystemName
137
     *
138
     * @return Entity
139
     * @throws \Opulence\Orm\OrmException
140
     */
141
    public function getByFilesystemName(string $filesystemName): Entity
142
    {
143
        $query = $this->getBaseQuery()->andWhere('files.filesystem_name = :filesystem_name');
144
145
        $params = [
146
            'filesystem_name' => [$filesystemName, \PDO::PARAM_STR],
147
        ];
148
        $sql    = $query->getSql();
149
150
        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|null which is incompatible with the type-hinted return AbterPhp\Files\Domain\Entities\File. Consider adding an additional type-check to rule them out.
Loading history...
151
    }
152
153
    /**
154
     * @param string $filesystemName
155
     *
156
     * @return Entity
157
     * @throws \Opulence\Orm\OrmException
158
     */
159
    public function getPublicByFilesystemName(string $filesystemName): Entity
160
    {
161
        $query = $this->getBaseQuery()
162
            ->andWhere('files.filesystem_name = :filesystem_name')
163
            ->andWhere('file_categories.is_public = 1');
164
165
        $params = [
166
            'filesystem_name' => [$filesystemName, \PDO::PARAM_STR],
167
        ];
168
        $sql    = $query->getSql();
169
170
        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|null which is incompatible with the type-hinted return AbterPhp\Files\Domain\Entities\File. Consider adding an additional type-check to rule them out.
Loading history...
171
    }
172
173
    /**
174
     * @param string[] $identifiers
175
     *
176
     * @return Entity[]
177
     * @throws \Opulence\Orm\OrmException
178
     */
179
    public function getPublicByCategoryIdentifiers(array $identifiers): array
180
    {
181
        if (count($identifiers) === 0) {
182
            return [];
183
        }
184
185
        $conditions = new ConditionFactory();
186
        $query      = $this
187
            ->withUserGroup($this->getBaseQuery())
188
            ->andWhere($conditions->in('file_categories.identifier', $identifiers));
189
190
        $sql    = $query->getSql();
191
        $params = $query->getParameters();
192
193
        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...
194
    }
195
196
    /**
197
     * @param string $userId
198
     *
199
     * @return Entity[]
200
     * @throws \Opulence\Orm\OrmException
201
     */
202
    public function getByUserId(string $userId): array
203
    {
204
        $query = $this
205
            ->withUserGroup($this->getBaseQuery())
206
            ->andWhere('user_groups.user_id = :user_id');
207
208
        $sql    = $query->getSql();
209
        $params = [
210
            'user_id' => [$userId, \PDO::PARAM_STR],
211
        ];
212
213
        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...
214
    }
215
216
    /**
217
     * @param Entity $entity
218
     *
219
     * @throws \Opulence\QueryBuilders\InvalidQueryException
220
     */
221
    public function update($entity)
222
    {
223
        assert($entity instanceof Entity, new \InvalidArgumentException());
224
225
        $query = (new QueryBuilder())
226
            ->update(
227
                'files',
228
                'files',
229
                [
230
                    'filesystem_name'  => [$entity->getFilesystemName(), \PDO::PARAM_STR],
231
                    'public_name'      => [$entity->getPublicName(), \PDO::PARAM_STR],
232
                    'mime'             => [$entity->getMime(), \PDO::PARAM_STR],
233
                    'description'      => [$entity->getDescription(), \PDO::PARAM_STR],
234
                    'uploaded_at'      => [$entity->getUploadedAt()->format(Entity::DATE_FORMAT), \PDO::PARAM_STR],
235
                    'file_category_id' => [$entity->getCategory()->getId(), \PDO::PARAM_STR],
236
                ]
237
            )
238
            ->where('id = ?')
239
            ->andWhere('deleted_at IS NULL')
240
            ->addUnnamedPlaceholderValue($entity->getId(), \PDO::PARAM_STR);
241
242
        $sql    = $query->getSql();
243
        $params = $query->getParameters();
244
245
        $statement = $this->writeConnection->prepare($sql);
246
        $statement->bindValues($params);
247
        $statement->execute();
248
    }
249
250
    /**
251
     * @param array $hash
252
     *
253
     * @return Entity|object
254
     * @throws \Exception
255
     */
256
    protected function loadEntity(array $hash)
257
    {
258
        $category = new FileCategory(
259
            $hash['file_category_id'],
260
            (string)$hash['file_category_identifier'],
261
            (string)$hash['file_category_name'],
262
            (bool)$hash['file_category_name']
263
        );
264
265
        $uploadedAt = new \DateTime((string)$hash['uploaded_at']);
266
267
        return new Entity(
268
            $hash['id'],
269
            $hash['filesystem_name'],
270
            $hash['public_name'],
271
            $hash['mime'],
272
            $hash['description'],
273
            $category,
274
            $uploadedAt,
275
            true
276
        );
277
    }
278
279
    /**
280
     * @return SelectQuery
281
     */
282
    private function getBaseQuery()
283
    {
284
        /** @var SelectQuery $query */
285
        $query = (new QueryBuilder())
286
            ->select(
287
                'files.id',
288
                'files.filesystem_name',
289
                'files.public_name',
290
                'files.mime',
291
                'files.file_category_id',
292
                'files.description',
293
                'files.uploaded_at',
294
                'file_categories.name AS file_category_name',
295
                'file_categories.identifier AS file_category_identifier'
296
            )
297
            ->from('files')
298
            ->innerJoin(
299
                'file_categories',
300
                'file_categories',
301
                'file_categories.id = files.file_category_id AND file_categories.deleted_at IS NULL'
302
            )
303
            ->where('files.deleted_at IS NULL')
304
            ->groupBy('files.id');
305
306
        return $query;
307
    }
308
309
    /**
310
     * @param SelectQuery $selectQuery
311
     *
312
     * @return SelectQuery
313
     */
314
    private function withUserGroup(SelectQuery $selectQuery): SelectQuery
315
    {
316
        /** @var SelectQuery $query */
317
        $selectQuery
318
            ->innerJoin(
319
                'user_groups_file_categories',
320
                'ugfc',
321
                'file_categories.id = ugfc.file_category_id AND file_categories.deleted_at IS NULL'
322
            )
323
            ->innerJoin(
324
                'user_groups',
325
                'user_groups',
326
                'user_groups.id = ugfc.user_group_id AND user_groups.deleted_at IS NULL'
327
            );
328
329
        return $selectQuery;
330
    }
331
}
332