Passed
Pull Request — master (#24)
by Michael
02:52
created

TagHandler::getByLimit()   F

Complexity

Conditions 19
Paths 4480

Size

Total Lines 60
Code Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 19
eloc 48
c 3
b 0
f 0
nc 4480
nop 5
dl 0
loc 60
rs 0.3499

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace XoopsModules\Tag;
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
 * XOOPS tag management module
17
 *
18
 * @package         XoopsModules\Tag
19
 * @copyright       {@link http://sourceforge.net/projects/xoops/ The XOOPS Project}
20
 * @license         {@link http://www.fsf.org/copyleft/gpl.html GNU public license}
21
 * @author          Taiwen Jiang <[email protected]>
22
 * @since           1.00
23
 */
24
defined('XOOPS_ROOT_PATH') || exit('Restricted access');
25
26
use XoopsModules\Tag\Utility;
27
28
/**
29
 * Class TagHandler
30
 */
31
class TagHandler extends \XoopsPersistableObjectHandler
32
{
33
    public $table_link;
34
    public $table_stats;
35
36
    /**
37
     * Constructor
38
     *
39
     * @param \XoopsDatabase|null $db reference to the object {@link XoopsDatabase}
40
     */
41
    public function __construct(\XoopsDatabase $db = null)
42
    {
43
        parent::__construct($db, 'tag_tag', Tag::class, 'tag_id', 'tag_term');
44
        $this->table_link  = $this->db->prefix('tag_link');
45
        $this->table_stats = $this->db->prefix('tag_stats');
46
    }
47
48
    /**
49
     * Get tags linked to an item
50
     *
51
     * @access public
52
     * @param  int $itemid item ID
53
     * @param  int $modid  module ID, optional
54
     * @param  int $catid  id of corresponding category, optional
55
     * @return array associative array of tags (id, term)
56
     */
57
    public function getByItem($itemid, $modid = 0, $catid = 0)
58
    {
59
        $ret = [];
60
61
        $itemid = (int)$itemid;
62
        $modid  = (empty($modid) && is_object($GLOBALS['xoopsModule'])
63
                   && 'tag' !== $GLOBALS['xoopsModule']->getVar('dirname')) ? $GLOBALS['xoopsModule']->getVar('mid') : (int)$modid;
64
        if (empty($itemid) || empty($modid)) {
65
            return $ret;
66
        }
67
68
        $sql = 'SELECT o.tag_id, o.tag_term'
69
               . " FROM {$this->table_link} AS l "
70
               . " LEFT JOIN {$this->table} AS o ON o.{$this->keyName} = l.{$this->keyName} "
71
               . " WHERE  l.tag_itemid = {$itemid} AND l.tag_modid = {$modid}"
72
               . (empty($catid) ? '' : (' AND l.tag_catid=' . (int)$catid))
73
               . ' ORDER BY o.tag_count DESC';
74
        if (false === ($result = $this->db->query($sql))) {
75
            return $ret;
76
        }
77
        while (false !== ($myrow = $this->db->fetchArray($result))) {
78
            $ret[$myrow[$this->keyName]] = $myrow['tag_term'];
79
        }
80
81
        return $ret;
82
    }
83
84
    /**
85
     * Update tags linked to an item
86
     *
87
     * @access   public
88
     * @param  array|string $tags   array of $tags or a single tag
89
     * @param  int          $itemid item ID
90
     * @param  int|string   $modid  module ID or module dirname, optional
91
     * @param  int          $catid  id of corresponding category, optional
92
     * @return bool
93
     */
94
    public function updateByItem($tags, $itemid, $modid = '', $catid = 0)
95
    {
96
        $catid  = (int)$catid;
97
        $itemid = (int)$itemid;
98
99
        if (!empty($modid) && !is_numeric($modid)) {
100
            if (($GLOBALS['xoopsModule'] instanceof \XoopsModule)
101
                && ($modid == $GLOBALS['xoopsModule']->getVar('dirname'))) {
102
                $modid = $GLOBALS['xoopsModule']->getVar('mid');
103
            } else {
104
                /** @var \XoopsModuleHandler $moduleHandler */
105
                $moduleHandler = xoops_getHandler('module');
106
                $modid         = ($module_obj = $moduleHandler->getByDirname($modid)) ? $module_obj->getVar('mid') : 0;
107
            }
108
        } elseif ($GLOBALS['xoopsModule'] instanceof \XoopsModule) {
109
            $modid = $GLOBALS['xoopsModule']->getVar('mid');
110
        }
111
112
        if (empty($itemid) || empty($modid)) {
113
            return false;
114
        }
115
116
        if (empty($tags)) {
117
            $tags = [];
118
        } elseif (!is_array($tags)) {
119
            //require_once $GLOBALS['xoops']->path('/modules/tag/include/functions.php');
120
            $tags = Utility::tag_parse_tag(addslashes(stripslashes($tags)));
121
        }
122
123
        $tags_existing = $this->getByItem($itemid, $modid, $catid);
124
        $tags_delete   = array_diff(array_values($tags_existing), $tags);
125
        $tags_add      = array_diff($tags, array_values($tags_existing));
126
        $tags_update   = [];
127
128
        if (0 < count($tags_delete)) {
129
            $tags_delete = array_map([$this->db, 'quoteString'], $tags_delete);
130
            $tags_id     = &$this->getIds(new \Criteria('tag_term', '(' . implode(', ', $tags_delete) . ')', 'IN'));
131
            if ($tags_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $tags_id 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...
132
                $sql = "DELETE FROM {$this->table_link}" . ' WHERE ' . "     {$this->keyName} IN (" . implode(', ', $tags_id) . ')' . "     AND tag_modid = {$modid} AND tag_catid = {$catid} AND tag_itemid = {$itemid}";
133
                if (false === ($result = $this->db->queryF($sql))) {
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
134
                    //@todo: decide if we should do something here on failure
135
                }
136
                $sql = 'DELETE FROM ' . $this->table . ' WHERE ' . '    tag_count < 2 AND ' . "     {$this->keyName} IN (" . implode(', ', $tags_id) . ')';
137
                if (false === ($result = $this->db->queryF($sql))) {
138
                    //xoops_error($this->db->error());
139
                }
140
141
                $sql = 'UPDATE ' . $this->table . ' SET tag_count = tag_count - 1' . ' WHERE ' . "     {$this->keyName} IN (" . implode(', ', $tags_id) . ')';
142
                if (false === ($result = $this->db->queryF($sql))) {
143
                    //xoops_error($this->db->error());
144
                }
145
                $tags_update = $tags_id;
146
            }
147
        }
148
149
        if (!empty($tags_add)) {
150
            $tag_link  = [];
151
            $tag_count = [];
152
            foreach ($tags_add as $tag) {
153
                $tags_id = &$this->getIds(new \Criteria('tag_term', $tag));
154
                if ($tags_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $tags_id 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...
155
                    $tag_id      = $tags_id[0];
156
                    $tag_count[] = $tag_id;
157
                } else {
158
                    $tag_obj = $this->create();
159
                    $tag_obj->setVars(['tag_term' => $tag, 'tag_count' => 1]);
160
                    $this->insert($tag_obj);
161
                    $tag_id = $tag_obj->getVar('tag_id');
162
                    unset($tag_obj);
163
                }
164
                $tag_link[]    = "({$tag_id}, {$itemid}, {$catid}, {$modid}, " . time() . ')';
165
                $tags_update[] = $tag_id;
166
            }
167
            $sql = "INSERT INTO {$this->table_link}" . ' (tag_id, tag_itemid, tag_catid, tag_modid, tag_time) ' . ' VALUES ' . implode(', ', $tag_link);
168
            if (false === ($result = $this->db->queryF($sql))) {
169
                //xoops_error($this->db->error());
170
            }
171
            if (!empty($tag_count)) {
172
                $sql = 'UPDATE ' . $this->table . ' SET tag_count = tag_count+1' . ' WHERE ' . "     {$this->keyName} IN (" . implode(', ', $tag_count) . ')';
173
                if (false === ($result = $this->db->queryF($sql))) {
174
                    //xoops_error($this->db->error());
175
                }
176
            }
177
        }
178
        if (is_array($tags_update)) {
179
            foreach ($tags_update as $tag_id) {
180
                $this->update_stats($tag_id, $modid, $catid);
181
            }
182
        }
183
184
        return true;
185
    }
186
187
    /**
188
     * Update count stats or tag
189
     *
190
     * @access public
191
     * @param  int $tag_id
192
     * @param  int $modid
193
     * @param  int $catid
194
     * @return bool
195
     */
196
    public function update_stats($tag_id, $modid = 0, $catid = 0)
197
    {
198
        $tag_id    = (int)$tag_id;
199
        if (0 === $tag_id) {
200
            return true;
201
        }
202
203
        $tag_count = [];
204
        $modid = (int)$modid;
205
        $catid = (0 === $modid) ? -1 : (int)$catid;
206
207
        /** @var \XoopsModules\Tag\LinkHandler $linkHandler */
208
        $linkHandler = \XoopsModules\Tag\Helper::getInstance()->getHandler('Link');
209
        $criteria = new \CriteriaCompo(new \Criteria('tag_id', $tag_id));
210
        if (0 !== $modid) {
211
            $criteria->add(new \Criteria('tag_modid', $modid), 'ADD');
212
        }
213
        if (0 < $catid) {
214
            $criteria->add(new \Criteria('tag_catid', $catid), 'ADD');
215
        }
216
        $count = $linkHandler->getCount($criteria);
217
        /*
218
        $sql   = 'SELECT COUNT(*) ' . " FROM {$this->table_link}" . " WHERE tag_id = {$tag_id}" . (empty($modid) ? '' : " AND tag_modid = {$modid}") . (($catid < 0) ? '' : " AND tag_catid = {$catid}");
219
220
        $result = $this->db->query($sql);
221
        if ($result) {
222
            list($count) = $this->db->fetchRow($result);
223
        }
224
        */
225
        if (0 === $modid) {
226
            $tag_obj = $this->get($tag_id);
227
            if ($tag_obj instanceof \XoopsModules\Tag\Tag) {
228
                if (0 === $count) {
229
                $this->delete($tag_obj);
230
            } else {
231
                $tag_obj->setVar('tag_count', $count);
232
                $this->insert($tag_obj, true);
233
            }
234
            }
235
        } else {
236
            $statsHandler = \XoopsModules\Tag\Helper::getInstance()->getHandler('Stats');
237
            if (empty($count)) {
238
                $criteria = new \CriteriaCompo(new \Criteria($this->keyName, $tag_id));
239
                $criteria->add(new \Criteria('tag_modid, $modid'), 'AND');
240
                $criteria->add(new \Criteria('tag_catid', $catid), 'AND');
241
                $status = $statsHandler->deleteAll($criteria);
242
                if (!$status) {
243
                    //@todo determine what should happen here on failure.
244
                }
245
                /*
246
                $sql = "DELETE FROM {$this->table_stats}" . ' WHERE ' . " {$this->keyName} = {$tag_id}" . " AND tag_modid = {$modid}" . " AND tag_catid = {$catid}";
247
248
                if (false === $result = $this->db->queryF($sql)) {
249
                    //xoops_error($this->db->error());
250
                }
251
                */
252
            } else {
253
                $ts_id = null;
254
                $criteria = new \CriteriaCompo(new \Criteria($this->keyName, $tag_id));
255
                $criteria->add(new \Criteria('tag_modid', $modid), 'AND');
256
                $criteria->add(new \Criteria('tag_catid', $catid), 'AND');
257
                $criteria->setLimit(1);
258
                $tsCountObjs = $statsHandler->getAll($criteria);
259
                if (count($tsCountObjs) > 0) {
260
                    $tsCountObj = pop_array($tsCountObjs); // get 1st (only) item
0 ignored issues
show
Bug introduced by
The function pop_array was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

260
                    $tsCountObj = /** @scrutinizer ignore-call */ pop_array($tsCountObjs); // get 1st (only) item
Loading history...
261
                    $ts_id = $tsCountObj->getVar('ts_id');
262
                    $tag_count = $tsCountObj->getVar('tag_count');
263
                }
264
                /*
265
                $sql   = 'SELECT ts_id, tag_count ' . " FROM {$this->table_stats}" . " WHERE {$this->keyName} = {$tag_id}" . " AND tag_modid = {$modid}" . " AND tag_catid = {$catid}";
266
                $result = $this->db->query($sql);
267
                if ($result) {
268
                    list($ts_id, $tag_count) = $this->db->fetchRow($result);
269
                }
270
                */
271
                $sql = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $sql is dead and can be removed.
Loading history...
272
                if ($ts_id) {
273
                    if ($tag_count != $count) {
274
                        $tsCountObj->setVar('tag_count', $count);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $tsCountObj does not seem to be defined for all execution paths leading up to this point.
Loading history...
275
                        $statsHandler->insert($tsCountObj);
276
                        //$sql = "UPDATE {$this->table_stats}" . " SET tag_count = {$count}" . ' WHERE ' . "     ts_id = {$ts_id}";
277
                    }
278
                } else {
279
                    $newTsObj = $statsHandler->create();
280
                    $newTsObj->setVars([
281
                        'tag_id' => $tag_id,
282
                        'tag_modid' => $modid,
283
                        'tag_catid' => $catid,
284
                        'tag_count' => $count
285
                    ]);
286
                    $statsHandler->insert($newTsObj);
287
                    //$sql = "INSERT INTO {$this->table_stats}" . ' (tag_id, tag_modid, tag_catid, tag_count)' . " VALUES ({$tag_id}, {$modid}, {$catid}, {$count})";
288
                }
289
                /*
290
                if (!empty($sql) && false === ($result = $this->db->queryF($sql))) {
291
                    //xoops_error($this->db->error());
292
                }
293
                */
294
            }
295
        }
296
297
        return true;
298
    }
299
300
    /**
301
     * Get tags with item count
302
     *
303
     * @access         public
304
     * @param int                                  $limit
305
     * @param int                                  $start
306
     * @param null|\CriteriaElement|\CriteriaCompo $criteria  {@link Criteria}
307
     * @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...
308
     * @param bool                                 $fromStats fetch from tag-stats table
309
     * @return array associative array of tags (id, term, status, count)
310
     */
311
    public function &getByLimit(
312
        $limit = Constants::UNLIMITED,
313
        $start = Constants::BEGINNING,
314
        \CriteriaElement $criteria = null,
315
        $fields = null,
316
        $fromStats = true)//&getByLimit($criteria = null, $fromStats = true)
317
    {
318
        $ret = [];
319
        if ($fromStats) {
320
            $sql = "SELECT DISTINCT(o.{$this->keyName}), o.tag_term, o.tag_status, SUM(l.tag_count) AS count" . " FROM {$this->table} AS o LEFT JOIN {$this->table_stats} AS l ON l.{$this->keyName} = o.{$this->keyName}";
321
        } else {
322
            $sql = "SELECT DISTINCT(o.{$this->keyName}), o.tag_term, o.tag_status, COUNT(l.tl_id) AS count" . " FROM {$this->table} AS o LEFT JOIN {$this->table_link} AS l ON l.{$this->keyName} = o.{$this->keyName}";
323
        }
324
325
        $limit = is_int($limit) && ($limit >= 0) ? $limit : Constants::UNLIMITED;
326
        $start = is_int($start) && ($start >= 0) ? $start : Constants::BEGINNING;
327
        $sort  = '';
328
        $order = '';
329
        if (null !== $criteria && $criteria instanceof \CriteriaCompo) {
330
            $sql   .= ' ' . $criteria->renderWhere();
331
            $sort  = $criteria->getSort();
332
            $order = $criteria->getOrder();
333
            $limit = $limit >= 0 ? $limit : $criteria->getLimit(); // non-zero arg passed to method overrides $criteria setting
334
            $start = $start >= 0 ? $start : $criteria->getStart(); // non-zero arg passed to method overrides $criteria setting
335
        }
336
        $sql .= " GROUP BY o.{$this->keyName}, o.tag_term, o.tag_status, l.tag_modid";
337
338
        $order = ('ASC' !== mb_strtoupper($order)) ? 'DESC' : 'ASC';
339
        $sort  = mb_strtolower($sort);
340
        switch ($sort) {
341
            case 'a':
342
            case 'alphabet':
343
                $sql   .= " ORDER BY o.tag_term {$order}";
344
                break;
345
            case 'id':
346
            case 'time':
347
                $sql   .= " ORDER BY o.{$this->keyName} {$order}";
348
                break;
349
            case 'c':
350
            case 'count':
351
            default:
352
                $sql   .= " ORDER BY count {$order}";
353
                break;
354
        }
355
356
        if (false === ($result = $this->db->query($sql, $limit, $start))) {
357
            //xoops_error($this->db->error());
358
            $ret = null;
359
        } else {
360
            while (false !== ($myrow = $this->db->fetchArray($result))) {
361
                $ret[$myrow[$this->keyName]] = [
362
                    'id'     => $myrow[$this->keyName],
363
                    'term'   => htmlspecialchars($myrow['tag_term'], ENT_QUOTES | ENT_HTML5),
364
                    'status' => $myrow['tag_status'],
365
                    'count'  => (int)$myrow['count'],
366
                ];
367
            }
368
        }
369
370
        return $ret;
371
    }
372
373
    /**
374
     * Get count of tags
375
     *
376
     * @access public
377
     * @param null|\CriteriaElement|\CriteriaCompo $criteria {@link Criteria)
378
     * @return int count
379
     */
380
    public function getCount(\CriteriaElement $criteria = null)
381
    {
382
        /*
383
        $catid    = (int)($catid);
384
        $modid    = (int)($modid);
385
        */
386
        $sql = "SELECT COUNT(DISTINCT o.{$this->keyName})" . "    FROM {$this->table} AS o LEFT JOIN {$this->table_link} AS l ON l.{$this->keyName} = o.{$this->keyName}";
387
        if ((null !== $criteria) && $criteria instanceof \CriteriaElement) {
388
            $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

388
            $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...
389
        }
390
        /*
391
        $sql_where    = "    WHERE 1 = 1";
392
        if (!empty($modid)) {
393
            $sql_where    .= " AND l.tag_modid = {$modid}";
394
        }
395
        if (empty($catid) || $catid > 0) {
396
            $sql_where    .= " AND l.tag_catid = {$catid}";
397
        }
398
399
        $sql =     $sql_select . " " . $sql_from . " " . $sql_where;
400
        */
401
        if (false === ($result = $this->db->query($sql))) {
402
            //xoops_error($this->db->error());
403
            $ret = 0;
404
        } else {
405
            list($ret) = $this->db->fetchRow($result);
406
        }
407
408
        return $ret;
409
    }
410
411
    /**
412
     * Get items linked with a tag
413
     *
414
     * @access public
415
     * @param \CriteriaElement $criteria {@link Criteria}
416
     * @return array associative array of items[] => (id, modid, catid, time)
417
     */
418
    public function getItems(\CriteriaElement $criteria = null)
419
    {
420
        $ret = [];
421
        $sql = '    SELECT o.tl_id, o.tag_itemid, o.tag_modid, o.tag_catid, o.tag_time';
422
        $sql .= "    FROM {$this->table_link} AS o LEFT JOIN {$this->table} AS l ON l.{$this->keyName} = o.{$this->keyName}";
423
424
        $limit = Constants::UNLIMITED;
425
        $start = Constants::BEGINNING;
426
        $sort  = '';
427
        $order = '';
428
        if ((null !== $criteria) && $criteria instanceof \CriteriaElement) {
429
            $sql   .= ' ' . $criteria->renderWhere();
430
            $sort  = $criteria->getSort();
431
            $order = $criteria->getOrder();
432
            $limit = $criteria->getLimit();
433
            $start = $criteria->getStart();
434
        }
435
436
        $order = ('ASC' !== mb_strtoupper($order)) ? 'DESC' : 'ASC';
437
        $sort  = mb_strtolower($sort);
438
        switch ($sort) {
439
            case 'i':
440
            case 'item':
441
                $sql   .= "    ORDER BY o.tag_itemid {$order}, o.tl_id DESC";
442
                break;
443
            case 'm':
444
            case 'module':
445
                $sql   .= "    ORDER BY o.tag_modid {$order}, o.tl_id DESC";
446
                break;
447
            case 't':
448
            case 'time':
449
            default:
450
                $sql   .= "    ORDER BY o.tl_id {$order}";
451
                break;
452
        }
453
454
        if (false === ($result = $this->db->query($sql, $limit, $start))) {
455
            //xoops_error($this->db->error());
456
            $ret = [];
457
        } else {
458
            while (false !== ($myrow = $this->db->fetchArray($result))) {
459
                $ret[$myrow['tl_id']] = [
460
                    'itemid' => $myrow['tag_itemid'],
461
                    'modid'  => $myrow['tag_modid'],
462
                    'catid'  => $myrow['tag_catid'],
463
                    'time'   => $myrow['tag_time'],
464
                ];
465
            }
466
        }
467
468
        return $ret;
469
    }
470
471
    /**
472
     * Get count of items linked with a tag
473
     *
474
     * @access public
475
     * @param  int $tag_id
476
     * @param  int $modid id of corresponding module, optional: 0 for all; >1 for a specific module
477
     * @param  int $catid id of corresponding category, optional
478
     * @return int count
479
     */
480
    public function getItemCount($tag_id, $modid = 0, $catid = 0)
481
    {
482
        if (!$tag_id = (int)$tag_id) {
483
            $ret = 0;
484
        } else {
485
            $catid = (int)$catid;
486
            $modid = (int)$modid;
487
488
            $sql_select = '    SELECT COUNT(DISTINCT o.tl_id)';
489
            $sql_from   = "    FROM {$this->table_link} AS o LEFT JOIN {$this->table} AS l ON l.{$this->keyName} = o.{$this->keyName}";
490
            $sql_where  = "    WHERE o.tag_id = {$tag_id}";
491
            if (!empty($modid)) {
492
                $sql_where .= " AND o.tag_modid = {$modid}";
493
            }
494
            if (empty($catid) || $catid > 0) {
495
                $sql_where .= " AND o.tag_catid = {$catid}";
496
            }
497
498
            $sql = $sql_select . ' ' . $sql_from . ' ' . $sql_where;
499
            if (false === ($result = $this->db->query($sql))) {
500
                //xoops_error($this->db->error());
501
                $ret = 0;
502
            } else {
503
                list($ret) = $this->db->fetchRow($result);
504
            }
505
        }
506
507
        return $ret;
508
    }
509
510
    /**
511
     * Get detailed data (and font) for a tag
512
     *
513
     * @access public
514
     * @param array $tags_array associative array of tags (id, term, status, count)
515
     * @param int   $font_max
516
     * @param int   $font_min
517
     * @return array tag data values for display
518
     */
519
    public function getTagData($tags_array, $font_max = 0, $font_min = 0)
520
    {
521
        $tags_data_array = [];
522
        if (is_array($tags_array) && !empty($tags_array)) {
523
            // set min and max tag count
524
            $count_array = array_column($tags_array, 'count', 'id');
525
            $count_min = count($count_array) > 0 ? min($count_array) : 0;
526
            $count_min = $count_min > 0 ? $count_min : 0;
527
            $count_max = count($count_array) > 0 ? max($count_array) : 0;
528
            $count_max = $count_max > 0 ? $count_max : 0;
529
530
            $term_array = array_column($tags_array, 'term', 'id');
531
            $tags_term_array  = array_map('mb_strtolower', $term_array);
532
            array_multisort($tags_term_array, SORT_ASC, $tags_array);
533
            $count_interval = $count_max - $count_min;
534
            $level_limit = 5;
535
536
            $font_ratio = $count_interval ? ($font_max - $font_min) / $count_interval : 1;
537
538
            foreach ($tags_array as $tag) {
539
                /*
540
                 * Font-size = ((tag.count - count.min) * (font.max - font.min) / (count.max - count.min) ) * 100%
541
                 */
542
                $font_sz = floor(($tag['count'] - $count_min) * $font_ratio) + $font_min;
543
                $level_sz = floor(($tag['count'] - $count_min) * $level_limit / $count_max);
544
                $tags_data_array[] = [
545
                    'id'    => $tag['id'],
546
                    'font'  => empty($count_interval) ? 100 : (int)$font_sz,
547
                    'level' => empty($count_max) ? 0 : (int)$level_sz,
548
                    'term'  => urlencode($tag['term']),
549
                    'title' => htmlspecialchars($tag['term'], ENT_QUOTES | ENT_HTML5),
550
                    'count' => $tag['count'],
551
                ];
552
            }
553
        }
554
        return $tags_data_array;
555
    }
556
557
558
    /**
559
     * Delete an object as well as links relying on it
560
     *
561
     * @access public
562
     * @param \XoopsObject $object $object {@link Tag}
563
     * @param  bool        $force  flag to force the query execution despite security settings
564
     * @return bool
565
     */
566
    public function delete(\XoopsObject $object, $force = true)
567
    {
568
        /* {@internal - this isn't needed if we type hint Tag object }}
569
        if (!is_object($object) || !$object->getVar($this->keyName)) {
570
            return false;
571
        }
572
        */
573
        //$queryFunc = empty($force) ? 'query' : 'queryF';
574
575
        /*
576
         * Remove item-tag links
577
         */
578
        /** @var \XoopsModules\Tag\Helper $helper */
579
        $helper = \XoopsModules\Tag\Helper::getInstance();
580
581
        /** @var \XoopsModules\Tag\LinkHandler $linkHandler */
582
        $linkHandler = $helper->getHandler('Link');
583
        $criteria = new \Criteria($this->keyName, $object->getVar($this->keyName));
0 ignored issues
show
Bug introduced by
It seems like $object->getVar($this->keyName) 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

583
        $criteria = new \Criteria($this->keyName, /** @scrutinizer ignore-type */ $object->getVar($this->keyName));
Loading history...
584
        $linkHandler->deleteAll($criteria, $force);
585
        //$sql = 'DELETE' . " FROM {$this->table_link}" . " WHERE  {$this->keyName} = " . $object->getVar($this->keyName);
586
        /*
587
                if (false ===  ($result = $this->db->{$queryFunc}($sql))) {
588
                   // xoops_error($this->db->error());
589
                }
590
        */
591
        /*
592
         * Remove stats-tag links
593
         */
594
        /** @var \XoopsModules\Tag\StatsHandler $statsHandler */
595
        $statsHandler = $helper->getHandler('Stats');
596
        $criteria = new \Criteria($this->keyName, $object->getVar($this->keyName));
597
        $statsHandler->deleteAll($criteria, $force);
598
        //$sql = 'DELETE' . " FROM {$this->table_stats}" . " WHERE  {$this->keyName} = " . $object->getVar($this->keyName);
599
600
        /*
601
                if (false === ($result = $this->db->{$queryFunc}($sql))) {
602
                   // xoops_error($this->db->error());
603
                }
604
        */
605
606
        return parent::delete($object, $force);
607
    }
608
609
    /**
610
     * clean orphan links from database
611
     *
612
     * @access public
613
     * @param string $table_link
614
     * @param string $field_link
615
     * @param string $field_object
616
     * @return bool true on success
617
     */
618
    public function cleanOrphan($table_link = '', $field_link = '', $field_object = '')
619
    {
620
        require_once $GLOBALS['xoops']->path('/modules/tag/functions.recon.php');
621
622
        //mod_loadFunctions("recon");
623
        return tag_cleanOrphan();
624
    }
625
}
626