GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — develop ( 92c79f...f4bfda )
by gyeong-won
06:35
created

Context::_setUploadedArgument()   B

Complexity

Conditions 11
Paths 8

Size

Total Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
nc 8
nop 0
dl 0
loc 46
rs 7.3166
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/* Copyright (C) NAVER <http://www.navercorp.com> */
3
4
define('FOLLOW_REQUEST_SSL', 0);
5
define('ENFORCE_SSL', 1);
6
define('RELEASE_SSL', 2);
7
8
/**
9
 * Manages Context such as request arguments/environment variables
10
 * It has dual method structure, easy-to use methods which can be called as self::methodname(),and methods called with static object.
11
 *
12
 * @author NAVER ([email protected])
13
 */
14
class Context
15
{
16
17
	/**
18
	 * Allow rewrite
19
	 * @var bool TRUE: using rewrite mod, FALSE: otherwise
20
	 */
21
	public $allow_rewrite = FALSE;
22
23
	/**
24
	 * Request method
25
	 * @var string GET|POST|XMLRPC|JSON
26
	 */
27
	public $request_method = 'GET';
28
29
	/**
30
	 * js callback function name.
31
	 * @var string
32
	 */
33
	public $js_callback_func = '';
34
35
	/**
36
	 * Response method.If it's not set, it follows request method.
37
	 * @var string HTML|XMLRPC|JSON|JS_CALLBACK
38
	 */
39
	public $response_method = '';
40
41
	/**
42
	 * Conatins request parameters and environment variables
43
	 * @var object
44
	 */
45
	public $context = NULL;
46
47
	/**
48
	 * DB info
49
	 * @var object
50
	 */
51
	public $db_info = NULL;
52
53
	/**
54
	 * FTP info
55
	 * @var object
56
	 */
57
	public $ftp_info = NULL;
58
59
	/**
60
	 * ssl action cache file
61
	 * @var array
62
	 */
63
	public $sslActionCacheFile = './files/cache/sslCacheFile.php';
64
65
	/**
66
	 * List of actions to be sent via ssl (it is used by javascript xml handler for ajax)
67
	 * @var array
68
	 */
69
	public $ssl_actions = array();
70
71
	/**
72
	 * obejct oFrontEndFileHandler()
73
	 * @var object
74
	 */
75
	public $oFrontEndFileHandler;
76
77
	/**
78
	 * script codes in <head>..</head>
79
	 * @var string
80
	 */
81
	public $html_header = NULL;
82
83
	/**
84
	 * class names of <body>
85
	 * @var array
86
	 */
87
	public $body_class = array();
88
89
	/**
90
	 * codes after <body>
91
	 * @var string
92
	 */
93
	public $body_header = NULL;
94
95
	/**
96
	 * class names before </body>
97
	 * @var string
98
	 */
99
	public $html_footer = NULL;
100
101
	/**
102
	 * path of Xpress Engine
103
	 * @var string
104
	 */
105
	public $path = '';
106
	// language information - it is changed by HTTP_USER_AGENT or user's cookie
107
	/**
108
	 * language type
109
	 * @var string
110
	 */
111
	public $lang_type = '';
112
113
	/**
114
	 * contains language-specific data
115
	 * @var object
116
	 */
117
	public $lang = NULL;
118
119
	/**
120
	 * list of loaded languages (to avoid re-loading them)
121
	 * @var array
122
	 */
123
	public $loaded_lang_files = array();
124
125
	/**
126
	 * site's browser title
127
	 * @var string
128
	 */
129
	public $site_title = '';
130
131
	/**
132
	 * variables from GET or form submit
133
	 * @var mixed
134
	 */
135
	public $get_vars = NULL;
136
137
	/**
138
	 * Checks uploaded
139
	 * @var bool TRUE if attached file exists
140
	 */
141
	public $is_uploaded = FALSE;
142
	/**
143
	 * Pattern for request vars check
144
	 * @var array
145
	 */
146
	public $patterns = array(
147
			'/<\?/iUsm',
148
			'/<\%/iUsm',
149
			'/<script\s*?language\s*?=\s*?("|\')?\s*?php\s*("|\')?/iUsm'
150
			);
151
	/**
152
	 * Check init
153
	 * @var bool FALSE if init fail
154
	 */
155
	public $isSuccessInit = TRUE;
156
157
	/**
158
	 * returns static context object (Singleton). It's to use Context without declaration of an object
159
	 *
160
	 * @return object Instance
161
	 */
162
	function &getInstance()
163
	{
164
		static $theInstance = null;
165
		if(!$theInstance)
166
		{
167
			$theInstance = new Context();
168
		}
169
170
		return $theInstance;
171
	}
172
173
	/**
174
	 * Cunstructor
175
	 *
176
	 * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
177
	 */
178
	function __construct()
179
	{
180
		$this->oFrontEndFileHandler = new FrontEndFileHandler();
181
		$this->get_vars = new stdClass();
182
183
		// include ssl action cache file
184
		$this->sslActionCacheFile = FileHandler::getRealPath($this->sslActionCacheFile);
0 ignored issues
show
Documentation introduced by
$this->sslActionCacheFile is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation Bug introduced by
It seems like \FileHandler::getRealPat...is->sslActionCacheFile) of type string is incompatible with the declared type array of property $sslActionCacheFile.

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...
185
		if(is_readable($this->sslActionCacheFile))
186
		{
187
			require($this->sslActionCacheFile);
188
			if(isset($sslActions))
0 ignored issues
show
Bug introduced by
The variable $sslActions seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
189
			{
190
				$this->ssl_actions = $sslActions;
191
			}
192
		}
193
	}
194
195
	/**
196
	 * Initialization, it sets DB information, request arguments and so on.
197
	 *
198
	 * @see This function should be called only once
199
	 * @return void
200
	 */
201
	function init()
202
	{
203
		// fix missing HTTP_RAW_POST_DATA in PHP 5.6 and above
204
		if(!isset($GLOBALS['HTTP_RAW_POST_DATA']) && version_compare(PHP_VERSION, '5.6.0', '>=') === TRUE)
205
		{
206
			$GLOBALS['HTTP_RAW_POST_DATA'] = file_get_contents("php://input");
207
208
			// If content is not XML JSON, unset
209
			if(!preg_match('/^[\<\{\[]/', $GLOBALS['HTTP_RAW_POST_DATA']) && strpos($_SERVER['CONTENT_TYPE'], 'json') === FALSE && strpos($_SERVER['HTTP_CONTENT_TYPE'], 'json') === FALSE)
210
			{
211
				unset($GLOBALS['HTTP_RAW_POST_DATA']);
212
			}
213
		}
214
215
		// set context variables in $GLOBALS (to use in display handler)
216
		$this->context = &$GLOBALS['__Context__'];
217
		$this->context->lang = &$GLOBALS['lang'];
218
		$this->context->_COOKIE = $_COOKIE;
219
220
		// 20140429 editor/image_link
221
		$this->_checkGlobalVars();
222
223
		$this->setRequestMethod('');
224
225
		$this->_setXmlRpcArgument();
226
		$this->_setJSONRequestArgument();
227
		$this->_setRequestArgument();
228
		$this->_setUploadedArgument();
229
230
		$this->loadDBInfo();
231
		if($this->db_info->use_sitelock == 'Y')
232
		{
233
			if(is_array($this->db_info->sitelock_whitelist)) $whitelist = $this->db_info->sitelock_whitelist;
234
235
			if(!IpFilter::filter($whitelist))
0 ignored issues
show
Bug introduced by
The variable $whitelist does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
236
			{
237
				$title = ($this->db_info->sitelock_title) ? $this->db_info->sitelock_title : 'Maintenance in progress...';
238
				$message = $this->db_info->sitelock_message;
239
240
				define('_XE_SITELOCK_', TRUE);
241
				define('_XE_SITELOCK_TITLE_', $title);
242
				define('_XE_SITELOCK_MESSAGE_', $message);
243
244
				header("HTTP/1.1 403 Forbidden");
245
				if(FileHandler::exists(_XE_PATH_ . 'common/tpl/sitelock.user.html'))
0 ignored issues
show
Bug Best Practice introduced by
The expression \FileHandler::exists(_XE...pl/sitelock.user.html') of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false 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...
246
				{
247
					include _XE_PATH_ . 'common/tpl/sitelock.user.html';
248
				}
249
				else
250
				{
251
					include _XE_PATH_ . 'common/tpl/sitelock.html';
252
				}
253
				exit;
254
			}
255
		}
256
257
		// If XE is installed, get virtual site information
258
		if(self::isInstalled())
259
		{
260
			$oModuleModel = getModel('module');
261
			$site_module_info = $oModuleModel->getDefaultMid();
262
263
			if(!isset($site_module_info))
264
			{
265
				$site_module_info = new stdClass();
266
			}
267
268
			// if site_srl of site_module_info is 0 (default site), compare the domain to default_url of db_config
269
			if($site_module_info->site_srl == 0 && $site_module_info->domain != $this->db_info->default_url)
270
			{
271
				$site_module_info->domain = $this->db_info->default_url;
272
			}
273
274
			$this->set('site_module_info', $site_module_info);
275
			if($site_module_info->site_srl && isSiteID($site_module_info->domain))
276
			{
277
				$this->set('vid', $site_module_info->domain, TRUE);
0 ignored issues
show
Documentation introduced by
TRUE is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
278
			}
279
280
			if(!isset($this->db_info))
281
			{
282
				$this->db_info = new stdClass();
283
			}
284
285
			$this->db_info->lang_type = $site_module_info->default_language;
286
			if(!$this->db_info->lang_type)
287
			{
288
				$this->db_info->lang_type = 'en';
289
			}
290
			if(!$this->db_info->use_db_session)
291
			{
292
				$this->db_info->use_db_session = 'N';
293
			}
294
		}
295
296
		// Load Language File
297
		$lang_supported = $this->loadLangSelected();
298
299
		// Retrieve language type set in user's cookie
300
		if($this->lang_type = $this->get('l'))
301
		{
302
			if($_COOKIE['lang_type'] != $this->lang_type)
303
			{
304
				setcookie('lang_type', $this->lang_type, $_SERVER['REQUEST_TIME'] + 3600 * 24 * 1000);
305
			}
306
		}
307
		elseif($_COOKIE['lang_type'])
308
		{
309
			$this->lang_type = $_COOKIE['lang_type'];
310
		}
311
312
		// If it's not exists, follow default language type set in db_info
313
		if(!$this->lang_type)
314
		{
315
			$this->lang_type = $this->db_info->lang_type;
316
		}
317
318
		// if still lang_type has not been set or has not-supported type , set as English.
319
		if(!$this->lang_type)
320
		{
321
			$this->lang_type = 'en';
322
		}
323
		if(is_array($lang_supported) && !isset($lang_supported[$this->lang_type]))
324
		{
325
			$this->lang_type = 'en';
326
		}
327
328
		$this->set('lang_supported', $lang_supported);
329
		$this->setLangType($this->lang_type);
330
331
		// load module module's language file according to language setting
332
		$this->loadLang(_XE_PATH_ . 'modules/module/lang');
333
334
		// set session handler
335
		if(self::isInstalled() && $this->db_info->use_db_session == 'Y')
336
		{
337
			$oSessionModel = getModel('session');
338
			$oSessionController = getController('session');
339
			session_set_save_handler(
340
					array(&$oSessionController, 'open'), array(&$oSessionController, 'close'), array(&$oSessionModel, 'read'), array(&$oSessionController, 'write'), array(&$oSessionController, 'destroy'), array(&$oSessionController, 'gc')
341
			);
342
		}
343
344
		if($sess = $_POST[session_name()]) session_id($sess);
345
		session_start();
346
347
		// set authentication information in Context and session
348
		if(self::isInstalled())
349
		{
350
			$oModuleModel = getModel('module');
351
			$oModuleModel->loadModuleExtends();
352
353
			$oMemberModel = getModel('member');
354
			$oMemberController = getController('member');
355
356
			if($oMemberController && $oMemberModel)
357
			{
358
				// if signed in, validate it.
359
				if($oMemberModel->isLogged())
360
				{
361
					$oMemberController->setSessionInfo();
362
				}
363
				// check auto sign-in
364
				elseif($_COOKIE['xeak'])
365
				{
366
					$oMemberController->doAutologin();
367
				}
368
369
				$this->set('is_logged', $oMemberModel->isLogged());
370
				$this->set('logged_info', $oMemberModel->getLoggedInfo());
371
			}
372
		}
373
374
		// load common language file
375
		$this->lang = &$GLOBALS['lang'];
376
		$this->loadLang(_XE_PATH_ . 'common/lang/');
377
378
		// check if using rewrite module
379
		$this->allow_rewrite = ($this->db_info->use_rewrite == 'Y' ? TRUE : FALSE);
380
381
		// set locations for javascript use
382
		$url = array();
0 ignored issues
show
Unused Code introduced by
$url 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...
383
		$current_url = self::getRequestUri();
0 ignored issues
show
Unused Code introduced by
$current_url 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...
384
		if($_SERVER['REQUEST_METHOD'] == 'GET')
385
		{
386
			if($this->get_vars)
387
			{
388
				$url = array();
389 View Code Duplication
				foreach($this->get_vars as $key => $val)
390
				{
391
					if(is_array($val) && count($val) > 0)
392
					{
393
						foreach($val as $k => $v)
394
						{
395
							$url[] = $key . '[' . $k . ']=' . urlencode($v);
396
						}
397
					}
398
					elseif($val)
399
					{
400
						$url[] = $key . '=' . urlencode($val);
401
					}
402
				}
403
404
				$current_url = self::getRequestUri();
405
				if($url) $current_url .= '?' . join('&', $url);
0 ignored issues
show
Bug Best Practice introduced by
The expression $url of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
406
			}
407
			else
408
			{
409
				$current_url = $this->getUrl();
410
			}
411
		}
412
		else
413
		{
414
			$current_url = self::getRequestUri();
415
		}
416
417
		$this->set('current_url', $current_url);
418
		$this->set('request_uri', self::getRequestUri());
419
420
		if(strpos($current_url, 'xn--') !== FALSE)
421
		{
422
			$this->set('current_url', self::decodeIdna($current_url));
423
		}
424
425
		if(strpos(self::getRequestUri(), 'xn--') !== FALSE)
426
		{
427
			$this->set('request_uri', self::decodeIdna(self::getRequestUri()));
428
		}
429
	}
430
431
	/**
432
	 * Finalize using resources, such as DB connection
433
	 *
434
	 * @return void
435
	 */
436
	function close()
437
	{
438
		session_write_close();
439
	}
440
441
	/**
442
	 * Load the database information
443
	 *
444
	 * @return void
445
	 */
446
	function loadDBInfo()
447
	{
448
		$self = self::getInstance();
449
450
		if(!$self->isInstalled())
451
		{
452
			return;
453
		}
454
455
		ob_start(); // trash BOM
456
		include($self::getConfigFile());
457
		ob_end_clean();
458
459
		// If master_db information does not exist, the config file needs to be updated
460
		if(!isset($db_info->master_db))
461
		{
462
			$db_info->master_db = array();
0 ignored issues
show
Bug introduced by
The variable $db_info does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
463
			$db_info->master_db["db_type"] = $db_info->db_type;
464
			unset($db_info->db_type);
465
			$db_info->master_db["db_port"] = $db_info->db_port;
466
			unset($db_info->db_port);
467
			$db_info->master_db["db_hostname"] = $db_info->db_hostname;
468
			unset($db_info->db_hostname);
469
			$db_info->master_db["db_password"] = $db_info->db_password;
470
			unset($db_info->db_password);
471
			$db_info->master_db["db_database"] = $db_info->db_database;
472
			unset($db_info->db_database);
473
			$db_info->master_db["db_userid"] = $db_info->db_userid;
474
			unset($db_info->db_userid);
475
			$db_info->master_db["db_table_prefix"] = $db_info->db_table_prefix;
476
			unset($db_info->db_table_prefix);
477
478
			if(isset($db_info->master_db["db_table_prefix"]) && substr_compare($db_info->master_db["db_table_prefix"], '_', -1) !== 0)
479
			{
480
				$db_info->master_db["db_table_prefix"] .= '_';
481
			}
482
483
			$db_info->slave_db = array($db_info->master_db);
484
			$self->setDBInfo($db_info);
485
486
			$oInstallController = getController('install');
487
			$oInstallController->makeConfigFile();
488
		}
489
490
		if(!$db_info->use_prepared_statements)
491
		{
492
			$db_info->use_prepared_statements = 'Y';
493
		}
494
495
		if(!$db_info->time_zone)
496
			$db_info->time_zone = date('O');
497
		$GLOBALS['_time_zone'] = $db_info->time_zone;
498
499
		if($db_info->qmail_compatibility != 'Y')
500
			$db_info->qmail_compatibility = 'N';
501
		$GLOBALS['_qmail_compatibility'] = $db_info->qmail_compatibility;
502
503
		if(!$db_info->use_db_session)
504
			$db_info->use_db_session = 'N';
505
		if(!$db_info->use_ssl)
506
			$db_info->use_ssl = 'none';
507
		$this->set('_use_ssl', $db_info->use_ssl);
508
509
		$self->set('_http_port', ($db_info->http_port) ? $db_info->http_port : NULL);
510
		$self->set('_https_port', ($db_info->https_port) ? $db_info->https_port : NULL);
511
512
		if(!$db_info->sitelock_whitelist) {
513
			$db_info->sitelock_whitelist = '127.0.0.1';
514
		}
515
516
		if(is_string($db_info->sitelock_whitelist)) {
517
			$db_info->sitelock_whitelist = explode(',', $db_info->sitelock_whitelist);
518
		}
519
520
		$self->setDBInfo($db_info);
521
	}
522
523
	/**
524
	 * Get DB's db_type
525
	 *
526
	 * @return string DB's db_type
527
	 */
528
	function getDBType()
529
	{
530
		$self = self::getInstance();
531
		return $self->db_info->master_db["db_type"];
532
	}
533
534
	/**
535
	 * Set DB information
536
	 *
537
	 * @param object $db_info DB information
538
	 * @return void
539
	 */
540
	function setDBInfo($db_info)
541
	{
542
		$self = self::getInstance();
543
		$self->db_info = $db_info;
544
	}
545
546
	/**
547
	 * Get DB information
548
	 *
549
	 * @return object DB information
550
	 */
551
	function getDBInfo()
552
	{
553
		$self = self::getInstance();
554
		return $self->db_info;
555
	}
556
557
	/**
558
	 * Return ssl status
559
	 *
560
	 * @return object SSL status (Optional - none|always|optional)
561
	 */
562
	function getSslStatus()
563
	{
564
		$dbInfo = self::getDBInfo();
565
		return $dbInfo->use_ssl;
566
	}
567
568
	/**
569
	 * Return default URL
570
	 *
571
	 * @return string Default URL
572
	 */
573
	function getDefaultUrl()
574
	{
575
		$db_info = self::getDBInfo();
576
		return $db_info->default_url;
577
	}
578
579
	/**
580
	 * Find supported languages
581
	 *
582
	 * @return array Supported languages
583
	 */
584
	function loadLangSupported()
585
	{
586
		static $lang_supported = null;
587 View Code Duplication
		if(!$lang_supported)
588
		{
589
			$langs = file(_XE_PATH_ . 'common/lang/lang.info');
590
			foreach($langs as $val)
591
			{
592
				list($lang_prefix, $lang_text) = explode(',', $val);
593
				$lang_text = trim($lang_text);
594
				$lang_supported[$lang_prefix] = $lang_text;
595
			}
596
		}
597
		return $lang_supported;
598
	}
599
600
	/**
601
	 * Find selected languages to serve in the site
602
	 *
603
	 * @return array Selected languages
604
	 */
605
	function loadLangSelected()
606
	{
607
		static $lang_selected = null;
608
		if(!$lang_selected)
609
		{
610
			$orig_lang_file = _XE_PATH_ . 'common/lang/lang.info';
611
			$selected_lang_file = _XE_PATH_ . 'files/config/lang_selected.info';
612
			if(!FileHandler::hasContent($selected_lang_file))
613
			{
614
				$old_selected_lang_file = _XE_PATH_ . 'files/cache/lang_selected.info';
615
				FileHandler::moveFile($old_selected_lang_file, $selected_lang_file);
616
			}
617
618
			if(!FileHandler::hasContent($selected_lang_file))
619
			{
620
				$buff = FileHandler::readFile($orig_lang_file);
621
				FileHandler::writeFile($selected_lang_file, $buff);
622
				$lang_selected = self::loadLangSupported();
623
			}
624 View Code Duplication
			else
625
			{
626
				$langs = file($selected_lang_file);
627
				foreach($langs as $val)
628
				{
629
					list($lang_prefix, $lang_text) = explode(',', $val);
630
					$lang_text = trim($lang_text);
631
					$lang_selected[$lang_prefix] = $lang_text;
632
				}
633
			}
634
		}
635
		return $lang_selected;
636
	}
637
638
	/**
639
	 * Single Sign On (SSO)
640
	 *
641
	 * @return bool True : Module handling is necessary in the control path of current request , False : Otherwise
642
	 */
643
	function checkSSO()
644
	{
645
		// pass if it's not GET request or XE is not yet installed
646
		if($this->db_info->use_sso != 'Y' || isCrawler())
647
		{
648
			return TRUE;
649
		}
650
		$checkActList = array('rss' => 1, 'atom' => 1);
651
		if(self::getRequestMethod() != 'GET' || !self::isInstalled() || isset($checkActList[self::get('act')]))
652
		{
653
			return TRUE;
654
		}
655
656
		// pass if default URL is not set
657
		$default_url = trim($this->db_info->default_url);
658
		if(!$default_url)
659
		{
660
			return TRUE;
661
		}
662
663
		if(substr_compare($default_url, '/', -1) !== 0)
664
		{
665
			$default_url .= '/';
666
		}
667
668
		// for sites recieving SSO valdiation
669
		if($default_url == self::getRequestUri())
670
		{
671
			if(self::get('url'))
672
			{
673
				$url = base64_decode(self::get('url'));
674
				$url_info = parse_url($url);
675 View Code Duplication
				if(!Password::checkSignature($url, self::get('sig')))
676
				{
677
					echo self::get('lang')->msg_invalid_request;
678
					return false;
679
				}
680
681
				$oModuleModel = getModel('module');
682
				$domain = $url_info['host'] . $url_info['path'];
683
				if(substr_compare($domain, '/', -1) === 0) $domain = substr($domain, 0, -1);
684
				$site_info = $oModuleModel->getSiteInfoByDomain($domain);
685
686
				if($site_info->site_srl)
687
				{
688
				$url_info['query'].= ($url_info['query'] ? '&' : '') . 'SSOID=' . urlencode(session_id()) . '&sig=' . urlencode(Password::createSignature(session_id()));
689
				$redirect_url = sprintf('%s://%s%s%s?%s', $url_info['scheme'], $url_info['host'], $url_info['port'] ? ':' . $url_info['port'] : '', $url_info['path'], $url_info['query']);
690
				}
691
				else
692
				{
693
					$redirect_url = $url;
694
				}
695
				header('location:' . $redirect_url);
696
697
				return FALSE;
698
			}
699
			// for sites requesting SSO validation
700
		}
701
		else
702
		{
703
			// result handling : set session_name()
704
			if($session_name = self::get('SSOID'))
705
			{
706 View Code Duplication
				if(!Password::checkSignature($session_name, self::get('sig')))
707
				{
708
					echo self::get('lang')->msg_invalid_request;
709
					return false;
710
				}
711
712
				setcookie(session_name(), $session_name);
713
714
				$url = preg_replace('/[\?\&]SSOID=.+$/', '', self::getRequestUrl());
715
				header('location:' . $url);
716
				return FALSE;
717
				// send SSO request
718
			}
719
			else if(!self::get('SSOID') && $_COOKIE['sso'] != md5(self::getRequestUri()))
720
			{
721
				setcookie('sso', md5(self::getRequestUri()));
722
				$origin_url = self::getRequestUrl();
723
				$origin_sig = Password::createSignature($origin_url);
724
				$url = sprintf("%s?url=%s&sig=%s", $default_url, urlencode(base64_encode($origin_url)), urlencode($origin_sig));
725
				header('location:' . $url);
726
				return FALSE;
727
			}
728
		}
729
730
		return TRUE;
731
	}
732
733
	/**
734
	 * Check if FTP info is registered
735
	 *
736
	 * @return bool True: FTP information is registered, False: otherwise
737
	 */
738
	function isFTPRegisted()
739
	{
740
		return file_exists(self::getFTPConfigFile());
741
	}
742
743
	/**
744
	 * Get FTP information
745
	 *
746
	 * @return object FTP information
747
	 */
748
	function getFTPInfo()
749
	{
750
		$self = self::getInstance();
751
752
		if(!$self->isFTPRegisted())
753
		{
754
			return null;
755
		}
756
757
		include($self->getFTPConfigFile());
758
759
		return $ftp_info;
0 ignored issues
show
Bug introduced by
The variable $ftp_info does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
760
	}
761
762
	/**
763
	 * Add string to browser title
764
	 *
765
	 * @param string $site_title Browser title to be added
766
	 * @return void
767
	 */
768
	function addBrowserTitle($site_title)
769
	{
770
		if(!$site_title)
771
		{
772
			return;
773
		}
774
		$self = self::getInstance();
775
776
		if($self->site_title)
777
		{
778
			$self->site_title .= ' - ' . $site_title;
779
		}
780
		else
781
		{
782
			$self->site_title = $site_title;
783
		}
784
	}
785
786
	/**
787
	 * Set string to browser title
788
	 *
789
	 * @param string $site_title Browser title  to be set
790
	 * @return void
791
	 */
792
	function setBrowserTitle($site_title)
793
	{
794
		if(!$site_title)
795
		{
796
			return;
797
		}
798
		$self = self::getInstance();
799
		$self->site_title = $site_title;
800
	}
801
802
	/**
803
	 * Get browser title
804
	 *
805
	 * @return string Browser title(htmlspecialchars applied)
806
	 */
807
	function getBrowserTitle()
808
	{
809
		$self = self::getInstance();
810
811
		$oModuleController = getController('module');
812
		$oModuleController->replaceDefinedLangCode($self->site_title);
813
814
		return htmlspecialchars($self->site_title, ENT_COMPAT | ENT_HTML401, 'UTF-8', FALSE);
815
	}
816
817
	/**
818
	 * Return layout's title
819
	 * @return string layout's title
820
	 */
821
	public function getSiteTitle()
822
	{
823
		$oModuleModel = getModel('module');
824
		$moduleConfig = $oModuleModel->getModuleConfig('module');
825
826
		if(isset($moduleConfig->siteTitle))
827
		{
828
			return $moduleConfig->siteTitle;
829
		}
830
		return '';
831
	}
832
833
	/**
834
	 * Get browser title
835
	 * @deprecated
836
	 */
837
	function _getBrowserTitle()
838
	{
839
		return $this->getBrowserTitle();
840
	}
841
842
	/**
843
	 * Load language file according to language type
844
	 *
845
	 * @param string $path Path of the language file
846
	 * @return void
847
	 */
848
	function loadLang($path)
849
	{
850
		global $lang;
851
852
		$self = self::getInstance();
853
		if(!$self->lang_type)
854
		{
855
			return;
856
		}
857
		if(!is_object($lang))
858
		{
859
			$lang = new stdClass;
860
		}
861
862
		if(!($filename = $self->_loadXmlLang($path)))
863
		{
864
			$filename = $self->_loadPhpLang($path);
865
		}
866
867
		if(!is_array($self->loaded_lang_files))
868
		{
869
			$self->loaded_lang_files = array();
870
		}
871
		if(in_array($filename, $self->loaded_lang_files))
872
		{
873
			return;
874
		}
875
876
		if($filename && is_readable($filename))
877
		{
878
			$self->loaded_lang_files[] = $filename;
879
			include($filename);
880
		}
881
		else
882
		{
883
			$self->_evalxmlLang($path);
884
		}
885
	}
886
887
	/**
888
	 * Evaluation of xml language file
889
	 *
890
	 * @param string Path of the language file
891
	 * @return void
892
	 */
893
	function _evalxmlLang($path)
894
	{
895
		global $lang;
896
897
		if(!$path) return;
898
899
		$_path = 'eval://' . $path;
900
901
		if(in_array($_path, $this->loaded_lang_files))
902
		{
903
			return;
904
		}
905
906
		if(substr_compare($path, '/', -1) !== 0)
907
		{
908
			$path .= '/';
909
		}
910
911
		$oXmlLangParser = new XmlLangParser($path . 'lang.xml', $this->lang_type);
912
		$content = $oXmlLangParser->getCompileContent();
913
914
		if($content)
0 ignored issues
show
Bug Best Practice introduced by
The expression $content of type false|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false 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...
915
		{
916
			$this->loaded_lang_files[] = $_path;
917
			eval($content);
918
		}
919
	}
920
921
	/**
922
	 * Load language file of xml type
923
	 *
924
	 * @param string $path Path of the language file
925
	 * @return string file name
926
	 */
927
	function _loadXmlLang($path)
928
	{
929
		if(!$path) return;
930
931
		$oXmlLangParser = new XmlLangParser($path . ((substr_compare($path, '/', -1) !== 0) ? '/' : '') . 'lang.xml', $this->lang_type);
932
		return $oXmlLangParser->compile();
933
	}
934
935
	/**
936
	 * Load language file of php type
937
	 *
938
	 * @param string $path Path of the language file
939
	 * @return string file name
940
	 */
941
	function _loadPhpLang($path)
942
	{
943
		if(!$path) return;
944
945
		if(substr_compare($path, '/', -1) !== 0)
946
		{
947
			$path .= '/';
948
		}
949
		$path_tpl = $path . '%s.lang.php';
950
		$file = sprintf($path_tpl, $this->lang_type);
951
952
		$langs = array('ko', 'en'); // this will be configurable.
953
		while(!is_readable($file) && $langs[0])
954
		{
955
			$file = sprintf($path_tpl, array_shift($langs));
956
		}
957
958
		if(!is_readable($file))
959
		{
960
			return FALSE;
961
		}
962
		return $file;
963
	}
964
965
	/**
966
	 * Set lang_type
967
	 *
968
	 * @param string $lang_type Language type.
969
	 * @return void
970
	 */
971
	function setLangType($lang_type = 'ko')
972
	{
973
		$self = self::getInstance();
974
975
		$self->lang_type = $lang_type;
976
		$self->set('lang_type', $lang_type);
977
978
		$_SESSION['lang_type'] = $lang_type;
979
	}
980
981
	/**
982
	 * Get lang_type
983
	 *
984
	 * @return string Language type
985
	 */
986
	function getLangType()
987
	{
988
		$self = self::getInstance();
989
		return $self->lang_type;
990
	}
991
992
	/**
993
	 * Return string accoring to the inputed code
994
	 *
995
	 * @param string $code Language variable name
996
	 * @return string If string for the code exists returns it, otherwise returns original code
997
	 */
998
	function getLang($code)
999
	{
1000
		if(!$code)
1001
		{
1002
			return;
1003
		}
1004
		if($GLOBALS['lang']->{$code})
1005
		{
1006
			return $GLOBALS['lang']->{$code};
1007
		}
1008
		return $code;
1009
	}
1010
1011
	/**
1012
	 * Set data to lang variable
1013
	 *
1014
	 * @param string $code Language variable name
1015
	 * @param string $val `$code`s value
1016
	 * @return void
1017
	 */
1018
	function setLang($code, $val)
1019
	{
1020
		if(!isset($GLOBALS['lang']))
1021
		{
1022
			$GLOBALS['lang'] = new stdClass();
1023
		}
1024
		$GLOBALS['lang']->{$code} = $val;
1025
	}
1026
1027
	/**
1028
	 * Convert strings of variables in $source_object into UTF-8
1029
	 *
1030
	 * @param object $source_obj Conatins strings to convert
1031
	 * @return object converted object
1032
	 */
1033
	function convertEncoding($source_obj)
1034
	{
1035
		$charset_list = array(
1036
			'UTF-8', 'EUC-KR', 'CP949', 'ISO8859-1', 'EUC-JP', 'SHIFT_JIS',
1037
			'CP932', 'EUC-CN', 'HZ', 'GBK', 'GB18030', 'EUC-TW', 'BIG5',
1038
			'CP950', 'BIG5-HKSCS', 'ISO8859-6', 'ISO8859-8', 'JOHAB', 'CP1255',
1039
			'CP1256', 'CP862', 'ASCII', 'ISO8859-1', 'CP1250', 'CP1251',
1040
			'CP1252', 'CP1253', 'CP1254', 'CP1257', 'CP850', 'CP866'
1041
		);
1042
1043
		$obj = clone $source_obj;
1044
1045
		foreach($charset_list as $charset)
1046
		{
1047
			array_walk($obj,'Context::checkConvertFlag',$charset);
1048
			$flag = self::checkConvertFlag($flag = TRUE);
0 ignored issues
show
Bug introduced by
$flag = TRUE cannot be passed to checkconvertflag() as the parameter $val expects a reference.
Loading history...
1049
			if($flag)
1050
			{
1051
				if($charset == 'UTF-8')
1052
				{
1053
					return $obj;
1054
				}
1055
				array_walk($obj,'Context::doConvertEncoding',$charset);
1056
				return $obj;
1057
			}
1058
		}
1059
		return $obj;
1060
	}
1061
1062
	/**
1063
	 * Check flag
1064
	 *
1065
	 * @param mixed $val
1066
	 * @param string $key
1067
	 * @param mixed $charset charset
1068
	 * @see arrayConvWalkCallback will replaced array_walk_recursive in >=PHP5
1069
	 * @return void
1070
	 */
1071
	function checkConvertFlag(&$val, $key = null, $charset = null)
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed.

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

Loading history...
1072
	{
1073
		static $flag = TRUE;
1074
		if($charset)
1075
		{
1076
			if(is_array($val))
1077
				array_walk($val,'Context::checkConvertFlag',$charset);
1078
			else if($val && iconv($charset,$charset,$val)!=$val) $flag = FALSE;
1079
			else $flag = FALSE;
1080
		}
1081
		else
1082
		{
1083
			$return = $flag;
1084
			$flag = TRUE;
1085
			return $return;
1086
		}
1087
	}
1088
1089
	/**
1090
	 * Convert array type variables into UTF-8
1091
	 *
1092
	 * @param mixed $val
1093
	 * @param string $key
1094
	 * @param string $charset character set
1095
	 * @see arrayConvWalkCallback will replaced array_walk_recursive in >=PHP5
1096
	 * @return object converted object
1097
	 */
1098
	function doConvertEncoding(&$val, $key = null, $charset)
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed.

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

Loading history...
1099
	{
1100
		if (is_array($val))
1101
		{
1102
			array_walk($val,'Context::doConvertEncoding',$charset);
1103
		}
1104
		else $val = iconv($charset,'UTF-8',$val);
1105
	}
1106
1107
	/**
1108
	 * Convert strings into UTF-8
1109
	 *
1110
	 * @param string $str String to convert
1111
	 * @return string converted string
1112
	 */
1113
	function convertEncodingStr($str)
1114
	{
1115
        if(!$str) return null;
1116
		$obj = new stdClass();
1117
		$obj->str = $str;
1118
		$obj = self::convertEncoding($obj);
1119
		return $obj->str;
1120
	}
1121
1122
	function decodeIdna($domain)
1123
	{
1124
		if(strpos($domain, 'xn--') !== FALSE)
1125
		{
1126
			require_once(_XE_PATH_ . 'libs/idna_convert/idna_convert.class.php');
1127
			$IDN = new idna_convert(array('idn_version' => 2008));
1128
			$domain = $IDN->decode($domain);
1129
		}
1130
1131
		return $domain;
1132
	}
1133
1134
	/**
1135
	 * Force to set response method
1136
	 *
1137
	 * @param string $method Response method. [HTML|XMLRPC|JSON]
1138
	 * @return void
1139
	 */
1140
	function setResponseMethod($method = 'HTML')
1141
	{
1142
		$self = self::getInstance();
1143
1144
		$methods = array('HTML' => 1, 'XMLRPC' => 1, 'JSON' => 1, 'JS_CALLBACK' => 1);
1145
		$self->response_method = isset($methods[$method]) ? $method : 'HTML';
1146
	}
1147
1148
	/**
1149
	 * Get reponse method
1150
	 *
1151
	 * @return string Response method. If it's not set, returns request method.
1152
	 */
1153
	function getResponseMethod()
1154
	{
1155
		$self = self::getInstance();
1156
1157
		if($self->response_method)
1158
		{
1159
			return $self->response_method;
1160
		}
1161
1162
		$method = $self->getRequestMethod();
1163
		$methods = array('HTML' => 1, 'XMLRPC' => 1, 'JSON' => 1, 'JS_CALLBACK' => 1);
1164
1165
		return isset($methods[$method]) ? $method : 'HTML';
1166
	}
1167
1168
	/**
1169
	 * Determine request method
1170
	 *
1171
	 * @param string $type Request method. (Optional - GET|POST|XMLRPC|JSON)
1172
	 * @return void
1173
	 */
1174
	function setRequestMethod($type = '')
1175
	{
1176
		$self = self::getInstance();
1177
1178
		$self->js_callback_func = $self->getJSCallbackFunc();
1179
1180
		($type && $self->request_method = $type) or
1181
				((strpos($_SERVER['CONTENT_TYPE'], 'json') || strpos($_SERVER['HTTP_CONTENT_TYPE'], 'json')) && $self->request_method = 'JSON') or
1182
				($GLOBALS['HTTP_RAW_POST_DATA'] && $self->request_method = 'XMLRPC') or
1183
				($self->js_callback_func && $self->request_method = 'JS_CALLBACK') or
1184
				($self->request_method = $_SERVER['REQUEST_METHOD']);
1185
	}
1186
1187
	/**
1188
	 * handle global arguments
1189
	 *
1190
	 * @return void
1191
	 */
1192
	function _checkGlobalVars()
1193
	{
1194
		$this->_recursiveCheckVar($_SERVER['HTTP_HOST']);
1195
1196
		$pattern = "/[\,\"\'\{\}\[\]\(\);$]/";
1197
		if(preg_match($pattern, $_SERVER['HTTP_HOST']))
1198
		{
1199
			$this->isSuccessInit = FALSE;
1200
		}
1201
	}
1202
1203
	/**
1204
	 * handle request arguments for GET/POST
1205
	 *
1206
	 * @return void
1207
	 */
1208
	function _setRequestArgument()
1209
	{
1210
		if(!count($_REQUEST))
1211
		{
1212
			return;
1213
		}
1214
1215
		$requestMethod = $this->getRequestMethod();
1216
		foreach($_REQUEST as $key => $val)
1217
		{
1218
			if($val === '' || self::get($key))
1219
			{
1220
				continue;
1221
			}
1222
			$key = htmlentities($key);
1223
			$val = $this->_filterRequestVar($key, $val, false, ($requestMethod == 'GET'));
1224
1225
			if($requestMethod == 'GET' && isset($_GET[$key]))
1226
			{
1227
				$set_to_vars = TRUE;
1228
			}
1229
			elseif($requestMethod == 'POST' && isset($_POST[$key]))
1230
			{
1231
				$set_to_vars = TRUE;
1232
			}
1233
			elseif($requestMethod == 'JS_CALLBACK' && (isset($_GET[$key]) || isset($_POST[$key])))
1234
			{
1235
				$set_to_vars = TRUE;
1236
			}
1237
			else
1238
			{
1239
				$set_to_vars = FALSE;
1240
			}
1241
1242
			if($set_to_vars)
1243
			{
1244
				$this->_recursiveCheckVar($val);
1245
			}
1246
1247
			$this->set($key, $val, $set_to_vars);
0 ignored issues
show
Documentation introduced by
$set_to_vars is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1248
		}
1249
	}
1250
1251
	function _recursiveCheckVar($val)
1252
	{
1253
		if(is_string($val))
1254
		{
1255
			foreach($this->patterns as $pattern)
1256
			{
1257
				if(preg_match($pattern, $val))
1258
				{
1259
					$this->isSuccessInit = FALSE;
1260
					return;
1261
				}
1262
			}
1263
		}
1264
		else if(is_array($val))
1265
		{
1266
			foreach($val as $val2)
1267
			{
1268
				$this->_recursiveCheckVar($val2);
1269
			}
1270
		}
1271
	}
1272
1273
	/**
1274
	 * Handle request arguments for JSON
1275
	 *
1276
	 * @return void
1277
	 */
1278
	function _setJSONRequestArgument()
1279
	{
1280
		if($this->getRequestMethod() != 'JSON')
1281
		{
1282
			return;
1283
		}
1284
1285
		$params = array();
1286
		parse_str($GLOBALS['HTTP_RAW_POST_DATA'], $params);
1287
1288
		foreach($params as $key => $val)
0 ignored issues
show
Bug introduced by
The expression $params of type null|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
1289
		{
1290
			$this->set($key, $this->_filterRequestVar($key, $val, 1), TRUE);
0 ignored issues
show
Documentation introduced by
TRUE is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1291
		}
1292
	}
1293
1294
	/**
1295
	 * Handle request arguments for XML RPC
1296
	 *
1297
	 * @return void
1298
	 */
1299
	function _setXmlRpcArgument()
1300
	{
1301
		if($this->getRequestMethod() != 'XMLRPC')
1302
		{
1303
			return;
1304
		}
1305
1306
		$xml = $GLOBALS['HTTP_RAW_POST_DATA'];
1307
		if(Security::detectingXEE($xml))
1308
		{
1309
			header("HTTP/1.0 400 Bad Request");
1310
			exit;
1311
		}
1312
1313
		$oXml = new XmlParser();
1314
		$xml_obj = $oXml->parse($xml);
1315
1316
		$params = $xml_obj->methodcall->params;
1317
		unset($params->node_name, $params->attrs, $params->body);
1318
1319
		if(!count(get_object_vars($params)))
1320
		{
1321
			return;
1322
		}
1323
1324
		foreach($params as $key => $val)
1325
		{
1326
			$this->set($key, $this->_filterXmlVars($key, $val), TRUE);
0 ignored issues
show
Documentation introduced by
TRUE is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1327
		}
1328
	}
1329
1330
	/**
1331
	 * Filter xml variables
1332
	 *
1333
	 * @param string $key Variable key
1334
	 * @param object $val Variable value
1335
	 * @return mixed filtered value
1336
	 */
1337
	function _filterXmlVars($key, $val)
1338
	{
1339
		if(is_array($val))
1340
		{
1341
			$stack = array();
1342
			foreach($val as $k => $v)
1343
			{
1344
				$stack[$k] = $this->_filterXmlVars($k, $v);
1345
			}
1346
1347
			return $stack;
1348
		}
1349
1350
		$body = $val->body;
1351
		unset($val->node_name, $val->attrs, $val->body);
1352
		if(!count(get_object_vars($val)))
1353
		{
1354
			return $this->_filterRequestVar($key, $body, 0);
1355
		}
1356
1357
		$stack = new stdClass();
1358
		foreach($val as $k => $v)
1359
		{
1360
			$output = $this->_filterXmlVars($k, $v);
1361
			if(is_object($v) && $v->attrs->type == 'array')
1362
			{
1363
				$output = array($output);
1364
			}
1365
			if($k == 'value' && (is_array($v) || $v->attrs->type == 'array'))
1366
			{
1367
				return $output;
1368
			}
1369
1370
			$stack->{$k} = $output;
1371
		}
1372
1373
		if(!count(get_object_vars($stack)))
1374
		{
1375
			return NULL;
1376
		}
1377
1378
		return $stack;
1379
	}
1380
1381
	/**
1382
	 * Filter request variable
1383
	 *
1384
	 * @see Cast variables, such as _srl, page, and cpage, into interger
1385
	 * @param string $key Variable key
1386
	 * @param string $val Variable value
1387
	 * @param string $do_stripslashes Whether to strip slashes
1388
	 * @return mixed filtered value. Type are string or array
1389
	 */
1390
	function _filterRequestVar($key, $val, $do_stripslashes = true, $remove_hack = false)
1391
	{
1392
		if(!($isArray = is_array($val)))
1393
		{
1394
			$val = array($val);
1395
		}
1396
1397
		$result = array();
1398
		foreach($val as $k => $v)
1399
		{
1400
			if($remove_hack && !is_array($v)) {
1401
				if(stripos($v, '<script') || stripos($v, 'lt;script') || stripos($v, '%3Cscript'))
1402
				{
1403
					$result[$k] = escape($v);
1404
					continue;
1405
				}
1406
			}
1407
1408
			$k = htmlentities($k);
1409
			if($key === 'page' || $key === 'cpage' || substr_compare($key, 'srl', -3) === 0)
1410
			{
1411
				$result[$k] = !preg_match('/^[0-9,]+$/', $v) ? (int) $v : $v;
1412
			}
1413
			elseif(in_array($key, array('mid','search_keyword','search_target','xe_validator_id'))) {
1414
				$result[$k] = escape($v, false);
1415
			}
1416
			elseif($key === 'vid')
1417
			{
1418
				$result[$k] = urlencode($v);
1419
			}
1420
			elseif(stripos($key, 'XE_VALIDATOR', 0) === 0)
1421
			{
1422
				unset($result[$k]);
1423
			}
1424
			else
1425
			{
1426
				$result[$k] = $v;
1427
1428
				if($do_stripslashes && version_compare(PHP_VERSION, '5.4.0', '<') && get_magic_quotes_gpc())
1429
				{
1430 View Code Duplication
					if (is_array($result[$k]))
1431
					{
1432
						array_walk_recursive($result[$k], function(&$val) { $val = stripslashes($val); });
1433
					}
1434
					else
1435
					{
1436
						$result[$k] = stripslashes($result[$k]);
1437
					}
1438
				}
1439
1440 View Code Duplication
				if(is_array($result[$k]))
1441
				{
1442
					array_walk_recursive($result[$k], function(&$val) { $val = trim($val); });
1443
				}
1444
				else
1445
				{
1446
					$result[$k] = trim($result[$k]);
1447
				}
1448
1449
				if($remove_hack)
1450
				{
1451
					$result[$k] = escape($result[$k], false);
1452
				}
1453
			}
1454
		}
1455
1456
		return $isArray ? $result : $result[0];
1457
	}
1458
1459
	/**
1460
	 * Check if there exists uploaded file
1461
	 *
1462
	 * @return bool True: exists, False: otherwise
1463
	 */
1464
	function isUploaded()
1465
	{
1466
		$self = self::getInstance();
1467
		return $self->is_uploaded;
1468
	}
1469
1470
	/**
1471
	 * Handle uploaded file
1472
	 *
1473
	 * @return void
1474
	 */
1475
	function _setUploadedArgument()
1476
	{
1477
		if($_SERVER['REQUEST_METHOD'] != 'POST' || !$_FILES || (stripos($_SERVER['CONTENT_TYPE'], 'multipart/form-data') === FALSE && stripos($_SERVER['HTTP_CONTENT_TYPE'], 'multipart/form-data') === FALSE))
1478
		{
1479
			return;
1480
		}
1481
1482
		foreach($_FILES as $key => $val)
1483
		{
1484
			$tmp_name = $val['tmp_name'];
1485
			if(!is_array($tmp_name))
1486
			{
1487
				if(!UploadFileFilter::check($tmp_name, $val['name']))
1488
				{
1489
					continue;
1490
				}
1491
				$val['name'] = htmlspecialchars($val['name'], ENT_COMPAT | ENT_HTML401, 'UTF-8', FALSE);
1492
				$this->set($key, $val, TRUE);
0 ignored issues
show
Documentation introduced by
TRUE is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1493
				$this->is_uploaded = TRUE;
1494
			}
1495
			else
1496
			{
1497
				$files = array();
1498
				foreach ($tmp_name as $i => $j)
1499
				{
1500
					if(!UploadFileFilter::check($val['tmp_name'][$i], $val['name'][$i]))
1501
					{
1502
						$files = array();
1503
						unset($_FILES[$key]);
1504
						break;
1505
					}
1506
					$file = array();
1507
					$file['name'] = $val['name'][$i];
1508
					$file['type'] = $val['type'][$i];
1509
					$file['tmp_name'] = $val['tmp_name'][$i];
1510
					$file['error'] = $val['error'][$i];
1511
					$file['size'] = $val['size'][$i];
1512
					$files[] = $file;
1513
				}
1514
				if(count($files))
1515
				{
1516
					self::set($key, $files, true);
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1517
				}
1518
			}
1519
		}
1520
	}
1521
1522
	/**
1523
	 * Return request method
1524
	 * @return string Request method type. (Optional - GET|POST|XMLRPC|JSON)
1525
	 */
1526
	function getRequestMethod()
1527
	{
1528
		$self = self::getInstance();
1529
		return $self->request_method;
1530
	}
1531
1532
	/**
1533
	 * Return request URL
1534
	 * @return string request URL
1535
	 */
1536
	function getRequestUrl()
1537
	{
1538
		static $url = null;
1539
		if(is_null($url))
1540
		{
1541
			$url = self::getRequestUri();
1542
			if(count($_GET) > 0)
1543
			{
1544
				foreach($_GET as $key => $val)
1545
				{
1546
					$vars[] = $key . '=' . ($val ? urlencode(self::convertEncodingStr($val)) : '');
0 ignored issues
show
Coding Style Comprehensibility introduced by
$vars was never initialized. Although not strictly required by PHP, it is generally a good practice to add $vars = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1547
				}
1548
				$url .= '?' . join('&', $vars);
0 ignored issues
show
Bug introduced by
The variable $vars does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1549
			}
1550
		}
1551
		return $url;
1552
	}
1553
1554
	/**
1555
	 * Return js callback func.
1556
	 * @return string callback func.
1557
	 */
1558
	function getJSCallbackFunc()
1559
	{
1560
		$self = self::getInstance();
0 ignored issues
show
Unused Code introduced by
$self 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...
1561
		$js_callback_func = isset($_GET['xe_js_callback']) ? $_GET['xe_js_callback'] : $_POST['xe_js_callback'];
1562
1563
		if(!preg_match('/^[a-z0-9\.]+$/i', $js_callback_func))
1564
		{
1565
			unset($js_callback_func);
1566
			unset($_GET['xe_js_callback']);
1567
			unset($_POST['xe_js_callback']);
1568
		}
1569
1570
		return $js_callback_func;
1571
	}
1572
1573
	/**
1574
	 * Make URL with args_list upon request URL
1575
	 *
1576
	 * @param int $num_args Arguments nums
1577
	 * @param array $args_list Argument list for set url
1578
	 * @param string $domain Domain
1579
	 * @param bool $encode If TRUE, use url encode.
1580
	 * @param bool $autoEncode If TRUE, url encode automatically, detailed. Use this option, $encode value should be TRUE
1581
	 * @return string URL
1582
	 */
1583
	function getUrl($num_args = 0, $args_list = array(), $domain = null, $encode = TRUE, $autoEncode = FALSE)
0 ignored issues
show
Unused Code introduced by
The parameter $num_args is not used and could be removed.

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

Loading history...
1584
	{
1585
		static $site_module_info = null;
1586
		static $current_info = null;
1587
1588
		$self = self::getInstance();
1589
1590
		// retrieve virtual site information
1591
		if(is_null($site_module_info))
1592
		{
1593
			$site_module_info = self::get('site_module_info');
1594
		}
1595
1596
		// If $domain is set, handle it (if $domain is vid type, remove $domain and handle with $vid)
1597
		if($domain && isSiteID($domain))
0 ignored issues
show
Bug Best Practice introduced by
The expression $domain of type string|null 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...
1598
		{
1599
			$vid = $domain;
1600
			$domain = '';
1601
		}
1602
1603
		// If $domain, $vid are not set, use current site information
1604
		if(!$domain && !$vid)
0 ignored issues
show
Bug introduced by
The variable $vid does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug Best Practice introduced by
The expression $domain 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...
1605
		{
1606
			if($site_module_info->domain && isSiteID($site_module_info->domain))
1607
			{
1608
				$vid = $site_module_info->domain;
1609
			}
1610
			else
1611
			{
1612
				$domain = $site_module_info->domain;
1613
			}
1614
		}
1615
1616
		// if $domain is set, compare current URL. If they are same, remove the domain, otherwise link to the domain.
1617
		if($domain)
1618
		{
1619
			$domain_info = parse_url($domain);
1620
			if(is_null($current_info))
1621
			{
1622
				$current_info = parse_url(($_SERVER['HTTPS'] == 'on' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . getScriptPath());
1623
			}
1624
			if($domain_info['host'] . $domain_info['path'] == $current_info['host'] . $current_info['path'])
1625
			{
1626
				unset($domain);
1627
			}
1628
			else
1629
			{
1630
				$domain = preg_replace('/^(http|https):\/\//i', '', trim($domain));
1631
				if(substr_compare($domain, '/', -1) !== 0)
1632
				{
1633
					$domain .= '/';
1634
				}
1635
			}
1636
		}
1637
1638
		$get_vars = array();
1639
1640
		// If there is no GET variables or first argument is '' to reset variables
1641
		if(!$self->get_vars || $args_list[0] == '')
1642
		{
1643
			// rearrange args_list
1644
			if(is_array($args_list) && $args_list[0] == '')
1645
			{
1646
				array_shift($args_list);
1647
			}
1648
		}
1649
		elseif($_SERVER['REQUEST_METHOD'] == 'GET')
1650
		{
1651
			// Otherwise, make GET variables into array
1652
			$get_vars = get_object_vars($self->get_vars);
1653
		}
1654
		else
1655
		{
1656
			if(!!$self->get_vars->module) $get_vars['module'] = $self->get_vars->module;
1657
			if(!!$self->get_vars->mid) $get_vars['mid'] = $self->get_vars->mid;
1658
			if(!!$self->get_vars->act) $get_vars['act'] = $self->get_vars->act;
1659
			if(!!$self->get_vars->page) $get_vars['page'] = $self->get_vars->page;
1660
			if(!!$self->get_vars->search_target) $get_vars['search_target'] = $self->get_vars->search_target;
1661
			if(!!$self->get_vars->search_keyword) $get_vars['search_keyword'] = $self->get_vars->search_keyword;
1662
			if($get_vars['act'] == 'IS')
1663
			{
1664
				if(!!$self->get_vars->is_keyword) $get_vars['is_keyword'] = $self->get_vars->is_keyword;
1665
			}
1666
		}
1667
1668
		// arrange args_list
1669
		for($i = 0, $c = count($args_list); $i < $c; $i += 2)
1670
		{
1671
			$key = $args_list[$i];
1672
			$val = trim($args_list[$i + 1]);
1673
1674
			// If value is not set, remove the key
1675
			if(!isset($val) || !strlen($val))
1676
			{
1677
				unset($get_vars[$key]);
1678
				continue;
1679
			}
1680
			// set new variables
1681
			$get_vars[$key] = $val;
1682
		}
1683
1684
		// remove vid, rnd
1685
		unset($get_vars['rnd']);
1686
		if($vid)
1687
		{
1688
			$get_vars['vid'] = $vid;
1689
		}
1690
		else
1691
		{
1692
			unset($get_vars['vid']);
1693
		}
1694
1695
		// for compatibility to lower versions
1696
		$act = $get_vars['act'];
1697
		$act_alias = array(
1698
			'dispMemberFriend' => 'dispCommunicationFriend',
1699
			'dispMemberMessages' => 'dispCommunicationMessages',
1700
			'dispDocumentAdminManageDocument' => 'dispDocumentManageDocument',
1701
			'dispModuleAdminSelectList' => 'dispModuleSelectList'
1702
		);
1703
		if($act_alias[$act])
1704
		{
1705
			$get_vars['act'] = $act_alias[$act];
1706
		}
1707
1708
		// organize URL
1709
		$query = '';
1710
		if(count($get_vars) > 0)
1711
		{
1712
			// if using rewrite mod
1713
			if($self->allow_rewrite)
1714
			{
1715
				$var_keys = array_keys($get_vars);
1716
				sort($var_keys);
1717
1718
				$target = join('.', $var_keys);
1719
1720
				$act = $get_vars['act'];
1721
				$vid = $get_vars['vid'];
1722
				$mid = $get_vars['mid'];
1723
				$key = $get_vars['key'];
1724
				$srl = $get_vars['document_srl'];
1725
1726
				$tmpArray = array('rss' => 1, 'atom' => 1, 'api' => 1);
1727
				$is_feed = isset($tmpArray[$act]);
1728
1729
				$target_map = array(
1730
					'vid' => $vid,
1731
					'mid' => $mid,
1732
					'mid.vid' => "$vid/$mid",
1733
					'entry.mid' => "$mid/entry/" . $get_vars['entry'],
1734
					'entry.mid.vid' => "$vid/$mid/entry/" . $get_vars['entry'],
1735
					'document_srl' => $srl,
1736
					'document_srl.mid' => "$mid/$srl",
1737
					'document_srl.vid' => "$vid/$srl",
1738
					'document_srl.mid.vid' => "$vid/$mid/$srl",
1739
					'act' => ($is_feed && $act !== 'api') ? $act : '',
1740
					'act.mid' => $is_feed ? "$mid/$act" : '',
1741
					'act.mid.vid' => $is_feed ? "$vid/$mid/$act" : '',
1742
					'act.document_srl.key' => ($act == 'trackback') ? "$srl/$key/$act" : '',
1743
					'act.document_srl.key.mid' => ($act == 'trackback') ? "$mid/$srl/$key/$act" : '',
1744
					'act.document_srl.key.vid' => ($act == 'trackback') ? "$vid/$srl/$key/$act" : '',
1745
					'act.document_srl.key.mid.vid' => ($act == 'trackback') ? "$vid/$mid/$srl/$key/$act" : ''
1746
				);
1747
1748
				$query = $target_map[$target];
1749
			}
1750
1751
			if(!$query)
1752
			{
1753
				$queries = array();
1754 View Code Duplication
				foreach($get_vars as $key => $val)
1755
				{
1756
					if(is_array($val) && count($val) > 0)
1757
					{
1758
						foreach($val as $k => $v)
1759
						{
1760
							$queries[] = $key . '[' . $k . ']=' . urlencode($v);
1761
						}
1762
					}
1763
					elseif(!is_array($val))
1764
					{
1765
						$queries[] = $key . '=' . urlencode($val);
1766
					}
1767
				}
1768
				if(count($queries) > 0)
1769
				{
1770
					$query = 'index.php?' . join('&', $queries);
1771
				}
1772
			}
1773
		}
1774
1775
		// If using SSL always
1776
		$_use_ssl = $self->get('_use_ssl');
1777
		if($_use_ssl == 'always')
1778
		{
1779
			$query = $self->getRequestUri(ENFORCE_SSL, $domain) . $query;
1780
			// optional SSL use
1781
		}
1782
		elseif($_use_ssl == 'optional')
1783
		{
1784
			$ssl_mode = (($self->get('module') === 'admin') || ($get_vars['module'] === 'admin') || (isset($get_vars['act']) && $self->isExistsSSLAction($get_vars['act']))) ? ENFORCE_SSL : RELEASE_SSL;
1785
			$query = $self->getRequestUri($ssl_mode, $domain) . $query;
1786
			// no SSL
1787
		}
1788
		else
1789
		{
1790
			// currently on SSL but target is not based on SSL
1791
			if($_SERVER['HTTPS'] == 'on')
1792
			{
1793
				$query = $self->getRequestUri(ENFORCE_SSL, $domain) . $query;
1794
			}
1795
			else if($domain) // if $domain is set
1796
			{
1797
				$query = $self->getRequestUri(FOLLOW_REQUEST_SSL, $domain) . $query;
1798
			}
1799
			else
1800
			{
1801
				$query = getScriptPath() . $query;
1802
			}
1803
		}
1804
1805
		if(!$encode)
1806
		{
1807
			return $query;
1808
		}
1809
1810
		if(!$autoEncode)
1811
		{
1812
			return htmlspecialchars($query, ENT_COMPAT | ENT_HTML401, 'UTF-8', FALSE);
1813
		}
1814
1815
		$output = array();
1816
		$encode_queries = array();
1817
		$parsedUrl = parse_url($query);
1818
		parse_str($parsedUrl['query'], $output);
1819
		foreach($output as $key => $value)
0 ignored issues
show
Bug introduced by
The expression $output of type null|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
1820
		{
1821
			if(preg_match('/&([a-z]{2,}|#\d+);/', urldecode($value)))
1822
			{
1823
				$value = urlencode(htmlspecialchars_decode(urldecode($value)));
1824
			}
1825
			$encode_queries[] = $key . '=' . $value;
1826
		}
1827
1828
		return htmlspecialchars($parsedUrl['path'] . '?' . join('&', $encode_queries), ENT_COMPAT | ENT_HTML401, 'UTF-8', FALSE);
1829
	}
1830
1831
	/**
1832
	 * Return after removing an argument on the requested URL
1833
	 *
1834
	 * @param string $ssl_mode SSL mode
1835
	 * @param string $domain Domain
1836
	 * @retrun string converted URL
1837
	 */
1838
	function getRequestUri($ssl_mode = FOLLOW_REQUEST_SSL, $domain = null)
1839
	{
1840
		static $url = array();
1841
1842
		// Check HTTP Request
1843
		if(!isset($_SERVER['SERVER_PROTOCOL']))
1844
		{
1845
			return;
1846
		}
1847
1848
		if(self::get('_use_ssl') == 'always')
1849
		{
1850
			$ssl_mode = ENFORCE_SSL;
1851
		}
1852
1853
		if($domain)
0 ignored issues
show
Bug Best Practice introduced by
The expression $domain of type string|null 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...
1854
		{
1855
			$domain_key = md5($domain);
1856
		}
1857
		else
1858
		{
1859
			$domain_key = 'default';
1860
		}
1861
1862
		if(isset($url[$ssl_mode][$domain_key]))
1863
		{
1864
			return $url[$ssl_mode][$domain_key];
1865
		}
1866
1867
		$current_use_ssl = ($_SERVER['HTTPS'] == 'on');
1868
1869
		switch($ssl_mode)
1870
		{
1871
			case FOLLOW_REQUEST_SSL: $use_ssl = $current_use_ssl;
1872
				break;
1873
			case ENFORCE_SSL: $use_ssl = TRUE;
1874
				break;
1875
			case RELEASE_SSL: $use_ssl = FALSE;
1876
				break;
1877
		}
1878
1879
		if($domain)
0 ignored issues
show
Bug Best Practice introduced by
The expression $domain of type string|null 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...
1880
		{
1881
			$target_url = trim($domain);
1882
			if(substr_compare($target_url, '/', -1) !== 0)
1883
			{
1884
				$target_url.= '/';
1885
			}
1886
		}
1887
		else
1888
		{
1889
			$target_url = $_SERVER['HTTP_HOST'] . getScriptPath();
1890
		}
1891
1892
		$url_info = parse_url('http://' . $target_url);
1893
1894
		if($current_use_ssl != $use_ssl)
0 ignored issues
show
Bug introduced by
The variable $use_ssl does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1895
		{
1896
			unset($url_info['port']);
1897
		}
1898
1899
		if($use_ssl)
1900
		{
1901
			$port = self::get('_https_port');
1902 View Code Duplication
			if($port && $port != 443)
1903
			{
1904
				$url_info['port'] = $port;
1905
			}
1906
			elseif($url_info['port'] == 443)
1907
			{
1908
				unset($url_info['port']);
1909
			}
1910
		}
1911 View Code Duplication
		else
1912
		{
1913
			$port = self::get('_http_port');
1914
			if($port && $port != 80)
1915
			{
1916
				$url_info['port'] = $port;
1917
			}
1918
			elseif($url_info['port'] == 80)
1919
			{
1920
				unset($url_info['port']);
1921
			}
1922
		}
1923
1924
		$url[$ssl_mode][$domain_key] = sprintf('%s://%s%s%s', $use_ssl ? 'https' : $url_info['scheme'], $url_info['host'], $url_info['port'] && $url_info['port'] != 80 ? ':' . $url_info['port'] : '', $url_info['path']);
1925
1926
		return $url[$ssl_mode][$domain_key];
1927
	}
1928
1929
	/**
1930
	 * Set a context value with a key
1931
	 *
1932
	 * @param string $key Key
1933
	 * @param mixed $val Value
1934
	 * @param mixed $set_to_get_vars If not FALSE, Set to get vars.
1935
	 * @return void
1936
	 */
1937
	function set($key, $val, $set_to_get_vars = 0)
1938
	{
1939
		$self = self::getInstance();
1940
		$self->context->{$key} = $val;
1941
		if($set_to_get_vars === FALSE)
1942
		{
1943
			return;
1944
		}
1945
		if($val === NULL || $val === '')
1946
		{
1947
			unset($self->get_vars->{$key});
1948
			return;
1949
		}
1950
		if($set_to_get_vars || $self->get_vars->{$key})
1951
		{
1952
			$self->get_vars->{$key} = $val;
1953
		}
1954
	}
1955
1956
	/**
1957
	 * Return key's value
1958
	 *
1959
	 * @param string $key Key
1960
	 * @return string Key
1961
	 */
1962
	function get($key)
1963
	{
1964
		$self = self::getInstance();
1965
1966
		if(!isset($self->context->{$key}))
1967
		{
1968
			return null;
1969
		}
1970
		return $self->context->{$key};
1971
	}
1972
1973
	/**
1974
	 * Get one more vars in object vars with given arguments(key1, key2, key3,...)
1975
	 *
1976
	 * @return object
1977
	 */
1978
	function gets()
1979
	{
1980
		$num_args = func_num_args();
1981
		if($num_args < 1)
1982
		{
1983
			return;
1984
		}
1985
		$self = self::getInstance();
1986
1987
		$args_list = func_get_args();
1988
		$output = new stdClass();
1989
		foreach($args_list as $v)
1990
		{
1991
			$output->{$v} = $self->get($v);
1992
		}
1993
		return $output;
1994
	}
1995
1996
	/**
1997
	 * Return all data
1998
	 *
1999
	 * @return object All data
2000
	 */
2001
	function getAll()
2002
	{
2003
		$self = self::getInstance();
2004
		return $self->context;
2005
	}
2006
2007
	/**
2008
	 * Return values from the GET/POST/XMLRPC
2009
	 *
2010
	 * @return BaseObject Request variables.
2011
	 */
2012
	function getRequestVars()
2013
	{
2014
		$self = self::getInstance();
2015
		if($self->get_vars)
2016
		{
2017
			return clone($self->get_vars);
2018
		}
2019
		return new stdClass;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return new \stdClass(); (stdClass) is incompatible with the return type documented by Context::getRequestVars of type BaseObject.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
2020
	}
2021
2022
	/**
2023
	 * Register if an action is to be encrypted by SSL. Those actions are sent to https in common/js/xml_handler.js
2024
	 *
2025
	 * @param string $action act name
2026
	 * @return void
2027
	 */
2028
	function addSSLAction($action)
2029
	{
2030
		$self = self::getInstance();
2031
2032
		if(!is_readable($self->sslActionCacheFile))
2033
		{
2034
			$buff = '<?php if(!defined("__XE__"))exit;';
2035
			FileHandler::writeFile($self->sslActionCacheFile, $buff);
0 ignored issues
show
Documentation introduced by
$self->sslActionCacheFile is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2036
		}
2037
2038 View Code Duplication
		if(!isset($self->ssl_actions[$action]))
2039
		{
2040
			$self->ssl_actions[$action] = 1;
2041
			$sslActionCacheString = sprintf('$sslActions[\'%s\'] = 1;', $action);
2042
			FileHandler::writeFile($self->sslActionCacheFile, $sslActionCacheString, 'a');
0 ignored issues
show
Documentation introduced by
$self->sslActionCacheFile is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2043
		}
2044
	}
2045
2046
	/**
2047
	 * Register if actions are to be encrypted by SSL. Those actions are sent to https in common/js/xml_handler.js
2048
	 *
2049
	 * @param string $action act name
0 ignored issues
show
Documentation introduced by
There is no parameter named $action. Did you maybe mean $action_array?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
2050
	 * @return void
2051
	 */
2052
	function addSSLActions($action_array)
2053
	{
2054
		$self = self::getInstance();
2055
2056
		if(!is_readable($self->sslActionCacheFile))
2057
		{
2058
			unset($self->ssl_actions);
2059
			$buff = '<?php if(!defined("__XE__"))exit;';
2060
			FileHandler::writeFile($self->sslActionCacheFile, $buff);
0 ignored issues
show
Documentation introduced by
$self->sslActionCacheFile is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2061
		}
2062
2063
		foreach($action_array as $action)
2064
		{
2065 View Code Duplication
			if(!isset($self->ssl_actions[$action]))
2066
			{
2067
				$self->ssl_actions[$action] = 1;
2068
				$sslActionCacheString = sprintf('$sslActions[\'%s\'] = 1;', $action);
2069
				FileHandler::writeFile($self->sslActionCacheFile, $sslActionCacheString, 'a');
0 ignored issues
show
Documentation introduced by
$self->sslActionCacheFile is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2070
			}
2071
		}
2072
	}
2073
2074
	/**
2075
	 * Delete if action is registerd to be encrypted by SSL.
2076
	 *
2077
	 * @param string $action act name
2078
	 * @return void
2079
	 */
2080
	function subtractSSLAction($action)
2081
	{
2082
		$self = self::getInstance();
2083
2084
		if($self->isExistsSSLAction($action))
2085
		{
2086
			$sslActionCacheString = sprintf('$sslActions[\'%s\'] = 1;', $action);
2087
			$buff = FileHandler::readFile($self->sslActionCacheFile);
0 ignored issues
show
Documentation introduced by
$self->sslActionCacheFile is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2088
			$buff = str_replace($sslActionCacheString, '', $buff);
2089
			FileHandler::writeFile($self->sslActionCacheFile, $buff);
0 ignored issues
show
Documentation introduced by
$self->sslActionCacheFile is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2090
		}
2091
	}
2092
2093
	/**
2094
	 * Get SSL Action
2095
	 *
2096
	 * @return string acts in array
2097
	 */
2098
	function getSSLActions()
2099
	{
2100
		$self = self::getInstance();
2101
		if($self->getSslStatus() == 'optional')
2102
		{
2103
			return $self->ssl_actions;
2104
		}
2105
	}
2106
2107
	/**
2108
	 * Check SSL action are existed
2109
	 *
2110
	 * @param string $action act name
2111
	 * @return bool If SSL exists, return TRUE.
2112
	 */
2113
	function isExistsSSLAction($action)
2114
	{
2115
		$self = self::getInstance();
2116
		return isset($self->ssl_actions[$action]);
2117
	}
2118
2119
	/**
2120
	 * Normalize file path
2121
	 *
2122
	 * @deprecated
2123
	 * @param string $file file path
2124
	 * @return string normalized file path
2125
	 */
2126
	function normalizeFilePath($file)
2127
	{
2128
		if($file{0} != '/' && $file{0} != '.' && strpos($file, '://') === FALSE)
2129
		{
2130
			$file = './' . $file;
2131
		}
2132
		$file = preg_replace('@/\./|(?<!:)\/\/@', '/', $file);
2133
		while(strpos($file, '/../') !== FALSE)
2134
		{
2135
			$file = preg_replace('/\/([^\/]+)\/\.\.\//s', '/', $file, 1);
2136
		}
2137
2138
		return $file;
2139
	}
2140
2141
	/**
2142
	 * Get abstract file url
2143
	 *
2144
	 * @deprecated
2145
	 * @param string $file file path
2146
	 * @return string Converted file path
2147
	 */
2148
	function getAbsFileUrl($file)
2149
	{
2150
		$file = self::normalizeFilePath($file);
0 ignored issues
show
Deprecated Code introduced by
The method Context::normalizeFilePath() has been deprecated.

This method has been deprecated.

Loading history...
2151
		$script_path = getScriptPath();
2152
		if(strpos($file, './') === 0)
2153
		{
2154
			$file = $script_path . substr($file, 2);
2155
		}
2156
		elseif(strpos($file, '../') === 0)
2157
		{
2158
			$file = self::normalizeFilePath($script_path . $file);
0 ignored issues
show
Deprecated Code introduced by
The method Context::normalizeFilePath() has been deprecated.

This method has been deprecated.

Loading history...
2159
		}
2160
2161
		return $file;
2162
	}
2163
2164
	/**
2165
	 * Load front end file
2166
	 *
2167
	 * @param array $args array
2168
	 * case js :
2169
	 * 		$args[0]: file name,
2170
	 * 		$args[1]: type (head | body),
2171
	 * 		$args[2]: target IE,
2172
	 * 		$args[3]: index
2173
	 * case css :
2174
	 * 		$args[0]: file name,
2175
	 * 		$args[1]: media,
2176
	 * 		$args[2]: target IE,
2177
	 * 		$args[3]: index
2178
	 *
2179
	 */
2180
	function loadFile($args)
2181
	{
2182
		$self = self::getInstance();
2183
2184
		$self->oFrontEndFileHandler->loadFile($args);
2185
	}
2186
2187
	/**
2188
	 * Unload front end file
2189
	 *
2190
	 * @param string $file File name with path
2191
	 * @param string $targetIe Target IE
2192
	 * @param string $media Media query
2193
	 * @return void
2194
	 */
2195
	function unloadFile($file, $targetIe = '', $media = 'all')
2196
	{
2197
		$self = self::getInstance();
2198
		$self->oFrontEndFileHandler->unloadFile($file, $targetIe, $media);
2199
	}
2200
2201
	/**
2202
	 * Unload front end file all
2203
	 *
2204
	 * @param string $type Unload target (optional - all|css|js)
2205
	 * @return void
2206
	 */
2207
	function unloadAllFiles($type = 'all')
2208
	{
2209
		$self = self::getInstance();
2210
		$self->oFrontEndFileHandler->unloadAllFiles($type);
2211
	}
2212
2213
	/**
2214
	 * Add the js file
2215
	 *
2216
	 * @deprecated
2217
	 * @param string $file File name with path
2218
	 * @param string $optimized optimized (That seems to not use)
2219
	 * @param string $targetie target IE
2220
	 * @param string $index index
2221
	 * @param string $type Added position. (head:<head>..</head>, body:<body>..</body>)
2222
	 * @param bool $isRuleset Use ruleset
2223
	 * @param string $autoPath If path not readed, set the path automatically.
2224
	 * @return void
2225
	 */
2226
	function addJsFile($file, $optimized = FALSE, $targetie = '', $index = 0, $type = 'head', $isRuleset = FALSE, $autoPath = null)
0 ignored issues
show
Unused Code introduced by
The parameter $optimized is not used and could be removed.

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

Loading history...
2227
	{
2228
		if($isRuleset)
2229
		{
2230
			if(strpos($file, '#') !== FALSE)
2231
			{
2232
				$file = str_replace('#', '', $file);
2233
				if(!is_readable($file))
2234
				{
2235
					$file = $autoPath;
2236
				}
2237
			}
2238
			$validator = new Validator($file);
2239
			$validator->setCacheDir('files/cache');
2240
			$file = $validator->getJsPath();
2241
		}
2242
2243
		$self = self::getInstance();
2244
		$self->oFrontEndFileHandler->loadFile(array($file, $type, $targetie, $index));
2245
	}
2246
2247
	/**
2248
	 * Remove the js file
2249
	 *
2250
	 * @deprecated
2251
	 * @param string $file File name with path
2252
	 * @param string $optimized optimized (That seems to not use)
2253
	 * @param string $targetie target IE
2254
	 * @return void
2255
	 */
2256
	function unloadJsFile($file, $optimized = FALSE, $targetie = '')
0 ignored issues
show
Unused Code introduced by
The parameter $optimized is not used and could be removed.

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

Loading history...
2257
	{
2258
		$self = self::getInstance();
2259
		$self->oFrontEndFileHandler->unloadFile($file, $targetie);
2260
	}
2261
2262
	/**
2263
	 * Unload all javascript files
2264
	 *
2265
	 * @return void
2266
	 */
2267
	function unloadAllJsFiles()
2268
	{
2269
		$self = self::getInstance();
2270
		$self->oFrontEndFileHandler->unloadAllFiles('js');
2271
	}
2272
2273
	/**
2274
	 * Add javascript filter
2275
	 *
2276
	 * @param string $path File path
2277
	 * @param string $filename File name
2278
	 * @return void
2279
	 */
2280
	function addJsFilter($path, $filename)
2281
	{
2282
		$oXmlFilter = new XmlJSFilter($path, $filename);
2283
		$oXmlFilter->compile();
2284
	}
2285
2286
	/**
2287
	 * Same as array_unique but works only for file subscript
2288
	 *
2289
	 * @deprecated
2290
	 * @param array $files File list
2291
	 * @return array File list
2292
	 */
2293
	function _getUniqueFileList($files)
2294
	{
2295
		ksort($files);
2296
		$files = array_values($files);
2297
		$filenames = array();
2298
		for($i = 0, $c = count($files); $i < $c; ++$i)
2299
		{
2300
			if(in_array($files[$i]['file'], $filenames))
2301
			{
2302
				unset($files[$i]);
2303
			}
2304
			$filenames[] = $files[$i]['file'];
2305
		}
2306
2307
		return $files;
2308
	}
2309
2310
	/**
2311
	 * Returns the list of javascripts that matches the given type.
2312
	 *
2313
	 * @param string $type Added position. (head:<head>..</head>, body:<body>..</body>)
2314
	 * @return array Returns javascript file list. Array contains file, targetie.
2315
	 */
2316
	function getJsFile($type = 'head')
2317
	{
2318
		$self = self::getInstance();
2319
		return $self->oFrontEndFileHandler->getJsFileList($type);
2320
	}
2321
2322
	/**
2323
	 * Add CSS file
2324
	 *
2325
	 * @deprecated
2326
	 * @param string $file File name with path
2327
	 * @param string $optimized optimized (That seems to not use)
2328
	 * @param string $media Media query
2329
	 * @param string $targetie target IE
2330
	 * @param string $index index
2331
	 * @return void
2332
	 *
2333
	 */
2334
	function addCSSFile($file, $optimized = FALSE, $media = 'all', $targetie = '', $index = 0)
0 ignored issues
show
Unused Code introduced by
The parameter $optimized is not used and could be removed.

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

Loading history...
2335
	{
2336
		$self = self::getInstance();
2337
		$self->oFrontEndFileHandler->loadFile(array($file, $media, $targetie, $index));
2338
	}
2339
2340
	/**
2341
	 * Remove css file
2342
	 *
2343
	 * @deprecated
2344
	 * @param string $file File name with path
2345
	 * @param string $optimized optimized (That seems to not use)
2346
	 * @param string $media Media query
2347
	 * @param string $targetie target IE
2348
	 * @return void
2349
	 */
2350
	function unloadCSSFile($file, $optimized = FALSE, $media = 'all', $targetie = '')
0 ignored issues
show
Unused Code introduced by
The parameter $optimized is not used and could be removed.

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

Loading history...
2351
	{
2352
		$self = self::getInstance();
2353
		$self->oFrontEndFileHandler->unloadFile($file, $targetie, $media);
2354
	}
2355
2356
	/**
2357
	 * Unload all css files
2358
	 *
2359
	 * @return void
2360
	 */
2361
	function unloadAllCSSFiles()
2362
	{
2363
		$self = self::getInstance();
2364
		$self->oFrontEndFileHandler->unloadAllFiles('css');
2365
	}
2366
2367
	/**
2368
	 * Return a list of css files
2369
	 *
2370
	 * @return array Returns css file list. Array contains file, media, targetie.
2371
	 */
2372
	function getCSSFile()
2373
	{
2374
		$self = self::getInstance();
2375
		return $self->oFrontEndFileHandler->getCssFileList();
2376
	}
2377
2378
	/**
2379
	 * Returns javascript plugin file info
2380
	 * @param string $pluginName
2381
	 * @return stdClass
2382
	 */
2383
	function getJavascriptPluginInfo($pluginName)
2384
	{
2385
		if($plugin_name == 'ui.datepicker')
0 ignored issues
show
Bug introduced by
The variable $plugin_name seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
2386
		{
2387
			$plugin_name = 'ui';
0 ignored issues
show
Unused Code introduced by
$plugin_name 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...
2388
		}
2389
2390
		$plugin_path = './common/js/plugins/' . $pluginName . '/';
2391
		$info_file = $plugin_path . 'plugin.load';
2392
		if(!is_readable($info_file))
2393
		{
2394
			return;
2395
		}
2396
2397
		$list = file($info_file);
2398
		$result = new stdClass();
2399
		$result->jsList = array();
2400
		$result->cssList = array();
2401
2402
		foreach($list as $filename)
2403
		{
2404
			$filename = trim($filename);
2405
			if(!$filename)
2406
			{
2407
				continue;
2408
			}
2409
2410
			if(strncasecmp('./', $filename, 2) === 0)
2411
			{
2412
				$filename = substr($filename, 2);
2413
			}
2414
2415
			if(substr_compare($filename, '.js', -3) === 0)
2416
			{
2417
				$result->jsList[] = $plugin_path . $filename;
2418
			}
2419
			elseif(substr_compare($filename, '.css', -4) === 0)
2420
			{
2421
				$result->cssList[] = $plugin_path . $filename;
2422
			}
2423
		}
2424
2425
		if(is_dir($plugin_path . 'lang'))
2426
		{
2427
			$result->langPath = $plugin_path . 'lang';
2428
		}
2429
2430
		return $result;
2431
	}
2432
	/**
2433
	 * Load javascript plugin
2434
	 *
2435
	 * @param string $plugin_name plugin name
2436
	 * @return void
2437
	 */
2438
	function loadJavascriptPlugin($plugin_name)
2439
	{
2440
		static $loaded_plugins = array();
2441
2442
		$self = self::getInstance();
2443
		if($plugin_name == 'ui.datepicker')
2444
		{
2445
			$plugin_name = 'ui';
2446
		}
2447
2448
		if($loaded_plugins[$plugin_name])
2449
		{
2450
			return;
2451
		}
2452
		$loaded_plugins[$plugin_name] = TRUE;
2453
2454
		$plugin_path = './common/js/plugins/' . $plugin_name . '/';
2455
		$info_file = $plugin_path . 'plugin.load';
2456
		if(!is_readable($info_file))
2457
		{
2458
			return;
2459
		}
2460
2461
		$list = file($info_file);
2462
		foreach($list as $filename)
2463
		{
2464
			$filename = trim($filename);
2465
			if(!$filename)
2466
			{
2467
				continue;
2468
			}
2469
2470
			if(strncasecmp('./', $filename, 2) === 0)
2471
			{
2472
				$filename = substr($filename, 2);
2473
			}
2474 View Code Duplication
			if(substr_compare($filename, '.js', -3) === 0)
2475
			{
2476
				$self->loadFile(array($plugin_path . $filename, 'body', '', 0), TRUE);
0 ignored issues
show
Unused Code introduced by
The call to Context::loadFile() has too many arguments starting with TRUE.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
2477
			}
2478 View Code Duplication
			if(substr_compare($filename, '.css', -4) === 0)
2479
			{
2480
				$self->loadFile(array($plugin_path . $filename, 'all', '', 0), TRUE);
0 ignored issues
show
Unused Code introduced by
The call to Context::loadFile() has too many arguments starting with TRUE.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
2481
			}
2482
		}
2483
2484
		if(is_dir($plugin_path . 'lang'))
2485
		{
2486
			$self->loadLang($plugin_path . 'lang');
2487
		}
2488
	}
2489
2490
	/**
2491
	 * Add html code before </head>
2492
	 *
2493
	 * @param string $header add html code before </head>.
2494
	 * @return void
2495
	 */
2496
	function addHtmlHeader($header)
2497
	{
2498
		$self = self::getInstance();
2499
		$self->html_header .= "\n" . $header;
2500
	}
2501
2502
	function clearHtmlHeader()
2503
	{
2504
		$self = self::getInstance();
2505
		$self->html_header = '';
2506
	}
2507
2508
	/**
2509
	 * Returns added html code by addHtmlHeader()
2510
	 *
2511
	 * @return string Added html code before </head>
2512
	 */
2513
	function getHtmlHeader()
2514
	{
2515
		$self = self::getInstance();
2516
		return $self->html_header;
2517
	}
2518
2519
	/**
2520
	 * Add css class to Html Body
2521
	 *
2522
	 * @param string $class_name class name
2523
	 */
2524
	function addBodyClass($class_name)
2525
	{
2526
		$self = self::getInstance();
2527
		$self->body_class[] = $class_name;
2528
	}
2529
2530
	/**
2531
	 * Return css class to Html Body
2532
	 *
2533
	 * @return string Return class to html body
2534
	 */
2535
	function getBodyClass()
2536
	{
2537
		$self = self::getInstance();
2538
		$self->body_class = array_unique($self->body_class);
2539
2540
		return (count($self->body_class) > 0) ? sprintf(' class="%s"', join(' ', $self->body_class)) : '';
2541
	}
2542
2543
	/**
2544
	 * Add html code after <body>
2545
	 *
2546
	 * @param string $header Add html code after <body>
2547
	 */
2548
	function addBodyHeader($header)
2549
	{
2550
		$self = self::getInstance();
2551
		$self->body_header .= "\n" . $header;
2552
	}
2553
2554
	/**
2555
	 * Returns added html code by addBodyHeader()
2556
	 *
2557
	 * @return string Added html code after <body>
2558
	 */
2559
	function getBodyHeader()
2560
	{
2561
		$self = self::getInstance();
2562
		return $self->body_header;
2563
	}
2564
2565
	/**
2566
	 * Add html code before </body>
2567
	 *
2568
	 * @param string $footer Add html code before </body>
2569
	 */
2570
	function addHtmlFooter($footer)
2571
	{
2572
		$self = self::getInstance();
2573
		$self->html_footer .= ($self->Htmlfooter ? "\n" : '') . $footer;
0 ignored issues
show
Bug introduced by
The property Htmlfooter does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
2574
	}
2575
2576
	/**
2577
	 * Returns added html code by addHtmlHeader()
2578
	 *
2579
	 * @return string Added html code before </body>
2580
	 */
2581
	function getHtmlFooter()
2582
	{
2583
		$self = self::getInstance();
2584
		return $self->html_footer;
2585
	}
2586
2587
	/**
2588
	 * Get config file
2589
	 *
2590
	 * @retrun string The path of the config file that contains database settings
2591
	 */
2592
	function getConfigFile()
2593
	{
2594
		return _XE_PATH_ . 'files/config/db.config.php';
2595
	}
2596
2597
	/**
2598
	 * Get FTP config file
2599
	 *
2600
	 * @return string The path of the config file that contains FTP settings
2601
	 */
2602
	function getFTPConfigFile()
2603
	{
2604
		return _XE_PATH_ . 'files/config/ftp.config.php';
2605
	}
2606
2607
	/**
2608
	 * Checks whether XE is installed
2609
	 *
2610
	 * @return bool True if the config file exists, otherwise FALSE.
2611
	 */
2612
	function isInstalled()
2613
	{
2614
		return FileHandler::hasContent(self::getConfigFile());
2615
	}
2616
2617
	/**
2618
	 * Transforms codes about widget or other features into the actual code, deprecatred
2619
	 *
2620
	 * @param string Transforms codes
2621
	 * @return string Transforms codes
2622
	 */
2623
	function transContent($content)
2624
	{
2625
		return $content;
2626
	}
2627
2628
	/**
2629
	 * Check whether it is allowed to use rewrite mod
2630
	 *
2631
	 * @return bool True if it is allowed to use rewrite mod, otherwise FALSE
2632
	 */
2633
	function isAllowRewrite()
2634
	{
2635
		$oContext = self::getInstance();
2636
		return $oContext->allow_rewrite;
2637
	}
2638
2639
	/**
2640
	 * Converts a local path into an URL
2641
	 *
2642
	 * @param string $path URL path
2643
	 * @return string Converted path
2644
	 */
2645
	function pathToUrl($path)
2646
	{
2647
		$xe = _XE_PATH_;
2648
		$path = strtr($path, "\\", "/");
2649
2650
		$base_url = preg_replace('@^https?://[^/]+/?@', '', self::getRequestUri());
2651
2652
		$_xe = explode('/', $xe);
2653
		$_path = explode('/', $path);
2654
		$_base = explode('/', $base_url);
2655
2656
		if(!$_base[count($_base) - 1])
2657
		{
2658
			array_pop($_base);
2659
		}
2660
2661
		foreach($_xe as $idx => $dir)
2662
		{
2663
			if($_path[0] != $dir)
2664
			{
2665
				break;
2666
			}
2667
			array_shift($_path);
2668
		}
2669
2670
		$idx = count($_xe) - $idx - 1;
0 ignored issues
show
Bug introduced by
The variable $idx does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2671
		while($idx--)
2672
		{
2673
			if(count($_base) > 0)
2674
			{
2675
				array_shift($_base);
2676
			}
2677
			else
2678
			{
2679
				array_unshift($_base, '..');
2680
			}
2681
		}
2682
2683
		if(count($_base) > 0)
2684
		{
2685
			array_unshift($_path, join('/', $_base));
2686
		}
2687
2688
		$path = '/' . join('/', $_path);
2689
		if(substr_compare($path, '/', -1) !== 0)
2690
		{
2691
			$path .= '/';
2692
		}
2693
		return $path;
2694
	}
2695
2696
	/**
2697
	 * Get meta tag
2698
	 * @return array The list of meta tags
2699
	 */
2700
	function getMetaTag()
2701
	{
2702
		$self = self::getInstance();
2703
2704
		if(!is_array($self->meta_tags))
2705
		{
2706
			$self->meta_tags = array();
0 ignored issues
show
Bug introduced by
The property meta_tags does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
2707
		}
2708
2709
		$ret = array();
2710
		foreach($self->meta_tags as $key => $val)
2711
		{
2712
			list($name, $is_http_equiv) = explode("\t", $key);
2713
			$ret[] = array('name' => $name, 'is_http_equiv' => $is_http_equiv, 'content' => $val);
2714
		}
2715
2716
		return $ret;
2717
	}
2718
2719
	/**
2720
	 * Add the meta tag
2721
	 *
2722
	 * @param string $name name of meta tag
2723
	 * @param string $content content of meta tag
2724
	 * @param mixed $is_http_equiv value of http_equiv
2725
	 * @return void
2726
	 */
2727
	function addMetaTag($name, $content, $is_http_equiv = FALSE)
2728
	{
2729
		$self = self::getInstance();
2730
		$self->meta_tags[$name . "\t" . ($is_http_equiv ? '1' : '0')] = $content;
2731
	}
2732
2733
}
2734
/* End of file Context.class.php */
2735
/* Location: ./classes/context/Context.class.php */
2736