Completed
Push — master ( 658b35...b781ca )
by Richard
28s queued 23s
created

ItemHandler   F

Complexity

Total Complexity 114

Size/Duplication

Total Lines 654
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 298
dl 0
loc 654
rs 2
c 0
b 0
f 0
wmc 114

20 Methods

Rating   Name   Duplication   Size   Complexity  
C getItems() 0 47 14
A getAllRejected() 0 3 1
F getItemsFromSearch() 0 92 28
A __construct() 0 4 1
A getAllSubmitted() 0 3 1
A getRandomItem() 0 17 3
C getItemsCount() 0 38 13
A getAllPublished() 0 5 1
A updateCounter() 0 10 2
A delete() 0 19 4
A getLastPublishedByCat() 0 40 5
B getCountsByCat() 0 51 8
A countArticlesByCat() 0 14 3
A getAllOffline() 0 3 1
B insert() 0 27 9
A getPreviousPublished() 0 11 2
A getItemCount() 0 19 4
A addNotNullFieldClause() 0 18 5
A getNextPublished() 0 12 2
B getItemObjects() 0 34 7

How to fix   Complexity   

Complex Class

Complex classes like ItemHandler often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ItemHandler, and based on these observations, apply Extract Interface, too.

1
<?php
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
use PDO;
16
use Xoops;
17
use Xoops\Core\Database\Connection;
18
use Xoops\Core\Database\QueryBuilder;
19
use Xoops\Core\Kernel\Criteria;
20
use Xoops\Core\Kernel\CriteriaCompo;
21
use Xoops\Core\Kernel\CriteriaElement;
22
use Xoops\Core\Kernel\XoopsObject;
23
use Xoops\Core\Kernel\XoopsPersistableObjectHandler;
24
use XoopsModules\Publisher;
25
26
/**
27
 * @copyright       The XUUPS Project http://sourceforge.net/projects/xuups/
28
 * @license         GNU GPL V2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
29
 * @package         Publisher
30
 * @since           1.0
31
 * @author          trabis <[email protected]>
32
 * @author          The SmartFactory <www.smartfactory.ca>
33
 * @version         $Id$
34
 */
35
require_once \dirname(__DIR__) . '/include/common.php';
36
37
/**
38
 * Items handler class.
39
 * This class is responsible for providing data access mechanisms to the data source
40
 * of Q&A class objects.
41
 *
42
 * @author  marcan <[email protected]>
43
 * @package Publisher
44
 */
45
class ItemHandler extends XoopsPersistableObjectHandler
46
{
47
    /**
48
     * @var Helper
49
     * @access public
50
     */
51
    public $helper = null;
52
53
    public function __construct(Connection $db)
54
    {
55
        parent::__construct($db, 'publisher_items', Item::class, 'itemid', 'title');
56
        $this->helper = Helper::getInstance();
57
    }
58
59
    /**
60
     * insert a new item in the database
61
     *
62
     * @param XoopsObject $item reference to the {@link Publisher\Item} object
63
     * @param bool        $force
64
     *
65
     * @return bool FALSE if failed, TRUE if already present and unchanged or successful
66
     */
67
    public function insert(XoopsObject $item, $force = true)
68
    {
69
        $xoops = Xoops::getInstance();
70
        if (!$item->getVar('meta_keywords') || !$item->getVar('meta_description') || !$item->getVar('short_url')) {
71
            $publisher_metagen = new Publisher\Metagen($item->title(), $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 string[]; 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

71
            $publisher_metagen = new Publisher\Metagen($item->title(), $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 string[]; 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

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

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

71
            $publisher_metagen = new Publisher\Metagen($item->/** @scrutinizer ignore-call */ title(), $item->getVar('meta_keywords'), $item->getVar('summary'));
Loading history...
72
            // Auto create meta tags if empty
73
            if (!$item->getVar('meta_keywords')) {
74
                $item->setVar('meta_keywords', $publisher_metagen->_keywords);
75
            }
76
            if (!$item->getVar('meta_description')) {
77
                $item->setVar('meta_description', $publisher_metagen->_description);
78
            }
79
            // Auto create short_url if empty
80
            if (!$item->getVar('short_url')) {
81
                $item->setVar('short_url', $publisher_metagen::generateSeoTitle($item->getVar('title', 'n'), false));
82
            }
83
        }
84
        if (!parent::insert($item, $force)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression parent::insert($item, $force) of type false|integer is loosely compared to false; this is ambiguous if the integer can be 0. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
85
            return false;
86
        }
87
        if ($xoops->isActiveModule('tag')) {
88
            // Storing tags information
89
            $tagHandler = $xoops->getModuleHandler('tag', 'tag');
90
            $tagHandler->updateByItem($item->getVar('item_tag'), $item->getVar('itemid'), \PUBLISHER_DIRNAME, 0);
0 ignored issues
show
Bug introduced by
The method updateByItem() does not exist on XoopsObjectHandler. ( Ignorable by Annotation )

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

90
            $tagHandler->/** @scrutinizer ignore-call */ 
91
                         updateByItem($item->getVar('item_tag'), $item->getVar('itemid'), \PUBLISHER_DIRNAME, 0);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method updateByItem() does not exist on XoopsPersistableObjectHandler. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

90
            $tagHandler->/** @scrutinizer ignore-call */ 
91
                         updateByItem($item->getVar('item_tag'), $item->getVar('itemid'), \PUBLISHER_DIRNAME, 0);
Loading history...
91
        }
92
93
        return true;
94
    }
95
96
    /**
97
     * delete an item from the database
98
     *
99
     * @param XoopsObject $item reference to the ITEM to delete
100
     * @param bool        $force
101
     *
102
     * @return bool FALSE if failed.
103
     */
104
    public function delete(XoopsObject $item, $force = false)
105
    {
106
        $xoops = Xoops::getInstance();
107
        // Deleting the files
108
        if (!$this->helper->getFileHandler()->deleteItemFiles($item)) {
109
            $item->setErrors('An error while deleting a file.');
110
        }
111
        if (!parent::delete($item, $force)) {
112
            $item->setErrors('An error while deleting.');
113
114
            return false;
115
        }
116
        // Removing tags information
117
        if ($xoops->isActiveModule('tag')) {
118
            $tagHandler = $xoops->getModuleHandler('tag', 'tag');
119
            $tagHandler->updateByItem('', $item->getVar('itemid'), \PUBLISHER_DIRNAME, 0);
120
        }
121
122
        return true;
123
    }
124
125
    /**
126
     * retrieve items from the database
127
     *
128
     * @param object $criteria      {@link CriteriaElement} conditions to be met
129
     * @param string $id_key        what shall we use as array key ? none, itemid, categoryid
130
     * @param string $notNullFields fields that cannot be null or empty
131
     *
132
     * @return array array of {@link Publisher\Item} objects
133
     */
134
    public function getItemObjects($criteria = null, $id_key = 'none', $notNullFields = ''): array
135
    {
136
        $ret = [];
137
        $whereMode = '';
138
139
        $qb = $this->db2->createXoopsQueryBuilder();
140
        $qb->select('*')->fromPrefix('publisher_items', '');
141
        if (isset($criteria) && $criteria instanceof CriteriaElement) {
142
            $criteria->renderQb($qb, '');
143
            $whereMode = 'AND';
144
        }
145
        $this->addNotNullFieldClause($qb, $notNullFields, $whereMode);
146
        $theObjects = [];
147
        $result = $qb->execute();
148
        while (false !== ($myrow = $result->fetch(PDO::FETCH_ASSOC))) {
149
            $item = new Publisher\Item();
150
            $item->assignVars($myrow);
151
            $theObjects[$myrow['itemid']] = $item;
152
            unset($item);
153
        }
154
155
        /* @var Publisher\Item $theObject */
156
        foreach ($theObjects as $theObject) {
157
            if ('none' === $id_key) {
158
                $ret[] = $theObject;
159
            } elseif ('itemid' === $id_key) {
160
                $ret[$theObject->getVar('itemid')] = $theObject;
161
            } else {
162
                $ret[$theObject->getVar($id_key)][$theObject->getVar('itemid')] = $theObject;
163
            }
164
            unset($theObject);
165
        }
166
167
        return $ret;
168
    }
169
170
    /**
171
     * count items matching a condition
172
     *
173
     * @param object $criteria      {@link CriteriaElement} to match
174
     * @param string $notNullFields fields that cannot be null or empty
175
     *
176
     * @return int count of items
177
     */
178
    public function getItemCount($criteria = null, $notNullFields = ''): int
179
    {
180
        $whereMode = '';
181
182
        $qb = $this->db2->createXoopsQueryBuilder();
183
        $qb->select('COUNT(*)')->fromPrefix('publisher_items', '');
184
        if (isset($criteria) && $criteria instanceof CriteriaElement) {
185
            $whereClause = $criteria->renderQb($qb, '');
0 ignored issues
show
Unused Code introduced by
The assignment to $whereClause is dead and can be removed.
Loading history...
186
            $whereMode = 'AND';
187
        }
188
        $this->addNotNullFieldClause($qb, $notNullFields, $whereMode);
189
        $result = $qb->execute();
190
191
        if (!$result) {
192
            return 0;
193
        }
194
        [$count] = $result->fetch(PDO::FETCH_NUM);
195
196
        return $count;
197
    }
198
199
    /**
200
     * @param        $categoryid
201
     * @param string|array $status
202
     * @param string $notNullFields
203
     */
204
    public function getItemsCount($categoryid = -1, $status = '', $notNullFields = ''): int
205
    {
206
        global $publisher_isAdmin;
207
        $criteriaCategory = null;
208
        if (!$publisher_isAdmin) {
209
            $criteriaPermissions = new CriteriaCompo();
210
            // Categories for which user has access
211
            $categoriesGranted = $this->helper->getPermissionHandler()->getGrantedItems('category_read');
212
            if (!empty($categoriesGranted)) {
213
                $grantedCategories = new Criteria('categoryid', '(' . \implode(',', $categoriesGranted) . ')', 'IN');
214
                $criteriaPermissions->add($grantedCategories, 'AND');
215
            } else {
216
                return 0;
217
            }
218
        }
219
        if (isset($categoryid) && -1 != $categoryid) {
220
            $criteriaCategory = new criteria('categoryid', $categoryid);
221
        }
222
        $criteriaStatus = new CriteriaCompo();
223
        if (!empty($status) && \is_array($status)) {
224
            foreach ($status as $v) {
225
                $criteriaStatus->add(new Criteria('status', $v), 'OR');
226
            }
227
        } elseif (!empty($status) && -1 != $status) {
228
            $criteriaStatus->add(new Criteria('status', $status), 'OR');
229
        }
230
        $criteria = new CriteriaCompo();
231
        if (null !== $criteriaCategory) {
232
            $criteria->add($criteriaCategory);
233
        }
234
        if (null !== $criteriaPermissions) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $criteriaPermissions does not seem to be defined for all execution paths leading up to this point.
Loading history...
235
            $criteria->add($criteriaPermissions);
236
        }
237
        if (null !== $criteriaStatus) {
238
            $criteria->add($criteriaStatus);
239
        }
240
241
        return $this->getItemCount($criteria, $notNullFields);
242
    }
243
244
    /**
245
     * @param int    $limit
246
     * @param int    $start
247
     * @param int    $categoryid
248
     * @param string $sort
249
     * @param string $order
250
     * @param string $notNullFields
251
     * @param bool   $asobject
252
     * @param string $id_key
253
     */
254
    public function getAllPublished($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $id_key = 'none'): array
255
    {
256
        $otherCriteria = new Criteria('datesub', \time(), '<=');
257
258
        return $this->getItems($limit, $start, [\_PUBLISHER_STATUS_PUBLISHED], $categoryid, $sort, $order, $notNullFields, $asobject, $otherCriteria, $id_key);
0 ignored issues
show
Bug introduced by
array(_PUBLISHER_STATUS_PUBLISHED) of type array<integer,integer> is incompatible with the type string expected by parameter $status of XoopsModules\Publisher\ItemHandler::getItems(). ( Ignorable by Annotation )

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

258
        return $this->getItems($limit, $start, /** @scrutinizer ignore-type */ [\_PUBLISHER_STATUS_PUBLISHED], $categoryid, $sort, $order, $notNullFields, $asobject, $otherCriteria, $id_key);
Loading history...
259
    }
260
261
    /**
262
     * @param Publisher\Item $obj
263
     */
264
    public function getPreviousPublished($obj): bool
265
    {
266
        $ret = false;
267
        $otherCriteria = new CriteriaCompo();
268
        $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 string[]; however, parameter $value of Xoops\Core\Kernel\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

268
        $otherCriteria->add(new Criteria('datesub', /** @scrutinizer ignore-type */ $obj->getVar('datesub'), '<'));
Loading history...
269
        $objs = $this->getItems(1, 0, [\_PUBLISHER_STATUS_PUBLISHED], $obj->getVar('categoryid'), 'datesub', 'DESC', '', true, $otherCriteria, 'none');
0 ignored issues
show
Bug introduced by
array(_PUBLISHER_STATUS_PUBLISHED) of type array<integer,integer> is incompatible with the type string expected by parameter $status of XoopsModules\Publisher\ItemHandler::getItems(). ( Ignorable by Annotation )

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

269
        $objs = $this->getItems(1, 0, /** @scrutinizer ignore-type */ [\_PUBLISHER_STATUS_PUBLISHED], $obj->getVar('categoryid'), 'datesub', 'DESC', '', true, $otherCriteria, 'none');
Loading history...
270
        if (\count($objs) > 0) {
271
            $ret = $objs[0];
272
        }
273
274
        return $ret;
275
    }
276
277
    /**
278
     * @param Publisher\Item $obj
279
     */
280
    public function getNextPublished($obj): bool
281
    {
282
        $ret = false;
283
        $otherCriteria = new CriteriaCompo();
284
        $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 string[]; however, parameter $value of Xoops\Core\Kernel\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

284
        $otherCriteria->add(new Criteria('datesub', /** @scrutinizer ignore-type */ $obj->getVar('datesub'), '>'));
Loading history...
285
        $otherCriteria->add(new Criteria('datesub', \time(), '<='));
286
        $objs = $this->getItems(1, 0, [\_PUBLISHER_STATUS_PUBLISHED], $obj->getVar('categoryid'), 'datesub', 'ASC', '', true, $otherCriteria, 'none');
0 ignored issues
show
Bug introduced by
array(_PUBLISHER_STATUS_PUBLISHED) of type array<integer,integer> is incompatible with the type string expected by parameter $status of XoopsModules\Publisher\ItemHandler::getItems(). ( Ignorable by Annotation )

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

286
        $objs = $this->getItems(1, 0, /** @scrutinizer ignore-type */ [\_PUBLISHER_STATUS_PUBLISHED], $obj->getVar('categoryid'), 'datesub', 'ASC', '', true, $otherCriteria, 'none');
Loading history...
287
        if (\count($objs) > 0) {
288
            $ret = $objs[0];
289
        }
290
291
        return $ret;
292
    }
293
294
    /**
295
     * @param int    $limit
296
     * @param int    $start
297
     * @param int    $categoryid
298
     * @param string $sort
299
     * @param string $order
300
     * @param string $notNullFields
301
     * @param bool   $asobject
302
     * @param string $id_key
303
     */
304
    public function getAllSubmitted($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $id_key = 'none'): array
305
    {
306
        return $this->getItems($limit, $start, [\_PUBLISHER_STATUS_SUBMITTED], $categoryid, $sort, $order, $notNullFields, $asobject, null, $id_key);
0 ignored issues
show
Bug introduced by
array(_PUBLISHER_STATUS_SUBMITTED) of type array<integer,integer> is incompatible with the type string expected by parameter $status of XoopsModules\Publisher\ItemHandler::getItems(). ( Ignorable by Annotation )

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

306
        return $this->getItems($limit, $start, /** @scrutinizer ignore-type */ [\_PUBLISHER_STATUS_SUBMITTED], $categoryid, $sort, $order, $notNullFields, $asobject, null, $id_key);
Loading history...
307
    }
308
309
    /**
310
     * @param int    $limit
311
     * @param int    $start
312
     * @param int    $categoryid
313
     * @param string $sort
314
     * @param string $order
315
     * @param string $notNullFields
316
     * @param bool   $asobject
317
     * @param string $id_key
318
     */
319
    public function getAllOffline($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $id_key = 'none'): array
320
    {
321
        return $this->getItems($limit, $start, [\_PUBLISHER_STATUS_OFFLINE], $categoryid, $sort, $order, $notNullFields, $asobject, null, $id_key);
0 ignored issues
show
Bug introduced by
array(_PUBLISHER_STATUS_OFFLINE) of type array<integer,integer> is incompatible with the type string expected by parameter $status of XoopsModules\Publisher\ItemHandler::getItems(). ( Ignorable by Annotation )

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

321
        return $this->getItems($limit, $start, /** @scrutinizer ignore-type */ [\_PUBLISHER_STATUS_OFFLINE], $categoryid, $sort, $order, $notNullFields, $asobject, null, $id_key);
Loading history...
322
    }
323
324
    /**
325
     * @param int    $limit
326
     * @param int    $start
327
     * @param int    $categoryid
328
     * @param string $sort
329
     * @param string $order
330
     * @param string $notNullFields
331
     * @param bool   $asobject
332
     * @param string $id_key
333
     */
334
    public function getAllRejected($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $id_key = 'none'): array
335
    {
336
        return $this->getItems($limit, $start, [\_PUBLISHER_STATUS_REJECTED], $categoryid, $sort, $order, $notNullFields, $asobject, null, $id_key);
0 ignored issues
show
Bug introduced by
array(_PUBLISHER_STATUS_REJECTED) of type array<integer,integer> is incompatible with the type string expected by parameter $status of XoopsModules\Publisher\ItemHandler::getItems(). ( Ignorable by Annotation )

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

336
        return $this->getItems($limit, $start, /** @scrutinizer ignore-type */ [\_PUBLISHER_STATUS_REJECTED], $categoryid, $sort, $order, $notNullFields, $asobject, null, $id_key);
Loading history...
337
    }
338
339
    /**
340
     * @param int    $limit
341
     * @param int    $start
342
     * @param string $status
343
     * @param int    $categoryid
344
     * @param string $sort
345
     * @param string $order
346
     * @param string $notNullFields
347
     * @param bool   $asobject
348
     * @param null   $otherCriteria
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $otherCriteria is correct as it would always require null to be passed?
Loading history...
349
     * @param string $id_key
350
     */
351
    public function getItems($limit = 0, $start = 0, $status = '', $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $otherCriteria = null, $id_key = 'none'): array
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

351
    public function getItems($limit = 0, $start = 0, $status = '', $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', /** @scrutinizer ignore-unused */ $asobject = true, $otherCriteria = null, $id_key = 'none'): array

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...
352
    {
353
        global $publisher_isAdmin;
354
        $criteriaCategory = $criteriaStatus = null;
355
        if (!$publisher_isAdmin) {
356
            $criteriaPermissions = new CriteriaCompo();
357
            // Categories for which user has access
358
            $categoriesGranted = $this->helper->getPermissionHandler()->getGrantedItems('category_read');
359
            if (!empty($categoriesGranted)) {
360
                $grantedCategories = new Criteria('categoryid', '(' . \implode(',', $categoriesGranted) . ')', 'IN');
361
                $criteriaPermissions->add($grantedCategories, 'AND');
362
            } else {
363
                return [];
364
            }
365
        }
366
        if (isset($categoryid) && (-1 != $categoryid)) {
367
            $criteriaCategory = new criteria('categoryid', $categoryid);
368
        }
369
        if (!empty($status) && \is_array($status)) {
0 ignored issues
show
introduced by
The condition is_array($status) is always false.
Loading history...
370
            $criteriaStatus = new CriteriaCompo();
371
            foreach ($status as $v) {
372
                $criteriaStatus->add(new Criteria('status', $v), 'OR');
373
            }
374
        } elseif (!empty($status) && -1 != $status) {
375
            $criteriaStatus = new CriteriaCompo();
376
            $criteriaStatus->add(new Criteria('status', $status), 'OR');
377
        }
378
        $criteria = new CriteriaCompo();
379
        if (null !== $criteriaCategory) {
380
            $criteria->add($criteriaCategory);
381
        }
382
        if (null !== $criteriaPermissions) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $criteriaPermissions does not seem to be defined for all execution paths leading up to this point.
Loading history...
383
            $criteria->add($criteriaPermissions);
384
        }
385
        if (null !== $criteriaStatus) {
386
            $criteria->add($criteriaStatus);
387
        }
388
        if (!empty($otherCriteria)) {
389
            $criteria->add($otherCriteria);
390
        }
391
        $criteria->setLimit($limit);
392
        $criteria->setStart($start);
393
        $criteria->setSort($sort);
394
        $criteria->setOrder($order);
395
        $ret = $this->getItemObjects($criteria, $id_key, $notNullFields);
396
397
        return $ret;
398
    }
399
400
    /**
401
     * @param string $field
402
     * @param string $status
403
     * @param int    $categoryId
404
     */
405
    public function getRandomItem($field = '', $status = '', $categoryId = -1): bool
406
    {
407
        $ret = false;
408
        $notNullFields = $field;
409
        // Getting the number of published Items
410
        $totalItems = $this->getItemsCount($categoryId, $status, $notNullFields);
411
        if ($totalItems > 0) {
412
            $totalItems = $totalItems - 1;
413
            // mt_srand((float)\microtime() * 1000000);
414
            $entrynumber = \random_int(0, $totalItems);
415
            $item = $this->getItems(1, $entrynumber, $status, $categoryId, $sort = 'datesub', $order = 'DESC', $notNullFields);
416
            if ($item) {
417
                $ret = $item[0];
418
            }
419
        }
420
421
        return $ret;
422
    }
423
424
    /**
425
     * @param $itemid
426
     *
427
     * @return bool
428
     */
429
    public function updateCounter($itemid): ?bool
430
    {
431
        $qb = $this->db2->createXoopsQueryBuilder();
432
        $qb->updatePrefix('publisher_items', 'i')->set('i.counter', 'i.counter+1')->where('i.itemid = :itemid')->setParameter(':itemid', $itemid, PDO::PARAM_INT);
433
        $result = $qb->execute();
434
        if ($result) {
435
            return true;
436
        }
437
438
        return false;
439
    }
440
441
    /**
442
     * addNotNullFieldClause exclude rows where specified columns are empty or null
443
     *
444
     * @param QueryBuilder $qb            QueryBuilder instance
445
     * @param string|array $notNullFields fields that should not be empty
446
     * @param string       $whereMode     Initial where method, 'AND' andWhere(), otherwise where()
447
     *
448
     * @return QueryBuilder instance
449
     */
450
    protected function addNotNullFieldClause(QueryBuilder $qb, $notNullFields = [], $whereMode = ''): QueryBuilder
451
    {
452
        $eb = $qb->expr();
453
        if (!empty($notNullFields)) {
454
            if (!\is_array($notNullFields)) {
455
                $notNullFields = (array)$notNullFields;
456
            }
457
            foreach ($notNullFields as $v) {
458
                if ('AND' === $whereMode) {
459
                    $qb->andWhere($eb->isNotNull($v, ''))->andWhere($eb->neq($v, "''"));
0 ignored issues
show
Unused Code introduced by
The call to Doctrine\DBAL\Query\Expr...ionBuilder::isNotNull() has too many arguments starting with ''. ( Ignorable by Annotation )

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

459
                    $qb->andWhere($eb->/** @scrutinizer ignore-call */ isNotNull($v, ''))->andWhere($eb->neq($v, "''"));

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
460
                } else {
461
                    $qb->where($eb->isNotNull($v, ''))->andWhere($eb->neq($v, "''"));
462
                    $whereMode = 'AND';
463
                }
464
            }
465
        }
466
467
        return $qb;
468
    }
469
470
    /**
471
     * @param array        $queryarray
472
     * @param string       $andor
473
     * @param int          $limit
474
     * @param int          $offset
475
     * @param int|array    $userid
476
     * @param array        $categories
477
     * @param int|string   $sortby
478
     * @param string|array $searchin
479
     * @param string       $extra
480
     */
481
    public function getItemsFromSearch($queryarray = [], $andor = 'AND', $limit = 0, $offset = 0, $userid = 0, $categories = [], $sortby = 0, $searchin = '', $extra = ''): array
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

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

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...
482
    {
483
        $xoops = Xoops::getInstance();
484
        $ret = [];
485
        $gpermHandler = $xoops->getHandlerGroupPermission();
486
        $groups = $xoops->getUserGroups();
487
        $searchin = empty($searchin) ? [
488
            'title',
489
            'body',
490
            'summary',
491
        ] : (\is_array($searchin) ? $searchin : [$searchin]);
492
        if (\in_array('all', $searchin) || 0 == \count($searchin)) {
493
            $searchin = ['title', 'subtitle', 'body', 'summary', 'meta_keywords'];
494
        }
495
        if (\is_array($userid) && \count($userid) > 0) {
496
            $userid = \array_map('\intval', $userid);
497
            $criteriaUser = new CriteriaCompo();
498
            $criteriaUser->add(new Criteria('uid', '(' . \implode(',', $userid) . ')', 'IN'), 'OR');
499
        } elseif (\is_numeric($userid) && $userid > 0) {
500
            $criteriaUser = new CriteriaCompo();
501
            $criteriaUser->add(new Criteria('uid', $userid), 'OR');
502
        }
503
        $count = \count($queryarray);
504
        if (\is_array($queryarray) && $count > 0) {
505
            $criteriaKeywords = new CriteriaCompo();
506
            foreach ($queryarray as $iValue) {
507
                $criteriaKeyword = new CriteriaCompo();
508
                if (\in_array('title', $searchin)) {
509
                    $criteriaKeyword->add(new Criteria('title', '%' . $iValue . '%', 'LIKE'), 'OR');
510
                }
511
                if (\in_array('subtitle', $searchin)) {
512
                    $criteriaKeyword->add(new Criteria('subtitle', '%' . $iValue . '%', 'LIKE'), 'OR');
513
                }
514
                if (\in_array('body', $searchin)) {
515
                    $criteriaKeyword->add(new Criteria('body', '%' . $iValue . '%', 'LIKE'), 'OR');
516
                }
517
                if (\in_array('summary', $searchin)) {
518
                    $criteriaKeyword->add(new Criteria('summary', '%' . $iValue . '%', 'LIKE'), 'OR');
519
                }
520
                if (\in_array('meta_keywords', $searchin)) {
521
                    $criteriaKeyword->add(new Criteria('meta_keywords', '%' . $iValue . '%', 'LIKE'), 'OR');
522
                }
523
                $criteriaKeywords->add($criteriaKeyword, $andor);
524
                unset($criteriaKeyword);
525
            }
526
        }
527
        if (!Publisher\Utils::IsUserAdmin() && (\count($categories) > 0)) {
528
            $criteriaPermissions = new CriteriaCompo();
529
            // Categories for which user has access
530
            $categoriesGranted = $gpermHandler->getItemIds('category_read', $groups, $this->helper->getModule()->getVar('mid'));
531
            if (\count($categories) > 0) {
532
                $categoriesGranted = \array_intersect($categoriesGranted, $categories);
533
            }
534
            if (0 == \count($categoriesGranted)) {
535
                return $ret;
536
            }
537
            $grantedCategories = new Criteria('categoryid', '(' . \implode(',', $categoriesGranted) . ')', 'IN');
538
            $criteriaPermissions->add($grantedCategories, 'AND');
539
        } elseif (\count($categories) > 0) {
540
            $criteriaPermissions = new CriteriaCompo();
541
            $grantedCategories = new Criteria('categoryid', '(' . \implode(',', $categories) . ')', 'IN');
542
            $criteriaPermissions->add($grantedCategories, 'AND');
543
        }
544
        $criteriaItemsStatus = new CriteriaCompo();
545
        $criteriaItemsStatus->add(new Criteria('status', \_PUBLISHER_STATUS_PUBLISHED));
546
        $criteria = new CriteriaCompo();
547
        if (null !== $criteriaUser) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $criteriaUser does not seem to be defined for all execution paths leading up to this point.
Loading history...
548
            $criteria->add($criteriaUser, 'AND');
549
        }
550
        if (null !== $criteriaKeywords) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $criteriaKeywords does not seem to be defined for all execution paths leading up to this point.
Loading history...
551
            $criteria->add($criteriaKeywords, 'AND');
552
        }
553
        if (null !== $criteriaPermissions) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $criteriaPermissions does not seem to be defined for all execution paths leading up to this point.
Loading history...
554
            $criteria->add($criteriaPermissions);
555
        }
556
        if (null !== $criteriaItemsStatus) {
557
            $criteria->add($criteriaItemsStatus, 'AND');
558
        }
559
        $criteria->setLimit($limit);
560
        $criteria->setStart($offset);
561
        if (empty($sortby)) {
562
            $sortby = 'datesub';
563
        }
564
        $criteria->setSort($sortby);
565
        $order = 'ASC';
566
        if ('datesub' === $sortby) {
567
            $order = 'DESC';
568
        }
569
        $criteria->setOrder($order);
570
        $ret = $this->getItemObjects($criteria);
571
572
        return $ret;
573
    }
574
575
    /**
576
     * @param array $categoriesObj
577
     * @param array $status
578
     */
579
    public function getLastPublishedByCat($categoriesObj, $status = [\_PUBLISHER_STATUS_PUBLISHED]): array
580
    {
581
        $ret = [];
582
        $catIds = [];
583
        /* @var Publisher\Category $category */
584
        foreach ($categoriesObj as $parentid) {
585
            foreach ($parentid as $category) {
586
                $catId = $category->getVar('categoryid');
587
                $catIds[$catId] = $catId;
588
            }
589
        }
590
        if (empty($catIds)) {
591
            return $ret;
592
        }
593
594
        // $sql = "SELECT mi.categoryid, mi.itemid, mi.title, mi.short_url, mi.uid, mi.datesub";
595
        // $sql .= " FROM (SELECT categoryid, MAX(datesub) AS date FROM " . $this->db->prefix('publisher_items');
596
        // $sql .= " WHERE status IN (" . implode(',', $status) . ")";
597
        // $sql .= " AND categoryid IN (" . implode(',', $catIds) . ")";
598
        // $sql .= " GROUP BY categoryid)mo";
599
        // $sql .= " JOIN " . $this->db->prefix('publisher_items') . " mi ON mi.datesub = mo.date";
600
601
        $qb = $this->db2->createXoopsQueryBuilder();
602
        $qb->select('mi.categoryid', 'mi.itemid', 'mi.title', 'mi.short_url', 'mi.uid', 'mi.datesub');
603
604
        $subqb = $this->db2->createXoopsQueryBuilder();
605
        $subqb->select('categoryid', 'MAX(datesub) AS date')->fromPrefix('publisher_items', '')->where($subqb->expr()->in('status', $status))->andWhere($subqb->expr()->in('categoryid', $catIds))->groupBy('categoryid');
606
        $subquery = '(' . $subqb->getSQL() . ')';
607
608
        $qb->from($subquery, 'mo')->joinPrefix('mo', 'publisher_items', 'mi', 'mi.datesub = mo.date');
609
610
        $result = $qb->execute();
611
        while (false !== ($row = $result->fetch(PDO::FETCH_ASSOC))) {
612
            $item = new Publisher\Item();
613
            $item->assignVars($row);
614
            $ret[$row['categoryid']] = $item;
615
            unset($item);
616
        }
617
618
        return $ret;
619
    }
620
621
    /**
622
     * @param int    $parentid
623
     * @param array  $catsCount
624
     * @param string $spaces
625
     * @param array  $resultCatCounts
626
     */
627
    public function countArticlesByCat($parentid, &$catsCount, $spaces = '', $resultCatCounts = []): int
628
    {
629
        $newspaces = $spaces . '--';
630
        $thecount = 0;
631
        foreach ($catsCount[$parentid] as $subCatId => $count) {
632
            $thecount = $thecount + $count;
633
            $resultCatCounts[$subCatId] = $count;
634
            if (isset($catsCount[$subCatId])) {
635
                $thecount = $thecount + $this->countArticlesByCat($subCatId, $catsCount, $newspaces, $resultCatCounts);
636
                $resultCatCounts[$subCatId] = $thecount;
637
            }
638
        }
639
640
        return $thecount;
641
    }
642
643
    /**
644
     * @param int   $cat_id
645
     * @param array $status
646
     * @param bool  $inSubCat
647
     */
648
    public function getCountsByCat($cat_id, $status, $inSubCat = false): array
649
    {
650
        $ret = [];
651
        $catsCount = [];
652
653
        $qb = $this->db2->createXoopsQueryBuilder();
654
        $qb->select('c.parentid', 'i.categoryid', 'COUNT(*) AS count')->fromPrefix('publisher_items', 'i')->innerJoinPrefix('i', 'publisher_categories', 'c', 'i.categoryid=c.categoryid')->where($qb->expr()->in('i.status', $status))->groupBy('i.categoryid')->orderBy(
655
            'c.parentid',
656
            'ASC'
657
        )->addOrderBy(
658
                                                                                                                                                                                                                                                                              'i.categoryid',
659
                                                                                                                                                                                                                                                                              'ASC'
660
                                                                                                                                                                                                                                                                          );
661
        if ((int)$cat_id > 0) {
662
            $qb->andWhere($qb->expr()->eq('i.categoryid', ':catid'))->setParameter(':catid', $cat_id, PDO::PARAM_INT);
663
        }
664
665
        //$sql = 'SELECT c.parentid, i.categoryid, COUNT(*) AS count FROM ' . $this->db->prefix('publisher_items')
666
        //. ' AS i INNER JOIN ' . $this->db->prefix('publisher_categories') . ' AS c ON i.categoryid=c.categoryid';
667
        //if ((int)($cat_id) > 0) {
668
        //    $sql .= ' WHERE i.categoryid = ' . (int)($cat_id);
669
        //    $sql .= ' AND i.status IN (' . implode(',', $status) . ')';
670
        //} else {
671
        //    $sql .= ' WHERE i.status IN (' . implode(',', $status) . ')';
672
        //}
673
        //$sql .= ' GROUP BY i.categoryid ORDER BY c.parentid ASC, i.categoryid ASC';
674
675
        $result = $qb->execute();
676
677
        if (!$result) {
678
            return $ret;
679
        }
680
        if (!$inSubCat) {
681
            while (false !== ($row = $result->fetch(PDO::FETCH_ASSOC))) {
682
                $catsCount[$row['categoryid']] = $row['count'];
683
            }
684
685
            return $catsCount;
686
        }
687
        while (false !== ($row = $result->fetch(PDO::FETCH_ASSOC))) {
688
            $catsCount[$row['parentid']][$row['categoryid']] = $row['count'];
689
        }
690
        $resultCatCounts = [];
691
        foreach ($catsCount[0] as $subCatId => $count) {
692
            $resultCatCounts[$subCatId] = $count;
693
            if (isset($catsCount[$subCatId])) {
694
                $resultCatCounts[$subCatId] = $resultCatCounts[$subCatId] + $this->countArticlesByCat($subCatId, $catsCount, $spaces = '', $resultCatCounts);
695
            }
696
        }
697
698
        return $resultCatCounts;
699
    }
700
}
701