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 — master ( b130b6...8a2f54 )
by gyeong-won
07:36
created

Context::getFTPInfo()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 0
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
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
177
	 */
178
	function Context()
0 ignored issues
show
Coding Style Best Practice introduced by
Please use __construct() instead of a PHP4-style constructor that is named after the class.
Loading history...
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);
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
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', 'CP932',
1037
			'EUC-CN', 'HZ', 'GBK', 'GB18030', 'EUC-TW', 'BIG5', 'CP950', 'BIG5-HKSCS',
1038
			'ISO2022-CN', 'ISO2022-CN-EXT', 'ISO2022-JP', 'ISO2022-JP-2', 'ISO2022-JP-1',
1039
			'ISO8859-6', 'ISO8859-8', 'JOHAB', 'ISO2022-KR', 'CP1255', 'CP1256', 'CP862',
1040
			'ASCII', 'ISO8859-1', 'ISO8850-2', 'ISO8850-3', 'ISO8850-4', 'ISO8850-5',
1041
			'ISO8850-7', 'ISO8850-9', 'ISO8850-10', 'ISO8850-13', 'ISO8850-14',
1042
			'ISO8850-15', 'ISO8850-16', 'CP1250', 'CP1251', 'CP1252', 'CP1253', 'CP1254',
1043
			'CP1257', 'CP850', 'CP866',
1044
		);
1045
1046
		$obj = clone $source_obj;
1047
1048
		foreach($charset_list as $charset)
1049
		{
1050
			array_walk($obj,'Context::checkConvertFlag',$charset);
1051
			$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...
1052
			if($flag)
1053
			{
1054
				if($charset == 'UTF-8')
1055
				{
1056
					return $obj;
1057
				}
1058
				array_walk($obj,'Context::doConvertEncoding',$charset);
1059
				return $obj;
1060
			}
1061
		}
1062
		return $obj;
1063
	}
1064
1065
	/**
1066
	 * Check flag
1067
	 *
1068
	 * @param mixed $val
1069
	 * @param string $key
1070
	 * @param mixed $charset charset
1071
	 * @see arrayConvWalkCallback will replaced array_walk_recursive in >=PHP5
1072
	 * @return void
1073
	 */
1074
	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...
1075
	{
1076
		static $flag = TRUE;
1077
		if($charset)
1078
		{
1079
			if(is_array($val))
1080
				array_walk($val,'Context::checkConvertFlag',$charset);
1081
			else if($val && iconv($charset,$charset,$val)!=$val) $flag = FALSE;
1082
			else $flag = FALSE;
1083
		}
1084
		else
1085
		{
1086
			$return = $flag;
1087
			$flag = TRUE;
1088
			return $return;
1089
		}
1090
	}
1091
1092
	/**
1093
	 * Convert array type variables into UTF-8
1094
	 *
1095
	 * @param mixed $val
1096
	 * @param string $key
1097
	 * @param string $charset character set
1098
	 * @see arrayConvWalkCallback will replaced array_walk_recursive in >=PHP5
1099
	 * @return object converted object
1100
	 */
1101
	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...
1102
	{
1103
		if (is_array($val))
1104
		{
1105
			array_walk($val,'Context::doConvertEncoding',$charset);
1106
		}
1107
		else $val = iconv($charset,'UTF-8',$val);
1108
	}
1109
1110
	/**
1111
	 * Convert strings into UTF-8
1112
	 *
1113
	 * @param string $str String to convert
1114
	 * @return string converted string
1115
	 */
1116
	function convertEncodingStr($str)
1117
	{
1118
        if(!$str) return null;
1119
		$obj = new stdClass();
1120
		$obj->str = $str;
1121
		$obj = self::convertEncoding($obj);
1122
		return $obj->str;
1123
	}
1124
1125
	function decodeIdna($domain)
1126
	{
1127
		if(strpos($domain, 'xn--') !== FALSE)
1128
		{
1129
			require_once(_XE_PATH_ . 'libs/idna_convert/idna_convert.class.php');
1130
			$IDN = new idna_convert(array('idn_version' => 2008));
1131
			$domain = $IDN->decode($domain);
1132
		}
1133
1134
		return $domain;
1135
	}
1136
1137
	/**
1138
	 * Force to set response method
1139
	 *
1140
	 * @param string $method Response method. [HTML|XMLRPC|JSON]
1141
	 * @return void
1142
	 */
1143
	function setResponseMethod($method = 'HTML')
1144
	{
1145
		$self = self::getInstance();
1146
1147
		$methods = array('HTML' => 1, 'XMLRPC' => 1, 'JSON' => 1, 'JS_CALLBACK' => 1);
1148
		$self->response_method = isset($methods[$method]) ? $method : 'HTML';
1149
	}
1150
1151
	/**
1152
	 * Get reponse method
1153
	 *
1154
	 * @return string Response method. If it's not set, returns request method.
1155
	 */
1156
	function getResponseMethod()
1157
	{
1158
		$self = self::getInstance();
1159
1160
		if($self->response_method)
1161
		{
1162
			return $self->response_method;
1163
		}
1164
1165
		$method = $self->getRequestMethod();
1166
		$methods = array('HTML' => 1, 'XMLRPC' => 1, 'JSON' => 1, 'JS_CALLBACK' => 1);
1167
1168
		return isset($methods[$method]) ? $method : 'HTML';
1169
	}
1170
1171
	/**
1172
	 * Determine request method
1173
	 *
1174
	 * @param string $type Request method. (Optional - GET|POST|XMLRPC|JSON)
1175
	 * @return void
1176
	 */
1177
	function setRequestMethod($type = '')
1178
	{
1179
		$self = self::getInstance();
1180
1181
		$self->js_callback_func = $self->getJSCallbackFunc();
1182
1183
		($type && $self->request_method = $type) or
1184
				((strpos($_SERVER['CONTENT_TYPE'], 'json') || strpos($_SERVER['HTTP_CONTENT_TYPE'], 'json')) && $self->request_method = 'JSON') or
1185
				($GLOBALS['HTTP_RAW_POST_DATA'] && $self->request_method = 'XMLRPC') or
1186
				($self->js_callback_func && $self->request_method = 'JS_CALLBACK') or
1187
				($self->request_method = $_SERVER['REQUEST_METHOD']);
1188
	}
1189
1190
	/**
1191
	 * handle global arguments
1192
	 *
1193
	 * @return void
1194
	 */
1195
	function _checkGlobalVars()
1196
	{
1197
		$this->_recursiveCheckVar($_SERVER['HTTP_HOST']);
1198
1199
		$pattern = "/[\,\"\'\{\}\[\]\(\);$]/";
1200
		if(preg_match($pattern, $_SERVER['HTTP_HOST']))
1201
		{
1202
			$this->isSuccessInit = FALSE;
1203
		}
1204
	}
1205
1206
	/**
1207
	 * handle request arguments for GET/POST
1208
	 *
1209
	 * @return void
1210
	 */
1211
	function _setRequestArgument()
1212
	{
1213
		if(!count($_REQUEST))
1214
		{
1215
			return;
1216
		}
1217
1218
		$requestMethod = $this->getRequestMethod();
1219
		foreach($_REQUEST as $key => $val)
1220
		{
1221
			if($val === '' || self::get($key))
1222
			{
1223
				continue;
1224
			}
1225
			$key = htmlentities($key);
1226
			$val = $this->_filterRequestVar($key, $val);
1227
1228
			if($requestMethod == 'GET' && isset($_GET[$key]))
1229
			{
1230
				$set_to_vars = TRUE;
1231
			}
1232
			elseif($requestMethod == 'POST' && isset($_POST[$key]))
1233
			{
1234
				$set_to_vars = TRUE;
1235
			}
1236
			elseif($requestMethod == 'JS_CALLBACK' && (isset($_GET[$key]) || isset($_POST[$key])))
1237
			{
1238
				$set_to_vars = TRUE;
1239
			}
1240
			else
1241
			{
1242
				$set_to_vars = FALSE;
1243
			}
1244
1245
			if($set_to_vars)
1246
			{
1247
				$this->_recursiveCheckVar($val);
1248
			}
1249
1250
			$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...
1251
		}
1252
	}
1253
1254
	function _recursiveCheckVar($val)
1255
	{
1256
		if(is_string($val))
1257
		{
1258
			foreach($this->patterns as $pattern)
1259
			{
1260
				if(preg_match($pattern, $val))
1261
				{
1262
					$this->isSuccessInit = FALSE;
1263
					return;
1264
				}
1265
			}
1266
		}
1267
		else if(is_array($val))
1268
		{
1269
			foreach($val as $val2)
1270
			{
1271
				$this->_recursiveCheckVar($val2);
1272
			}
1273
		}
1274
	}
1275
1276
	/**
1277
	 * Handle request arguments for JSON
1278
	 *
1279
	 * @return void
1280
	 */
1281
	function _setJSONRequestArgument()
1282
	{
1283
		if($this->getRequestMethod() != 'JSON')
1284
		{
1285
			return;
1286
		}
1287
1288
		$params = array();
1289
		parse_str($GLOBALS['HTTP_RAW_POST_DATA'], $params);
1290
1291
		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...
1292
		{
1293
			$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...
1294
		}
1295
	}
1296
1297
	/**
1298
	 * Handle request arguments for XML RPC
1299
	 *
1300
	 * @return void
1301
	 */
1302
	function _setXmlRpcArgument()
1303
	{
1304
		if($this->getRequestMethod() != 'XMLRPC')
1305
		{
1306
			return;
1307
		}
1308
1309
		$xml = $GLOBALS['HTTP_RAW_POST_DATA'];
1310
		if(Security::detectingXEE($xml))
1311
		{
1312
			header("HTTP/1.0 400 Bad Request");
1313
			exit;
1314
		}
1315
1316
		$oXml = new XmlParser();
1317
		$xml_obj = $oXml->parse($xml);
1318
1319
		$params = $xml_obj->methodcall->params;
1320
		unset($params->node_name, $params->attrs, $params->body);
1321
1322
		if(!count(get_object_vars($params)))
1323
		{
1324
			return;
1325
		}
1326
1327
		foreach($params as $key => $val)
1328
		{
1329
			$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...
1330
		}
1331
	}
1332
1333
	/**
1334
	 * Filter xml variables
1335
	 *
1336
	 * @param string $key Variable key
1337
	 * @param object $val Variable value
1338
	 * @return mixed filtered value
1339
	 */
1340
	function _filterXmlVars($key, $val)
1341
	{
1342
		if(is_array($val))
1343
		{
1344
			$stack = array();
1345
			foreach($val as $k => $v)
1346
			{
1347
				$stack[$k] = $this->_filterXmlVars($k, $v);
1348
			}
1349
1350
			return $stack;
1351
		}
1352
1353
		$body = $val->body;
1354
		unset($val->node_name, $val->attrs, $val->body);
1355
		if(!count(get_object_vars($val)))
1356
		{
1357
			return $this->_filterRequestVar($key, $body, 0);
1358
		}
1359
1360
		$stack = new stdClass();
1361
		foreach($val as $k => $v)
1362
		{
1363
			$output = $this->_filterXmlVars($k, $v);
1364
			if(is_object($v) && $v->attrs->type == 'array')
1365
			{
1366
				$output = array($output);
1367
			}
1368
			if($k == 'value' && (is_array($v) || $v->attrs->type == 'array'))
1369
			{
1370
				return $output;
1371
			}
1372
1373
			$stack->{$k} = $output;
1374
		}
1375
1376
		if(!count(get_object_vars($stack)))
1377
		{
1378
			return NULL;
1379
		}
1380
1381
		return $stack;
1382
	}
1383
1384
	/**
1385
	 * Filter request variable
1386
	 *
1387
	 * @see Cast variables, such as _srl, page, and cpage, into interger
1388
	 * @param string $key Variable key
1389
	 * @param string $val Variable value
1390
	 * @param string $do_stripslashes Whether to strip slashes
1391
	 * @return mixed filtered value. Type are string or array
1392
	 */
1393
	function _filterRequestVar($key, $val, $do_stripslashes = 1)
1394
	{
1395
		if(!($isArray = is_array($val)))
1396
		{
1397
			$val = array($val);
1398
		}
1399
1400
		$result = array();
1401
		foreach($val as $k => $v)
1402
		{
1403
			$k = htmlentities($k);
1404
			if($key === 'page' || $key === 'cpage' || substr_compare($key, 'srl', -3) === 0)
1405
			{
1406
				$result[$k] = !preg_match('/^[0-9,]+$/', $v) ? (int) $v : $v;
1407
			}
1408 View Code Duplication
			elseif($key === 'mid' || $key === 'search_keyword')
1409
			{
1410
				$result[$k] = htmlspecialchars($v, ENT_COMPAT | ENT_HTML401, 'UTF-8', FALSE);
1411
			}
1412
			elseif($key === 'vid')
1413
			{
1414
				$result[$k] = urlencode($v);
1415
			}
1416 View Code Duplication
			elseif($key === 'xe_validator_id')
1417
			{
1418
				$result[$k] = htmlspecialchars($v, ENT_COMPAT | ENT_HTML401, 'UTF-8', FALSE);
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
		}
1450
1451
		return $isArray ? $result : $result[0];
1452
	}
1453
1454
	/**
1455
	 * Check if there exists uploaded file
1456
	 *
1457
	 * @return bool True: exists, False: otherwise
1458
	 */
1459
	function isUploaded()
1460
	{
1461
		$self = self::getInstance();
1462
		return $self->is_uploaded;
1463
	}
1464
1465
	/**
1466
	 * Handle uploaded file
1467
	 *
1468
	 * @return void
1469
	 */
1470
	function _setUploadedArgument()
1471
	{
1472
		if($_SERVER['REQUEST_METHOD'] != 'POST' || !$_FILES || (stripos($_SERVER['CONTENT_TYPE'], 'multipart/form-data') === FALSE && stripos($_SERVER['HTTP_CONTENT_TYPE'], 'multipart/form-data') === FALSE))
1473
		{
1474
			return;
1475
		}
1476
1477
		foreach($_FILES as $key => $val)
1478
		{
1479
			$tmp_name = $val['tmp_name'];
1480
			if(!is_array($tmp_name))
1481
			{
1482
				if(!$tmp_name || !is_uploaded_file($tmp_name))
1483
				{
1484
					continue;
1485
				}
1486
				$val['name'] = htmlspecialchars($val['name'], ENT_COMPAT | ENT_HTML401, 'UTF-8', FALSE);
1487
				$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...
1488
				$this->is_uploaded = TRUE;
1489
			}
1490
			else
1491
			{
1492
				$files = array();
1493
				$count_files = count($tmp_name);
1494
1495
				for($i = 0; $i < $count_files; $i++)
1496
				{
1497
					if($val['size'][$i] > 0)
1498
					{
1499
						$file = array();
1500
						$file['name'] = $val['name'][$i];
1501
						$file['type'] = $val['type'][$i];
1502
						$file['tmp_name'] = $val['tmp_name'][$i];
1503
						$file['error'] = $val['error'][$i];
1504
						$file['size'] = $val['size'][$i];
1505
						$files[] = $file;
1506
					}
1507
				}
1508
				if($files) $this->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...
Bug Best Practice introduced by
The expression $files 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...
1509
			}
1510
		}
1511
	}
1512
1513
	/**
1514
	 * Return request method
1515
	 * @return string Request method type. (Optional - GET|POST|XMLRPC|JSON)
1516
	 */
1517
	function getRequestMethod()
1518
	{
1519
		$self = self::getInstance();
1520
		return $self->request_method;
1521
	}
1522
1523
	/**
1524
	 * Return request URL
1525
	 * @return string request URL
1526
	 */
1527
	function getRequestUrl()
1528
	{
1529
		static $url = null;
1530
		if(is_null($url))
1531
		{
1532
			$url = self::getRequestUri();
1533
			if(count($_GET) > 0)
1534
			{
1535
				foreach($_GET as $key => $val)
1536
				{
1537
					$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...
1538
				}
1539
				$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...
1540
			}
1541
		}
1542
		return $url;
1543
	}
1544
1545
	/**
1546
	 * Return js callback func.
1547
	 * @return string callback func.
1548
	 */
1549
	function getJSCallbackFunc()
1550
	{
1551
		$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...
1552
		$js_callback_func = isset($_GET['xe_js_callback']) ? $_GET['xe_js_callback'] : $_POST['xe_js_callback'];
1553
1554
		if(!preg_match('/^[a-z0-9\.]+$/i', $js_callback_func))
1555
		{
1556
			unset($js_callback_func);
1557
			unset($_GET['xe_js_callback']);
1558
			unset($_POST['xe_js_callback']);
1559
		}
1560
1561
		return $js_callback_func;
1562
	}
1563
1564
	/**
1565
	 * Make URL with args_list upon request URL
1566
	 *
1567
	 * @param int $num_args Arguments nums
1568
	 * @param array $args_list Argument list for set url
1569
	 * @param string $domain Domain
1570
	 * @param bool $encode If TRUE, use url encode.
1571
	 * @param bool $autoEncode If TRUE, url encode automatically, detailed. Use this option, $encode value should be TRUE
1572
	 * @return string URL
1573
	 */
1574
	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...
1575
	{
1576
		static $site_module_info = null;
1577
		static $current_info = null;
1578
1579
		$self = self::getInstance();
1580
1581
		// retrieve virtual site information
1582
		if(is_null($site_module_info))
1583
		{
1584
			$site_module_info = self::get('site_module_info');
1585
		}
1586
1587
		// If $domain is set, handle it (if $domain is vid type, remove $domain and handle with $vid)
1588
		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...
1589
		{
1590
			$vid = $domain;
1591
			$domain = '';
1592
		}
1593
1594
		// If $domain, $vid are not set, use current site information
1595
		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...
1596
		{
1597
			if($site_module_info->domain && isSiteID($site_module_info->domain))
1598
			{
1599
				$vid = $site_module_info->domain;
1600
			}
1601
			else
1602
			{
1603
				$domain = $site_module_info->domain;
1604
			}
1605
		}
1606
1607
		// if $domain is set, compare current URL. If they are same, remove the domain, otherwise link to the domain.
1608
		if($domain)
1609
		{
1610
			$domain_info = parse_url($domain);
1611
			if(is_null($current_info))
1612
			{
1613
				$current_info = parse_url(($_SERVER['HTTPS'] == 'on' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . getScriptPath());
1614
			}
1615
			if($domain_info['host'] . $domain_info['path'] == $current_info['host'] . $current_info['path'])
1616
			{
1617
				unset($domain);
1618
			}
1619
			else
1620
			{
1621
				$domain = preg_replace('/^(http|https):\/\//i', '', trim($domain));
1622
				if(substr_compare($domain, '/', -1) !== 0)
1623
				{
1624
					$domain .= '/';
1625
				}
1626
			}
1627
		}
1628
1629
		$get_vars = array();
1630
1631
		// If there is no GET variables or first argument is '' to reset variables
1632
		if(!$self->get_vars || $args_list[0] == '')
1633
		{
1634
			// rearrange args_list
1635
			if(is_array($args_list) && $args_list[0] == '')
1636
			{
1637
				array_shift($args_list);
1638
			}
1639
		}
1640
		elseif($_SERVER['REQUEST_METHOD'] == 'GET')
1641
		{
1642
			// Otherwise, make GET variables into array
1643
			$get_vars = get_object_vars($self->get_vars);
1644
		}
1645
		else
1646
		{
1647
			if(!!$self->get_vars->module) $get_vars['module'] = $self->get_vars->module;
1648
			if(!!$self->get_vars->mid) $get_vars['mid'] = $self->get_vars->mid;
1649
			if(!!$self->get_vars->act) $get_vars['act'] = $self->get_vars->act;
1650
			if(!!$self->get_vars->page) $get_vars['page'] = $self->get_vars->page;
1651
			if(!!$self->get_vars->search_target) $get_vars['search_target'] = $self->get_vars->search_target;
1652
			if(!!$self->get_vars->search_keyword) $get_vars['search_keyword'] = $self->get_vars->search_keyword;
1653
			if($get_vars['act'] == 'IS')
1654
			{
1655
				if(!!$self->get_vars->is_keyword) $get_vars['is_keyword'] = $self->get_vars->is_keyword;
1656
			}
1657
		}
1658
1659
		// arrange args_list
1660
		for($i = 0, $c = count($args_list); $i < $c; $i += 2)
1661
		{
1662
			$key = $args_list[$i];
1663
			$val = trim($args_list[$i + 1]);
1664
1665
			// If value is not set, remove the key
1666
			if(!isset($val) || !strlen($val))
1667
			{
1668
				unset($get_vars[$key]);
1669
				continue;
1670
			}
1671
			// set new variables
1672
			$get_vars[$key] = $val;
1673
		}
1674
1675
		// remove vid, rnd
1676
		unset($get_vars['rnd']);
1677
		if($vid)
1678
		{
1679
			$get_vars['vid'] = $vid;
1680
		}
1681
		else
1682
		{
1683
			unset($get_vars['vid']);
1684
		}
1685
1686
		// for compatibility to lower versions
1687
		$act = $get_vars['act'];
1688
		$act_alias = array(
1689
			'dispMemberFriend' => 'dispCommunicationFriend',
1690
			'dispMemberMessages' => 'dispCommunicationMessages',
1691
			'dispDocumentAdminManageDocument' => 'dispDocumentManageDocument',
1692
			'dispModuleAdminSelectList' => 'dispModuleSelectList'
1693
		);
1694
		if($act_alias[$act])
1695
		{
1696
			$get_vars['act'] = $act_alias[$act];
1697
		}
1698
1699
		// organize URL
1700
		$query = '';
1701
		if(count($get_vars) > 0)
1702
		{
1703
			// if using rewrite mod
1704
			if($self->allow_rewrite)
1705
			{
1706
				$var_keys = array_keys($get_vars);
1707
				sort($var_keys);
1708
1709
				$target = join('.', $var_keys);
1710
1711
				$act = $get_vars['act'];
1712
				$vid = $get_vars['vid'];
1713
				$mid = $get_vars['mid'];
1714
				$key = $get_vars['key'];
1715
				$srl = $get_vars['document_srl'];
1716
1717
				$tmpArray = array('rss' => 1, 'atom' => 1, 'api' => 1);
1718
				$is_feed = isset($tmpArray[$act]);
1719
1720
				$target_map = array(
1721
					'vid' => $vid,
1722
					'mid' => $mid,
1723
					'mid.vid' => "$vid/$mid",
1724
					'entry.mid' => "$mid/entry/" . $get_vars['entry'],
1725
					'entry.mid.vid' => "$vid/$mid/entry/" . $get_vars['entry'],
1726
					'document_srl' => $srl,
1727
					'document_srl.mid' => "$mid/$srl",
1728
					'document_srl.vid' => "$vid/$srl",
1729
					'document_srl.mid.vid' => "$vid/$mid/$srl",
1730
					'act' => ($is_feed && $act !== 'api') ? $act : '',
1731
					'act.mid' => $is_feed ? "$mid/$act" : '',
1732
					'act.mid.vid' => $is_feed ? "$vid/$mid/$act" : '',
1733
					'act.document_srl.key' => ($act == 'trackback') ? "$srl/$key/$act" : '',
1734
					'act.document_srl.key.mid' => ($act == 'trackback') ? "$mid/$srl/$key/$act" : '',
1735
					'act.document_srl.key.vid' => ($act == 'trackback') ? "$vid/$srl/$key/$act" : '',
1736
					'act.document_srl.key.mid.vid' => ($act == 'trackback') ? "$vid/$mid/$srl/$key/$act" : ''
1737
				);
1738
1739
				$query = $target_map[$target];
1740
			}
1741
1742
			if(!$query)
1743
			{
1744
				$queries = array();
1745 View Code Duplication
				foreach($get_vars as $key => $val)
1746
				{
1747
					if(is_array($val) && count($val) > 0)
1748
					{
1749
						foreach($val as $k => $v)
1750
						{
1751
							$queries[] = $key . '[' . $k . ']=' . urlencode($v);
1752
						}
1753
					}
1754
					elseif(!is_array($val))
1755
					{
1756
						$queries[] = $key . '=' . urlencode($val);
1757
					}
1758
				}
1759
				if(count($queries) > 0)
1760
				{
1761
					$query = 'index.php?' . join('&', $queries);
1762
				}
1763
			}
1764
		}
1765
1766
		// If using SSL always
1767
		$_use_ssl = $self->get('_use_ssl');
1768
		if($_use_ssl == 'always')
1769
		{
1770
			$query = $self->getRequestUri(ENFORCE_SSL, $domain) . $query;
1771
			// optional SSL use
1772
		}
1773
		elseif($_use_ssl == 'optional')
1774
		{
1775
			$ssl_mode = (($self->get('module') === 'admin') || ($get_vars['module'] === 'admin') || (isset($get_vars['act']) && $self->isExistsSSLAction($get_vars['act']))) ? ENFORCE_SSL : RELEASE_SSL;
1776
			$query = $self->getRequestUri($ssl_mode, $domain) . $query;
1777
			// no SSL
1778
		}
1779
		else
1780
		{
1781
			// currently on SSL but target is not based on SSL
1782
			if($_SERVER['HTTPS'] == 'on')
1783
			{
1784
				$query = $self->getRequestUri(ENFORCE_SSL, $domain) . $query;
1785
			}
1786
			else if($domain) // if $domain is set
1787
			{
1788
				$query = $self->getRequestUri(FOLLOW_REQUEST_SSL, $domain) . $query;
1789
			}
1790
			else
1791
			{
1792
				$query = getScriptPath() . $query;
1793
			}
1794
		}
1795
1796
		if(!$encode)
1797
		{
1798
			return $query;
1799
		}
1800
1801
		if(!$autoEncode)
1802
		{
1803
			return htmlspecialchars($query, ENT_COMPAT | ENT_HTML401, 'UTF-8', FALSE);
1804
		}
1805
1806
		$output = array();
1807
		$encode_queries = array();
1808
		$parsedUrl = parse_url($query);
1809
		parse_str($parsedUrl['query'], $output);
1810
		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...
1811
		{
1812
			if(preg_match('/&([a-z]{2,}|#\d+);/', urldecode($value)))
1813
			{
1814
				$value = urlencode(htmlspecialchars_decode(urldecode($value)));
1815
			}
1816
			$encode_queries[] = $key . '=' . $value;
1817
		}
1818
1819
		return htmlspecialchars($parsedUrl['path'] . '?' . join('&', $encode_queries), ENT_COMPAT | ENT_HTML401, 'UTF-8', FALSE);
1820
	}
1821
1822
	/**
1823
	 * Return after removing an argument on the requested URL
1824
	 *
1825
	 * @param string $ssl_mode SSL mode
1826
	 * @param string $domain Domain
1827
	 * @retrun string converted URL
1828
	 */
1829
	function getRequestUri($ssl_mode = FOLLOW_REQUEST_SSL, $domain = null)
1830
	{
1831
		static $url = array();
1832
1833
		// Check HTTP Request
1834
		if(!isset($_SERVER['SERVER_PROTOCOL']))
1835
		{
1836
			return;
1837
		}
1838
1839
		if(self::get('_use_ssl') == 'always')
1840
		{
1841
			$ssl_mode = ENFORCE_SSL;
1842
		}
1843
1844
		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...
1845
		{
1846
			$domain_key = md5($domain);
1847
		}
1848
		else
1849
		{
1850
			$domain_key = 'default';
1851
		}
1852
1853
		if(isset($url[$ssl_mode][$domain_key]))
1854
		{
1855
			return $url[$ssl_mode][$domain_key];
1856
		}
1857
1858
		$current_use_ssl = ($_SERVER['HTTPS'] == 'on');
1859
1860
		switch($ssl_mode)
1861
		{
1862
			case FOLLOW_REQUEST_SSL: $use_ssl = $current_use_ssl;
1863
				break;
1864
			case ENFORCE_SSL: $use_ssl = TRUE;
1865
				break;
1866
			case RELEASE_SSL: $use_ssl = FALSE;
1867
				break;
1868
		}
1869
1870
		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...
1871
		{
1872
			$target_url = trim($domain);
1873
			if(substr_compare($target_url, '/', -1) !== 0)
1874
			{
1875
				$target_url.= '/';
1876
			}
1877
		}
1878
		else
1879
		{
1880
			$target_url = $_SERVER['HTTP_HOST'] . getScriptPath();
1881
		}
1882
1883
		$url_info = parse_url('http://' . $target_url);
1884
1885
		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...
1886
		{
1887
			unset($url_info['port']);
1888
		}
1889
1890
		if($use_ssl)
1891
		{
1892
			$port = self::get('_https_port');
1893 View Code Duplication
			if($port && $port != 443)
1894
			{
1895
				$url_info['port'] = $port;
1896
			}
1897
			elseif($url_info['port'] == 443)
1898
			{
1899
				unset($url_info['port']);
1900
			}
1901
		}
1902 View Code Duplication
		else
1903
		{
1904
			$port = self::get('_http_port');
1905
			if($port && $port != 80)
1906
			{
1907
				$url_info['port'] = $port;
1908
			}
1909
			elseif($url_info['port'] == 80)
1910
			{
1911
				unset($url_info['port']);
1912
			}
1913
		}
1914
1915
		$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']);
1916
1917
		return $url[$ssl_mode][$domain_key];
1918
	}
1919
1920
	/**
1921
	 * Set a context value with a key
1922
	 *
1923
	 * @param string $key Key
1924
	 * @param mixed $val Value
1925
	 * @param mixed $set_to_get_vars If not FALSE, Set to get vars.
1926
	 * @return void
1927
	 */
1928
	function set($key, $val, $set_to_get_vars = 0)
1929
	{
1930
		$self = self::getInstance();
1931
		$self->context->{$key} = $val;
1932
		if($set_to_get_vars === FALSE)
1933
		{
1934
			return;
1935
		}
1936
		if($val === NULL || $val === '')
1937
		{
1938
			unset($self->get_vars->{$key});
1939
			return;
1940
		}
1941
		if($set_to_get_vars || $self->get_vars->{$key})
1942
		{
1943
			$self->get_vars->{$key} = $val;
1944
		}
1945
	}
1946
1947
	/**
1948
	 * Return key's value
1949
	 *
1950
	 * @param string $key Key
1951
	 * @return string Key
1952
	 */
1953
	function get($key)
1954
	{
1955
		$self = self::getInstance();
1956
1957
		if(!isset($self->context->{$key}))
1958
		{
1959
			return null;
1960
		}
1961
		return $self->context->{$key};
1962
	}
1963
1964
	/**
1965
	 * Get one more vars in object vars with given arguments(key1, key2, key3,...)
1966
	 *
1967
	 * @return object
1968
	 */
1969
	function gets()
1970
	{
1971
		$num_args = func_num_args();
1972
		if($num_args < 1)
1973
		{
1974
			return;
1975
		}
1976
		$self = self::getInstance();
1977
1978
		$args_list = func_get_args();
1979
		$output = new stdClass();
1980
		foreach($args_list as $v)
1981
		{
1982
			$output->{$v} = $self->get($v);
1983
		}
1984
		return $output;
1985
	}
1986
1987
	/**
1988
	 * Return all data
1989
	 *
1990
	 * @return object All data
1991
	 */
1992
	function getAll()
1993
	{
1994
		$self = self::getInstance();
1995
		return $self->context;
1996
	}
1997
1998
	/**
1999
	 * Return values from the GET/POST/XMLRPC
2000
	 *
2001
	 * @return BaseObject Request variables.
2002
	 */
2003
	function getRequestVars()
2004
	{
2005
		$self = self::getInstance();
2006
		if($self->get_vars)
2007
		{
2008
			return clone($self->get_vars);
2009
		}
2010
		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...
2011
	}
2012
2013
	/**
2014
	 * Register if an action is to be encrypted by SSL. Those actions are sent to https in common/js/xml_handler.js
2015
	 *
2016
	 * @param string $action act name
2017
	 * @return void
2018
	 */
2019
	function addSSLAction($action)
2020
	{
2021
		$self = self::getInstance();
2022
2023
		if(!is_readable($self->sslActionCacheFile))
2024
		{
2025
			$buff = '<?php if(!defined("__XE__"))exit;';
2026
			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...
2027
		}
2028
2029 View Code Duplication
		if(!isset($self->ssl_actions[$action]))
2030
		{
2031
			$self->ssl_actions[$action] = 1;
2032
			$sslActionCacheString = sprintf('$sslActions[\'%s\'] = 1;', $action);
2033
			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...
2034
		}
2035
	}
2036
2037
	/**
2038
	 * Register if actions are to be encrypted by SSL. Those actions are sent to https in common/js/xml_handler.js
2039
	 *
2040
	 * @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...
2041
	 * @return void
2042
	 */
2043
	function addSSLActions($action_array)
2044
	{
2045
		$self = self::getInstance();
2046
2047
		if(!is_readable($self->sslActionCacheFile))
2048
		{
2049
			unset($self->ssl_actions);
2050
			$buff = '<?php if(!defined("__XE__"))exit;';
2051
			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...
2052
		}
2053
2054
		foreach($action_array as $action)
2055
		{
2056 View Code Duplication
			if(!isset($self->ssl_actions[$action]))
2057
			{
2058
				$self->ssl_actions[$action] = 1;
2059
				$sslActionCacheString = sprintf('$sslActions[\'%s\'] = 1;', $action);
2060
				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...
2061
			}
2062
		}
2063
	}
2064
2065
	/**
2066
	 * Delete if action is registerd to be encrypted by SSL.
2067
	 *
2068
	 * @param string $action act name
2069
	 * @return void
2070
	 */
2071
	function subtractSSLAction($action)
2072
	{
2073
		$self = self::getInstance();
2074
2075
		if($self->isExistsSSLAction($action))
2076
		{
2077
			$sslActionCacheString = sprintf('$sslActions[\'%s\'] = 1;', $action);
2078
			$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...
2079
			$buff = str_replace($sslActionCacheString, '', $buff);
2080
			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...
2081
		}
2082
	}
2083
2084
	/**
2085
	 * Get SSL Action
2086
	 *
2087
	 * @return string acts in array
2088
	 */
2089
	function getSSLActions()
2090
	{
2091
		$self = self::getInstance();
2092
		if($self->getSslStatus() == 'optional')
2093
		{
2094
			return $self->ssl_actions;
2095
		}
2096
	}
2097
2098
	/**
2099
	 * Check SSL action are existed
2100
	 *
2101
	 * @param string $action act name
2102
	 * @return bool If SSL exists, return TRUE.
2103
	 */
2104
	function isExistsSSLAction($action)
2105
	{
2106
		$self = self::getInstance();
2107
		return isset($self->ssl_actions[$action]);
2108
	}
2109
2110
	/**
2111
	 * Normalize file path
2112
	 *
2113
	 * @deprecated
2114
	 * @param string $file file path
2115
	 * @return string normalized file path
2116
	 */
2117
	function normalizeFilePath($file)
2118
	{
2119
		if($file{0} != '/' && $file{0} != '.' && strpos($file, '://') === FALSE)
2120
		{
2121
			$file = './' . $file;
2122
		}
2123
		$file = preg_replace('@/\./|(?<!:)\/\/@', '/', $file);
2124
		while(strpos($file, '/../') !== FALSE)
2125
		{
2126
			$file = preg_replace('/\/([^\/]+)\/\.\.\//s', '/', $file, 1);
2127
		}
2128
2129
		return $file;
2130
	}
2131
2132
	/**
2133
	 * Get abstract file url
2134
	 *
2135
	 * @deprecated
2136
	 * @param string $file file path
2137
	 * @return string Converted file path
2138
	 */
2139
	function getAbsFileUrl($file)
2140
	{
2141
		$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...
2142
		$script_path = getScriptPath();
2143
		if(strpos($file, './') === 0)
2144
		{
2145
			$file = $script_path . substr($file, 2);
2146
		}
2147
		elseif(strpos($file, '../') === 0)
2148
		{
2149
			$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...
2150
		}
2151
2152
		return $file;
2153
	}
2154
2155
	/**
2156
	 * Load front end file
2157
	 *
2158
	 * @param array $args array
2159
	 * case js :
2160
	 * 		$args[0]: file name,
2161
	 * 		$args[1]: type (head | body),
2162
	 * 		$args[2]: target IE,
2163
	 * 		$args[3]: index
2164
	 * case css :
2165
	 * 		$args[0]: file name,
2166
	 * 		$args[1]: media,
2167
	 * 		$args[2]: target IE,
2168
	 * 		$args[3]: index
2169
	 *
2170
	 */
2171
	function loadFile($args)
2172
	{
2173
		$self = self::getInstance();
2174
2175
		$self->oFrontEndFileHandler->loadFile($args);
2176
	}
2177
2178
	/**
2179
	 * Unload front end file
2180
	 *
2181
	 * @param string $file File name with path
2182
	 * @param string $targetIe Target IE
2183
	 * @param string $media Media query
2184
	 * @return void
2185
	 */
2186
	function unloadFile($file, $targetIe = '', $media = 'all')
2187
	{
2188
		$self = self::getInstance();
2189
		$self->oFrontEndFileHandler->unloadFile($file, $targetIe, $media);
2190
	}
2191
2192
	/**
2193
	 * Unload front end file all
2194
	 *
2195
	 * @param string $type Unload target (optional - all|css|js)
2196
	 * @return void
2197
	 */
2198
	function unloadAllFiles($type = 'all')
2199
	{
2200
		$self = self::getInstance();
2201
		$self->oFrontEndFileHandler->unloadAllFiles($type);
2202
	}
2203
2204
	/**
2205
	 * Add the js file
2206
	 *
2207
	 * @deprecated
2208
	 * @param string $file File name with path
2209
	 * @param string $optimized optimized (That seems to not use)
2210
	 * @param string $targetie target IE
2211
	 * @param string $index index
2212
	 * @param string $type Added position. (head:<head>..</head>, body:<body>..</body>)
2213
	 * @param bool $isRuleset Use ruleset
2214
	 * @param string $autoPath If path not readed, set the path automatically.
2215
	 * @return void
2216
	 */
2217
	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...
2218
	{
2219
		if($isRuleset)
2220
		{
2221
			if(strpos($file, '#') !== FALSE)
2222
			{
2223
				$file = str_replace('#', '', $file);
2224
				if(!is_readable($file))
2225
				{
2226
					$file = $autoPath;
2227
				}
2228
			}
2229
			$validator = new Validator($file);
2230
			$validator->setCacheDir('files/cache');
2231
			$file = $validator->getJsPath();
2232
		}
2233
2234
		$self = self::getInstance();
2235
		$self->oFrontEndFileHandler->loadFile(array($file, $type, $targetie, $index));
2236
	}
2237
2238
	/**
2239
	 * Remove the js file
2240
	 *
2241
	 * @deprecated
2242
	 * @param string $file File name with path
2243
	 * @param string $optimized optimized (That seems to not use)
2244
	 * @param string $targetie target IE
2245
	 * @return void
2246
	 */
2247
	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...
2248
	{
2249
		$self = self::getInstance();
2250
		$self->oFrontEndFileHandler->unloadFile($file, $targetie);
2251
	}
2252
2253
	/**
2254
	 * Unload all javascript files
2255
	 *
2256
	 * @return void
2257
	 */
2258
	function unloadAllJsFiles()
2259
	{
2260
		$self = self::getInstance();
2261
		$self->oFrontEndFileHandler->unloadAllFiles('js');
2262
	}
2263
2264
	/**
2265
	 * Add javascript filter
2266
	 *
2267
	 * @param string $path File path
2268
	 * @param string $filename File name
2269
	 * @return void
2270
	 */
2271
	function addJsFilter($path, $filename)
2272
	{
2273
		$oXmlFilter = new XmlJSFilter($path, $filename);
2274
		$oXmlFilter->compile();
2275
	}
2276
2277
	/**
2278
	 * Same as array_unique but works only for file subscript
2279
	 *
2280
	 * @deprecated
2281
	 * @param array $files File list
2282
	 * @return array File list
2283
	 */
2284
	function _getUniqueFileList($files)
2285
	{
2286
		ksort($files);
2287
		$files = array_values($files);
2288
		$filenames = array();
2289
		for($i = 0, $c = count($files); $i < $c; ++$i)
2290
		{
2291
			if(in_array($files[$i]['file'], $filenames))
2292
			{
2293
				unset($files[$i]);
2294
			}
2295
			$filenames[] = $files[$i]['file'];
2296
		}
2297
2298
		return $files;
2299
	}
2300
2301
	/**
2302
	 * Returns the list of javascripts that matches the given type.
2303
	 *
2304
	 * @param string $type Added position. (head:<head>..</head>, body:<body>..</body>)
2305
	 * @return array Returns javascript file list. Array contains file, targetie.
2306
	 */
2307
	function getJsFile($type = 'head')
2308
	{
2309
		$self = self::getInstance();
2310
		return $self->oFrontEndFileHandler->getJsFileList($type);
2311
	}
2312
2313
	/**
2314
	 * Add CSS file
2315
	 *
2316
	 * @deprecated
2317
	 * @param string $file File name with path
2318
	 * @param string $optimized optimized (That seems to not use)
2319
	 * @param string $media Media query
2320
	 * @param string $targetie target IE
2321
	 * @param string $index index
2322
	 * @return void
2323
	 *
2324
	 */
2325
	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...
2326
	{
2327
		$self = self::getInstance();
2328
		$self->oFrontEndFileHandler->loadFile(array($file, $media, $targetie, $index));
2329
	}
2330
2331
	/**
2332
	 * Remove css file
2333
	 *
2334
	 * @deprecated
2335
	 * @param string $file File name with path
2336
	 * @param string $optimized optimized (That seems to not use)
2337
	 * @param string $media Media query
2338
	 * @param string $targetie target IE
2339
	 * @return void
2340
	 */
2341
	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...
2342
	{
2343
		$self = self::getInstance();
2344
		$self->oFrontEndFileHandler->unloadFile($file, $targetie, $media);
2345
	}
2346
2347
	/**
2348
	 * Unload all css files
2349
	 *
2350
	 * @return void
2351
	 */
2352
	function unloadAllCSSFiles()
2353
	{
2354
		$self = self::getInstance();
2355
		$self->oFrontEndFileHandler->unloadAllFiles('css');
2356
	}
2357
2358
	/**
2359
	 * Return a list of css files
2360
	 *
2361
	 * @return array Returns css file list. Array contains file, media, targetie.
2362
	 */
2363
	function getCSSFile()
2364
	{
2365
		$self = self::getInstance();
2366
		return $self->oFrontEndFileHandler->getCssFileList();
2367
	}
2368
2369
	/**
2370
	 * Returns javascript plugin file info
2371
	 * @param string $pluginName
2372
	 * @return stdClass
2373
	 */
2374
	function getJavascriptPluginInfo($pluginName)
2375
	{
2376
		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...
2377
		{
2378
			$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...
2379
		}
2380
2381
		$plugin_path = './common/js/plugins/' . $pluginName . '/';
2382
		$info_file = $plugin_path . 'plugin.load';
2383
		if(!is_readable($info_file))
2384
		{
2385
			return;
2386
		}
2387
2388
		$list = file($info_file);
2389
		$result = new stdClass();
2390
		$result->jsList = array();
2391
		$result->cssList = array();
2392
2393
		foreach($list as $filename)
2394
		{
2395
			$filename = trim($filename);
2396
			if(!$filename)
2397
			{
2398
				continue;
2399
			}
2400
2401
			if(strncasecmp('./', $filename, 2) === 0)
2402
			{
2403
				$filename = substr($filename, 2);
2404
			}
2405
2406
			if(substr_compare($filename, '.js', -3) === 0)
2407
			{
2408
				$result->jsList[] = $plugin_path . $filename;
2409
			}
2410
			elseif(substr_compare($filename, '.css', -4) === 0)
2411
			{
2412
				$result->cssList[] = $plugin_path . $filename;
2413
			}
2414
		}
2415
2416
		if(is_dir($plugin_path . 'lang'))
2417
		{
2418
			$result->langPath = $plugin_path . 'lang';
2419
		}
2420
2421
		return $result;
2422
	}
2423
	/**
2424
	 * Load javascript plugin
2425
	 *
2426
	 * @param string $plugin_name plugin name
2427
	 * @return void
2428
	 */
2429
	function loadJavascriptPlugin($plugin_name)
2430
	{
2431
		static $loaded_plugins = array();
2432
2433
		$self = self::getInstance();
2434
		if($plugin_name == 'ui.datepicker')
2435
		{
2436
			$plugin_name = 'ui';
2437
		}
2438
2439
		if($loaded_plugins[$plugin_name])
2440
		{
2441
			return;
2442
		}
2443
		$loaded_plugins[$plugin_name] = TRUE;
2444
2445
		$plugin_path = './common/js/plugins/' . $plugin_name . '/';
2446
		$info_file = $plugin_path . 'plugin.load';
2447
		if(!is_readable($info_file))
2448
		{
2449
			return;
2450
		}
2451
2452
		$list = file($info_file);
2453
		foreach($list as $filename)
2454
		{
2455
			$filename = trim($filename);
2456
			if(!$filename)
2457
			{
2458
				continue;
2459
			}
2460
2461
			if(strncasecmp('./', $filename, 2) === 0)
2462
			{
2463
				$filename = substr($filename, 2);
2464
			}
2465 View Code Duplication
			if(substr_compare($filename, '.js', -3) === 0)
2466
			{
2467
				$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...
2468
			}
2469 View Code Duplication
			if(substr_compare($filename, '.css', -4) === 0)
2470
			{
2471
				$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...
2472
			}
2473
		}
2474
2475
		if(is_dir($plugin_path . 'lang'))
2476
		{
2477
			$self->loadLang($plugin_path . 'lang');
2478
		}
2479
	}
2480
2481
	/**
2482
	 * Add html code before </head>
2483
	 *
2484
	 * @param string $header add html code before </head>.
2485
	 * @return void
2486
	 */
2487
	function addHtmlHeader($header)
2488
	{
2489
		$self = self::getInstance();
2490
		$self->html_header .= "\n" . $header;
2491
	}
2492
2493
	function clearHtmlHeader()
2494
	{
2495
		$self = self::getInstance();
2496
		$self->html_header = '';
2497
	}
2498
2499
	/**
2500
	 * Returns added html code by addHtmlHeader()
2501
	 *
2502
	 * @return string Added html code before </head>
2503
	 */
2504
	function getHtmlHeader()
2505
	{
2506
		$self = self::getInstance();
2507
		return $self->html_header;
2508
	}
2509
2510
	/**
2511
	 * Add css class to Html Body
2512
	 *
2513
	 * @param string $class_name class name
2514
	 */
2515
	function addBodyClass($class_name)
2516
	{
2517
		$self = self::getInstance();
2518
		$self->body_class[] = $class_name;
2519
	}
2520
2521
	/**
2522
	 * Return css class to Html Body
2523
	 *
2524
	 * @return string Return class to html body
2525
	 */
2526
	function getBodyClass()
2527
	{
2528
		$self = self::getInstance();
2529
		$self->body_class = array_unique($self->body_class);
2530
2531
		return (count($self->body_class) > 0) ? sprintf(' class="%s"', join(' ', $self->body_class)) : '';
2532
	}
2533
2534
	/**
2535
	 * Add html code after <body>
2536
	 *
2537
	 * @param string $header Add html code after <body>
2538
	 */
2539
	function addBodyHeader($header)
2540
	{
2541
		$self = self::getInstance();
2542
		$self->body_header .= "\n" . $header;
2543
	}
2544
2545
	/**
2546
	 * Returns added html code by addBodyHeader()
2547
	 *
2548
	 * @return string Added html code after <body>
2549
	 */
2550
	function getBodyHeader()
2551
	{
2552
		$self = self::getInstance();
2553
		return $self->body_header;
2554
	}
2555
2556
	/**
2557
	 * Add html code before </body>
2558
	 *
2559
	 * @param string $footer Add html code before </body>
2560
	 */
2561
	function addHtmlFooter($footer)
2562
	{
2563
		$self = self::getInstance();
2564
		$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...
2565
	}
2566
2567
	/**
2568
	 * Returns added html code by addHtmlHeader()
2569
	 *
2570
	 * @return string Added html code before </body>
2571
	 */
2572
	function getHtmlFooter()
2573
	{
2574
		$self = self::getInstance();
2575
		return $self->html_footer;
2576
	}
2577
2578
	/**
2579
	 * Get config file
2580
	 *
2581
	 * @retrun string The path of the config file that contains database settings
2582
	 */
2583
	function getConfigFile()
2584
	{
2585
		return _XE_PATH_ . 'files/config/db.config.php';
2586
	}
2587
2588
	/**
2589
	 * Get FTP config file
2590
	 *
2591
	 * @return string The path of the config file that contains FTP settings
2592
	 */
2593
	function getFTPConfigFile()
2594
	{
2595
		return _XE_PATH_ . 'files/config/ftp.config.php';
2596
	}
2597
2598
	/**
2599
	 * Checks whether XE is installed
2600
	 *
2601
	 * @return bool True if the config file exists, otherwise FALSE.
2602
	 */
2603
	function isInstalled()
2604
	{
2605
		return FileHandler::hasContent(self::getConfigFile());
2606
	}
2607
2608
	/**
2609
	 * Transforms codes about widget or other features into the actual code, deprecatred
2610
	 *
2611
	 * @param string Transforms codes
2612
	 * @return string Transforms codes
2613
	 */
2614
	function transContent($content)
2615
	{
2616
		return $content;
2617
	}
2618
2619
	/**
2620
	 * Check whether it is allowed to use rewrite mod
2621
	 *
2622
	 * @return bool True if it is allowed to use rewrite mod, otherwise FALSE
2623
	 */
2624
	function isAllowRewrite()
2625
	{
2626
		$oContext = self::getInstance();
2627
		return $oContext->allow_rewrite;
2628
	}
2629
2630
	/**
2631
	 * Converts a local path into an URL
2632
	 *
2633
	 * @param string $path URL path
2634
	 * @return string Converted path
2635
	 */
2636
	function pathToUrl($path)
2637
	{
2638
		$xe = _XE_PATH_;
2639
		$path = strtr($path, "\\", "/");
2640
2641
		$base_url = preg_replace('@^https?://[^/]+/?@', '', self::getRequestUri());
2642
2643
		$_xe = explode('/', $xe);
2644
		$_path = explode('/', $path);
2645
		$_base = explode('/', $base_url);
2646
2647
		if(!$_base[count($_base) - 1])
2648
		{
2649
			array_pop($_base);
2650
		}
2651
2652
		foreach($_xe as $idx => $dir)
2653
		{
2654
			if($_path[0] != $dir)
2655
			{
2656
				break;
2657
			}
2658
			array_shift($_path);
2659
		}
2660
2661
		$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...
2662
		while($idx--)
2663
		{
2664
			if(count($_base) > 0)
2665
			{
2666
				array_shift($_base);
2667
			}
2668
			else
2669
			{
2670
				array_unshift($_base, '..');
2671
			}
2672
		}
2673
2674
		if(count($_base) > 0)
2675
		{
2676
			array_unshift($_path, join('/', $_base));
2677
		}
2678
2679
		$path = '/' . join('/', $_path);
2680
		if(substr_compare($path, '/', -1) !== 0)
2681
		{
2682
			$path .= '/';
2683
		}
2684
		return $path;
2685
	}
2686
2687
	/**
2688
	 * Get meta tag
2689
	 * @return array The list of meta tags
2690
	 */
2691
	function getMetaTag()
2692
	{
2693
		$self = self::getInstance();
2694
2695
		if(!is_array($self->meta_tags))
2696
		{
2697
			$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...
2698
		}
2699
2700
		$ret = array();
2701
		foreach($self->meta_tags as $key => $val)
2702
		{
2703
			list($name, $is_http_equiv) = explode("\t", $key);
2704
			$ret[] = array('name' => $name, 'is_http_equiv' => $is_http_equiv, 'content' => $val);
2705
		}
2706
2707
		return $ret;
2708
	}
2709
2710
	/**
2711
	 * Add the meta tag
2712
	 *
2713
	 * @param string $name name of meta tag
2714
	 * @param string $content content of meta tag
2715
	 * @param mixed $is_http_equiv value of http_equiv
2716
	 * @return void
2717
	 */
2718
	function addMetaTag($name, $content, $is_http_equiv = FALSE)
2719
	{
2720
		$self = self::getInstance();
2721
		$self->meta_tags[$name . "\t" . ($is_http_equiv ? '1' : '0')] = $content;
2722
	}
2723
2724
}
2725
/* End of file Context.class.php */
2726
/* Location: ./classes/context/Context.class.php */
2727