Passed
Branch master (35e8f4)
by Michael
02:57
created

ItemHandler   F

Complexity

Total Complexity 126

Size/Duplication

Total Lines 846
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 313
dl 0
loc 846
rs 2
c 0
b 0
f 0
wmc 126

25 Methods

Rating   Name   Duplication   Size   Complexity  
A get() 0 8 2
A __construct() 0 5 1
A getItemsCount() 0 43 3
A create() 0 9 2
B getCount() 0 23 8
A delete() 0 19 4
C getObjects() 0 49 15
B insert() 0 27 9
B getItemsCriteria() 0 39 11
A getAllRejected() 0 3 1
A getItems() 0 52 4
F getItemsFromSearch() 0 92 28
A getAllSubmitted() 0 3 1
A getRandomItem() 0 16 3
A getAllPublished() 0 15 2
A updateCounter() 0 8 2
A deleteAll() 0 9 2
B getCountsByCat() 0 38 8
A getAllExpired() 0 7 1
A getLastPublishedByCat() 0 55 5
A countArticlesByCat() 0 15 3
A notNullFieldClause() 0 15 6
A getAllOffline() 0 3 1
A getPreviousPublished() 0 11 2
A getNextPublished() 0 12 2

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
/**
16
 * @copyright       The XUUPS Project http://sourceforge.net/projects/xuups/
17
 * @license         http://www.fsf.org/copyleft/gpl.html GNU public license
18
 * @package         Publisher
19
 * @since           1.0
20
 * @author          trabis <[email protected]>
21
 * @author          The SmartFactory <www.smartfactory.ca>
22
 */
23
24
use XoopsModules\Publisher;
25
26
//namespace Publisher;
27
28
// defined('XOOPS_ROOT_PATH') || die('Restricted access');
29
require_once dirname(__DIR__) . '/include/common.php';
30
31
/**
32
 * Items handler class.
33
 * This class is responsible for providing data access mechanisms to the data source
34
 * of Q&A class objects.
35
 *
36
 * @author  marcan <[email protected]>
37
 * @package Publisher
38
 */
39
class ItemHandler extends \XoopsPersistableObjectHandler
40
{
41
    /**
42
     * @var Publisher\Helper
43
     */
44
    public $helper;
45
46
    protected $resultCatCounts = [];
47
48
    /**
49
     * @param \XoopsDatabase $db
50
     * @param null|\XoopsModules\Publisher\Helper           $helper
51
     */
52
    public function __construct(\XoopsDatabase $db = null, $helper = null)
53
    {
54
        /** @var Publisher\Helper $this->helper */
55
        $this->helper = $helper;
56
        parent::__construct($db, 'publisher_items', Item::class, 'itemid', 'title');
57
    }
58
59
    /**
60
     * @param bool $isNew
61
     *
62
     * @return \XoopsObject
63
     */
64
    public function create($isNew = true)
65
    {
66
        $obj = parent::create($isNew);
67
        if ($isNew) {
68
            $obj->setDefaultPermissions();
0 ignored issues
show
Bug introduced by
The method setDefaultPermissions() 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

68
            $obj->/** @scrutinizer ignore-call */ 
69
                  setDefaultPermissions();
Loading history...
69
        }
70
        $obj->helper = $this->helper;
71
72
        return $obj;
73
    }
74
75
    /**
76
     * retrieve an item
77
     *
78
     * @param int   $id     itemid of the user
79
     *
80
     * @param  null $fields
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $fields is correct as it would always require null to be passed?
Loading history...
81
     * @return mixed reference to the <a href='psi_element://Item'>Item</a> object, FALSE if failed
82
     *                      object, FALSE if failed
83
     */
84
    public function get($id = null, $fields = null)
85
    {
86
        $obj = parent::get($id);
87
        if (is_object($obj)) {
88
            $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

88
            $obj->/** @scrutinizer ignore-call */ 
89
                  assignOtherProperties();
Loading history...
89
        }
90
91
        return $obj;
92
    }
93
94
    /**
95
     * insert a new item in the database
96
     *
97
     * @param \XoopsObject $item reference to the {@link Item}
98
     *                           object
99
     * @param bool         $force
100
     *
101
     * @return bool FALSE if failed, TRUE if already present and unchanged or successful
102
     */
103
    public function insert(\XoopsObject $item, $force = false)  //insert(&$item, $force = false)
104
    {
105
        if (!$item->meta_keywords() || !$item->meta_description() || !$item->short_url()) {
0 ignored issues
show
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

105
        if (!$item->meta_keywords() || !$item->meta_description() || !$item->/** @scrutinizer ignore-call */ short_url()) {
Loading history...
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

105
        if (!$item->/** @scrutinizer ignore-call */ meta_keywords() || !$item->meta_description() || !$item->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

105
        if (!$item->meta_keywords() || !$item->/** @scrutinizer ignore-call */ meta_description() || !$item->short_url()) {
Loading history...
106
            $publisherMetagen = new Publisher\Metagen($item->getTitle(), $item->getVar('meta_keywords'), $item->getVar('summary'));
0 ignored issues
show
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

106
            $publisherMetagen = new Publisher\Metagen($item->/** @scrutinizer ignore-call */ getTitle(), $item->getVar('meta_keywords'), $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

106
            $publisherMetagen = new Publisher\Metagen($item->getTitle(), /** @scrutinizer ignore-type */ $item->getVar('meta_keywords'), $item->getVar('summary'));
Loading history...
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

106
            $publisherMetagen = new Publisher\Metagen($item->getTitle(), $item->getVar('meta_keywords'), /** @scrutinizer ignore-type */ $item->getVar('summary'));
Loading history...
107
            // Auto create meta tags if empty
108
            if (!$item->meta_keywords()) {
109
                $item->setVar('meta_keywords', $publisherMetagen->keywords);
110
            }
111
            if (!$item->meta_description()) {
112
                $item->setVar('meta_description', $publisherMetagen->description);
113
            }
114
            // Auto create short_url if empty
115
            if (!$item->short_url()) {
116
                $item->setVar('short_url', mb_substr(Publisher\Metagen::generateSeoTitle($item->getVar('title', 'n'), false), 0, 254));
117
            }
118
        }
119
        if (!parent::insert($item, $force)) {
120
            return false;
121
        }
122
        if (xoops_isActiveModule('tag')) {
123
            // Storing tags information
124
            /** @var \XoopsModules\Tag\Helper $tagHandler */
125
            $tagHandler = \XoopsModules\Tag\Helper::getInstance()->getHandler('Tag'); // xoops_getModuleHandler('tag', 'tag');
126
            $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 XoopsModules\Tag\Helper. ( Ignorable by Annotation )

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

126
            $tagHandler->/** @scrutinizer ignore-call */ 
127
                         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 constant XoopsModules\Publisher\PUBLISHER_DIRNAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
127
        }
128
129
        return true;
130
    }
131
132
    /**
133
     * delete an item from the database
134
     *
135
     * @param \XoopsObject $item reference to the ITEM to delete
136
     * @param bool         $force
137
     *
138
     * @return bool FALSE if failed.
139
     */
140
    public function delete(\XoopsObject $item, $force = false)
141
    {
142
        // Deleting the files
143
        if (!$this->helper->getHandler('File')->deleteItemFiles($item)) {
0 ignored issues
show
Bug introduced by
The method deleteItemFiles() does not exist on XoopsObjectHandler. Did you maybe mean delete()? ( Ignorable by Annotation )

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

143
        if (!$this->helper->getHandler('File')->/** @scrutinizer ignore-call */ deleteItemFiles($item)) {

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...
144
            $item->setErrors(_AM_PUBLISHER_FILE_DELETE_ERROR);
145
        }
146
        if (!parent::delete($item, $force)) {
147
            $item->setErrors(_AM_PUBLISHER_ITEM_DELETE_ERROR);
148
149
            return false;
150
        }
151
        // Removing tags information
152
        if (xoops_isActiveModule('tag')) {
153
            /** @var \XoopsModules\Tag\Helper $tagHandler */
154
            $tagHandler = \XoopsModules\Tag\Helper::getInstance()->getHandler('Tag'); // xoops_getModuleHandler('tag', 'tag');
155
            $tagHandler->updateByItem('', $item->getVar('itemid'), PUBLISHER_DIRNAME, 0);
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Publisher\PUBLISHER_DIRNAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
156
        }
157
158
        return true;
159
    }
160
161
    /**
162
     * retrieve items from the database
163
     *
164
     * @param \CriteriaElement|\CriteriaCompo $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|bool                    $notNullFields
169
     * @return array           array of <a href='psi_element://Item'>Item</a> objects
170
     *                                                  objects
171
     */
172
    public function &getObjects(\CriteriaElement $criteria = null, $idKey = 'none', $as_object = true, $notNullFields = null)
173
    {
174
        $limit         = $start = 0;
175
        $ret           = [];
176
        $notNullFields = (null !== $notNullFields) ?: '';
177
178
        $sql = 'SELECT * FROM ' . $this->db->prefix($this->helper->getDirname() . '_items');
179
        if (null !== $criteria && $criteria instanceof \CriteriaElement) {
180
            $whereClause = $criteria->renderWhere();
0 ignored issues
show
Bug introduced by
The method renderWhere() does not exist on CriteriaElement. Did you maybe mean render()? ( Ignorable by Annotation )

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

180
            /** @scrutinizer ignore-call */ 
181
            $whereClause = $criteria->renderWhere();

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...
181
            if ('WHERE ()' !== $whereClause) {
182
                $sql .= ' ' . $criteria->renderWhere();
183
                if (!empty($notNullFields)) {
184
                    $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

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

264
    private function getItemsCriteria($categoryid = -1, $status = '', /** @scrutinizer ignore-unused */ $notNullFields = '', $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...
265
    {
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
        $criteriaCategory = null;
280
        if (isset($categoryid) && -1 != $categoryid) {
281
            $criteriaCategory = new \Criteria('categoryid', $categoryid);
282
        }
283
        $criteriaStatus = new \CriteriaCompo();
284
        if (!empty($status) && is_array($status)) {
285
            foreach ($status as $v) {
286
                $criteriaStatus->add(new \Criteria('status', $v), 'OR');
287
            }
288
        } elseif (!empty($status) && -1 != $status) {
289
            $criteriaStatus->add(new \Criteria('status', $status), 'OR');
290
        }
291
        $criteria = new \CriteriaCompo();
292
        if (null !== $criteriaCategory) {
293
            $criteria->add($criteriaCategory);
294
        }
295
        if (null !== $criteriaPermissions) {
296
            $criteria->add($criteriaPermissions);
297
        }
298
        if (null !== $criteriaStatus) {
299
            $criteria->add($criteriaStatus);
300
        }
301
302
        return $criteria;
303
    }
304
305
    /**
306
     * @param        $categoryid
307
     * @param string $status
308
     * @param string $notNullFields
309
     *
310
     * @return int
311
     */
312
    public function getItemsCount($categoryid = -1, $status = '', $notNullFields = '')
313
    {
314
        //        global $publisherIsAdmin;
315
        $criteriaPermissions = null;
316
        if (!$GLOBALS['publisherIsAdmin']) {
317
            $criteriaPermissions = new \CriteriaCompo();
318
            // Categories for which user has access
319
            $categoriesGranted = $this->helper->getHandler('Permission')->getGrantedItems('category_read');
0 ignored issues
show
Bug introduced by
The method getGrantedItems() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of XoopsObjectHandler such as XoopsPersistableObjectHandler or XoopsModules\Publisher\PermissionHandler. ( Ignorable by Annotation )

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

319
            $categoriesGranted = $this->helper->getHandler('Permission')->/** @scrutinizer ignore-call */ getGrantedItems('category_read');
Loading history...
320
            if (!empty($categoriesGranted)) {
321
                $grantedCategories = new \Criteria('categoryid', '(' . implode(',', $categoriesGranted) . ')', 'IN');
322
                $criteriaPermissions->add($grantedCategories, 'AND');
323
            } else {
324
                return 0;
325
            }
326
        }
327
        //        $ret = array();
328
        $criteria = $this->getItemsCriteria($categoryid, $status, $notNullFields, $criteriaPermissions);
329
        /*
330
                if (isset($categoryid) && $categoryid != -1) {
331
                    $criteriaCategory = new \Criteria('categoryid', $categoryid);
332
                }
333
                $criteriaStatus = new \CriteriaCompo();
334
                if (!empty($status) && is_array($status)) {
335
                    foreach ($status as $v) {
336
                        $criteriaStatus->add(new \Criteria('status', $v), 'OR');
337
                    }
338
                } elseif (!empty($status) && $status != -1) {
339
                    $criteriaStatus->add(new \Criteria('status', $status), 'OR');
340
                }
341
                $criteria = new \CriteriaCompo();
342
                if (!empty($criteriaCategory)) {
343
                    $criteria->add($criteriaCategory);
344
                }
345
                if (!empty($criteriaPermissions)) {
346
                    $criteria->add($criteriaPermissions);
347
                }
348
                if (!empty($criteriaStatus)) {
349
                    $criteria->add($criteriaStatus);
350
                }
351
        */
352
        $ret = $this->getCount($criteria, $notNullFields);
353
354
        return $ret;
355
    }
356
357
    /**
358
     * @param int    $limit
359
     * @param int    $start
360
     * @param int    $categoryid
361
     * @param string $sort
362
     * @param string $order
363
     * @param string $notNullFields
364
     * @param bool   $asObject
365
     * @param string $idKey
366
     * @param bool   $excludeExpired
367
     *
368
     * @return array
369
     */
370
    public function getAllPublished($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asObject = true, $idKey = 'none', $excludeExpired = true)
371
    {
372
        
373
        $otherCriteria = new \CriteriaCompo();
374
        $criteriaDateSub = new \Criteria('datesub', time(), '<=');
375
        $otherCriteria->add($criteriaDateSub);
376
		if ($excludeExpired) {
377
            // by default expired items are excluded from list of published items
378
            $criteriaExpire = new \CriteriaCompo();
379
            $criteriaExpire->add(new \Criteria('dateexpire', '0'), 'OR');
380
            $criteriaExpire->add(new \Criteria('dateexpire', time() , '>='), 'OR');
381
            $otherCriteria->add($criteriaExpire);
382
        }
383
384
        return $this->getItems($limit, $start, [Constants::PUBLISHER_STATUS_PUBLISHED], $categoryid, $sort, $order, $notNullFields, $asObject, $otherCriteria, $idKey);
385
    }
386
387
    /**
388
     * @param int    $limit
389
     * @param int    $start
390
     * @param int    $categoryid
391
     * @param string $sort
392
     * @param string $order
393
     * @param string $notNullFields
394
     * @param bool   $asObject
395
     * @param string $idKey
396
     *
397
     * @return array
398
     */
399
    public function getAllExpired($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asObject = true, $idKey = 'none')
400
    {
401
        $otherCriteria = new \CriteriaCompo();
402
        $otherCriteria->add(new \Criteria('dateexpire', time(), '<='));
403
        $otherCriteria->add(new \Criteria('dateexpire', 0, '>'));
404
405
        return $this->getItems($limit, $start, -1, $categoryid, $sort, $order, $notNullFields, $asObject, $otherCriteria, $idKey);
406
    }
407
    
408
    /**
409
     * @param Item $obj
410
     *
411
     * @return bool
412
     */
413
    public function getPreviousPublished($obj)
414
    {
415
        $ret           = false;
416
        $otherCriteria = new \CriteriaCompo();
417
        $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

417
        $otherCriteria->add(new \Criteria('datesub', /** @scrutinizer ignore-type */ $obj->getVar('datesub'), '<'));
Loading history...
418
        $objs = $this->getItems(1, 0, [Constants::PUBLISHER_STATUS_PUBLISHED], $obj->getVar('categoryid'), 'datesub', 'DESC', '', true, $otherCriteria, 'none');
419
        if (count($objs) > 0) {
420
            $ret = $objs[0];
421
        }
422
423
        return $ret;
424
    }
425
426
    /**
427
     * @param Item $obj
428
     *
429
     * @return bool
430
     */
431
    public function getNextPublished($obj)
432
    {
433
        $ret           = false;
434
        $otherCriteria = new \CriteriaCompo();
435
        $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

435
        $otherCriteria->add(new \Criteria('datesub', /** @scrutinizer ignore-type */ $obj->getVar('datesub'), '>'));
Loading history...
436
        $otherCriteria->add(new \Criteria('datesub', time(), '<='));
437
        $objs = $this->getItems(1, 0, [Constants::PUBLISHER_STATUS_PUBLISHED], $obj->getVar('categoryid'), 'datesub', 'ASC', '', true, $otherCriteria, 'none');
438
        if (count($objs) > 0) {
439
            $ret = $objs[0];
440
        }
441
442
        return $ret;
443
    }
444
445
    /**
446
     * @param int    $limit
447
     * @param int    $start
448
     * @param int    $categoryid
449
     * @param string $sort
450
     * @param string $order
451
     * @param string $notNullFields
452
     * @param bool   $asObject
453
     * @param string $idKey
454
     *
455
     * @return array
456
     */
457
    public function getAllSubmitted($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asObject = true, $idKey = 'none')
458
    {
459
        return $this->getItems($limit, $start, [Constants::PUBLISHER_STATUS_SUBMITTED], $categoryid, $sort, $order, $notNullFields, $asObject, null, $idKey);
460
    }
461
462
    /**
463
     * @param int    $limit
464
     * @param int    $start
465
     * @param int    $categoryid
466
     * @param string $sort
467
     * @param string $order
468
     * @param string $notNullFields
469
     * @param bool   $asObject
470
     * @param string $idKey
471
     *
472
     * @return array
473
     */
474
    public function getAllOffline($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asObject = true, $idKey = 'none')
475
    {
476
        return $this->getItems($limit, $start, [Constants::PUBLISHER_STATUS_OFFLINE], $categoryid, $sort, $order, $notNullFields, $asObject, null, $idKey);
477
    }
478
479
    /**
480
     * @param int    $limit
481
     * @param int    $start
482
     * @param int    $categoryid
483
     * @param string $sort
484
     * @param string $order
485
     * @param string $notNullFields
486
     * @param bool   $asObject
487
     * @param string $idKey
488
     *
489
     * @return array
490
     */
491
    public function getAllRejected($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asObject = true, $idKey = 'none')
492
    {
493
        return $this->getItems($limit, $start, [Constants::PUBLISHER_STATUS_REJECTED], $categoryid, $sort, $order, $notNullFields, $asObject, null, $idKey);
494
    }
495
496
    /**
497
     * @param  int          $limit
498
     * @param  int          $start
499
     * @param  array|string $status
500
     * @param  int          $categoryid
501
     * @param  string       $sort
502
     * @param  string       $order
503
     * @param  string       $notNullFields
504
     * @param  bool         $asObject
505
     * @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...
506
     * @param  bool|string  $idKey
507
     * @return array
508
     * @internal param bool $asObject
509
     */
510
    public function getItems($limit = 0, $start = 0, $status = '', $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $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

510
    public function getItems($limit = 0, $start = 0, $status = '', $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', /** @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...
511
    {
512
        //        global $publisherIsAdmin;
513
        $criteriaPermissions = null;
514
        if (!$GLOBALS['publisherIsAdmin']) {
515
            $criteriaPermissions = new \CriteriaCompo();
516
            // Categories for which user has access
517
            $categoriesGranted = $this->helper->getHandler('Permission')->getGrantedItems('category_read');
518
            if (!empty($categoriesGranted)) {
519
                $grantedCategories = new \Criteria('categoryid', '(' . implode(',', $categoriesGranted) . ')', 'IN');
520
                $criteriaPermissions->add($grantedCategories, 'AND');
521
            } else {
522
                return [];
523
            }
524
        }
525
526
        $criteria = $this->getItemsCriteria($categoryid, $status, $notNullFields, $criteriaPermissions);
527
        /*
528
                if (isset($categoryid) && $categoryid != -1) {
529
                    $criteriaCategory = new \Criteria('categoryid', $categoryid);
530
                }
531
                $criteriaStatus = new \CriteriaCompo();
532
                if (!empty($status) && is_array($status)) {
533
                    foreach ($status as $v) {
534
                        $criteriaStatus->add(new \Criteria('status', $v), 'OR');
535
                    }
536
                } elseif (!empty($status) && $status != -1) {
537
                    $criteriaStatus->add(new \Criteria('status', $status), 'OR');
538
                }
539
                $criteria = new \CriteriaCompo();
540
                if (!empty($criteriaCategory)) {
541
                    $criteria->add($criteriaCategory);
542
                }
543
                if (!empty($criteriaPermissions)) {
544
                    $criteria->add($criteriaPermissions);
545
                }
546
                if (!empty($criteriaStatus)) {
547
                    $criteria->add($criteriaStatus);
548
                }
549
        */
550
        //        $ret = array();
551
552
        if (!empty($otherCriteria)) {
553
            $criteria->add($otherCriteria);
554
        }
555
        $criteria->setLimit($limit);
556
        $criteria->setStart($start);
557
        $criteria->setSort($sort);
558
        $criteria->setOrder($order);
559
        $ret = &$this->getObjects($criteria, $idKey, $notNullFields);
0 ignored issues
show
Bug introduced by
$notNullFields of type string is incompatible with the type boolean expected by parameter $as_object of XoopsModules\Publisher\ItemHandler::getObjects(). ( Ignorable by Annotation )

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

559
        $ret = &$this->getObjects($criteria, $idKey, /** @scrutinizer ignore-type */ $notNullFields);
Loading history...
560
561
        return $ret;
562
    }
563
564
    /**
565
     * @param string $field
566
     * @param string $status
567
     * @param int    $categoryId
568
     *
569
     * @return bool
570
     */
571
    public function getRandomItem($field = '', $status = '', $categoryId = -1)
572
    {
573
        $ret           = false;
574
        $notNullFields = $field;
575
        // Getting the number of published Items
576
        $totalItems = $this->getItemsCount($categoryId, $status, $notNullFields);
577
        if ($totalItems > 0) {
578
            --$totalItems;
579
            $entryNumber = mt_rand(0, $totalItems);
580
            $item        = $this->getItems(1, $entryNumber, $status, $categoryId, $sort = 'datesub', $order = 'DESC', $notNullFields);
581
            if ($item) {
582
                $ret = $item[0];
583
            }
584
        }
585
586
        return $ret;
587
    }
588
589
    /**
590
     * delete Items matching a set of conditions
591
     *
592
     * @param \CriteriaElement $criteria {@link CriteriaElement}
593
     *
594
     * @param  bool            $force
595
     * @param  bool            $asObject
596
     * @return bool FALSE if deletion failed
597
     */
598
    public function deleteAll(\CriteriaElement $criteria = null, $force = true, $asObject = false) //deleteAll($criteria = null)
599
    {
600
        //todo resource consuming, use get list instead?
601
        $items = &$this->getObjects($criteria);
602
        foreach ($items as $item) {
603
            $this->delete($item);
604
        }
605
606
        return true;
607
    }
608
609
    /**
610
     * @param $itemid
611
     *
612
     * @return bool
613
     */
614
    public function updateCounter($itemid)
615
    {
616
        $sql = 'UPDATE ' . $this->db->prefix($this->helper->getDirname() . '_items') . ' SET counter=counter+1 WHERE itemid = ' . $itemid;
617
        if ($this->db->queryF($sql)) {
618
            return true;
619
        }
620
621
        return false;
622
    }
623
624
    /**
625
     * @param string|array $notNullFields
626
     * @param bool         $withAnd
627
     *
628
     * @return string
629
     */
630
    public function notNullFieldClause($notNullFields = '', $withAnd = false)
631
    {
632
        $ret = '';
633
        if ($withAnd) {
634
            $ret .= ' AND ';
635
        }
636
        if (!empty($notNullFields) && is_array($notNullFields)) {
637
            foreach ($notNullFields as $v) {
638
                $ret .= " ($v IS NOT NULL AND $v <> ' ' )";
639
            }
640
        } elseif (!empty($notNullFields)) {
641
            $ret .= " ($notNullFields IS NOT NULL AND $notNullFields <> ' ' )";
642
        }
643
644
        return $ret;
645
    }
646
647
    /**
648
     * @param array        $queryArray
649
     * @param string       $andor
650
     * @param int          $limit
651
     * @param int          $offset
652
     * @param int|array    $userid
653
     * @param array        $categories
654
     * @param int|string   $sortby
655
     * @param string|array $searchin
656
     * @param string       $extra
657
     *
658
     * @return array
659
     */
660
    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

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