Completed
Push — master ( a47eb4...10fc3d )
by Richard
06:23
created

Xoops::makePass()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3.0175

Importance

Changes 0
Metric Value
cc 3
eloc 15
nc 3
nop 0
dl 0
loc 20
ccs 7
cts 8
cp 0.875
crap 3.0175
rs 9.4285
c 0
b 0
f 0
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.

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.

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.

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.

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.

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 398
    public static function getInstance()
164
    {
165 398
        static $instance;
166 398
        if (!isset($instance)) {
167
            $class = __CLASS__;
168
            $instance = new $class();
169
        }
170 398
        return $instance;
171
    }
172
173
    /**
174
     * get database connection instance
175
     *
176
     * @return Xoops\Core\Database\Connection
177
     */
178 135
    public function db()
179
    {
180 135
        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 28
    public function cache($cacheName = 'default')
191
    {
192 28
        static $cacheManager;
193
194 28
        if (!isset($cacheManager)) {
195
            $cacheManager = new \Xoops\Core\Cache\CacheManager();
196
        }
197
198 28
        return $cacheManager->getCache($cacheName);
199
    }
200
201
    /**
202
     * get the system logger instance
203
     *
204
     * @return \Xoops\Core\Logger
205
     */
206 15
    public function logger()
207
    {
208 15
        return \Xoops\Core\Logger::getInstance();
209
    }
210
211
212
    /**
213
     * get the event processor
214
     *
215
     * @return \Xoops\Core\Events instance
216
     */
217 138
    public function events()
218
    {
219 138
        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 4
    public function service($service)
244
    {
245 4
        static $instance;
246 4
        if (!isset($instance)) {
247 1
            $instance = \Xoops\Core\Service\Manager::getInstance();
248
        }
249 4
        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 6
    public function security()
272
    {
273 6
        static $instance;
274 6
        if (!isset($instance)) {
275
            $instance = new \Xoops\Core\Security();
276
        }
277 6
        return $instance;
278
    }
279
280
    /**
281
     * get current template engine
282
     *
283
     * @return null|XoopsTpl
284
     */
285 9
    public function tpl()
286
    {
287 9
        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 6
    public function theme($tpl_name = null)
310
    {
311 6
        if (!isset($this->theme)) {
312
            if ($tpl_name) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $tpl_name of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
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');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getConfig('theme_set_allowed') of type * is incompatible with the declared type array of property $allowedThemes.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
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 6
            if ($tpl_name) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $tpl_name of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
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 6
        $GLOBALS['xoTheme'] = $this->theme;
348 6
        return $this->theme;
349
    }
350
351
    /**
352
     * set theme
353
     *
354
     * @param XoopsTheme $theme theme
355
     *
356
     * @return XoopsTheme
357
     */
358 5
    public function setTheme(XoopsTheme $theme)
359
    {
360 5
        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 31
    public function path($url, $virtual = false)
372
    {
373 31
        $url = $this->normalizePath($url);
374 31
        $rootPath = $this->normalizePath(\XoopsBaseConfig::get('root-path') . '/');
375 31
        if (0 === strpos($url, $rootPath)) {
376 1
            $url = substr($url, strlen($rootPath));
377
        }
378
        //$url = ltrim($url, '/');
379 31
        $parts = explode('/', $url, 2);
380 31
        $root = isset($parts[0]) ? $parts[0] : '';
381 31
        $path = isset($parts[1]) ? $parts[1] : '';
382 31
        if (!isset($this->paths[$root])) {
383 7
            list($root, $path) = array('www', $url);
384
        }
385 31
        if (!$virtual) { // Returns a physical path
386 29
            $path = $this->paths[$root][0] . '/' . $path;
387
            //$path = str_replace('/', DIRECTORY_SEPARATOR, $path);
388 29
            return $path;
389
        }
390 5
        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 31
    public function normalizePath($path)
401
    {
402 31
        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 5
    public function url($url)
413
    {
414 5
        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);
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 View Code Duplication
        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 8
    public function getTplInfo($tpl_name)
555
    {
556 8
        $parts = array();
557 8
        $matched = preg_match('#(\w+):(\w+)/(.*)$#', $tpl_name, $parts);
558 8
        if ($matched) {
559 7
            $names = array('tpl_name', 'type', 'module', 'file');
560 7
            $ret = array();
561 7
            for ($i=0; $i<4; ++$i) {
562 7
                $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');
589
                }
590
            }
591 1
            $ret['tpl_name'] = $ret['type'] . ':' . $ret['module'] . '/' . $ret['file'];
592
        }
593
594 8
        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'])) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $tpl_name of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
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();
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();
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);
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);
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);
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 18
    public function getHandlerConfigItem($optional = false)
775
    {
776 18
        return $this->getHandler('ConfigItem', $optional);
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 18
    public function getHandlerConfigOption($optional = false)
787
    {
788 18
        return $this->getHandler('ConfigOption', $optional);
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 8
    public function getHandlerGroup($optional = false)
799
    {
800 8
        return $this->getHandler('Group', $optional);
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 4
    public function getHandlerGroupPermission($optional = false)
811
    {
812 4
        return $this->getHandler('GroupPerm', $optional);
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 18
    public function getHandlerMember($optional = false)
823
    {
824 18
        return $this->getHandler('Member', $optional);
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 8
    public function getHandlerMembership($optional = false)
835
    {
836 8
        return $this->getHandler('Membership', $optional);
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 11
    public function getHandlerModule($optional = false)
847
    {
848 11
        return $this->getHandler('Module', $optional);
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);
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);
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);
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);
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 8
    public function getHandlerUser($optional = false)
920
    {
921 8
        return $this->getHandler('user', $optional);
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 69
    protected function getHandler($name, $optional = false)
933
    {
934 69
        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 69
        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 View Code Duplication
        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 9
    public function getActiveModules()
1107
    {
1108 9
        if (is_array($this->activeModules)) {
1109 9
            return $this->activeModules;
1110
        }
1111
1112
        try {
1113
            if (!$this->activeModules = $this->cache()->read('system/modules/active')) {
1114
                $this->setActiveModules();
1115
            }
1116
        } catch (\Exception $e) {
1117
            $this->activeModules = array();
1118
        }
1119
        return $this->activeModules;
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);
0 ignored issues
show
Bug introduced by
The method getAll does only exist in XoopsPersistableObjectHandler, but not in XoopsObjectHandler.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
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 7
    public function isActiveModule($dirname)
1148
    {
1149 7
        if (isset($dirname) && in_array($dirname, $this->getActiveModules())) {
1150 2
            return true;
1151
        }
1152 6
        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 View Code Duplication
    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 View Code Duplication
    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 1
    public function simpleHeader($closehead = true)
1197
    {
1198 1
        $this->events()->triggerEvent('core.header.start');
1199 1
        $this->theme();
1200 1
        $xoopsConfigMetaFooter = $this->getConfigs();
1201
1202 1
        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 1
        echo "<!DOCTYPE html>\n";
1213 1
        $xoops_url = \XoopsBaseConfig::get('url');
1214 1
        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 1
              <meta name="robots" content="' . htmlspecialchars($xoopsConfigMetaFooter['meta_robots']) . '" />
1220 1
              <meta name="keywords" content="' . htmlspecialchars($xoopsConfigMetaFooter['meta_keywords']) . '" />
1221 1
              <meta name="description" content="' . htmlspecialchars($xoopsConfigMetaFooter['meta_description']) . '" />
1222 1
              <meta name="rating" content="' . htmlspecialchars($xoopsConfigMetaFooter['meta_rating']) . '" />
1223 1
              <meta name="author" content="' . htmlspecialchars($xoopsConfigMetaFooter['meta_author']) . '" />
1224
              <meta name="generator" content="XOOPS" />
1225 1
              <title>' . htmlspecialchars($this->getConfig('sitename')) . '</title>'
1226 1
            . $this->theme->renderBaseAssets();
1227
1228 1
        $locale = $this->getConfig('locale');
1229 1
        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 1
        $themecss = $this->getCss($this->getConfig('theme_set'));
1234 1
        if ($themecss) {
1235 1
            echo '<link rel="stylesheet" type="text/css" media="all" href="' . $themecss . '" />';
1236
        }
1237 1
        if ($closehead) {
1238 1
            echo '</head><body>';
1239
        }
1240 1
    }
1241
1242
    /**
1243
     * Render simpleFooter
1244
     *
1245
     * @return void
1246
     */
1247 2
    public function simpleFooter()
1248
    {
1249 2
        $this->events()->triggerEvent('core.header.footer');
1250 2
        echo '</body></html>';
1251 2
        ob_end_flush();
1252 2
    }
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':
0 ignored issues
show
Unused Code introduced by
case 'error': $tpl->...ERROR; } break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
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
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
                $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 View Code Duplication
        if (!$allowExternalLink && $pos = strpos($url, '://')) {
1502
            $xoopsLocation = substr($xoops_url, strpos($xoops_url, '://') + 3);
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
$xoopsThemeFactory is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1514
        $xoopsThemeFactory = new \Xoops\Core\Theme\Factory();
1515
        $xoopsThemeFactory->allowedThemes = $this->getConfig('theme_set_allowed');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getConfig('theme_set_allowed') of type * is incompatible with the declared type array of property $allowedThemes.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
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')) {
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));
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();
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;
1563
    }
1564
1565
    /**
1566
     * Get Environment Value
1567
     *
1568
     * @param string $key key (name) in the environment
1569
     *
1570
     * @return string
1571
     */
1572 7
    public function getEnv($key)
1573
    {
1574 7
        return HttpRequest::getInstance()->getEnv($key, '');
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 5
    public function getCss($theme = '')
1585
    {
1586 5
        if ($theme == '') {
1587
            $theme = $this->getConfig('theme_set');
1588
        }
1589 5
        $userAgent = $this->getEnv('HTTP_USER_AGENT');
1590 5
        if (stristr($userAgent, 'mac')) {
1591
            $str_css = 'styleMAC.css';
1592 5
        } elseif (preg_match("/MSIE ([0-9]\.[0-9]{1,2})/i", $userAgent)) {
1593
            $str_css = 'style.css';
1594
        } else {
1595 5
            $str_css = 'styleNN.css';
1596
        }
1597 5
        $xoops_theme_path = \XoopsBaseConfig::get('themes-path');
1598 5
        $xoops_theme_url = \XoopsBaseConfig::get('themes-url');
1599 5 View Code Duplication
        if (is_dir($xoops_theme_path . '/' . $theme)) {
1600 5
            if (XoopsLoad::fileExists($xoops_theme_path . '/' . $theme . '/' . $str_css)) {
1601
                return $xoops_theme_url . '/' . $theme . '/' . $str_css;
1602 5
            } elseif (XoopsLoad::fileExists($xoops_theme_path . '/' . $theme . '/style.css')) {
1603
                return $xoops_theme_url . '/' . $theme . '/style.css';
1604
            }
1605
        }
1606 5 View Code Duplication
        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 5 View Code Duplication
        if (is_dir($xoops_theme_path . '/' . $theme . '/assets/css')) {
1614 5
            if (XoopsLoad::fileExists($xoops_theme_path . '/' . $theme . '/assets/css/' . $str_css)) {
1615
                return $xoops_theme_url . '/' . $theme . '/assets/css/' . $str_css;
1616 5
            } elseif (XoopsLoad::fileExists($xoops_theme_path . '/' . $theme . '/assets/css/style.css')) {
1617 5
                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
1664
     *
1665
     * @return void
1666
     */
1667 1
    public function setOption($key, $value = null)
1668
    {
1669 1
        if (!is_null($value)) {
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 62
    public function getConfig($key)
1682
    {
1683 62
        return $this->getModuleConfig($key, 'system');
1684
    }
1685
1686
    /**
1687
     * Get all Config Values
1688
     *
1689
     * @return array
1690
     */
1691 19
    public function getConfigs()
1692
    {
1693 19
        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 View Code Duplication
    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 13 View Code Duplication
    public function setConfig($key, $value = null, $dirname = 'system')
1725
    {
1726 13
        if (!is_null($value)) {
1727 13
            $dirname = trim(strtolower($dirname));
1728 13
            if (empty($dirname)) {
1729
                $dirname = $this->isModule() ? $this->module->getVar('dirname') : 'system';
1730
            }
1731 13
            $this->moduleConfigs[$dirname][$key] =& $value;
1732
        }
1733 13
    }
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 64
    public function getModuleConfig($key, $dirname = '')
1774
    {
1775 64
        $dirname = trim(strtolower($dirname));
1776 64
        if (empty($dirname)) {
1777 1
            $dirname = $this->isModule() ? $this->module->getVar('dirname') : 'system';
1778
        }
1779
1780 64
        if (isset($this->moduleConfigs[$dirname][$key])) {
1781 61
            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 27
    public function getModuleConfigs($dirname = '')
1800
    {
1801 27
        $dirname = trim($dirname);
1802 27
        if (empty($dirname)) {
1803 2
            $dirname = $this->isModule() ? $this->module->getVar('dirname') : 'system';
1804
        }
1805 27
        if (isset($this->moduleConfigs[$dirname])) {
1806 26
            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 1
    public function getBaseDomain($url, $includeSubdomain = false)
1885
    {
1886 1
        $url=mb_strtolower($url, 'UTF-8');
1887
1888 1
        $host = parse_url($url, PHP_URL_HOST);
1889 1
        if (empty($host)) {
1890 1
            $host = parse_url($url, PHP_URL_PATH); // bare host name
1891 1
            if (empty($host)) {
1892
                return null;
1893
            }
1894
        }
1895
1896
        // check for exceptions, localhost and ip address (v4 & v6)
1897 1
        if ($host==='localhost') {
1898 1
            return $host;
1899
        }
1900
        // Check for IPV6 URL (see http://www.ietf.org/rfc/rfc2732.txt)
1901
        // strip brackets before validating
1902 1
        if (substr($host, 0, 1)==='[' && substr($host, -1)===']') {
1903 1
            $host = substr($host, 1, (strlen($host)-2));
1904
        }
1905 1
        if (filter_var($host, FILTER_VALIDATE_IP)) {
1906 1
            return $host;
1907
        }
1908
1909 1
        $regdom = new \Geekwright\RegDom\RegisteredDomain();
1910 1
        $regHost = $regdom->getRegisteredDomain($host);
1911 1
        if (null === $regHost) {
1912 1
            return null;
1913
        }
1914 1
        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 13
    public function deprecated($message)
1960
    {
1961 13
        $message = $this->logger()->sanitizePath($message);
1962 13
        $this->events()->triggerEvent('core.deprecated', array($message));
1963 13
    }
1964
1965
    /**
1966
     * Support for disabling error reporting
1967
     *
1968
     * @return void
1969
     */
1970 3
    public function disableErrorReporting()
1971
    {
1972
        //error_reporting(0);
1973 3
        $this->events()->triggerEvent('core.disableerrorreporting');
1974 3
    }
1975
}
1976