TagHandler::update_stats()   C
last analyzed

Complexity

Conditions 13
Paths 89

Size

Total Lines 102
Code Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 13
eloc 52
c 3
b 0
f 0
nc 89
nop 3
dl 0
loc 102
rs 6.6166

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

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

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