XoopsModule   F
last analyzed

Complexity

Total Complexity 86

Size/Duplication

Total Lines 642
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 172
dl 0
loc 642
rs 2
c 2
b 1
f 0
wmc 86

45 Methods

Rating   Name   Duplication   Size   Complexity  
A id() 0 3 1
A checkAccess() 0 5 1
A executeScript() 0 5 1
A gettemplate() 0 5 1
A subLink() 0 12 4
A install() 0 5 1
A hassearch() 0 3 1
A hasnotification() 0 3 1
A insert() 0 5 1
A update() 0 5 1
F loadInfoAsVar() 0 23 15
A setMessage() 0 3 1
A insertGroupPermissions() 0 5 1
A getAdminMenu() 0 7 2
A __construct() 0 17 1
A getCurrentPage() 0 5 1
A name() 0 3 1
A loadErrorMessages() 0 5 1
A insertConfigCategories() 0 5 1
A mainLink() 0 9 2
A loadLanguage() 0 5 1
A executeSQL() 0 5 1
A getInfo() 0 15 4
A insertConfig() 0 5 1
A version() 0 3 1
A versionCompare() 0 11 3
A mid() 0 3 1
A weight() 0 3 1
A last_update() 0 3 1
A getByDirname() 0 7 1
A dirname() 0 3 1
A getMessages() 0 3 1
A hasmain() 0 3 1
A hascomments() 0 3 1
A insertTemplates() 0 5 1
A loadInfo() 0 28 6
A insertBlocks() 0 5 1
A hasadmin() 0 3 1
B search() 0 21 9
A setInfo() 0 9 2
A isactive() 0 3 1
A hasconfig() 0 3 1
A insertProfileFields() 0 5 1
A loadAdminMenu() 0 7 4
A getStatus() 0 3 1

How to fix   Complexity   

Complex Class

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

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-2016 XOOPS Project (www.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
defined('XOOPS_ROOT_PATH') || exit('Restricted access');
18
19
/**
20
 * A Module
21
 *
22
 * @package kernel
23
 * @author  Kazumi Ono <[email protected]>
24
 */
25
class XoopsModule extends XoopsObject
26
{
27
    /**
28
     *
29
     * @var string
30
     */
31
    public $modinfo;
32
    /**
33
     *
34
     * @var array
35
     */
36
    public $adminmenu;
37
    /**
38
     *
39
     * @var array
40
     */
41
    public $_msg;
42
43
    //PHP 8.2 Dynamic properties deprecated
44
    public $mid;
45
    public $name;
46
    public $version;
47
    public $last_update;
48
    public $weight;
49
    public $isactive;
50
    public $dirname;
51
    public $hasmain;
52
    public $hasadmin;
53
    public $hassearch;
54
    public $hasconfig;
55
    public $hascomments;
56
    // RMV-NOTIFY
57
    public $hasnotification;
58
59
    /**
60
     * Constructor
61
     */
62
    public function __construct()
63
    {
64
        parent::__construct();
65
        $this->initVar('mid', XOBJ_DTYPE_INT, null, false);
66
        $this->initVar('name', XOBJ_DTYPE_TXTBOX, null, true, 150);
67
        $this->initVar('version', XOBJ_DTYPE_TXTBOX, null, false);
68
        $this->initVar('last_update', XOBJ_DTYPE_INT, null, false);
69
        $this->initVar('weight', XOBJ_DTYPE_INT, 0, false);
70
        $this->initVar('isactive', XOBJ_DTYPE_INT, 1, false);
71
        $this->initVar('dirname', XOBJ_DTYPE_OTHER, null, true);
72
        $this->initVar('hasmain', XOBJ_DTYPE_INT, 0, false);
73
        $this->initVar('hasadmin', XOBJ_DTYPE_INT, 0, false);
74
        $this->initVar('hassearch', XOBJ_DTYPE_INT, 0, false);
75
        $this->initVar('hasconfig', XOBJ_DTYPE_INT, 0, false);
76
        $this->initVar('hascomments', XOBJ_DTYPE_INT, 0, false);
77
        // RMV-NOTIFY
78
        $this->initVar('hasnotification', XOBJ_DTYPE_INT, 0, false);
79
    }
80
81
    /**
82
     * Load module info
83
     *
84
     * @param string  $dirname Directory Name
85
     * @param boolean $verbose
86
     */
87
    public function loadInfoAsVar($dirname, $verbose = true)
88
    {
89
        $dirname = basename($dirname);
90
        if (!isset($this->modinfo)) {
91
            $this->loadInfo($dirname, $verbose);
92
        }
93
        $this->setVar('name', $this->modinfo['name'], true);
94
        $this->setVar('version', $this->modinfo['version'], true);
95
        $this->setVar('dirname', $this->modinfo['dirname'], true);
96
        $hasmain     = (isset($this->modinfo['hasMain']) && $this->modinfo['hasMain'] == 1) ? 1 : 0;
97
        $hasadmin    = (isset($this->modinfo['hasAdmin']) && $this->modinfo['hasAdmin'] == 1) ? 1 : 0;
98
        $hassearch   = (isset($this->modinfo['hasSearch']) && $this->modinfo['hasSearch'] == 1) ? 1 : 0;
99
        $hasconfig   = ((isset($this->modinfo['config']) && \is_array($this->modinfo['config'])) || !empty($this->modinfo['hasComments'])) ? 1 : 0;
100
        $hascomments = (isset($this->modinfo['hasComments']) && $this->modinfo['hasComments'] == 1) ? 1 : 0;
101
        // RMV-NOTIFY
102
        $hasnotification = (isset($this->modinfo['hasNotification']) && $this->modinfo['hasNotification'] == 1) ? 1 : 0;
103
        $this->setVar('hasmain', $hasmain);
104
        $this->setVar('hasadmin', $hasadmin);
105
        $this->setVar('hassearch', $hassearch);
106
        $this->setVar('hasconfig', $hasconfig);
107
        $this->setVar('hascomments', $hascomments);
108
        // RMV-NOTIFY
109
        $this->setVar('hasnotification', $hasnotification);
110
    }
111
112
    /**
113
     * add a message
114
     *
115
     * @param string $str message to add
116
     * @access public
117
     */
118
    public function setMessage($str)
119
    {
120
        $this->_msg[] = trim($str);
121
    }
122
123
    /**
124
     * return the messages for this object as an array
125
     *
126
     * @return array an array of messages
127
     * @access public
128
     */
129
    public function getMessages()
130
    {
131
        return $this->_msg;
132
    }
133
134
    /**
135
     * Set module info
136
     *
137
     * @param  string $name
138
     * @param  mixed  $value
139
     * @return bool
140
     **/
141
    public function setInfo($name, $value)
142
    {
143
        if (empty($name)) {
144
            $this->modinfo = $value;
145
        } else {
146
            $this->modinfo[$name] = $value;
147
        }
148
149
        return true;
150
    }
151
152
    /**
153
     * Get module info
154
     *
155
     * @param  string $name
156
     * @return array|string    Array of module information.
157
     *                     If {@link $name} is set, returns a single module information item as string.
158
     */
159
    public function &getInfo($name = null)
160
    {
161
        if (!isset($this->modinfo)) {
162
            $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

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

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

510
    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...
511
    {
512
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
513
514
        return false;
515
    }
516
517
    /**
518
     * @return bool
519
     */
520
    public function loadErrorMessages()
521
    {
522
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
523
524
        return false;
525
    }
526
527
    /**
528
     * @return bool
529
     */
530
    public function getCurrentPage()
531
    {
532
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
533
534
        return false;
535
    }
536
537
    /**
538
     * @param array $admingroups
539
     * @param array $accessgroups
540
     *
541
     * @return bool
542
     */
543
    public function install($admingroups = array(), $accessgroups = array())
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

543
    public function install(/** @scrutinizer ignore-unused */ $admingroups = array(), $accessgroups = array())

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

543
    public function install($admingroups = array(), /** @scrutinizer ignore-unused */ $accessgroups = array())

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...
544
    {
545
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
546
547
        return false;
548
    }
549
550
    /**
551
     * @return bool
552
     */
553
    public function update()
554
    {
555
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
556
557
        return false;
558
    }
559
560
    /**
561
     * @return bool
562
     */
563
    public function insert()
564
    {
565
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
566
567
        return false;
568
    }
569
570
    /**
571
     * @return bool
572
     */
573
    public function executeSQL()
574
    {
575
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
576
577
        return false;
578
    }
579
580
    /**
581
     * @return bool
582
     */
583
    public function insertTemplates()
584
    {
585
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
586
587
        return false;
588
    }
589
590
    /**
591
     * @param      $template
592
     * @param bool $block
593
     *
594
     * @return bool
595
     */
596
    public function gettemplate($template, $block = false)
0 ignored issues
show
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

596
    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...
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

596
    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...
597
    {
598
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
599
600
        return false;
601
    }
602
603
    /**
604
     * @return bool
605
     */
606
    public function insertBlocks()
607
    {
608
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
609
610
        return false;
611
    }
612
613
    /**
614
     * @return bool
615
     */
616
    public function insertConfigCategories()
617
    {
618
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
619
620
        return false;
621
    }
622
623
    /**
624
     * @return bool
625
     */
626
    public function insertConfig()
627
    {
628
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
629
630
        return false;
631
    }
632
633
    /**
634
     * @return bool
635
     */
636
    public function insertProfileFields()
637
    {
638
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
639
640
        return false;
641
    }
642
643
    /**
644
     * @param     $type
645
     * @param int $state
646
     *
647
     * @return bool
648
     */
649
    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

649
    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

649
    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...
650
    {
651
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
652
653
        return false;
654
    }
655
656
    /**
657
     * @param $groups
658
     * @param $type
659
     *
660
     * @return bool
661
     */
662
    public function insertGroupPermissions($groups, $type)
0 ignored issues
show
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

662
    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...
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

662
    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...
663
    {
664
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
665
666
        return false;
667
    }
668
    /**#@-*/
669
}
670
671
/**
672
 * XOOPS module handler class.
673
 *
674
 * This class is responsible for providing data access mechanisms to the data source
675
 * of XOOPS module class objects.
676
 *
677
 * @package       kernel
678
 * @author        Kazumi Ono <[email protected]>
679
 * @copyright (c) 2000-2016 XOOPS Project - www.xoops.org
680
 *
681
 * @todo Why is this not a XoopsPersistableObjectHandler?
682
 */
683
class XoopsModuleHandler extends XoopsObjectHandler
684
{
685
    /**
686
     * holds an array of cached module references, indexed by module id
687
     *
688
     * @var array
689
     * @access private
690
     */
691
    public $_cachedModule_mid = array();
692
693
    /**
694
     * holds an array of cached module references, indexed by module dirname
695
     *
696
     * @var array
697
     * @access private
698
     */
699
    public $_cachedModule_dirname = array();
700
701
    /**
702
     * Create a new {@link XoopsModule} object
703
     *
704
     * @param  boolean $isNew Flag the new object as "new"
705
     * @return XoopsModule
706
     */
707
    public function create($isNew = true)
708
    {
709
        $module = new XoopsModule();
710
        if ($isNew) {
711
            $module->setNew();
712
        }
713
714
        return $module;
715
    }
716
717
    /**
718
     * Load a module from the database
719
     *
720
     * @param  int $id ID of the module
721
     * @return XoopsObject|false false on fail
722
     */
723
    public function get($id)
724
    {
725
        static $_cachedModule_dirname;
726
        static $_cachedModule_mid;
727
        $id     = (int)$id;
728
        $module = false;
729
        if ($id > 0) {
730
            if (!empty($_cachedModule_mid[$id])) {
731
                return $_cachedModule_mid[$id];
732
            } else {
733
                $sql = 'SELECT * FROM ' . $this->db->prefix('modules') . ' WHERE mid = ' . $id;
734
                $result = $this->db->query($sql);
0 ignored issues
show
Bug introduced by
The method query() 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

734
                /** @scrutinizer ignore-call */ 
735
                $result = $this->db->query($sql);
Loading history...
735
                if (!$this->db->isResultSet($result)) {
736
                    return $module;
737
                }
738
                $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

738
                /** @scrutinizer ignore-call */ 
739
                $numrows = $this->db->getRowsNum($result);
Loading history...
739
                if ($numrows == 1) {
740
                    $module = new XoopsModule();
741
                    $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

741
                    /** @scrutinizer ignore-call */ 
742
                    $myrow  = $this->db->fetchArray($result);
Loading history...
742
                    $module->assignVars($myrow);
743
                    $_cachedModule_mid[$id]                            = &$module;
744
                    $_cachedModule_dirname[$module->getVar('dirname')] = &$module;
745
746
                    return $module;
747
                }
748
            }
749
        }
750
751
        return $module;
752
    }
753
754
    /**
755
     * Load a module by its dirname
756
     *
757
     * @param  string $dirname
758
     * @return XoopsModule|FALSE on fail
759
     */
760
    public function getByDirname($dirname)
761
    {
762
        $dirname = basename($dirname);
763
        // Sanitize $dirname to prevent SQL injection
764
        $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

764
        /** @scrutinizer ignore-call */ 
765
        $dirname = $this->db->escape(trim($dirname));
Loading history...
765
766
        //could not we check for spaces instead??
767
        if (strpos(strtolower($dirname), ' union ')) {
768
            return false;
769
        }
770
        static $_cachedModule_mid;
771
        static $_cachedModule_dirname;
772
        if (!empty($_cachedModule_dirname[$dirname])) {
773
            return $_cachedModule_dirname[$dirname];
774
        } else {
775
            $module = false;
776
            $sql    = 'SELECT * FROM ' . $this->db->prefix('modules') . ' WHERE dirname = ?';
777
            $stmt   = $this->db->conn->prepare($sql);
778
            $stmt->bind_param('s',  $dirname);
779
            $success = $stmt->execute();
780
            if (!$success) {
781
                return $module;
782
            }
783
            $result = $stmt->get_result();
784
785
            if (!$this->db->isResultSet($result)) {
786
                return $module;
787
            }
788
            $numrows = $this->db->getRowsNum($result);
789
            if ($numrows == 1) {
790
                $module = new XoopsModule();
791
                $myrow  = $this->db->fetchArray($result);
792
                $module->assignVars($myrow);
793
                $_cachedModule_dirname[$dirname]           =& $module;
794
                $_cachedModule_mid[$module->getVar('mid')] =& $module;
795
            }
796
797
            return $module;
798
        }
799
    }
800
801
    /**
802
     * Write a module to the database
803
     *
804
     * @param  XoopsObject|XoopsModule $module a XoopsModule object
805
     *
806
     * @return bool true on success, otherwise false
807
     */
808
    public function insert(XoopsObject $module)
809
    {
810
        $className = 'XoopsModule';
811
        if (!($module instanceof $className)) {
812
            return false;
813
        }
814
        if (!$module->isDirty()) {
815
            return true;
816
        }
817
        if (!$module->cleanVars()) {
818
            return false;
819
        }
820
        foreach ($module->cleanVars as $k => $v) {
821
            ${$k} = $v;
822
        }
823
        if ($module->isNew()) {
824
            $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

824
            /** @scrutinizer ignore-call */ 
825
            $mid = $this->db->genId('modules_mid_seq');
Loading history...
825
            $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->quoteString($name), $this->db->quoteString($version), time(), $weight, 1, $this->db->quoteString($dirname), $hasmain, $hasadmin, $hassearch, $hasconfig, $hascomments, $hasnotification);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $hascomments seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $hasmain 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 $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 $version 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 $dirname seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $name seems to be never defined.
Loading history...
Bug introduced by
The method quoteString() 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

825
            $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->/** @scrutinizer ignore-call */ quoteString($name), $this->db->quoteString($version), time(), $weight, 1, $this->db->quoteString($dirname), $hasmain, $hasadmin, $hassearch, $hasconfig, $hascomments, $hasnotification);
Loading history...
Comprehensibility Best Practice introduced by
The variable $weight seems to be never defined.
Loading history...
826
        } else {
827
            $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->quoteString($name), $this->db->quoteString($dirname), $this->db->quoteString($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...
828
        }
829
        if (!$result = $this->db->query($sql)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
830
            return false;
831
        }
832
        if (empty($mid)) {
833
            $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

833
            /** @scrutinizer ignore-call */ 
834
            $mid = $this->db->getInsertId();
Loading history...
834
        }
835
        $module->assignVar('mid', $mid);
836
        if (!empty($this->_cachedModule_dirname[$dirname])) {
837
            unset($this->_cachedModule_dirname[$dirname]);
838
        }
839
        if (!empty($this->_cachedModule_mid[$mid])) {
840
            unset($this->_cachedModule_mid[$mid]);
841
        }
842
843
        return true;
844
    }
845
846
    /**
847
     * Delete a module from the database
848
     *
849
     * @param  XoopsObject|XoopsModule $module a XoopsModule object
850
     *
851
     * @return bool true on success, otherwise false
852
     */
853
    public function delete(XoopsObject $module)
854
    {
855
        $className = 'XoopsModule';
856
        if (!($module instanceof $className)) {
857
            return false;
858
        }
859
        $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

859
        $sql = sprintf('DELETE FROM %s WHERE mid = %u', $this->db->prefix('modules'), /** @scrutinizer ignore-type */ $module->getVar('mid'));
Loading history...
860
        if (!$result = $this->db->query($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
        // delete admin permissions assigned for this module
864
        $sql = sprintf("DELETE FROM %s WHERE gperm_name = 'module_admin' AND gperm_itemid = %u", $this->db->prefix('group_permission'), $module->getVar('mid'));
865
        $this->db->query($sql);
866
        // delete read permissions assigned for this module
867
        $sql = sprintf("DELETE FROM %s WHERE gperm_name = 'module_read' AND gperm_itemid = %u", $this->db->prefix('group_permission'), $module->getVar('mid'));
868
        $this->db->query($sql);
869
870
        $sql = sprintf('SELECT block_id FROM %s WHERE module_id = %u', $this->db->prefix('block_module_link'), $module->getVar('mid'));
871
        $result = $this->db->query($sql);
872
        if ($this->db->isResultSet($result)) {
873
            $block_id_arr = array();
874
            /** @var array $myrow */
875
            while (false !== ($myrow = $this->db->fetchArray($result))) {
876
                $block_id_arr[] = $myrow['block_id'];
877
            }
878
        }
879
        // loop through block_id_arr
880
        if (isset($block_id_arr)) {
881
            foreach ($block_id_arr as $i) {
882
                $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);
883
                $result2 = $this->db->query($sql);
884
                if ($this->db->isResultSet($result2)) {
885
                    if (0 < $this->db->getRowsNum($result2)) {
886
                        // this block has other entries, so delete the entry for this module
887
                        $sql = sprintf('DELETE FROM %s WHERE (module_id = %u) AND (block_id = %u)', $this->db->prefix('block_module_link'), $module->getVar('mid'), $i);
888
                        $this->db->query($sql);
889
                    } else {
890
                        // 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!
891
                        $sql = sprintf('UPDATE %s SET visible = 0 WHERE bid = %u', $this->db->prefix('newblocks'), $i);
892
                        $this->db->query($sql);
893
                        $sql = sprintf('UPDATE %s SET module_id = -1 WHERE module_id = %u', $this->db->prefix('block_module_link'), $module->getVar('mid'));
894
                        $this->db->query($sql);
895
                    }
896
                }
897
            }
898
        }
899
900
        $dirname = (string) $module->getVar('dirname');
901
        $mid = (int) $module->getVar('mid');
902
903
        if (!empty($this->_cachedModule_dirname[$dirname])) {
904
            unset($this->_cachedModule_dirname[$dirname]);
905
        }
906
        if (!empty($this->_cachedModule_mid[$mid])) {
907
            unset($this->_cachedModule_mid[$mid]);
908
        }
909
910
        return true;
911
    }
912
913
    /**
914
     * Load some modules
915
     *
916
     * @param  CriteriaElement|CriteriaCompo $criteria  {@link CriteriaElement}
917
     * @param  boolean         $id_as_key Use the ID as key into the array
918
     * @return array
919
     */
920
    public function getObjects(CriteriaElement $criteria = null, $id_as_key = false)
921
    {
922
        $ret   = array();
923
        $limit = $start = 0;
924
        $sql   = 'SELECT * FROM ' . $this->db->prefix('modules');
925
        if (isset($criteria) && \method_exists($criteria, 'renderWhere')) {
926
            $sql .= ' ' . $criteria->renderWhere();
927
            $sql .= ' ORDER BY weight ' . $criteria->getOrder() . ', mid ASC';
928
            $limit = $criteria->getLimit();
929
            $start = $criteria->getStart();
930
        }
931
        $result = $this->db->query($sql, $limit, $start);
932
        if (!$this->db->isResultSet($result)) {
933
            return $ret;
934
        }
935
        /** @var array $myrow */
936
        while (false !== ($myrow = $this->db->fetchArray($result))) {
937
            $module = new XoopsModule();
938
            $module->assignVars($myrow);
939
            if (!$id_as_key) {
940
                $ret[] =& $module;
941
            } else {
942
                $ret[$myrow['mid']] =& $module;
943
            }
944
            unset($module);
945
        }
946
947
        return $ret;
948
    }
949
950
    /**
951
     * Count some modules
952
     *
953
     * @param  CriteriaElement|CriteriaCompo $criteria {@link CriteriaElement}
954
     * @return int
955
     */
956
    public function getCount(CriteriaElement $criteria = null)
957
    {
958
        $sql = 'SELECT COUNT(*) FROM ' . $this->db->prefix('modules');
959
        if (isset($criteria) && \method_exists($criteria, 'renderWhere')) {
960
            $sql .= ' ' . $criteria->renderWhere();
961
        }
962
        $result = $this->db->query($sql);
963
        if (!$this->db->isResultSet($result)) {
964
            return 0;
965
        }
966
        list($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

966
        /** @scrutinizer ignore-call */ 
967
        list($count) = $this->db->fetchRow($result);
Loading history...
967
968
        return (int)$count;
969
    }
970
971
    /**
972
     * returns an array of module names
973
     *
974
     * @param  CriteriaElement $criteria
975
     * @param  boolean         $dirname_as_key if true, array keys will be module directory names
976
     *                                         if false, array keys will be module id
977
     * @return array
978
     */
979
    public function getList(CriteriaElement $criteria = null, $dirname_as_key = false)
980
    {
981
        $ret     = array();
982
        $modules = $this->getObjects($criteria, true);
983
        foreach (array_keys($modules) as $i) {
984
            if (!$dirname_as_key) {
985
                $ret[$i] = $modules[$i]->getVar('name');
986
            } else {
987
                $ret[$modules[$i]->getVar('dirname')] = $modules[$i]->getVar('name');
988
            }
989
        }
990
991
        return $ret;
992
    }
993
}
994