Completed
Pull Request — master (#462)
by Richard
18:07
created

Xoops::getHandlerGroupPermission()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1
Metric Value
dl 0
loc 4
rs 10
ccs 2
cts 2
cp 1
cc 1
eloc 2
nc 1
nop 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.

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 Xoops\Core\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 Psr\Log\LogLevel;
20
21
/**
22
 * XOOPS
23
 *
24
 * @category  Xoops
25
 * @package   Xoops
26
 * @author    trabis <[email protected]>
27
 * @author    formuss
28
 * @author    Richard Griffith <[email protected]>
29
 * @copyright 2011-2015 XOOPS Project (http://xoops.org)
30
 * @license   GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
31
 * @link      http://xoops.org
32
 */
33
class Xoops
0 ignored issues
show
Coding Style introduced by
Since you have declared the constructor as private, maybe you should also declare the class as final.
Loading history...
34
{
35
    const VERSION = 'XOOPS 2.6.0-Alpha 3';
36
37
    /**
38
     * @var null|Xoops\Core\Session\Manager
39
     */
40
    public $sessionManager = null;
41
42
    /**
43
     * @var null|XoopsModule
44
     */
45
    public $module = null;
46
47
    /**
48
     * @var array
49
     */
50
    public $config = array();
51
52
    /**
53
     * @var array
54
     */
55
    public $moduleConfig = array();
56
57
    /**
58
     * @var array
59
     */
60
    public $moduleDirname = '';
61
62
    /**
63
     * @var XoopsUser|string
64
     */
65
    public $user = '';
66
67
    /**
68
     * @var bool
69
     */
70
    public $userIsAdmin = false;
71
72
    /**
73
     * @var array
74
     */
75
    public $option = array();
76
77
    /**
78
     * @var XoopsTpl|null
79
     */
80
    private $tpl = null;
81
82
    /**
83
     * @var XoopsTheme|null
84
     */
85
    private $theme = null;
86
87
    /**
88
     * @var array
89
     */
90
    public $paths = array(
91
        'XOOPS'  => array(), 'www' => array(), 'var' => array(), 'lib' => array(), 'modules' => array(),
92
        'themes' => array(), 'media' => array()
93
    );
94
95
    /**
96
     * @var string
97
     */
98
    public $tpl_name = '';
99
100
    /**
101
     * @var HandlerFactory
102
     */
103
    private $handlerFactory;
104
105
    /**
106
     * @var array
107
     */
108
    private $kernelHandlers = array();
109
110
    /**
111
     * @var array
112
     */
113
    private $moduleHandlers = array();
114
115
    /**
116
     * @var null|array
117
     */
118
    private $activeModules = null;
119
120
    /**
121
     * @var array
122
     */
123
    private $moduleConfigs = array();
124
125
    /**
126
     * @var bool
127
     */
128
    public $isAdminSide = false;
129
130
    /**
131
     * Actual Xoops OS
132
     */
133
    private function __construct()
134
    {
135
        $root = \XoopsBaseConfig::get('root-path');
136
        $lib = \XoopsBaseConfig::get('lib-path');
137
        $var = \XoopsBaseConfig::get('var-path');
138
139
        $url = \XoopsBaseConfig::get('url');
140
141
        $this->paths['www'] = array($root, $url);
142
        $this->paths['var'] = array($var, null);
143
        $this->paths['lib'] = array($lib, $url . '/browse.php');
144
        $this->paths['XOOPS'] = array($lib, $url . '/browse.php');
145
        $this->paths['assets'] = array(\XoopsBaseConfig::get('asset-path'), \XoopsBaseConfig::get('asset-url'));
146
        $this->paths['images'] = array($root . '/images', $url . '/images');
147
        $this->paths['language'] = array($root . '/language', $url . '/language');
148
        $this->paths['locale'] = array($root . '/locale', $url . '/locale');
149
        $this->paths['media'] = array(\XoopsBaseConfig::get('media-path'), \XoopsBaseConfig::get('media-url'));
150
        $this->paths['modules'] = array($root . '/modules', $url . '/modules');
151
        $this->paths['themes'] = array(\XoopsBaseConfig::get('themes-path'), \XoopsBaseConfig::get('themes-url'));
152
        $this->paths['uploads'] = array(\XoopsBaseConfig::get('uploads-path'), \XoopsBaseConfig::get('uploads-url'));
153
154
        $this->pathTranslation();
155
    }
156
157
    /**
158
     * Access the only instance of this class
159
     *
160
     * @return Xoops
161
     */
162 385
    public static function getInstance()
163
    {
164 385
        static $instance;
165 385
        if (!isset($instance)) {
166
            $class = __CLASS__;
167
            $instance = new $class();
168
        }
169 385
        return $instance;
170
    }
171
172
    /**
173
     * get database connection instance
174
     *
175
     * @return Xoops\Core\Database\Connection
176
     */
177 138
    public function db()
178
    {
179 138
        return \Xoops\Core\Database\Factory::getConnection();
180
    }
181
182
    /**
183
     * get a \Xoops\Core\Cache\Access object for a named cache
184
     *
185
     * @param string $cacheName a named cached pool
186
     *
187
     * @return \Xoops\Core\Cache\Access
188
     */
189 25
    public function cache($cacheName = 'default')
190
    {
191 25
        static $cacheManager;
192
193 25
        if (!isset($cacheManager)) {
194
            $cacheManager = new \Xoops\Core\Cache\CacheManager();
195
        }
196
197 25
        return $cacheManager->getCache($cacheName);
198
    }
199
200
    /**
201
     * get the system logger instance
202
     *
203
     * @return \Xoops\Core\Logger
204
     */
205 17
    public function logger()
206
    {
207 17
        return \Xoops\Core\Logger::getInstance();
208
    }
209
210
211
    /**
212
     * get the event processor
213
     *
214
     * @return \Xoops\Core\Events instance
215
     */
216 129
    public function events()
217
    {
218 129
        return \Xoops\Core\Events::getInstance();
219
    }
220
221
    /**
222
     * Deprecated - use events() instead
223
     *
224
     * @return XoopsPreload
225
     */
226 16
    public function preload()
227
    {
228 16
        return $this->events();
229
    }
230
231
    /**
232
     * get the asset utility
233
     *
234
     * @return Xoops\Core\Assets instance
235
     */
236 4
    public function assets()
237
    {
238 4
        static $instance;
239 4
        if (!isset($instance)) {
240 1
            $instance = new \Xoops\Core\Assets;
241 1
        }
242 4
        return $instance;
243
    }
244
245
    /**
246
     * get the service manager
247
     *
248
     * @param string $service - service name
249
     *
250
     * @return Xoops\Core\Service\Provider instance
251
     */
252 4
    public function service($service)
253
    {
254 4
        static $instance;
255 4
        if (!isset($instance)) {
256 1
            $instance = \Xoops\Core\Service\Manager::getInstance();
257 1
        }
258 4
        return $instance->locate($service);
259
    }
260
261
    /**
262
     * provide a common registry instance
263
     *
264
     * @return Xoops\Core\Registry
265
     */
266 4
    public function registry()
267
    {
268 3
        static $instance;
269 3
        if (!isset($instance)) {
270 1
            $instance = new \Xoops\Core\Registry();
271 1
        }
272 4
        return $instance;
273
    }
274
275
    /**
276
     * get security instance
277
     *
278
     * @return XoopsSecurity
279
     */
280 4
    public function security()
281
    {
282 4
        static $instance;
283 4
        if (!isset($instance)) {
284
            $instance = new \Xoops\Core\Security();
285
        }
286 4
        return $instance;
287
    }
288
289
    /**
290
     * get current template engine
291
     *
292
     * @return null|XoopsTpl
293
     */
294 9
    public function tpl()
295
    {
296 9
        return $this->tpl;
297
    }
298
299
    /**
300
     * set current template engine
301
     *
302
     * @param XoopsTpl $tpl template engine
303
     *
304
     * @return XoopsTpl
305
     */
306 6
    public function setTpl(XoopsTpl $tpl)
307
    {
308 6
        return $this->tpl = $tpl;
309
    }
310
311
    /**
312
     * establish the theme
313
     *
314
     * @param null|string $tpl_name base template
315
     *
316
     * @return null|XoopsTheme
317
     */
318 6
    public function theme($tpl_name = null)
0 ignored issues
show
Coding Style introduced by
theme uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
319
    {
320 6
        if (!isset($this->theme)) {
321
            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...
322
                $tpl_info = $this->getTplInfo($tpl_name);
323
                $this->tpl_name = $tpl_info['tpl_name'];
324
            } else {
325
                $tpl_name = 'module:system/system_dummy.tpl';
326
                $tpl_info = $this->getTplInfo($tpl_name);
327
                $this->tpl_name = $tpl_info['tpl_name'];
328
            }
329
            if (!$this->isAdminSide) {
330
                $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...
331
                $xoopsThemeFactory = new \Xoops\Core\Theme\Factory();
332
                $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...
333
                $xoopsThemeFactory->defaultTheme = $this->getConfig('theme_set');
334
                $this->setTheme($xoopsThemeFactory->createInstance(array('contentTemplate' => $this->tpl_name)));
335
            } else {
336
                $adminThemeFactory = new \Xoops\Core\Theme\AdminFactory();
337
                $this->setTheme($adminThemeFactory->createInstance(array(
338
                    'folderName'      => 'default', 'themesPath' => 'modules/system/themes',
339
                    'contentTemplate' => $this->tpl_name
340
                )));
341
                //$this->theme()->loadLocalization('admin');
342
                list($cssAssets, $jsAssets) = $this->theme()->getLocalizationAssets('admin');
343
                if (!empty($cssAssets)) {
344
                    $this->theme()->addBaseStylesheetAssets($cssAssets);
345
                }
346
                if (!empty($jsAssets)) {
347
                    $this->theme()->addBaseScriptAssets($jsAssets);
348
                }
349
            }
350
        } else {
351 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...
352
                $tpl_info = $this->getTplInfo($tpl_name);
353
                $this->tpl_name = $tpl_info['tpl_name'];
354
                $this->theme->contentTemplate = $this->tpl_name;
355
            }
356
        }
357 6
        $GLOBALS['xoTheme'] = $this->theme;
358 6
        return $this->theme;
359
    }
360
361
    /**
362
     * set theme
363
     *
364
     * @param XoopsTheme $theme theme
365
     *
366
     * @return XoopsTheme
367
     */
368 4
    public function setTheme(XoopsTheme $theme)
369
    {
370 4
        return $this->theme = $theme;
371
    }
372
373
    /**
374
     * Convert a XOOPS path to a physical one
375
     *
376
     * @param string $url     url to derive path from
377
     * @param bool   $virtual virtual
378
     *
379
     * @return string
380
     */
381 31
    public function path($url, $virtual = false)
382
    {
383 31
        $url = $this->normalizePath($url);
384 31
        $rootPath = $this->normalizePath(\XoopsBaseConfig::get('root-path') . '/');
385 31
        if (0 === strpos($url, $rootPath)) {
386
            $url = substr($url, strlen($rootPath));
387
        }
388
        //$url = ltrim($url, '/');
389 31
        $parts = explode('/', $url, 2);
390 31
        $root = isset($parts[0]) ? $parts[0] : '';
391 31
        $path = isset($parts[1]) ? $parts[1] : '';
392 31
        if (!isset($this->paths[$root])) {
393 5
            list($root, $path) = array('www', $url);
394 5
        }
395 31
        if (!$virtual) { // Returns a physical path
396 29
            $path = $this->paths[$root][0] . '/' . $path;
397
            //$path = str_replace('/', DIRECTORY_SEPARATOR, $path);
398 29
            return $path;
399
        }
400 5
        return !isset($this->paths[$root][1]) ? '' : ($this->paths[$root][1] . '/' . $path);
401
    }
402
403
    /**
404
     * Convert path separators to unix style
405
     *
406
     * @param string $path path to normalize
407
     *
408
     * @return string normalized path
409
     */
410 31
    public function normalizePath($path)
411
    {
412 31
        return str_replace('\\', '/', $path);
413
    }
414
415
    /**
416
     * Convert a XOOPS path to an URL
417
     *
418
     * @param string $url path (or url)
419
     *
420
     * @return string
421
     */
422 5
    public function url($url)
423
    {
424 5
        return (false !== strpos($url, '://') ? $url : $this->path($url, true));
425
    }
426
427
    /**
428
     * Build an URL with the specified request params
429
     *
430
     * @param string $url    base url
431
     * @param array  $params parameters to add to the url
432
     *
433
     * @return string
434
     */
435 1
    public function buildUrl($url, $params = array())
0 ignored issues
show
Coding Style introduced by
buildUrl uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
436
    {
437 1
        if ($url === '.') {
438 1
            $url = $_SERVER['REQUEST_URI'];
439 1
        }
440 1
        $split = explode('?', $url);
441 1
        if (count($split) > 1) {
442 1
            list($url, $query) = $split;
443 1
            parse_str($query, $query);
444 1
            $params = array_merge($query, $params);
445 1
        }
446 1
        if (!empty($params)) {
447 1
            foreach ($params as $k => $v) {
448 1
                $params[$k] = $k . '=' . rawurlencode($v);
449 1
            }
450 1
            $url .= '?' . implode('&', $params);
451 1
        }
452 1
        return $url;
453
    }
454
455
    /**
456
     * Check if a path exists
457
     *
458
     * @param string $path       filesystem path
459
     * @param string $error_type error level i.e. Psr\Log\LogLevel
460
     *
461
     * @return string|false
462
     */
463 2
    public function pathExists($path, $error_type)
464
    {
465 2
        if (XoopsLoad::fileExists($path)) {
466 1
            return $path;
467
        } else {
468 1
            $this->logger()->log(
469 1
                LogLevel::WARNING,
470 1
                \XoopsLocale::E_FILE_NOT_FOUND,
471 1
                array($path, $error_type)
472 1
            );
473
474
            //trigger_error(XoopsLocale::E_FILE_NOT_FOUND, $error_type);
475 1
            return false;
476
        }
477
    }
478
479
    /**
480
     * Start gzipCompression output buffer
481
     *
482
     * @return void
483
     */
484 1
    public function gzipCompression()
0 ignored issues
show
Coding Style introduced by
gzipCompression uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
485
    {
486
        /**
487
         * Disable gzip compression if PHP is run under CLI mode and needs refactored to work correctly
488
         */
489 1
        if (empty($_SERVER['SERVER_NAME']) || substr(PHP_SAPI, 0, 3) === 'cli') {
490 1
            $this->setConfig('gzip_compression', 0);
491 1
        }
492
493 1
        if ($this->getConfig('gzip_compression') == 1
494 1
            && extension_loaded('zlib')
495 1
            && !ini_get('zlib.output_compression')
496 1
        ) {
497
            if (@ini_get('zlib.output_compression_level') < 0) {
498
                ini_set('zlib.output_compression_level', 6);
499
            }
500
            ob_start('ob_gzhandler');
501
        }
502 1
    }
503
504
    /**
505
     * Translate a path
506
     *
507
     * @return void
508
     */
509 1
    public function pathTranslation()
0 ignored issues
show
Coding Style introduced by
pathTranslation uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
510
    {
511
        /**
512
         * *#@+
513
         * Host abstraction layer
514
         */
515 1
        if (!isset($_SERVER['PATH_TRANSLATED']) && isset($_SERVER['SCRIPT_FILENAME'])) {
516 1
            $_SERVER['PATH_TRANSLATED'] = $_SERVER['SCRIPT_FILENAME']; // For Apache CGI
517 1
        } else {
518 1
            if (isset($_SERVER['PATH_TRANSLATED']) && !isset($_SERVER['SCRIPT_FILENAME'])) {
519 1
                $_SERVER['SCRIPT_FILENAME'] = $_SERVER['PATH_TRANSLATED']; // For IIS/2K now I think :-(
520 1
            }
521
        }
522
        /**
523
         * User Mulitbytes
524
         */
525 1 View Code Duplication
        if (empty($_SERVER['REQUEST_URI'])) { // Not defined by IIS
526
            // Under some configs, IIS makes SCRIPT_NAME point to php.exe :-(
527 1
            if (!($_SERVER['REQUEST_URI'] = @$_SERVER['PHP_SELF'])) {
528 1
                $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'];
529 1
            }
530 1
            if (isset($_SERVER['QUERY_STRING'])) {
531 1
                $_SERVER['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING'];
532 1
            }
533 1
        }
534 1
    }
535
536
    /**
537
     * Select Theme
538
     *
539
     * @return void
540
     */
541 1
    public function themeSelect()
0 ignored issues
show
Coding Style introduced by
themeSelect uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
542
    {
543 1
        $xoopsThemeSelect = Request::getString('xoops_theme_select', '', 'POST');
544 1
        if (!empty($xoopsThemeSelect) && in_array($xoopsThemeSelect, $this->getConfig('theme_set_allowed'))) {
545 1
            $this->setConfig('theme_set', $xoopsThemeSelect);
546 1
            $_SESSION['xoopsUserTheme'] = $xoopsThemeSelect;
547 1
        } else {
548 1
            if (!empty($_SESSION['xoopsUserTheme'])
549 1
                && in_array($_SESSION['xoopsUserTheme'], $this->getConfig('theme_set_allowed'))
550 1
            ) {
551 1
                $this->setConfig('theme_set', $_SESSION['xoopsUserTheme']);
552 1
            }
553
        }
554 1
    }
555
556
    /**
557
     * Gets module, type and file from a tpl name
558
     *
559
     * @param string $tpl_name in form type:module/filename.tpl
560
     *
561
     * @return array|false associative array of 'tpl_name', 'type', 'module', 'file'
562
     *                     or false on error
563
     */
564 9
    public function getTplInfo($tpl_name)
565
    {
566 9
        $parts = array();
567 9
        $matched = preg_match('#(\w+):(\w+)/(.*)$#', $tpl_name, $parts);
568 9
        if ($matched) {
569 8
            $names = array('tpl_name', 'type', 'module', 'file');
570 8
            $ret = array();
571 8
            for ($i=0; $i<4; ++$i) {
572 8
                $ret[$names[$i]] = $parts[$i];
573 8
            }
574 8
        } else {
575
            // this should be eliminated
576 1
            $this->events()->triggerEvent('debug.log', "Sloppy template: " . $tpl_name);
577 1
            $ret = array();
578 1
            $ret['type'] = $this->isAdminSide ? 'admin' : 'module';
579 1
            $info = explode(':', $tpl_name);
580 1
            if (count($info) == 2) {
581 1
                $ret['type'] = $info[0];
582 1
                $tpl_name = str_replace($ret['type'] . ':', '', $tpl_name);
583 1
            }
584
585 1
            if ($ret['type'] === 'db') {
586
                //For legacy compatibility
587 1
                $ret['type'] = $this->isAdminSide ? 'admin' : 'module';
588 1
            }
589
590 1
            $info = explode('|', $tpl_name);
591 1
            if (count($info) == 2) {
592
                $ret['module'] = $info[0];
593
                $ret['file'] = $info[1];
594
            } else {
595 1
                $ret['module'] = 'system';
596 1
                $ret['file'] = $tpl_name;
597 1
                if ($this->isModule()) {
598
                    $ret['module'] = $this->module->getVar('dirname', 'n');
599
                }
600
            }
601 1
            $ret['tpl_name'] = $ret['type'] . ':' . $ret['module'] . '/' . $ret['file'];
602
        }
603
604 9
        return $ret;
605
    }
606
607
    /**
608
     * Render Header
609
     *
610
     * @param string|null $tpl_name template name
611
     *
612
     * @return null|boolean
613
     */
614
    public function header($tpl_name = null)
615
    {
616
        static $included = false;
617
        if ($included) {
618
            return false;
619
        }
620
        $included = true;
621
622
        $this->events()->triggerEvent('core.header.start');
623
624
        //For legacy
625
        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...
626
            $tpl_name = $this->option['template_main'];
627
            $this->deprecated(
628
                'XoopsOption \'template_main\' is deprecated, please use $xoops->header(\'templatename.tpl\') instead'
629
            );
630
        }
631
        $this->theme($tpl_name);
632
        $this->tpl()->assign('xoops', $this);
633
634
        if ($this->isAdminSide) {
635
            $this->events()->triggerEvent('system.class.gui.header');
636
            include_once $this->path('modules/system/themes/default/default.php');
637
            $gui = new XoopsGuiDefault();
638
            $gui->header();
639
        } else {
640
            $this->events()->triggerEvent('core.header.addmeta');
641
            // Temporary solution for start page redirection
642
            if (defined("XOOPS_STARTPAGE_REDIRECTED")) {
643
                $smarty = $repeat = null;
644
                $this->theme()->headContent(
645
                    null,
646
                    "<base href='" . \XoopsBaseConfig::get('url') . '/modules/'
647
                    . $this->getConfig('startpage') . "/' />",
648
                    $smarty,
649
                    $repeat
650
                );
651
            }
652
653
            // Sets cache time
654
            if ($this->isModule()) {
655
                $cache_times = $this->getConfig('module_cache');
656
                $this->theme()->contentCacheLifetime =
657
                    isset($cache_times[$this->module->getVar('mid')]) ? $cache_times[$this->module->getVar('mid')] : 0;
658
                // Tricky solution for setting cache time for homepage
659
            } else {
660
                if ($this->tpl_name === 'module:system/system_homepage.tpl') {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
661
                    // $this->theme->contentCacheLifetime = 604800;
662
                }
663
            }
664
            $this->events()->triggerEvent('core.header.checkcache');
665
            if ($this->theme()->checkCache()) {
666
                exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The method header() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
667
            }
668
        }
669
670
        if (!isset($this->tpl_name) && $this->isModule()) {
671
            ob_start();
672
        }
673
674
        $this->events()->triggerEvent('core.header.end');
675
        return true;
676
    }
677
678
    /**
679
     * Render Footer
680
     *
681
     * @return false|null
682
     */
683
    public function footer()
684
    {
685
        static $included = false;
686
        if ($included) {
687
            return false;
688
        }
689
        $included = true;
690
691
        $this->events()->triggerEvent('core.footer.start');
692
693
        if (!headers_sent()) {
694
            header('Content-Type:text/html; charset=' . XoopsLocale::getCharset());
695
            header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
696
            header('Cache-Control: private, no-cache');
697
            header('Pragma: no-cache');
698
        }
699
700
        if (isset($this->option['template_main'])
701
            && $this->option['template_main'] != $this->theme()->contentTemplate
702
        ) {
703
            trigger_error("xoopsOption[template_main] should be defined before including header.php", E_USER_WARNING);
704
            $this->theme()->contentTemplate = $this->tpl_name;
705
        }
706
        $this->theme()->render();
707
        $this->events()->triggerEvent('core.footer.end');
708
        exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The method footer() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
709
    }
710
711
    /**
712
     * Check if a module is set
713
     *
714
     * @return bool
715
     */
716 12
    public function isModule()
717
    {
718 12
        return $this->module instanceof XoopsModule ? true : false;
719
    }
720
721
    /**
722
     * Check if a user is set
723
     *
724
     * @return bool
725
     */
726 7
    public function isUser()
727
    {
728 7
        return $this->user instanceof XoopsUser ? true : false;
729
    }
730
731
    /**
732
     * Check if user is admin
733
     *
734
     * @return bool
735
     */
736 1
    public function isAdmin()
737
    {
738 1
        return $this->userIsAdmin;
739
    }
740
741
    /**
742
     * Get handler of Block
743
     *
744
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
745
     *
746
     * @return \Xoops\Core\Kernel\Handlers\XoopsBlockHandler
747
     */
748 4
    public function getHandlerBlock($optional = false)
749
    {
750 4
        return $this->getHandler('Block', $optional);
751
    }
752
753
    /**
754
     * Get handler of Block Module Link
755
     *
756
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
757
     *
758
     * @return \Xoops\Core\Kernel\Handlers\XoopsBlockModuleLinkHandler
759
     */
760 1
    public function getHandlerBlockModuleLink($optional = false)
761
    {
762 1
        return $this->getHandler('BlockModuleLink', $optional);
763
    }
764
765
    /**
766
     * Get handler of Config
767
     *
768
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
769
     *
770
     * @return \Xoops\Core\Kernel\Handlers\XoopsConfigHandler
771
     */
772 1
    public function getHandlerConfig($optional = false)
773
    {
774 1
        return $this->getHandler('Config', $optional);
775
    }
776
777
    /**
778
     * Get handler of Config  Item
779
     *
780
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
781
     *
782
     * @return \Xoops\Core\Kernel\Handlers\XoopsConfigItemHandler
783
     */
784 18
    public function getHandlerConfigItem($optional = false)
785
    {
786 18
        return $this->getHandler('ConfigItem', $optional);
787
    }
788
789
    /**
790
     * Get handler of Config Option
791
     *
792
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
793
     *
794
     * @return \Xoops\Core\Kernel\Handlers\XoopsConfigOptionHandler
795
     */
796 18
    public function getHandlerConfigOption($optional = false)
797
    {
798 18
        return $this->getHandler('ConfigOption', $optional);
799
    }
800
801
    /**
802
     * Get handler of Group
803
     *
804
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
805
     *
806
     * @return \Xoops\Core\Kernel\Handlers\XoopsGroupHandler
807
     */
808 2
    public function getHandlerGroup($optional = false)
809
    {
810 2
        return $this->getHandler('Group', $optional);
811
    }
812
813
    /**
814
     * Get handler of Group Permission
815
     *
816
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
817
     *
818
     * @return \Xoops\Core\Kernel\Handlers\XoopsGroupPermHandler
819
     */
820 4
    public function getHandlerGroupPermission($optional = false)
821
    {
822 4
        return $this->getHandler('GroupPerm', $optional);
823
    }
824
825
    /**
826
     * Get handler of Member
827
     *
828
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
829
     *
830
     * @return \Xoops\Core\Kernel\Handlers\XoopsMemberHandler
831
     */
832 15
    public function getHandlerMember($optional = false)
833
    {
834 15
        return $this->getHandler('Member', $optional);
835
    }
836
837
    /**
838
     * Get handler of Membership
839
     *
840
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
841
     *
842
     * @return \Xoops\Core\Kernel\Handlers\XoopsMembershipHandler
843
     */
844 2
    public function getHandlerMembership($optional = false)
845
    {
846 2
        return $this->getHandler('Membership', $optional);
847
    }
848
849
    /**
850
     * Get handler of Module
851
     *
852
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
853
     *
854
     * @return \Xoops\Core\Kernel\Handlers\XoopsModuleHandler
855
     */
856 10
    public function getHandlerModule($optional = false)
857
    {
858 10
        return $this->getHandler('Module', $optional);
859
    }
860
861
    /**
862
     * Get handler of Online
863
     *
864
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
865
     *
866
     * @return \Xoops\Core\Kernel\Handlers\XoopsOnlineHandler
867
     */
868 2
    public function getHandlerOnline($optional = false)
869
    {
870 2
        return $this->getHandler('Online', $optional);
871
    }
872
873
    /**
874
     * Get handler of Private Message
875
     *
876
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
877
     *
878
     * @return \Xoops\Core\Kernel\Handlers\XoopsPrivateMessageHandler
879
     */
880 1
    public function getHandlerPrivateMessage($optional = false)
881
    {
882 1
        return $this->getHandler('Privmessage', $optional);
883
    }
884
885
    /**
886
     * Get the session manager
887
     *
888
     * @return Xoops\Core\Session\Manager
889
     */
890 1
    public function session()
891
    {
892 1
        if ($this->sessionManager === null) {
893 1
            $this->sessionManager = new \Xoops\Core\Session\Manager();
894 1
        }
895 1
        return $this->sessionManager;
896
    }
897
898
    /**
899
     * Get handler of Template File
900
     *
901
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
902
     *
903
     * @return \Xoops\Core\Kernel\Handlers\XoopsTplFileHandler
904
     */
905 2
    public function getHandlerTplFile($optional = false)
906
    {
907 2
        return $this->getHandler('tplfile', $optional);
908
    }
909
910
    /**
911
     * Get handler of Template Set
912
     *
913
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
914
     *
915
     * @return \Xoops\Core\Kernel\Handlers\XoopsTplSetHandler
916
     */
917 1
    public function getHandlerTplSet($optional = false)
918
    {
919 1
        return $this->getHandler('Tplset', $optional);
920
    }
921
922
    /**
923
     * Get handler of User
924
     *
925
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
926
     *
927
     * @return \Xoops\Core\Kernel\Handlers\XoopsUserHandler
928
     */
929 2
    public function getHandlerUser($optional = false)
930
    {
931 2
        return $this->getHandler('user', $optional);
932
    }
933
934
    /**
935
     * Get handler
936
     *
937
     * @param string  $name     name of handler
938
     * @param boolean $optional true if failure to load handler should be considered a warning, not an error
939
     *
940
     * @return XoopsObjectHandler|XoopsPersistableObjectHandler|null
941
     */
942 59
    protected function getHandler($name, $optional = false)
943
    {
944 59
        if (!isset($this->kernelHandlers[$name])) {
945 6
            if (!isset($this->handlerFactory)) {
946
                $this->handlerFactory = HandlerFactory::getInstance();
947
            }
948 6
            $handler = $this->handlerFactory->newSpec()->scheme('kernel')->name($name)->optional($optional)->build();
949 6
            if ($handler === null) {
950
                $this->logger()->log(
951
                    \Psr\Log\LogLevel::WARNING,
952
                    sprintf('A handler for %s is not available', $name)
953
                );
954
            }
955 6
            $this->kernelHandlers[$name] = $handler;
956 6
        }
957
958 59
        return $this->kernelHandlers[$name];
959
    }
960
961
    /**
962
     * Get Module Handler
963
     *
964
     * @param string|null $name       name of handler
965
     * @param string|null $module_dir dirname of module
966
     * @param boolean     $optional   true if failure to load handler should be considered a warning, not an error
967
     *
968
     * @return XoopsObjectHandler|XoopsPersistableObjectHandler|bool
969
     */
970 2
    public function getModuleHandler($name = null, $module_dir = null, $optional = false)
971
    {
972
        // if $module_dir is not specified
973 2
        if (!isset($module_dir)) {
974
            // if a module is loaded
975
            if ($this->module instanceof XoopsModule) {
976
                $module_dir = $this->module->getVar('dirname', 'n');
977
            } else {
978
                trigger_error('No Module is loaded', E_USER_ERROR);
979
            }
980
        } else {
981 2
            $module_dir = trim($module_dir);
982
        }
983 2
        $name = (!isset($name)) ? $module_dir : trim($name);
984 2
        if (!isset($this->moduleHandlers[$module_dir][$name])) {
985 2
            if (!isset($this->handlerFactory)) {
986
                $this->handlerFactory = HandlerFactory::getInstance();
987
            }
988 2
            $handler = $this->handlerFactory->create($name, $module_dir, $optional);
989 2
            if ($handler === null) {
990
                $this->logger()->log(
991
                    LogLevel::WARNING,
992
                    sprintf('No handler for %s exists in module %s', $name, $module_dir)
993
                );
994
            }
995 2
            $this->moduleHandlers[$module_dir][$name] = $handler;
996 2
        }
997 2
        return $this->moduleHandlers[$module_dir][$name];
998
    }
999
1000
    /**
1001
     * Get Module Form
1002
     *
1003
     * @param XoopsObject $obj        object to populate form
1004
     * @param string      $name       name of form
1005
     * @param string      $module_dir dirname of associated module
1006
     *
1007
     * @return Xoops\Form\Form|bool
1008
     */
1009 1
    public function getModuleForm($obj, $name, $module_dir = null)
1010
    {
1011 1
        if (empty($name)) {
1012 1
            return false;
1013
        }
1014
        if (empty($module_dir)) {
1015
            if ($this->isModule()) {
1016
                $module_dir = $this->module->getVar('dirname', 'n');
1017
            } else {
1018
                return false;
1019
            }
1020
        }
1021
        if (XoopsLoad::fileExists(
1022
            $hnd_file = \XoopsBaseConfig::get('root-path') . "/modules/{$module_dir}/class/form/{$name}.php"
1023
        )) {
1024
            include_once $hnd_file;
1025
            $class = ucfirst(strtolower($module_dir)) . ucfirst($name) . 'Form';
1026
            if (class_exists($class)) {
1027
                $instance = new $class($obj);
1028
                if ($instance instanceof \Xoops\Form\Form) {
1029
                    return $instance;
1030
                }
1031
            }
1032
        }
1033
        return false;
1034
    }
1035
1036
    /**
1037
     * Get Module Helper
1038
     *
1039
     * @param string $dirname dirname of module
1040
     *
1041
     * @return bool|Xoops\Module\Helper\HelperAbstract
1042
     */
1043 1
    public static function getModuleHelper($dirname)
1044
    {
1045 1
        return \Xoops\Module\Helper::getHelper($dirname);
1046
    }
1047
1048
    /**
1049
     * XOOPS language loader wrapper
1050
     * Temporary solution, not encouraged to use
1051
     *
1052
     * @param string $name     Name of language file to be loaded, without extension
1053
     * @param mixed  $domain   string: Module dirname; global language file will be loaded if
1054
     *                           $domain is set to 'global' or not specified
1055
     *                          array:  example; array('Frameworks/moduleclasses/moduleadmin')
1056
     * @param string $language Language to be loaded, current language content will be loaded if not specified
1057
     *
1058
     * @return  boolean
1059
     */
1060 7
    public function loadLanguage($name, $domain = '', $language = null)
1061
    {
1062 7
        if (empty($name)) {
1063 1
            return false;
1064
        }
1065
1066 7
        $language = empty($language) ? XoopsLocale::getLegacyLanguage() : $language;
1067
        // expanded domain to multiple categories, e.g. module:Fsystem, framework:filter, etc.
1068 7 View Code Duplication
        if ((empty($domain) || 'global' === $domain)) {
1069 1
            $path = '';
1070 1
        } else {
1071 6
            $path = (is_array($domain)) ? array_shift($domain) . '/' : "modules/{$domain}/";
1072
        }
1073 7
        $path .= 'language';
1074
1075 7
        if (!XoopsLoad::fileExists($file = $this->path("{$path}/{$language}/{$name}.php"))) {
1076 6
            if (!XoopsLoad::fileExists($file = $this->path("{$path}/english/{$name}.php"))) {
1077 6
                return false;
1078
            }
1079
        }
1080 1
        $ret = include_once $file;
1081 1
        return $ret;
1082
    }
1083
1084
    /**
1085
     * loadLocale
1086
     *
1087
     * @param string $domain Module dirname; global language file will be loaded if set to 'global' or not specified
1088
     * @param string $locale Locale to be loaded, current language content will be loaded if not specified
1089
     *
1090
     * @return  boolean
1091
     */
1092 4
    public static function loadLocale($domain = null, $locale = null)
1093
    {
1094 4
        return \Xoops\Locale::loadLocale($domain, $locale);
1095
    }
1096
1097
    /**
1098
     * Translate a key value
1099
     *
1100
     * @param string $key     constant name
1101
     * @param string $dirname dirname of module (domain)
1102
     *
1103
     * @return string
1104
     */
1105 1
    public function translate($key, $dirname = 'xoops')
1106
    {
1107 1
        return \Xoops\Locale::translate($key, $dirname);
1108
    }
1109
1110
    /**
1111
     * Get active modules from cache file
1112
     *
1113
     * @return array
1114
     */
1115 10
    public function getActiveModules()
1116
    {
1117 10
        if (is_array($this->activeModules)) {
1118 10
            return $this->activeModules;
1119
        }
1120
1121
        try {
1122
            if (!$this->activeModules = $this->cache()->read('system/modules/active')) {
1123
                $this->activeModules = $this->setActiveModules();
1124
            }
1125
        } catch (\Exception $e) {
1126
            $this->activeModules = array();
1127
        }
1128
        return $this->activeModules;
1129
    }
1130
1131
    /**
1132
     * Write active modules to cache file
1133
     *
1134
     * @return array
1135
     */
1136 1
    public function setActiveModules()
1137
    {
1138 1
        $module_handler = $this->getHandlerModule();
1139 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...
1140 1
        $modules_active = array();
1141 1
        foreach ($modules_array as $module) {
1142 1
            $modules_active[$module['mid']] = $module['dirname'];
1143 1
        }
1144 1
        $this->cache()->write('system/modules/active', $modules_active);
1145 1
        return $modules_active;
1146
    }
1147
1148
    /**
1149
     * Checks is module is installed and active
1150
     *
1151
     * @param string $dirname module directory
1152
     *
1153
     * @return bool
1154
     */
1155 8
    public function isActiveModule($dirname)
1156
    {
1157 8
        if (isset($dirname) && in_array($dirname, $this->getActiveModules())) {
1158 3
            return true;
1159
        }
1160 6
        return false;
1161
    }
1162
1163
    /**
1164
     * get module object from module name (dirname)
1165
     *
1166
     * @param string $dirname dirname of the module
1167
     *
1168
     * @return bool|XoopsModule
1169
     */
1170 4 View Code Duplication
    public function getModuleByDirname($dirname)
1171
    {
1172 4
        $key = "system/module/dirname/{$dirname}";
1173 4
        if (!$module = $this->cache()->read($key)) {
1174 4
            $module = $this->getHandlerModule()->getByDirname($dirname);
1175 4
            $this->cache()->write($key, $module);
1176 4
        }
1177 4
        return $module;
1178
    }
1179
1180
    /**
1181
     * Get Module By Id
1182
     *
1183
     * @param int $id Id of the module
1184
     *
1185
     * @return bool|XoopsModule
1186
     */
1187 1 View Code Duplication
    public function getModuleById($id)
1188
    {
1189 1
        $key = "system/module/id/{$id}";
1190 1
        if (!$module = $this->cache()->read($key)) {
1191 1
            $module = $this->getHandlerModule()->getById($id);
1192 1
            $this->cache()->write($key, $module);
1193 1
        }
1194 1
        return $module;
1195
    }
1196
1197
    /**
1198
     * Render Simple Header
1199
     *
1200
     * @param bool $closehead true to close the HTML head element
1201
     *
1202
     * @return void
1203
     */
1204 1
    public function simpleHeader($closehead = true)
1205
    {
1206 1
        $this->events()->triggerEvent('core.header.start');
1207 1
        $this->theme();
1208 1
        $xoopsConfigMetaFooter = $this->getConfigs();
1209
1210 1
        if (!headers_sent()) {
1211
            header('Content-Type:text/html; charset=' . XoopsLocale::getCharset());
1212
            header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
1213
            header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
1214
            header(
1215
                'Cache-Control: no-store, no-cache, max-age=1, s-maxage=1, must-revalidate, post-check=0, pre-check=0'
1216
            );
1217
            header("Pragma: no-cache");
1218
        }
1219
1220 1
        echo "<!DOCTYPE html>\n";
1221 1
        $xoops_url = \XoopsBaseConfig::get('url');
1222 1
        echo '<html lang="' . XoopsLocale::getLangCode() . '">
1223
              <head>
1224 1
              <meta http-equiv="content-type" content="text/html; charset=' . XoopsLocale::getCharset() . '" />
1225 1
              <meta name="robots" content="' . htmlspecialchars($xoopsConfigMetaFooter['meta_robots']) . '" />
1226 1
              <meta name="keywords" content="' . htmlspecialchars($xoopsConfigMetaFooter['meta_keywords']) . '" />
1227 1
              <meta name="description" content="' . htmlspecialchars($xoopsConfigMetaFooter['meta_description']) . '" />
1228 1
              <meta name="rating" content="' . htmlspecialchars($xoopsConfigMetaFooter['meta_rating']) . '" />
1229 1
              <meta name="author" content="' . htmlspecialchars($xoopsConfigMetaFooter['meta_author']) . '" />
1230
              <meta name="generator" content="XOOPS" />
1231 1
              <title>' . htmlspecialchars($this->getConfig('sitename')) . '</title>
1232 1
              <script type="text/javascript" src="' . $xoops_url . '/include/xoops.js"></script>
1233 1
              <script type="text/javascript" src="' . $xoops_url . '/media/jquery/jquery.js"></script>
1234 1
              <script type="text/javascript" src="' . $xoops_url . '/media/bootstrap/js/bootstrap.min.js"></script>';
1235 1
        $themecss = $this->getCss($this->getConfig('theme_set'));
1236 1
        echo '<link rel="stylesheet" type="text/css" media="all" href="' . $xoops_url . '/xoops.css" />';
1237 1
        $locale = $this->getConfig('locale');
1238 1
        if (XoopsLoad::fileExists($this->path('locale/' . $locale . '/style.css'))) {
1239
            echo '<link rel="stylesheet" type="text/css" media="all" href="' . $xoops_url
1240
                . '/locale/' . $locale . '/style.css" />';
1241
        }
1242 1
        if ($themecss) {
1243 1
            echo '<link rel="stylesheet" type="text/css" media="all" href="' . $themecss . '" />';
1244
            echo '<link rel="stylesheet" type="text/css" media="screen" href="' .
1245 1
                $this->url('themes/' . $this->getConfig('theme_set') . '/media/bootstrap/css/xoops.bootstrap.css')
1246 1
                .'" />';
1247 1
        }
1248 1
        if ($closehead) {
1249 1
            echo '</head><body>';
1250 1
        }
1251 1
    }
1252
1253
    /**
1254
     * Render simpleFooter
1255
     *
1256
     * @return void
1257
     */
1258 2
    public function simpleFooter()
1259
    {
1260 2
        $this->events()->triggerEvent('core.header.footer');
1261 2
        echo '</body></html>';
1262 2
        ob_end_flush();
1263 2
    }
1264
    /**
1265
     * render an alert message to a string
1266
     *
1267
     * @param string $type  alert type, one of 'info', 'error', 'success' or 'warning'
1268
     * @param mixed  $msg   string or array of strings
1269
     * @param string $title title for alert
1270
     *
1271
     * @return string
1272
     */
1273 1
    public function alert($type, $msg, $title = '/')
1274
    {
1275 1
        $tpl = new \XoopsTpl();
1276
        switch ($type) {
1277 1
            case 'info':
1278 1
            default:
1279 1
                $tpl->assign('alert_type', 'alert-info');
1280 1
                if ($title === '/') {
1281 1
                    $title = XoopsLocale::INFORMATION;
1282 1
                }
1283 1
                break;
1284
1285 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...
1286 1
                $tpl->assign('alert_type', 'alert-error');
1287 1
                if ($title === '/') {
1288 1
                    $title = XoopsLocale::ERROR;
1289 1
                }
1290 1
                break;
1291
1292 1
            case 'success':
1293 1
                $tpl->assign('alert_type', 'alert-success');
1294 1
                if ($title === '/') {
1295 1
                    $title = XoopsLocale::SUCCESS;
1296 1
                }
1297 1
                break;
1298
1299 1
            case 'warning':
1300 1
                $tpl->assign('alert_type', '');
1301 1
                if ($title === '/') {
1302 1
                    $title = XoopsLocale::WARNING;
1303 1
                }
1304 1
                break;
1305 1
        }
1306
1307 1
        if ($title != '') {
1308 1
            $tpl->assign('alert_title', $title);
1309 1
        }
1310 1
        if (!is_scalar($msg) && !is_array($msg)) {
1311 1
            $msg = ''; // don't know what to do with this, so make it blank
1312 1
        }
1313 1
        if (is_array($msg)) {
1314
            // if this is not a simple array of strings, this might not work
1315 1
            $alert_msg = @implode("<br />", $msg);
1316 1
        } else {
1317 1
            $alert_msg = $msg;
1318
        }
1319 1
        if ($alert_msg == '') {
1320 1
            return '';
1321
        } else {
1322 1
            $tpl->assign('alert_msg', $alert_msg);
1323 1
            $ret = $tpl->fetch('module:system/system_alert.tpl');
1324 1
            return $ret;
1325
        }
1326
    }
1327
1328
    /**
1329
     * Render a confirmation form to a string
1330
     *
1331
     * @param array   $hiddens  associative array of values used to complete confirmed action
1332
     * @param string  $action   form action (URL)
1333
     * @param string  $msg      message to display
1334
     * @param string  $submit   submit button message
1335
     * @param boolean $addtoken true to add CSRF token
1336
     *
1337
     * @return string rendered confirm message
1338
     */
1339 1
    public function confirm($hiddens, $action, $msg, $submit = '', $addtoken = true)
1340
    {
1341 1
        $tpl = new \XoopsTpl();
1342 1
        $submit = ($submit != '') ? trim($submit) : XoopsLocale::A_SUBMIT;
1343 1
        $tpl->assign('msg', $msg);
1344 1
        $tpl->assign('action', $action);
1345 1
        $tpl->assign('submit', $submit);
1346 1
        $str_hiddens = '';
1347 1
        foreach ($hiddens as $name => $value) {
1348 1
            if (is_array($value)) {
1349 1
                foreach ($value as $caption => $newvalue) {
1350 1
                    $str_hiddens .= '<input type="radio" name="' . $name . '" value="'
1351 1
                        . htmlspecialchars($newvalue) . '" > ' . $caption . NWLINE;
1352 1
                }
1353 1
                $str_hiddens .= '<br />' . NWLINE;
1354 1
            } else {
1355 1
                $str_hiddens .= '<input type="hidden" name="' . $name . '" value="'
1356 1
                    . htmlspecialchars($value) . '" />' . NWLINE;
1357
            }
1358 1
        }
1359 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...
1360 1
            $tpl->assign('token', $this->security()->getTokenHTML());
1361 1
        }
1362 1
        $tpl->assign('hiddens', $str_hiddens);
1363 1
        return $tpl->fetch('module:system/system_confirm.tpl');
1364
    }
1365
1366
    /**
1367
     * Get User Timestamp (kind of pointless, since timestamps are UTC?)
1368
     *
1369
     * @param \DateTime|int $time DateTime object or unix timestamp
1370
     *
1371
     * @return int unix timestamp
1372
     */
1373 1
    public function getUserTimestamp($time)
1374
    {
1375 1
        $dt = \Xoops\Core\Locale\Time::cleanTime($time);
1376 1
        return $dt->getTimestamp();
1377
    }
1378
1379
    /**
1380
     * Function to calculate server timestamp from user entered time (timestamp)
1381
     *
1382
     * @param int  $timestamp time stamp
1383
     * @param null $userTZ    timezone
1384
     *
1385
     * @return int
1386
     */
1387 1
    public function userTimeToServerTime($timestamp, $userTZ = null)
1388
    {
1389 1
        if (!isset($userTZ)) {
1390 1
            $userTZ = $this->getConfig('default_TZ');
1391 1
        }
1392 1
        $timestamp = $timestamp - (($userTZ - $this->getConfig('server_TZ')) * 3600);
1393 1
        return (int)$timestamp;
1394
    }
1395
1396
    /**
1397
     * get the groups associated with the current user
1398
     *
1399
     * @return int[]
1400
     */
1401 3
    public function getUserGroups()
1402
    {
1403 3
        $groups = $this->isUser() ? $this->user->getGroups() : array(FixedGroups::ANONYMOUS);
1404
1405 3
        return $groups;
1406
    }
1407
1408
    /**
1409
     * generate a temporary password
1410
     *
1411
     * @return string
1412
     *
1413
     * @todo make better passwords
1414
     */
1415 1
    public function makePass()
1416
    {
1417 1
        $makepass = '';
1418
        $syllables = array(
1419 1
            'er', 'in', 'tia', 'wol', 'fe', 'pre', 'vet', 'jo', 'nes', 'al', 'len', 'son', 'cha', 'ir', 'ler', 'bo',
1420 1
            'ok', 'tio', 'nar', 'sim', 'ple', 'bla', 'ten', 'toe', 'cho', 'co', 'lat', 'spe', 'ak', 'er', 'po', 'co',
1421 1
            'lor', 'pen', 'cil', 'li', 'ght', 'wh', 'at', 'the', 'he', 'ck', 'is', 'mam', 'bo', 'no', 'fi', 've', 'any',
1422 1
            'way', 'pol', 'iti', 'cs', 'ra', 'dio', 'sou', 'rce', 'sea', 'rch', 'pa', 'per', 'com', 'bo', 'sp', 'eak',
1423 1
            'st', 'fi', 'rst', 'gr', 'oup', 'boy', 'ea', 'gle', 'tr', 'ail', 'bi', 'ble', 'brb', 'pri', 'dee', 'kay',
1424 1
            'en', 'be', 'se'
1425 1
        );
1426 1
        for ($count = 1; $count <= 4; ++$count) {
1427 1
            if (1 == mt_rand() % 10) {
1428 1
                $makepass .= sprintf('%0.0f', (rand() % 50) + 1);
1429 1
            } else {
1430 1
                $makepass .= sprintf('%s', $syllables[rand() % 62]);
1431
            }
1432 1
        }
1433 1
        return $makepass;
1434
    }
1435
1436
    /**
1437
     * Check Email
1438
     *
1439
     * @param string $email    check email
1440
     * @param bool   $antispam true if returned email should be have anti-SPAM measures applied
1441
     *
1442
     * @return false|string email address if valid, otherwise false
1443
     */
1444 2
    public function checkEmail($email, $antispam = false)
1445
    {
1446 2
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
1447 1
            return false;
1448
        }
1449 2
        if ($antispam) {
1450 1
            $email = str_replace("@", " at ", $email);
1451 1
            $email = str_replace(".", " dot ", $email);
1452 1
        }
1453 2
        return $email;
1454
    }
1455
1456
    /**
1457
     * formatURL - add default http:// if no valid protocol specified
1458
     *
1459
     * @param string $url full or partial url
1460
     *
1461
     * @return string
1462
     */
1463 1
    public function formatURL($url)
1464
    {
1465 1
        $url = trim($url);
1466 1
        if ($url != '') {
1467 1
            if (!preg_match('/^(https?|ftps?|ed2k)\:\/\//i', $url)) {
1468 1
                $url = 'http://' . $url;
1469 1
            }
1470 1
        }
1471 1
        return $url;
1472
    }
1473
1474
    /**
1475
     * Function to get banner html tags for use in templates
1476
     *
1477
     * @return string
1478
     */
1479 3
    public function getBanner()
1480
    {
1481 3
        $options = '';
1482 3
        $this->events()->triggerEvent('core.banner.display', array(&$options));
1483 3
        return $options;
1484
    }
1485
1486
    /**
1487
     * Function to redirect a user to certain pages
1488
     *
1489
     * @param string $url               URL to redirect to
1490
     * @param int    $time              time to wait (to allow reading message display)
1491
     * @param string $message           message to display
1492
     * @param bool   $addredirect       add xoops_redirect parameter with current URL to the redirect
1493
     *                                   URL -  used for return from login redirect
1494
     * @param bool   $allowExternalLink allow redirect to external URL
1495
     *
1496
     * @return void
1497
     */
1498
    public function redirect($url, $time = 3, $message = '', $addredirect = true, $allowExternalLink = false)
0 ignored issues
show
Coding Style introduced by
redirect uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
1499
    {
1500
        $this->events()->triggerEvent('core.redirect.start', array(
1501
            $url, $time, $message, $addredirect, $allowExternalLink
1502
        ));
1503
        // if conditions are right, system preloads will exit on this call
1504
        // so don't use it if you want to be called, use start version above.
1505
        $this->events()->triggerEvent('core.include.functions.redirectheader', array(
1506
            $url, $time, $message, $addredirect, $allowExternalLink
1507
        ));
1508
1509
        $xoops_url = \XoopsBaseConfig::get('url');
1510
1511
        if (preg_match("/[\\0-\\31]|about:|script:/i", $url)) {
1512
            if (!preg_match('/^\b(java)?script:([\s]*)history\.go\(-[0-9]*\)([\s]*[;]*[\s]*)$/si', $url)) {
1513
                $url = $xoops_url;
1514
            }
1515
        }
1516 View Code Duplication
        if (!$allowExternalLink && $pos = strpos($url, '://')) {
1517
            $xoopsLocation = substr($xoops_url, strpos($xoops_url, '://') + 3);
1518
            if (strcasecmp(substr($url, $pos + 3, strlen($xoopsLocation)), $xoopsLocation)) {
1519
                $url = $xoops_url;
1520
            }
1521
        }
1522
        if (!defined('XOOPS_CPFUNC_LOADED')) {
1523
            $theme = 'default';
1524
        } else {
1525
            $theme = $this->getConfig('theme_set');
1526
        }
1527
1528
        $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...
1529
        $xoopsThemeFactory = new \Xoops\Core\Theme\Factory();
1530
        $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...
1531
        $xoopsThemeFactory->defaultTheme = $theme;
1532
        $this->setTheme($xoopsThemeFactory->createInstance(array(
1533
            "plugins" => array(), "renderBanner" => false
1534
        )));
1535
        $this->setTpl($this->theme()->template);
1536
        $this->tpl()->assign(array(
1537
            'xoops_theme'      => $theme, 'xoops_imageurl' => \XoopsBaseConfig::get('themes-url') . '/' . $theme . '/',
1538
            'xoops_themecss'   => $this->getCss($theme),
1539
            'xoops_requesturi' => htmlspecialchars($_SERVER['REQUEST_URI'], ENT_QUOTES),
1540
            'xoops_sitename'   => htmlspecialchars($this->getConfig('sitename'), ENT_QUOTES),
1541
            'xoops_slogan'     => htmlspecialchars($this->getConfig('slogan'), ENT_QUOTES),
1542
            'xoops_dirname'    => $this->isModule() ? $this->module->getVar('dirname') : 'system',
1543
            'xoops_pagetitle'  => $this->isModule() ? $this->module->getVar('name')
1544
                : htmlspecialchars($this->getConfig('slogan'), ENT_QUOTES)
1545
        ));
1546
1547
        $this->tpl()->assign('time', (int)($time));
1548
        if (!empty($_SERVER['REQUEST_URI']) && $addredirect && strstr($url, 'user.php')) {
1549
            $joiner = (false===strpos($url, '?')) ? '?' : '&amp;';
1550
            $url .= $joiner . 'xoops_redirect=' . urlencode($_SERVER['REQUEST_URI']);
1551
        }
1552
        $url = preg_replace("/&amp;/i", '&', htmlspecialchars($url, ENT_QUOTES));
1553
        $this->tpl()->assign('url', $url);
1554
        $message = trim($message) != '' ? $message : XoopsLocale::E_TAKING_YOU_BACK;
1555
        $this->tpl()->assign('message', $message);
1556
        $this->tpl()->assign('lang_ifnotreload', sprintf(XoopsLocale::F_IF_PAGE_NOT_RELOAD_CLICK_HERE, $url));
1557
1558
        $this->events()->triggerEvent('core.include.functions.redirectheader.end');
1559
        $this->tpl()->display('module:system/system_redirect.tpl');
1560
        exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The method redirect() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
1561
    }
1562
1563
    /**
1564
     * Do an immediate redirect to the specified url. Use this instead of using PHP's header()
1565
     * directly so that a core.redirect.start event is triggered. An example is debugbar, that
1566
     * stacks data so the details for both original and redirected scripts data are available.
1567
     *
1568
     * @param string $url URL to redirect to
1569
     *
1570
     * @return void
1571
     */
1572
    public static function simpleRedirect($url)
1573
    {
1574
        header("location: {$url}");
1575
        $xoops = \Xoops::getInstance();
1576
        $xoops->events()->triggerEvent('core.redirect.start', array($url));
1577
        exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method simpleRedirect() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

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