ItemHandler::create()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 10
rs 10
1
<?php declare(strict_types=1);
2
3
namespace XoopsModules\Publisher;
4
5
/*
6
 You may not change or alter any portion of this comment or credits
7
 of supporting developers from this source code or any supporting source code
8
 which is considered copyrighted (c) material of the original comment or credit authors.
9
10
 This program is distributed in the hope that it will be useful,
11
 but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 */
14
15
/**
16
 * @copyright       XOOPS Project (https://xoops.org)
17
 * @license         https://www.fsf.org/copyleft/gpl.html GNU public license
18
 * @since           1.0
19
 * @author          trabis <[email protected]>
20
 * @author          The SmartFactory <www.smartfactory.ca>
21
 */
22
23
/** @var Helper $this- >helper */
24
/** @var Item $obj */
25
require_once \dirname(__DIR__) . '/include/common.php';
26
27
/**
28
 * Items handler class.
29
 * This class is responsible for providing data access mechanisms to the data source
30
 * of Q&A class objects.
31
 *
32
 * @author  marcan <[email protected]>
33
 */
34
class ItemHandler extends \XoopsPersistableObjectHandler
35
{
36
    private const TABLE      = 'publisher_items';
37
    private const ENTITY     = Item::class;
38
    private const ENTITYNAME = 'Item';
39
    private const KEYNAME    = 'itemid';
40
    private const IDENTIFIER = 'title';
41
    /**
42
     * @var Helper
43
     */
44
    public    $helper;
45
    public    $publisherIsAdmin;
46
    protected $resultCatCounts = [];
47
48
    public function __construct(?\XoopsDatabase $db = null, ?Helper $helper = null)
49
    {
50
        $this->helper           = $helper ?? Helper::getInstance();
51
        $this->db               = $db;
52
        $this->publisherIsAdmin = $this->helper->isUserAdmin();
53
        parent::__construct($db, static::TABLE, static::ENTITY, static::KEYNAME, static::IDENTIFIER);
54
    }
55
56
    /**
57
     * @param bool $isNew
58
     *
59
     * @return \XoopsObject
60
     */
61
    public function create($isNew = true)
62
    {
63
        /** @var Item $obj */
64
        $obj = parent::create($isNew);
65
        if ($isNew) {
66
            $obj->setDefaultPermissions();
67
        }
68
        $obj->helper = $this->helper;
69
70
        return $obj;
71
    }
72
73
    /**
74
     * retrieve an item
75
     *
76
     * @param null|int   $id itemid of the user
77
     *
78
     * @param array|null $fields
79
     * @return mixed reference to the <a href='psi_element://Item'>Item</a> object, FALSE if failed
80
     */
81
    public function get($id = null, $fields = null)
82
    {
83
        $obj = parent::get($id);
84
        if (\is_object($obj)) {
85
            $obj->assignOtherProperties();
0 ignored issues
show
Bug introduced by
The method assignOtherProperties() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as XoopsModules\Publisher\Item or XoopsModules\Publisher\File or XoopsModules\Publisher\Category. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

85
            $obj->/** @scrutinizer ignore-call */ 
86
                  assignOtherProperties();
Loading history...
86
        }
87
88
        return $obj;
89
    }
90
91
    /**
92
     * insert a new item in the database
93
     *
94
     * @param \XoopsObject $item reference to the {@link Item}
95
     *                           object
96
     * @param bool         $force
97
     *
98
     * @return bool FALSE if failed, TRUE if already present and unchanged or successful
99
     */
100
    public function insert(\XoopsObject $item, $force = false)  //insert(&$item, $force = false)
101
    {
102
        if (!$item->meta_keywords() || !$item->meta_description() || !$item->short_url()) {
0 ignored issues
show
Bug introduced by
The method meta_keywords() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as XoopsModules\Publisher\Item or XoopsModules\Publisher\File or XoopsModules\Publisher\Category. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

102
        if (!$item->/** @scrutinizer ignore-call */ meta_keywords() || !$item->meta_description() || !$item->short_url()) {
Loading history...
Bug introduced by
The method short_url() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as XoopsModules\Publisher\Item or XoopsModules\Publisher\File or XoopsModules\Publisher\Category. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

102
        if (!$item->meta_keywords() || !$item->meta_description() || !$item->/** @scrutinizer ignore-call */ short_url()) {
Loading history...
Bug introduced by
The method meta_description() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as XoopsModules\Publisher\Item or XoopsModules\Publisher\File or XoopsModules\Publisher\Category. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

102
        if (!$item->meta_keywords() || !$item->/** @scrutinizer ignore-call */ meta_description() || !$item->short_url()) {
Loading history...
103
            $publisherMetagen = new Metagen($item->getTitle(), $item->getVar('meta_keywords'), $item->getVar('summary'));
0 ignored issues
show
Bug introduced by
It seems like $item->getVar('summary') can also be of type array and array; however, parameter $description of XoopsModules\Publisher\Metagen::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

103
            $publisherMetagen = new Metagen($item->getTitle(), $item->getVar('meta_keywords'), /** @scrutinizer ignore-type */ $item->getVar('summary'));
Loading history...
Bug introduced by
It seems like $item->getVar('meta_keywords') can also be of type array and array; however, parameter $keywords of XoopsModules\Publisher\Metagen::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

103
            $publisherMetagen = new Metagen($item->getTitle(), /** @scrutinizer ignore-type */ $item->getVar('meta_keywords'), $item->getVar('summary'));
Loading history...
Bug introduced by
The method getTitle() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as XoopsModules\Publisher\Item or XoopsModules\Publisher\File or XoopsModules\Publisher\Category. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

103
            $publisherMetagen = new Metagen($item->/** @scrutinizer ignore-call */ getTitle(), $item->getVar('meta_keywords'), $item->getVar('summary'));
Loading history...
104
            // Auto create meta tags if empty
105
            if (!$item->meta_keywords()) {
106
                $item->setVar('meta_keywords', $publisherMetagen->keywords);
107
            }
108
            if (!$item->meta_description()) {
109
                $item->setVar('meta_description', $publisherMetagen->description);
110
            }
111
            // Auto create short_url if empty
112
            if (!$item->short_url()) {
113
                $item->setVar('short_url', \mb_substr(Metagen::generateSeoTitle($item->getVar('title', 'n'), false), 0, 254));
114
            }
115
        }
116
        if (!parent::insert($item, $force)) {
117
            return false;
118
        }
119
        if (\class_exists(\XoopsModules\Tag\TagHandler::class) && \xoops_isActiveModule('tag')) {
120
            // Storing tags information
121
            /** @var \XoopsModules\Tag\TagHandler $tagHandler */
122
            $tagHandler = \XoopsModules\Tag\Helper::getInstance()
123
                                                  ->getHandler('Tag');
124
            $tagHandler->updateByItem($item->getVar('item_tag'), $item->getVar('itemid'), $this->helper->getDirname(), 0);
125
        }
126
127
        return true;
128
    }
129
130
    /**
131
     * delete an item from the database
132
     *
133
     * @param \XoopsObject $item reference to the ITEM to delete
134
     * @param bool         $force
135
     *
136
     * @return bool FALSE if failed.
137
     */
138
    public function delete(\XoopsObject $item, $force = false)
139
    {
140
        // Deleting the files
141
        if (!$this->helper->getHandler('File')
142
                          ->deleteItemFiles($item)) {
143
            $item->setErrors(\_AM_PUBLISHER_FILE_DELETE_ERROR);
144
        }
145
        if (!parent::delete($item, $force)) {
146
            $item->setErrors(\_AM_PUBLISHER_ITEM_DELETE_ERROR);
147
148
            return false;
149
        }
150
        // Removing tags information
151
        if (\class_exists(\XoopsModules\Tag\TagHandler::class) && \xoops_isActiveModule('tag')) {
152
            /** @var \XoopsModules\Tag\TagHandler $tagHandler */
153
            $tagHandler = \XoopsModules\Tag\Helper::getInstance()
154
                                                  ->getHandler('Tag');
155
            $tagHandler->updateByItem('', $item->getVar('itemid'), $this->helper->getDirname(), 0);
156
        }
157
158
        return true;
159
    }
160
161
    /**
162
     * retrieve items from the database
163
     *
164
     * @param \CriteriaElement|null $criteria           {@link CriteriaElement}
165
     *                                                  conditions to be met
166
     * @param bool|string           $idKey              what shall we use as array key ? none, itemid, categoryid
167
     * @param bool                  $as_object
168
     * @param string|null           $notNullFields
169
     * @return array           array of <a href='psi_element://Item'>Item</a> objects
170
     */
171
    public function &getObjects(?\CriteriaElement $criteria = null, $idKey = 'none', $as_object = true, $notNullFields = null)
172
    {
173
        $limit         = $start = 0;
174
        $ret           = [];
175
        $notNullFields = (null !== $notNullFields) ?: '';
176
177
        $sql = 'SELECT * FROM ' . $this->db->prefix($this->helper->getDirname() . '_items');
178
        if (null !== $criteria && ($criteria instanceof \Criteria || $criteria instanceof \CriteriaCompo)) {
179
            $whereClause = $criteria->renderWhere();
180
            if ('WHERE ()' !== $whereClause) {
181
                $sql .= ' ' . $criteria->renderWhere();
182
                if (!empty($notNullFields)) {
183
                    $sql .= $this->notNullFieldClause($notNullFields, true);
0 ignored issues
show
Bug introduced by
It seems like $notNullFields can also be of type true; however, parameter $notNullFields of XoopsModules\Publisher\I...r::notNullFieldClause() does only seem to accept array|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

183
                    $sql .= $this->notNullFieldClause(/** @scrutinizer ignore-type */ $notNullFields, true);
Loading history...
184
                }
185
            } elseif (!empty($notNullFields)) {
186
                $sql .= ' WHERE ' . $this->notNullFieldClause($notNullFields);
187
            }
188
            if ('' != $criteria->getSort()) {
189
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
190
            }
191
            $limit = $criteria->getLimit();
192
            $start = $criteria->getStart();
193
        } elseif (!empty($notNullFields)) {
194
            $sql .= $sql .= ' WHERE ' . $this->notNullFieldClause($notNullFields);
195
        }
196
        $result = $this->db->query($sql, $limit, $start);
197
        if (!$result || 0 === $GLOBALS['xoopsDB']->getRowsNum($result)) {
198
            return $ret;
199
        }
200
        $theObjects = [];
201
        while (false !== ($myrow = $this->db->fetchArray($result))) {
202
            //            $item = new Item();
203
            $item = $this->create();
204
            $item->assignVars($myrow);
205
            $theObjects[$myrow['itemid']] = $item;
206
            unset($item);
207
        }
208
        foreach ($theObjects as $theObject) {
209
            if ('none' === $idKey) {
210
                $ret[] = $theObject;
211
            } elseif ('itemid' === $idKey) {
212
                $ret[$theObject->itemid()] = $theObject;
213
            } else {
214
                $ret[$theObject->getVar($idKey)][$theObject->itemid()] = $theObject;
215
            }
216
            unset($theObject);
217
        }
218
219
        return $ret;
220
    }
221
222
    /**
223
     * count items matching a condition
224
     *
225
     * @param \CriteriaElement|null $criteria Criteria to match
226
     * @param string|null           $notNullFields
227
     *
228
     * @return int count of items
229
     */
230
    public function getCount(?\CriteriaElement $criteria = null, $notNullFields = null)
231
    {
232
        //        $notNullFields = $notNullFields ?? null;
233
        $sql = 'SELECT COUNT(*) FROM ' . $this->db->prefix($this->helper->getDirname() . '_items');
234
        if (null !== $criteria && ($criteria instanceof \Criteria || $criteria instanceof \CriteriaCompo)) {
235
            $whereClause = $criteria->renderWhere();
236
            if ('WHERE ()' !== $whereClause) {
237
                $sql .= ' ' . $criteria->renderWhere();
238
                if (!empty($notNullFields)) {
239
                    $sql .= $this->notNullFieldClause($notNullFields, true);
240
                }
241
            } elseif (!empty($notNullFields)) {
242
                $sql .= ' WHERE ' . $this->notNullFieldClause($notNullFields);
243
            }
244
        } elseif (!empty($notNullFields)) {
245
            $sql .= ' WHERE ' . $this->notNullFieldClause($notNullFields);
246
        }
247
        $result = $this->db->query($sql);
248
        if (!$result) {
249
            return 0;
250
        }
251
        [$count] = $this->db->fetchRow($result);
252
253
        return $count;
254
    }
255
256
    /**
257
     * @param int                 $categoryid
258
     * @param string|array        $status
259
     * @param string|null         $notNullFields
260
     * @param null|\CriteriaCompo $criteriaPermissions
261
     * @return \CriteriaCompo
262
     */
263
    private function getItemsCriteria($categoryid = -1, $status = '', $notNullFields = null, $criteriaPermissions = null)
0 ignored issues
show
Unused Code introduced by
The parameter $notNullFields is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

263
    private function getItemsCriteria($categoryid = -1, $status = '', /** @scrutinizer ignore-unused */ $notNullFields = null, $criteriaPermissions = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
264
    {
265
        //        $notNullFields = (null !== $notNullFields) ?: '';
266
        //        global $publisherIsAdmin;
267
        //        $ret = 0;
268
        //        if (!$publisherIsAdmin) {
269
        //            $criteriaPermissions = new \CriteriaCompo();
270
        //            // Categories for which user has access
271
        //            $categoriesGranted = $this->helper->getHandler('Permission')->getGrantedItems('category_read');
272
        //            if (!empty($categoriesGranted)) {
273
        //                $grantedCategories = new \Criteria('categoryid', "(" . implode(',', $categoriesGranted) . ")", 'IN');
274
        //                $criteriaPermissions->add($grantedCategories, 'AND');
275
        //            } else {
276
        //                return $ret;
277
        //            }
278
        //        }
279
280
        $criteriaCategory = null;
281
        if (isset($categoryid) && -1 !== $categoryid) {
282
            $criteriaCategory = new \Criteria('categoryid', $categoryid);
283
        }
284
285
        $criteriaStatus = new \CriteriaCompo();
286
        if (!empty($status) && \is_array($status)) {
287
            foreach ($status as $v) {
288
                $criteriaStatus->add(new \Criteria('status', $v), 'OR');
289
            }
290
        } elseif (!empty($status) && -1 !== $status) {
291
            $criteriaStatus->add(new \Criteria('status', $status), 'OR');
292
        }
293
294
        $criteria = new \CriteriaCompo();
295
        if (null !== $criteriaCategory) {
296
            $criteria->add($criteriaCategory);
297
        }
298
299
        if (null !== $criteriaPermissions) {
300
            $criteria->add($criteriaPermissions);
301
        }
302
303
        if (null !== $criteriaStatus) {
304
            $criteria->add($criteriaStatus);
305
        }
306
307
        return $criteria;
308
    }
309
310
    /**
311
     * @param             $categoryid
312
     * @param string      $status
313
     * @param string|null $notNullFields
314
     *
315
     * @return int
316
     */
317
    public function getItemsCount($categoryid = -1, $status = '', $notNullFields = null)
318
    {
319
        //        $notNullFields       = $notNullFields ?? null;
320
        $criteriaPermissions = null;
321
        if (!$this->publisherIsAdmin) {
322
            $criteriaPermissions = new \CriteriaCompo();
323
            // Categories for which user has access
324
            $categoriesGranted = $this->helper->getHandler('Permission')
325
                                              ->getGrantedItems('category_read');
326
            if (!empty($categoriesGranted)) {
327
                $grantedCategories = new \Criteria('categoryid', '(' . \implode(',', $categoriesGranted) . ')', 'IN');
328
                $criteriaPermissions->add($grantedCategories, 'AND');
329
            } else {
330
                return 0;
331
            }
332
        }
333
        //        $ret = [];
334
        $criteria = $this->getItemsCriteria($categoryid, $status, $notNullFields, $criteriaPermissions);
335
336
        $ret = $this->getCount($criteria, $notNullFields);
337
338
        return $ret;
339
    }
340
341
    /**
342
     * @param int         $limit
343
     * @param int         $start
344
     * @param int         $categoryid
345
     * @param string      $sort
346
     * @param string      $order
347
     * @param string|null $notNullFields
348
     * @param bool        $asObject
349
     * @param string      $idKey
350
     * @param bool        $excludeExpired
351
     *
352
     * @return array
353
     */
354
    public function getAllPublished($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = null, $asObject = true, $idKey = 'none', $excludeExpired = true)
355
    {
356
        $notNullFields = (null !== $notNullFields) ?: '';
357
        $otherCriteria = new \CriteriaCompo();
358
        if (!$this->publisherIsAdmin) {
359
            $criteriaDateSub = new \Criteria('datesub', \time(), '<=');
360
            $otherCriteria->add($criteriaDateSub);
361
        }
362
        if ($excludeExpired) {
363
            // by default expired items are excluded from list of published items
364
            $criteriaExpire = new \CriteriaCompo();
365
            $criteriaExpire->add(new \Criteria('dateexpire', '0'), 'OR');
366
            $criteriaExpire->add(new \Criteria('dateexpire', \time(), '>='), 'OR');
367
            $otherCriteria->add($criteriaExpire);
368
        }
369
370
        return $this->getItems($limit, $start, [Constants::PUBLISHER_STATUS_PUBLISHED], $categoryid, $sort, $order, $notNullFields, $asObject, $otherCriteria, $idKey);
0 ignored issues
show
Bug introduced by
It seems like $notNullFields can also be of type true; however, parameter $notNullFields of XoopsModules\Publisher\ItemHandler::getItems() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

370
        return $this->getItems($limit, $start, [Constants::PUBLISHER_STATUS_PUBLISHED], $categoryid, $sort, $order, /** @scrutinizer ignore-type */ $notNullFields, $asObject, $otherCriteria, $idKey);
Loading history...
371
    }
372
373
    /**
374
     * @param int         $limit
375
     * @param int         $start
376
     * @param int         $categoryid
377
     * @param string      $sort
378
     * @param string      $order
379
     * @param string|null $notNullFields
380
     * @param bool        $asObject
381
     * @param string      $idKey
382
     *
383
     * @return array
384
     */
385
    public function getAllExpired($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = null, $asObject = true, $idKey = 'none')
386
    {
387
        $notNullFields = (null !== $notNullFields) ?: '';
388
        $otherCriteria = new \CriteriaCompo();
389
        $otherCriteria->add(new \Criteria('dateexpire', \time(), '<='));
390
        $otherCriteria->add(new \Criteria('dateexpire', 0, '>'));
391
392
        return $this->getItems($limit, $start, -1, $categoryid, $sort, $order, $notNullFields, $asObject, $otherCriteria, $idKey);
0 ignored issues
show
Bug introduced by
It seems like $notNullFields can also be of type true; however, parameter $notNullFields of XoopsModules\Publisher\ItemHandler::getItems() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

392
        return $this->getItems($limit, $start, -1, $categoryid, $sort, $order, /** @scrutinizer ignore-type */ $notNullFields, $asObject, $otherCriteria, $idKey);
Loading history...
393
    }
394
395
    /**
396
     * @param Item $obj
397
     *
398
     * @return bool
399
     */
400
    public function getPreviousPublished($obj)
401
    {
402
        $ret           = false;
403
        $otherCriteria = new \CriteriaCompo();
404
        $otherCriteria->add(new \Criteria('datesub', $obj->getVar('datesub'), '<'));
0 ignored issues
show
Bug introduced by
It seems like $obj->getVar('datesub') can also be of type array and array; however, parameter $value of Criteria::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

404
        $otherCriteria->add(new \Criteria('datesub', /** @scrutinizer ignore-type */ $obj->getVar('datesub'), '<'));
Loading history...
405
        $objs = $this->getItems(1, 0, [Constants::PUBLISHER_STATUS_PUBLISHED], $obj->getVar('categoryid'), 'datesub', 'DESC', '', true, $otherCriteria, 'none');
406
        if (\count($objs) > 0) {
407
            $ret = $objs[0];
408
        }
409
410
        return $ret;
411
    }
412
413
    /**
414
     * @param Item $obj
415
     *
416
     * @return bool
417
     */
418
    public function getNextPublished($obj)
419
    {
420
        $ret           = false;
421
        $otherCriteria = new \CriteriaCompo();
422
        $otherCriteria->add(new \Criteria('datesub', $obj->getVar('datesub'), '>'));
0 ignored issues
show
Bug introduced by
It seems like $obj->getVar('datesub') can also be of type array and array; however, parameter $value of Criteria::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

422
        $otherCriteria->add(new \Criteria('datesub', /** @scrutinizer ignore-type */ $obj->getVar('datesub'), '>'));
Loading history...
423
        $otherCriteria->add(new \Criteria('datesub', \time(), '<='));
424
        $objs = $this->getItems(1, 0, [Constants::PUBLISHER_STATUS_PUBLISHED], $obj->getVar('categoryid'), 'datesub', 'ASC', '', true, $otherCriteria, 'none');
425
        if (\count($objs) > 0) {
426
            $ret = $objs[0];
427
        }
428
429
        return $ret;
430
    }
431
432
    /**
433
     * @param int         $limit
434
     * @param int         $start
435
     * @param int         $categoryid
436
     * @param string      $sort
437
     * @param string      $order
438
     * @param string|null $notNullFields
439
     * @param bool        $asObject
440
     * @param string      $idKey
441
     *
442
     * @return array
443
     */
444
    public function getAllSubmitted($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = null, $asObject = true, $idKey = 'none')
445
    {
446
        $notNullFields = (null !== $notNullFields) ?: '';
447
448
        return $this->getItems($limit, $start, [Constants::PUBLISHER_STATUS_SUBMITTED], $categoryid, $sort, $order, $notNullFields, $asObject, null, $idKey);
0 ignored issues
show
Bug introduced by
It seems like $notNullFields can also be of type true; however, parameter $notNullFields of XoopsModules\Publisher\ItemHandler::getItems() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

448
        return $this->getItems($limit, $start, [Constants::PUBLISHER_STATUS_SUBMITTED], $categoryid, $sort, $order, /** @scrutinizer ignore-type */ $notNullFields, $asObject, null, $idKey);
Loading history...
449
    }
450
451
    /**
452
     * @param int    $limit
453
     * @param int    $start
454
     * @param int    $categoryid
455
     * @param string $sort
456
     * @param string $order
457
     * @param string $notNullFields
458
     * @param bool   $asObject
459
     * @param string $idKey
460
     *
461
     * @return array
462
     */
463
    public function getAllOffline($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asObject = true, $idKey = 'none')
464
    {
465
        return $this->getItems($limit, $start, [Constants::PUBLISHER_STATUS_OFFLINE], $categoryid, $sort, $order, $notNullFields, $asObject, null, $idKey);
466
    }
467
468
    /**
469
     * @param int    $limit
470
     * @param int    $start
471
     * @param int    $categoryid
472
     * @param string $sort
473
     * @param string $order
474
     * @param string $notNullFields
475
     * @param bool   $asObject
476
     * @param string $idKey
477
     *
478
     * @return array
479
     */
480
    public function getAllRejected($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asObject = true, $idKey = 'none')
481
    {
482
        return $this->getItems($limit, $start, [Constants::PUBLISHER_STATUS_REJECTED], $categoryid, $sort, $order, $notNullFields, $asObject, null, $idKey);
483
    }
484
485
    /**
486
     * @param int                 $limit
487
     * @param int                 $start
488
     * @param array|string        $status
489
     * @param int                 $categoryid
490
     * @param string              $sort
491
     * @param string              $order
492
     * @param string|null         $notNullFields
493
     * @param bool                $asObject
494
     * @param null|\CriteriaCompo $otherCriteria
495
     * @param bool|string         $idKey
496
     * @return array
497
     * @internal param bool $asObject
498
     */
499
    public function getItems($limit = 0, $start = 0, $status = '', $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = null, $asObject = true, $otherCriteria = null, $idKey = 'none')
0 ignored issues
show
Unused Code introduced by
The parameter $asObject is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

499
    public function getItems($limit = 0, $start = 0, $status = '', $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = null, /** @scrutinizer ignore-unused */ $asObject = true, $otherCriteria = null, $idKey = 'none')

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
500
    {
501
        $notNullFields       = (null !== $notNullFields) ?: '';
502
        $criteriaPermissions = null;
503
        if (!$this->publisherIsAdmin) {
504
            $criteriaPermissions = new \CriteriaCompo();
505
            // Categories for which user has access
506
            $categoriesGranted = $this->helper->getHandler('Permission')
507
                                              ->getGrantedItems('category_read');
508
            if (!empty($categoriesGranted)) {
509
                $grantedCategories = new \Criteria('categoryid', '(' . \implode(',', $categoriesGranted) . ')', 'IN');
510
                $criteriaPermissions->add($grantedCategories, 'AND');
511
            } else {
512
                return [];
513
            }
514
        }
515
516
        $criteria = $this->getItemsCriteria($categoryid, $status, $notNullFields, $criteriaPermissions);
0 ignored issues
show
Bug introduced by
It seems like $notNullFields can also be of type true; however, parameter $notNullFields of XoopsModules\Publisher\I...ler::getItemsCriteria() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

516
        $criteria = $this->getItemsCriteria($categoryid, $status, /** @scrutinizer ignore-type */ $notNullFields, $criteriaPermissions);
Loading history...
517
        /*
518
                if (isset($categoryid) && $categoryid != -1) {
519
                    $criteriaCategory = new \Criteria('categoryid', $categoryid);
520
                }
521
                $criteriaStatus = new \CriteriaCompo();
522
                if (!empty($status) && \is_array($status)) {
523
                    foreach ($status as $v) {
524
                        $criteriaStatus->add(new \Criteria('status', $v), 'OR');
525
                    }
526
                } elseif (!empty($status) && $status != -1) {
527
                    $criteriaStatus->add(new \Criteria('status', $status), 'OR');
528
                }
529
                $criteria = new \CriteriaCompo();
530
                if (!empty($criteriaCategory)) {
531
                    $criteria->add($criteriaCategory);
532
                }
533
                if (!empty($criteriaPermissions)) {
534
                    $criteria->add($criteriaPermissions);
535
                }
536
                if (!empty($criteriaStatus)) {
537
                    $criteria->add($criteriaStatus);
538
                }
539
        */
540
        //        $ret  = [];
541
542
        if (null !== $otherCriteria) {
543
            $criteria->add($otherCriteria);
544
        }
545
        $criteria->setLimit($limit);
546
        $criteria->setStart($start);
547
        $criteria->setSort($sort);
548
        $criteria->order = $order; // patch for XOOPS <= 2.5.10 does not set order correctly using setOrder() method
549
        $ret             = &$this->getObjects($criteria, $idKey, true);
550
551
        return $ret;
552
    }
553
554
    /**
555
     * @param string $field
556
     * @param string $status
557
     * @param int    $categoryid
558
     *
559
     * @return bool
560
     * @throws \Exception
561
     */
562
    public function getRandomItem($field = '', $status = '', $categoryid = -1)
563
    {
564
        $ret           = false;
565
        $notNullFields = $field;
566
        // Getting the number of published Items
567
        $totalItems = $this->getItemsCount($categoryid, $status, $notNullFields);
568
        if ($totalItems > 0) {
569
            --$totalItems;
570
            $entryNumber = \random_int(0, $totalItems);
571
            //            $entryNumber2 = random_int(0, $totalItems);
572
573
            $item = $this->getItems(1, $entryNumber, $status, $categoryid, $sort = 'datesub', $order = 'DESC', $notNullFields);
574
            if ($item) {
575
                $ret = $item[0];
576
            }
577
        }
578
579
        return $ret;
580
    }
581
582
    /**
583
     * delete Items matching a set of conditions
584
     *
585
     * @param \CriteriaElement|null $criteria {@link CriteriaElement}
586
     *
587
     * @param bool                  $force
588
     * @param bool                  $asObject
589
     * @return bool FALSE if deletion failed
590
     */
591
    public function deleteAll(?\CriteriaElement $criteria = null, $force = true, $asObject = false) //deleteAll($criteria = null)
592
    {
593
        //todo resource consuming, use get list instead?
594
        $items = &$this->getObjects($criteria);
595
        foreach ($items as $item) {
596
            $this->delete($item);
597
        }
598
599
        return true;
600
    }
601
602
    /**
603
     * @param $itemId
604
     *
605
     * @return bool
606
     */
607
    public function updateCounter($itemId)
608
    {
609
        $sql = 'UPDATE ' . $this->db->prefix($this->helper->getDirname() . '_items') . ' SET counter=counter+1 WHERE itemid = ' . $itemId;
610
        if ($this->db->queryF($sql)) {
611
            return true;
612
        }
613
614
        return false;
615
    }
616
617
    /**
618
     * @param string|array $notNullFields
619
     * @param bool         $withAnd
620
     *
621
     * @return string
622
     */
623
    public function notNullFieldClause($notNullFields = '', $withAnd = false)
624
    {
625
        $ret = '';
626
        if ($withAnd) {
627
            $ret .= ' AND ';
628
        }
629
        if (!empty($notNullFields) && \is_array($notNullFields)) {
630
            foreach ($notNullFields as $v) {
631
                $ret .= " ($v IS NOT NULL AND $v <> ' ' )";
632
            }
633
        } elseif (!empty($notNullFields)) {
634
            $ret .= " ($notNullFields IS NOT NULL AND $notNullFields <> ' ' )";
635
        }
636
637
        return $ret;
638
    }
639
640
    /**
641
     * @param array        $queryArray
642
     * @param string       $andor
643
     * @param int          $limit
644
     * @param int          $offset
645
     * @param int|array    $userid
646
     * @param array        $categories
647
     * @param int|string   $sortby
648
     * @param string|array $searchin
649
     * @param string       $extra
650
     *
651
     * @return array
652
     */
653
    public function getItemsFromSearch($queryArray = [], $andor = 'AND', $limit = 0, $offset = 0, $userid = 0, $categories = [], $sortby = 0, $searchin = '', $extra = '')
0 ignored issues
show
Unused Code introduced by
The parameter $extra is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

653
    public function getItemsFromSearch($queryArray = [], $andor = 'AND', $limit = 0, $offset = 0, $userid = 0, $categories = [], $sortby = 0, $searchin = '', /** @scrutinizer ignore-unused */ $extra = '')

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
654
    {
655
        $count            = 0;
0 ignored issues
show
Unused Code introduced by
The assignment to $count is dead and can be removed.
Loading history...
656
        $ret              = [];
657
        $criteriaKeywords = $criteriaPermissions = $criteriaUser = null;
658
        /** @var \XoopsGroupPermHandler $grouppermHandler */
659
        $grouppermHandler = \xoops_getHandler('groupperm');
660
        $groups           = \is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->getGroups() : XOOPS_GROUP_ANONYMOUS;
661
        $searchin         = empty($searchin) ? ['title', 'body', 'summary'] : (\is_array($searchin) ? $searchin : [$searchin]);
662
        if (\in_array('all', $searchin, true) || 0 === \count($searchin)) {
663
            $searchin = ['title', 'subtitle', 'body', 'summary', 'meta_keywords'];
664
            //add support for searching in tags if Tag module exists and is active
665
            if (false !== $this->helper::getHelper('tag')) {
666
                $searchin[] = 'item_tag';
667
            }
668
        }
669
        if ($userid && \is_array($userid)) {
670
            $userid       = \array_map('\intval', $userid);
671
            $criteriaUser = new \CriteriaCompo();
672
            $criteriaUser->add(new \Criteria('uid', '(' . \implode(',', $userid) . ')', 'IN'), 'OR');
673
        } elseif (\is_numeric($userid) && $userid > 0) {
674
            $criteriaUser = new \CriteriaCompo();
675
            $criteriaUser->add(new \Criteria('uid', $userid), 'OR');
676
        }
677
678
        //        if (is_array($queryArray)) {
679
        //            $count = count($queryArray);
680
        //        }
681
        if ($queryArray && \is_array($queryArray)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $queryArray of type array 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...
682
            $criteriaKeywords = new \CriteriaCompo();
683
            foreach ($queryArray as $iValue) {
684
                $criteriaKeyword = new \CriteriaCompo();
685
                foreach ($searchin as $searchField) {
686
                    $criteriaKeyword->add(new \Criteria($searchField, '%' . $iValue . '%', 'LIKE'), 'OR');
687
                }
688
                /*
689
                if (in_array('title', $searchin)) {
690
                    $criteriaKeyword->add(new \Criteria('title', '%' . $iValue . '%', 'LIKE'), 'OR');
691
                }
692
                if (in_array('subtitle', $searchin)) {
693
                    $criteriaKeyword->add(new \Criteria('subtitle', '%' . $iValue . '%', 'LIKE'), 'OR');
694
                }
695
                if (in_array('body', $searchin)) {
696
                    $criteriaKeyword->add(new \Criteria('body', '%' . $iValue . '%', 'LIKE'), 'OR');
697
                }
698
                if (in_array('summary', $searchin)) {
699
                    $criteriaKeyword->add(new \Criteria('summary', '%' . $iValue . '%', 'LIKE'), 'OR');
700
                }
701
                if (in_array('meta_keywords', $searchin)) {
702
                    $criteriaKeyword->add(new \Criteria('meta_keywords', '%' . $iValue . '%', 'LIKE'), 'OR');
703
                }
704
                */
705
                $criteriaKeywords->add($criteriaKeyword, $andor);
706
                unset($criteriaKeyword);
707
            }
708
        }
709
        if (!$this->publisherIsAdmin && (\count($categories) > 0)) {
710
            $criteriaPermissions = new \CriteriaCompo();
711
            // Categories for which user has access
712
            $categoriesGranted = $grouppermHandler->getItemIds(
713
                'category_read', $groups, $this->helper->getModule()
714
                                                       ->getVar('mid')
715
            );
716
            $categoriesGranted = \array_intersect($categoriesGranted, $categories);
717
            if (0 === \count($categoriesGranted)) {
718
                return $ret;
719
            }
720
            $grantedCategories = new \Criteria('categoryid', '(' . \implode(',', $categoriesGranted) . ')', 'IN');
721
            $criteriaPermissions->add($grantedCategories, 'AND');
722
        } elseif (\count($categories) > 0) {
723
            $criteriaPermissions = new \CriteriaCompo();
724
            $grantedCategories   = new \Criteria('categoryid', '(' . \implode(',', $categories) . ')', 'IN');
725
            $criteriaPermissions->add($grantedCategories, 'AND');
726
        }
727
        $criteriaItemsStatus = new \CriteriaCompo();
728
        $criteriaItemsStatus->add(new \Criteria('status', Constants::PUBLISHER_STATUS_PUBLISHED));
729
        $criteria = new \CriteriaCompo();
730
        if (null !== $criteriaUser) {
731
            $criteria->add($criteriaUser, 'AND');
732
        }
733
        if (null !== $criteriaKeywords) {
734
            $criteria->add($criteriaKeywords, 'AND');
735
        }
736
        if (null !== $criteriaPermissions) {
737
            $criteria->add($criteriaPermissions);
738
        }
739
        if (null !== $criteriaItemsStatus) {
740
            $criteria->add($criteriaItemsStatus, 'AND');
741
        }
742
        $criteria->setLimit($limit);
743
        $criteria->setStart($offset);
744
        if (empty($sortby)) {
745
            $sortby = 'datesub';
746
        }
747
        $criteria->setSort($sortby);
748
        $order = 'ASC';
749
        if ('datesub' === $sortby) {
750
            $order = 'DESC';
751
        }
752
        $criteria->order = $order; // patch for XOOPS <= 2.5.10, does not set order correctly using setOrder() method
753
        $ret             = &$this->getObjects($criteria);
754
755
        return $ret;
756
    }
757
758
    /**
759
     * @param array $categoriesObj
760
     * @param array $status
761
     *
762
     * @return array
763
     */
764
    public function getLastPublishedByCat($categoriesObj, $status = [Constants::PUBLISHER_STATUS_PUBLISHED])
765
    {
766
        $ret    = [];
767
        $catIds = [];
768
        foreach ($categoriesObj as $parentid) {
769
            foreach ($parentid as $category) {
770
                $catId          = $category->getVar('categoryid');
771
                $catIds[$catId] = $catId;
772
            }
773
        }
774
        if (empty($catIds)) {
775
            return $ret;
776
        }
777
        /*$cat  = [];
778
779
        $sql = "SELECT categoryid, MAX(datesub) as date FROM " . $this->db->prefix($this->helper->getDirname() . '_items') . " WHERE status IN (" . implode(',', $status) . ") GROUP BY categoryid";
780
        $result = $this->db->query($sql);
781
        while (false !== ($row = $this->db->fetchArray($result))) {
782
            $cat[$row['categoryid']] = $row['date'];
783
        }
784
        if (count($cat) == 0) return $ret;
785
        $sql = "SELECT categoryid, itemid, title, short_url, uid, datesub FROM " . $this->db->prefix($this->helper->getDirname() . '_items');
786
        $criteriaBig = new \CriteriaCompo();
787
        foreach ($cat as $id => $date) {
788
            $criteria = new \CriteriaCompo(new \Criteria('categoryid', $id));
789
            $criteria->add(new \Criteria('datesub', $date));
790
            $criteriaBig->add($criteria, 'OR');
791
            unset($criteria);
792
        }
793
        $sql .= " " . $criteriaBig->renderWhere();
794
        $result = $this->db->query($sql);
795
        while (false !== ($row = $this->db->fetchArray($result))) {
796
//            $item = new Item();
797
            $item = static::create();
798
            $item->assignVars($row);
799
            $ret[$row['categoryid']] = $item;
800
            unset($item);
801
        }
802
        */
803
        $sql    = 'SELECT mi.categoryid, mi.itemid, mi.title, mi.short_url, mi.uid, mi.datesub';
804
        $sql    .= ' FROM (SELECT categoryid, MAX(datesub) AS date FROM ' . $this->db->prefix($this->helper->getDirname() . '_items');
805
        $sql    .= ' WHERE status IN (' . \implode(',', $status) . ')';
806
        $sql    .= ' AND categoryid IN (' . \implode(',', $catIds) . ')';
807
        $sql    .= ' GROUP BY categoryid)mo';
808
        $sql    .= ' JOIN ' . $this->db->prefix($this->helper->getDirname() . '_items') . ' mi ON mi.datesub = mo.date';
809
        $result = $this->db->query($sql);
810
        while (false !== ($row = $this->db->fetchArray($result))) {
811
            // $item = new Item();
812
            $item = $this->create();
813
            $item->assignVars($row);
814
            $ret[$row['categoryid']] = $item;
815
            unset($item);
816
        }
817
818
        return $ret;
819
    }
820
821
    /**
822
     * @param         $parentid
823
     * @param         $catsCount
824
     * @param string  $spaces
825
     * @return int
826
     */
827
    public function countArticlesByCat($parentid, $catsCount, $spaces = '')
828
    {
829
        //        global $resultCatCounts;
830
        $newspaces = $spaces . '--';
831
        $thecount  = 0;
832
        foreach ($catsCount[$parentid] as $subCatId => $count) {
833
            $thecount                         += $count;
834
            $this->resultCatCounts[$subCatId] = $count;
835
            if (isset($catsCount[$subCatId])) {
836
                $thecount                         += $this->countArticlesByCat($subCatId, $catsCount, $newspaces);
837
                $this->resultCatCounts[$subCatId] = $thecount;
838
            }
839
        }
840
841
        return $thecount;
842
    }
843
844
    /**
845
     * @param int   $catId
846
     * @param array $status
847
     * @param bool  $inSubCat
848
     *
849
     * @return array
850
     */
851
    public function getCountsByCat($catId, $status, $inSubCat = false)
852
    {
853
        //        global $resultCatCounts;
854
855
        $ret       = [];
856
        $catsCount = [];
857
        $sql       = 'SELECT c.parentid, i.categoryid, COUNT(*) AS count FROM ' . $this->db->prefix($this->helper->getDirname() . '_items') . ' AS i INNER JOIN ' . $this->db->prefix($this->helper->getDirname() . '_categories') . ' AS c ON i.categoryid=c.categoryid';
858
        if ((int)$catId > 0) {
859
            $sql .= ' WHERE i.categoryid = ' . (int)$catId;
860
            $sql .= ' AND i.status IN (' . \implode(',', $status) . ')';
861
        } else {
862
            $sql .= ' WHERE i.status IN (' . \implode(',', $status) . ')';
863
        }
864
        $sql    .= ' GROUP BY i.categoryid ORDER BY c.parentid ASC, i.categoryid ASC';
865
        $result = $this->db->query($sql);
866
        if (!$result) {
867
            return $ret;
868
        }
869
        if (!$inSubCat) {
870
            while (false !== ($row = $this->db->fetchArray($result))) {
871
                $catsCount[$row['categoryid']] = $row['count'];
872
            }
873
874
            return $catsCount;
875
        }
876
        //        while (false !== ($row = $this->db->fetchArray($result))) {
877
        while (false !== ($row = $this->db->fetchArray($result))) {
878
            $catsCount[$row['parentid']][$row['categoryid']] = $row['count'];
879
        }
880
        //        $resultCatCounts = [];
881
        foreach ($catsCount[0] as $subCatId => $count) {
882
            $this->resultCatCounts[$subCatId] = $count;
883
            if (isset($catsCount[$subCatId])) {
884
                $this->resultCatCounts[$subCatId] += $this->countArticlesByCat($subCatId, $catsCount, '');
885
            }
886
        }
887
888
        return $this->resultCatCounts;
889
    }
890
}
891