XoopsModule::isactive()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 1
1
<?php
2
/**
3
 * XOOPS Kernel Class
4
 *
5
 * You may not change or alter any portion of this comment or credits
6
 * of supporting developers from this source code or any supporting source code
7
 * which is considered copyrighted (c) material of the original comment or credit authors.
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * @copyright       (c) 2000-2025 XOOPS Project (https://xoops.org)
13
 * @license             GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
14
 * @package             kernel
15
 * @since               2.0.0
16
 */
17
if (!defined('XOOPS_ROOT_PATH')) {
18
    throw new \RuntimeException('Restricted access');
19
}
20
21
/**
22
 * A Module
23
 *
24
 * @package kernel
25
 * @author  Kazumi Ono <[email protected]>
26
 */
27
class XoopsModule extends XoopsObject
28
{
29
    /**
30
     *
31
     * @var string
32
     */
33
    public $modinfo;
34
    /**
35
     *
36
     * @var array
37
     */
38
    public $adminmenu;
39
    /**
40
     *
41
     * @var array
42
     */
43
    public $_msg;
44
45
    //PHP 8.2 Dynamic properties deprecated
46
    public $mid;
47
    public $name;
48
    public $version;
49
    public $last_update;
50
    public $weight;
51
    public $isactive;
52
    public $dirname;
53
    public $hasmain;
54
    public $hasadmin;
55
    public $hassearch;
56
    public $hasconfig;
57
    public $hascomments;
58
    // RMV-NOTIFY
59
    public $hasnotification;
60
61
    /**
62
     * Constructor
63
     */
64
    public function __construct()
65
    {
66
        parent::__construct();
67
        $this->initVar('mid', XOBJ_DTYPE_INT, null, false);
68
        $this->initVar('name', XOBJ_DTYPE_TXTBOX, null, true, 150);
69
        $this->initVar('version', XOBJ_DTYPE_TXTBOX, null, false);
70
        $this->initVar('last_update', XOBJ_DTYPE_INT, null, false);
71
        $this->initVar('weight', XOBJ_DTYPE_INT, 0, false);
72
        $this->initVar('isactive', XOBJ_DTYPE_INT, 1, false);
73
        $this->initVar('dirname', XOBJ_DTYPE_OTHER, null, true);
74
        $this->initVar('hasmain', XOBJ_DTYPE_INT, 0, false);
75
        $this->initVar('hasadmin', XOBJ_DTYPE_INT, 0, false);
76
        $this->initVar('hassearch', XOBJ_DTYPE_INT, 0, false);
77
        $this->initVar('hasconfig', XOBJ_DTYPE_INT, 0, false);
78
        $this->initVar('hascomments', XOBJ_DTYPE_INT, 0, false);
79
        // RMV-NOTIFY
80
        $this->initVar('hasnotification', XOBJ_DTYPE_INT, 0, false);
81
    }
82
83
    /**
84
     * Load module info
85
     *
86
     * @param string  $dirname Directory Name
87
     * @param boolean $verbose
88
     */
89
    public function loadInfoAsVar($dirname, $verbose = true)
90
    {
91
        $dirname = basename($dirname);
92
        if (!isset($this->modinfo)) {
93
            $this->loadInfo($dirname, $verbose);
94
        }
95
        $this->setVar('name', $this->modinfo['name'], true);
96
        $this->setVar('version', $this->modinfo['version'], true);
97
        $this->setVar('dirname', $this->modinfo['dirname'], true);
98
        $hasmain     = (isset($this->modinfo['hasMain']) && $this->modinfo['hasMain'] == 1) ? 1 : 0;
99
        $hasadmin    = (isset($this->modinfo['hasAdmin']) && $this->modinfo['hasAdmin'] == 1) ? 1 : 0;
100
        $hassearch   = (isset($this->modinfo['hasSearch']) && $this->modinfo['hasSearch'] == 1) ? 1 : 0;
101
        $hasconfig   = ((isset($this->modinfo['config']) && \is_array($this->modinfo['config'])) || !empty($this->modinfo['hasComments'])) ? 1 : 0;
102
        $hascomments = (isset($this->modinfo['hasComments']) && $this->modinfo['hasComments'] == 1) ? 1 : 0;
103
        // RMV-NOTIFY
104
        $hasnotification = (isset($this->modinfo['hasNotification']) && $this->modinfo['hasNotification'] == 1) ? 1 : 0;
105
        $this->setVar('hasmain', $hasmain);
106
        $this->setVar('hasadmin', $hasadmin);
107
        $this->setVar('hassearch', $hassearch);
108
        $this->setVar('hasconfig', $hasconfig);
109
        $this->setVar('hascomments', $hascomments);
110
        // RMV-NOTIFY
111
        $this->setVar('hasnotification', $hasnotification);
112
    }
113
114
    /**
115
     * add a message
116
     *
117
     * @param string $str message to add
118
     * @access public
119
     */
120
    public function setMessage($str)
121
    {
122
        $this->_msg[] = trim($str);
123
    }
124
125
    /**
126
     * return the messages for this object as an array
127
     *
128
     * @return array an array of messages
129
     * @access public
130
     */
131
    public function getMessages()
132
    {
133
        return $this->_msg;
134
    }
135
136
    /**
137
     * Set module info
138
     *
139
     * @param  string $name
140
     * @param  mixed  $value
141
     * @return bool
142
     **/
143
    public function setInfo($name, $value)
144
    {
145
        if (empty($name)) {
146
            $this->modinfo = $value;
147
        } else {
148
            $this->modinfo[$name] = $value;
149
        }
150
151
        return true;
152
    }
153
154
    /**
155
     * Get module info
156
     *
157
     * @param  string $name
158
     * @return array|string    Array of module information.
159
     *                     If {@link $name} is set, returns a single module information item as string.
160
     */
161
    public function &getInfo($name = null)
162
    {
163
        if (!isset($this->modinfo)) {
164
            $this->loadInfo($this->getVar('dirname'));
0 ignored issues
show
Bug introduced by
It seems like $this->getVar('dirname') can also be of type array and array; however, parameter $dirname of XoopsModule::loadInfo() 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

164
            $this->loadInfo(/** @scrutinizer ignore-type */ $this->getVar('dirname'));
Loading history...
165
        }
166
        if (isset($name)) {
167
            if (isset($this->modinfo[$name])) {
168
                return $this->modinfo[$name];
169
            }
170
            $return = false;
171
172
            return $return;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $return returns the type false which is incompatible with the documented return type array|string.
Loading history...
173
        }
174
175
        return $this->modinfo;
176
    }
177
178
    /**
179
     * Get status
180
     *
181
     * @return string
182
     */
183
    public function getStatus()
184
    {
185
        return substr(strrchr($this->getVar('version'), '-'), 1);
186
    }
187
188
    /**
189
     * Compares two "XOOPS-standardized" version number strings.
190
     *
191
     * @param  string $version1
192
     * @param  string $version2
193
     * @param  string $operator
194
     * @return boolean The function will return true if the relationship is the one specified by the operator, false otherwise.
195
     */
196
    public function versionCompare($version1 = '', $version2 = '', $operator = '<')
197
    {
198
        $version1 = strtolower($version1);
199
        $version2 = strtolower($version2);
200
        if (false !== strpos($version2, '-stable')) {
201
            $version2 = substr($version2, 0, strpos($version2, '-stable'));
202
        }
203
        if (false !== strpos($version1, '-stable')) {
204
            $version1 = substr($version1, 0, strpos($version1, '-stable'));
205
        }
206
        return version_compare($version1, $version2, $operator);
0 ignored issues
show
Bug Best Practice introduced by
The expression return version_compare($..., $version2, $operator) also could return the type integer which is incompatible with the documented return type boolean.
Loading history...
207
    }
208
209
    /**
210
     * Get a link to the modules main page
211
     *
212
     * @return string FALSE on fail
213
     */
214
    public function mainLink()
215
    {
216
        if ($this->getVar('hasmain') == 1) {
217
            $ret = '<a href="' . XOOPS_URL . '/modules/' . $this->getVar('dirname') . '/">' . $this->getVar('name') . '</a>';
218
219
            return $ret;
220
        }
221
222
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type string.
Loading history...
223
    }
224
225
    /**
226
     * Get links to the subpages
227
     *
228
     * @return array
229
     */
230
    public function subLink()
231
    {
232
        $ret = [];
233
        if ($this->getInfo('sub') && \is_array($this->getInfo('sub'))) {
234
            foreach ($this->getInfo('sub') as $submenu) {
235
                $ret[] = [
236
                    'id' => $submenu['id']?? '',
237
                    'name' => $submenu['name'],
238
                    'url'  => $submenu['url'],
239
                    'icon' => $submenu['icon']?? '',
240
                ];
241
            }
242
        }
243
244
        return $ret;
245
    }
246
247
    /**
248
     * Load the admin menu for the module
249
     */
250
    public function loadAdminMenu()
251
    {
252
        $adminmenu = [];
253
        if ($this->getInfo('adminmenu') && $this->getInfo('adminmenu') != '' && file_exists(XOOPS_ROOT_PATH . '/modules/' . $this->getVar('dirname') . '/' . $this->getInfo('adminmenu'))) {
0 ignored issues
show
Bug introduced by
Are you sure $this->getInfo('adminmenu') of type array|string can be used in concatenation? ( Ignorable by Annotation )

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

253
        if ($this->getInfo('adminmenu') && $this->getInfo('adminmenu') != '' && file_exists(XOOPS_ROOT_PATH . '/modules/' . $this->getVar('dirname') . '/' . /** @scrutinizer ignore-type */ $this->getInfo('adminmenu'))) {
Loading history...
254
            include XOOPS_ROOT_PATH . '/modules/' . $this->getVar('dirname') . '/' . $this->getInfo('adminmenu');
255
        }
256
        $this->adminmenu = & $adminmenu;
257
    }
258
259
    /**
260
     * Get the admin menu for the module
261
     *
262
     * @return array
263
     */
264
    public function &getAdminMenu()
265
    {
266
        if (!isset($this->adminmenu)) {
267
            $this->loadAdminMenu();
268
        }
269
270
        return $this->adminmenu;
271
    }
272
273
    /**
274
     * Load the module info for this module
275
     *
276
     * @param string $dirname Module directory
277
     * @param bool   $verbose Give an error on fail?
278
     *
279
     * @return bool true if loaded
280
     */
281
    public function loadInfo($dirname, $verbose = true)
282
    {
283
        static $modVersions;
284
        $dirname = basename($dirname);
285
        if (isset($modVersions[$dirname])) {
286
            $this->modinfo = $modVersions[$dirname];
287
288
            return true;
289
        }
290
        global $xoopsConfig;
291
        if (file_exists($file = $GLOBALS['xoops']->path('modules/' . $dirname . '/language/' . $xoopsConfig['language'] . '/modinfo.php'))) {
292
            include_once $file;
293
        } elseif (file_exists($file = $GLOBALS['xoops']->path('modules/' . $dirname . '/language/english/modinfo.php'))) {
294
            include_once $file;
295
        }
296
297
        if (!file_exists($file = $GLOBALS['xoops']->path('modules/' . $dirname . '/xoops_version.php'))) {
298
            if (false !== (bool) $verbose) {
299
                echo "Module File for $dirname Not Found!";
300
            }
301
302
            return false;
303
        }
304
        include $file;
305
        $modVersions[$dirname] = $modversion;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $modversion does not exist. Did you maybe mean $modVersions?
Loading history...
306
        $this->modinfo         = $modVersions[$dirname];
307
308
        return true;
309
    }
310
311
    /**
312
     * Search contents within a module
313
     *
314
     * @param  string  $term
315
     * @param  string  $andor 'AND' or 'OR'
316
     * @param  integer $limit
317
     * @param  integer $offset
318
     * @param  integer $userid
319
     * @return mixed   Search result.
320
     */
321
    public function search($term = '', $andor = 'AND', $limit = 0, $offset = 0, $userid = 0)
322
    {
323
        if ($this->getVar('hassearch') != 1) {
324
            return false;
325
        }
326
        $search = & $this->getInfo('search');
327
        if ($this->getVar('hassearch') != 1 || !isset($search['file']) || !isset($search['func']) || $search['func'] == '' || $search['file'] == '') {
328
            return false;
329
        }
330
        if (file_exists($file = $GLOBALS['xoops']->path('modules/' . $this->getVar('dirname') . '/' . $search['file']))) {
331
            include_once $file;
332
        } else {
333
            return false;
334
        }
335
        if (function_exists($search['func'])) {
336
            $func = $search['func'];
337
338
            return $func($term, $andor, $limit, $offset, $userid);
339
        }
340
341
        return false;
342
    }
343
344
    /**
345
     * Returns Class Base Variable mid
346
     * @param  string $format
347
     * @return mixed
348
     */
349
    public function id($format = 'N')
350
    {
351
        return $this->getVar('mid', $format);
352
    }
353
354
    /**
355
     * Returns Class Base Variable mid
356
     * @param  string $format
357
     * @return mixed
358
     */
359
    public function mid($format = '')
360
    {
361
        return $this->getVar('mid', $format);
362
    }
363
364
    /**
365
     * Returns Class Base Variable name
366
     * @param  string $format
367
     * @return mixed
368
     */
369
    public function name($format = '')
370
    {
371
        return $this->getVar('name', $format);
372
    }
373
374
    /**
375
     * Returns Class Base Variable version
376
     * @param  string $format
377
     * @return mixed
378
     */
379
    public function version($format = '')
380
    {
381
        return $this->getVar('version', $format);
382
    }
383
384
    /**
385
     * Returns Class Base Variable last_update
386
     * @param  string $format
387
     * @return mixed
388
     */
389
    public function last_update($format = '')
390
    {
391
        return $this->getVar('last_update', $format);
392
    }
393
394
    /**
395
     * Returns Class Base Variable weight
396
     * @param  string $format
397
     * @return mixed
398
     */
399
    public function weight($format = '')
400
    {
401
        return $this->getVar('weight', $format);
402
    }
403
404
    /**
405
     * Returns Class Base Variable isactive
406
     * @param  string $format
407
     * @return mixed
408
     */
409
    public function isactive($format = '')
410
    {
411
        return $this->getVar('isactive', $format);
412
    }
413
414
    /**
415
     * Returns Class Base Variable dirname
416
     * @param  string $format
417
     * @return mixed
418
     */
419
    public function dirname($format = '')
420
    {
421
        return $this->getVar('dirname', $format);
422
    }
423
424
    /**
425
     * Returns Class Base Variable hasmain
426
     * @param  string $format
427
     * @return mixed
428
     */
429
    public function hasmain($format = '')
430
    {
431
        return $this->getVar('hasmain', $format);
432
    }
433
434
    /**
435
     * Returns Class Base Variable hasadmin
436
     * @param  string $format
437
     * @return mixed
438
     */
439
    public function hasadmin($format = '')
440
    {
441
        return $this->getVar('hasadmin', $format);
442
    }
443
444
    /**
445
     * Returns Class Base Variable hassearch
446
     * @param  string $format
447
     * @return mixed
448
     */
449
    public function hassearch($format = '')
450
    {
451
        return $this->getVar('hassearch', $format);
452
    }
453
454
    /**
455
     * Returns Class Base Variable hasconfig
456
     * @param  string $format
457
     * @return mixed
458
     */
459
    public function hasconfig($format = '')
460
    {
461
        return $this->getVar('hasconfig', $format);
462
    }
463
464
    /**
465
     * Returns Class Base Variable hascomments
466
     * @param  string $format
467
     * @return mixed
468
     */
469
    public function hascomments($format = '')
470
    {
471
        return $this->getVar('hascomments', $format);
472
    }
473
474
    /**
475
     * Returns Class Base Variable hasnotification
476
     * @param  string $format
477
     * @return mixed
478
     */
479
    public function hasnotification($format = '')
480
    {
481
        return $this->getVar('hasnotification', $format);
482
    }
483
484
    /**
485
     * @param $dirname
486
     *
487
     * @return mixed
488
     */
489
    public static function getByDirname($dirname)
490
    {
491
        /** @var XoopsModuleHandler $modhandler */
492
        $modhandler = xoops_getHandler('module');
493
        $inst       = $modhandler->getByDirname($dirname);
494
495
        return $inst;
496
    }
497
498
499
    /**
500
     * Returns Class Base Variable icon
501
     * @param  string $format
502
     * @return mixed
503
     */
504
    public function icon($format = '')
505
    {
506
        return $this->getVar('icon', $format);
507
    }
508
509
510
    ##################### Deprecated Methods ######################
511
512
    /**#@+
513
     * @deprecated
514
     */
515
    public function checkAccess()
516
    {
517
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
518
519
        return false;
520
    }
521
522
    /**
523
     * @param string $type
524
     *
525
     * @return bool
526
     * @deprecated
527
     */
528
    public function loadLanguage($type = 'main')
0 ignored issues
show
Unused Code introduced by
The parameter $type is not used and could be removed. ( Ignorable by Annotation )

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

528
    public function loadLanguage(/** @scrutinizer ignore-unused */ $type = 'main')

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
529
    {
530
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
531
532
        return false;
533
    }
534
535
    /**
536
     * @return bool
537
     * @deprecated
538
     */
539
    public function loadErrorMessages()
540
    {
541
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
542
543
        return false;
544
    }
545
546
    /**
547
     * @return bool
548
     * @deprecated
549
     */
550
    public function getCurrentPage()
551
    {
552
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
553
554
        return false;
555
    }
556
557
    /**
558
     * @param array $admingroups
559
     * @param array $accessgroups
560
     *
561
     * @return bool
562
     * @deprecated
563
     */
564
    public function install($admingroups = [], $accessgroups = [])
0 ignored issues
show
Unused Code introduced by
The parameter $admingroups is not used and could be removed. ( Ignorable by Annotation )

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

564
    public function install(/** @scrutinizer ignore-unused */ $admingroups = [], $accessgroups = [])

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $accessgroups is not used and could be removed. ( Ignorable by Annotation )

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

564
    public function install($admingroups = [], /** @scrutinizer ignore-unused */ $accessgroups = [])

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
565
    {
566
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
567
568
        return false;
569
    }
570
571
    /**
572
     * @return bool
573
     * @deprecated
574
     */
575
    public function update()
576
    {
577
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
578
579
        return false;
580
    }
581
582
    /**
583
     * @return bool
584
     * @deprecated
585
     */
586
    public function insert()
587
    {
588
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
589
590
        return false;
591
    }
592
593
    /**
594
     * @return bool
595
     */
596
    public function executeSQL()
597
    {
598
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
599
600
        return false;
601
    }
602
603
    /**
604
     * @return bool
605
     * @deprecated
606
     */
607
    public function insertTemplates()
608
    {
609
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
610
611
        return false;
612
    }
613
614
    /**
615
     * @param      $template
616
     * @param bool $block
617
     *
618
     * @return bool
619
     * @deprecated
620
     */
621
    public function gettemplate($template, $block = false)
0 ignored issues
show
Unused Code introduced by
The parameter $block is not used and could be removed. ( Ignorable by Annotation )

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

621
    public function gettemplate($template, /** @scrutinizer ignore-unused */ $block = false)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $template is not used and could be removed. ( Ignorable by Annotation )

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

621
    public function gettemplate(/** @scrutinizer ignore-unused */ $template, $block = false)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
622
    {
623
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
624
625
        return false;
626
    }
627
628
    /**
629
     * @return bool
630
     * @deprecated
631
     */
632
    public function insertBlocks()
633
    {
634
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
635
636
        return false;
637
    }
638
639
    /**
640
     * @return bool
641
     * @deprecated
642
     */
643
    public function insertConfigCategories()
644
    {
645
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
646
647
        return false;
648
    }
649
650
    /**
651
     * @return bool
652
     * @deprecated
653
     */
654
    public function insertConfig()
655
    {
656
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
657
658
        return false;
659
    }
660
661
    /**
662
     * @return bool
663
     * @deprecated
664
     */
665
    public function insertProfileFields()
666
    {
667
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
668
669
        return false;
670
    }
671
672
    /**
673
     * @param     $type
674
     * @param int $state
675
     *
676
     * @return bool
677
     * @deprecated
678
     */
679
    public function executeScript($type, $state = 2)
0 ignored issues
show
Unused Code introduced by
The parameter $type is not used and could be removed. ( Ignorable by Annotation )

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

679
    public function executeScript(/** @scrutinizer ignore-unused */ $type, $state = 2)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $state is not used and could be removed. ( Ignorable by Annotation )

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

679
    public function executeScript($type, /** @scrutinizer ignore-unused */ $state = 2)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
680
    {
681
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
682
683
        return false;
684
    }
685
686
    /**
687
     * @param $groups
688
     * @param $type
689
     *
690
     * @return bool
691
     * @deprecated
692
     */
693
    public function insertGroupPermissions($groups, $type)
0 ignored issues
show
Unused Code introduced by
The parameter $type is not used and could be removed. ( Ignorable by Annotation )

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

693
    public function insertGroupPermissions($groups, /** @scrutinizer ignore-unused */ $type)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $groups is not used and could be removed. ( Ignorable by Annotation )

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

693
    public function insertGroupPermissions(/** @scrutinizer ignore-unused */ $groups, $type)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
694
    {
695
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
696
697
        return false;
698
    }
699
    /**#@-*/
700
}
701
702
/**
703
 * XOOPS module handler class.
704
 *
705
 * This class is responsible for providing data access mechanisms to the data source
706
 * of XOOPS module class objects.
707
 *
708
 * @package       kernel
709
 * @author        Kazumi Ono <[email protected]>
710
 * @copyright (c) 2000-2016 XOOPS Project - www.xoops.org
711
 *
712
 * @todo Why is this not a XoopsPersistableObjectHandler?
713
 */
714
class XoopsModuleHandler extends XoopsObjectHandler
715
{
716
    /**
717
     * holds an array of cached module references, indexed by module id
718
     *
719
     * @var array
720
     * @access private
721
     */
722
    public $_cachedModule_mid = [];
723
724
    /**
725
     * holds an array of cached module references, indexed by module dirname
726
     *
727
     * @var array
728
     * @access private
729
     */
730
    public $_cachedModule_dirname = [];
731
732
    /**
733
     * Create a new {@link XoopsModule} object
734
     *
735
     * @param  boolean $isNew Flag the new object as "new"
736
     * @return XoopsModule
737
     */
738
    public function create($isNew = true)
739
    {
740
        $module = new XoopsModule();
741
        if ($isNew) {
742
            $module->setNew();
743
        }
744
745
        return $module;
746
    }
747
748
    /**
749
     * Load a module from the database
750
     *
751
     * @param  int $id ID of the module
752
     * @return XoopsObject|false false on fail
753
     */
754
    public function get($id)
755
    {
756
        static $_cachedModule_dirname;
757
        static $_cachedModule_mid;
758
        $id     = (int) $id;
759
        $module = false;
760
        if ($id > 0) {
761
            if (!empty($_cachedModule_mid[$id])) {
762
                return $_cachedModule_mid[$id];
763
            } else {
764
                $sql = 'SELECT * FROM ' . $this->db->prefix('modules') . ' WHERE mid = ' . $id;
765
                $result = $this->db->query($sql);
766
                if (!$this->db->isResultSet($result)) {
767
                    return $module;
768
                }
769
                $numrows = $this->db->getRowsNum($result);
0 ignored issues
show
Bug introduced by
The method getRowsNum() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

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

769
                /** @scrutinizer ignore-call */ 
770
                $numrows = $this->db->getRowsNum($result);
Loading history...
770
                if ($numrows == 1) {
771
                    $module = new XoopsModule();
772
                    $myrow  = $this->db->fetchArray($result);
0 ignored issues
show
Bug introduced by
The method fetchArray() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

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

772
                    /** @scrutinizer ignore-call */ 
773
                    $myrow  = $this->db->fetchArray($result);
Loading history...
773
                    $module->assignVars($myrow);
774
                    $_cachedModule_mid[$id]                            = &$module;
775
                    $_cachedModule_dirname[$module->getVar('dirname')] = &$module;
776
777
                    return $module;
778
                }
779
            }
780
        }
781
782
        return $module;
783
    }
784
785
    /**
786
     * Load a module by its dirname
787
     *
788
     * @param  string $dirname
789
     * @return XoopsModule|FALSE on fail
790
     */
791
    public function getByDirname($dirname)
792
    {
793
        $dirname = basename($dirname);
794
        // Sanitize $dirname to prevent SQL injection
795
        $dirname = $this->db->escape(trim($dirname));
0 ignored issues
show
Bug introduced by
The method escape() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

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

795
        /** @scrutinizer ignore-call */ 
796
        $dirname = $this->db->escape(trim($dirname));
Loading history...
796
797
        //could not we check for spaces instead??
798
        if (strpos(strtolower($dirname), ' union ')) {
799
            return false;
800
        }
801
        static $_cachedModule_mid;
802
        static $_cachedModule_dirname;
803
        if (!empty($_cachedModule_dirname[$dirname])) {
804
            return $_cachedModule_dirname[$dirname];
805
        } else {
806
            $module = false;
807
            $sql    = 'SELECT * FROM ' . $this->db->prefix('modules') . ' WHERE dirname = ?';
808
            $stmt   = $this->db->conn->prepare($sql);
809
            $stmt->bind_param('s', $dirname);
810
            $success = $stmt->execute();
811
            if (!$success) {
812
                return $module;
813
            }
814
            $result = $stmt->get_result();
815
816
            if (!$this->db->isResultSet($result)) {
817
                return $module;
818
            }
819
            $numrows = $this->db->getRowsNum($result);
820
            if ($numrows == 1) {
821
                $module = new XoopsModule();
822
                $myrow  = $this->db->fetchArray($result);
823
                $module->assignVars($myrow);
824
                $_cachedModule_dirname[$dirname]           = & $module;
825
                $_cachedModule_mid[$module->getVar('mid')] = & $module;
826
            }
827
828
            return $module;
829
        }
830
    }
831
832
    /**
833
     * Write a module to the database
834
     *
835
     * @param  XoopsObject|XoopsModule $module a XoopsModule object
836
     *
837
     * @return bool true on success, otherwise false
838
     */
839
    public function insert(XoopsObject $module)
840
    {
841
        $className = 'XoopsModule';
842
        if (!($module instanceof $className)) {
843
            return false;
844
        }
845
        if (!$module->isDirty()) {
846
            return true;
847
        }
848
        if (!$module->cleanVars()) {
849
            return false;
850
        }
851
        foreach ($module->cleanVars as $k => $v) {
852
            ${$k} = $v;
853
        }
854
        if ($module->isNew()) {
855
            $mid = $this->db->genId('modules_mid_seq');
0 ignored issues
show
Bug introduced by
The method genId() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

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

855
            /** @scrutinizer ignore-call */ 
856
            $mid = $this->db->genId('modules_mid_seq');
Loading history...
856
            $sql = sprintf('INSERT INTO %s (mid, name, version, last_update, weight, isactive, dirname, hasmain, hasadmin, hassearch, hasconfig, hascomments, hasnotification) VALUES (%u, %s, %s, %u, %u, %u, %s, %u, %u, %u, %u, %u, %u)', $this->db->prefix('modules'), $mid, $this->db->quote($name), $this->db->quote($version), time(), $weight, 1, $this->db->quote($dirname), $hasmain, $hasadmin, $hassearch, $hasconfig, $hascomments, $hasnotification);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $hasmain seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $version seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $hasadmin seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $weight seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $dirname seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $hassearch seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $hasnotification seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $hasconfig seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $hascomments seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $name seems to be never defined.
Loading history...
857
        } else {
858
            $sql = sprintf('UPDATE %s SET name = %s, dirname = %s, version = %s, last_update = %u, weight = %u, isactive = %u, hasmain = %u, hasadmin = %u, hassearch = %u, hasconfig = %u, hascomments = %u, hasnotification = %u WHERE mid = %u', $this->db->prefix('modules'), $this->db->quote($name), $this->db->quote($dirname), $this->db->quote($version), time(), $weight, $isactive, $hasmain, $hasadmin, $hassearch, $hasconfig, $hascomments, $hasnotification, $mid);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $isactive seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $mid seems to be never defined.
Loading history...
859
        }
860
        if (!$result = $this->db->exec($sql)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
861
            return false;
862
        }
863
        if (empty($mid)) {
864
            $mid = $this->db->getInsertId();
0 ignored issues
show
Bug introduced by
The method getInsertId() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

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

864
            /** @scrutinizer ignore-call */ 
865
            $mid = $this->db->getInsertId();
Loading history...
865
        }
866
        $module->assignVar('mid', $mid);
867
        if (!empty($this->_cachedModule_dirname[$dirname])) {
868
            unset($this->_cachedModule_dirname[$dirname]);
869
        }
870
        if (!empty($this->_cachedModule_mid[$mid])) {
871
            unset($this->_cachedModule_mid[$mid]);
872
        }
873
874
        return true;
875
    }
876
877
    /**
878
     * Delete a module from the database
879
     *
880
     * @param  XoopsObject|XoopsModule $module a XoopsModule object
881
     *
882
     * @return bool true on success, otherwise false
883
     */
884
    public function delete(XoopsObject $module)
885
    {
886
        $className = 'XoopsModule';
887
        if (!($module instanceof $className)) {
888
            return false;
889
        }
890
        $sql = sprintf('DELETE FROM %s WHERE mid = %u', $this->db->prefix('modules'), $module->getVar('mid'));
0 ignored issues
show
Bug introduced by
It seems like $module->getVar('mid') can also be of type array and array; however, parameter $values of sprintf() does only seem to accept double|integer|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

890
        $sql = sprintf('DELETE FROM %s WHERE mid = %u', $this->db->prefix('modules'), /** @scrutinizer ignore-type */ $module->getVar('mid'));
Loading history...
891
        if (!$result = $this->db->exec($sql)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
892
            return false;
893
        }
894
        // delete admin permissions assigned for this module
895
        $sql = sprintf("DELETE FROM %s WHERE gperm_name = 'module_admin' AND gperm_itemid = %u", $this->db->prefix('group_permission'), $module->getVar('mid'));
896
        $this->db->exec($sql);
897
        // delete read permissions assigned for this module
898
        $sql = sprintf("DELETE FROM %s WHERE gperm_name = 'module_read' AND gperm_itemid = %u", $this->db->prefix('group_permission'), $module->getVar('mid'));
899
        $this->db->exec($sql);
900
901
        $sql = sprintf('SELECT block_id FROM %s WHERE module_id = %u', $this->db->prefix('block_module_link'), $module->getVar('mid'));
902
        $result = $this->db->query($sql);
903
        if ($this->db->isResultSet($result)) {
904
            $block_id_arr = [];
905
            /** @var array $myrow */
906
            while (false !== ($myrow = $this->db->fetchArray($result))) {
907
                $block_id_arr[] = $myrow['block_id'];
908
            }
909
        }
910
        // loop through block_id_arr
911
        if (isset($block_id_arr)) {
912
            foreach ($block_id_arr as $i) {
913
                $sql = sprintf('SELECT block_id FROM %s WHERE module_id != %u AND block_id = %u', $this->db->prefix('block_module_link'), $module->getVar('mid'), $i);
914
                $result2 = $this->db->query($sql);
915
                if ($this->db->isResultSet($result2)) {
916
                    if (0 < $this->db->getRowsNum($result2)) {
917
                        // this block has other entries, so delete the entry for this module
918
                        $sql = sprintf('DELETE FROM %s WHERE (module_id = %u) AND (block_id = %u)', $this->db->prefix('block_module_link'), $module->getVar('mid'), $i);
919
                        $this->db->exec($sql);
920
                    } else {
921
                        // this block doesn't have other entries, so disable the block and let it show on top page only. otherwise, this block will not display anymore on block admin page!
922
                        $sql = sprintf('UPDATE %s SET visible = 0 WHERE bid = %u', $this->db->prefix('newblocks'), $i);
923
                        $this->db->exec($sql);
924
                        $sql = sprintf('UPDATE %s SET module_id = -1 WHERE module_id = %u', $this->db->prefix('block_module_link'), $module->getVar('mid'));
925
                        $this->db->exec($sql);
926
                    }
927
                }
928
            }
929
        }
930
931
        $dirname = (string) $module->getVar('dirname');
932
        $mid = (int) $module->getVar('mid');
933
934
        if (!empty($this->_cachedModule_dirname[$dirname])) {
935
            unset($this->_cachedModule_dirname[$dirname]);
936
        }
937
        if (!empty($this->_cachedModule_mid[$mid])) {
938
            unset($this->_cachedModule_mid[$mid]);
939
        }
940
941
        return true;
942
    }
943
944
    /**
945
     * Load some modules
946
     *
947
     * @param  CriteriaElement|CriteriaCompo $criteria  {@link CriteriaElement}
948
     * @param  boolean         $id_as_key Use the ID as key into the array
949
     * @return array
950
     */
951
    public function getObjects(?CriteriaElement $criteria = null, $id_as_key = false)
952
    {
953
        if (func_num_args() > 0) {
954
            $criteria = func_get_arg(0);
955
        }
956
957
        if (version_compare(PHP_VERSION, '8.0.0', '>=')) {
958
            $criteria = $criteria ?? null;
959
        }
960
961
        if (func_num_args() > 0) {
962
            $criteria = func_get_arg(0);
963
        }
964
965
        if (version_compare(PHP_VERSION, '8.0.0', '>=')) {
966
            $criteria = $criteria ?? null; // Explicitly set to null if not provided
967
        }
968
969
        $ret   = [];
970
        $limit = $start = 0;
971
        $sql   = 'SELECT * FROM ' . $this->db->prefix('modules');
972
        if (isset($criteria) && \method_exists($criteria, 'renderWhere')) {
973
            $sql .= ' ' . $criteria->renderWhere();
974
            $sql .= ' ORDER BY weight ' . $criteria->getOrder() . ', mid ASC';
975
            $limit = $criteria->getLimit();
976
            $start = $criteria->getStart();
977
        }
978
        $result = $this->db->query($sql, $limit, $start);
979
        if (!$this->db->isResultSet($result)) {
980
            return $ret;
981
        }
982
        /** @var array $myrow */
983
        while (false !== ($myrow = $this->db->fetchArray($result))) {
984
            $module = new XoopsModule();
985
            $module->assignVars($myrow);
986
            if (!$id_as_key) {
987
                $ret[] = & $module;
988
            } else {
989
                $ret[$myrow['mid']] = & $module;
990
            }
991
            unset($module);
992
        }
993
994
        return $ret;
995
    }
996
997
    /**
998
     * Count some modules
999
     *
1000
     * @param  CriteriaElement|CriteriaCompo $criteria {@link CriteriaElement}
1001
     * @return int
1002
     */
1003
    public function getCount(?CriteriaElement $criteria = null)
1004
    {
1005
        if (func_num_args() > 0) {
1006
            $criteria = func_get_arg(0);
1007
        }
1008
1009
        if (version_compare(PHP_VERSION, '8.0.0', '>=')) {
1010
            $criteria = $criteria ?? null;
1011
        }
1012
1013
        $sql = 'SELECT COUNT(*) FROM ' . $this->db->prefix('modules');
1014
        if (isset($criteria) && \method_exists($criteria, 'renderWhere')) {
1015
            $sql .= ' ' . $criteria->renderWhere();
1016
        }
1017
        $result = $this->db->query($sql);
1018
        if (!$this->db->isResultSet($result)) {
1019
            return 0;
1020
        }
1021
        [$count] = $this->db->fetchRow($result);
0 ignored issues
show
Bug introduced by
The method fetchRow() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

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

1021
        /** @scrutinizer ignore-call */ 
1022
        [$count] = $this->db->fetchRow($result);
Loading history...
1022
1023
        return (int) $count;
1024
    }
1025
1026
    /**
1027
     * returns an array of module names
1028
     *
1029
     * @param  CriteriaElement|null $criteria
1030
     * @param  boolean         $dirname_as_key if true, array keys will be module directory names
1031
     *                                         if false, array keys will be module id
1032
     * @return array
1033
     */
1034
    public function getList(?CriteriaElement $criteria = null, $dirname_as_key = false)
1035
    {
1036
1037
        if (func_num_args() > 0) {
1038
            $criteria = func_get_arg(0);
1039
        }
1040
1041
        if (version_compare(PHP_VERSION, '8.0.0', '>=')) {
1042
            $criteria = $criteria ?? null; // Explicitly set to null if not provided
1043
        }
1044
1045
1046
        $ret     = [];
1047
        $modules = $this->getObjects($criteria, true);
1048
        foreach (array_keys($modules) as $i) {
1049
            if (!$dirname_as_key) {
1050
                $ret[$i] = $modules[$i]->getVar('name');
1051
            } else {
1052
                $ret[$modules[$i]->getVar('dirname')] = $modules[$i]->getVar('name');
1053
            }
1054
        }
1055
1056
        return $ret;
1057
    }
1058
}
1059