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 ( 8a2f54...8e2d68 )
by gyeong-won
07:47
created

FileHandler::clearStatCache()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 3
nop 2
dl 0
loc 17
rs 9.2
c 0
b 0
f 0
1
<?php
2
/* Copyright (C) NAVER <http://www.navercorp.com> */
3
4
/**
5
 * Contains methods for accessing file system
6
 *
7
 * @author NAVER ([email protected])
8
 */
9
class FileHandler
10
{
11
12
	/**
13
	 * Changes path of target file, directory into absolute path
14
	 *
15
	 * @param string $source path to change into absolute path
16
	 * @return string Absolute path
17
	 */
18
	function getRealPath($source)
19
	{
20
		if(strlen($source) >= 2 && substr_compare($source, './', 0, 2) === 0)
21
		{
22
			return _XE_PATH_ . substr($source, 2);
23
		}
24
25
		return $source;
26
	}
27
28
	/**
29
	 * Copy a directory to target
30
	 *
31
	 * If target directory does not exist, this function creates it
32
	 *
33
	 * @param string $source_dir Path of source directory
34
	 * @param string $target_dir Path of target dir
35
	 * @param string $filter Regex to filter files. If file matches this regex, the file is not copied.
36
	 * @param string $type If set as 'force'. Even if the file exists in target, the file is copied.
37
	 * @return void
38
	 */
39
	function copyDir($source_dir, $target_dir, $filter = null, $type = null)
40
	{
41
		$source_dir = self::getRealPath($source_dir);
42
		$target_dir = self::getRealPath($target_dir);
43
		if(!is_dir($source_dir))
44
		{
45
			return FALSE;
46
		}
47
48
		// generate when no target exists
49
		self::makeDir($target_dir);
50
51
		if(substr($source_dir, -1) != DIRECTORY_SEPARATOR)
52
		{
53
			$source_dir .= DIRECTORY_SEPARATOR;
54
		}
55
56
		if(substr($target_dir, -1) != DIRECTORY_SEPARATOR)
57
		{
58
			$target_dir .= DIRECTORY_SEPARATOR;
59
		}
60
61
		$oDir = dir($source_dir);
62
		while($file = $oDir->read())
63
		{
64
			if($file{0} == '.')
65
			{
66
				continue;
67
			}
68
69
			if($filter && preg_match($filter, $file))
0 ignored issues
show
Bug Best Practice introduced by
The expression $filter 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...
70
			{
71
				continue;
72
			}
73
74
			if(is_dir($source_dir . $file))
75
			{
76
				self::copyDir($source_dir . $file, $target_dir . $file, $type);
77
			}
78
			else
79
			{
80
				if($type == 'force')
81
				{
82
					@unlink($target_dir . $file);
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...
83
				}
84
				else
85
				{
86
					if(!file_exists($target_dir . $file))
87
					{
88
						@copy($source_dir . $file, $target_dir . $file);
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...
89
					}
90
				}
91
			}
92
		}
93
		$oDir->close();
94
	}
95
96
	/**
97
	 * Copy a file to target
98
	 *
99
	 * @param string $source Path of source file
100
	 * @param string $target Path of target file
101
	 * @param string $force Y: overwrite
102
	 * @return void
103
	 */
104
	function copyFile($source, $target, $force = 'Y')
105
	{
106
		setlocale(LC_CTYPE, 'en_US.UTF8', 'ko_KR.UTF8');
107
		$source = self::getRealPath($source);
108
		$target_dir = self::getRealPath(dirname($target));
109
		$target = basename($target);
110
111
		self::makeDir($target_dir);
112
113
		if($force == 'Y')
114
		{
115
			@unlink($target_dir . DIRECTORY_SEPARATOR . $target);
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...
116
		}
117
118
		@copy($source, $target_dir . DIRECTORY_SEPARATOR . $target);
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...
119
	}
120
121
	/**
122
	 * Returns the content of the file
123
	 *
124
	 * @param string $filename Path of target file
125
	 * @return string The content of the file. If target file does not exist, this function returns nothing.
126
	 */
127
	function readFile($filename)
128
	{
129
		if(($filename = self::exists($filename)) === FALSE || filesize($filename) < 1)
130
		{
131
			return;
132
		}
133
134
		return @file_get_contents($filename);
135
	}
136
137
	/**
138
	 * Write $buff into the specified file
139
	 *
140
	 * @param string $filename Path of target file
141
	 * @param string $buff Content to be written
142
	 * @param string $mode a(append) / w(write)
143
	 * @return void
144
	 */
145
	function writeFile($filename, $buff, $mode = "w")
146
	{
147
		$filename = self::getRealPath($filename);
148
		$pathinfo = pathinfo($filename);
149
		self::makeDir($pathinfo['dirname']);
150
151
		$flags = 0;
152
		if(strtolower($mode) == 'a')
153
		{
154
			$flags = FILE_APPEND;
155
		}
156
157
		@file_put_contents($filename, $buff, $flags|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...
158
		@chmod($filename, 0644);
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...
159
		self::clearStatCache($filename);
160
		self::invalidateOpcache($filename);
161
	}
162
163
	/**
164
	 * Remove a file
165
	 *
166
	 * @param string $filename path of target file
167
	 * @return bool Returns TRUE on success or FALSE on failure.
168
	 */
169
	function removeFile($filename)
170
	{
171
		return (($filename = self::exists($filename)) !== FALSE) && @unlink($filename);
172
	}
173
174
	/**
175
	 * Rename a file
176
	 *
177
	 * In order to move a file, use this function.
178
	 *
179
	 * @param string $source Path of source file
180
	 * @param string $target Path of target file
181
	 * @return bool Returns TRUE on success or FALSE on failure.
182
	 */
183
	function rename($source, $target)
184
	{
185
		return @rename(self::getRealPath($source), self::getRealPath($target));
186
	}
187
188
	/**
189
	 * Move a file
190
	 *
191
	 * @param string $source Path of source file
192
	 * @param string $target Path of target file
193
	 * @return bool Returns TRUE on success or FALSE on failure.
194
	 */
195
	function moveFile($source, $target)
196
	{
197
		if(($source = self::exists($source)) !== FALSE)
198
		{
199
			self::removeFile($target);
200
			return self::rename($source, $target);
201
		}
202
		return FALSE;
203
	}
204
205
	/**
206
	 * Move a directory
207
	 *
208
	 * This function just wraps rename function.
209
	 *
210
	 * @param string $source_dir Path of source directory
211
	 * @param string $target_dir Path of target directory
212
	 * @return void
213
	 */
214
	function moveDir($source_dir, $target_dir)
215
	{
216
		self::rename($source_dir, $target_dir);
217
	}
218
219
	/**
220
	 * Return list of the files in the path
221
	 *
222
	 * The array does not contain files, such as '.', '..', and files starting with '.'
223
	 *
224
	 * @param string $path Path of target directory
225
	 * @param string $filter If specified, return only files matching with the filter
226
	 * @param bool $to_lower If TRUE, file names will be changed into lower case.
227
	 * @param bool $concat_prefix If TRUE, return file name as absolute path
228
	 * @return string[] Array of the filenames in the path
229
	 */
230
	function readDir($path, $filter = '', $to_lower = FALSE, $concat_prefix = FALSE)
231
	{
232
		$path = self::getRealPath($path);
233
		$output = array();
234
235
		if(substr($path, -1) != '/')
236
		{
237
			$path .= '/';
238
		}
239
240
		if(!is_dir($path))
241
		{
242
			return $output;
243
		}
244
245
		$files = scandir($path);
246
		foreach($files as $file)
247
		{
248
			if($file{0} == '.' || ($filter && !preg_match($filter, $file)))
249
			{
250
				continue;
251
			}
252
253
			if($to_lower)
254
			{
255
				$file = strtolower($file);
256
			}
257
258
			if($filter)
259
			{
260
				$file = preg_replace($filter, '$1', $file);
261
			}
262
263
			if($concat_prefix)
264
			{
265
				$file = sprintf('%s%s', str_replace(_XE_PATH_, '', $path), $file);
266
			}
267
268
			$output[] = str_replace(array('/\\', '//'), '/', $file);
269
		}
270
271
		return $output;
272
	}
273
274
	/**
275
	 * Creates a directory
276
	 *
277
	 * This function creates directories recursively, which means that if ancestors of the target directory does not exist, they will be created too.
278
	 *
279
	 * @param string $path_string Path of target directory
280
	 * @return bool TRUE if success. It might return nothing when ftp is used and connection to the ftp address failed.
281
	 */
282
	function makeDir($path_string)
283
	{
284
		if(self::exists($path_string) !== FALSE)
285
		{
286
			return TRUE;
287
		}
288
289
		if(!ini_get('safe_mode'))
290
		{
291
			@mkdir($path_string, 0755, TRUE);
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...
292
			@chmod($path_string, 0755);
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...
293
		}
294
		// if safe_mode is on, use FTP
295
		else
296
		{
297
			static $oFtp = NULL;
298
299
			$ftp_info = Context::getFTPInfo();
300
			if($oFtp == NULL)
301
			{
302
				if(!Context::isFTPRegisted())
303
				{
304
					return;
305
				}
306
307
				require_once(_XE_PATH_ . 'libs/ftp.class.php');
308
				$oFtp = new ftp();
309
				if(!$ftp_info->ftp_host)
310
				{
311
					$ftp_info->ftp_host = "127.0.0.1";
312
				}
313
				if(!$ftp_info->ftp_port)
314
				{
315
					$ftp_info->ftp_port = 21;
316
				}
317
				if(!$oFtp->ftp_connect($ftp_info->ftp_host, $ftp_info->ftp_port))
318
				{
319
					return;
320
				}
321
				if(!$oFtp->ftp_login($ftp_info->ftp_user, $ftp_info->ftp_password))
322
				{
323
					$oFtp->ftp_quit();
324
					return;
325
				}
326
			}
327
328
			if(!($ftp_path = $ftp_info->ftp_root_path))
329
			{
330
				$ftp_path = DIRECTORY_SEPARATOR;
331
			}
332
333
			$path_string = str_replace(_XE_PATH_, '', $path_string);
334
			$path_list = explode(DIRECTORY_SEPARATOR, $path_string);
335
336
			$path = _XE_PATH_;
337
			for($i = 0, $c = count($path_list); $i < $c; $i++)
338
			{
339
				if(!$path_list[$i])
340
				{
341
					continue;
342
				}
343
344
				$path .= $path_list[$i] . DIRECTORY_SEPARATOR;
345
				$ftp_path .= $path_list[$i] . DIRECTORY_SEPARATOR;
346
				if(!is_dir($path))
347
				{
348
					$oFtp->ftp_mkdir($ftp_path);
349
					$oFtp->ftp_site("CHMOD 777 " . $ftp_path);
350
				}
351
			}
352
		}
353
354
		return is_dir($path_string);
355
	}
356
357
	/**
358
	 * Remove all files under the path
359
	 *
360
	 * @param string $path Path of the target directory
361
	 * @return void
362
	 */
363 View Code Duplication
	function removeDir($path)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
364
	{
365
		if(($path = self::isDir($path)) === FALSE)
366
		{
367
			return;
368
		}
369
370
		if(self::isDir($path))
0 ignored issues
show
Bug Best Practice introduced by
The expression self::isDir($path) 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...
371
		{
372
			$files = array_diff(scandir($path), array('..', '.'));
373
374
			foreach($files as $file)
375
			{
376
				if(($target = self::getRealPath($path . DIRECTORY_SEPARATOR . $file)) === FALSE)
377
				{
378
					continue;
379
				}
380
381
				if(is_dir($target))
382
				{
383
					self::removeDir($target);
384
				}
385
				else
386
				{
387
					unlink($target);
388
				}
389
			}
390
			rmdir($path);
391
		}
392
		else
393
		{
394
			unlink($path);
395
		}
396
	}
397
398
	/**
399
	 * Remove a directory only if it is empty
400
	 *
401
	 * @param string $path Path of the target directory
402
	 * @return void
403
	 */
404
	function removeBlankDir($path)
405
	{
406
		if(($path = self::isDir($path)) === FALSE)
407
		{
408
			return;
409
		}
410
411
		$files = array_diff(scandir($path), array('..', '.'));
412
413
		if(count($files) < 1)
414
		{
415
			rmdir($path);
416
			return;
417
		}
418
419
		foreach($files as $file)
420
		{
421
			if(($target = self::isDir($path . DIRECTORY_SEPARATOR . $file)) === FALSE)
422
			{
423
				continue;
424
			}
425
426
			self::removeBlankDir($target);
427
		}
428
	}
429
430
	/**
431
	 * Remove files in the target directory
432
	 *
433
	 * This function keeps the directory structure.
434
	 *
435
	 * @param string $path Path of the target directory
436
	 * @return void
437
	 */
438 View Code Duplication
	function removeFilesInDir($path)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
439
	{
440
		if(($path = self::getRealPath($path)) === FALSE)
441
		{
442
			return;
443
		}
444
445
		if(is_dir($path))
446
		{
447
			$files = array_diff(scandir($path), array('..', '.'));
448
449
			foreach($files as $file)
450
			{
451
				if(($target = self::getRealPath($path . DIRECTORY_SEPARATOR . $file)) === FALSE)
452
				{
453
					continue;
454
				}
455
456
				if(is_dir($target))
457
				{
458
					self::removeFilesInDir($target);
459
				}
460
				else
461
				{
462
					unlink($target);
463
				}
464
			}
465
		}
466
		else
467
		{
468
			if(self::exists($path)) unlink($path);
0 ignored issues
show
Bug Best Practice introduced by
The expression self::exists($path) 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...
469
		}
470
471
	}
472
473
	/**
474
	 * Makes file size byte into KB, MB according to the size
475
	 *
476
	 * @see self::returnBytes()
477
	 * @param int $size Number of the size
478
	 * @return string File size string
479
	 */
480
	function filesize($size)
481
	{
482
		if(!$size)
483
		{
484
			return '0Byte';
485
		}
486
487
		if($size === 1)
488
		{
489
			return '1Byte';
490
		}
491
492
		if($size < 1024)
493
		{
494
			return $size . 'Bytes';
495
		}
496
497
		if($size >= 1024 && $size < 1024 * 1024)
498
		{
499
			return sprintf("%0.1fKB", $size / 1024);
500
		}
501
502
		return sprintf("%0.2fMB", $size / (1024 * 1024));
503
	}
504
505
	/**
506
	 * Return remote file's content via HTTP
507
	 *
508
	 * If the target is moved (when return code is 300~399), this function follows the location specified response header.
509
	 *
510
	 * @param string $url The address of the target file
511
	 * @param string $body HTTP request body
512
	 * @param int $timeout Connection timeout
513
	 * @param string $method GET/POST
514
	 * @param string $content_type Content type header of HTTP request
515
	 * @param string[] $headers Headers key value array.
516
	 * @param string[] $cookies Cookies key value array.
517
	 * @param string $post_data Request arguments array for POST method
518
	 * @return string If success, the content of the target file. Otherwise: none
519
	 */
520
	function getRemoteResource($url, $body = null, $timeout = 3, $method = 'GET', $content_type = null, $headers = array(), $cookies = array(), $post_data = array(), $request_config = array())
521
	{
522
		require_once(_XE_PATH_ . 'libs/idna_convert/idna_convert.class.php');
523
		$IDN = new idna_convert(array('idn_version' => 2008));
524
		$url = $IDN->encode($url);
525
526
		try
527
		{
528
			requirePear();
529
			require_once('HTTP/Request.php');
530
531
			$parsed_url = parse_url(__PROXY_SERVER__);
532
			if($parsed_url["host"] && $parsed_url["path"])
533
			{
534
				// Old style proxy server support (POST payload to proxy script)
535
				$oRequest = new HTTP_Request(__PROXY_SERVER__);
536
				$oRequest->setMethod('POST');
537
				$oRequest->addPostData('arg', serialize(array('Destination' => $url, 'method' => $method, 'body' => $body, 'content_type' => $content_type, "headers" => $headers, "post_data" => $post_data)));
538
			}
539
			else
540
			{
541
				$oRequest = new HTTP_Request($url);
0 ignored issues
show
Security Bug introduced by
It seems like $url defined by $IDN->encode($url) on line 524 can also be of type false; however, HTTP_Request2::__construct() does only seem to accept string|object<Net_URL2>|null, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
542
543
				// New style proxy server support (Use HTTP_Request2 native config format)
544
				if($parsed_url['host'])
545
				{
546
					$request_config['proxy_host'] = $parsed_url['host'];
547
					$request_config['proxy_port'] = $parsed_url['port'] ? $parsed_url['port'] : '';
548
					$request_config['proxy_user'] = rawurldecode($parsed_url['user'] ? $parsed_url['user'] : '');
549
					$request_config['proxy_password'] = rawurldecode($parsed_url['pass'] ? $parsed_url['pass'] : '');
550
					$request_config['proxy_type'] = $parsed_url['scheme'] ? $parsed_url['scheme'] : 'http';
551
				}
552
553
				if(count($request_config) && method_exists($oRequest, 'setConfig'))
554
				{
555
					foreach($request_config as $key=>$val)
556
					{
557
						if($key === 'observers')
558
						{
559
							foreach($val as $observer)
560
							{
561
								$oRequest->attach($observer);
562
							}
563
						}
564
						else
565
						{
566
							$oRequest->setConfig($key, $val);
567
						}
568
					}
569
				}
570
				if(method_exists($oRequest, 'setConfig'))
571
				{
572
					if(extension_loaded('curl'))
573
					{
574
						$oRequest->setConfig('adapter', 'curl');
575
					}
576
					elseif(version_compare(PHP_VERSION, '5.6', '<'))
577
					{
578
						$oRequest->setConfig('ssl_verify_host', false);
579
					}
580
					if(file_exists(_XE_PATH_ . 'libs/cacert/cacert.pem'))
581
					{
582
						$oRequest->setConfig('ssl_cafile', _XE_PATH_ . 'libs/cacert/cacert.pem');
583
					}
584
				}
585
586
				if(count($headers) > 0)
587
				{
588
					foreach($headers as $key => $val)
589
					{
590
						$oRequest->addHeader($key, $val);
591
					}
592
				}
593
				$host = parse_url($url, PHP_URL_HOST);
594
				if($cookies[$host])
595
				{
596
					foreach($cookies[$host] as $key => $val)
0 ignored issues
show
Bug introduced by
The expression $cookies[$host] of type string is not traversable.
Loading history...
597
					{
598
						$oRequest->addCookie($key, $val);
599
					}
600
				}
601
				if(count($post_data) > 0)
602
				{
603
					foreach($post_data as $key => $val)
0 ignored issues
show
Bug introduced by
The expression $post_data of type string|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

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

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

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

Loading history...
604
					{
605
						$oRequest->addPostData($key, $val);
606
					}
607
				}
608
				if(!$content_type)
0 ignored issues
show
Bug Best Practice introduced by
The expression $content_type of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
609
					$oRequest->addHeader('Content-Type', 'text/html');
610
				else
611
					$oRequest->addHeader('Content-Type', $content_type);
612
				$oRequest->setMethod($method);
613
				if($body)
0 ignored issues
show
Bug Best Practice introduced by
The expression $body 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...
614
					$oRequest->setBody($body);
615
			}
616
			
617
			if(method_exists($oRequest, 'setConfig'))
618
			{
619
				$oRequest->setConfig('timeout', $timeout);
620
			}
621
			elseif(property_exists($oRequest, '_timeout'))
622
			{
623
				$oRequest->_timeout = $timeout;
0 ignored issues
show
Bug introduced by
The property _timeout does not seem to exist in HTTP_Request.

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...
624
			}
625
626
			$oResponse = $oRequest->sendRequest();
0 ignored issues
show
Unused Code introduced by
$oResponse 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...
627
628
			$code = $oRequest->getResponseCode();
629
			$header = $oRequest->getResponseHeader();
630
			$response = $oRequest->getResponseBody();
631
			if($c = $oRequest->getResponseCookies())
632
			{
633
				foreach($c as $k => $v)
634
				{
635
					$cookies[$host][$v['name']] = $v['value'];
0 ignored issues
show
Bug introduced by
The variable $host 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...
636
				}
637
			}
638
639
			if($code > 300 && $code < 399 && $header['location'])
640
			{
641
				return self::getRemoteResource($header['location'], $body, $timeout, $method, $content_type, $headers, $cookies, $post_data);
642
			}
643
644
			if($code != 200)
645
			{
646
				return;
647
			}
648
649
			if(isset($request_config['store_body']) && !$request_config['store_body'])
650
			{
651
				return TRUE;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return TRUE; (boolean) is incompatible with the return type documented by FileHandler::getRemoteResource of type string.

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

Let’s take a look at an example:

class Author {
    private $name;

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

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

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

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

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

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

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

Loading history...
652
			}
653
			else
654
			{
655
				return $response;
656
			}
657
		}
658
		catch(Exception $e)
659
		{
660
			return NULL;
661
		}
662
	}
663
664
	/**
665
	 * Retrieves remote file, then stores it into target path.
666
	 *
667
	 * @param string $url The address of the target file
668
	 * @param string $target_filename The location to store
669
	 * @param string $body HTTP request body
670
	 * @param string $timeout Connection timeout
671
	 * @param string $method GET/POST
672
	 * @param string $content_type Content type header of HTTP request
673
	 * @param string[] $headers Headers key value array.
674
	 * @return bool TRUE: success, FALSE: failed
675
	 */
676
	function getRemoteFile($url, $target_filename, $body = null, $timeout = 3, $method = 'GET', $content_type = null, $headers = array(), $cookies = array(), $post_data = array(), $request_config = array())
677
	{
678
		$target_filename = self::getRealPath($target_filename);
679
		self::writeFile($target_filename, '');
680
		
681
		requirePear();
682
		require_once('HTTP/Request2/Observer/Download.php');
683
		
684
		$request_config['store_body'] = false;
685
		$request_config['observers'][] = new HTTP_Request2_Observer_Download($target_filename);
686
		try
687
		{
688
			$result = self::getRemoteResource($url, $body, $timeout, $method, $content_type, $headers, $cookies, $post_data, $request_config);
689
		}
690
		catch(Exception $e)
691
		{
692
			return FALSE;
693
		}
694
		return $result ? TRUE : FALSE;
695
	}
696
697
	/**
698
	 * Convert size in string into numeric value
699
	 *
700
	 * @see self::filesize()
701
	 * @param $val Size in string (ex., 10, 10K, 10M, 10G )
702
	 * @return int converted size
703
	 */
704
	function returnBytes($val)
705
	{
706
		$unit = strtoupper(substr($val, -1));
707
		$val = (float)$val;
708
709
		switch ($unit)
710
		{
711
			case 'G': $val *= 1024;
712
			case 'M': $val *= 1024;
713
			case 'K': $val *= 1024;
714
		}
715
716
		return round($val);
717
	}
718
719
	/**
720
	 * Check available memory to load image file
721
	 *
722
	 * @param array $imageInfo Image info retrieved by getimagesize function
723
	 * @return bool TRUE: it's ok, FALSE: otherwise
724
	 */
725
	function checkMemoryLoadImage(&$imageInfo)
726
	{
727
		$K64 = 65536;
728
		$TWEAKFACTOR = 2.0;
729
		$channels = $imageInfo['channels'];
730
		if(!$channels)
731
		{
732
			$channels = 6; //for png
733
		}
734
		$memoryNeeded = round(($imageInfo[0] * $imageInfo[1] * $imageInfo['bits'] * $channels / 8 + $K64 ) * $TWEAKFACTOR);
735
		$availableMemory = self::returnBytes(ini_get('memory_limit')) - memory_get_usage();
736
		if($availableMemory < $memoryNeeded)
737
		{
738
			return FALSE;
739
		}
740
		return TRUE;
741
	}
742
743
	/**
744
	 * Moves an image file (resizing is possible)
745
	 *
746
	 * @param string $source_file Path of the source file
747
	 * @param string $target_file Path of the target file
748
	 * @param int $resize_width Width to resize
749
	 * @param int $resize_height Height to resize
750
	 * @param string $target_type If $target_type is set (gif, jpg, png, bmp), result image will be saved as target type
751
	 * @param string $thumbnail_type Thumbnail type(crop, ratio)
752
	 * @return bool TRUE: success, FALSE: failed
753
	 */
754
	function createImageFile($source_file, $target_file, $resize_width = 0, $resize_height = 0, $target_type = '', $thumbnail_type = 'crop')
755
	{
756
		// check params
757
		if (($source_file = self::exists($source_file)) === FALSE)
758
		{
759
			return;
760
		}
761
762
		$target_file = self::getRealPath($target_file);
763
		if(!$resize_width)
764
		{
765
			$resize_width = 100;
766
		}
767
768
		if(!$resize_height)
769
		{
770
			$resize_height = $resize_width;
771
		}
772
773
		// retrieve source image's information
774
		$imageInfo = getimagesize($source_file);
775
		if(!self::checkMemoryLoadImage($imageInfo))
776
		{
777
			return FALSE;
778
		}
779
780
		list($width, $height, $type, $attrs) = $imageInfo;
0 ignored issues
show
Unused Code introduced by
The assignment to $attrs is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
781
		if($width < 1 || $height < 1)
782
		{
783
			return;
784
		}
785
786
		switch($type)
787
		{
788
			case '1' :
789
				$type = 'gif';
790
				break;
791
			case '2' :
792
				$type = 'jpg';
793
				break;
794
			case '3' :
795
				$type = 'png';
796
				break;
797
			case '6' :
798
				$type = 'bmp';
799
				break;
800
			default :
801
				return;
802
		}
803
804
		if(!$target_type)
805
		{
806
			$target_type = $type;
807
		}
808
		$target_type = strtolower($target_type);
809
810
		// if original image is larger than specified size to resize, calculate the ratio
811
		$width_per = ($resize_width > 0 && $width >= $resize_width) ? $resize_width / $width : 1;
812
		$height_per = ($resize_height > 0 && $height >= $resize_height) ? $resize_height / $height : 1;
813
814
		$per = NULL;
0 ignored issues
show
Unused Code introduced by
$per 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...
815
		if($thumbnail_type == 'ratio')
816
		{
817
			$per = ($width_per > $height_per) ? $height_per : $width_per;
818
			$resize_width = $width * $per;
819
			$resize_height = $height * $per;
820
		}
821
		else
822
		{
823
			$per = ($width_per < $height_per) ? $height_per : $width_per;
824
		}
825
826
		// create temporary image with target size
827
		$thumb = NULL;
828
		if(function_exists('imagecreateTRUEcolor'))
829
		{
830
			$thumb = imagecreateTRUEcolor($resize_width, $resize_height);
831
		}
832
		else if(function_exists('imagecreate'))
833
		{
834
			$thumb = imagecreate($resize_width, $resize_height);
835
		}
836
837
		if(!$thumb)
838
		{
839
			return FALSE;
840
		}
841
842
		imagefilledrectangle($thumb, 0, 0, $resize_width - 1, $resize_height - 1, imagecolorallocate($thumb, 255, 255, 255));
843
844
		// create temporary image having original type
845
		$source = NULL;
846
		switch($type)
847
		{
848
			case 'gif' :
849
				if(function_exists('imagecreatefromgif'))
850
				{
851
					$source = @imagecreatefromgif($source_file);
852
				}
853
				break;
854
			case 'jpeg' :
855
			case 'jpg' :
856
				if(function_exists('imagecreatefromjpeg'))
857
				{
858
					$source = @imagecreatefromjpeg($source_file);
859
				}
860
				break;
861
			case 'png' :
862
				if(function_exists('imagecreatefrompng'))
863
				{
864
					$source = @imagecreatefrompng($source_file);
865
				}
866
				break;
867
			case 'wbmp' :
868
			case 'bmp' :
869
				if(function_exists('imagecreatefromwbmp'))
870
				{
871
					$source = @imagecreatefromwbmp($source_file);
872
				}
873
				break;
874
		}
875
876
		if(!$source)
877
		{
878
			imagedestroy($thumb);
879
			return FALSE;
880
		}
881
882
		// resize original image and put it into temporary image
883
		$new_width = (int) ($width * $per);
884
		$new_height = (int) ($height * $per);
885
886
		$x = 0;
887
		$y = 0;
888
		if($thumbnail_type == 'crop')
889
		{
890
			$x = (int) ($resize_width / 2 - $new_width / 2);
891
			$y = (int) ($resize_height / 2 - $new_height / 2);
892
		}
893
894
		if(function_exists('imagecopyresampled'))
895
		{
896
			imagecopyresampled($thumb, $source, $x, $y, 0, 0, $new_width, $new_height, $width, $height);
897
		}
898
		else
899
		{
900
			imagecopyresized($thumb, $source, $x, $y, 0, 0, $new_width, $new_height, $width, $height);
901
		}
902
903
		// create directory
904
		self::makeDir(dirname($target_file));
905
906
		// write into the file
907
		$output = NULL;
908
		switch($target_type)
909
		{
910
			case 'gif' :
911
				if(function_exists('imagegif'))
912
				{
913
					$output = imagegif($thumb, $target_file);
914
				}
915
				break;
916
			case 'jpeg' :
917
			case 'jpg' :
918
				if(function_exists('imagejpeg'))
919
				{
920
					$output = imagejpeg($thumb, $target_file, 100);
921
				}
922
				break;
923
			case 'png' :
924
				if(function_exists('imagepng'))
925
				{
926
					$output = imagepng($thumb, $target_file, 9);
927
				}
928
				break;
929
			case 'wbmp' :
930
			case 'bmp' :
931
				if(function_exists('imagewbmp'))
932
				{
933
					$output = imagewbmp($thumb, $target_file, 100);
934
				}
935
				break;
936
		}
937
938
		imagedestroy($thumb);
939
		imagedestroy($source);
940
941
		if(!$output)
0 ignored issues
show
Bug Best Practice introduced by
The expression $output of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
942
		{
943
			return FALSE;
944
		}
945
		@chmod($target_file, 0644);
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...
946
947
		return TRUE;
948
	}
949
950
	/**
951
	 * Reads ini file, and puts result into array
952
	 *
953
	 * @see self::writeIniFile()
954
	 * @param string $filename Path of the ini file
955
	 * @return array ini array (if the target file does not exist, it returns FALSE)
956
	 */
957
	function readIniFile($filename)
958
	{
959
		if(($filename = self::exists($filename)) === FALSE)
960
		{
961
			return FALSE;
962
		}
963
		$arr = parse_ini_file($filename, TRUE);
964
		if(is_array($arr) && count($arr) > 0)
965
		{
966
			return $arr;
967
		}
968
		else
969
		{
970
			return array();
971
		}
972
	}
973
974
	/**
975
	 * Write array into ini file
976
	 *
977
	 * 	$ini['key1'] = 'value1';<br/>
978
	 * 	$ini['key2'] = 'value2';<br/>
979
	 * 	$ini['section']['key1_in_section'] = 'value1_in_section';<br/>
980
	 * 	$ini['section']['key2_in_section'] = 'value2_in_section';<br/>
981
	 * 	self::writeIniFile('exmple.ini', $ini);
982
	 *
983
	 * @see self::readIniFile()
984
	 * @param string $filename Target ini file name
985
	 * @param array $arr Array
986
	 * @return bool if array contains nothing it returns FALSE, otherwise TRUE
987
	 */
988
	function writeIniFile($filename, $arr)
989
	{
990
		if(!is_array($arr) || count($arr) == 0)
991
		{
992
			return FALSE;
993
		}
994
		self::writeFile($filename, self::_makeIniBuff($arr));
995
		return TRUE;
996
	}
997
998
	/**
999
	 * Make array to ini string
1000
	 *
1001
	 * @param array $arr Array
1002
	 * @return string
1003
	 */
1004
	function _makeIniBuff($arr)
1005
	{
1006
		$return = array();
1007
		foreach($arr as $key => $val)
1008
		{
1009
			// section
1010
			if(is_array($val))
1011
			{
1012
				$return[] = sprintf("[%s]", $key);
1013
				foreach($val as $k => $v)
1014
				{
1015
					$return[] = sprintf("%s=\"%s\"", $k, $v);
1016
				}
1017
				// value
1018
			}
1019
			else if(is_object($val))
1020
			{
1021
				continue;
1022
			}
1023
			else
1024
			{
1025
				$return[] = sprintf("%s=\"%s\"", $key, $val);
1026
			}
1027
		}
1028
1029
		return join("\n", $return);
1030
	}
1031
1032
	/**
1033
	 * Returns a file object
1034
	 *
1035
	 * If the directory of the file does not exist, create it.
1036
	 *
1037
	 * @param string $filename Target file name
1038
	 * @param string $mode File mode for fopen
1039
	 * @return FileObject File object
1040
	 */
1041
	function openFile($filename, $mode)
1042
	{
1043
		$pathinfo = pathinfo($filename);
1044
		self::makeDir($pathinfo['dirname']);
1045
1046
		require_once("FileObject.class.php");
1047
		return  new FileObject($filename, $mode);
1048
	}
1049
1050
	/**
1051
	 * Check whether the given file has the content.
1052
	 *
1053
	 * @param string $filename Target file name
1054
	 * @return bool Returns TRUE if the file exists and contains something.
1055
	 */
1056
	function hasContent($filename)
1057
	{
1058
		return (is_readable($filename) && (filesize($filename) > 0));
1059
	}
1060
1061
	/**
1062
	 * Check file exists.
1063
	 *
1064
	 * @param string $filename Target file name
1065
	 * @return bool Returns FALSE if the file does not exists, or Returns full path file(string).
1066
	 */
1067
	function exists($filename)
1068
	{
1069
		$filename = self::getRealPath($filename);
1070
		return file_exists($filename) ? $filename : FALSE;
1071
	}
1072
1073
	/**
1074
	 * Check it is dir
1075
	 *
1076
	 * @param string $dir Target dir path
0 ignored issues
show
Bug introduced by
There is no parameter named $dir. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

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

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

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

Loading history...
1077
	 * @return bool Returns FALSE if the dir is not dir, or Returns full path of dir(string).
1078
	 */
1079
	function isDir($path)
1080
	{
1081
		$path = self::getRealPath($path);
1082
		return is_dir($path) ? $path : FALSE;
1083
	}
1084
1085
	/**
1086
	 * Check is writable dir
1087
	 *
1088
	 * @param string $path Target dir path
1089
	 * @return bool
1090
	 */
1091
	function isWritableDir($path)
1092
	{
1093
		$path = self::getRealPath($path);
1094
		if(is_dir($path)==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...
1095
		{
1096
			return FALSE;
1097
		}
1098
1099
		$checkFile = $path . '/_CheckWritableDir';
1100
1101
		$fp = fopen($checkFile, 'w');
1102
		if(!is_resource($fp))
1103
		{
1104
			return FALSE;
1105
		}
1106
		fclose($fp);
1107
1108
		self::removeFile($checkFile);
1109
		return TRUE;
1110
	}
1111
1112
	/**
1113
	 * Clears file status cache
1114
	 *
1115
	 * @param string|array $target filename or directory
1116
	 * @param boolean $include include files in the directory
1117
	 **/
1118
	static public function clearStatCache($target, $include = false)
1119
	{
1120
		if(is_array($target))
1121
		{
1122
			array_map('self::clearStatCache', $target);
1123
			return;
1124
		}
1125
1126
		$target = self::getRealPath($target);
1127
1128
		if($include && self::isDir($target))
0 ignored issues
show
Bug Best Practice introduced by
The expression self::isDir($target) 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...
1129
		{
1130
			self::clearStatCache(self::readDir($target, '', false, true), $include);
1131
		}
1132
1133
		clearstatcache(true, $target);
1134
	}
1135
1136
	/**
1137
	 * Invalidates a cached script of OPcache
1138
	 *
1139
	 * @param string|array $target filename or directory
1140
	 * @param boolean $force force
1141
	 **/
1142
	static public function invalidateOpcache($target, $force = true)
1143
	{
1144
		static $opcache = null;
1145
1146
		if($opcache === null)
1147
		{
1148
			$opcache = (function_exists('opcache_get_status') && function_exists('opcache_invalidate'));
1149
		}
1150
1151
		if($opcache === false)
1152
		{
1153
			return;
1154
		}
1155
1156
		if(is_array($target))
1157
		{
1158
			array_map('self::invalidateOpcache', $target);
1159
			return;
1160
		}
1161
1162
		if(substr($target, -4) === '.php')
1163
		{
1164
			opcache_invalidate(self::getRealPath($target), $force);
1165
		}
1166
		else if($path = self::isDir($target))
1167
		{
1168
			self::invalidateOpcache(self::readDir($path, '', false, true));
1169
		}
1170
	}
1171
}
1172
1173
/* End of file FileHandler.class.php */
1174
/* Location: ./classes/file/FileHandler.class.php */
1175