Passed
Push — master ( bf3918...698edc )
by Gabor
12:58 queued 06:03
created

FilesystemStorage::getPublishedDocumentsByAuthor()   B

Complexity

Conditions 6
Paths 18

Size

Total Lines 42
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
dl 0
loc 42
ccs 0
cts 32
cp 0
rs 8.439
c 0
b 0
f 0
cc 6
eloc 26
nc 18
nop 5
crap 42
1
<?php
2
/**
3
 * WebHemi.
4
 *
5
 * PHP version 7.1
6
 *
7
 * @copyright 2012 - 2017 Gixx-web (http://www.gixx-web.com)
8
 * @license   https://opensource.org/licenses/MIT The MIT License (MIT)
9
 *
10
 * @link      http://www.gixx-web.com
11
 */
12
declare(strict_types = 1);
13
14
namespace WebHemi\Data\Storage\Filesystem;
15
16
use PDO;
17
use WebHemi\Data\ConnectorInterface;
18
use WebHemi\Data\EntityInterface;
19
use WebHemi\Data\Entity\Filesystem\FilesystemEntity;
20
use WebHemi\Data\Storage\AbstractStorage;
21
use WebHemi\DateTime;
22
use WebHemi\StringLib;
23
24
/**
25
 * Class FilesystemStorage.
26
 *
27
 * @SuppressWarnings(PHPMD.TooManyFields)
28
 */
29
class FilesystemStorage extends AbstractStorage
30
{
31
    public const TYPE_DOCUMENT = FilesystemEntity::TYPE_DOCUMENT;
32
    public const TYPE_BINARY = FilesystemEntity::TYPE_BINARY;
33
    public const TYPE_DIRECTORY = FilesystemEntity::TYPE_DIRECTORY;
34
    public const TYPE_SYMLINK = FilesystemEntity::TYPE_SYMLINK;
35
36
    /** @var string */
37
    protected $dataGroup = 'webhemi_filesystem';
38
    /** @var string */
39
    protected $idKey = 'id_filesystem';
40
    /** @var string */
41
    private $idApplication = 'fk_application';
42
    /** @var string */
43
    private $idCategory = 'fk_category';
44
    /** @var string */
45
    private $idParent = 'fk_parent_node';
46
    /** @var string */
47
    private $idDocument = 'fk_filesystem_document';
48
    /** @var string */
49
    private $idFile = 'fk_filesystem_file';
50
    /** @var string */
51
    private $idDirectory = 'fk_filesystem_directory';
52
    /** @var string */
53
    private $idLink = 'fk_filesystem_link';
54
    /** @var string */
55
    private $path = 'path';
56
    /** @var string */
57
    private $baseName = 'basename';
58
    /** @var string */
59
    private $title = 'title';
60
    /** @var string */
61
    private $description = 'description';
62
    /** @var string */
63
    private $isHidden = 'is_hidden';
64
    /** @var string */
65
    private $isReadOnly = 'is_read_only';
66
    /** @var string */
67
    private $isDeleted = 'is_deleted';
68
    /** @var string */
69
    private $dateCreated = 'date_created';
70
    /** @var string */
71
    private $dateModified = 'date_modified';
72
    /** @var string */
73
    private $datePublished = 'date_published';
74
75
    /**
76
     * Populates an entity with storage data.
77
     *
78
     * @param EntityInterface $dataEntity
79
     * @param array           $data
80
     * @return void
81
     *
82
     * @SuppressWarnings(PHPMD.NPathComplexity) - sorry, this will remain like this. It's a complex object, period.
83
     */
84
    protected function populateEntity(EntityInterface&$dataEntity, array $data) : void
85
    {
86
        /* @var FilesystemEntity $dataEntity */
87
        $dataEntity->setFilesystemId((int) $data[$this->idKey])
88
            ->setApplicationId((int) $data[$this->idApplication])
89
            ->setCategoryId(isset($data[$this->idCategory]) ? (int) $data[$this->idCategory] : null)
90
            ->setParentId(isset($data[$this->idParent]) ? (int) $data[$this->idParent] : null)
91
            ->setDocumentId(isset($data[$this->idDocument]) ? (int) $data[$this->idDocument] : null)
92
            ->setFileId(isset($data[$this->idFile]) ? (int) $data[$this->idFile] : null)
93
            ->setDirectoryId(isset($data[$this->idDirectory]) ? (int) $data[$this->idDirectory] : null)
94
            ->setLinkId(isset($data[$this->idLink]) ? (int) $data[$this->idLink] : null)
95
            ->setPath($data[$this->path])
96
            ->setBaseName($data[$this->baseName])
97
            ->setTitle($data[$this->title])
98
            ->setDescription($data[$this->description])
99
            ->setHidden((bool) $data[$this->isHidden])
100
            ->setReadOnly((bool) $data[$this->isReadOnly])
101
            ->setDeleted((bool) $data[$this->isDeleted])
102
            ->setDateCreated(new DateTime($data[$this->dateCreated] ?? 'now'))
103
            ->setDateModified(!empty($data[$this->dateModified]) ? new DateTime($data[$this->dateModified]) : null)
104
            ->setDatePublished(!empty($data[$this->datePublished]) ? new DateTime($data[$this->datePublished]) : null);
105
    }
106
107
    /**
108
     * Get data from an entity.
109
     *
110
     * @param EntityInterface $dataEntity
111
     * @return array
112
     */
113
    protected function getEntityData(EntityInterface $dataEntity) : array
114
    {
115
        /** @var FilesystemEntity $dataEntity */
116
        $dateCreated = $dataEntity->getDateCreated();
117
        $dateModified = $dataEntity->getDateModified();
118
        $datePublished = $dataEntity->getDatePublished();
119
120
        return [
121
            $this->idKey => $dataEntity->getKeyData(),
122
            $this->idApplication => $dataEntity->getApplicationId(),
123
            $this->idCategory => $dataEntity->getCategoryId(),
124
            $this->idParent => $dataEntity->getParentId(),
125
            $this->idDocument => $dataEntity->getDocumentId(),
126
            $this->idFile => $dataEntity->getFileId(),
127
            $this->idDirectory => $dataEntity->getDirectoryId(),
128
            $this->idLink => $dataEntity->getLinkId(),
129
            $this->path => $dataEntity->getPath(),
130
            $this->baseName => $dataEntity->getBaseName(),
131
            $this->title => $dataEntity->getTitle(),
132
            $this->description => $dataEntity->getDescription(),
133
            $this->isHidden => (int) $dataEntity->getHidden(),
134
            $this->isReadOnly => (int) $dataEntity->getReadOnly(),
135
            $this->isDeleted => (int) $dataEntity->getDeleted(),
136
            $this->dateCreated => $dateCreated instanceof DateTime ? $dateCreated->format('Y-m-d H:i:s') : null,
137
            $this->dateModified => $dateModified instanceof DateTime ? $dateModified->format('Y-m-d H:i:s') : null,
138
            $this->datePublished => $datePublished instanceof DateTime ? $datePublished->format('Y-m-d H:i:s') : null
139
        ];
140
    }
141
142
    /**
143
     * Gets the filesystem entity by the identifier.
144
     *
145
     * @param int $identifier
146
     * @return null|FilesystemEntity
147
     */
148
    public function getFilesystemById(int $identifier) : ? FilesystemEntity
149
    {
150
        /** @var null|FilesystemEntity $dataEntity */
151
        $dataEntity = $this->getDataEntity([$this->idKey => $identifier]);
152
153
        return $dataEntity;
154
    }
155
156
    /**
157
     * Gets the filesystem entity set by application and directory.
158
     *
159
     * @param int $applicationId
160
     * @param int $directoryId
161
     * @return FilesystemEntity[]
162
     */
163
    public function getFilesystemSetByApplicationAndDirectory(int $applicationId, int $directoryId) : ? array
164
    {
165
        /** @var FilesystemEntity[] $dataEntitySet */
166
        $dataEntitySet = $this->getDataEntitySet(
167
            [$this->idApplication => $applicationId, $this->idDirectory => $directoryId]
168
        );
169
170
        return $dataEntitySet;
171
    }
172
173
    /**
174
     * Gets the filesystem entity by application and path.
175
     *
176
     * @param int $applicationId
177
     * @param string $path
178
     * @param string $baseName
179
     * @return null|FilesystemEntity
180
     */
181
    public function getFilesystemByApplicationAndPath(
182
        int $applicationId,
183
        string $path,
184
        string $baseName
185
    ) : ? FilesystemEntity {
186
        /** @var null|FilesystemEntity $dataEntity */
187
        $dataEntity = $this->getDataEntity(
188
            [
189
                $this->idApplication => $applicationId,
190
                $this->path => $path,
191
                $this->baseName => $baseName
192
            ]
193
        );
194
195
        return $dataEntity;
196
    }
197
198
    /**
199
     * Gets the published documents
200
     *
201
     * @param int $applicationId
202
     * @param array $additionalExpressions
203
     * @param string|null $order
204
     * @param int|null $limit
205
     * @param int|null $offset
206
     * @param string|null $groupBy
207
     * @param string|null $having
208
     * @return FilesystemEntity[]
209
     */
210
    public function getPublishedDocuments(
211
        int $applicationId,
212
        array $additionalExpressions = [],
213
        string $order = null,
214
        int $limit = null,
215
        int $offset = null,
216
        string $groupBy = null,
217
        string $having = null
218
    ) : array {
219
        $defaultExpressions = [
220
            $this->idApplication => $applicationId,
221
            $this->isHidden => 0,
222
            $this->isDeleted => 0,
223
            $this->datePublished => true, // >> IS NOT NULL
224
            $this->idDocument => true // >> will get documents only
225
        ];
226
227
        // This way the default ones can be overwritten.
228
        $expressions = array_merge($defaultExpressions, $additionalExpressions);
229
230
        $options = [
231
            ConnectorInterface::OPTION_ORDER => ($order ?? $this->datePublished.' DESC')
232
        ];
233
234
        if (is_numeric($limit)) {
235
            $options[ConnectorInterface::OPTION_LIMIT] = (int) $limit;
236
237
            if (is_numeric($offset)) {
238
                $options[ConnectorInterface::OPTION_OFFSET] = (int) $offset;
239
            }
240
        }
241
242
        if (!empty($groupBy)) {
243
            $options[ConnectorInterface::OPTION_GROUP] = $groupBy;
244
245
            if (!empty($having)) {
246
                $options[ConnectorInterface::OPTION_HAVING] = $having;
247
            }
248
        }
249
250
        /** @var FilesystemEntity[] $dataEntitySet */
251
        $dataEntitySet = $this->getDataEntitySet($expressions, $options);
252
253
        return $dataEntitySet;
254
    }
255
256
    /**
257
     * Gets the published documents by author id
258
     *
259
     * @param int $applicationId
260
     * @param int $userId
261
     * @param string|null $order
262
     * @param int|null $limit
263
     * @param int|null $offset
264
     * @return array
265
     */
266
    public function getPublishedDocumentsByAuthor(
267
        int $applicationId,
268
        int $userId,
269
        string $order = null,
270
        int $limit = null,
271
        int $offset = null
272
    ) : array {
273
        /** @var PDO $adapter */
274
        $adapter = $this->getConnector()->getDataDriver();
275
276
        if (empty($order)) {
277
            $order = $this->datePublished.' DESC';
278
        }
279
280
        $query = file_get_contents(__DIR__.'/SpecialQueries/getPublishedDocumentsByAuthor.sql');
281
282
        if (is_numeric($limit)) {
283
            $query .= ' LIMIT :limit';
284
285
            if (is_numeric($offset)) {
286
                $query .= ' OFFSET :offset';
287
            }
288
        }
289
290
        $statement = $adapter->prepare($query);
291
        $statement->bindParam(':applicationId', $applicationId, PDO::PARAM_INT);
292
        $statement->bindParam(':userId', $userId, PDO::PARAM_INT);
293
        $statement->bindParam(':orderBy', $order, PDO::PARAM_STR);
294
295
        if (is_numeric($limit)) {
296
            $statement->bindParam(':limit', $limit, PDO::PARAM_INT);
297
298
            if (is_numeric($offset)) {
299
                $statement->bindParam(':offset', $offset, PDO::PARAM_INT);
300
            }
301
        }
302
303
        $statement->execute();
304
        $dataList = $statement->fetchAll(PDO::FETCH_ASSOC);
305
306
        return $this->getEntitySetFromDataSet($dataList);
307
    }
308
309
    /**
310
     * Gets the published documents by tag id
311
     *
312
     * @param int $applicationId
313
     * @param int $filesystemTagId
314
     * @param string|null $order
315
     * @param int|null $limit
316
     * @param int|null $offset
317
     * @return array
318
     */
319
    public function getPublishedDocumentsByTag(
320
        int $applicationId,
321
        int $filesystemTagId,
322
        string $order = null,
323
        int $limit = null,
324
        int $offset = null
325
    ) : array {
326
        /** @var PDO $adapter */
327
        $adapter = $this->getConnector()->getDataDriver();
328
329
        if (empty($order)) {
330
            $order = $this->datePublished.' DESC';
331
        }
332
333
        $query = file_get_contents(__DIR__.'/SpecialQueries/getPublishedDocumentsByTag.sql');
334
335
        if (is_numeric($limit)) {
336
            $query .= ' LIMIT :limit';
337
338
            if (is_numeric($offset)) {
339
                $query .= ' OFFSET :offset';
340
            }
341
        }
342
343
        $statement = $adapter->prepare($query);
344
        $statement->bindParam(':applicationId', $applicationId, PDO::PARAM_INT);
345
        $statement->bindParam(':tagId', $filesystemTagId, PDO::PARAM_INT);
346
        $statement->bindParam(':orderBy', $order, PDO::PARAM_STR);
347
348
        if (is_numeric($limit)) {
349
            $statement->bindParam(':limit', $limit, PDO::PARAM_INT);
350
351
            if (is_numeric($offset)) {
352
                $statement->bindParam(':offset', $offset, PDO::PARAM_INT);
353
            }
354
        }
355
356
        $statement->execute();
357
        $dataList = $statement->fetchAll(PDO::FETCH_ASSOC);
358
359
        return $this->getEntitySetFromDataSet($dataList);
360
    }
361
362
    /**
363
     * Gets simple structured meta information for a filesystem record.
364
     *
365
     * @param int $filesystemId
366
     * @return array
367
     */
368
    public function getPublicationMeta(int $filesystemId) : array
369
    {
370
        $filesystemMetaSet = [];
371
372
        /** @var ConnectorInterface $connector */
373
        $connector = $this->getConnector();
374
375
        // Switch to another data group (DO NOT FORGET TO SET IT BACK!!)
376
        $connector->setDataGroup('webhemi_filesystem_meta')
377
            ->setIdKey('id_filesystem_meta');
378
379
        $filesystemRecord = $connector->getDataSet(['fk_filesystem' => $filesystemId]);
380
381
        // switch back to the original data group
382
        $connector->setDataGroup($this->dataGroup)
383
            ->setIdKey($this->idKey);
384
385
        foreach ($filesystemRecord as $data) {
386
            $key = lcfirst(StringLib::convertUnderscoreToCamelCase($data['meta_key']));
387
            $filesystemMetaSet[$key] = $data['meta_data'];
388
        }
389
390
        return $filesystemMetaSet;
391
    }
392
}
393