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.

ModuleHandler   F
last analyzed

Complexity

Total Complexity 293

Size/Duplication

Total Lines 1430
Duplicated Lines 12.45 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
dl 178
loc 1430
rs 0.8
c 0
b 0
f 0
wmc 293
lcom 1
cbo 8

15 Methods

Rating   Name   Duplication   Size   Complexity  
F __construct() 0 82 30
B xeErrorLog() 4 35 9
A shutdownHandler() 0 29 5
C getErrorType() 0 22 16
F init() 0 200 47
F procModule() 137 489 99
C _setInputErrorToContext() 0 29 12
A _clearErrorSession() 0 9 1
A _setInputValueToSession() 0 9 2
F displayContent() 37 182 35
A getModulePath() 0 4 1
F getModuleInstance() 0 86 17
A _getModuleFilePath() 0 31 5
C triggerCall() 0 57 12
B _setHttpStatusMessage() 0 78 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like ModuleHandler often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ModuleHandler, and based on these observations, apply Extract Interface, too.

1
<?php
2
/* Copyright (C) XEHub <https://www.xehub.io> */
3
4
/**
5
 * @class ModuleHandler
6
 * @author XEHub ([email protected])
7
 * Handling modules
8
 *
9
 * @remarks This class is to excute actions of modules.
10
 *          Constructing an instance without any parameterconstructor, it finds the target module based on Context.
11
 *          If there is no act on the found module, excute an action referencing action_forward.
12
 * */
13
class ModuleHandler extends Handler
14
{
15
16
	var $module = NULL; ///< Module
17
	var $act = NULL; ///< action
18
	var $mid = NULL; ///< Module ID
19
	var $document_srl = NULL; ///< Document Number
20
	var $module_srl = NULL; ///< Module Number
21
	var $module_info = NULL; ///< Module Info. Object
22
	var $error = NULL; ///< an error code.
23
	var $httpStatusCode = NULL; ///< http status code.
24
25
	/**
26
	 * prepares variables to use in moduleHandler
27
	 * @param string $module name of module
28
	 * @param string $act name of action
29
	 * @param int $mid
30
	 * @param int $document_srl
31
	 * @param int $module_srl
32
	 * @return void
33
	 * */
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

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

Please refer to the PHP core documentation on constructors.

Loading history...
34
35
	function __construct($module = '', $act = '', $mid = '', $document_srl = '', $module_srl = '')
36
	{
37
		// If XE has not installed yet, set module as install
38
		if(!Context::isInstalled())
39
		{
40
			$this->module = 'install';
41
			$this->act = Context::get('act');
42
			return;
43
		}
44
45
		$oContext = Context::getInstance();
46
		if($oContext->isSuccessInit == FALSE)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

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

Loading history...
47
		{
48
			// @see https://github.com/xpressengine/xe-core/issues/2304
49
			$this->error = 'msg_invalid_request';
50
			return;
51
		}
52
53
		// Set variables from request arguments
54
		$this->module = $module ? $module : Context::get('module');
55
		$this->act = $act ? $act : Context::get('act');
56
		$this->mid = $mid ? $mid : Context::get('mid');
57
		$this->document_srl = $document_srl ? (int) $document_srl : (int) Context::get('document_srl');
58
		$this->module_srl = $module_srl ? (int) $module_srl : (int) Context::get('module_srl');
59
        if($entry = Context::get('entry'))
60
        {
61
            $this->entry = Context::convertEncodingStr($entry);
0 ignored issues
show
Bug introduced by
The property entry 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...
62
        }
63
64
		// Validate variables to prevent XSS
65
		$isInvalid = NULL;
66
		if($this->module && !preg_match("/^([a-z0-9\_\-]+)$/i", $this->module))
67
		{
68
			$isInvalid = TRUE;
69
		}
70
		if($this->mid && !preg_match("/^([a-z0-9\_\-]+)$/i", $this->mid))
71
		{
72
			$isInvalid = TRUE;
73
		}
74
		if($this->act && !preg_match("/^([a-z0-9\_\-]+)$/i", $this->act))
75
		{
76
			$isInvalid = TRUE;
77
		}
78
		if($isInvalid)
79
		{
80
			htmlHeader();
81
			echo Context::getLang("msg_invalid_request");
82
			htmlFooter();
83
			Context::close();
84
			exit;
85
		}
86
87
		if(isset($this->act) && (strlen($this->act) >= 4 && substr_compare($this->act, 'disp', 0, 4) === 0))
88
		{
89
			if(Context::get('_use_ssl') == 'optional' && Context::isExistsSSLAction($this->act) && $_SERVER['HTTPS'] != 'on')
90
			{
91
				if(Context::get('_https_port')!=null) {
92
					header('location:https://' . $_SERVER['HTTP_HOST'] . ':' . Context::get('_https_port') . $_SERVER['REQUEST_URI']);
93
				} else {
94
					header('location:https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
95
				}
96
				return;
97
			}
98
		}
99
100
		// call a trigger before moduleHandler init
101
		ModuleHandler::triggerCall('moduleHandler.init', 'before', $this);
102
		if(__ERROR_LOG__ == 1 && __DEBUG_OUTPUT__ == 0)
103
		{
104
			if(__DEBUG_PROTECT__ === 0 || __DEBUG_PROTECT__ === 1 && __DEBUG_PROTECT_IP__ == $_SERVER['REMOTE_ADDR'])
105
			{
106
				set_error_handler(array($this, 'xeErrorLog'), E_WARNING);
107
				register_shutdown_function(array($this, 'shutdownHandler'));
108
			}
109
		}
110
111
		// execute addon (before module initialization)
112
		$called_position = 'before_module_init';
113
		$oAddonController = getController('addon');
114
		$addon_file = $oAddonController->getCacheFilePath(Mobile::isFromMobilePhone() ? 'mobile' : 'pc');
115
		if(file_exists($addon_file)) include($addon_file);
116
	}
117
118
	public static function xeErrorLog($errnumber, $errormassage, $errorfile, $errorline, $errorcontext)
0 ignored issues
show
Unused Code introduced by
The parameter $errorfile 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...
Unused Code introduced by
The parameter $errorline 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...
Unused Code introduced by
The parameter $errorcontext 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...
119
	{
120
		if(($errnumber & 3) == 0 || error_reporting() == 0)
121
		{
122
			return false;
123
		}
124
125
		set_error_handler(function() { }, ~0);
126
127
		$debug_file = _XE_PATH_ . 'files/_debug_message.php';
128
		if(!file_exists($debug_file))
129
		{
130
			$print[] = '<?php exit() ?>';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$print was never initialized. Although not strictly required by PHP, it is generally a good practice to add $print = 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...
131
		}
132
133
		$errorname = self::getErrorType($errnumber);
134
		$print[] = '['.date('Y-m-d H:i:s').'] ' . $errorname . ' : ' . $errormassage;
0 ignored issues
show
Bug introduced by
The variable $print 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...
135
		$backtrace_args = defined('DEBUG_BACKTRACE_IGNORE_ARGS') ? \DEBUG_BACKTRACE_IGNORE_ARGS : 0;
136
		$backtrace = debug_backtrace($backtrace_args);
137 View Code Duplication
		if(count($backtrace) > 1 && $backtrace[1]['function'] === 'xeErrorLog' && !$backtrace[1]['class'])
138
		{
139
			array_shift($backtrace);
140
		}
141
142
		foreach($backtrace as $key => $value)
143
		{
144
			$message = '    - ' . $value['file'] . ' : ' . $value['line'];
145
			$print[] = $message;
146
		}
147
		$print[] = PHP_EOL;
148
		@file_put_contents($debug_file, implode(PHP_EOL, $print), FILE_APPEND|LOCK_EX);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
149
		restore_error_handler();
150
151
		return true;
152
	}
153
154
	function shutdownHandler()
155
	{
156
		$errinfo = error_get_last();
157
		if ($errinfo === null || ($errinfo['type'] != 1 && $errinfo['type'] != 4))
158
		{
159
			return false;
160
		}
161
162
		set_error_handler(function() { }, ~0);
163
164
		$debug_file = _XE_PATH_ . 'files/_debug_message.php';
165
		if(!file_exists($debug_file))
166
		{
167
			$print[] = '<?php exit() ?>';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$print was never initialized. Although not strictly required by PHP, it is generally a good practice to add $print = 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...
168
		}
169
170
		$errorname = self::getErrorType($errinfo['type']);
171
		$print[] = '['.date('Y-m-d H:i:s').']';
0 ignored issues
show
Bug introduced by
The variable $print 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...
172
		$print[] = $errorname . ' : ' . $errinfo['message'];
173
174
		$message = '    - ' . $errinfo['file'] . ' : ' . $errinfo['line'];
175
		$print[] = $message;
176
177
		$print[] = PHP_EOL;
178
		@file_put_contents($debug_file, implode(PHP_EOL, $print), FILE_APPEND|LOCK_EX);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
179
		set_error_handler(array($this, 'dummyHandler'), ~0);
180
181
		return true;
182
	}
183
184
	public static function getErrorType($errno)
185
	{
186
		switch ($errno)
187
		{
188
			case E_ERROR: return 'Fatal Error';
189
			case E_WARNING: return 'Warning';
190
			case E_NOTICE: return 'Notice';
191
			case E_CORE_ERROR: return 'Core Error';
192
			case E_CORE_WARNING: return 'Core Warning';
193
			case E_COMPILE_ERROR: return 'Compile Error';
194
			case E_COMPILE_WARNING: return 'Compile Warning';
195
			case E_USER_ERROR: return 'User Error';
196
			case E_USER_WARNING: return 'User Warning';
197
			case E_USER_NOTICE: return 'User Notice';
198
			case E_STRICT: return 'Strict Standards';
199
			case E_PARSE: return 'Parse Error';
200
			case E_DEPRECATED: return 'Deprecated';
201
			case E_USER_DEPRECATED: return 'User Deprecated';
202
			case E_RECOVERABLE_ERROR: return 'Catchable Fatal Error';
203
			default: return 'Error';
204
		}
205
	}
206
207
	/**
208
	 * Initialization. It finds the target module based on module, mid, document_srl, and prepares to execute an action
209
	 * @return boolean true: OK, false: redirected
210
	 * */
211
	function init()
212
	{
213
		$oModuleModel = getModel('module');
214
		$site_module_info = Context::get('site_module_info');
215
216
		// if success_return_url and error_return_url is incorrect
217
		$urls = array(Context::get('success_return_url'), Context::get('error_return_url'));
218
		$dbInfo = Context::getDBInfo();
219
		$defaultUrlInfo = parse_url($dbInfo->default_url);
220
		$defaultHost = $defaultUrlInfo['host'];
221
		$siteDomain = parse_url($site_module_info->domain);
222
		$siteDomain = $siteDomain['host'];
223
224
		foreach($urls as $url)
225
		{
226
			if(empty($url))
227
			{
228
				continue;
229
			}
230
231
			$urlInfo = parse_url(urldecode($url));
232
			$host = $urlInfo['host'];
233
234
			if($host && ($host !== $defaultHost && ($host !== $site_module_info->domain || $host !== $siteDomain)))
235
			{
236
				throw new Exception('msg_default_url_is_null');
237
			}
238
			else if((!$host || !$urlInfo || !$urlInfo['scheme']) && preg_match("/^(https?|[a-z0-9])+\:(\/)*/i", urldecode($url)))
239
			{
240
				throw new exception('msg_invalid_request');
241
			}
242
		}
243
244
		if(!$this->document_srl && $this->mid && $this->entry)
245
		{
246
			$oDocumentModel = getModel('document');
247
			$this->document_srl = $oDocumentModel->getDocumentSrlByAlias($this->mid, $this->entry);
248
			if($this->document_srl)
249
			{
250
				Context::set('document_srl', $this->document_srl);
251
			}
252
		}
253
254
		// Get module's information based on document_srl, if it's specified
255
		if($this->document_srl)
256
		{
257
258
			$module_info = $oModuleModel->getModuleInfoByDocumentSrl($this->document_srl);
259
			// If the document does not exist, remove document_srl
260
			if(!$module_info)
261
			{
262
				unset($this->document_srl);
263
			}
264
			else
265
			{
266
				// If it exists, compare mid based on the module information
267
				// if mids are not matching, set it as the document's mid
268
				if(!$this->mid || ($this->mid != $module_info->mid))
269
				{
270
271
					if(Context::getRequestMethod() == 'GET')
272
					{
273
						$this->mid = $module_info->mid;
274
						header('location:' . getNotEncodedSiteUrl($site_module_info->domain, 'mid', $this->mid, 'document_srl', $this->document_srl));
275
						return FALSE;
276
					}
277
					else
278
					{
279
						$this->mid = $module_info->mid;
280
						Context::set('mid', $this->mid);
281
					}
282
283
				}
284
				// if requested module is different from one of the document, remove the module information retrieved based on the document number
285
				if($this->module && $module_info->module != $this->module)
286
				{
287
					unset($module_info);
288
				}
289
			}
290
291
		}
292
293
		// If module_info is not set yet, and there exists mid information, get module information based on the mid
294
		if(!$module_info && $this->mid)
0 ignored issues
show
Bug introduced by
The variable $module_info 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...
295
		{
296
			$module_info = $oModuleModel->getModuleInfoByMid($this->mid, $site_module_info->site_srl);
297
			//if($this->module && $module_info->module != $this->module) unset($module_info);
298
		}
299
300
		// redirect, if module_site_srl and site_srl are different
301
		if(!$this->module && !$module_info && $site_module_info->site_srl == 0 && $site_module_info->module_site_srl > 0)
302
		{
303
			$site_info = $oModuleModel->getSiteInfo($site_module_info->module_site_srl);
304
			header("location:" . getNotEncodedSiteUrl($site_info->domain, 'mid', $site_module_info->mid));
305
			return FALSE;
306
		}
307
308
		// If module_info is not set still, and $module does not exist, find the default module
309
		if(!$module_info && !$this->module && !$this->mid)
310
		{
311
			$module_info = $site_module_info;
312
		}
313
314
		if(!$module_info && !$this->module && $site_module_info->module_site_srl)
315
		{
316
			$module_info = $site_module_info;
317
		}
318
319
		// redirect, if site_srl of module_info is different from one of site's module_info
320
		if($module_info && $module_info->site_srl != $site_module_info->site_srl && !isCrawler())
321
		{
322
			// If the module is of virtual site
323
			if($module_info->site_srl)
324
			{
325
				$site_info = $oModuleModel->getSiteInfo($module_info->site_srl);
326
				$redirect_url = getNotEncodedSiteUrl($site_info->domain, 'mid', Context::get('mid'), 'document_srl', Context::get('document_srl'), 'module_srl', Context::get('module_srl'), 'entry', Context::get('entry'));
327
				// If it's called from a virtual site, though it's not a module of the virtual site
328
			}
329
			else
330
			{
331
				$db_info = Context::getDBInfo();
332
				if(!$db_info->default_url)
333
				{
334
					return Context::getLang('msg_default_url_is_not_defined');
335
				}
336
				else
337
				{
338
					$redirect_url = getNotEncodedSiteUrl($db_info->default_url, 'mid', Context::get('mid'), 'document_srl', Context::get('document_srl'), 'module_srl', Context::get('module_srl'), 'entry', Context::get('entry'));
339
				}
340
			}
341
			header("location:" . $redirect_url);
342
			return FALSE;
343
		}
344
345
		// If module info was set, retrieve variables from the module information
346
		if($module_info)
347
		{
348
			$this->module = $module_info->module;
349
			$this->mid = $module_info->mid;
350
			$this->module_info = $module_info;
351
			Context::setBrowserTitle($module_info->browser_title);
352
353
			$viewType = (Mobile::isFromMobilePhone()) ? 'M' : 'P';
354
			$targetSrl = (Mobile::isFromMobilePhone()) ? 'mlayout_srl' : 'layout_srl';
355
356
			// use the site default layout.
357
			if($module_info->{$targetSrl} == -1)
358
			{
359
				$oLayoutAdminModel = getAdminModel('layout');
360
				$layoutSrl = $oLayoutAdminModel->getSiteDefaultLayout($viewType, $module_info->site_srl);
361
			}
362
			else
363
			{
364
				$layoutSrl = $module_info->{$targetSrl};
365
			}
366
367
			// reset a layout_srl in module_info.
368
			$module_info->{$targetSrl} = $layoutSrl;
369
370
			$part_config = $oModuleModel->getModulePartConfig('layout', $layoutSrl);
371
			Context::addHtmlHeader($part_config->header_script);
372
		}
373
374
		// Set module and mid into module_info
375
		if(!isset($this->module_info))
376
		{
377
			$this->module_info = new stdClass();
378
		}
379
		$this->module_info->module = $this->module;
380
		$this->module_info->mid = $this->mid;
381
382
		// Set site_srl add 2011 08 09
383
		$this->module_info->site_srl = $site_module_info->site_srl;
384
385
		// Still no module? it's an error
386
		if(!$this->module)
387
		{
388
			$this->error = 'msg_module_is_not_exists';
389
			$this->httpStatusCode = '404';
390
		}
391
392
		// If mid exists, set mid into context
393
		if($this->mid)
394
		{
395
			Context::set('mid', $this->mid, 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...
396
		}
397
398
		// Call a trigger after moduleHandler init
399
		$output = ModuleHandler::triggerCall('moduleHandler.init', 'after', $this->module_info);
400
		if(!$output->toBool())
401
		{
402
			$this->error = $output->getMessage();
403
			return TRUE;
404
		}
405
406
		// Set current module info into context
407
		Context::set('current_module_info', $this->module_info);
408
409
		return TRUE;
410
	}
411
412
	/**
413
	 * get a module instance and execute an action
414
	 * @return ModuleObject executed module instance
415
	 * */
416
	function procModule()
417
	{
418
		$oModuleModel = getModel('module');
419
		$display_mode = Mobile::isFromMobilePhone() ? 'mobile' : 'view';
420
421
		// If error occurred while preparation, return a message instance
422
		if($this->error)
423
		{
424
			$this->_setInputErrorToContext();
425
			$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
426
			$oMessageObject->setError(-1);
427
			$oMessageObject->setMessage($this->error);
428
			$oMessageObject->dispMessage();
429
			if($this->httpStatusCode)
430
			{
431
				$oMessageObject->setHttpStatusCode($this->httpStatusCode);
432
			}
433
			return $oMessageObject;
434
		}
435
436
		// Get action information with conf/module.xml
437
		$xml_info = $oModuleModel->getModuleActionXml($this->module);
438
439
		// If not installed yet, modify act
440
		if($this->module == "install")
441
		{
442
			if(!$this->act || !$xml_info->action->{$this->act})
443
			{
444
				$this->act = $xml_info->default_index_act;
445
			}
446
		}
447
448
		// if act exists, find type of the action, if not use default index act
449
		if(!$this->act)
450
		{
451
			$this->act = $xml_info->default_index_act;
452
		}
453
454
		// still no act means error
455
		if(!$this->act)
456
		{
457
			$this->error = 'msg_module_is_not_exists';
458
			$this->httpStatusCode = '404';
459
460
			$this->_setInputErrorToContext();
461
			$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
462
			$oMessageObject->setError(-1);
463
			$oMessageObject->setMessage($this->error);
464
			$oMessageObject->dispMessage();
465
			if($this->httpStatusCode)
466
			{
467
				$oMessageObject->setHttpStatusCode($this->httpStatusCode);
468
			}
469
			return $oMessageObject;
470
		}
471
472
		// get type, kind
473
		$type = $xml_info->action->{$this->act}->type;
474
		$ruleset = $xml_info->action->{$this->act}->ruleset;
475
		$meta_noindex = $xml_info->action->{$this->act}->meta_noindex;
476
		$kind = stripos($this->act, 'admin') !== FALSE ? 'admin' : '';
477
478
		if ($meta_noindex === 'true')
479
		{
480
			Context::addMetaTag('robots', 'noindex');
481
		}
482
483
		if(!$kind && $this->module == 'admin')
484
		{
485
			$kind = 'admin';
486
		}
487
488
		// check REQUEST_METHOD in controller
489 View Code Duplication
		if($type == 'controller')
490
		{
491
			$allowedMethod = $xml_info->action->{$this->act}->method;
492
493
			if(!$allowedMethod)
494
			{
495
				$allowedMethodList[0] = 'POST';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$allowedMethodList was never initialized. Although not strictly required by PHP, it is generally a good practice to add $allowedMethodList = 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...
496
			}
497
			else
498
			{
499
				$allowedMethodList = explode('|', strtoupper($allowedMethod));
500
			}
501
502
			if(!in_array(strtoupper($_SERVER['REQUEST_METHOD']), $allowedMethodList))
503
			{
504
				$this->error = "msg_invalid_request";
505
				$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
506
				$oMessageObject->setError(-1);
507
				$oMessageObject->setMessage($this->error);
508
				$oMessageObject->dispMessage();
509
				return $oMessageObject;
510
			}
511
		}
512
513
		if($this->module_info->use_mobile != "Y")
514
		{
515
			Mobile::setMobile(FALSE);
516
		}
517
518
		$logged_info = Context::get('logged_info');
519
520
		// check CSRF for non-GET actions
521
		$use_check_csrf = isset($xml_info->action->{$this->act}) && $xml_info->action->{$this->act}->check_csrf !== 'false';
522 View Code Duplication
		if($use_check_csrf && $_SERVER['REQUEST_METHOD'] !== 'GET' && Context::isInstalled() && !checkCSRF())
523
		{
524
			$this->error = 'msg_invalid_request';
525
			$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
526
			$oMessageObject->setError(-1);
527
			$oMessageObject->setMessage($this->error);
528
			$oMessageObject->dispMessage();
529
			return $oMessageObject;
530
		}
531
532
		// Admin ip
533
		if($kind == 'admin' && $_SESSION['denied_admin'] == 'Y')
534
		{
535
			$this->_setInputErrorToContext();
536
			$this->error = "msg_not_permitted_act";
537
			$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
538
			$oMessageObject->setError(-1);
539
			$oMessageObject->setMessage($this->error);
540
			$oMessageObject->dispMessage();
541
			return $oMessageObject;
542
		}
543
544
		// if(type == view, and case for using mobilephone)
545
		if($type == "view" && Mobile::isFromMobilePhone() && Context::isInstalled())
546
		{
547
			$orig_type = "view";
548
			$type = "mobile";
549
			// create a module instance
550
			$oModule = $this->getModuleInstance($this->module, $type, $kind);
551 View Code Duplication
			if(!is_object($oModule) || !method_exists($oModule, $this->act))
552
			{
553
				$type = $orig_type;
554
				Mobile::setMobile(FALSE);
555
				$oModule = $this->getModuleInstance($this->module, $type, $kind);
556
			}
557
		}
558
		else
559
		{
560
			// create a module instance
561
			$oModule = $this->getModuleInstance($this->module, $type, $kind);
562
		}
563
564 View Code Duplication
		if(!is_object($oModule))
565
		{
566
			$this->_setInputErrorToContext();
567
			$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
568
			$oMessageObject->setError(-1);
569
			$oMessageObject->setMessage($this->error);
570
			$oMessageObject->dispMessage();
571
			if($this->httpStatusCode)
572
			{
573
				$oMessageObject->setHttpStatusCode($this->httpStatusCode);
574
			}
575
			return $oMessageObject;
576
		}
577
578
		// If there is no such action in the module object
579
		if(!isset($xml_info->action->{$this->act}) || !method_exists($oModule, $this->act))
580
		{
581
582 View Code Duplication
			if(!Context::isInstalled())
583
			{
584
				$this->_setInputErrorToContext();
585
				$this->error = 'msg_invalid_request';
586
				$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
587
				$oMessageObject->setError(-1);
588
				$oMessageObject->setMessage($this->error);
589
				$oMessageObject->dispMessage();
590
				if($this->httpStatusCode)
591
				{
592
					$oMessageObject->setHttpStatusCode($this->httpStatusCode);
593
				}
594
				return $oMessageObject;
595
			}
596
597
			$forward = NULL;
598
			// 1. Look for the module with action name
599
			if(preg_match('/^([a-z]+)([A-Z])([a-z0-9\_]+)(.*)$/', $this->act, $matches))
600
			{
601
				$module = strtolower($matches[2] . $matches[3]);
602
				$xml_info = $oModuleModel->getModuleActionXml($module);
603
604
				if($xml_info->action->{$this->act} && ((stripos($this->act, 'admin') !== FALSE) || $xml_info->action->{$this->act}->standalone != 'false'))
605
				{
606
					$forward = new stdClass();
607
					$forward->module = $module;
608
					$forward->type = $xml_info->action->{$this->act}->type;
609
					$forward->ruleset = $xml_info->action->{$this->act}->ruleset;
610
					$forward->meta_noindex = $xml_info->action->{$this->act}->meta_noindex;
611
					$forward->act = $this->act;
612
				}
613 View Code Duplication
				else
614
				{
615
					$this->error = 'msg_invalid_request';
616
					$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
617
					$oMessageObject->setError(-1);
618
					$oMessageObject->setMessage($this->error);
619
					$oMessageObject->dispMessage();
620
621
					return $oMessageObject;
622
				}
623
			}
624
625
			if(!$forward)
626
			{
627
				$forward = $oModuleModel->getActionForward($this->act);
628
			}
629
630
			if($forward->module && $forward->type && $forward->act && $forward->act == $this->act)
631
			{
632
				$kind = stripos($forward->act, 'admin') !== FALSE ? 'admin' : '';
633
				$type = $forward->type;
634
				$ruleset = $forward->ruleset;
635
				$tpl_path = $oModule->getTemplatePath();
0 ignored issues
show
Unused Code introduced by
$tpl_path 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...
636
				$orig_module = $oModule;
0 ignored issues
show
Unused Code introduced by
$orig_module 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...
637
638
				if($forward->meta_noindex === 'true') {
639
					Context::addMetaTag('robots', 'noindex');
640
				}
641
642
				$xml_info = $oModuleModel->getModuleActionXml($forward->module);
643
644
				// check CSRF for non-GET actions
645
				$use_check_csrf = isset($xml_info->action->{$this->act}) && $xml_info->action->{$this->act}->check_csrf !== 'false';
646 View Code Duplication
				if($use_check_csrf && $_SERVER['REQUEST_METHOD'] !== 'GET' && Context::isInstalled() && !checkCSRF())
647
				{
648
					$this->error = 'msg_invalid_request';
649
					$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
650
					$oMessageObject->setError(-1);
651
					$oMessageObject->setMessage($this->error);
652
					$oMessageObject->dispMessage();
653
					return $oMessageObject;
654
				}
655
656
				// SECISSUE also check foward act method
657
				// check REQUEST_METHOD in controller
658 View Code Duplication
				if($type == 'controller')
659
				{
660
					$allowedMethod = $xml_info->action->{$forward->act}->method;
661
662
					if(!$allowedMethod)
663
					{
664
						$allowedMethodList[0] = 'POST';
0 ignored issues
show
Bug introduced by
The variable $allowedMethodList 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...
665
					}
666
					else
667
					{
668
						$allowedMethodList = explode('|', strtoupper($allowedMethod));
669
					}
670
671
					if(!in_array(strtoupper($_SERVER['REQUEST_METHOD']), $allowedMethodList))
672
					{
673
						$this->error = "msg_invalid_request";
674
						$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
675
						$oMessageObject->setError(-1);
676
						$oMessageObject->setMessage($this->error);
677
						$oMessageObject->dispMessage();
678
						return $oMessageObject;
679
					}
680
				}
681
682
				if($type == "view" && Mobile::isFromMobilePhone())
683
				{
684
					$orig_type = "view";
685
					$type = "mobile";
686
					// create a module instance
687
					$oModule = $this->getModuleInstance($forward->module, $type, $kind);
688 View Code Duplication
					if(!is_object($oModule) || !method_exists($oModule, $this->act))
689
					{
690
						$type = $orig_type;
691
						Mobile::setMobile(FALSE);
692
						$oModule = $this->getModuleInstance($forward->module, $type, $kind);
693
					}
694
				}
695
				else
696
				{
697
					$oModule = $this->getModuleInstance($forward->module, $type, $kind);
698
				}
699
700 View Code Duplication
				if(!is_object($oModule))
701
				{
702
					$this->_setInputErrorToContext();
703
					$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
704
					$oMessageObject->setError(-1);
705
					$oMessageObject->setMessage('msg_module_is_not_exists');
706
					$oMessageObject->dispMessage();
707
					if($this->httpStatusCode)
708
					{
709
						$oMessageObject->setHttpStatusCode($this->httpStatusCode);
710
					}
711
					return $oMessageObject;
712
				}
713
714
				if($this->module == "admin" && $type == "view")
715
				{
716
					if($logged_info->is_admin == 'Y')
717
					{
718
						if($this->act != 'dispLayoutAdminLayoutModify')
719
						{
720
							$oAdminView = getAdminView('admin');
721
							$oAdminView->makeGnbUrl($forward->module);
722
							$oModule->setLayoutPath("./modules/admin/tpl");
723
							$oModule->setLayoutFile("layout.html");
724
						}
725
					}
726 View Code Duplication
					else
727
					{
728
						$this->_setInputErrorToContext();
729
730
						$this->error = 'msg_is_not_administrator';
731
						$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
732
						$oMessageObject->setError(-1);
733
						$oMessageObject->setMessage($this->error);
734
						$oMessageObject->dispMessage();
735
						return $oMessageObject;
736
					}
737
				}
738
				if($kind == 'admin')
739
				{
740
					$grant = $oModuleModel->getGrant($this->module_info, $logged_info);
741
					if(!$grant->manager)
742
					{
743
						$this->_setInputErrorToContext();
744
						$this->error = 'msg_is_not_manager';
745
						$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
746
						$oMessageObject->setError(-1);
747
						$oMessageObject->setMessage($this->error);
748
						$oMessageObject->dispMessage();
749
						return $oMessageObject;
750
					}
751
					else
752
					{
753
						if(!$grant->is_admin && $this->module != $this->orig_module->module && $xml_info->permission->{$this->act} != 'manager')
0 ignored issues
show
Bug introduced by
The property orig_module does not seem to exist. Did you mean module?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
754
						{
755
							$this->_setInputErrorToContext();
756
							$this->error = 'msg_is_not_administrator';
757
							$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
758
							$oMessageObject->setError(-1);
759
							$oMessageObject->setMessage($this->error);
760
							$oMessageObject->dispMessage();
761
							return $oMessageObject;
762
						}
763
					}
764
				}
765
			}
766
			else if($xml_info->default_index_act && method_exists($oModule, $xml_info->default_index_act))
767
			{
768
				$this->act = $xml_info->default_index_act;
769
			}
770
			else
771
			{
772
				$this->error = 'msg_invalid_request';
773
				$oModule->setError(-1);
774
				$oModule->setMessage($this->error);
775
				return $oModule;
776
			}
777
		}
778
779
		// ruleset check...
780
		if(!empty($ruleset))
781
		{
782
			$rulesetModule = $forward->module ? $forward->module : $this->module;
0 ignored issues
show
Bug introduced by
The variable $forward 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...
783
			$rulesetFile = $oModuleModel->getValidatorFilePath($rulesetModule, $ruleset, $this->mid);
784
			if(!empty($rulesetFile))
785
			{
786
				if($_SESSION['XE_VALIDATOR_ERROR_LANG'])
787
				{
788
					$errorLang = $_SESSION['XE_VALIDATOR_ERROR_LANG'];
789
					foreach($errorLang as $key => $val)
790
					{
791
						Context::setLang($key, $val);
792
					}
793
					unset($_SESSION['XE_VALIDATOR_ERROR_LANG']);
794
				}
795
796
				$Validator = new Validator($rulesetFile);
797
				$result = $Validator->validate();
798
				if(!$result)
799
				{
800
					$lastError = $Validator->getLastError();
801
					$returnUrl = Context::get('error_return_url');
802
					$errorMsg = $lastError['msg'] ? $lastError['msg'] : 'validation error';
803
804
					//for xml response
805
					$oModule->setError(-1);
806
					$oModule->setMessage($errorMsg);
807
					//for html redirect
808
					$this->error = $errorMsg;
809
					$_SESSION['XE_VALIDATOR_ERROR'] = -1;
810
					$_SESSION['XE_VALIDATOR_MESSAGE'] = $this->error;
811
					$_SESSION['XE_VALIDATOR_MESSAGE_TYPE'] = 'error';
812
					$_SESSION['XE_VALIDATOR_RETURN_URL'] = $returnUrl;
813
					$_SESSION['XE_VALIDATOR_ID'] = Context::get('xe_validator_id');
814
					$this->_setInputValueToSession();
815
					return $oModule;
816
				}
817
			}
818
		}
819
820
		$oModule->setAct($this->act);
821
822
		$this->module_info->module_type = $type;
823
		$oModule->setModuleInfo($this->module_info, $xml_info);
824
825
		$skipAct = array(
826
				'dispEditorConfigPreview' => 1,
827
				'dispLayoutPreviewWithModule' => 1
828
		);
829
		$db_use_mobile = Mobile::isMobileEnabled();
830
		if($type == "view" && $this->module_info->use_mobile == "Y" && Mobile::isMobileCheckByAgent() && !isset($skipAct[Context::get('act')]) && $db_use_mobile === true)
831
		{
832
			global $lang;
833
			$header = '<style>div.xe_mobile{opacity:0.7;margin:1em 0;padding:.5em;background:#333;border:1px solid #666;border-left:0;border-right:0}p.xe_mobile{text-align:center;margin:1em 0}a.xe_mobile{color:#ff0;font-weight:bold;font-size:24px}@media only screen and (min-width:500px){a.xe_mobile{font-size:15px}}</style>';
834
			$footer = '<div class="xe_mobile"><p class="xe_mobile"><a class="xe_mobile" href="' . getUrl('m', '1') . '">' . $lang->msg_pc_to_mobile . '</a></p></div>';
835
			Context::addHtmlHeader($header);
836
			Context::addHtmlFooter($footer);
837
		}
838
839
		if(($type == 'view' || $type == 'mobile') && $kind != 'admin')
840
		{
841
			$module_config = $oModuleModel->getModuleConfig('module');
842
			if($module_config->htmlFooter)
843
			{
844
				Context::addHtmlFooter($module_config->htmlFooter);
845
			}
846
			if($module_config->siteTitle)
847
			{
848
				$siteTitle = Context::getBrowserTitle();
849
				if(!$siteTitle)
850
				{
851
					Context::setBrowserTitle($module_config->siteTitle);
852
				}
853
			}
854
		}
855
856
		if ($kind === 'admin') {
857
			Context::addMetaTag('robots', 'noindex');
858
		}
859
860
		// if failed message exists in session, set context
861
		$this->_setInputErrorToContext();
862
863
		$procResult = $oModule->proc();
864
865
		$methodList = array('XMLRPC' => 1, 'JSON' => 1, 'JS_CALLBACK' => 1);
866
		if(!$oModule->stop_proc && !isset($methodList[Context::getRequestMethod()]))
867
		{
868
			$error = $oModule->getError();
869
			$message = $oModule->getMessage();
870
			$messageType = $oModule->getMessageType();
871
			$redirectUrl = $oModule->getRedirectUrl();
872
			if($messageType == 'error') debugPrint($message, 'ERROR');
0 ignored issues
show
Documentation introduced by
'ERROR' is of type string, but the function expects a boolean.

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...
873
874
			if(!$procResult)
875
			{
876
				$this->error = $message;
877
				if(!$redirectUrl && Context::get('error_return_url'))
878
				{
879
					$redirectUrl = Context::get('error_return_url');
880
				}
881
				$this->_setInputValueToSession();
882
			}
883
			else
884
			{
885
886
			}
887
888
			$_SESSION['XE_VALIDATOR_ERROR'] = $error;
889
			$_SESSION['XE_VALIDATOR_ID'] = Context::get('xe_validator_id');
890
			if($message != 'success')
891
			{
892
				$_SESSION['XE_VALIDATOR_MESSAGE'] = $message;
893
			}
894
			$_SESSION['XE_VALIDATOR_MESSAGE_TYPE'] = $messageType;
895
896
			if(Context::get('xeVirtualRequestMethod') != 'xml')
897
			{
898
				$_SESSION['XE_VALIDATOR_RETURN_URL'] = $redirectUrl;
899
			}
900
		}
901
902
		unset($logged_info);
903
		return $oModule;
904
	}
905
906
	/**
907
	 * set error message to Session.
908
	 * @return void
909
	 * */
910
	function _setInputErrorToContext()
911
	{
912
		if($_SESSION['XE_VALIDATOR_ERROR'] && !Context::get('XE_VALIDATOR_ERROR'))
913
		{
914
			Context::set('XE_VALIDATOR_ERROR', $_SESSION['XE_VALIDATOR_ERROR']);
915
		}
916
		if($_SESSION['XE_VALIDATOR_MESSAGE'] && !Context::get('XE_VALIDATOR_MESSAGE'))
917
		{
918
			Context::set('XE_VALIDATOR_MESSAGE', $_SESSION['XE_VALIDATOR_MESSAGE']);
919
		}
920
		if($_SESSION['XE_VALIDATOR_MESSAGE_TYPE'] && !Context::get('XE_VALIDATOR_MESSAGE_TYPE'))
921
		{
922
			Context::set('XE_VALIDATOR_MESSAGE_TYPE', $_SESSION['XE_VALIDATOR_MESSAGE_TYPE']);
923
		}
924
		if($_SESSION['XE_VALIDATOR_RETURN_URL'] && !Context::get('XE_VALIDATOR_RETURN_URL'))
925
		{
926
			Context::set('XE_VALIDATOR_RETURN_URL', $_SESSION['XE_VALIDATOR_RETURN_URL']);
927
		}
928
		if($_SESSION['XE_VALIDATOR_ID'] && !Context::get('XE_VALIDATOR_ID'))
929
		{
930
			Context::set('XE_VALIDATOR_ID', $_SESSION['XE_VALIDATOR_ID']);
931
		}
932
		if(count($_SESSION['INPUT_ERROR']))
933
		{
934
			Context::set('INPUT_ERROR', $_SESSION['INPUT_ERROR']);
935
		}
936
937
		$this->_clearErrorSession();
938
	}
939
940
	/**
941
	 * clear error message to Session.
942
	 * @return void
943
	 * */
944
	function _clearErrorSession()
945
	{
946
		$_SESSION['XE_VALIDATOR_ERROR'] = '';
947
		$_SESSION['XE_VALIDATOR_MESSAGE'] = '';
948
		$_SESSION['XE_VALIDATOR_MESSAGE_TYPE'] = '';
949
		$_SESSION['XE_VALIDATOR_RETURN_URL'] = '';
950
		$_SESSION['XE_VALIDATOR_ID'] = '';
951
		$_SESSION['INPUT_ERROR'] = '';
952
	}
953
954
	/**
955
	 * occured error when, set input values to session.
956
	 * @return void
957
	 * */
958
	function _setInputValueToSession()
959
	{
960
		$requestVars = Context::getRequestVars();
961
		unset($requestVars->act, $requestVars->mid, $requestVars->vid, $requestVars->success_return_url, $requestVars->error_return_url);
962
		foreach($requestVars AS $key => $value)
0 ignored issues
show
Bug introduced by
The expression $requestVars of type object<BaseObject> is not traversable.
Loading history...
963
		{
964
			$_SESSION['INPUT_ERROR'][$key] = $value;
965
		}
966
	}
967
968
	/**
969
	 * display contents from executed module
970
	 * @param ModuleObject $oModule module instance
971
	 * @return void
972
	 * */
973
	function displayContent($oModule = NULL)
974
	{
975
		// If the module is not set or not an object, set error
976
		if(!$oModule || !is_object($oModule))
977
		{
978
			$this->error = 'msg_module_is_not_exists';
979
			$this->httpStatusCode = '404';
980
		}
981
982
		// If connection to DB has a problem even though it's not install module, set error
983
		if($this->module != 'install' && isset($GLOBALS['__DB__']) && $GLOBALS['__DB__'][Context::getDBType()]->isConnected() == FALSE)
984
		{
985
			$this->error = 'msg_dbconnect_failed';
986
		}
987
988
		// Call trigger after moduleHandler proc
989
		$output = ModuleHandler::triggerCall('moduleHandler.proc', 'after', $oModule);
0 ignored issues
show
Bug introduced by
It seems like $oModule defined by parameter $oModule on line 973 can be null; however, ModuleHandler::triggerCall() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
990
		if(!$output->toBool())
991
		{
992
			$this->error = $output->getMessage();
993
		}
994
995
		// Use message view object, if HTML call
996
		$methodList = array('XMLRPC' => 1, 'JSON' => 1, 'JS_CALLBACK' => 1);
997
		if(!isset($methodList[Context::getRequestMethod()]))
998
		{
999
1000
			if($_SESSION['XE_VALIDATOR_RETURN_URL'])
1001
			{
1002
				$display_handler = new DisplayHandler();
1003
				$display_handler->_debugOutput();
1004
1005
				header('location:' . $_SESSION['XE_VALIDATOR_RETURN_URL']);
1006
				return;
1007
			}
1008
1009
			// If error occurred, handle it
1010
			if($this->error)
1011
			{
1012
				// display content with message module instance
1013
				$type = Mobile::isFromMobilePhone() ? 'mobile' : 'view';
1014
				$oMessageObject = ModuleHandler::getModuleInstance('message', $type);
1015
				$oMessageObject->setError(-1);
1016
				$oMessageObject->setMessage($this->error);
1017
				$oMessageObject->dispMessage();
1018
1019
				if($oMessageObject->getHttpStatusCode() && $oMessageObject->getHttpStatusCode() != '200')
1020
				{
1021
					$this->_setHttpStatusMessage($oMessageObject->getHttpStatusCode());
1022
					$oMessageObject->setTemplateFile('http_status_code');
1023
				}
1024
1025
				// If module was called normally, change the templates of the module into ones of the message view module
1026
				if($oModule)
1027
				{
1028
					$oModule->setTemplatePath($oMessageObject->getTemplatePath());
1029
					$oModule->setTemplateFile($oMessageObject->getTemplateFile());
1030
					// Otherwise, set message instance as the target module
1031
				}
1032
				else
1033
				{
1034
					$oModule = $oMessageObject;
1035
				}
1036
1037
				$this->_clearErrorSession();
1038
			}
1039
1040
			// Check if layout_srl exists for the module
1041
			if(Mobile::isFromMobilePhone())
1042
			{
1043
				$layout_srl = $oModule->module_info->mlayout_srl;
1044
			}
1045
			else
1046
			{
1047
				$layout_srl = $oModule->module_info->layout_srl;
1048
			}
1049
1050
			// if layout_srl is rollback by module, set default layout
1051
			if($layout_srl == -1)
1052
			{
1053
				$viewType = (Mobile::isFromMobilePhone()) ? 'M' : 'P';
1054
				$oLayoutAdminModel = getAdminModel('layout');
1055
				$layout_srl = $oLayoutAdminModel->getSiteDefaultLayout($viewType, $oModule->module_info->site_srl);
1056
			}
1057
1058
			if($layout_srl && !$oModule->getLayoutFile())
1059
			{
1060
1061
				// If layout_srl exists, get information of the layout, and set the location of layout_path/ layout_file
1062
				$oLayoutModel = getModel('layout');
1063
				$layout_info = $oLayoutModel->getLayout($layout_srl);
0 ignored issues
show
Bug introduced by
The method getLayout() does not exist on ModuleObject. Did you maybe mean getLayoutFile()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1064
				if($layout_info)
1065
				{
1066
1067
					// Input extra_vars into $layout_info
1068 View Code Duplication
					if($layout_info->extra_var_count)
1069
					{
1070
1071
						foreach($layout_info->extra_var as $var_id => $val)
1072
						{
1073
							if($val->type == 'image')
1074
							{
1075
								if(strncmp('./files/attach/images/', $val->value, 22) === 0)
1076
								{
1077
									$val->value = Context::getRequestUri() . substr($val->value, 2);
1078
								}
1079
							}
1080
							$layout_info->{$var_id} = $val->value;
1081
						}
1082
					}
1083
					// Set menus into context
1084
					if($layout_info->menu_count)
1085
					{
1086
						foreach($layout_info->menu as $menu_id => $menu)
1087
						{
1088
							// set default menu set(included home menu)
1089 View Code Duplication
							if(!$menu->menu_srl || $menu->menu_srl == -1)
1090
							{
1091
								$oMenuAdminController = getAdminController('menu');
1092
								$homeMenuCacheFile = $oMenuAdminController->getHomeMenuCacheFile();
1093
1094
								if(FileHandler::exists($homeMenuCacheFile))
0 ignored issues
show
Bug Best Practice introduced by
The expression \FileHandler::exists($homeMenuCacheFile) 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...
1095
								{
1096
									include($homeMenuCacheFile);
1097
								}
1098
1099
								if(!$menu->menu_srl)
1100
								{
1101
									$menu->xml_file = str_replace('.xml.php', $homeMenuSrl . '.xml.php', $menu->xml_file);
0 ignored issues
show
Bug introduced by
The variable $homeMenuSrl 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...
1102
									$menu->php_file = str_replace('.php', $homeMenuSrl . '.php', $menu->php_file);
1103
									$layout_info->menu->{$menu_id}->menu_srl = $homeMenuSrl;
1104
								}
1105
								else
1106
								{
1107
									$menu->xml_file = str_replace($menu->menu_srl, $homeMenuSrl, $menu->xml_file);
1108
									$menu->php_file = str_replace($menu->menu_srl, $homeMenuSrl, $menu->php_file);
1109
								}
1110
							}
1111
1112
							$php_file = FileHandler::exists($menu->php_file);
1113
							if($php_file)
0 ignored issues
show
Bug Best Practice introduced by
The expression $php_file 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...
1114
							{
1115
								include($php_file);
1116
							}
1117
							Context::set($menu_id, $menu);
1118
						}
1119
					}
1120
1121
					// Set layout information into context
1122
					Context::set('layout_info', $layout_info);
1123
1124
					$oModule->setLayoutPath($layout_info->path);
1125
					$oModule->setLayoutFile('layout');
1126
1127
					// If layout was modified, use the modified version
1128
					$edited_layout = $oLayoutModel->getUserLayoutHtml($layout_info->layout_srl);
1129
					if(file_exists($edited_layout))
1130
					{
1131
						$oModule->setEditedLayoutFile($edited_layout);
1132
					}
1133
				}
1134
			}
1135
			$isLayoutDrop = Context::get('isLayoutDrop');
1136
			if($isLayoutDrop)
1137
			{
1138
				$kind = stripos($this->act, 'admin') !== FALSE ? 'admin' : '';
1139
				if($kind == 'admin')
1140
				{
1141
					$oModule->setLayoutFile('popup_layout');
1142
				}
1143
				else
1144
				{
1145
					$oModule->setLayoutPath('common/tpl');
1146
					$oModule->setLayoutFile('default_layout');
1147
				}
1148
			}
1149
		}
1150
1151
		// Display contents
1152
		$oDisplayHandler = new DisplayHandler();
1153
		$oDisplayHandler->printContent($oModule);
1154
	}
1155
1156
	/**
1157
	 * returns module's path
1158
	 * @param string $module module name
1159
	 * @return string path of the module
1160
	 * */
1161
	function getModulePath($module)
1162
	{
1163
		return sprintf('./modules/%s/', $module);
1164
	}
1165
1166
	/**
1167
	 * It creates a module instance
1168
	 * @param string $module module name
1169
	 * @param string $type instance type, (e.g., view, controller, model)
1170
	 * @param string $kind admin or svc
1171
	 * @return ModuleObject module instance (if failed it returns null)
1172
	 * @remarks if there exists a module instance created before, returns it.
1173
	 * */
1174
	function &getModuleInstance($module, $type = 'view', $kind = '')
1175
	{
1176
1177
		if(__DEBUG__ == 3)
1178
		{
1179
			$start_time = getMicroTime();
1180
		}
1181
1182
		$parent_module = $module;
1183
		$kind = strtolower($kind);
1184
		$type = strtolower($type);
1185
1186
		$kinds = array('svc' => 1, 'admin' => 1);
1187
		if(!isset($kinds[$kind]))
1188
		{
1189
			$kind = 'svc';
1190
		}
1191
1192
		$key = $module . '.' . ($kind != 'admin' ? '' : 'admin') . '.' . $type;
1193
1194
		if(is_array($GLOBALS['__MODULE_EXTEND__']) && array_key_exists($key, $GLOBALS['__MODULE_EXTEND__']))
1195
		{
1196
			$module = $extend_module = $GLOBALS['__MODULE_EXTEND__'][$key];
1197
		}
1198
1199
		// if there is no instance of the module in global variable, create a new one
1200
		if(!isset($GLOBALS['_loaded_module'][$module][$type][$kind]))
1201
		{
1202
			ModuleHandler::_getModuleFilePath($module, $type, $kind, $class_path, $high_class_file, $class_file, $instance_name);
1203
1204
			if($extend_module && (!is_readable($high_class_file) || !is_readable($class_file)))
0 ignored issues
show
Bug introduced by
The variable $extend_module 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...
1205
			{
1206
				$module = $parent_module;
1207
				ModuleHandler::_getModuleFilePath($module, $type, $kind, $class_path, $high_class_file, $class_file, $instance_name);
1208
			}
1209
1210
			// Check if the base class and instance class exist
1211
			if(!class_exists($module, true))
1212
			{
1213
				return NULL;
1214
			}
1215
			if(!class_exists($instance_name, true))
1216
			{
1217
				return NULL;
1218
			}
1219
1220
			// Create an instance
1221
			$oModule = new $instance_name();
1222
			if(!is_object($oModule))
1223
			{
1224
				return NULL;
1225
			}
1226
1227
			// Load language files for the class
1228
			Context::loadLang($class_path . 'lang');
1229
			if($extend_module)
1230
			{
1231
				Context::loadLang(ModuleHandler::getModulePath($parent_module) . 'lang');
1232
			}
1233
1234
			// Set variables to the instance
1235
			$oModule->setModule($module);
1236
			$oModule->setModulePath($class_path);
1237
1238
			// If the module has a constructor, run it.
1239
			if(!isset($GLOBALS['_called_constructor'][$instance_name]))
1240
			{
1241
				$GLOBALS['_called_constructor'][$instance_name] = TRUE;
1242
				if(@method_exists($oModule, $instance_name))
1243
				{
1244
					$oModule->{$instance_name}();
1245
				}
1246
			}
1247
1248
			// Store the created instance into GLOBALS variable
1249
			$GLOBALS['_loaded_module'][$module][$type][$kind] = $oModule;
1250
		}
1251
1252
		if(__DEBUG__ == 3)
1253
		{
1254
			$GLOBALS['__elapsed_class_load__'] += getMicroTime() - $start_time;
0 ignored issues
show
Bug introduced by
The variable $start_time 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...
1255
		}
1256
1257
		// return the instance
1258
		return $GLOBALS['_loaded_module'][$module][$type][$kind];
1259
	}
1260
1261
	function _getModuleFilePath($module, $type, $kind, &$classPath, &$highClassFile, &$classFile, &$instanceName)
1262
	{
1263
		$classPath = ModuleHandler::getModulePath($module);
1264
1265
		$highClassFile = sprintf('%s%s%s.class.php', _XE_PATH_, $classPath, $module);
1266
		$highClassFile = FileHandler::getRealPath($highClassFile);
1267
1268
		$types = array('view','controller','model','api','wap','mobile','class');
1269
		if(!in_array($type, $types))
1270
		{
1271
			$type = $types[0];
1272
		}
1273
		if($type == 'class')
1274
		{
1275
			$instanceName = '%s';
1276
			$classFile = '%s%s.%s.php';
1277
		}
1278
		elseif($kind == 'admin' && array_search($type, $types) < 3)
1279
		{
1280
			$instanceName = '%sAdmin%s';
1281
			$classFile = '%s%s.admin.%s.php';
1282
		}
1283
		else
1284
		{
1285
			$instanceName = '%s%s';
1286
			$classFile = '%s%s.%s.php';
1287
		}
1288
1289
		$instanceName = sprintf($instanceName, $module, ucfirst($type));
1290
		$classFile = FileHandler::getRealPath(sprintf($classFile, $classPath, $module, $type));
1291
	}
1292
1293
	/**
1294
	 * call a trigger
1295
	 * @param string $trigger_name trigger's name to call
1296
	 * @param string $called_position called position
1297
	 * @param object $obj an object as a parameter to trigger
1298
	 * @return BaseObject
1299
	 * */
1300
	function triggerCall($trigger_name, $called_position, &$obj)
1301
	{
1302
		// skip if not installed
1303
		if(!Context::isInstalled())
1304
		{
1305
			return new BaseObject();
1306
		}
1307
1308
		$oModuleModel = getModel('module');
1309
		$triggers = $oModuleModel->getTriggers($trigger_name, $called_position);
1310
		if(!$triggers || count($triggers) < 1)
1311
		{
1312
			return new BaseObject();
1313
		}
1314
1315
		//store before trigger call time
1316
		$before_trigger_time = NULL;
0 ignored issues
show
Unused Code introduced by
$before_trigger_time 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...
1317
		if(__LOG_SLOW_TRIGGER__> 0)
1318
		{
1319
			$before_trigger_time = microtime(true);
0 ignored issues
show
Unused Code introduced by
$before_trigger_time 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...
1320
		}
1321
1322
		foreach($triggers as $item)
1323
		{
1324
			$module = $item->module;
1325
			$type = $item->type;
1326
			$called_method = $item->called_method;
1327
1328
			// todo why don't we call a normal class object ?
1329
			$oModule = getModule($module, $type);
1330
			if(!$oModule || !method_exists($oModule, $called_method))
1331
			{
1332
				continue;
1333
			}
1334
1335
			$before_each_trigger_time = microtime(true);
1336
1337
			$output = $oModule->{$called_method}($obj);
1338
1339
			$after_each_trigger_time = microtime(true);
1340
			$elapsed_time_trigger = $after_each_trigger_time - $before_each_trigger_time;
1341
1342
			$slowlog = new stdClass;
1343
			$slowlog->caller = $trigger_name . '.' . $called_position;
1344
			$slowlog->called = $module . '.' . $called_method;
1345
			$slowlog->called_extension = $module;
1346
			if($trigger_name != 'XE.writeSlowlog') writeSlowlog('trigger', $elapsed_time_trigger, $slowlog);
1347
1348
			if(is_object($output) && method_exists($output, 'toBool') && !$output->toBool())
1349
			{
1350
				return $output;
1351
			}
1352
			unset($oModule);
1353
		}
1354
1355
		return new BaseObject();
1356
	}
1357
1358
	/**
1359
	 * get http status message by http status code
1360
	 * @param string $code
1361
	 * @return string
1362
	 * */
1363
	function _setHttpStatusMessage($code)
1364
	{
1365
		$statusMessageList = array(
1366
			// 1×× Informational
1367
			'100' => 'Continue',
1368
			'101' => 'Switching Protocols',
1369
			'102' => 'Processing',
1370
			// 2×× Success
1371
			'200' => 'OK',
1372
			'201' => 'Created',
1373
			'202' => 'Accepted',
1374
			'203' => 'Non-authoritative Information',
1375
			'204' => 'No Content',
1376
			'205' => 'Reset Content',
1377
			'206' => 'Partial Content',
1378
			'207' => 'Multi-Status',
1379
			'208' => 'Already Reported',
1380
			'226' => 'IM Used',
1381
			// 3×× Redirection
1382
			'300' => 'Multiple Choices',
1383
			'301' => 'Moved Permanently',
1384
			'302' => 'Found',
1385
			'303' => 'See Other',
1386
			'304' => 'Not Modified',
1387
			'305' => 'Use Proxy',
1388
			'307' => 'Temporary Redirect',
1389
			'308' => 'Permanent Redirect',
1390
			// 4×× Client Error
1391
			'400' => 'Bad Request',
1392
			'401' => 'Unauthorized',
1393
			'402' => 'Payment Required',
1394
			'403' => 'Forbidden',
1395
			'404' => 'Not Found',
1396
			'405' => 'Method Not Allowed',
1397
			'406' => 'Not Acceptable',
1398
			'407' => 'Proxy Authentication Required',
1399
			'408' => 'Request Timeout',
1400
			'409' => 'Conflict',
1401
			'410' => 'Gone',
1402
			'411' => 'Length Required',
1403
			'412' => 'Precondition Failed',
1404
			'413' => 'Payload Too Large',
1405
			'414' => 'Request-URI Too Long',
1406
			'415' => 'Unsupported Media Type',
1407
			'416' => 'Requested Range Not Satisfiable',
1408
			'417' => 'Expectation Failed',
1409
			'418' => 'I\'m a teapot',
1410
			'421' => 'Misdirected Request',
1411
			'422' => 'Unprocessable Entity',
1412
			'423' => 'Locked',
1413
			'424' => 'Failed Dependency',
1414
			'426' => 'Upgrade Required',
1415
			'428' => 'Precondition Required',
1416
			'429' => 'Too Many Requests',
1417
			'431' => 'Request Header Fields Too Large',
1418
			'451' => 'Unavailable For Legal Reasons',
1419
			// 5×× Server Error
1420
			'500' => 'Internal Server Error',
1421
			'501' => 'Not Implemented',
1422
			'502' => 'Bad Gateway',
1423
			'503' => 'Service Unavailable',
1424
			'504' => 'Gateway Timeout',
1425
			'505' => 'HTTP Version Not Supported',
1426
			'506' => 'Variant Also Negotiates',
1427
			'507' => 'Insufficient Storage',
1428
			'508' => 'Loop Detected',
1429
			'510' => 'Not Extended',
1430
			'511' => 'Network Authentication Required',
1431
		);
1432
		$statusMessage = $statusMessageList[$code];
1433
		if(!$statusMessage)
1434
		{
1435
			$statusMessage = 'HTTP ' . $code;
1436
		}
1437
1438
		Context::set('http_status_code', $code);
1439
		Context::set('http_status_message', $statusMessage);
1440
	}
1441
1442
}
1443
/* End of file ModuleHandler.class.php */
1444
/* Location: ./classes/module/ModuleHandler.class.php */
1445