Passed
Push — master ( 26f223...98f436 )
by Peter
03:08
created

ContentListSqlDataMapper::createUpdateQuery()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 24
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 18
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 24
rs 9.6666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Website\Orm\DataMappers;
6
7
use AbterPhp\Admin\Orm\DataMappers\IdGeneratorUserTrait;
8
use AbterPhp\Framework\Domain\Entities\IStringerEntity;
9
use AbterPhp\Framework\Helper\DateHelper;
10
use AbterPhp\Website\Domain\Entities\ContentList as Entity;
11
use AbterPhp\Website\Domain\Entities\ContentListItem;
12
use Opulence\Orm\DataMappers\SqlDataMapper;
13
use Opulence\QueryBuilders\MySql\QueryBuilder;
14
use Opulence\QueryBuilders\MySql\SelectQuery;
15
use Opulence\QueryBuilders\Query;
16
use PDO;
17
18
/**
19
 * @phan-file-suppress PhanTypeMismatchArgument
20
 */
21
class ContentListSqlDataMapper extends SqlDataMapper implements IContentListDataMapper
22
{
23
    use IdGeneratorUserTrait;
24
25
    /**
26
     * @param IStringerEntity $entity
27
     */
28
    public function add($entity)
29
    {
30
        assert($entity instanceof Entity, new \InvalidArgumentException());
31
32
        $query = (new QueryBuilder())
33
            ->insert(
34
                'lists',
35
                [
36
                    'id'         => [$entity->getId(), PDO::PARAM_STR],
37
                    'type_id'    => [$entity->getTypeId(), PDO::PARAM_STR],
38
                    'name'       => [$entity->getName(), PDO::PARAM_STR],
39
                    'identifier' => [$entity->getIdentifier(), PDO::PARAM_STR],
40
                    'classes'    => [$entity->getClasses(), PDO::PARAM_STR],
41
                    'protected'  => [$entity->isProtected(), PDO::PARAM_BOOL],
42
                    'with_image' => [$entity->isWithImage(), PDO::PARAM_BOOL],
43
                    'with_links' => [$entity->isWithLinks(), PDO::PARAM_BOOL],
44
                    'with_html'  => [$entity->isWithHtml(), PDO::PARAM_BOOL],
45
                ]
46
            );
47
48
        $statement = $this->writeConnection->prepare($query->getSql());
49
        $statement->bindValues($query->getParameters());
50
        $statement->execute();
51
52
        $this->upsertItems($entity);
53
    }
54
55
    /**
56
     * @param IStringerEntity $entity
57
     *
58
     * @throws \Opulence\QueryBuilders\InvalidQueryException
59
     */
60
    public function delete($entity)
61
    {
62
        assert($entity instanceof Entity, new \InvalidArgumentException());
63
64
        $query = (new QueryBuilder())
65
            ->update('lists', 'lists', ['deleted_at' => [(new \DateTime())->format(\DATE_RFC3339), \PDO::PARAM_STR]])
66
            ->where('id = ?')
67
            ->addUnnamedPlaceholderValue($entity->getId(), PDO::PARAM_STR);
68
69
        $statement = $this->writeConnection->prepare($query->getSql());
70
        $statement->bindValues($query->getParameters());
71
        $statement->execute();
72
73
        $this->deleteItems($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
        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...
85
    }
86
87
    /**
88
     * @param int      $limitFrom
89
     * @param int      $pageSize
90
     * @param string[] $orders
91
     * @param array    $conditions
92
     * @param array    $params
93
     *
94
     * @return Entity[]
95
     * @throws \Opulence\Orm\OrmException
96
     */
97
    public function getPage(int $limitFrom, int $pageSize, array $orders, array $conditions, array $params): array
98
    {
99
        $query = $this->getBaseQuery()
100
            ->limit($pageSize)
101
            ->offset($limitFrom);
102
103
        foreach ($orders as $order) {
104
            $query->addOrderBy($order);
105
        }
106
107
        foreach ($conditions as $condition) {
108
            $query->andWhere($condition);
109
        }
110
111
        $replaceCount = 1;
112
113
        $sql = $query->getSql();
114
        $sql = str_replace('SELECT', 'SELECT SQL_CALC_FOUND_ROWS', $sql, $replaceCount);
115
116
        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...
117
    }
118
119
    /**
120
     * @param int|string $id
121
     *
122
     * @return Entity|null
123
     * @throws \Opulence\Orm\OrmException
124
     */
125
    public function getById($id)
126
    {
127
        $query = $this->getBaseQuery()->andWhere('lists.id = :list_id');
128
129
        $parameters = [
130
            'list_id' => [$id, PDO::PARAM_STR],
131
        ];
132
133
        $sql = $query->getSql();
134
135
        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\Website\Domain\Entities\ContentList|null.
Loading history...
136
    }
137
138
    /**
139
     * @param string $identifier
140
     *
141
     * @return Entity|null
142
     * @throws \Opulence\Orm\OrmException
143
     */
144
    public function getByIdentifier(string $identifier): ?Entity
145
    {
146
        $query = $this->getBaseQuery()->andWhere('lists.identifier = :identifier');
147
148
        $parameters = [
149
            'identifier' => [$identifier, PDO::PARAM_STR],
150
        ];
151
152
        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\Website\Domain\Entities\ContentList|null. Consider adding an additional type-check to rule them out.
Loading history...
153
    }
154
155
    /**
156
     * @param IStringerEntity $entity
157
     *
158
     * @throws \Opulence\QueryBuilders\InvalidQueryException
159
     */
160
    public function update($entity)
161
    {
162
        assert($entity instanceof Entity, new \InvalidArgumentException());
163
164
        $query = (new QueryBuilder())
165
            ->update(
166
                'lists',
167
                'lists',
168
                [
169
                    'type_id'    => [$entity->getTypeId(), PDO::PARAM_STR],
170
                    'name'       => [$entity->getName(), PDO::PARAM_STR],
171
                    'identifier' => [$entity->getIdentifier(), PDO::PARAM_STR],
172
                    'classes'    => [$entity->getClasses(), PDO::PARAM_STR],
173
                    'protected'  => [$entity->isProtected(), PDO::PARAM_BOOL],
174
                    'with_image' => [$entity->isWithImage(), PDO::PARAM_BOOL],
175
                    'with_links' => [$entity->isWithLinks(), PDO::PARAM_BOOL],
176
                    'with_html'  => [$entity->isWithHtml(), PDO::PARAM_BOOL],
177
                ]
178
            )
179
            ->where('id = ?')
180
            ->andWhere('lists.deleted_at IS NULL')
181
            ->addUnnamedPlaceholderValue($entity->getId(), PDO::PARAM_STR);
182
183
        $statement = $this->writeConnection->prepare($query->getSql());
184
        $statement->bindValues($query->getParameters());
185
        $statement->execute();
186
187
        $this->upsertItems($entity);
188
    }
189
190
    /**
191
     * @param array $hash
192
     *
193
     * @return Entity
194
     */
195
    protected function loadEntity(array $hash)
196
    {
197
        return new Entity(
198
            $hash['id'],
199
            $hash['type_id'],
200
            $hash['name'],
201
            $hash['identifier'],
202
            $hash['classes'],
203
            (bool)$hash['protected'],
204
            (bool)$hash['with_image'],
205
            (bool)$hash['with_links'],
206
            (bool)$hash['with_html']
207
        );
208
    }
209
210
    /**
211
     * @return SelectQuery
212
     */
213
    private function getBaseQuery(): SelectQuery
214
    {
215
        /** @var SelectQuery $query */
216
        $query = (new QueryBuilder())
217
            ->select(
218
                'lists.id',
219
                'lists.type_id',
220
                'lists.name',
221
                'lists.identifier',
222
                'lists.classes',
223
                'lists.protected',
224
                'lists.with_image',
225
                'lists.with_links',
226
                'lists.with_html'
227
            )
228
            ->from('lists')
229
            ->where('lists.deleted_at IS NULL');
230
231
        return $query;
232
    }
233
234
    /**
235
     * @param Entity $entity
236
     */
237
    protected function upsertItems(Entity $entity)
238
    {
239
        foreach ($entity->getItems() as $item) {
240
            if (!$item->getId() && $item->getDeletedAt()) {
241
                continue;
242
            }
243
244
            $query = $item->getId() ? $this->createUpdateQuery($item) : $this->createInsertQuery($item);
245
246
            $sql = $query->getSql();
247
248
            $statement = $this->writeConnection->prepare($sql);
249
            $statement->bindValues($query->getParameters());
250
            $statement->execute();
251
        }
252
    }
253
254
    /**
255
     * @param ContentListItem $item
256
     *
257
     * @return Query
258
     */
259
    protected function createUpdateQuery(ContentListItem $item): Query
260
    {
261
        $deletedAt = $item->getDeletedAt()
262
            ? [DateHelper::mysqlDateTime($item->getDeletedAt()), \PDO::PARAM_STR]
263
            : [null, \PDO::PARAM_STR];
264
265
        return (new QueryBuilder())
266
            ->update(
267
                'list_items',
268
                'list_items',
269
                [
270
                    'list_id'    => [$item->getListId(), \PDO::PARAM_STR],
271
                    'name'       => [$item->getName(), \PDO::PARAM_STR],
272
                    'name_href'  => [$item->getNameHref(), \PDO::PARAM_STR],
273
                    'body'       => [$item->getBody(), \PDO::PARAM_STR],
274
                    'body_href'  => [$item->getBodyHref(), \PDO::PARAM_STR],
275
                    'img_src'    => [$item->getImgSrc(), \PDO::PARAM_STR],
276
                    'img_alt'    => [$item->getImgAlt(), \PDO::PARAM_STR],
277
                    'img_href'   => [$item->getImgHref(), \PDO::PARAM_STR],
278
                    'deleted_at' => $deletedAt,
279
                ]
280
            )
281
            ->where('id = ?')
282
            ->addUnnamedPlaceholderValue($item->getId(), \PDO::PARAM_STR);
283
    }
284
285
    /**
286
     * @param ContentListItem $item
287
     *
288
     * @return Query
289
     */
290
    protected function createInsertQuery(ContentListItem $item): Query
291
    {
292
        return (new QueryBuilder())
293
            ->insert(
294
                'list_items',
295
                [
296
                    'id'        => [$this->getIdGenerator()->generate($item), \PDO::PARAM_STR],
297
                    'list_id'   => [$item->getListId(), \PDO::PARAM_STR],
298
                    'name'      => [$item->getName(), \PDO::PARAM_STR],
299
                    'name_href' => [$item->getNameHref(), \PDO::PARAM_STR],
300
                    'body'      => [$item->getBody(), \PDO::PARAM_STR],
301
                    'body_href' => [$item->getBodyHref(), \PDO::PARAM_STR],
302
                    'img_src'   => [$item->getImgSrc(), \PDO::PARAM_STR],
303
                    'img_alt'   => [$item->getImgAlt(), \PDO::PARAM_STR],
304
                    'img_href'  => [$item->getImgHref(), \PDO::PARAM_STR],
305
                ]
306
            );
307
    }
308
309
    /**
310
     * @param Entity $entity
311
     */
312
    protected function deleteItems(Entity $entity)
313
    {
314
        $query = (new QueryBuilder())
315
            ->update('list_items', 'list_items', ['deleted_at' => [DateHelper::mysqlDateTime(), \PDO::PARAM_STR]])
316
            ->where('list_id = ?')
317
            ->andWhere('deleted_at IS NOT NULL')
318
            ->addUnnamedPlaceholderValue($entity->getId(), \PDO::PARAM_STR);
319
320
        $sql = $query->getSql();
321
322
        $statement = $this->writeConnection->prepare($sql);
323
        $statement->bindValues($query->getParameters());
324
        $statement->execute();
325
    }
326
}
327