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 ( a47a81...50dc3a )
by gyeong-won
06:20
created

TemplateHandler::parse()   C

Complexity

Conditions 10
Paths 49

Size

Total Lines 73

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
nc 49
nop 1
dl 0
loc 73
rs 6.7224
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/* Copyright (C) NAVER <http://www.navercorp.com> */
3
4
/**
5
 * @class TemplateHandler
6
 * @author NAVER ([email protected])
7
 * template compiler
8
 * @version 0.1
9
 * @remarks It compiles template file by using regular expression into php
10
 *          code, and XE caches compiled code for further uses
11
 */
12
class TemplateHandler
13
{
14
15
	private $compiled_path = 'files/cache/template_compiled/'; ///< path of compiled caches files
16
	private $path = NULL; ///< target directory
17
	private $filename = NULL; ///< target filename
18
	private $file = NULL; ///< target file (fullpath)
19
	private $xe_path = NULL;  ///< XpressEngine base path
20
	private $web_path = NULL; ///< tpl file web path
21
	private $compiled_file = NULL; ///< tpl file web path
22
	private $config = NULL;
23
	private $skipTags = NULL;
24
	private $handler_mtime = 0;
25
	private $autoescape = false;
26
	static private $rootTpl = NULL;
27
28
	/**
29
	 * constructor
30
	 * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

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

Please refer to the PHP core documentation on constructors.

Loading history...
31
	 */
32
	public function __construct()
33
	{
34
		ini_set('pcre.jit', "0");
35
		$this->xe_path = rtrim(getScriptPath(), '/');
36
		$this->compiled_path = _XE_PATH_ . $this->compiled_path;
37
		$this->config = new stdClass();
38
39
		$this->ignoreEscape = array(
0 ignored issues
show
Bug introduced by
The property ignoreEscape 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...
40
			'functions' => function ($m) {
41
				$list = array(
42
					'htmlspecialchars',
43
					'nl2br',
44
				);
45
				return preg_match('/^(' . implode('|', $list) . ')\(/', $m[1]);
46
			},
47
			'lang' => function ($m) {
48
				// 다국어
49
				return preg_match('/^\$lang\-\>/', trim($m[1]));
50
			}
51
		);
52
53
		$this->dbinfo = Context::getDBInfo();
0 ignored issues
show
Bug introduced by
The property dbinfo 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...
54
	}
55
56
	/**
57
	 * returns TemplateHandler's singleton object
58
	 * @return TemplateHandler instance
59
	 */
60
	static public function &getInstance()
61
	{
62
		static $oTemplate = NULL;
63
64
		if(__DEBUG__ == 3)
65
		{
66
			if(!isset($GLOBALS['__TemplateHandlerCalled__']))
67
			{
68
				$GLOBALS['__TemplateHandlerCalled__'] = 1;
69
			}
70
			else
71
			{
72
				$GLOBALS['__TemplateHandlerCalled__']++;
73
			}
74
		}
75
76
		if(!$oTemplate)
77
		{
78
			$oTemplate = new TemplateHandler();
79
		}
80
81
		return $oTemplate;
82
	}
83
84
	/**
85
	 * set variables for template compile
86
	 * @param string $tpl_path
87
	 * @param string $tpl_filename
88
	 * @param string $tpl_file
89
	 * @return void
90
	 */
91
	protected function init($tpl_path, $tpl_filename, $tpl_file = '')
92
	{
93
		// verify arguments
94
		if(substr($tpl_path, -1) != '/')
95
		{
96
			$tpl_path .= '/';
97
		}
98
		if(!is_dir($tpl_path))
99
		{
100
			return;
101
		}
102
		if(!file_exists($tpl_path . $tpl_filename) && file_exists($tpl_path . $tpl_filename . '.html'))
103
		{
104
			$tpl_filename .= '.html';
105
		}
106
107
		// create tpl_file variable
108
		if(!$tpl_file)
109
		{
110
			$tpl_file = $tpl_path . $tpl_filename;
111
		}
112
113
		// set template file infos.
114
		$this->path = $tpl_path;
115
		$this->filename = $tpl_filename;
116
		$this->file = $tpl_file;
117
118
		$this->web_path = $this->xe_path . '/' . ltrim(preg_replace('@^' . preg_quote(_XE_PATH_, '@') . '|\./@', '', $this->path), '/');
119
120
		// get compiled file name
121
		$hash = md5($this->file . __XE_VERSION__);
122
		$this->compiled_file = "{$this->compiled_path}{$hash}.compiled.php";
123
124
		$this->autoescape = $this->isAutoescape();
125
126
		// compare various file's modified time for check changed
127
		$this->handler_mtime = filemtime(__FILE__);
128
129
		$skip = array('');
0 ignored issues
show
Unused Code introduced by
$skip 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...
130
	}
131
132
	/**
133
	 * compiles specified tpl file and execution result in Context into resultant content
134
	 * @param string $tpl_path path of the directory containing target template file
135
	 * @param string $tpl_filename target template file's name
136
	 * @param string $tpl_file if specified use it as template file's full path
137
	 * @return string Returns compiled result in case of success, NULL otherwise
138
	 */
139
	public function compile($tpl_path, $tpl_filename, $tpl_file = '')
140
	{
141
		$buff = false;
142
143
		// store the starting time for debug information
144
		if(__DEBUG__ == 3)
145
		{
146
			$start = getMicroTime();
147
		}
148
149
		// initiation
150
		$this->init($tpl_path, $tpl_filename, $tpl_file);
151
152
		// if target file does not exist exit
153
		if(!$this->file || !file_exists($this->file))
154
		{
155
			return "Err : '{$this->file}' template file does not exists.";
156
		}
157
158
		// for backward compatibility
159
		if(is_null(self::$rootTpl))
160
		{
161
			self::$rootTpl = $this->file;
162
		}
163
164
		$source_template_mtime = filemtime($this->file);
165
		$latest_mtime = $source_template_mtime > $this->handler_mtime ? $source_template_mtime : $this->handler_mtime;
166
167
		// cache control
168
		$oCacheHandler = CacheHandler::getInstance('template');
169
170
		// get cached buff
171
		if($oCacheHandler->isSupport())
172
		{
173
			$cache_key = 'template:' . $this->file;
174
			$buff = $oCacheHandler->get($cache_key, $latest_mtime);
175
		}
176
		else
177
		{
178
			if(is_readable($this->compiled_file) && filemtime($this->compiled_file) > $latest_mtime && filesize($this->compiled_file))
179
			{
180
				$buff = 'file://' . $this->compiled_file;
181
			}
182
		}
183
184
		if($buff === FALSE)
185
		{
186
			$buff = $this->parse();
187
			if($oCacheHandler->isSupport())
188
			{
189
				$oCacheHandler->put($cache_key, $buff);
0 ignored issues
show
Bug introduced by
The variable $cache_key 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...
190
			}
191
			else
192
			{
193
				FileHandler::writeFile($this->compiled_file, $buff);
194
			}
195
		}
196
197
		$output = $this->_fetch($buff);
0 ignored issues
show
Bug introduced by
It seems like $buff can also be of type boolean or null; however, TemplateHandler::_fetch() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
198
199
		if($__templatehandler_root_tpl == $this->file)
0 ignored issues
show
Bug introduced by
The variable $__templatehandler_root_tpl 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...
200
		{
201
			$__templatehandler_root_tpl = null;
0 ignored issues
show
Unused Code introduced by
$__templatehandler_root_tpl 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...
202
		}
203
204
		// store the ending time for debug information
205
		if(__DEBUG__ == 3)
206
		{
207
			$GLOBALS['__template_elapsed__'] += getMicroTime() - $start;
0 ignored issues
show
Bug introduced by
The variable $start 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...
208
		}
209
210
		return $output;
211
	}
212
213
	/**
214
	 * compile specified file and immediately return
215
	 * @param string $tpl_path path of the directory containing target template file
216
	 * @param string $tpl_filename target template file's name
217
	 * @return string Returns compiled content in case of success or NULL in case of failure
218
	 */
219
	public function compileDirect($tpl_path, $tpl_filename)
220
	{
221
		$this->init($tpl_path, $tpl_filename, null);
222
223
		// if target file does not exist exit
224
		if(!$this->file || !file_exists($this->file))
225
		{
226
			Context::close();
227
			exit("Cannot find the template file: '{$this->file}'");
228
		}
229
230
		return $this->parse();
231
	}
232
233
	/**
234
	 * parse syntax.
235
	 * @param string $buff template file
236
	 * @return string compiled result in case of success or NULL in case of error
237
	 */
238
	protected function parse($buff = null)
239
	{
240
		if(is_null($buff))
241
		{
242
			if(!is_readable($this->file))
243
			{
244
				return;
245
			}
246
247
			// read tpl file
248
			$buff = FileHandler::readFile($this->file);
249
		}
250
251
		// HTML tags to skip
252
		if(is_null($this->skipTags))
253
		{
254
			$this->skipTags = array('marquee');
255
		}
256
257
		// reset config for this buffer (this step is necessary because we use a singleton for every template)
258
		$previous_config = clone $this->config;
259
		$this->config = new stdClass();
260
		$this->config->autoescape = null;
261
262
		if(preg_match('/\<config( [^\>\/]+)/', $buff, $config_match))
263
		{
264
			if(preg_match_all('@ (?<name>\w+)="(?<value>[^"]+)"@', $config_match[1], $config_matches, PREG_SET_ORDER))
265
			{
266
				foreach($config_matches as $config_match)
267
				{
268
					if($config_match['name'] === 'autoescape')
269
					{
270
						$this->config->autoescape = $config_match['value'];
271
					}
272
				}
273
			}
274
		}
275
276
		if($this->config->autoescape === 'on') $this->autoescape = true;
277
278
		// replace comments
279
		$buff = preg_replace('@<!--//.*?-->@s', '', $buff);
280
281
		// replace value of src in img/input/script tag
282
		$buff = preg_replace_callback('/<(?:img|input|script)(?:[^<>]*?)(?(?=cond=")(?:cond="[^"]+"[^<>]*)+|)[^<>]* src="(?!(?:https?|file):\/\/|[\/\{])([^"]+)"/is', array($this, '_replacePath'), $buff);
283
284
		// replace loop and cond template syntax
285
		$buff = $this->_parseInline($buff);
286
287
		// include, unload/load, import
288
		$buff = preg_replace_callback('/{(@[\s\S]+?|(?=\$\w+|_{1,2}[A-Z]+|[!\(+-]|\w+(?:\(|::)|\d+|[\'"].*?[\'"]).+?)}|<(!--[#%])?(include|import|(un)?load(?(4)|(?:_js_plugin)?)|config)(?(2)\(["\']([^"\']+)["\'])(.*?)(?(2)\)--|\/)>|<!--(@[a-z@]*)([\s\S]*?)-->(\s*)/', array($this, '_parseResource'), $buff);
289
290
		// remove block which is a virtual tag
291
		$buff = preg_replace('@</?block\s*>@is', '', $buff);
292
293
		// form auto generation
294
		$temp = preg_replace_callback('/(<form(?:<\?php.+?\?>|[^<>]+)*?>)(.*?)(<\/form>)/is', array($this, '_compileFormAuthGeneration'), $buff);
295
		if($temp)
296
		{
297
			$buff = $temp;
298
		}
299
300
		// prevent from calling directly before writing into file
301
		$buff = '<?php if(!defined("__XE__"))exit;?>' . $buff;
302
303
		// remove php script reopening
304
		$buff = preg_replace(array('/(\n|\r\n)+/', '/(;)?( )*\?\>\<\?php([\n\t ]+)?/'), array("\n", ";\n"), $buff);
305
306
		// restore config to previous value
307
		$this->config = $previous_config;
308
309
		return $buff;
310
	}
311
312
	/**
313
	 * preg_replace_callback handler
314
	 * 1. remove ruleset from form tag
315
	 * 2. add hidden tag with ruleset value
316
	 * 3. if empty default hidden tag, generate hidden tag (ex:mid, vid, act...)
317
	 * 4. generate return url, return url use in server side validator
318
	 * @param array $matches
319
	 * @return string
320
	 */
321
	private function _compileFormAuthGeneration($matches)
322
	{
323
		// form ruleset attribute move to hidden tag
324
		if($matches[1])
325
		{
326
			preg_match('/ruleset="([^"]*?)"/is', $matches[1], $m);
327
			if($m[0])
328
			{
329
				$matches[1] = preg_replace('/' . addcslashes($m[0], '?$') . '/i', '', $matches[1]);
330
331
				if(strpos($m[1], '@') !== FALSE)
332
				{
333
					$path = str_replace('@', '', $m[1]);
334
					$path = './files/ruleset/' . $path . '.xml';
335
				}
336
				else if(strpos($m[1], '#') !== FALSE)
337
				{
338
					$fileName = str_replace('#', '', $m[1]);
339
					$fileName = str_replace('<?php echo ', '', $fileName);
340
					$fileName = str_replace(' ?>', '', $fileName);
341
					$path = '#./files/ruleset/' . $fileName . '.xml';
342
343
					preg_match('@(?:^|\.?/)(modules/[\w-]+)@', $this->path, $mm);
344
					$module_path = $mm[1];
345
					list($rulsetFile) = explode('.', $fileName);
346
					$autoPath = $module_path . '/ruleset/' . $rulsetFile . '.xml';
347
					$m[1] = $rulsetFile;
348
				}
349
				else if(preg_match('@(?:^|\.?/)(modules/[\w-]+)@', $this->path, $mm))
350
				{
351
					$module_path = $mm[1];
352
					$path = $module_path . '/ruleset/' . $m[1] . '.xml';
353
				}
354
355
				$matches[2] = '<input type="hidden" name="ruleset" value="' . $m[1] . '" />' . $matches[2];
356
				//assign to addJsFile method for js dynamic recache
357
				$matches[1] = '<?php Context::addJsFile("' . $path . '", FALSE, "", 0, "body", TRUE, "' . $autoPath . '") ?' . '>' . $matches[1];
0 ignored issues
show
Bug introduced by
The variable $path 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 introduced by
The variable $autoPath 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...
358
			}
359
		}
360
361
		// if not exists default hidden tag, generate hidden tag
362
		preg_match_all('/<input[^>]* name="(act|mid|vid)"/is', $matches[2], $m2);
363
		$checkVar = array('act', 'mid', 'vid');
364
		$resultArray = array_diff($checkVar, $m2[1]);
365
		if(is_array($resultArray))
366
		{
367
			$generatedHidden = '';
368
			foreach($resultArray AS $key => $value)
369
			{
370
				$generatedHidden .= '<input type="hidden" name="' . $value . '" value="<?php echo $__Context->' . $value . ' ?>" />';
371
			}
372
			$matches[2] = $generatedHidden . $matches[2];
373
		}
374
375
		// return url generate
376
		if(!preg_match('/no-error-return-url="true"/i', $matches[1]))
377
		{
378
			preg_match('/<input[^>]*name="error_return_url"[^>]*>/is', $matches[2], $m3);
379
			if(!$m3[0])
380
				$matches[2] = '<input type="hidden" name="error_return_url" value="<?php echo htmlspecialchars(getRequestUriByServerEnviroment(), ENT_COMPAT | ENT_HTML401, \'UTF-8\', false) ?>" />' . $matches[2];
381
		}
382
		else
383
		{
384
			$matches[1] = preg_replace('/no-error-return-url="true"/i', '', $matches[1]);
385
		}
386
387
		$matches[0] = '';
388
		return implode($matches);
389
	}
390
391
	/**
392
	 * fetch using ob_* function
393
	 * @param string $buff if buff is not null, eval it instead of including compiled template file
394
	 * @return string
395
	 */
396
	private function _fetch($buff)
397
	{
398
		if(!$buff)
399
		{
400
			return;
401
		}
402
403
		$__Context = &$GLOBALS['__Context__'];
404
		$__Context->tpl_path = $this->path;
405
406
		if($_SESSION['is_logged'])
407
		{
408
			$__Context->logged_info = Context::get('logged_info');
409
		}
410
411
		$level = ob_get_level();
412
		ob_start();
413
		if(substr($buff, 0, 7) == 'file://')
414
		{
415
			if(__DEBUG__)
416
			{
417
				//load cache file from disk
418
				$eval_str = FileHandler::readFile(substr($buff, 7));
419
				$eval_str_buffed = "?>" . $eval_str;
420
				@eval($eval_str_buffed);
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...
421
				$error_info = error_get_last();
422
				//parse error
423
				if ($error_info['type'] == 4)
424
				{
425
				    throw new Exception("Error Parsing Template - {$error_info['message']} in template file {$this->file}");
426
				}
427
			}
428
			else
429
			{
430
				include(substr($buff, 7));
431
			}
432
		}
433
		else
434
		{
435
			$eval_str = "?>" . $buff;
436
			@eval($eval_str);
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...
437
			$error_info = error_get_last();
438
			//parse error
439
			if ($error_info['type'] == 4)
440
			{
441
			    throw new Exception("Error Parsing Template - {$error_info['message']} in template file {$this->file}");
442
			}
443
		}
444
445
		$contents = '';
446
		while (ob_get_level() - $level > 0) {
447
			$contents .= ob_get_contents();
448
			ob_end_clean();
449
		}
450
		return $contents;
451
	}
452
453
	/**
454
	 * preg_replace_callback hanlder
455
	 *
456
	 * replace image path
457
	 * @param array $match
458
	 *
459
	 * @return string changed result
460
	 */
461
	private function _replacePath($match)
462
	{
463
		//return origin conde when src value started '${'.
464
		if(preg_match('@^\${@', $match[1]))
465
		{
466
			return $match[0];
467
		}
468
469
		//return origin code when src value include variable.
470
		if(preg_match('@^[\'|"]\s*\.\s*\$@', $match[1]))
471
		{
472
			return $match[0];
473
		}
474
475
		$src = preg_replace('@^(\./)+@', '', trim($match[1]));
476
477
		$src = $this->web_path . $src;
478
		$src = str_replace('/./', '/', $src);
479
480
		// for backward compatibility
481
		$src = preg_replace('@/((?:[\w-]+/)+)\1@', '/\1', $src);
482
483
		while(($tmp = preg_replace('@[^/]+/\.\./@', '', $src, 1)) !== $src)
484
		{
485
			$src = $tmp;
486
		}
487
488
		return substr($match[0], 0, -strlen($match[1]) - 6) . "src=\"{$src}\"";
489
	}
490
491
	/**
492
	 * replace loop and cond template syntax
493
	 * @param string $buff
494
	 * @return string changed result
495
	 */
496
	private function _parseInline($buff)
497
	{
498
		if(!preg_match_all('/<([a-zA-Z]+\d?)(?:\s)/', $buff, $match))
499
		{
500
			return $buff;
501
		}
502
503
		$tags = array_diff(array_unique($match[1]), $this->skipTags);
504
505
		if(!count($tags))
506
		{
507
			return $buff;
508
		}
509
510
		$tags = '(?:' . implode('|', $tags) . ')';
511
		$split_regex = "@(<(?>/?{$tags})(?>[^<>\{\}\"']+|<!--.*?-->|{[^}]+}|\".*?\"|'.*?'|.)*?>)@s";
512
513
		$nodes = preg_split($split_regex, $buff, -1, PREG_SPLIT_DELIM_CAPTURE);
514
515
		// list of self closing tags
516
		$self_closing = array('area' => 1, 'base' => 1, 'basefont' => 1, 'br' => 1, 'hr' => 1, 'input' => 1, 'img' => 1, 'link' => 1, 'meta' => 1, 'param' => 1, 'frame' => 1, 'col' => 1);
517
518
		for($idx = 1, $node_len = count($nodes); $idx < $node_len; $idx+=2)
519
		{
520
			if(!($node = $nodes[$idx]))
521
			{
522
				continue;
523
			}
524
525
			if(preg_match_all('@\s(loop|cond)="([^"]+)"@', $node, $matches))
526
			{
527
				// this tag
528
				$tag = substr($node, 1, strpos($node, ' ') - 1);
529
530
				// if the vale of $closing is 0, it means 'skipping'
531
				$closing = 0;
532
533
				// process opening tag
534
				foreach($matches[1] as $n => $stmt)
535
				{
536
					$expr = $matches[2][$n];
537
					$expr = $this->_replaceVar($expr);
538
					$closing++;
539
540
					switch($stmt)
541
					{
542
						case 'cond':
543
							$nodes[$idx - 1] .= "<?php if({$expr}){ ?>";
544
							break;
545
						case 'loop':
546
							if(!preg_match('@^(?:(.+?)=>(.+?)(?:,(.+?))?|(.*?;.*?;.*?)|(.+?)\s*=\s*(.+?))$@', $expr, $expr_m))
547
							{
548
								break;
549
							}
550
							if($expr_m[1])
551
							{
552
								$expr_m[1] = trim($expr_m[1]);
553
								$expr_m[2] = trim($expr_m[2]);
554
								if($expr_m[3])
555
								{
556
									$expr_m[2] .= '=>' . trim($expr_m[3]);
557
								}
558
								$nodes[$idx - 1] .= "<?php if({$expr_m[1]}&&count({$expr_m[1]}))foreach({$expr_m[1]} as {$expr_m[2]}){ ?>";
559
							}
560
							elseif($expr_m[4])
561
							{
562
								$nodes[$idx - 1] .= "<?php for({$expr_m[4]}){ ?>";
563
							}
564
							elseif($expr_m[5])
565
							{
566
								$nodes[$idx - 1] .= "<?php while({$expr_m[5]}={$expr_m[6]}){ ?>";
567
							}
568
							break;
569
					}
570
				}
571
				$node = preg_replace('@\s(loop|cond)="([^"]+)"@', '', $node);
572
573
				// find closing tag
574
				$close_php = '<?php ' . str_repeat('}', $closing) . ' ?>';
575
				//  self closing tag
576
				if($node{1} == '!' || substr($node, -2, 1) == '/' || isset($self_closing[$tag]))
577
				{
578
					$nodes[$idx + 1] = $close_php . $nodes[$idx + 1];
579
				}
580
				else
581
				{
582
					$depth = 1;
583
					for($i = $idx + 2; $i < $node_len; $i+=2)
584
					{
585
						$nd = $nodes[$i];
586
						if(strpos($nd, $tag) === 1)
587
						{
588
							$depth++;
589
						}
590
						elseif(strpos($nd, '/' . $tag) === 1)
591
						{
592
							$depth--;
593
							if(!$depth)
594
							{
595
								$nodes[$i - 1] .= $nodes[$i] . $close_php;
596
								$nodes[$i] = '';
597
								break;
598
							}
599
						}
600
					}
601
				}
602
			}
603
604
			if(strpos($node, '|cond="') !== false)
605
			{
606
				$node = preg_replace('@(\s[-\w:]+(?:="[^"]+?")?)\|cond="(.+?)"@s', '<?php if($2){ ?>$1<?php } ?>', $node);
607
				$node = $this->_replaceVar($node);
608
			}
609
610
			if($nodes[$idx] != $node)
611
			{
612
				$nodes[$idx] = $node;
613
			}
614
		}
615
616
		$buff = implode('', $nodes);
617
618
		return $buff;
619
	}
620
621
	/**
622
	 * preg_replace_callback hanlder
623
	 * replace php code.
624
	 * @param array $m
625
	 * @return string changed result
626
	 */
627
	private function _parseResource($m)
628
	{
629
		$escape_option = 'noescape';
630
631
		if($this->autoescape)
632
		{
633
			$escape_option = 'autoescape';
634
		}
635
636
		// 템플릿에서 명시적으로 off이면 'noescape' 적용
637
		if ($this->config->autoescape === 'off') {
638
			$escape_option = 'noescape';
639
		}
640
641
		// {@ ... } or {$var} or {func(...)}
642
		if($m[1])
643
		{
644
			if(preg_match('@^(\w+)\(@', $m[1], $mm) && !function_exists($mm[1]))
645
			{
646
				return $m[0];
647
			}
648
			
649
			if($m[1]{0} == '@')
650
			{
651
				$m[1] = $this->_replaceVar(substr($m[1], 1));
652
				return "<?php {$m[1]} ?>";
653
			}
654
			else
655
			{
656
				// Get escape options.
657
				foreach ($this->ignoreEscape as $key => $value)
658
				{
659
					if($this->ignoreEscape[$key]($m))
660
					{
661
						$escape_option = 'noescape';
662
						break;
663
					}
664
				}
665
666
				// Separate filters from variable.
667
				if (preg_match('@^(.+?)(?<![|\s])((?:\|[a-z]{2}[a-z0-9_]+(?::.+)?)+)$@', $m[1], $mm))
668
				{
669
					$m[1] = $mm[1];
670
					$filters = array_map('trim', explode_with_escape('|', substr($mm[2], 1)));
671
				}
672
				else
673
				{
674
					$filters = array();
675
				}
676
677
				// Process the variable.
678
				$var = self::_replaceVar($m[1]);
679
680
				// Apply filters.
681
				foreach ($filters as $filter)
682
				{
683
					// Separate filter option from the filter name.
684
					if (preg_match('/^([a-z0-9_-]+):(.+)$/', $filter, $matches))
685
					{
686
						$filter = $matches[1];
687
						$filter_option = $matches[2];
688
						if (!self::_isVar($filter_option) && !preg_match("/^'.*'$/", $filter_option) && !preg_match('/^".*"$/', $filter_option))
689
						{
690
							$filter_option = "'" . escape_sqstr($filter_option) . "'";
691
						}
692
						else
693
						{
694
							$filter_option = self::_replaceVar($filter_option);
695
						}
696
					}
697
					else
698
					{
699
						$filter_option = null;
700
					}
701
702
					// Apply each filter.
703
					switch ($filter)
704
					{
705
						case 'auto':
706
						case 'autoescape':
707
						case 'escape':
708
						case 'noescape':
709
							$escape_option = $filter;
710
							break;
711
712
						case 'escapejs':
713
							$var = "escape_js({$var})";
714
							$escape_option = 'noescape';
715
							break;
716
717
						case 'json':
718
							$var = "json_encode({$var})";
719
							$escape_option = 'noescape';
720
							break;
721
722
						case 'strip':
723
						case 'strip_tags':
724
							$var = $filter_option ? "strip_tags({$var}, {$filter_option})" : "strip_tags({$var})";
725
							break;
726
727
						case 'trim':
728
							$var = "trim({$var})";
729
							break;
730
731
						case 'urlencode':
732
							$var = "rawurlencode({$var})";
733
							$escape_option = 'noescape';
734
							break;
735
736
						case 'lower':
737
							$var = "strtolower({$var})";
738
							break;
739
740
						case 'upper':
741
							$var = "strtoupper({$var})";
742
							break;
743
744
						case 'nl2br':
745
							$var = $this->_applyEscapeOption($var, $escape_option);
746
							$var = "nl2br({$var})";
747
							$escape_option = 'noescape';
748
							break;
749
750
						case 'join':
751
							$var = $filter_option ? "implode({$filter_option}, {$var})" : "implode(', ', {$var})";
752
							break;
753
754
						// case 'date':
755
						// 	$var = $filter_option ? "getDisplayDateTime(ztime({$var}), {$filter_option})" : "getDisplayDateTime(ztime({$var}), 'Y-m-d H:i:s')";
756
						// 	$escape_option = 'noescape';
757
						// 	break;
758
759
						case 'format':
760
						case 'number_format':
761
							$var = $filter_option ? "number_format({$var}, {$filter_option})" : "number_format({$var})";
762
							$escape_option = 'noescape';
763
							break;
764
765
						case 'link':
766
							$var = $this->_applyEscapeOption($var, 'autoescape');
767
							if ($filter_option)
0 ignored issues
show
Bug Best Practice introduced by
The expression $filter_option 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...
768
							{
769
								$filter_option = $this->_applyEscapeOption($filter_option, 'autoescape');
770
								$var = "'<a href=\"' . {$filter_option} . '\">' . {$var} . '</a>'";
771
							}
772
							else
773
							{
774
								$var = "'<a href=\"' . {$var} . '\">' . {$var} . '</a>'";
775
							}
776
							$escape_option = 'noescape';
777
							break;
778
779
						default:
780
							$filter = escape_sqstr($filter);
781
							$var = "'INVALID FILTER ({$filter})'";
782
							$escape_option = 'noescape';
783
					}
784
				}
785
786
				// Apply the escape option and return.
787
				return '<?php echo ' . $this->_applyEscapeOption($var, $escape_option) . ' ?>';
788
			}
789
		}
790
791
		if($m[3])
792
		{
793
			$attr = array();
794
			if($m[5])
795
			{
796 View Code Duplication
				if(preg_match_all('@,(\w+)="([^"]+)"@', $m[6], $mm))
797
				{
798
					foreach($mm[1] as $idx => $name)
799
					{
800
						$attr[$name] = $mm[2][$idx];
801
					}
802
				}
803
				$attr['target'] = $m[5];
804
			}
805 View Code Duplication
			else
806
			{
807
				if(!preg_match_all('@ (\w+)="([^"]+)"@', $m[6], $mm))
808
				{
809
					return $m[0];
810
				}
811
				foreach($mm[1] as $idx => $name)
812
				{
813
					$attr[$name] = $mm[2][$idx];
814
				}
815
			}
816
817
			switch($m[3])
818
			{
819
				// <!--#include--> or <include ..>
820
				case 'include':
821
					if(!$this->file || !$attr['target'])
822
					{
823
						return '';
824
					}
825
826
					$pathinfo = pathinfo($attr['target']);
827
					$fileDir = $this->_getRelativeDir($pathinfo['dirname']);
828
829
					if(!$fileDir)
830
					{
831
						return '';
832
					}
833
834
					return "<?php \$__tpl=TemplateHandler::getInstance();echo \$__tpl->compile('{$fileDir}','{$pathinfo['basename']}') ?>";
835
				// <!--%load_js_plugin-->
836
				case 'load_js_plugin':
837
					$plugin = $this->_replaceVar($m[5]);
838
					$s = "<!--#JSPLUGIN:{$plugin}-->";
839
					if(strpos($plugin, '$__Context') === false)
840
					{
841
						$plugin = "'{$plugin}'";
842
					}
843
844
					$s .= "<?php Context::loadJavascriptPlugin({$plugin}); ?>";
845
					return $s;
846
				// <load ...> or <unload ...> or <!--%import ...--> or <!--%unload ...-->
847
				case 'import':
848
				case 'load':
849
				case 'unload':
850
					$metafile = '';
851
					$pathinfo = pathinfo($attr['target']);
852
					$doUnload = ($m[3] === 'unload');
853
					$isRemote = !!preg_match('@^(https?:)?//@i', $attr['target']);
854
855
					if(!$isRemote)
856
					{
857
						if(!preg_match('@^\.?/@', $attr['target']))
858
						{
859
							$attr['target'] = './' . $attr['target'];
860
						}
861
						if(substr($attr['target'], -5) == '/lang')
862
						{
863
							$pathinfo['dirname'] .= '/lang';
864
							$pathinfo['basename'] = '';
865
							$pathinfo['extension'] = 'xml';
866
						}
867
868
						$relativeDir = $this->_getRelativeDir($pathinfo['dirname']);
869
870
						$attr['target'] = $relativeDir . '/' . $pathinfo['basename'];
871
					}
872
873
					switch($pathinfo['extension'])
874
					{
875
						case 'xml':
876
							if($isRemote || $doUnload)
877
							{
878
								return '';
879
							}
880
							// language file?
881
							if($pathinfo['basename'] == 'lang.xml' || substr($pathinfo['dirname'], -5) == '/lang')
882
							{
883
								$result = "Context::loadLang('{$relativeDir}');";
0 ignored issues
show
Bug introduced by
The variable $relativeDir 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...
884
							}
885
							else
886
							{
887
								$result = "require_once('./classes/xml/XmlJsFilter.class.php');\$__xmlFilter=new XmlJsFilter('{$relativeDir}','{$pathinfo['basename']}');\$__xmlFilter->compile();";
888
							}
889
							break;
890 View Code Duplication
						case 'js':
891
							if($doUnload)
892
							{
893
								$result = "Context::unloadFile('{$attr['target']}','{$attr['targetie']}');";
894
							}
895
							else
896
							{
897
								$metafile = $attr['target'];
898
								$result = "\$__tmp=array('{$attr['target']}','{$attr['type']}','{$attr['targetie']}','{$attr['index']}');Context::loadFile(\$__tmp);unset(\$__tmp);";
899
							}
900
							break;
901 View Code Duplication
						case 'css':
902
							if($doUnload)
903
							{
904
								$result = "Context::unloadFile('{$attr['target']}','{$attr['targetie']}','{$attr['media']}');";
905
							}
906
							else
907
							{
908
								$metafile = $attr['target'];
909
								$result = "\$__tmp=array('{$attr['target']}','{$attr['media']}','{$attr['targetie']}','{$attr['index']}');Context::loadFile(\$__tmp);unset(\$__tmp);";
910
							}
911
							break;
912
					}
913
914
					$result = "<?php {$result} ?>";
0 ignored issues
show
Bug introduced by
The variable $result 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...
915
					if($metafile)
916
					{
917
						$result = "<!--#Meta:{$metafile}-->" . $result;
918
					}
919
920
					return $result;
921
				// <config ...>
922
				case 'config':
923
					$result = '';
924
					if(preg_match_all('@ (\w+)="([^"]+)"@', $m[6], $config_matches, PREG_SET_ORDER))
925
					{
926
						foreach($config_matches as $config_match)
927
						{
928
							$result .= "\$this->config->{$config_match[1]} = '" . trim(strtolower($config_match[2])) . "';";
929
						}
930
					}
931
					return "<?php {$result} ?>";
932
			}
933
		}
934
935
		// <[email protected]> such as <!--@if($cond)-->, <!--@else-->, <!--@end-->
936
		if($m[7])
937
		{
938
			$m[7] = substr($m[7], 1);
939 View Code Duplication
			if(!$m[7])
940
			{
941
				return '<?php ' . $this->_replaceVar($m[8]) . '{ ?>' . $m[9];
942
			}
943
			if(!preg_match('/^(?:((?:end)?(?:if|switch|for(?:each)?|while)|end)|(else(?:if)?)|(break@)?(case|default)|(break))$/', $m[7], $mm))
944
			{
945
				return '';
946
			}
947
			if($mm[1])
948
			{
949
				if($mm[1]{0} == 'e')
950
				{
951
					return '<?php } ?>' . $m[9];
952
				}
953
954
				$precheck = '';
955
				if($mm[1] == 'switch')
956
				{
957
					$m[9] = '';
958
				}
959
				elseif($mm[1] == 'foreach')
960
				{
961
					$var = preg_replace('/^\s*\(\s*(.+?) .*$/', '$1', $m[8]);
962
					$precheck = "if({$var}&&count({$var}))";
963
				}
964
				return '<?php ' . $this->_replaceVar($precheck . $m[7] . $m[8]) . '{ ?>' . $m[9];
965
			}
966 View Code Duplication
			if($mm[2])
967
			{
968
				return "<?php }{$m[7]}" . $this->_replaceVar($m[8]) . "{ ?>" . $m[9];
969
			}
970
			if($mm[4])
971
			{
972
				return "<?php " . ($mm[3] ? 'break;' : '') . "{$m[7]} " . trim($m[8], '()') . ": ?>" . $m[9];
973
			}
974
			if($mm[5])
975
			{
976
				return "<?php break; ?>";
977
			}
978
			return '';
979
		}
980
		return $m[0];
981
	}
982
983
	/**
984
 	 * Apply escape option to an expression.
985
 	 */
986
 	private function _applyEscapeOption($str, $escape_option = 'noescape')
987
 	{
988
 		switch($escape_option)
989
 		{
990
 			case 'escape':
991
 				return "escape({$str}, true)";
992
 			case 'noescape':
993
 				return "{$str}";
994
 			case 'autoescape':
995
 				return "escape({$str}, false)";
996
 			case 'auto':
997
 			default:
998
 				return "(\$this->config->autoescape === 'on' ? escape({$str}, false) : ({$str}))";
999
 		}
1000
 	}
1001
1002
	/**
1003
	 * change relative path
1004
	 * @param string $path
1005
	 * @return string
1006
	 */
1007
	function _getRelativeDir($path)
1008
	{
1009
		$_path = $path;
1010
1011
		$fileDir = strtr(realpath($this->path), '\\', '/');
1012
		if($path{0} != '/')
1013
		{
1014
			$path = strtr(realpath($fileDir . '/' . $path), '\\', '/');
1015
		}
1016
1017
		// for backward compatibility
1018
		if(!$path)
1019
		{
1020
			$dirs = explode('/', $fileDir);
1021
			$paths = explode('/', $_path);
1022
			$idx = array_search($paths[0], $dirs);
1023
1024
			if($idx !== false)
1025
			{
1026
				while($dirs[$idx] && $dirs[$idx] === $paths[0])
1027
				{
1028
					array_splice($dirs, $idx, 1);
1029
					array_shift($paths);
1030
				}
1031
				$path = strtr(realpath($fileDir . '/' . implode('/', $paths)), '\\', '/');
1032
			}
1033
		}
1034
1035
		$path = preg_replace('/^' . preg_quote(_XE_PATH_, '/') . '/', '', $path);
1036
1037
		return $path;
1038
	}
1039
1040
	/**
1041
 	 * Check if a string seems to contain a variable.
1042
 	 * 
1043
 	 * @param string $str
1044
 	 * @return bool
1045
 	 */
1046
 	private static function _isVar($str)
1047
 	{
1048
 		return preg_match('@(?<!::|\\\\|(?<!eval\()\')\$([a-z_][a-z0-9_]*)@i', $str) ? true : false;
1049
 	}
1050
1051
	/**
1052
	 * Replace PHP variables of $ character
1053
	 * @param string $php
1054
	 * @return string $__Context->varname
1055
	 */
1056
	function _replaceVar($php)
1057
	{
1058
		if(!strlen($php))
1059
		{
1060
			return '';
1061
		}
1062
		return preg_replace('@(?<!::|\\\\|(?<!eval\()\')\$([a-z]|_[a-z0-9])@i', '\$__Context->$1', $php);
1063
	}
1064
1065
	function isAutoescape()
1066
	{
1067
		$absPath = str_replace(_XE_PATH_, '', $this->path);
1068
		$dirTpl = '(addon|admin|adminlogging|autoinstall|board|comment|communication|counter|document|editor|file|importer|install|integration_search|krzip|layout|member|menu|message|module|page|point|poll|rss|seo|session|spamfilter|syndication|tag|trash|widget)';
1069
		$dirSkins = '(layouts\/default|layouts\/user_layout|layouts\/xedition|layouts\/xedition\/demo|m\.layouts\/colorCode|m\.layouts\/default|m\.layouts\/simpleGray|modules\/board\/m\.skins\/default|modules\/board\/m\.skins\/simpleGray|modules\/board\/skins\/default|modules\/board\/skins\/xedition|modules\/communication\/m\.skins\/default|modules\/communication\/skins\/default|modules\/editor\/skins\/ckeditor|modules\/editor\/skins\/xpresseditor|modules\/integration_search\/skins\/default|modules\/layout\/faceoff|modules\/member\/m\.skins\/default|modules\/member\/skins\/default|modules\/message\/m\.skins\/default|modules\/message\/skins\/default|modules\/message\/skins\/xedition|modules\/page\/m\.skins\/default|modules\/page\/skins\/default|modules\/poll\/skins\/default|modules\/poll\/skins\/simple|widgets\/content\/skins\/default|widgets\/counter_status\/skins\/default|widgets\/language_select\/skins\/default|widgets\/login_info\/skins\/default|widgets\/mcontent\/skins\/default|widgetstyles\/simple)';
0 ignored issues
show
Unused Code introduced by
$dirSkins 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...
1070
1071
		// 'tpl'
1072
		if(preg_match('/^(\.\/)?(modules\/' . $dirTpl . '|common)\/tpl\//', $absPath))
1073
		{
1074
			return true;
1075
		}
1076
1077
		// skin, layout
1078
		if(preg_match('/^(\.\/)?\(' . $dirSkin . '\//', $absPath))
0 ignored issues
show
Bug introduced by
The variable $dirSkin does not exist. Did you mean $dirSkins?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
1079
		{
1080
			return true;
1081
		}
1082
1083
		return false;
1084
	}
1085
1086
	public function setAutoescape($val = true)
1087
	{
1088
		$this->autoescape = $val;
1089
	}
1090
}
1091
/* End of File: TemplateHandler.class.php */
1092
/* Location: ./classes/template/TemplateHandler.class.php */
1093