Xoops::deprecated()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 3
cts 3
cp 1
crap 1
1
<?php
2
/*
3
 You may not change or alter any portion of this comment or credits
4
 of supporting developers from this source code or any supporting source code
5
 which is considered copyrighted (c) material of the original comment or credit authors.
6
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
*/
11
12
use Xoops\Core\HttpRequest;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, HttpRequest. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
13
use Xmf\Request;
14
use Xoops\Core\FixedGroups;
15
use Xoops\Core\Handler\Factory as HandlerFactory;
16
use Xoops\Core\Kernel\Handlers\XoopsModule;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, XoopsModule. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
17
use Xoops\Core\Kernel\Handlers\XoopsUser;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, XoopsUser. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
18
use Xoops\Core\Theme\XoopsTheme;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, XoopsTheme. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
19
use Xoops\Core\XoopsTpl;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, XoopsTpl. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
20
use Psr\Log\LogLevel;
21
22
/**
23
 * XOOPS
24
 *
25
 * @category  Xoops
26
 * @package   Xoops
27
 * @author    trabis <[email protected]>
28
 * @author    formuss
29
 * @author    Richard Griffith <[email protected]>
30
 * @copyright 2011-2015 XOOPS Project (http://xoops.org)
31
 * @license   GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
32
 * @link      http://xoops.org
33
 */
34
class Xoops
35
{
36
    const VERSION = 'XOOPS 2.6.0-Alpha 3';
37
38
    /**
39
     * @var null|Xoops\Core\Session\Manager
40
     */
41
    public $sessionManager = null;
42
43
    /**
44
     * @var null|XoopsModule
45
     */
46
    public $module = null;
47
48
    /**
49
     * @var array
50
     */
51
    public $config = array();
52
53
    /**
54
     * @var array
55
     */
56
    public $moduleConfig = array();
57
58
    /**
59
     * @var array
60
     */
61
    public $moduleDirname = '';
62
63
    /**
64
     * @var XoopsUser|string
65
     */
66
    public $user = '';
67
68
    /**
69
     * @var bool
70
     */
71
    public $userIsAdmin = false;
72
73
    /**
74
     * @var array
75
     */
76
    public $option = array();
77
78
    /**
79
     * @var XoopsTpl|null
80
     */
81
    private $tpl = null;
82
83
    /**
84
     * @var XoopsTheme|null
85
     */
86
    private $theme = null;
87
88
    /**
89
     * @var array
90
     */
91
    public $paths = array(
92
        'XOOPS'  => array(), 'www' => array(), 'var' => array(), 'lib' => array(), 'modules' => array(),
93
        'themes' => array(), 'media' => array()
94
    );
95
96
    /**
97
     * @var string
98
     */
99
    public $tpl_name = '';
100
101
    /**
102
     * @var HandlerFactory
103
     */
104
    private $handlerFactory;
105
106
    /**
107
     * @var array
108
     */
109
    private $kernelHandlers = array();
110
111
    /**
112
     * @var array
113
     */
114
    private $moduleHandlers = array();
115
116
    /**
117
     * @var null|array
118
     */
119
    private $activeModules = null;
120
121
    /**
122
     * @var array
123
     */
124
    private $moduleConfigs = array();
125
126
    /**
127
     * @var bool
128
     */
129
    public $isAdminSide = false;
130
131
    /**
132
     * Actual Xoops OS
133
     */
134
    private function __construct()
135
    {
136
        $root = \XoopsBaseConfig::get('root-path');
137
        $lib = \XoopsBaseConfig::get('lib-path');
138
        $var = \XoopsBaseConfig::get('var-path');
139
140
        $url = \XoopsBaseConfig::get('url');
141
142
        $this->paths['www'] = array($root, $url);
143
        $this->paths['var'] = array($var, null);
144
        $this->paths['lib'] = array($lib, $url . '/browse.php');
145
        $this->paths['XOOPS'] = array($lib, $url . '/browse.php');
146
        $this->paths['assets'] = array(\XoopsBaseConfig::get('asset-path'), \XoopsBaseConfig::get('asset-url'));
147
        $this->paths['images'] = array($root . '/images', $url . '/images');
148
        $this->paths['language'] = array($root . '/language', $url . '/language');
149
        $this->paths['locale'] = array($root . '/locale', $url . '/locale');
150
        $this->paths['media'] = array(\XoopsBaseConfig::get('media-path'), \XoopsBaseConfig::get('media-url'));
151
        $this->paths['modules'] = array($root . '/modules', $url . '/modules');
152
        $this->paths['themes'] = array(\XoopsBaseConfig::get('themes-path'), \XoopsBaseConfig::get('themes-url'));
153
        $this->paths['uploads'] = array(\XoopsBaseConfig::get('uploads-path'), \XoopsBaseConfig::get('uploads-url'));
154
155
        $this->pathTranslation();
156
    }
157
158
    /**
159
     * Access the only instance of this class
160
     *
161
     * @return Xoops
162
     */
163 519
    public static function getInstance()
164
    {
165 519
        static $instance;
166 519
        if (!isset($instance)) {
167
            $class = __CLASS__;
168
            $instance = new $class();
169
        }
170 519
        return $instance;
171
    }
172
173
    /**
174
     * get database connection instance
175
     *
176
     * @return Xoops\Core\Database\Connection
177
     */
178 137
    public function db()
179
    {
180 137
        return \Xoops\Core\Database\Factory::getConnection();
181
    }
182
183
    /**
184
     * get a \Xoops\Core\Cache\Access object for a named cache
185
     *
186
     * @param string $cacheName a named cached pool
187
     *
188
     * @return \Xoops\Core\Cache\Access
189
     */
190 37
    public function cache($cacheName = 'default')
191
    {
192 37
        static $cacheManager;
193
194 37
        if (!isset($cacheManager)) {
195
            $cacheManager = new \Xoops\Core\Cache\CacheManager();
196
        }
197
198 37
        return $cacheManager->getCache($cacheName);
199
    }
200
201
    /**
202
     * get the system logger instance
203
     *
204
     * @return \Xoops\Core\Logger
205
     */
206 20
    public function logger()
207
    {
208 20
        return \Xoops\Core\Logger::getInstance();
209
    }
210
211
212
    /**
213
     * get the event processor
214
     *
215
     * @return \Xoops\Core\Events instance
216
     */
217 183
    public function events()
218
    {
219 183
        return \Xoops\Core\Events::getInstance();
220
    }
221
222
    /**
223
     * get the asset utility
224
     *
225
     * @return Xoops\Core\Assets instance
226
     */
227 4
    public function assets()
228
    {
229 4
        static $instance;
230 4
        if (!isset($instance)) {
231 1
            $instance = new \Xoops\Core\Assets;
232
        }
233 4
        return $instance;
234
    }
235
236
    /**
237
     * get the service manager
238
     *
239
     * @param string $service - service name
240
     *
241
     * @return Xoops\Core\Service\Provider instance
242
     */
243 19
    public function service($service)
244
    {
245 19
        static $instance;
246 19
        if (!isset($instance)) {
247 1
            $instance = \Xoops\Core\Service\Manager::getInstance();
248
        }
249 19
        return $instance->locate($service);
250
    }
251
252
    /**
253
     * provide a common registry instance
254
     *
255
     * @return Xoops\Core\Registry
256
     */
257 2
    public function registry()
258
    {
259 2
        static $instance;
260 2
        if (!isset($instance)) {
261
            $instance = new \Xoops\Core\Registry();
262
        }
263 2
        return $instance;
264
    }
265
266
    /**
267
     * get security instance
268
     *
269
     * @return XoopsSecurity
270
     */
271 9
    public function security()
272
    {
273 9
        static $instance;
274 9
        if (!isset($instance)) {
275 1
            $instance = new \Xoops\Core\Security();
276
        }
277 9
        return $instance;
278
    }
279
280
    /**
281
     * get current template engine
282
     *
283
     * @return null|XoopsTpl
284
     */
285 8
    public function tpl()
286
    {
287 8
        return $this->tpl;
288
    }
289
290
    /**
291
     * set current template engine
292
     *
293
     * @param XoopsTpl $tpl template engine
294
     *
295
     * @return XoopsTpl
296
     */
297 6
    public function setTpl(XoopsTpl $tpl)
298
    {
299 6
        return $this->tpl = $tpl;
300
    }
301
302
    /**
303
     * establish the theme
304
     *
305
     * @param null|string $tpl_name base template
306
     *
307
     * @return null|XoopsTheme
308
     */
309 68
    public function theme($tpl_name = null)
310
    {
311 68
        if (!isset($this->theme)) {
312
            if ($tpl_name) {
313
                $tpl_info = $this->getTplInfo($tpl_name);
314
                $this->tpl_name = $tpl_info['tpl_name'];
315
            } else {
316
                $tpl_name = 'module:system/system_dummy.tpl';
317
                $tpl_info = $this->getTplInfo($tpl_name);
318
                $this->tpl_name = $tpl_info['tpl_name'];
319
            }
320
            if (!$this->isAdminSide) {
321
                $xoopsThemeFactory = new \Xoops\Core\Theme\Factory();
322
                $xoopsThemeFactory->allowedThemes = $this->getConfig('theme_set_allowed');
323
                $xoopsThemeFactory->defaultTheme = $this->getConfig('theme_set');
324
                $this->setTheme($xoopsThemeFactory->createInstance(array('contentTemplate' => $this->tpl_name)));
325
            } else {
326
                $adminThemeFactory = new \Xoops\Core\Theme\AdminFactory();
327
                $this->setTheme($adminThemeFactory->createInstance(array(
328
                    'folderName'      => 'default', 'themesPath' => 'modules/system/themes',
329
                    'contentTemplate' => $this->tpl_name
330
                )));
331
                //$this->theme()->loadLocalization('admin');
332
                list($cssAssets, $jsAssets) = $this->theme()->getLocalizationAssets('admin');
333
                if (!empty($cssAssets)) {
334
                    $this->theme()->addBaseStylesheetAssets($cssAssets);
335
                }
336
                if (!empty($jsAssets)) {
337
                    $this->theme()->addBaseScriptAssets($jsAssets);
338
                }
339
            }
340
        } else {
341 68
            if ($tpl_name) {
342
                $tpl_info = $this->getTplInfo($tpl_name);
343
                $this->tpl_name = $tpl_info['tpl_name'];
344
                $this->theme->contentTemplate = $this->tpl_name;
345
            }
346
        }
347 68
        $GLOBALS['xoTheme'] = $this->theme;
348 68
        return $this->theme;
349
    }
350
351
    /**
352
     * set theme
353
     *
354
     * @param XoopsTheme $theme theme
355
     *
356
     * @return XoopsTheme
357
     */
358 17
    public function setTheme(XoopsTheme $theme)
359
    {
360 17
        return $this->theme = $theme;
361
    }
362
363
    /**
364
     * Convert a XOOPS path to a physical one
365
     *
366
     * @param string $url     url to derive path from
367
     * @param bool   $virtual virtual
368
     *
369
     * @return string
370
     */
371 40
    public function path($url, $virtual = false)
372
    {
373 40
        $url = $this->normalizePath($url);
374 40
        $rootPath = $this->normalizePath(\XoopsBaseConfig::get('root-path') . '/');
375 40
        if (0 === strpos($url, $rootPath)) {
376 1
            $url = substr($url, strlen($rootPath));
377
        }
378
        //$url = ltrim($url, '/');
379 40
        $parts = explode('/', $url, 2);
380 40
        $root = isset($parts[0]) ? $parts[0] : '';
381 40
        $path = isset($parts[1]) ? $parts[1] : '';
382 40
        if (!isset($this->paths[$root])) {
383 8
            list($root, $path) = array('www', $url);
384
        }
385 40
        if (!$virtual) { // Returns a physical path
386 35
            $path = $this->paths[$root][0] . '/' . $path;
387
            //$path = str_replace('/', DIRECTORY_SEPARATOR, $path);
388 35
            return $path;
389
        }
390 7
        return !isset($this->paths[$root][1]) ? '' : ($this->paths[$root][1] . '/' . $path);
391
    }
392
393
    /**
394
     * Convert path separators to unix style
395
     *
396
     * @param string $path path to normalize
397
     *
398
     * @return string normalized path
399
     */
400 40
    public function normalizePath($path)
401
    {
402 40
        return str_replace('\\', '/', $path);
403
    }
404
405
    /**
406
     * Convert a XOOPS path to an URL
407
     *
408
     * @param string $url path (or url)
409
     *
410
     * @return string
411
     */
412 7
    public function url($url)
413
    {
414 7
        return (false !== strpos($url, '://') ? $url : $this->path($url, true));
415
    }
416
417
    /**
418
     * Build an URL with the specified request params
419
     *
420
     * @param string $url    base url
421
     * @param array  $params parameters to add to the url
422
     *
423
     * @return string
424
     */
425 1
    public function buildUrl($url, $params = array())
426
    {
427 1
        if ($url === '.') {
428 1
            $url = $_SERVER['REQUEST_URI'];
429
        }
430 1
        $split = explode('?', $url);
431 1
        if (count($split) > 1) {
432 1
            list($url, $query) = $split;
433 1
            parse_str($query, $query);
0 ignored issues
show
Bug introduced by
$query of type string is incompatible with the type array expected by parameter $result of parse_str(). ( Ignorable by Annotation )

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

433
            parse_str($query, /** @scrutinizer ignore-type */ $query);
Loading history...
434 1
            $params = array_merge($query, $params);
435
        }
436 1
        if (!empty($params)) {
437 1
            foreach ($params as $k => $v) {
438 1
                $params[$k] = $k . '=' . rawurlencode($v);
439
            }
440 1
            $url .= '?' . implode('&', $params);
441
        }
442 1
        return $url;
443
    }
444
445
    /**
446
     * Check if a path exists
447
     *
448
     * @param string $path       filesystem path
449
     * @param string $error_type error level i.e. Psr\Log\LogLevel
450
     *
451
     * @return string|false
452
     */
453 2
    public function pathExists($path, $error_type)
454
    {
455 2
        if (XoopsLoad::fileExists($path)) {
456 1
            return $path;
457
        } else {
458 1
            $this->logger()->log(
459 1
                LogLevel::WARNING,
460 1
                \XoopsLocale::E_FILE_NOT_FOUND,
461 1
                array($path, $error_type)
462
            );
463
464
            //trigger_error(XoopsLocale::E_FILE_NOT_FOUND, $error_type);
465 1
            return false;
466
        }
467
    }
468
469
    /**
470
     * Start gzipCompression output buffer
471
     *
472
     * @return void
473
     */
474 1
    public function gzipCompression()
475
    {
476
        /**
477
         * Disable gzip compression if PHP is run under CLI mode and needs refactored to work correctly
478
         */
479 1
        if (empty($_SERVER['SERVER_NAME']) || substr(PHP_SAPI, 0, 3) === 'cli') {
480 1
            $this->setConfig('gzip_compression', 0);
481
        }
482
483 1
        if ($this->getConfig('gzip_compression') == 1
484 1
            && extension_loaded('zlib')
485 1
            && !ini_get('zlib.output_compression')
486
        ) {
487
            if (@ini_get('zlib.output_compression_level') < 0) {
488
                ini_set('zlib.output_compression_level', 6);
489
            }
490
            ob_start('ob_gzhandler');
491
        }
492 1
    }
493
494
    /**
495
     * Translate a path
496
     *
497
     * @return void
498
     */
499 1
    public function pathTranslation()
500
    {
501
        /**
502
         * *#@+
503
         * Host abstraction layer
504
         */
505 1
        if (!isset($_SERVER['PATH_TRANSLATED']) && isset($_SERVER['SCRIPT_FILENAME'])) {
506 1
            $_SERVER['PATH_TRANSLATED'] = $_SERVER['SCRIPT_FILENAME']; // For Apache CGI
507
        } else {
508 1
            if (isset($_SERVER['PATH_TRANSLATED']) && !isset($_SERVER['SCRIPT_FILENAME'])) {
509 1
                $_SERVER['SCRIPT_FILENAME'] = $_SERVER['PATH_TRANSLATED']; // For IIS/2K now I think :-(
510
            }
511
        }
512
        /**
513
         * User Mulitbytes
514
         */
515 1
        if (empty($_SERVER['REQUEST_URI'])) { // Not defined by IIS
516
            // Under some configs, IIS makes SCRIPT_NAME point to php.exe :-(
517 1
            if (!($_SERVER['REQUEST_URI'] = @$_SERVER['PHP_SELF'])) {
518 1
                $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'];
519
            }
520 1
            if (isset($_SERVER['QUERY_STRING'])) {
521 1
                $_SERVER['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING'];
522
            }
523
        }
524 1
    }
525
526
    /**
527
     * Select Theme
528
     *
529
     * @return void
530
     */
531 1
    public function themeSelect()
532
    {
533 1
        $xoopsThemeSelect = Request::getString('xoops_theme_select', '', 'POST');
534 1
        if (!empty($xoopsThemeSelect) && in_array($xoopsThemeSelect, $this->getConfig('theme_set_allowed'))) {
535 1
            $this->setConfig('theme_set', $xoopsThemeSelect);
536 1
            $_SESSION['xoopsUserTheme'] = $xoopsThemeSelect;
537
        } else {
538 1
            if (!empty($_SESSION['xoopsUserTheme'])
539 1
                && in_array($_SESSION['xoopsUserTheme'], $this->getConfig('theme_set_allowed'))
540
            ) {
541 1
                $this->setConfig('theme_set', $_SESSION['xoopsUserTheme']);
542
            }
543
        }
544 1
    }
545
546
    /**
547
     * Gets module, type and file from a tpl name
548
     *
549
     * @param string $tpl_name in form type:module/filename.tpl
550
     *
551
     * @return array|false associative array of 'tpl_name', 'type', 'module', 'file'
552
     *                     or false on error
553
     */
554 7
    public function getTplInfo($tpl_name)
555
    {
556 7
        $parts = array();
557 7
        $matched = preg_match('#(\w+):(\w+)/(.*)$#', $tpl_name, $parts);
558 7
        if ($matched) {
559 6
            $names = array('tpl_name', 'type', 'module', 'file');
560 6
            $ret = array();
561 6
            for ($i=0; $i<4; ++$i) {
562 6
                $ret[$names[$i]] = $parts[$i];
563
            }
564
        } else {
565
            // this should be eliminated
566 1
            $this->events()->triggerEvent('debug.log', "Sloppy template: " . $tpl_name);
567 1
            $ret = array();
568 1
            $ret['type'] = $this->isAdminSide ? 'admin' : 'module';
569 1
            $info = explode(':', $tpl_name);
570 1
            if (count($info) == 2) {
571 1
                $ret['type'] = $info[0];
572 1
                $tpl_name = str_replace($ret['type'] . ':', '', $tpl_name);
573
            }
574
575 1
            if ($ret['type'] === 'db') {
576
                //For legacy compatibility
577 1
                $ret['type'] = $this->isAdminSide ? 'admin' : 'module';
578
            }
579
580 1
            $info = explode('|', $tpl_name);
581 1
            if (count($info) == 2) {
582
                $ret['module'] = $info[0];
583
                $ret['file'] = $info[1];
584
            } else {
585 1
                $ret['module'] = 'system';
586 1
                $ret['file'] = $tpl_name;
587 1
                if ($this->isModule()) {
588
                    $ret['module'] = $this->module->getVar('dirname', 'n');
0 ignored issues
show
Bug introduced by
The method getVar() does not exist on null. ( Ignorable by Annotation )

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

588
                    /** @scrutinizer ignore-call */ 
589
                    $ret['module'] = $this->module->getVar('dirname', 'n');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
589
                }
590
            }
591 1
            $ret['tpl_name'] = $ret['type'] . ':' . $ret['module'] . '/' . $ret['file'];
592
        }
593
594 7
        return $ret;
595
    }
596
597
    /**
598
     * Render Header
599
     *
600
     * @param string|null $tpl_name template name
601
     *
602
     * @return null|boolean
603
     */
604
    public function header($tpl_name = null)
605
    {
606
        static $included = false;
607
        if ($included) {
608
            return false;
609
        }
610
        $included = true;
611
612
        $this->events()->triggerEvent('core.header.start');
613
614
        //For legacy
615
        if (!$tpl_name && isset($this->option['template_main'])) {
616
            $tpl_name = $this->option['template_main'];
617
            $this->deprecated(
618
                'XoopsOption \'template_main\' is deprecated, please use $xoops->header(\'templatename.tpl\') instead'
619
            );
620
        }
621
        $this->theme($tpl_name);
622
        $this->tpl()->assign('xoops', $this);
623
624
        if ($this->isAdminSide) {
625
            $this->events()->triggerEvent('system.class.gui.header');
626
            include_once $this->path('modules/system/themes/default/default.php');
627
            $gui = new XoopsGuiDefault();
628
            $gui->header();
629
        } else {
630
            $this->events()->triggerEvent('core.header.addmeta');
631
            // Temporary solution for start page redirection
632
            if (defined("XOOPS_STARTPAGE_REDIRECTED")) {
633
                $smarty = $repeat = null;
634
                $this->theme()->headContent(
635
                    null,
636
                    "<base href='" . \XoopsBaseConfig::get('url') . '/modules/'
637
                    . $this->getConfig('startpage') . "/' />",
638
                    $smarty,
639
                    $repeat
640
                );
641
            }
642
643
            // Sets cache time
644
            if ($this->isModule()) {
645
                $cache_times = $this->getConfig('module_cache');
646
                $this->theme()->contentCacheLifetime =
647
                    isset($cache_times[$this->module->getVar('mid')]) ? $cache_times[$this->module->getVar('mid')] : 0;
648
                // Tricky solution for setting cache time for homepage
649
            } else {
650
                if ($this->tpl_name === 'module:system/system_homepage.tpl') {
651
                    // $this->theme->contentCacheLifetime = 604800;
652
                }
653
            }
654
            $this->events()->triggerEvent('core.header.checkcache');
655
            if ($this->theme()->checkCache()) {
656
                exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
657
            }
658
        }
659
660
        if (!isset($this->tpl_name) && $this->isModule()) {
661
            ob_start();
662
        }
663
664
        $this->events()->triggerEvent('core.header.end');
665
        return true;
666
    }
667
668
    /**
669
     * Render Footer
670
     *
671
     * @return false|null
672
     */
673
    public function footer()
674
    {
675
        static $included = false;
676
        if ($included) {
677
            return false;
678
        }
679
        $included = true;
680
681
        $this->events()->triggerEvent('core.footer.start');
682
683
        if (!headers_sent()) {
684
            header('Content-Type:text/html; charset=' . XoopsLocale::getCharset());
685
            header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
686
            header('Cache-Control: private, no-cache');
687
            header('Pragma: no-cache');
688
        }
689
690
        if (isset($this->option['template_main'])
691
            && $this->option['template_main'] != $this->theme()->contentTemplate
692
        ) {
693
            trigger_error("xoopsOption[template_main] should be defined before including header.php", E_USER_WARNING);
694
            $this->theme()->contentTemplate = $this->tpl_name;
695
        }
696
        $this->theme()->render();
697
        $this->events()->triggerEvent('core.footer.end');
698
        exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
699
    }
700
701
    /**
702
     * Check if a module is set
703
     *
704
     * @return bool
705
     */
706 12
    public function isModule()
707
    {
708 12
        return $this->module instanceof XoopsModule ? true : false;
709
    }
710
711
    /**
712
     * Check if a user is set
713
     *
714
     * @return bool
715
     */
716 8
    public function isUser()
717
    {
718 8
        return $this->user instanceof XoopsUser ? true : false;
719
    }
720
721
    /**
722
     * Check if user is admin
723
     *
724
     * @return bool
725
     */
726 1
    public function isAdmin()
727
    {
728 1
        return $this->userIsAdmin;
729
    }
730
731
    /**
732
     * Get handler of Block
733
     *
734
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
735
     *
736
     * @return \Xoops\Core\Kernel\Handlers\XoopsBlockHandler
737
     */
738 4
    public function getHandlerBlock($optional = false)
739
    {
740 4
        return $this->getHandler('Block', $optional);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getHandler('Block', $optional) also could return the type XoopsObjectHandler|XoopsPersistableObjectHandler which is incompatible with the documented return type Xoops\Core\Kernel\Handlers\XoopsBlockHandler.
Loading history...
741
    }
742
743
    /**
744
     * Get handler of Block Module Link
745
     *
746
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
747
     *
748
     * @return \Xoops\Core\Kernel\Handlers\XoopsBlockModuleLinkHandler
749
     */
750 1
    public function getHandlerBlockModuleLink($optional = false)
751
    {
752 1
        return $this->getHandler('BlockModuleLink', $optional);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getHandler...ModuleLink', $optional) also could return the type XoopsObjectHandler|XoopsPersistableObjectHandler which is incompatible with the documented return type Xoops\Core\Kernel\Handle...sBlockModuleLinkHandler.
Loading history...
753
    }
754
755
    /**
756
     * Get handler of Config
757
     *
758
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
759
     *
760
     * @return \Xoops\Core\Kernel\Handlers\XoopsConfigHandler
761
     */
762 1
    public function getHandlerConfig($optional = false)
763
    {
764 1
        return $this->getHandler('Config', $optional);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getHandler('Config', $optional) also could return the type XoopsObjectHandler|XoopsPersistableObjectHandler which is incompatible with the documented return type Xoops\Core\Kernel\Handlers\XoopsConfigHandler.
Loading history...
765
    }
766
767
    /**
768
     * Get handler of Config  Item
769
     *
770
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
771
     *
772
     * @return \Xoops\Core\Kernel\Handlers\XoopsConfigItemHandler
773
     */
774 19
    public function getHandlerConfigItem($optional = false)
775
    {
776 19
        return $this->getHandler('ConfigItem', $optional);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getHandler('ConfigItem', $optional) also could return the type XoopsObjectHandler|XoopsPersistableObjectHandler which is incompatible with the documented return type Xoops\Core\Kernel\Handlers\XoopsConfigItemHandler.
Loading history...
777
    }
778
779
    /**
780
     * Get handler of Config Option
781
     *
782
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
783
     *
784
     * @return \Xoops\Core\Kernel\Handlers\XoopsConfigOptionHandler
785
     */
786 19
    public function getHandlerConfigOption($optional = false)
787
    {
788 19
        return $this->getHandler('ConfigOption', $optional);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getHandler...nfigOption', $optional) also could return the type XoopsObjectHandler|XoopsPersistableObjectHandler which is incompatible with the documented return type Xoops\Core\Kernel\Handle...oopsConfigOptionHandler.
Loading history...
789
    }
790
791
    /**
792
     * Get handler of Group
793
     *
794
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
795
     *
796
     * @return \Xoops\Core\Kernel\Handlers\XoopsGroupHandler
797
     */
798 9
    public function getHandlerGroup($optional = false)
799
    {
800 9
        return $this->getHandler('Group', $optional);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getHandler('Group', $optional) also could return the type XoopsObjectHandler|XoopsPersistableObjectHandler which is incompatible with the documented return type Xoops\Core\Kernel\Handlers\XoopsGroupHandler.
Loading history...
801
    }
802
803
    /**
804
     * Get handler of Group Permission
805
     *
806
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
807
     *
808
     * @return \Xoops\Core\Kernel\Handlers\XoopsGroupPermHandler
809
     */
810 6
    public function getHandlerGroupPermission($optional = false)
811
    {
812 6
        return $this->getHandler('GroupPerm', $optional);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getHandler('GroupPerm', $optional) also could return the type XoopsObjectHandler|XoopsPersistableObjectHandler which is incompatible with the documented return type Xoops\Core\Kernel\Handlers\XoopsGroupPermHandler.
Loading history...
813
    }
814
815
    /**
816
     * Get handler of Member
817
     *
818
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
819
     *
820
     * @return \Xoops\Core\Kernel\Handlers\XoopsMemberHandler
821
     */
822 24
    public function getHandlerMember($optional = false)
823
    {
824 24
        return $this->getHandler('Member', $optional);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getHandler('Member', $optional) also could return the type XoopsObjectHandler|XoopsPersistableObjectHandler which is incompatible with the documented return type Xoops\Core\Kernel\Handlers\XoopsMemberHandler.
Loading history...
825
    }
826
827
    /**
828
     * Get handler of Membership
829
     *
830
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
831
     *
832
     * @return \Xoops\Core\Kernel\Handlers\XoopsMembershipHandler
833
     */
834 9
    public function getHandlerMembership($optional = false)
835
    {
836 9
        return $this->getHandler('Membership', $optional);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getHandler('Membership', $optional) also could return the type XoopsObjectHandler|XoopsPersistableObjectHandler which is incompatible with the documented return type Xoops\Core\Kernel\Handlers\XoopsMembershipHandler.
Loading history...
837
    }
838
839
    /**
840
     * Get handler of Module
841
     *
842
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
843
     *
844
     * @return \Xoops\Core\Kernel\Handlers\XoopsModuleHandler
845
     */
846 12
    public function getHandlerModule($optional = false)
847
    {
848 12
        return $this->getHandler('Module', $optional);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getHandler('Module', $optional) also could return the type XoopsObjectHandler|XoopsPersistableObjectHandler which is incompatible with the documented return type Xoops\Core\Kernel\Handlers\XoopsModuleHandler.
Loading history...
849
    }
850
851
    /**
852
     * Get handler of Online
853
     *
854
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
855
     *
856
     * @return \Xoops\Core\Kernel\Handlers\XoopsOnlineHandler
857
     */
858 2
    public function getHandlerOnline($optional = false)
859
    {
860 2
        return $this->getHandler('Online', $optional);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getHandler('Online', $optional) also could return the type XoopsObjectHandler|XoopsPersistableObjectHandler which is incompatible with the documented return type Xoops\Core\Kernel\Handlers\XoopsOnlineHandler.
Loading history...
861
    }
862
863
    /**
864
     * Get handler of Private Message
865
     *
866
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
867
     *
868
     * @return \Xoops\Core\Kernel\Handlers\XoopsPrivateMessageHandler
869
     */
870 1
    public function getHandlerPrivateMessage($optional = false)
871
    {
872 1
        return $this->getHandler('Privmessage', $optional);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getHandler...rivmessage', $optional) also could return the type XoopsObjectHandler|XoopsPersistableObjectHandler which is incompatible with the documented return type Xoops\Core\Kernel\Handle...psPrivateMessageHandler.
Loading history...
873
    }
874
875
    /**
876
     * Get the session manager
877
     *
878
     * @return Xoops\Core\Session\Manager
879
     */
880 1
    public function session()
881
    {
882 1
        if ($this->sessionManager === null) {
883 1
            $this->sessionManager = new \Xoops\Core\Session\Manager();
884
        }
885 1
        return $this->sessionManager;
886
    }
887
888
    /**
889
     * Get handler of Template File
890
     *
891
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
892
     *
893
     * @return \Xoops\Core\Kernel\Handlers\XoopsTplFileHandler
894
     */
895 2
    public function getHandlerTplFile($optional = false)
896
    {
897 2
        return $this->getHandler('tplfile', $optional);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getHandler('tplfile', $optional) also could return the type XoopsObjectHandler|XoopsPersistableObjectHandler which is incompatible with the documented return type Xoops\Core\Kernel\Handlers\XoopsTplFileHandler.
Loading history...
898
    }
899
900
    /**
901
     * Get handler of Template Set
902
     *
903
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
904
     *
905
     * @return \Xoops\Core\Kernel\Handlers\XoopsTplSetHandler
906
     */
907 1
    public function getHandlerTplSet($optional = false)
908
    {
909 1
        return $this->getHandler('Tplset', $optional);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getHandler('Tplset', $optional) also could return the type XoopsObjectHandler|XoopsPersistableObjectHandler which is incompatible with the documented return type Xoops\Core\Kernel\Handlers\XoopsTplSetHandler.
Loading history...
910
    }
911
912
    /**
913
     * Get handler of User
914
     *
915
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
916
     *
917
     * @return \Xoops\Core\Kernel\Handlers\XoopsUserHandler
918
     */
919 9
    public function getHandlerUser($optional = false)
920
    {
921 9
        return $this->getHandler('user', $optional);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getHandler('user', $optional) also could return the type XoopsObjectHandler|XoopsPersistableObjectHandler which is incompatible with the documented return type Xoops\Core\Kernel\Handlers\XoopsUserHandler.
Loading history...
922
    }
923
924
    /**
925
     * Get handler
926
     *
927
     * @param string  $name     name of handler
928
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
929
     *
930
     * @return XoopsObjectHandler|XoopsPersistableObjectHandler|null
931
     */
932 77
    protected function getHandler($name, $optional = false)
933
    {
934 77
        if (!isset($this->kernelHandlers[$name])) {
935 6
            if (!isset($this->handlerFactory)) {
936
                $this->handlerFactory = HandlerFactory::getInstance();
937
            }
938 6
            $handler = $this->handlerFactory->newSpec()->scheme('kernel')->name($name)->optional($optional)->build();
939 6
            if ($handler === null) {
940
                $this->logger()->log(
941
                    \Psr\Log\LogLevel::WARNING,
942
                    sprintf('A handler for %s is not available', $name)
943
                );
944
            }
945 6
            $this->kernelHandlers[$name] = $handler;
946
        }
947
948 77
        return $this->kernelHandlers[$name];
949
    }
950
951
    /**
952
     * Get Module Handler
953
     *
954
     * @param string|null $name       name of handler
955
     * @param string|null $module_dir dirname of module
956
     * @param boolean     $optional   true if failure to load handler should be considered a warning, not an error
957
     *
958
     * @return XoopsObjectHandler|XoopsPersistableObjectHandler|bool
959
     */
960 2
    public function getModuleHandler($name = null, $module_dir = null, $optional = false)
961
    {
962
        // if $module_dir is not specified
963 2
        if (!isset($module_dir)) {
964
            // if a module is loaded
965
            if ($this->module instanceof XoopsModule) {
966
                $module_dir = $this->module->getVar('dirname', 'n');
967
            } else {
968
                trigger_error('No Module is loaded', E_USER_ERROR);
969
            }
970
        } else {
971 2
            $module_dir = trim($module_dir);
972
        }
973 2
        $name = (!isset($name)) ? $module_dir : trim($name);
974 2
        if (!isset($this->moduleHandlers[$module_dir][$name])) {
975 2
            if (!isset($this->handlerFactory)) {
976
                $this->handlerFactory = HandlerFactory::getInstance();
977
            }
978 2
            $handler = $this->handlerFactory->create($name, $module_dir, $optional);
979 2
            if ($handler === null) {
980
                $this->logger()->log(
981
                    LogLevel::WARNING,
982
                    sprintf('No handler for %s exists in module %s', $name, $module_dir)
983
                );
984
            }
985 2
            $this->moduleHandlers[$module_dir][$name] = $handler;
986
        }
987 2
        return $this->moduleHandlers[$module_dir][$name];
988
    }
989
990
    /**
991
     * Get Module Form
992
     *
993
     * @param XoopsObject $obj        object to populate form
994
     * @param string      $name       name of form
995
     * @param string      $module_dir dirname of associated module
996
     *
997
     * @return Xoops\Form\Form|bool
998
     */
999 1
    public function getModuleForm($obj, $name, $module_dir = null)
1000
    {
1001 1
        if (empty($name)) {
1002 1
            return false;
1003
        }
1004
        if (empty($module_dir)) {
1005
            if ($this->isModule()) {
1006
                $module_dir = $this->module->getVar('dirname', 'n');
1007
            } else {
1008
                return false;
1009
            }
1010
        }
1011
        if (XoopsLoad::fileExists(
1012
            $hnd_file = \XoopsBaseConfig::get('root-path') . "/modules/{$module_dir}/class/form/{$name}.php"
1013
        )) {
1014
            include_once $hnd_file;
1015
            $class = ucfirst(strtolower($module_dir)) . ucfirst($name) . 'Form';
1016
            if (class_exists($class)) {
1017
                $instance = new $class($obj);
1018
                if ($instance instanceof \Xoops\Form\Form) {
1019
                    return $instance;
1020
                }
1021
            }
1022
        }
1023
        return false;
1024
    }
1025
1026
    /**
1027
     * Get Module Helper
1028
     *
1029
     * @param string $dirname dirname of module
1030
     *
1031
     * @return bool|Xoops\Module\Helper\HelperAbstract
1032
     */
1033 1
    public static function getModuleHelper($dirname)
1034
    {
1035 1
        return \Xoops\Module\Helper::getHelper($dirname);
1036
    }
1037
1038
    /**
1039
     * XOOPS language loader wrapper
1040
     * Temporary solution, not encouraged to use
1041
     *
1042
     * @param string $name     Name of language file to be loaded, without extension
1043
     * @param mixed  $domain   string: Module dirname; global language file will be loaded if
1044
     *                           $domain is set to 'global' or not specified
1045
     *                          array:  example; array('Frameworks/moduleclasses/moduleadmin')
1046
     * @param string $language Language to be loaded, current language content will be loaded if not specified
1047
     *
1048
     * @return  boolean
1049
     */
1050 8
    public function loadLanguage($name, $domain = '', $language = null)
1051
    {
1052 8
        if (empty($name)) {
1053 1
            return false;
1054
        }
1055
1056 8
        $language = empty($language) ? XoopsLocale::getLegacyLanguage() : $language;
1057
        // expanded domain to multiple categories, e.g. module:Fsystem, framework:filter, etc.
1058 8
        if ((empty($domain) || 'global' === $domain)) {
1059 1
            $path = '';
1060
        } else {
1061 7
            $path = (is_array($domain)) ? array_shift($domain) . '/' : "modules/{$domain}/";
1062
        }
1063 8
        $path .= 'language';
1064
1065 8
        if (!XoopsLoad::fileExists($file = $this->path("{$path}/{$language}/{$name}.php"))) {
1066 7
            if (!XoopsLoad::fileExists($file = $this->path("{$path}/english/{$name}.php"))) {
1067 7
                return false;
1068
            }
1069
        }
1070 1
        $ret = include_once $file;
1071 1
        return $ret;
1072
    }
1073
1074
    /**
1075
     * loadLocale
1076
     *
1077
     * @param string $domain Module dirname; global language file will be loaded if set to 'global' or not specified
1078
     * @param string $locale Locale to be loaded, current language content will be loaded if not specified
1079
     *
1080
     * @return  boolean
1081
     */
1082 5
    public static function loadLocale($domain = null, $locale = null)
1083
    {
1084 5
        return \Xoops\Locale::loadLocale($domain, $locale);
1085
    }
1086
1087
    /**
1088
     * Translate a key value
1089
     *
1090
     * @param string $key     constant name
1091
     * @param string $dirname dirname of module (domain)
1092
     *
1093
     * @param array $params   array of params used by this key
1094
     * @return string
1095
     */
1096 1
    public function translate($key, $dirname = 'xoops', $params = [])
1097
    {
1098 1
        return \Xoops\Locale::translate($key, $dirname, $params);
1099
    }
1100
1101
    /**
1102
     * Get active modules from cache file
1103
     *
1104
     * @return array
1105
     */
1106 4
    public function getActiveModules()
1107
    {
1108 4
        if (is_array($this->activeModules)) {
1109 4
            return $this->activeModules;
1110
        }
1111
1112
        try {
1113
            if (!$this->activeModules = $this->cache()->read('system/modules/active')) {
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->cache()->read('system/modules/active') can also be of type false. However, the property $activeModules is declared as type array|null. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1114
                $this->setActiveModules();
1115
            }
1116
        } catch (\Exception $e) {
1117
            $this->activeModules = array();
1118
        }
1119
        return $this->activeModules;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->activeModules could also return false which is incompatible with the documented return type array. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
1120
    }
1121
1122
    /**
1123
     * Write active modules to cache file
1124
     *
1125
     * @return array
1126
     */
1127 1
    public function setActiveModules()
1128
    {
1129 1
        $module_handler = $this->getHandlerModule();
1130 1
        $modules_array = $module_handler->getAll(new Criteria('isactive', 1), array('dirname'), false, false);
1131 1
        $modules_active = array();
1132 1
        foreach ($modules_array as $module) {
1133 1
            $modules_active[$module['mid']] = $module['dirname'];
1134
        }
1135 1
        $this->cache()->write('system/modules/active', $modules_active);
1136 1
        $this->activeModules = $modules_active;
1137 1
        return $modules_active;
1138
    }
1139
1140
    /**
1141
     * Checks is module is installed and active
1142
     *
1143
     * @param string $dirname module directory
1144
     *
1145
     * @return bool
1146
     */
1147 2
    public function isActiveModule($dirname)
1148
    {
1149 2
        if (isset($dirname) && in_array($dirname, $this->getActiveModules())) {
1150 2
            return true;
1151
        }
1152 1
        return false;
1153
    }
1154
1155
    /**
1156
     * get module object from module name (dirname)
1157
     *
1158
     * @param string $dirname dirname of the module
1159
     *
1160
     * @return bool|XoopsModule
1161
     */
1162 5
    public function getModuleByDirname($dirname)
1163
    {
1164 5
        $key = "system/module/dirname/{$dirname}";
1165 5
        if (!$module = $this->cache()->read($key)) {
1166 5
            $module = $this->getHandlerModule()->getByDirname($dirname);
1167 5
            $this->cache()->write($key, $module);
1168
        }
1169 5
        return $module;
1170
    }
1171
1172
    /**
1173
     * Get Module By Id
1174
     *
1175
     * @param int $id Id of the module
1176
     *
1177
     * @return bool|XoopsModule
1178
     */
1179 1
    public function getModuleById($id)
1180
    {
1181 1
        $key = "system/module/id/{$id}";
1182 1
        if (!$module = $this->cache()->read($key)) {
1183 1
            $module = $this->getHandlerModule()->getById($id);
1184 1
            $this->cache()->write($key, $module);
1185
        }
1186 1
        return $module;
1187
    }
1188
1189
    /**
1190
     * Render Simple Header
1191
     *
1192
     * @param bool $closehead true to close the HTML head element
1193
     *
1194
     * @return void
1195
     */
1196
    public function simpleHeader($closehead = true)
1197
    {
1198
        $this->events()->triggerEvent('core.header.start');
1199
        $this->theme();
1200
        $xoopsConfigMetaFooter = $this->getConfigs();
1201
1202
        if (!headers_sent()) {
1203
            header('Content-Type:text/html; charset=' . XoopsLocale::getCharset());
1204
            header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
1205
            header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
1206
            header(
1207
                'Cache-Control: no-store, no-cache, max-age=1, s-maxage=1, must-revalidate, post-check=0, pre-check=0'
1208
            );
1209
            header("Pragma: no-cache");
1210
        }
1211
1212
        echo "<!DOCTYPE html>\n";
1213
        $xoops_url = \XoopsBaseConfig::get('url');
1214
        echo '<html lang="' . XoopsLocale::getLangCode() . '">
1215
              <head>
1216
              <meta charset="utf-8">
1217
              <meta http-equiv="X-UA-Compatible" content="IE=edge">
1218
              <meta name="viewport" content="width=device-width, initial-scale=1">
1219
              <meta name="robots" content="' . htmlspecialchars($xoopsConfigMetaFooter['meta_robots']) . '" />
1220
              <meta name="keywords" content="' . htmlspecialchars($xoopsConfigMetaFooter['meta_keywords']) . '" />
1221
              <meta name="description" content="' . htmlspecialchars($xoopsConfigMetaFooter['meta_description']) . '" />
1222
              <meta name="rating" content="' . htmlspecialchars($xoopsConfigMetaFooter['meta_rating']) . '" />
1223
              <meta name="author" content="' . htmlspecialchars($xoopsConfigMetaFooter['meta_author']) . '" />
1224
              <meta name="generator" content="XOOPS" />
1225
              <title>' . htmlspecialchars($this->getConfig('sitename')) . '</title>'
1226
            . $this->theme->renderBaseAssets();
0 ignored issues
show
Bug introduced by
The method renderBaseAssets() does not exist on null. ( Ignorable by Annotation )

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

1226
            . $this->theme->/** @scrutinizer ignore-call */ renderBaseAssets();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1227
1228
        $locale = $this->getConfig('locale');
1229
        if (XoopsLoad::fileExists($this->path('locale/' . $locale . '/style.css'))) {
1230
            echo '<link rel="stylesheet" type="text/css" media="all" href="' . $xoops_url
1231
                . '/locale/' . $locale . '/style.css" />';
1232
        }
1233
        $themecss = $this->getCss($this->getConfig('theme_set'));
1234
        if ($themecss) {
1235
            echo '<link rel="stylesheet" type="text/css" media="all" href="' . $themecss . '" />';
1236
        }
1237
        if ($closehead) {
1238
            echo '</head><body>';
1239
        }
1240
    }
1241
1242
    /**
1243
     * Render simpleFooter
1244
     *
1245
     * @return void
1246
     */
1247 1
    public function simpleFooter()
1248
    {
1249 1
        $this->events()->triggerEvent('core.header.footer');
1250 1
        echo '</body></html>';
1251 1
        ob_end_flush();
1252 1
    }
1253
    /**
1254
     * render an alert message to a string
1255
     *
1256
     * @param string $type  alert type, one of 'info', 'error', 'success' or 'warning'
1257
     * @param mixed  $msg   string or array of strings
1258
     * @param string $title title for alert
1259
     *
1260
     * @return string
1261
     */
1262 1
    public function alert($type, $msg, $title = '/')
1263
    {
1264 1
        $tpl = new XoopsTpl();
1265 1
        switch ($type) {
1266 1
            case 'info':
1267
            default:
1268 1
                $tpl->assign('alert_type', 'alert-info');
1269 1
                if ($title === '/') {
1270 1
                    $title = XoopsLocale::INFORMATION;
1271
                }
1272 1
                break;
1273
1274 1
            case 'error':
1275 1
                $tpl->assign('alert_type', 'alert-danger');
1276 1
                if ($title === '/') {
1277 1
                    $title = XoopsLocale::ERROR;
1278
                }
1279 1
                break;
1280
1281 1
            case 'success':
1282 1
                $tpl->assign('alert_type', 'alert-success');
1283 1
                if ($title === '/') {
1284 1
                    $title = XoopsLocale::SUCCESS;
1285
                }
1286 1
                break;
1287
1288 1
            case 'warning':
1289 1
                $tpl->assign('alert_type', 'alert-warning');
1290 1
                if ($title === '/') {
1291 1
                    $title = XoopsLocale::WARNING;
1292
                }
1293 1
                break;
1294
        }
1295
1296 1
        if ($title != '') {
1297 1
            $tpl->assign('alert_title', $title);
1298
        }
1299 1
        if (!is_scalar($msg) && !is_array($msg)) {
1300 1
            $msg = ''; // don't know what to do with this, so make it blank
1301
        }
1302 1
        $alert_msg = (is_array($msg)) ? @implode("<br />", $msg) : $msg;
1303
1304 1
        if (empty($alert_msg)) {
1305 1
            return '';
1306
        }
1307 1
        $tpl->assign('alert_msg', $alert_msg);
1308 1
        $ret = $tpl->fetch('module:system/system_alert.tpl');
1309 1
        return $ret;
1310
1311
    }
1312
1313
    /**
1314
     * Render a confirmation form to a string
1315
     *
1316
     * @param array   $hiddens  associative array of values used to complete confirmed action
1317
     * @param string  $action   form action (URL)
1318
     * @param string  $msg      message to display
1319
     * @param string  $submit   submit button message
1320
     * @param boolean $addtoken true to add CSRF token
1321
     *
1322
     * @return string rendered confirm message
1323
     */
1324 1
    public function confirm($hiddens, $action, $msg, $submit = '', $addtoken = true)
1325
    {
1326 1
        $tpl = new XoopsTpl();
1327 1
        $submit = ($submit != '') ? trim($submit) : XoopsLocale::A_SUBMIT;
1328 1
        $tpl->assign('msg', $msg);
1329 1
        $tpl->assign('action', $action);
1330 1
        $tpl->assign('submit', $submit);
1331 1
        $str_hiddens = '';
1332 1
        foreach ($hiddens as $name => $value) {
1333 1
            if (is_array($value)) {
1334 1
                foreach ($value as $caption => $newvalue) {
1335 1
                    $str_hiddens .= '<input type="radio" name="' . $name . '" value="'
1336 1
                        . htmlspecialchars($newvalue) . '" > ' . $caption . NWLINE;
1337
                }
1338 1
                $str_hiddens .= '<br />' . NWLINE;
1339
            } else {
1340 1
                $str_hiddens .= '<input type="hidden" name="' . $name . '" value="'
1341 1
                    . htmlspecialchars($value) . '" />' . NWLINE;
1342
            }
1343
        }
1344 1
        if ($addtoken != false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison !== instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1345 1
            $tpl->assign('token', $this->security()->getTokenHTML());
1346
        }
1347 1
        $tpl->assign('hiddens', $str_hiddens);
1348 1
        return $tpl->fetch('module:system/system_confirm.tpl');
1349
    }
1350
1351
    /**
1352
     * Get User Timestamp (kind of pointless, since timestamps are UTC?)
1353
     *
1354
     * @param \DateTime|int $time DateTime object or unix timestamp
1355
     *
1356
     * @return int unix timestamp
1357
     */
1358 1
    public function getUserTimestamp($time)
1359
    {
1360 1
        $dt = \Xoops\Core\Locale\Time::cleanTime($time);
1361 1
        return $dt->getTimestamp();
1362
    }
1363
1364
    /**
1365
     * Function to calculate server timestamp from user entered time (timestamp)
1366
     *
1367
     * @param int  $timestamp time stamp
1368
     * @param null $userTZ    timezone
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $userTZ is correct as it would always require null to be passed?
Loading history...
1369
     *
1370
     * @return int
1371
     */
1372 1
    public function userTimeToServerTime($timestamp, $userTZ = null)
1373
    {
1374 1
        if (!isset($userTZ)) {
1375 1
            $userTZ = $this->getConfig('default_TZ');
1376
        }
1377 1
        $timestamp = $timestamp - (($userTZ - $this->getConfig('server_TZ')) * 3600);
1378 1
        return (int)$timestamp;
1379
    }
1380
1381
    /**
1382
     * get the groups associated with the current user
1383
     *
1384
     * @return int[]
1385
     */
1386 3
    public function getUserGroups()
1387
    {
1388 3
        $groups = $this->isUser() ? $this->user->getGroups() : array(FixedGroups::ANONYMOUS);
1389
1390 3
        return $groups;
1391
    }
1392
1393
    /**
1394
     * generate a temporary password
1395
     *
1396
     * @return string
1397
     *
1398
     * @todo make better passwords
1399
     */
1400 1
    public function makePass()
1401
    {
1402 1
        $makepass = '';
1403
        $syllables = array(
1404 1
            'er', 'in', 'tia', 'wol', 'fe', 'pre', 'vet', 'jo', 'nes', 'al', 'len', 'son', 'cha', 'ir', 'ler', 'bo',
1405
            'ok', 'tio', 'nar', 'sim', 'ple', 'bla', 'ten', 'toe', 'cho', 'co', 'lat', 'spe', 'ak', 'er', 'po', 'co',
1406
            'lor', 'pen', 'cil', 'li', 'ght', 'wh', 'at', 'the', 'he', 'ck', 'is', 'mam', 'bo', 'no', 'fi', 've', 'any',
1407
            'way', 'pol', 'iti', 'cs', 'ra', 'dio', 'sou', 'rce', 'sea', 'rch', 'pa', 'per', 'com', 'bo', 'sp', 'eak',
1408
            'st', 'fi', 'rst', 'gr', 'oup', 'boy', 'ea', 'gle', 'tr', 'ail', 'bi', 'ble', 'brb', 'pri', 'dee', 'kay',
1409
            'en', 'be', 'se'
1410
        );
1411 1
        for ($count = 1; $count <= 4; ++$count) {
1412 1
            if (1 == mt_rand() % 10) {
1413 1
                $makepass .= sprintf('%0.0f', (rand() % 50) + 1);
1414
            } else {
1415 1
                $makepass .= sprintf('%s', $syllables[rand() % 62]);
1416
            }
1417
        }
1418 1
        return $makepass;
1419
    }
1420
1421
    /**
1422
     * Check Email
1423
     *
1424
     * @param string $email    check email
1425
     * @param bool   $antispam true if returned email should be have anti-SPAM measures applied
1426
     *
1427
     * @return false|string email address if valid, otherwise false
1428
     */
1429 2
    public function checkEmail($email, $antispam = false)
1430
    {
1431 2
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
1432 1
            return false;
1433
        }
1434 2
        if ($antispam) {
1435 1
            $email = str_replace("@", " at ", $email);
1436 1
            $email = str_replace(".", " dot ", $email);
1437
        }
1438 2
        return $email;
1439
    }
1440
1441
    /**
1442
     * formatURL - add default http:// if no valid protocol specified
1443
     *
1444
     * @param string $url full or partial url
1445
     *
1446
     * @return string
1447
     */
1448 1
    public function formatURL($url)
1449
    {
1450 1
        $url = trim($url);
1451 1
        if ($url != '') {
1452 1
            if (!preg_match('/^(https?|ftps?|ed2k)\:\/\//i', $url)) {
1453 1
                $url = 'http://' . $url;
1454
            }
1455
        }
1456 1
        return $url;
1457
    }
1458
1459
    /**
1460
     * Function to get banner html tags for use in templates
1461
     *
1462
     * @return string
1463
     */
1464 3
    public function getBanner()
1465
    {
1466 3
        $options = '';
1467 3
        $this->events()->triggerEvent('core.banner.display', array(&$options));
1468 3
        return $options;
1469
    }
1470
1471
    /**
1472
     * Function to redirect a user to certain pages
1473
     *
1474
     * @param string $url               URL to redirect to
1475
     * @param int    $time              time to wait (to allow reading message display)
1476
     * @param string $message           message to display
1477
     * @param bool   $addredirect       add xoops_redirect parameter with current URL to the redirect
1478
     *                                   URL -  used for return from login redirect
1479
     * @param bool   $allowExternalLink allow redirect to external URL
1480
     *
1481
     * @return void
1482
     */
1483
    public function redirect($url, $time = 3, $message = '', $addredirect = true, $allowExternalLink = false)
1484
    {
1485
        $this->events()->triggerEvent('core.redirect.start', array(
1486
            $url, $time, $message, $addredirect, $allowExternalLink
1487
        ));
1488
        // if conditions are right, system preloads will exit on this call
1489
        // so don't use it if you want to be called, use start version above.
1490
        $this->events()->triggerEvent('core.include.functions.redirectheader', array(
1491
            $url, $time, $message, $addredirect, $allowExternalLink
1492
        ));
1493
1494
        $xoops_url = \XoopsBaseConfig::get('url');
1495
1496
        if (preg_match("/[\\0-\\31]|about:|script:/i", $url)) {
1497
            if (!preg_match('/^\b(java)?script:([\s]*)history\.go\(-[0-9]*\)([\s]*[;]*[\s]*)$/si', $url)) {
1498
                $url = $xoops_url;
1499
            }
1500
        }
1501
        if (!$allowExternalLink && $pos = strpos($url, '://')) {
0 ignored issues
show
Bug introduced by
It seems like $url can also be of type null; however, parameter $haystack of strpos() 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

1501
        if (!$allowExternalLink && $pos = strpos(/** @scrutinizer ignore-type */ $url, '://')) {
Loading history...
1502
            $xoopsLocation = substr($xoops_url, strpos($xoops_url, '://') + 3);
0 ignored issues
show
Bug introduced by
It seems like $xoops_url can also be of type null; however, parameter $string of substr() 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

1502
            $xoopsLocation = substr(/** @scrutinizer ignore-type */ $xoops_url, strpos($xoops_url, '://') + 3);
Loading history...
1503
            if (strcasecmp(substr($url, $pos + 3, strlen($xoopsLocation)), $xoopsLocation)) {
1504
                $url = $xoops_url;
1505
            }
1506
        }
1507
        if (!defined('XOOPS_CPFUNC_LOADED')) {
1508
            $theme = 'default';
1509
        } else {
1510
            $theme = $this->getConfig('theme_set');
1511
        }
1512
1513
        $xoopsThemeFactory = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $xoopsThemeFactory is dead and can be removed.
Loading history...
1514
        $xoopsThemeFactory = new \Xoops\Core\Theme\Factory();
1515
        $xoopsThemeFactory->allowedThemes = $this->getConfig('theme_set_allowed');
1516
        $xoopsThemeFactory->defaultTheme = $theme;
1517
        $this->setTheme($xoopsThemeFactory->createInstance(array(
1518
            "plugins" => array(), "renderBanner" => false
1519
        )));
1520
        $this->setTpl($this->theme()->template);
1521
        $this->tpl()->assign(array(
1522
            'xoops_theme'      => $theme, 'xoops_imageurl' => \XoopsBaseConfig::get('themes-url') . '/' . $theme . '/',
1523
            'xoops_themecss'   => $this->getCss($theme),
1524
            'xoops_requesturi' => htmlspecialchars($_SERVER['REQUEST_URI'], ENT_QUOTES),
1525
            'xoops_sitename'   => htmlspecialchars($this->getConfig('sitename'), ENT_QUOTES),
1526
            'xoops_slogan'     => htmlspecialchars($this->getConfig('slogan'), ENT_QUOTES),
1527
            'xoops_dirname'    => $this->isModule() ? $this->module->getVar('dirname') : 'system',
1528
            'xoops_pagetitle'  => $this->isModule() ? $this->module->getVar('name')
1529
                : htmlspecialchars($this->getConfig('slogan'), ENT_QUOTES)
1530
        ));
1531
1532
        $this->tpl()->assign('time', (int)($time));
1533
        if (!empty($_SERVER['REQUEST_URI']) && $addredirect && strstr($url, 'user.php')) {
0 ignored issues
show
Bug introduced by
It seems like $url can also be of type null; however, parameter $haystack of strstr() 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

1533
        if (!empty($_SERVER['REQUEST_URI']) && $addredirect && strstr(/** @scrutinizer ignore-type */ $url, 'user.php')) {
Loading history...
1534
            $joiner = (false===strpos($url, '?')) ? '?' : '&amp;';
1535
            $url .= $joiner . 'xoops_redirect=' . urlencode($_SERVER['REQUEST_URI']);
1536
        }
1537
        $url = preg_replace("/&amp;/i", '&', htmlspecialchars($url, ENT_QUOTES));
0 ignored issues
show
Bug introduced by
It seems like $url can also be of type null; however, parameter $string of htmlspecialchars() 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

1537
        $url = preg_replace("/&amp;/i", '&', htmlspecialchars(/** @scrutinizer ignore-type */ $url, ENT_QUOTES));
Loading history...
1538
        $this->tpl()->assign('url', $url);
1539
        $message = trim($message) != '' ? $message : XoopsLocale::E_TAKING_YOU_BACK;
1540
        $this->tpl()->assign('message', $message);
1541
        $this->tpl()->assign('lang_ifnotreload', sprintf(XoopsLocale::F_IF_PAGE_NOT_RELOAD_CLICK_HERE, $url));
1542
1543
        $this->events()->triggerEvent('core.include.functions.redirectheader.end');
1544
        $this->tpl()->display('module:system/system_redirect.tpl');
1545
        exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1546
    }
1547
1548
    /**
1549
     * Do an immediate redirect to the specified url. Use this instead of using PHP's header()
1550
     * directly so that a core.redirect.start event is triggered. An example is debugbar, that
1551
     * stacks data so the details for both original and redirected scripts data are available.
1552
     *
1553
     * @param string $url URL to redirect to
1554
     *
1555
     * @return void
1556
     */
1557
    public static function simpleRedirect($url)
1558
    {
1559
        header("location: {$url}");
1560
        $xoops = \Xoops::getInstance();
1561
        $xoops->events()->triggerEvent('core.redirect.start', array($url));
1562
        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1563
    }
1564
1565
    /**
1566
     * Get Environment Value
1567
     *
1568
     * @param string $key key (name) in the environment
1569
     *
1570
     * @return string
1571
     */
1572 6
    public function getEnv($key)
1573
    {
1574 6
        return HttpRequest::getInstance()->getEnv($key, '');
0 ignored issues
show
Bug Best Practice introduced by
The expression return Xoops\Core\HttpRe...nce()->getEnv($key, '') also could return the type boolean which is incompatible with the documented return type string.
Loading history...
1575
    }
1576
1577
    /**
1578
     * Function to get css file for a certain themeset
1579
     *
1580
     * @param string $theme theme name
1581
     *
1582
     * @return string
1583
     */
1584 4
    public function getCss($theme = '')
1585
    {
1586 4
        if ($theme == '') {
1587
            $theme = $this->getConfig('theme_set');
1588
        }
1589 4
        $userAgent = $this->getEnv('HTTP_USER_AGENT');
1590 4
        if (stristr($userAgent, 'mac')) {
1591
            $str_css = 'styleMAC.css';
1592 4
        } elseif (preg_match("/MSIE ([0-9]\.[0-9]{1,2})/i", $userAgent)) {
1593
            $str_css = 'style.css';
1594
        } else {
1595 4
            $str_css = 'styleNN.css';
1596
        }
1597 4
        $xoops_theme_path = \XoopsBaseConfig::get('themes-path');
1598 4
        $xoops_theme_url = \XoopsBaseConfig::get('themes-url');
1599 4
        if (is_dir($xoops_theme_path . '/' . $theme)) {
1600 4
            if (XoopsLoad::fileExists($xoops_theme_path . '/' . $theme . '/' . $str_css)) {
1601
                return $xoops_theme_url . '/' . $theme . '/' . $str_css;
1602 4
            } elseif (XoopsLoad::fileExists($xoops_theme_path . '/' . $theme . '/style.css')) {
1603
                return $xoops_theme_url . '/' . $theme . '/style.css';
1604
            }
1605
        }
1606 4
        if (is_dir($xoops_theme_path . '/' . $theme . '/css')) {
1607
            if (XoopsLoad::fileExists($xoops_theme_path . '/' . $theme . '/css/' . $str_css)) {
1608
                return $xoops_theme_url . '/' . $theme . '/css/' . $str_css;
1609
            } elseif (XoopsLoad::fileExists($xoops_theme_path . '/' . $theme . '/css/style.css')) {
1610
                return $xoops_theme_url . '/' . $theme . '/css/style.css';
1611
            }
1612
        }
1613 4
        if (is_dir($xoops_theme_path . '/' . $theme . '/assets/css')) {
1614 4
            if (XoopsLoad::fileExists($xoops_theme_path . '/' . $theme . '/assets/css/' . $str_css)) {
1615
                return $xoops_theme_url . '/' . $theme . '/assets/css/' . $str_css;
1616 4
            } elseif (XoopsLoad::fileExists($xoops_theme_path . '/' . $theme . '/assets/css/style.css')) {
1617 4
                return $xoops_theme_url . '/' . $theme . '/assets/css/style.css';
1618
            }
1619
        }
1620
        return '';
1621
    }
1622
1623
    /**
1624
     * Get Mailer
1625
     *
1626
     * @return XoopsMailer|XoopsMailerLocale
1627
     */
1628 1
    public function getMailer()
1629
    {
1630 1
        static $mailer;
1631 1
        if (is_object($mailer)) {
1632
            return $mailer;
1633
        }
1634 1
        \Xoops\Locale::loadMailerLocale();
1635 1
        if (class_exists('XoopsMailerLocale')) {
1636 1
            $mailer = new XoopsMailerLocale();
1637
        } else {
1638
            $mailer = new XoopsMailer();
1639
        }
1640 1
        return $mailer;
1641
    }
1642
1643
    /**
1644
     * Get Option
1645
     *
1646
     * @param string $key key (name) of option
1647
     *
1648
     * @return string
1649
     */
1650 4
    public function getOption($key)
1651
    {
1652 4
        $ret = '';
1653 4
        if (isset($this->option[$key])) {
1654 1
            $ret = $this->option[$key];
1655
        }
1656 4
        return $ret;
1657
    }
1658
1659
    /**
1660
     * Set Option
1661
     *
1662
     * @param string $key   key (name) of option
1663
     * @param null   $value value for option
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $value is correct as it would always require null to be passed?
Loading history...
1664
     *
1665
     * @return void
1666
     */
1667 1
    public function setOption($key, $value = null)
1668
    {
1669 1
        if (!is_null($value)) {
0 ignored issues
show
introduced by
The condition is_null($value) is always true.
Loading history...
1670 1
            $this->option[$key] = $value;
1671
        }
1672 1
    }
1673
1674
    /**
1675
     * Get Config value
1676
     *
1677
     * @param string $key key (name) of configuration
1678
     *
1679
     * @return mixed
1680
     */
1681 67
    public function getConfig($key)
1682
    {
1683 67
        return $this->getModuleConfig($key, 'system');
1684
    }
1685
1686
    /**
1687
     * Get all Config Values
1688
     *
1689
     * @return array
1690
     */
1691 18
    public function getConfigs()
1692
    {
1693 18
        return $this->getModuleConfigs('system');
1694
    }
1695
1696
    /**
1697
     * Add Config Values
1698
     *
1699
     * @param array  $configs array of configs
1700
     * @param string $dirname module name
1701
     *
1702
     * @return void
1703
     */
1704 1
    public function addConfigs($configs, $dirname = 'system')
1705
    {
1706 1
        $dirname = trim(strtolower($dirname));
1707 1
        if (empty($dirname)) {
1708 1
            $dirname = $this->isModule() ? $this->module->getVar('dirname') : 'system';
1709
        }
1710 1
        if (!empty($dirname)) {
1711 1
            $this->moduleConfigs[$dirname] = array_merge($this->moduleConfigs[$dirname], (array)$configs);
1712
        }
1713 1
    }
1714
1715
    /**
1716
     * Set Config Value
1717
     *
1718
     * @param string $key     key (name) of the configuration item
1719
     * @param mixed  $value   configuration value
1720
     * @param string $dirname dirname of module
1721
     *
1722
     * @return void
1723
     */
1724 15
    public function setConfig($key, $value = null, $dirname = 'system')
1725
    {
1726 15
        if (!is_null($value)) {
1727 15
            $dirname = trim(strtolower($dirname));
1728 15
            if (empty($dirname)) {
1729
                $dirname = $this->isModule() ? $this->module->getVar('dirname') : 'system';
1730
            }
1731 15
            $this->moduleConfigs[$dirname][$key] =& $value;
1732
        }
1733 15
    }
1734
1735
    /**
1736
     * Unset Config Value
1737
     *
1738
     * @param string $key     key (name) of the configuration item
1739
     * @param string $dirname dirname of module
1740
     *
1741
     * @return void
1742
     */
1743 3
    public function unsetConfig($key, $dirname = 'system')
1744
    {
1745 3
        $dirname = trim(strtolower($dirname));
1746 3
        if (empty($dirname)) {
1747
            $dirname = $this->isModule() ? $this->module->getVar('dirname') : 'system';
1748
        }
1749 3
        unset($this->moduleConfigs[$dirname][$key]);
1750 3
        if (empty($this->moduleConfigs[$dirname])) {
1751 1
            unset($this->moduleConfigs[$dirname]);
1752
        }
1753 3
    }
1754
1755
    /**
1756
     * Unset all module configs
1757
     *
1758
     * @return void
1759
     */
1760
    public function clearModuleConfigsCache()
1761
    {
1762
        $this->moduleConfigs = array();
1763
    }
1764
1765
    /**
1766
     * getModuleConfig
1767
     *
1768
     * @param string $key     config name
1769
     * @param string $dirname module directory
1770
     *
1771
     * @return mixed the value for the named config
1772
     */
1773 69
    public function getModuleConfig($key, $dirname = '')
1774
    {
1775 69
        $dirname = trim(strtolower($dirname));
1776 69
        if (empty($dirname)) {
1777 1
            $dirname = $this->isModule() ? $this->module->getVar('dirname') : 'system';
1778
        }
1779
1780 69
        if (isset($this->moduleConfigs[$dirname][$key])) {
1781 66
            return $this->moduleConfigs[$dirname][$key];
1782
        }
1783
1784 5
        $this->getModuleConfigs($dirname);
1785
1786 5
        if (!isset($this->moduleConfigs[$dirname][$key])) {
1787 5
            $this->moduleConfigs[$dirname][$key] = '';
1788
        }
1789 5
        return $this->moduleConfigs[$dirname][$key];
1790
    }
1791
1792
    /**
1793
     * Get Module Configs
1794
     *
1795
     * @param string $dirname dirname of module
1796
     *
1797
     * @return array
1798
     */
1799 26
    public function getModuleConfigs($dirname = '')
1800
    {
1801 26
        $dirname = trim($dirname);
1802 26
        if (empty($dirname)) {
1803 2
            $dirname = $this->isModule() ? $this->module->getVar('dirname') : 'system';
1804
        }
1805 26
        if (isset($this->moduleConfigs[$dirname])) {
1806 25
            return $this->moduleConfigs[$dirname];
1807
        }
1808 1
        $this->moduleConfigs[$dirname] = array();
1809 1
        $key = "system/module/configs/{$dirname}";
1810 1
        if (!$configs = $this->cache()->read($key)) {
1811 1
            $module = $this->getModuleByDirname($dirname);
1812 1
            if (is_object($module)) {
1813
                $configs = $this->getHandlerConfig()->getConfigsByModule($module->getVar('mid'));
1814
                $this->cache()->write($key, $configs);
1815 1
                $this->moduleConfigs[$dirname] =& $configs;
1816
            }
1817
        } else {
1818
            $this->moduleConfigs[$dirname] =& $configs;
1819
        }
1820
1821 1
        if ($this->isModule()) {
1822
            //for legacy
1823 1
            $this->moduleConfig =& $this->moduleConfigs[$this->module->getVar('dirname')];
1824
        }
1825 1
        if ($dirname === 'system') {
1826
            $this->config =& $this->moduleConfigs['system'];
1827
        }
1828 1
        return $this->moduleConfigs[$dirname];
1829
    }
1830
1831
    /**
1832
     * Append Config Value
1833
     *
1834
     * @param string $key           key (name) of the configuration item
1835
     * @param array  $values        array of configuration value
1836
     * @param bool   $appendWithKey true to add each $value element with associative value
1837
     *                               false to add $values as a single index element
1838
     * @param string $dirname       dirname of module
1839
     *
1840
     * @return void
1841
     */
1842 3
    public function appendConfig($key, array $values, $appendWithKey = false, $dirname = 'system')
1843
    {
1844 3
        $dirname = trim(strtolower($dirname));
1845 3
        if (empty($dirname)) {
1846
            $dirname = $this->isModule() ? $this->module->getVar('dirname') : 'system';
1847
        }
1848 3
        if (!isset($this->moduleConfigs[$dirname][$key]) || !is_array($this->moduleConfigs[$dirname][$key])) {
1849 2
            $this->moduleConfigs[$dirname][$key] = array();
1850
        }
1851 3
        if ($appendWithKey) {
1852 3
            foreach ($values as $key2 => $value) {
1853 3
                $this->moduleConfigs[$dirname][$key][$key2] =& $value;
1854
            }
1855
        } else {
1856 1
            $this->moduleConfigs[$dirname][$key][] =& $values;
1857
        }
1858 3
    }
1859
1860
    /**
1861
     * Disables page cache by overriding module cache settings
1862
     *
1863
     * @return void
1864
     */
1865 1
    public function disableModuleCache()
1866
    {
1867 1
        if ($this->isModule()) {
1868 1
            $this->appendConfig('module_cache', array($this->module->getVar('mid') => 0), true);
1869
        }
1870 1
    }
1871
1872
    /**
1873
     * getBaseDomain
1874
     *
1875
     * Get domain name from a URL. This will check that the domain is valid for registering,
1876
     * preventing return of constructs like 'co.uk' as the domain. See https://publicsuffix.org/
1877
     *
1878
     * @param string  $url              URL
1879
     * @param boolean $includeSubdomain true to include include subdomains,
1880
     *                                  default is false registerable domain only
1881
     *
1882
     * @return string|null domain, or null if domain is invalid
1883
     */
1884 4
    public function getBaseDomain($url, $includeSubdomain = false)
1885
    {
1886 4
        $url=mb_strtolower($url, 'UTF-8');
1887
1888 4
        $host = parse_url($url, PHP_URL_HOST);
1889 4
        if (empty($host)) {
1890 4
            $host = parse_url($url, PHP_URL_PATH); // bare host name
1891 4
            if (empty($host)) {
1892
                return null;
1893
            }
1894
        }
1895
1896
        // check for exceptions, localhost and ip address (v4 & v6)
1897 4
        if ($host==='localhost') {
1898 2
            return $host;
1899
        }
1900
        // Check for IPV6 URL (see http://www.ietf.org/rfc/rfc2732.txt)
1901
        // strip brackets before validating
1902 4
        if (substr($host, 0, 1)==='[' && substr($host, -1)===']') {
1903 1
            $host = substr($host, 1, (strlen($host)-2));
1904
        }
1905 4
        if (filter_var($host, FILTER_VALIDATE_IP)) {
1906 1
            return $host;
1907
        }
1908
1909 4
        $regdom = new \Geekwright\RegDom\RegisteredDomain();
1910 4
        $regHost = $regdom->getRegisteredDomain($host);
1911 4
        if (null === $regHost) {
1912 2
            return null;
1913
        }
1914 4
        return $includeSubdomain ? $host : $regHost;
1915
    }
1916
1917
    /**
1918
     * function to update compiled template file in cache folder
1919
     *
1920
     * @param string $tpl_id template id
1921
     *
1922
     * @return boolean
1923
     */
1924 1
    public function templateTouch($tpl_id)
1925
    {
1926 1
        $tplfile = $this->getHandlerTplFile()->get($tpl_id);
1927
1928 1
        if (is_object($tplfile)) {
1929 1
            $file = $tplfile->getVar('tpl_file', 'n');
1930 1
            $module = $tplfile->getVar('tpl_module', 'n');
1931 1
            $type = $tplfile->getVar('tpl_type', 'n');
1932 1
            $tpl = new XoopsTpl();
1933 1
            return $tpl->touch($type . ':' . $module . '/' . $file);
1934
        }
1935
        return false;
1936
    }
1937
1938
    /**
1939
     * Clear the module cache
1940
     *
1941
     * @param int $mid Module ID
1942
     *
1943
     * @return void
1944
     */
1945
    public function templateClearModuleCache($mid)
1946
    {
1947
        $module = $this->getModuleById($mid);
1948
        $xoopsTpl = new XoopsTpl();
1949
        $xoopsTpl->clearModuleCompileCache($module->getVar('dirname'));
1950
    }
1951
1952
    /**
1953
     * Support for deprecated messages events
1954
     *
1955
     * @param string $message message
1956
     *
1957
     * @return void
1958
     */
1959 17
    public function deprecated($message)
1960
    {
1961 17
        $message = $this->logger()->sanitizePath($message);
1962 17
        $this->events()->triggerEvent('core.deprecated', array($message));
1963 17
    }
1964
1965
    /**
1966
     * Support for disabling error reporting
1967
     *
1968
     * @return void
1969
     */
1970 2
    public function disableErrorReporting()
1971
    {
1972
        //error_reporting(0);
1973 2
        $this->events()->triggerEvent('core.disableerrorreporting');
1974 2
    }
1975
}
1976