Issues (106)

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

1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Website\Orm\DataMappers;
6
7
use AbterPhp\Framework\Domain\Entities\IStringerEntity;
8
use AbterPhp\Website\Domain\Entities\PageLayout as Entity;
9
use Opulence\Orm\DataMappers\SqlDataMapper;
10
use Opulence\QueryBuilders\Expression;
11
use Opulence\QueryBuilders\MySql\QueryBuilder;
12
use Opulence\QueryBuilders\MySql\SelectQuery;
13
14
/** @phan-file-suppress PhanTypeMismatchArgument */
15
class PageLayoutSqlDataMapper extends SqlDataMapper implements IPageLayoutDataMapper
16
{
17
    /**
18
     * @param IStringerEntity $entity
19
     */
20
    public function add($entity)
21
    {
22
        assert($entity instanceof Entity, new \InvalidArgumentException());
23
24
        $data  = $this->getColumnNamesToValues($entity, true);
25
        $query = (new QueryBuilder())->insert('page_layouts', $data);
26
27
        $statement = $this->writeConnection->prepare($query->getSql());
28
        $statement->bindValues($query->getParameters());
29
        $statement->execute();
30
    }
31
32
    /**
33
     * @param IStringerEntity $entity
34
     *
35
     * @throws \Opulence\QueryBuilders\InvalidQueryException
36
     */
37
    public function delete($entity)
38
    {
39
        assert($entity instanceof Entity, new \InvalidArgumentException());
40
41
        $query = (new QueryBuilder())
42
            ->update('page_layouts', 'page_layouts', ['deleted_at' => new Expression('NOW()')])
43
            ->where('id = ?')
44
            ->addUnnamedPlaceholderValue($entity->getId(), \PDO::PARAM_STR);
45
46
        $statement = $this->writeConnection->prepare($query->getSql());
47
        $statement->bindValues($query->getParameters());
48
        $statement->execute();
49
    }
50
51
    /**
52
     * @return Entity[]
53
     * @throws \Opulence\Orm\OrmException
54
     */
55
    public function getAll(): array
56
    {
57
        $query = $this->getBaseQuery();
58
59
        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...
60
    }
61
62
    /**
63
     * @param int      $limitFrom
64
     * @param int      $pageSize
65
     * @param string[] $orders
66
     * @param array    $conditions
67
     * @param array    $params
68
     *
69
     * @return Entity[]
70
     * @throws \Opulence\Orm\OrmException
71
     */
72
    public function getPage(int $limitFrom, int $pageSize, array $orders, array $conditions, array $params): array
73
    {
74
        $query = $this->getBaseQuery()
75
            ->limit($pageSize)
76
            ->offset($limitFrom);
77
78
        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...
79
            $query->orderBy('page_layouts.name ASC');
80
        }
81
        foreach ($orders as $order) {
82
            $query->addOrderBy($order);
83
        }
84
85
        foreach ($conditions as $condition) {
86
            $query->andWhere($condition);
87
        }
88
89
        $replaceCount = 1;
90
91
        $sql = $query->getSql();
92
        $sql = str_replace('SELECT', 'SELECT SQL_CALC_FOUND_ROWS', $sql, $replaceCount);
93
94
        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...
95
    }
96
97
    /**
98
     * @param int|string $id
99
     *
100
     * @return Entity|null
101
     * @throws \Opulence\Orm\OrmException
102
     */
103
    public function getById($id)
104
    {
105
        $query = $this->getBaseQuery()->andWhere('page_layouts.id = :layout_id');
106
107
        $parameters = [
108
            'layout_id' => [$id, \PDO::PARAM_STR],
109
        ];
110
111
        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\Website\Domain\Entities\PageLayout|null.
Loading history...
112
    }
113
114
    /**
115
     * @param string $identifier
116
     *
117
     * @return Entity|null
118
     * @throws \Opulence\Orm\OrmException
119
     */
120
    public function getByIdentifier(string $identifier): ?Entity
121
    {
122
        $query = $this->getBaseQuery()->andWhere('identifier = :identifier');
123
124
        $parameters = [
125
            'identifier' => $identifier,
126
        ];
127
128
        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\PageLayout|null. Consider adding an additional type-check to rule them out.
Loading history...
129
    }
130
131
    /**
132
     * @param IStringerEntity $entity
133
     *
134
     * @throws \Opulence\QueryBuilders\InvalidQueryException
135
     */
136
    public function update($entity)
137
    {
138
        assert($entity instanceof Entity, new \InvalidArgumentException());
139
140
        $columnNamesToValues = $this->getColumnNamesToValues($entity, false);
141
142
        $query = (new QueryBuilder())
143
            ->update('page_layouts', 'page_layouts', $columnNamesToValues)
144
            ->where('id = ?')
145
            ->andWhere('deleted_at IS NULL')
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
153
    /**
154
     * @param Entity $entity
155
     * @param bool   $create
156
     *
157
     * @return array
158
     */
159
    protected function getColumnNamesToValues(Entity $entity, bool $create): array
160
    {
161
        $columnNamesToValues = [
162
            'name'       => [$entity->getName(), \PDO::PARAM_STR],
163
            'identifier' => [$entity->getIdentifier(), \PDO::PARAM_STR],
164
            'classes'    => [$entity->getClasses(), \PDO::PARAM_STR],
165
            'body'       => [$entity->getBody(), \PDO::PARAM_STR],
166
        ];
167
168
        if ($create) {
169
            $columnNamesToValues = array_merge(['id' => [$entity->getId(), \PDO::PARAM_STR]], $columnNamesToValues);
170
        }
171
172
        $columnNamesToValues = $this->populateWithAssets($entity, $columnNamesToValues);
173
174
        return $columnNamesToValues;
175
    }
176
177
    /**
178
     * @param Entity $entity
179
     * @param array  $columnNamesToValues
180
     *
181
     * @return array
182
     */
183
    protected function populateWithAssets(Entity $entity, array $columnNamesToValues): array
184
    {
185
        if (!$entity->getAssets()) {
186
            return $columnNamesToValues;
187
        }
188
189
        $assets = $entity->getAssets();
190
191
        $assetValues = [
192
            'header'    => $assets->getHeader(),
193
            'footer'    => $assets->getFooter(),
194
            'css_files' => implode("\n\r", $assets->getCssFiles()),
195
            'js_files'  => implode("\n\r", $assets->getJsFiles()),
196
        ];
197
198
        return array_merge($columnNamesToValues, $assetValues);
199
    }
200
201
    /**
202
     * @param array $hash
203
     *
204
     * @return Entity
205
     */
206
    protected function loadEntity(array $hash)
207
    {
208
        $assets = $this->loadAssets($hash);
209
210
        return new Entity(
211
            $hash['id'],
212
            $hash['name'],
213
            $hash['identifier'],
214
            $hash['classes'],
215
            $hash['body'],
216
            $assets
217
        );
218
    }
219
220
    /**
221
     * @param array $hash
222
     *
223
     * @return Entity\Assets|null
224
     */
225
    protected function loadAssets(array $hash): ?Entity\Assets
226
    {
227
        return new Entity\Assets(
228
            $hash['identifier'],
229
            $hash['header'],
230
            $hash['footer'],
231
            explode("\r\n", $hash['css_files']),
232
            explode("\r\n", $hash['js_files'])
233
        );
234
    }
235
236
    /**
237
     * @return SelectQuery
238
     */
239
    private function getBaseQuery()
240
    {
241
        /** @var SelectQuery $query */
242
        $query = (new QueryBuilder())
243
            ->select(
244
                'page_layouts.id',
245
                'page_layouts.name',
246
                'page_layouts.identifier',
247
                'page_layouts.classes',
248
                'page_layouts.body',
249
                'page_layouts.header',
250
                'page_layouts.footer',
251
                'page_layouts.css_files',
252
                'page_layouts.js_files'
253
            )
254
            ->from('page_layouts')
255
            ->where('page_layouts.deleted_at IS NULL');
256
257
        return $query;
258
    }
259
}
260