Passed
Push — master ( 81ba93...c6c854 )
by Michael
03:30
created

CategoryHandler::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
c 0
b 0
f 0
dl 0
loc 10
rs 10
cc 2
nc 2
nop 2
1
<?php
2
3
namespace XoopsModules\Smartfaq;
4
5
/**
6
 * Module: SmartFAQ
7
 * Author: The SmartFactory <www.smartfactory.ca>
8
 * Licence: GNU
9
 */
10
11
use XoopsModules\Smartfaq;
12
13
// defined('XOOPS_ROOT_PATH') || die('Restricted access');
14
15
/**
16
 * Categories handler class.
17
 * This class is responsible for providing data access mechanisms to the data source
18
 * of Category class objects.
19
 *
20
 * @author  marcan <[email protected]>
21
 * @package SmartFAQ
22
 */
23
class CategoryHandler extends \XoopsObjectHandler
24
{
25
    protected $helper;
26
    /**
27
     * @param \XoopsDatabase $db
28
     * @param null|\XoopsModules\Smartfaq\Helper           $helper
29
     */
30
    public function __construct(\XoopsDatabase $db = null, \XoopsModules\Smartfaq\Helper $helper = null)
31
    {
32
        /** @var \XoopsModules\Smartfaq\Helper $this->helper */
33
        if (null === $helper) {
34
            $this->helper = \XoopsModules\Smartfaq\Helper::getInstance();
35
        } else {
36
            $this->helper = $helper;
37
        }
38
        $smartfaqIsAdmin = $this->helper->isUserAdmin();
0 ignored issues
show
Unused Code introduced by
The assignment to $smartfaqIsAdmin is dead and can be removed.
Loading history...
39
        parent::__construct($db, 'smartfaq_categories', Category::class, 'categoryid', 'answer');
0 ignored issues
show
Unused Code introduced by
The call to XoopsObjectHandler::__construct() has too many arguments starting with 'smartfaq_categories'. ( Ignorable by Annotation )

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

39
        parent::/** @scrutinizer ignore-call */ 
40
                __construct($db, 'smartfaq_categories', Category::class, 'categoryid', 'answer');

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...
Bug introduced by
It seems like $db can also be of type null; however, parameter $db of XoopsObjectHandler::__construct() does only seem to accept XoopsDatabase, 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

39
        parent::__construct(/** @scrutinizer ignore-type */ $db, 'smartfaq_categories', Category::class, 'categoryid', 'answer');
Loading history...
40
    }
41
42
43
    /**
44
     * create a new category
45
     *
46
     * @param  bool $isNew flag the new objects as "new"?
47
     * @return object Smartfaq\Category
48
     */
49
    public function create($isNew = true)
50
    {
51
        $category = new Smartfaq\Category();
52
        if ($isNew) {
53
            $category->setNew();
54
        }
55
56
        return $category;
57
    }
58
59
    /**
60
     * retrieve a category
61
     *
62
     * @param  int $id categoryid of the category
63
     * @return mixed reference to the {@link Smartfaq\Category} object, FALSE if failed
64
     */
65
    public function get($id)
66
    {
67
        $false = false;
68
        if ((int)$id > 0) {
69
            $sql = 'SELECT * FROM ' . $this->db->prefix('smartfaq_categories') . ' WHERE categoryid=' . $id;
70
            if (!$result = $this->db->query($sql)) {
71
                return $false;
72
            }
73
74
            $numrows = $this->db->getRowsNum($result);
75
            if (1 == $numrows) {
76
                $category = new Smartfaq\Category();
77
                $category->assignVars($this->db->fetchArray($result));
78
79
                return $category;
80
            }
81
        }
82
83
        return $false;
84
    }
85
86
    /**
87
     * insert a new category in the database
88
     *
89
     * @param \XoopsObject $category reference to the {@link Smartfaq\Category}
90
     *                               object
91
     * @param  bool        $force
92
     * @return bool        FALSE if failed, TRUE if already present and unchanged or successful
93
     */
94
    public function insert(\XoopsObject $category, $force = false)
95
    {
96
        if ('xoopsmodules\smartfaq\category' !== mb_strtolower(get_class($category))) {
97
            return false;
98
        }
99
        if (!$category->isDirty()) {
100
            return true;
101
        }
102
        if (!$category->cleanVars()) {
103
            return false;
104
        }
105
106
        foreach ($category->cleanVars as $k => $v) {
107
            ${$k} = $v;
108
        }
109
110
        if ($category->isNew()) {
111
            $sql = sprintf('INSERT INTO `%s` (parentid, name, description, total, weight, created) VALUES (%u, %s, %s, %u, %u, %u)', $this->db->prefix('smartfaq_categories'), $parentid, $this->db->quoteString($name), $this->db->quoteString($description), $total, $weight, time());
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $name seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $total seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $weight seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $description seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $parentid seems to be never defined.
Loading history...
112
        } else {
113
            $sql = sprintf('UPDATE `%s` SET parentid = %u, name = %s, description = %s, total = %s, weight = %u, created = %u WHERE categoryid = %u', $this->db->prefix('smartfaq_categories'), $parentid, $this->db->quoteString($name), $this->db->quoteString($description), $total, $weight, $created,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $created seems to be never defined.
Loading history...
114
                           $categoryid);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $categoryid does not exist. Did you maybe mean $category?
Loading history...
115
        }
116
        if (false !== $force) {
117
            $result = $this->db->queryF($sql);
118
        } else {
119
            $result = $this->db->query($sql);
120
        }
121
        if (!$result) {
122
            return false;
123
        }
124
        if ($category->isNew()) {
125
            $category->assignVar('categoryid', $this->db->getInsertId());
126
        } else {
127
            $category->assignVar('categoryid', $categoryid);
128
        }
129
130
        return true;
131
    }
132
133
    /**
134
     * delete a category from the database
135
     *
136
     * @param \XoopsObject $category reference to the category to delete
137
     * @param  bool        $force
138
     * @return bool        FALSE if failed.
139
     */
140
    public function delete(\XoopsObject $category, $force = false)
141
    {
142
        if ('xoopsmodules\smartfaq\category' !== mb_strtolower(get_class($category))) {
143
            return false;
144
        }
145
146
        // Deleting the FAQs
147
        $faqHandler = new Smartfaq\FaqHandler($this->db);
148
        if (!$faqHandler->deleteAll(new \Criteria('categoryid', $category->categoryid()))) {
0 ignored issues
show
Bug introduced by
The method categoryid() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as XoopsModules\Smartfaq\Faq or XoopsModules\Smartfaq\Category. ( Ignorable by Annotation )

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

148
        if (!$faqHandler->deleteAll(new \Criteria('categoryid', $category->/** @scrutinizer ignore-call */ categoryid()))) {
Loading history...
149
            return false;
150
        }
151
152
        // Deleteing the sub categories
153
        $subcats = &$this->getCategories(0, 0, $category->categoryid());
154
        foreach ($subcats as $subcat) {
155
            $this->delete($subcat);
156
        }
157
158
        $sql = sprintf('DELETE FROM `%s` WHERE categoryid = %u', $this->db->prefix('smartfaq_categories'), $category->getVar('categoryid'));
0 ignored issues
show
Bug introduced by
It seems like $category->getVar('categoryid') can also be of type array and array; however, parameter $args of sprintf() 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

158
        $sql = sprintf('DELETE FROM `%s` WHERE categoryid = %u', $this->db->prefix('smartfaq_categories'), /** @scrutinizer ignore-type */ $category->getVar('categoryid'));
Loading history...
159
160
        $smartModule = Smartfaq\Utility::getModuleInfo();
161
        $module_id   = $smartModule->getVar('mid');
162
163
        if (false !== $force) {
164
            $result = $this->db->queryF($sql);
165
        } else {
166
            $result = $this->db->query($sql);
167
        }
168
169
        xoops_groupperm_deletebymoditem($module_id, 'category_read', $category->categoryid());
170
        //xoops_groupperm_deletebymoditem ($module_id, "category_admin", $categoryObj->categoryid());
171
172
        if (!$result) {
173
            return false;
174
        }
175
176
        return true;
177
    }
178
179
    /**
180
     * retrieve categories from the database
181
     *
182
     * @param  object $criteria  {@link CriteriaElement} conditions to be met
183
     * @param  bool   $id_as_key use the categoryid as key for the array?
184
     * @return array  array of {@link XoopsFaq} objects
185
     */
186
    public function getObjects($criteria = null, $id_as_key = false)
187
    {
188
        $ret   = [];
189
        $limit = $start = 0;
190
        $sql   = 'SELECT * FROM ' . $this->db->prefix('smartfaq_categories');
191
        if (null !== $criteria && $criteria instanceof \CriteriaElement) {
192
            $sql .= ' ' . $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

192
            $sql .= ' ' . $criteria->/** @scrutinizer ignore-call */ 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...
193
            if ('' != $criteria->getSort()) {
194
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
195
            }
196
            $limit = $criteria->getLimit();
197
            $start = $criteria->getStart();
198
        }
199
        //echo "<br>" . $sql . "<br>";
200
        $result = $this->db->query($sql, $limit, $start);
201
        if (!$result) {
202
            return $ret;
203
        }
204
205
        while (false !== ($myrow = $this->db->fetchArray($result))) {
206
            $category = new Smartfaq\Category();
207
            $category->assignVars($myrow);
208
            if (!$id_as_key) {
209
                $ret[] = $category;
210
            } else {
211
                $ret[$myrow['categoryid']] = $category;
212
            }
213
            unset($category);
214
        }
215
216
        return $ret;
217
    }
218
219
    /**
220
     * @param  int    $limit
221
     * @param  int    $start
222
     * @param  int    $parentid
223
     * @param  string $sort
224
     * @param  string $order
225
     * @param  bool   $id_as_key
226
     * @return array
227
     */
228
    public function &getCategories(
229
        $limit = 0,
230
        $start = 0,
231
        $parentid = 0,
232
        $sort = 'weight',
233
        $order = 'ASC',
234
        $id_as_key = true)
235
    {
236
        //        require_once XOOPS_ROOT_PATH . '/modules/smartfaq/include/functions.php';
237
238
        $criteria = new \CriteriaCompo();
239
240
        $criteria->setSort($sort);
241
        $criteria->setOrder($order);
242
243
        if (-1 != $parentid) {
244
            $criteria->add(new \Criteria('parentid', $parentid));
245
        }
246
        if (!Smartfaq\Utility::userIsAdmin()) {
247
            /** @var Smartfaq\PermissionHandler $smartPermHandler */
248
            $smartPermHandler = Smartfaq\Helper::getInstance()->getHandler('Permission');
249
250
            $categoriesGranted = $smartPermHandler->getPermissions('category');
251
            $criteria->add(new \Criteria('categoryid', '(' . implode(',', $categoriesGranted) . ')', 'IN'));
252
        }
253
        $criteria->setStart($start);
254
        $criteria->setLimit($limit);
255
        $ret = $this->getObjects($criteria, $id_as_key);
256
257
        return $ret;
258
    }
259
260
    /**
261
     * @param  int    $limit
262
     * @param  int    $start
263
     * @param  int    $parentid
264
     * @param  string $sort
265
     * @param  string $order
266
     * @return array
267
     */
268
    public function &getCategoriesWithOpenQuestion(
269
        $limit = 0,
270
        $start = 0,
271
        $parentid = 0,
272
        $sort = 'weight',
273
        $order = 'ASC')
274
    {
275
        //        require_once XOOPS_ROOT_PATH . '/modules/smartfaq/include/functions.php';
276
277
        $criteria = new \CriteriaCompo();
278
279
        $criteria->setSort($sort);
280
        $criteria->setOrder($order);
281
282
        if (-1 != $parentid) {
283
            $criteria->add(new \Criteria('c.parentid', $parentid));
284
        }
285
        if (!Smartfaq\Utility::userIsAdmin()) {
286
            /** @var Smartfaq\PermissionHandler $smartPermHandler */
287
            $smartPermHandler = Smartfaq\Helper::getInstance()->getHandler('Permission');
288
289
            $categoriesGranted = $smartPermHandler->getPermissions('category');
290
            $criteria->add(new \Criteria('categoryid', '(' . implode(',', $categoriesGranted) . ')', 'IN'));
291
        }
292
293
        $criteria->add(new \Criteria('f.status', Constants::SF_STATUS_OPENED));
294
        $criteria->setStart($start);
295
        $criteria->setLimit($limit);
296
297
        $ret   = [];
298
        $limit = $start = 0;
299
        $sql   = 'SELECT DISTINCT c.categoryid, c.parentid, c.name, c.description, c.total, c.weight, c.created FROM ' . $this->db->prefix('smartfaq_categories') . ' AS c INNER JOIN ' . $this->db->prefix('smartfaq_faq') . ' AS f ON c.categoryid = f.categoryid';
300
        if (null !== $criteria && $criteria instanceof \CriteriaElement) {
301
            $sql .= ' ' . $criteria->renderWhere();
302
            if ('' != $criteria->getSort()) {
303
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
304
            }
305
            $limit = $criteria->getLimit();
306
            $start = $criteria->getStart();
307
        }
308
        //echo "<br>" . $sql . "<br>";
309
        $result = $this->db->query($sql, $limit, $start);
310
        if (!$result) {
311
            return $ret;
312
        }
313
314
        while (false !== ($myrow = $this->db->fetchArray($result))) {
315
            $category = new Smartfaq\Category();
316
            $category->assignVars($myrow);
317
            $ret[] = $category;
318
            unset($category);
319
        }
320
321
        return $ret;
322
    }
323
324
    /**
325
     * count Categories matching a condition
326
     *
327
     * @param  object $criteria {@link CriteriaElement} to match
328
     * @return int    count of categories
329
     */
330
    public function getCount($criteria = null)
331
    {
332
        $sql = 'SELECT COUNT(*) FROM ' . $this->db->prefix('smartfaq_categories');
333
        if (null !== $criteria && $criteria instanceof \CriteriaElement) {
334
            $sql .= ' ' . $criteria->renderWhere();
335
        }
336
        $result = $this->db->query($sql);
337
        if (!$result) {
338
            return 0;
339
        }
340
        list($count) = $this->db->fetchRow($result);
341
342
        return $count;
343
    }
344
345
    /**
346
     * @param  int $parentid
347
     * @return int
348
     */
349
    public function getCategoriesCount($parentid = 0)
350
    {
351
        if (-1 == $parentid) {
352
            return $this->getCount();
353
        }
354
        $criteria = new \CriteriaCompo();
355
        if (isset($parentid) && (-1 != $parentid)) {
356
            $criteria->add(new \Criteria('parentid', $parentid));
357
            if (!Smartfaq\Utility::userIsAdmin()) {
358
                /** @var Smartfaq\PermissionHandler $smartPermHandler */
359
                $smartPermHandler = Smartfaq\Helper::getInstance()->getHandler('Permission');
360
361
                $categoriesGranted = $smartPermHandler->getPermissions('category');
362
                $criteria->add(new \Criteria('categoryid', '(' . implode(',', $categoriesGranted) . ')', 'IN'));
363
            }
364
        }
365
366
        return $this->getCount($criteria);
367
    }
368
369
    /**
370
     * @param  int $parentid
371
     * @return int
372
     */
373
    public function getCategoriesWithOpenQuestionsCount($parentid = 0)
374
    {
375
        if (-1 == $parentid) {
376
            return $this->getCount();
377
        }
378
        $criteria = new \CriteriaCompo();
379
        if (isset($parentid) && (-1 != $parentid)) {
380
            $criteria->add(new \Criteria('parentid', $parentid));
381
            if (!Smartfaq\Utility::userIsAdmin()) {
382
                /** @var Smartfaq\PermissionHandler $smartPermHandler */
383
                $smartPermHandler = Smartfaq\Helper::getInstance()->getHandler('Permission');
384
385
                $categoriesGranted = $smartPermHandler->getPermissions('category');
386
                $criteria->add(new \Criteria('categoryid', '(' . implode(',', $categoriesGranted) . ')', 'IN'));
387
            }
388
        }
389
390
        $criteria->add(new \Criteria('f.status', Constants::SF_STATUS_OPENED));
391
392
        $sql = 'SELECT COUNT(c.categoryid) FROM ' . $this->db->prefix('smartfaq_categories') . ' AS c INNER JOIN ' . $this->db->prefix('smartfaq_faq') . ' AS f ON c.categoryid = f.categoryid';
393
394
        if (isset($criteria) && $criteria instanceof \CriteriaElement) {
395
            $sql .= ' ' . $criteria->renderWhere();
396
        }
397
398
        $result = $this->db->query($sql);
399
        if (!$result) {
400
            return 0;
401
        }
402
        list($count) = $this->db->fetchRow($result);
403
404
        return $count;
405
    }
406
407
    /**
408
     * @param $categories
409
     * @return array
410
     */
411
    public function getSubCats($categories)
412
    {
413
        $criteria = new \CriteriaCompo(new \Criteria('parentid', '(' . implode(',', array_keys($categories)) . ')'), 'IN');
414
        $ret      = [];
415
        if (!Smartfaq\Utility::userIsAdmin()) {
416
            /** @var Smartfaq\PermissionHandler $smartPermHandler */
417
            $smartPermHandler = Smartfaq\Helper::getInstance()->getHandler('Permission');
418
419
            $categoriesGranted = $smartPermHandler->getPermissions('category');
420
            $criteria->add(new \Criteria('categoryid', '(' . implode(',', $categoriesGranted) . ')', 'IN'));
421
        }
422
        $subcats = $this->getObjects($criteria, true);
423
        foreach ($subcats as $subcat_id => $subcat) {
424
            $ret[$subcat->getVar('parentid')][$subcat->getVar('categoryid')] = $subcat;
425
        }
426
427
        return $ret;
428
    }
429
430
    /**
431
     * delete categories matching a set of conditions
432
     *
433
     * @param  object $criteria {@link CriteriaElement}
434
     * @return bool   FALSE if deletion failed
435
     */
436
    public function deleteAll($criteria = null)
437
    {
438
        $sql = 'DELETE FROM ' . $this->db->prefix('smartfaq_categories');
439
        if (null !== $criteria && $criteria instanceof \CriteriaElement) {
440
            $sql .= ' ' . $criteria->renderWhere();
441
        }
442
        if (!$this->db->query($sql)) {
443
            return false;
444
            // TODO : Also delete the permissions related to each FAQ
445
            // TODO : What about sub-categories???
446
        }
447
448
        return true;
449
    }
450
451
    /**
452
     * Change a value for categories with a certain criteria
453
     *
454
     * @param string           $fieldname  Name of the field
455
     * @param string           $fieldvalue Value to write
456
     * @param \CriteriaElement $criteria   {@link CriteriaElement}
457
     *
458
     * @return bool
459
     **/
460
    public function updateAll($fieldname, $fieldvalue, \CriteriaElement $criteria = null)
461
    {
462
        $set_clause = is_numeric($fieldvalue) ? $fieldname . ' = ' . $fieldvalue : $fieldname . ' = ' . $this->db->quoteString($fieldvalue);
463
        $sql        = 'UPDATE ' . $this->db->prefix('smartfaq_categories') . ' SET ' . $set_clause;
464
        if (null !== $criteria && $criteria instanceof \CriteriaElement) {
465
            $sql .= ' ' . $criteria->renderWhere();
466
        }
467
        if (!$this->db->queryF($sql)) {
468
            return false;
469
        }
470
471
        return true;
472
    }
473
474
    /**
475
     * @param  int $cat_id
476
     * @return mixed
477
     */
478
    public function publishedFaqsCount($cat_id = 0)
479
    {
480
        return $this->faqsCount($cat_id, $status = [Constants::SF_STATUS_PUBLISHED, Constants::SF_STATUS_NEW_ANSWER]);
0 ignored issues
show
Bug introduced by
$status = array(XoopsMod...::SF_STATUS_NEW_ANSWER) of type array<integer,integer> is incompatible with the type string expected by parameter $status of XoopsModules\Smartfaq\CategoryHandler::faqsCount(). ( Ignorable by Annotation )

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

480
        return $this->faqsCount($cat_id, /** @scrutinizer ignore-type */ $status = [Constants::SF_STATUS_PUBLISHED, Constants::SF_STATUS_NEW_ANSWER]);
Loading history...
481
    }
482
483
    /**
484
     * @param  int    $cat_id
485
     * @param  string $status
486
     * @return mixed
487
     */
488
    public function faqsCount($cat_id = 0, $status = '')
489
    {
490
        global $xoopsUser;
491
        //        require_once XOOPS_ROOT_PATH . '/modules/smartfaq/include/functions.php';
492
493
        /** @var Smartfaq\FaqHandler $faqHandler */
494
        $faqHandler = Smartfaq\Helper::getInstance()->getHandler('Faq');
495
496
        return $faqHandler->getCountsByCat($cat_id, $status);
497
    }
498
}
499