Passed
Pull Request — master (#29)
by Michael
05:40 queued 02:48
created

TagHandler   F

Complexity

Total Complexity 97

Size/Duplication

Total Lines 607
Duplicated Lines 0 %

Importance

Changes 11
Bugs 0 Features 0
Metric Value
eloc 286
dl 0
loc 607
rs 2
c 11
b 0
f 0
wmc 97

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
B getByItem() 0 26 9
F updateByItem() 0 91 24
C update_stats() 0 104 13
B getItemCount() 0 29 6
A delete() 0 40 1
F getByLimit() 0 57 19
A cleanOrphan() 0 6 1
B getTagData() 0 70 7
C getItems() 0 51 12
A getCount() 0 30 4

How to fix   Complexity   

Complex Class

Complex classes like TagHandler 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 TagHandler, and based on these observations, apply Extract Interface, too.

1
<?php declare(strict_types=1);
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
 * @copyright       {@link https://sourceforge.net/projects/xoops/ The XOOPS Project}
19
 * @license         {@link https://www.fsf.org/copyleft/gpl.html GNU public license}
20
 * @author          Taiwen Jiang <[email protected]>
21
 * @since           1.00
22
 */
23
\defined('XOOPS_ROOT_PATH') || exit('Restricted access');
24
25
/**
26
 * Class TagHandler
27
 */
28
class TagHandler extends \XoopsPersistableObjectHandler
29
{
30
    public $table_link;
31
    public $table_stats;
32
33
    /**
34
     * Constructor
35
     *
36
     * @param \XoopsMySQLDatabase|null $db reference to the object {@link XoopsMySQLDatabase}
37
     */
38
    public function __construct(?\XoopsMySQLDatabase $db = null)
39
    {
40
        parent::__construct($db, 'tag_tag', Tag::class, 'tag_id', 'tag_term');
41
        $this->table_link  = $this->db->prefix('tag_link');
42
        $this->table_stats = $this->db->prefix('tag_stats');
43
    }
44
45
    /**
46
     * Get tags linked to an item
47
     *
48
     * @param int $itemid item ID
49
     * @param int $modid  module ID, optional
50
     * @param int $catid  id of corresponding category, optional
51
     * @return array associative array of tags (id, term)
52
     */
53
    public function getByItem(int $itemid, int $modid = 0, int $catid = 0): array
54
    {
55
        $ret = [];
56
57
        $itemid = $itemid;
58
        $modid  = (empty($modid) && \is_object($GLOBALS['xoopsModule'])
59
                   && 'tag' !== $GLOBALS['xoopsModule']->getVar('dirname')) ? $GLOBALS['xoopsModule']->getVar('mid') : $modid;
60
        if (empty($itemid) || empty($modid)) {
61
            return $ret;
62
        }
63
64
        $sql = 'SELECT o.tag_id, o.tag_term'
65
               . " FROM {$this->table_link} AS l "
66
               . " LEFT JOIN {$this->table} AS o ON o.{$this->keyName} = l.{$this->keyName} "
67
               . " WHERE  l.tag_itemid = {$itemid} AND l.tag_modid = {$modid}"
68
               . (empty($catid) ? '' : (' AND l.tag_catid=' . $catid))
69
               . ' ORDER BY o.tag_count DESC';
70
71
        $result = $this->db->query($sql);
72
        if ($result instanceof \mysqli_result) {
73
            while (false !== ($myrow = $this->db->fetchArray($result))) {
74
                $ret[$myrow[$this->keyName]] = $myrow['tag_term'];
75
            }
76
        }
77
78
        return $ret;
79
    }
80
81
    /**
82
     * Update tags linked to an item
83
     *
84
     * @param array|string $tags   array of $tags or a single tag
85
     * @param int          $itemid item ID
86
     * @param int|string   $modid  module ID or module dirname, optional
87
     * @param int          $catid  id of corresponding category, optional
88
     */
89
    public function updateByItem($tags, int $itemid, $modid = '', int $catid = 0): bool
90
    {
91
        $catid  = $catid;
92
        $itemid = $itemid;
93
94
        if (!empty($modid) && !\is_numeric($modid)) {
95
            if (($GLOBALS['xoopsModule'] instanceof \XoopsModule)
96
                && ($modid == $GLOBALS['xoopsModule']->getVar('dirname'))) {
97
                $modid = $GLOBALS['xoopsModule']->getVar('mid');
98
            } else {
99
                /** @var \XoopsModuleHandler $moduleHandler */
100
                $moduleHandler = \xoops_getHandler('module');
101
                $modid         = ($moduleObj = $moduleHandler->getByDirname($modid)) ? $moduleObj->getVar('mid') : 0;
102
            }
103
        } elseif ($GLOBALS['xoopsModule'] instanceof \XoopsModule) {
104
            $modid = $GLOBALS['xoopsModule']->getVar('mid');
105
        }
106
107
        if (empty($itemid) || empty($modid)) {
108
            return false;
109
        }
110
111
        if (empty($tags)) {
112
            $tags = [];
113
        } elseif (!\is_array($tags)) {
114
            //require_once $GLOBALS['xoops']->path('/modules/tag/include/functions.php');
115
            $tags = Utility::tag_parse_tag(\addslashes(\stripslashes($tags)));
116
        }
117
118
        $tags_existing = $this->getByItem($itemid, $modid, $catid);
119
        $tags_delete   = \array_diff(\array_values($tags_existing), $tags);
120
        $tags_add      = \array_diff($tags, \array_values($tags_existing));
121
        $tags_update   = [];
122
123
        if (0 < \count($tags_delete)) {
124
            $tags_delete = \array_map([$this->db, 'quoteString'], $tags_delete);
125
            $tags_id     = &$this->getIds(new \Criteria('tag_term', '(' . \implode(', ', $tags_delete) . ')', 'IN'));
126
            if (!empty($tags_id)) {
127
                $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}";
128
                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...
129
                    //@todo: decide if we should do something here on failure
130
                }
131
                $sql = 'DELETE FROM ' . $this->table . ' WHERE ' . '    tag_count < 2 AND ' . "     {$this->keyName} IN (" . \implode(', ', $tags_id) . ')';
132
                if (false === ($result = $this->db->queryF($sql))) {
133
                    \trigger_error($this->db->error());
134
                }
135
136
                $sql = 'UPDATE ' . $this->table . ' SET tag_count = tag_count - 1' . ' WHERE ' . "     {$this->keyName} IN (" . \implode(', ', $tags_id) . ')';
137
                if (false === ($result = $this->db->queryF($sql))) {
138
                    \trigger_error($this->db->error());
139
                }
140
                $tags_update = $tags_id;
141
            }
142
        }
143
144
        if (!empty($tags_add)) {
145
            $tag_link  = [];
146
            $tag_count = [];
147
            foreach ($tags_add as $tag) {
148
                $tags_id = &$this->getIds(new \Criteria('tag_term', $tag));
149
                if (!empty($tags_id)) {
150
                    $tag_id      = $tags_id[0];
151
                    $tag_count[] = $tag_id;
152
                } else {
153
                    $tagObj = $this->create();
154
                    $tagObj->setVars(['tag_term' => $tag, 'tag_count' => 1]);
155
                    $this->insert($tagObj);
156
                    $tag_id = $tagObj->getVar('tag_id');
157
                    unset($tagObj);
158
                }
159
                $tag_link[]    = "({$tag_id}, {$itemid}, {$catid}, {$modid}, " . \time() . ')';
160
                $tags_update[] = $tag_id;
161
            }
162
            $sql = "INSERT INTO {$this->table_link}" . ' (tag_id, tag_itemid, tag_catid, tag_modid, tag_time) ' . ' VALUES ' . \implode(', ', $tag_link);
163
            if (false === ($result = $this->db->queryF($sql))) {
164
                \trigger_error($this->db->error());
165
            }
166
            if (!empty($tag_count)) {
167
                $sql = 'UPDATE ' . $this->table . ' SET tag_count = tag_count+1' . ' WHERE ' . "     {$this->keyName} IN (" . \implode(', ', $tag_count) . ')';
168
                if (false === ($result = $this->db->queryF($sql))) {
169
                    \trigger_error($this->db->error());
170
                }
171
            }
172
        }
173
        if (\is_array($tags_update)) {
174
            foreach ($tags_update as $tag_id) {
175
                $this->update_stats($tag_id, $modid, $catid);
176
            }
177
        }
178
179
        return true;
180
    }
181
182
    /**
183
     * Update count stats or tag
184
     *
185
     */
186
    public function update_stats(int $tag_id, int $modid = 0, int $catid = 0): bool
187
    {
188
        $tag_id = $tag_id;
189
        if (0 === $tag_id) {
190
            return true;
191
        }
192
193
        $tag_count = [];
194
        $modid     = $modid;
195
        $catid     = (0 === $modid) ? -1 : $catid;
196
197
        /** @var \XoopsModules\Tag\LinkHandler $linkHandler */
198
        $linkHandler = \XoopsModules\Tag\Helper::getInstance()->getHandler('Link');
199
        $criteria    = new \CriteriaCompo(new \Criteria('tag_id', (string)$tag_id));
200
        if (0 !== $modid) {
201
            $criteria->add(new \Criteria('tag_modid', (string)$modid), 'AND');
202
        }
203
        if (0 < $catid) {
204
            $criteria->add(new \Criteria('tag_catid', (string)$catid), 'AND');
205
        }
206
        $count = $linkHandler->getCount($criteria);
207
        /*
208
        $sql   = 'SELECT COUNT(*) ' . " FROM {$this->table_link}" . " WHERE tag_id = {$tag_id}" . (empty($modid) ? '' : " AND tag_modid = {$modid}") . (($catid < 0) ? '' : " AND tag_catid = {$catid}");
209
210
        $result = $this->db->query($sql);
211
        if ($result) {
212
            list($count) = $this->db->fetchRow($result);
213
        }
214
        */
215
        if (0 === $modid) {
216
            $tagObj = $this->get($tag_id);
217
            if ($tagObj instanceof \XoopsModules\Tag\Tag) {
218
                if (0 === $count) {
219
                    $this->delete($tagObj);
220
                } else {
221
                    $tagObj->setVar('tag_count', $count);
222
                    $this->insert($tagObj, true);
223
                }
224
            }
225
        } else {
226
            $statsHandler = Helper::getInstance()->getHandler('Stats');
227
            if (empty($count)) {
228
                $criteria = new \CriteriaCompo(new \Criteria($this->keyName, (string)$tag_id));
229
                $criteria->add(new \Criteria('tag_modid, $modid'), 'AND');
230
                $criteria->add(new \Criteria('tag_catid', $catid), 'AND');
231
                $status = $statsHandler->deleteAll($criteria);
232
                if (!$status) {
233
                    //@todo determine what should happen here on failure.
234
                }
235
                /*
236
                $sql = "DELETE FROM {$this->table_stats}" . ' WHERE ' . " {$this->keyName} = {$tag_id}" . " AND tag_modid = {$modid}" . " AND tag_catid = {$catid}";
237
238
                if (false === $result = $this->db->queryF($sql)) {
239
                    \trigger_error($this->db->error());
240
                }
241
                */
242
            } else {
243
                $ts_id    = null;
244
                $criteria = new \CriteriaCompo(new \Criteria($this->keyName, (string)$tag_id));
245
                $criteria->add(new \Criteria('tag_modid', (string)$modid), 'AND');
246
                $criteria->add(new \Criteria('tag_catid', (string)$catid), 'AND');
247
                $criteria->setLimit(1);
248
                $tsCountObjs = $statsHandler->getAll($criteria);
249
                if (\count($tsCountObjs) > 0) {
250
                    $tsCountObj = \array_pop($tsCountObjs); // get 1st (only) item
251
                    $ts_id      = $tsCountObj->getVar('ts_id');
252
                    $tag_count  = $tsCountObj->getVar('tag_count');
253
                }
254
                /*
255
                $sql   = 'SELECT ts_id, tag_count ' . " FROM {$this->table_stats}" . " WHERE {$this->keyName} = {$tag_id}" . " AND tag_modid = {$modid}" . " AND tag_catid = {$catid}";
256
                $result = $this->db->query($sql);
257
                if ($result) {
258
                    list($ts_id, $tag_count) = $this->db->fetchRow($result);
259
                }
260
                */
261
                $sql = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $sql is dead and can be removed.
Loading history...
262
                if ($ts_id) {
263
                    if ($tag_count != $count) {
264
                        $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...
265
                        $statsHandler->insert($tsCountObj);
266
                        //$sql = "UPDATE {$this->table_stats}" . " SET tag_count = {$count}" . ' WHERE ' . "     ts_id = {$ts_id}";
267
                    }
268
                } else {
269
                    $newTsObj = $statsHandler->create();
270
                    $newTsObj->setVars(
271
                        [
272
                            'tag_id'    => $tag_id,
273
                            'tag_modid' => $modid,
274
                            'tag_catid' => $catid,
275
                            'tag_count' => $count,
276
                        ]
277
                    );
278
                    $statsHandler->insert($newTsObj);
279
                    //$sql = "INSERT INTO {$this->table_stats}" . ' (tag_id, tag_modid, tag_catid, tag_count)' . " VALUES ({$tag_id}, {$modid}, {$catid}, {$count})";
280
                }
281
                /*
282
                if (!empty($sql) && false === ($result = $this->db->queryF($sql))) {
283
                    \trigger_error($this->db->error());
284
                }
285
                */
286
            }
287
        }
288
289
        return true;
290
    }
291
292
    /**
293
     * Get tags with item count
294
     *
295
     * @param int                                  $limit
296
     * @param int                                  $start
297
     * @param null|\CriteriaElement|\CriteriaCompo $criteria  {@link Criteria}
298
     * @param null|array                           $fields
299
     * @param bool                                 $fromStats fetch from tag-stats table
300
     * @return array associative array of tags (id, term, status, count)
301
     */
302
    public function &getByLimit($limit = Constants::UNLIMITED, $start = Constants::BEGINNING, \CriteriaElement $criteria = null, $fields = null, $fromStats = true): ?array
303
    {//&getByLimit($criteria = null, $fromStats = true)
304
        $ret = [];
305
        if ($fromStats) {
306
            $sql = "SELECT DISTINCT(o.{$this->keyName}), o.tag_term, o.tag_status, SUM(l.tag_count) AS count , l.tag_modid" . " FROM {$this->table} AS o LEFT JOIN {$this->table_stats} AS l ON l.{$this->keyName} = o.{$this->keyName}";
307
        } else {
308
            $sql = "SELECT DISTINCT(o.{$this->keyName}), o.tag_term, o.tag_status, COUNT(l.tl_id) AS count , l.tag_modid" . " FROM {$this->table} AS o LEFT JOIN {$this->table_link} AS l ON l.{$this->keyName} = o.{$this->keyName}";
309
        }
310
311
        $limit = \is_int($limit) && ($limit >= 0) ? $limit : Constants::UNLIMITED;
312
        $start = \is_int($start) && ($start >= 0) ? $start : Constants::BEGINNING;
313
        $sort  = '';
314
        $order = '';
315
        if (($criteria instanceof \CriteriaCompo) || ($criteria instanceof \Criteria)) {
316
            $sql   .= ' ' . $criteria->renderWhere();
317
            $sort  = $criteria->getSort();
318
            $order = $criteria->getOrder();
319
            $limit = $limit >= 0 ? $limit : $criteria->getLimit(); // non-zero arg passed to method overrides $criteria setting
320
            $start = $start >= 0 ? $start : $criteria->getStart(); // non-zero arg passed to method overrides $criteria setting
321
        }
322
        $sql .= " GROUP BY o.{$this->keyName}, o.tag_term, o.tag_status, l.tag_modid";
323
324
        $order = ('ASC' !== \mb_strtoupper($order)) ? 'DESC' : 'ASC';
325
        $sort  = \mb_strtolower($sort);
326
        switch ($sort) {
327
            case 'a':
328
            case 'alphabet':
329
                $sql .= " ORDER BY o.tag_term {$order}";
330
                break;
331
            case 'id':
332
            case 'time':
333
                $sql .= " ORDER BY o.{$this->keyName} {$order}";
334
                break;
335
            case 'c':
336
            case 'count':
337
            default:
338
                $sql .= " ORDER BY count {$order}";
339
                break;
340
        }
341
342
        $result = $this->db->query($sql, $limit, $start);
343
        if ($result instanceof \mysqli_result) {
344
            while (false !== ($myrow = $this->db->fetchArray($result))) {
345
                $ret[$myrow[$this->keyName]] = [
346
                    'id'     => $myrow[$this->keyName],
347
                    'term'   => \htmlspecialchars($myrow['tag_term'], \ENT_QUOTES | \ENT_HTML5),
348
                    'status' => $myrow['tag_status'],
349
                    'modid'  => $myrow['tag_modid'],
350
                    'count'  => (int)$myrow['count'],
351
                ];
352
            }
353
        } else {
354
            \trigger_error($this->db->error());
355
            $ret = null;
356
        }
357
358
        return $ret;
359
    }
360
361
    /**
362
     * Get count of tags
363
     *
364
     * @param null|\CriteriaElement|\CriteriaCompo $criteria {@link Criteria)
365
     */
366
    public function getCount(\CriteriaElement $criteria = null): ?int
367
    {
368
        /*
369
        $catid    = (int)($catid);
370
        $modid    = (int)($modid);
371
        */
372
        $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}";
373
        if (($criteria instanceof \CriteriaCompo) || ($criteria instanceof \Criteria)) {
374
            $sql .= ' ' . $criteria->renderWhere();
375
        }
376
        /*
377
        $sql_where    = "    WHERE 1 = 1";
378
        if (!empty($modid)) {
379
            $sql_where    .= " AND l.tag_modid = {$modid}";
380
        }
381
        if (empty($catid) || $catid > 0) {
382
            $sql_where    .= " AND l.tag_catid = {$catid}";
383
        }
384
385
        $sql =     $sql_select . " " . $sql_from . " " . $sql_where;
386
        */
387
        $result = $this->db->query($sql);
388
        if ($result instanceof \mysqli_result) {
389
            [$ret] = (int)$this->db->fetchRow($result);
390
        } else {
391
            \trigger_error($this->db->error());
392
            $ret = 0;
393
        }
394
395
        return $ret;
396
    }
397
398
    /**
399
     * Get items linked with a tag
400
     *
401
     * @param \CriteriaElement|null $criteria {@link Criteria}
402
     * @return array associative array of items[] => (id, modid, catid, time)
403
     */
404
    public function getItems(\CriteriaElement $criteria = null): array
405
    {
406
        $ret = [];
407
        $sql = '    SELECT o.tl_id, o.tag_itemid, o.tag_modid, o.tag_catid, o.tag_time';
408
        $sql .= "    FROM {$this->table_link} AS o LEFT JOIN {$this->table} AS l ON l.{$this->keyName} = o.{$this->keyName}";
409
410
        $limit = Constants::UNLIMITED;
411
        $start = Constants::BEGINNING;
412
        $sort  = '';
413
        $order = '';
414
        if (($criteria instanceof \CriteriaCompo) || ($criteria instanceof \Criteria)) {
415
            $sql   .= ' ' . $criteria->renderWhere();
416
            $sort  = $criteria->getSort();
417
            $order = $criteria->getOrder();
418
            $limit = $criteria->getLimit();
419
            $start = $criteria->getStart();
420
        }
421
422
        $order = ('ASC' !== \mb_strtoupper($order)) ? 'DESC' : 'ASC';
423
        $sort  = \mb_strtolower($sort);
424
        switch ($sort) {
425
            case 'i':
426
            case 'item':
427
                $sql .= "    ORDER BY o.tag_itemid {$order}, o.tl_id DESC";
428
                break;
429
            case 'm':
430
            case 'module':
431
                $sql .= "    ORDER BY o.tag_modid {$order}, o.tl_id DESC";
432
                break;
433
            case 't':
434
            case 'time':
435
            default:
436
                $sql .= "    ORDER BY o.tl_id {$order}";
437
                break;
438
        }
439
440
        $result = $this->db->query($sql, $limit, $start);
441
        if ($result instanceof \mysqli_result) {
442
            while (false !== ($myrow = $this->db->fetchArray($result))) {
443
                $ret[$myrow['tl_id']] = [
444
                    'itemid' => $myrow['tag_itemid'],
445
                    'modid'  => $myrow['tag_modid'],
446
                    'catid'  => $myrow['tag_catid'],
447
                    'time'   => $myrow['tag_time'],
448
                ];
449
            }
450
        } else {
451
            \trigger_error($this->db->error());
452
        }
453
454
        return $ret;
455
    }
456
457
    /**
458
     * Get count of items linked with a tag
459
     *
460
     * @param int $modid id of corresponding module, optional: 0 for all; >1 for a specific module
461
     * @param int $catid id of corresponding category, optional
462
     * @return int count
463
     */
464
    public function getItemCount(int $tag_id, int $modid = 0, int $catid = 0): int
465
    {
466
        if ($tag_id = $tag_id) {
467
            $catid = $catid;
468
            $modid = $modid;
469
470
            $sql_select = '    SELECT COUNT(DISTINCT o.tl_id)';
471
            $sql_from   = "    FROM {$this->table_link} AS o LEFT JOIN {$this->table} AS l ON l.{$this->keyName} = o.{$this->keyName}";
472
            $sql_where  = "    WHERE o.tag_id = {$tag_id}";
473
            if (!empty($modid)) {
474
                $sql_where .= " AND o.tag_modid = {$modid}";
475
            }
476
            if (empty($catid) || $catid > 0) {
477
                $sql_where .= " AND o.tag_catid = {$catid}";
478
            }
479
480
            $sql    = $sql_select . ' ' . $sql_from . ' ' . $sql_where;
481
            $result = $this->db->query($sql);
482
            if ($result instanceof \mysqli_result) {
483
                [$ret] = $this->db->fetchRow($result);
484
            } else {
485
                \trigger_error($this->db->error());
486
                $ret = 0;
487
            }
488
        } else {
489
            $ret = 0;
490
        }
491
492
        return $ret;
493
    }
494
495
    /**
496
     * Get detailed data (and font) for a tag
497
     *
498
     * @param array $tags_array associative array of tags (id, term, status, count)
499
     * @return array tag data values for display
500
     */
501
    public function getTagData(array $tags_array, int $font_max = 0, int $font_min = 0): array
502
    {
503
        //        $tags_data_array = [];
504
        //        if (\is_array($tags_array) && !empty($tags_array)) {
505
        //            // set min and max tag count
506
        //            $count_array = \array_column($tags_array, 'count', 'id');
507
        //            $count_min   = \count($count_array) > 0 ? \min($count_array) : 0;
508
        //            $count_min   = max($count_min, 0);
509
        //            $count_max   = \count($count_array) > 0 ? \max($count_array) : 0;
510
        //            $count_max   = max($count_max, 0);
511
        //            if ($count_max > 0) {
512
        //                $term_array      = \array_column($tags_array, 'term', 'id');
513
        //                $tags_term_array = \array_map('\mb_strtolower', $term_array);
514
        //                \array_multisort($tags_term_array, \SORT_ASC, $tags_array);
515
        //                $count_interval = $count_max - $count_min;
516
        //                $level_limit    = 5;
517
        //
518
        //                $font_ratio = $count_interval ? ($font_max - $font_min) / $count_interval : 1;
519
        //
520
        //                foreach ($tags_array as $tag) {
521
        //                    /*
522
        //                     * Font-size = ((tag.count - count.min) * (font.max - font.min) / (count.max - count.min) ) * 100%
523
        //                     */
524
        //                    $font_sz           = \floor(($tag['count'] - $count_min) * $font_ratio) + $font_min;
525
        //                    $level_sz          = \floor(($tag['count'] - $count_min) * $level_limit / $count_max);
526
        //                    $tags_data_array[] = [
527
        //                        'id'    => $tag['id'],
528
        //                        'font'  => empty($count_interval) ? 100 : (int)$font_sz,
529
        //                        'level' => empty($count_max) ? 0 : (int)$level_sz,
530
        //                        'term'  => \urlencode($tag['term']),
531
        //                        'title' => \htmlspecialchars($tag['term'], \ENT_QUOTES | \ENT_HTML5),
532
        //                        'count' => $tag['count'],
533
        //                    ];
534
        //                }
535
        //            }
536
        //        }
537
538
        $count_max = 0;
539
        $count_min = 0;
540
        $tags_term = [];
541
        foreach ($tags_array as $tag) {
542
            $count_max   = \max($count_max, $tag['count']); // set counter to the max tag count
543
            $count_min   = \min(0, $count_min, $tag['count']); //set counter to the minimum for tag count
544
            $tags_term[] = \mb_strtolower($tag['term']);
545
        }
546
547
        if (!empty($tags_term)) {
548
            \array_multisort($tags_term, \SORT_ASC, $tags_array);
0 ignored issues
show
Bug introduced by
SORT_ASC cannot be passed to array_multisort() as the parameter $rest expects a reference. ( Ignorable by Annotation )

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

548
            \array_multisort($tags_term, /** @scrutinizer ignore-type */ \SORT_ASC, $tags_array);
Loading history...
549
        }
550
        $count_interval = $count_max - $count_min;
551
        $level_limit    = 5;
552
553
        //            $font_max   = $options[2];
554
        //            $font_min   = $options[3];
555
        $font_ratio = $count_interval ? ($font_max - $font_min) / $count_interval : 1;
556
557
        $tags_data_array = [];
558
        foreach ($tags_array as $tag) {
559
            $tags_data_array[] = [
560
                'id'    => $tag['id'],
561
                'font'  => $count_interval ? \floor(($tag['count'] - $count_min) * $font_ratio + $font_min) : 100,
562
                'level' => empty($count_max) ? 0 : \floor(($tag['count'] - $count_min) * $level_limit / $count_max),
563
                'term'  => \urlencode($tag['term']),
564
                'title' => \htmlspecialchars($tag['term'], \ENT_QUOTES | \ENT_HTML5),
565
                'count' => $tag['count'],
566
            ];
567
        }
568
        //            unset($tags_array, $tag, $tags_term, $tag_count_array);
569
570
        return $tags_data_array;
571
    }
572
573
    /**
574
     * Delete an object as well as links relying on it
575
     *
576
     * @param \XoopsObject $object $object {@link Tag}
577
     * @param bool         $force  flag to force the query execution despite security settings
578
     */
579
    public function delete(\XoopsObject $object, $force = true): bool
580
    {
581
        /* {@internal - this isn't needed if we type hint Tag object }}
582
        if (!is_object($object) || !$object->getVar($this->keyName)) {
583
            return false;
584
        }
585
        */
586
        //$queryFunc = empty($force) ? 'query' : 'queryF';
587
588
        /*
589
         * Remove item-tag links
590
         */
591
        $helper = \XoopsModules\Tag\Helper::getInstance();
592
593
        /** @var \XoopsModules\Tag\LinkHandler $linkHandler */
594
        $linkHandler = $helper->getHandler('Link');
595
        $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

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