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.

func.inc.php ➔ removeSrcHack()   F
last analyzed

Complexity

Conditions 29
Paths 2818

Size

Total Lines 93

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 29
nc 2818
nop 1
dl 0
loc 93
rs 0
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) XEHub <https://www.xehub.io> */
3
4
/**
5
 * function library files for convenience
6
 *
7
 * @author XEHub ([email protected])
8
 */
9
if(!defined('__XE__'))
10
{
11
	exit();
12
}
13
14
// define an empty function to avoid errors when iconv function doesn't exist
15
if(!function_exists('iconv'))
16
{
17
	eval('
18
		function iconv($in_charset, $out_charset, $str)
19
		{
20
			return $str;
21
		}
22
	');
23
}
24
25
/**
26
 * Time zone
27
 * @var array
28
 */
29
$time_zone = array(
30
	'-1200' => '[GMT -12:00] Baker Island Time',
31
	'-1100' => '[GMT -11:00] Niue Time, Samoa Standard Time',
32
	'-1000' => '[GMT -10:00] Hawaii-Aleutian Standard Time, Cook Island Time',
33
	'-0930' => '[GMT -09:30] Marquesas Islands Time',
34
	'-0900' => '[GMT -09:00] Alaska Standard Time, Gambier Island Time',
35
	'-0800' => '[GMT -08:00] Pacific Standard Time',
36
	'-0700' => '[GMT -07:00] Mountain Standard Time',
37
	'-0600' => '[GMT -06:00] Central Standard Time',
38
	'-0500' => '[GMT -05:00] Eastern Standard Time',
39
	'-0400' => '[GMT -04:00] Atlantic Standard Time',
40
	'-0330' => '[GMT -03:30] Newfoundland Standard Time',
41
	'-0300' => '[GMT -03:00] Amazon Standard Time, Central Greenland Time',
42
	'-0200' => '[GMT -02:00] Fernando de Noronha Time, South Georgia &amp; the South Sandwich Islands Time',
43
	'-0100' => '[GMT -01:00] Azores Standard Time, Cape Verde Time, Eastern Greenland Time',
44
	'0000' => '[GMT  00:00] Western European Time, Greenwich Mean Time',
45
	'+0100' => '[GMT +01:00] Central European Time, West African Time',
46
	'+0200' => '[GMT +02:00] Eastern European Time, Central African Time',
47
	'+0300' => '[GMT +03:00] Moscow Standard Time, Eastern African Time',
48
	'+0330' => '[GMT +03:30] Iran Standard Time',
49
	'+0400' => '[GMT +04:00] Gulf Standard Time, Samara Standard Time',
50
	'+0430' => '[GMT +04:30] Afghanistan Time',
51
	'+0500' => '[GMT +05:00] Pakistan Standard Time, Yekaterinburg Standard Time',
52
	'+0530' => '[GMT +05:30] Indian Standard Time, Sri Lanka Time',
53
	'+0545' => '[GMT +05:45] Nepal Time',
54
	'+0600' => '[GMT +06:00] Bangladesh Time, Bhutan Time, Novosibirsk Standard Time',
55
	'+0630' => '[GMT +06:30] Cocos Islands Time, Myanmar Time',
56
	'+0700' => '[GMT +07:00] Indochina Time, Krasnoyarsk Standard Time',
57
	'+0800' => '[GMT +08:00] China Standard Time, Australian Western Standard Time, Irkutsk Standard Time',
58
	'+0845' => '[GMT +08:45] Southeastern Western Australia Standard Time',
59
	'+0900' => '[GMT +09:00] Korea Standard Time, Japan Standard Time',
60
	'+0930' => '[GMT +09:30] Australian Central Standard Time',
61
	'+1000' => '[GMT +10:00] Australian Eastern Standard Time, Vladivostok Standard Time',
62
	'+1030' => '[GMT +10:30] Lord Howe Standard Time',
63
	'+1100' => '[GMT +11:00] Solomon Island Time, Magadan Standard Time',
64
	'+1130' => '[GMT +11:30] Norfolk Island Time',
65
	'+1200' => '[GMT +12:00] New Zealand Time, Fiji Time, Kamchatka Standard Time',
66
	'+1245' => '[GMT +12:45] Chatham Islands Time',
67
	'+1300' => '[GMT +13:00] Tonga Time, Phoenix Islands Time',
68
	'+1400' => '[GMT +14:00] Line Island Time'
69
);
70
71
/**
72
 * Define a function to use {@see ModuleHandler::getModuleObject()} ($module_name, $type)
73
 *
74
 * @param string $module_name The module name to get a instance
75
 * @param string $type disp, proc, controller, class
76
 * @param string $kind admin, null
77
 * @return mixed Module instance
78
 */
79
function getModule($module_name, $type = 'view', $kind = '')
80
{
81
	return ModuleHandler::getModuleInstance($module_name, $type, $kind);
82
}
83
84
/**
85
 * Create a controller instance of the module
86
 *
87
 * @param string $module_name The module name to get a controller instance
88
 * @return mixed Module controller instance
89
 */
90
function getController($module_name)
91
{
92
	return getModule($module_name, 'controller');
93
}
94
95
/**
96
 * Create a admin controller instance of the module
97
 *
98
 * @param string $module_name The module name to get a admin controller instance
99
 * @return mixed Module admin controller instance
100
 */
101
function getAdminController($module_name)
102
{
103
	return getModule($module_name, 'controller', 'admin');
104
}
105
106
/**
107
 * Create a view instance of the module
108
 *
109
 * @param string $module_name The module name to get a view instance
110
 * @return mixed Module view instance
111
 */
112
function getView($module_name)
113
{
114
	return getModule($module_name, 'view');
115
}
116
117
/**
118
 * Create a mobile instance of the module
119
 *
120
 * @param string $module_name The module name to get a mobile instance
121
 * @return mixed Module mobile instance
122
 */
123
function &getMobile($module_name)
124
{
125
	return getModule($module_name, 'mobile');
126
}
127
128
/**
129
 * Create a admin view instance of the module
130
 *
131
 * @param string $module_name The module name to get a admin view instance
132
 * @return mixed Module admin view instance
133
 */
134
function getAdminView($module_name)
135
{
136
	return getModule($module_name, 'view', 'admin');
137
}
138
139
/**
140
 * Create a model instance of the module
141
 *
142
 * @param string $module_name The module name to get a model instance
143
 * @return mixed Module model instance
144
 */
145
function getModel($module_name)
146
{
147
	return getModule($module_name, 'model');
148
}
149
150
/**
151
 * Create an admin model instance of the module
152
 *
153
 * @param string $module_name The module name to get a admin model instance
154
 * @return mixed Module admin model instance
155
 */
156
function getAdminModel($module_name)
157
{
158
	return getModule($module_name, 'model', 'admin');
159
}
160
161
/**
162
 * Create an api instance of the module
163
 *
164
 * @param string $module_name The module name to get a api instance
165
 * @return mixed Module api class instance
166
 */
167
function getAPI($module_name)
168
{
169
	return getModule($module_name, 'api');
170
}
171
172
/**
173
 * Create a wap instance of the module
174
 *
175
 * @param string $module_name The module name to get a wap instance
176
 * @return mixed Module wap class instance
177
 */
178
function getWAP($module_name)
179
{
180
	return getModule($module_name, 'wap');
181
}
182
183
/**
184
 * Create a class instance of the module
185
 *
186
 * @param string $module_name The module name to get a class instance
187
 * @return mixed Module class instance
188
 */
189
function getClass($module_name)
190
{
191
	return getModule($module_name, 'class');
192
}
193
194
/**
195
 * The alias of DB::executeQuery()
196
 *
197
 * @see DB::executeQuery()
198
 * @param string $query_id (module name.query XML file)
199
 * @param object $args values of args object
200
 * @param string[] $arg_columns Column list
201
 * @return object Query result data
202
 */
203
function executeQuery($query_id, $args = NULL, $arg_columns = NULL)
204
{
205
	$oDB = DB::getInstance();
206
	return $oDB->executeQuery($query_id, $args, $arg_columns);
207
}
208
209
/**
210
 * Function to handle the result of DB::executeQuery() as an array
211
 *
212
 * @see DB::executeQuery()
213
 * @see executeQuery()
214
 * @param string $query_id (module name.query XML file)
215
 * @param object $args values of args object
216
 * @param string[] $arg_columns Column list
217
 * @return object Query result data
218
 */
219
function executeQueryArray($query_id, $args = NULL, $arg_columns = NULL)
220
{
221
	$oDB = DB::getInstance();
222
	$output = $oDB->executeQuery($query_id, $args, $arg_columns);
223
	if(!is_array($output->data) && count($output->data) > 0)
224
	{
225
		$output->data = array($output->data);
226
	}
227
	return $output;
228
}
229
230
/**
231
 * Alias of DB::getNextSequence()
232
 *
233
 * @see DB::getNextSequence()
234
 * @return int
235
 */
236
function getNextSequence()
237
{
238
	$oDB = DB::getInstance();
239
	$seq = $oDB->getNextSequence();
240
	setUserSequence($seq);
241
	return $seq;
242
}
243
244
/**
245
 * Set Sequence number to session
246
 *
247
 * @param int $seq sequence number
248
 * @return void
249
 */
250
function setUserSequence($seq)
251
{
252
	$arr_seq = array();
253
	if(isset($_SESSION['seq']))
254
	{
255
		if(!is_array($_SESSION['seq'])) {
256
			$_SESSION['seq'] = array($_SESSION['seq']);
257
		}
258
		$arr_seq = $_SESSION['seq'];
259
	}
260
	$arr_seq[] = $seq;
261
	$_SESSION['seq'] = $arr_seq;
262
}
263
264
/**
265
 * Check Sequence number grant
266
 *
267
 * @param int $seq sequence number
268
 * @return boolean
269
 */
270
function checkUserSequence($seq)
271
{
272
	if(!isset($_SESSION['seq']))
273
	{
274
		return false;
275
	}
276
	if(!in_array($seq, $_SESSION['seq']))
277
	{
278
		return false;
279
	}
280
281
	return true;
282
}
283
284
/**
285
 * Get a encoded url. Define a function to use Context::getUrl()
286
 *
287
 * getUrl() returns the URL transformed from given arguments of RequestURI
288
 * <ol>
289
 *  <li>argument format follows as (key, value).
290
 * ex) getUrl('key1', 'val1', 'key2',''): transform key1 and key2 to val1 and '' respectively</li>
291
 * <li>returns URL without the argument if no argument is given.</li>
292
 * <li>URL made of args_list added to RequestUri if the first argument value is ''.</li>
293
 * </ol>
294
 *
295
 * @return string
296
 */
297
function getUrl()
298
{
299
	$num_args = func_num_args();
300
	$args_list = func_get_args();
301
302
	if($num_args)
303
		$url = Context::getUrl($num_args, $args_list);
304
	else
305
		$url = Context::getRequestUri();
306
307
	return preg_replace('@\berror_return_url=[^&]*|\w+=(?:&|$)@', '', $url);
308
}
309
310
/**
311
 * Get a not encoded(html entity) url
312
 *
313
 * @see getUrl()
314
 * @return string
315
 */
316 View Code Duplication
function getNotEncodedUrl()
0 ignored issues
show
Duplication introduced by
This function 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...
317
{
318
	$num_args = func_num_args();
319
	$args_list = func_get_args();
320
321
	if($num_args)
322
	{
323
		$url = Context::getUrl($num_args, $args_list, NULL, FALSE);
324
	}
325
	else
326
	{
327
		$url = Context::getRequestUri();
328
	}
329
330
	return preg_replace('@\berror_return_url=[^&]*|\w+=(?:&|$)@', '', $url);
331
}
332
333
/**
334
 * Get a encoded url. If url is encoded, not encode. Otherwise html encode the url.
335
 *
336
 * @see getUrl()
337
 * @return string
338
 */
339 View Code Duplication
function getAutoEncodedUrl()
0 ignored issues
show
Duplication introduced by
This function 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...
340
{
341
	$num_args = func_num_args();
342
	$args_list = func_get_args();
343
344
	if($num_args)
345
	{
346
		$url = Context::getUrl($num_args, $args_list, NULL, TRUE, TRUE);
347
	}
348
	else
349
	{
350
		$url = Context::getRequestUri();
351
	}
352
353
	return preg_replace('@\berror_return_url=[^&]*|\w+=(?:&|$)@', '', $url);
354
}
355
356
/**
357
 * Return the value adding request uri to getUrl() to get the full url
358
 *
359
 * @return string
360
 */
361
function getFullUrl()
362
{
363
	$num_args = func_num_args();
364
	$args_list = func_get_args();
365
	$request_uri = Context::getRequestUri();
366
	if(!$num_args)
367
	{
368
		return $request_uri;
369
	}
370
371
	$url = Context::getUrl($num_args, $args_list);
372 View Code Duplication
	if(strncasecmp('http', $url, 4) !== 0)
373
	{
374
		preg_match('/^(http|https):\/\/([^\/]+)\//', $request_uri, $match);
375
		return substr($match[0], 0, -1) . $url;
376
	}
377
	return $url;
378
}
379
380
/**
381
 * Return the value adding request uri to getUrl() to get the not encoded full url
382
 *
383
 * @return string
384
 */
385
function getNotEncodedFullUrl()
386
{
387
	$num_args = func_num_args();
388
	$args_list = func_get_args();
389
	$request_uri = Context::getRequestUri();
390
	if(!$num_args)
391
	{
392
		return $request_uri;
393
	}
394
395
	$url = Context::getUrl($num_args, $args_list, NULL, FALSE);
396 View Code Duplication
	if(strncasecmp('http', $url, 4) !== 0)
397
	{
398
		preg_match('/^(http|https):\/\/([^\/]+)\//', $request_uri, $match);
399
		$url = Context::getUrl($num_args, $args_list, NULL, FALSE);
400
		return substr($match[0], 0, -1) . $url;
401
	}
402
	return $url;
403
}
404
405
/**
406
 * getSiteUrl() returns the URL by transforming the given argument value of domain
407
 * The first argument should consist of domain("http://" not included) and path
408
 * 
409
 * @return string
410
 */
411 View Code Duplication
function getSiteUrl()
0 ignored issues
show
Duplication introduced by
This function 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...
412
{
413
	$num_args = func_num_args();
414
	$args_list = func_get_args();
415
416
	if(!$num_args)
417
	{
418
		return Context::getRequestUri();
419
	}
420
421
	$domain = array_shift($args_list);
422
	$num_args = count($args_list);
423
424
	return Context::getUrl($num_args, $args_list, $domain);
425
}
426
427
/**
428
 * getSiteUrl() returns the not encoded URL by transforming the given argument value of domain
429
 * The first argument should consist of domain("http://" not included) and path
430
 * 
431
 * @return string
432
 */
433 View Code Duplication
function getNotEncodedSiteUrl()
0 ignored issues
show
Duplication introduced by
This function 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...
434
{
435
	$num_args = func_num_args();
436
	$args_list = func_get_args();
437
438
	if(!$num_args)
439
	{
440
		return Context::getRequestUri();
441
	}
442
443
	$domain = array_shift($args_list);
444
	$num_args = count($args_list);
445
446
	return Context::getUrl($num_args, $args_list, $domain, FALSE);
447
}
448
449
/**
450
 * Return the value adding request uri to the getSiteUrl() To get the full url
451
 *
452
 * @return string
453
 */
454
function getFullSiteUrl()
455
{
456
	$num_args = func_num_args();
457
	$args_list = func_get_args();
458
459
	$request_uri = Context::getRequestUri();
460
	if(!$num_args)
461
	{
462
		return $request_uri;
463
	}
464
465
	$domain = array_shift($args_list);
466
	$num_args = count($args_list);
467
468
	$url = Context::getUrl($num_args, $args_list, $domain);
469 View Code Duplication
	if(strncasecmp('http', $url, 4) !== 0)
470
	{
471
		preg_match('/^(http|https):\/\/([^\/]+)\//', $request_uri, $match);
472
		return substr($match[0], 0, -1) . $url;
473
	}
474
	return $url;
475
}
476
477
/**
478
 * Return the exact url of the current page
479
 *
480
 * @return string
481
 */
482
function getCurrentPageUrl()
483
{
484
	$protocol = $_SERVER['HTTPS'] == 'on' ? 'https://' : 'http://';
485
	$url = $protocol . $_SERVER['HTTP_HOST'] . preg_replace('/[<>"]/', '', $_SERVER['REQUEST_URI']);
486
	return htmlspecialchars($url, ENT_COMPAT, 'UTF-8', FALSE);
487
}
488
489
/**
490
 * Return if domain of the virtual site is url type or id type
491
 *
492
 * @param string $domain
493
 * @return bool
494
 */
495
function isSiteID($domain)
496
{
497
	return preg_match('/^([a-zA-Z0-9\_]+)$/', $domain);
498
}
499
500
/**
501
 * Put a given tail after trimming string to the specified size
502
 *
503
 * @param string $string The original string to trim
504
 * @param int $cut_size The size to be
505
 * @param string $tail Tail to put in the end of the string after trimming
506
 * @return string
507
 */
508
function cut_str($string, $cut_size = 0, $tail = '...')
509
{
510
	if($cut_size < 1 || !$string)
511
	{
512
		return $string;
513
	}
514
515
	if($GLOBALS['use_mb_strimwidth'] || function_exists('mb_strimwidth'))
516
	{
517
		$GLOBALS['use_mb_strimwidth'] = TRUE;
518
		return mb_strimwidth($string, 0, $cut_size + 4, $tail, 'utf-8');
519
	}
520
521
	$chars = array(12, 4, 3, 5, 7, 7, 11, 8, 4, 5, 5, 6, 6, 4, 6, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 4, 8, 6, 8, 6, 10, 8, 8, 9, 8, 8, 7, 9, 8, 3, 6, 7, 7, 11, 8, 9, 8, 9, 8, 8, 7, 8, 8, 10, 8, 8, 8, 6, 11, 6, 6, 6, 4, 7, 7, 7, 7, 7, 3, 7, 7, 3, 3, 6, 3, 9, 7, 7, 7, 7, 4, 7, 3, 7, 6, 10, 6, 6, 7, 6, 6, 6, 9);
522
	$max_width = $cut_size * $chars[0] / 2;
523
	$char_width = 0;
524
525
	$string_length = strlen($string);
526
	$char_count = 0;
527
528
	$idx = 0;
529
	while($idx < $string_length && $char_count < $cut_size && $char_width <= $max_width)
530
	{
531
		$c = ord(substr($string, $idx, 1));
532
		$char_count++;
533
		if($c < 128)
534
		{
535
			$char_width += (int) $chars[$c - 32];
536
			$idx++;
537
		}
538
		else if(191 < $c && $c < 224)
539
		{
540
			$char_width += $chars[4];
541
			$idx += 2;
542
		}
543
		else
544
		{
545
			$char_width += $chars[0];
546
			$idx += 3;
547
		}
548
	}
549
550
	$output = substr($string, 0, $idx);
551
	if(strlen($output) < $string_length)
552
	{
553
		$output .= $tail;
554
	}
555
556
	return $output;
557
}
558
559
/**
560
 * Get a time gap between server's timezone and XE's timezone
561
 *
562
 * @return int
563
 */
564
function zgap()
565
{
566
	$time_zone = $GLOBALS['_time_zone'];
567
	if($time_zone < 0)
568
	{
569
		$to = -1;
570
	}
571
	else
572
	{
573
		$to = 1;
574
	}
575
576
	$t_hour = substr($time_zone, 1, 2) * $to;
577
	$t_min = substr($time_zone, 3, 2) * $to;
578
579
	$server_time_zone = date("O");
580
	if($server_time_zone < 0)
581
	{
582
		$so = -1;
583
	}
584
	else
585
	{
586
		$so = 1;
587
	}
588
589
	$c_hour = substr($server_time_zone, 1, 2) * $so;
590
	$c_min = substr($server_time_zone, 3, 2) * $so;
591
592
	$g_min = $t_min - $c_min;
593
	$g_hour = $t_hour - $c_hour;
594
595
	$gap = $g_min * 60 + $g_hour * 60 * 60;
596
	return $gap;
597
}
598
599
/**
600
 * YYYYMMDDHHIISS format changed to unix time value
601
 *
602
 * @param string $str Time value in format of YYYYMMDDHHIISS
603
 * @return int
604
 */
605
function ztime($str)
606
{
607
	if(!$str)
608
	{
609
		return;
610
	}
611
	if (strlen($str) === 9 || (strlen($str) === 10 && $str <= 2147483647))
612
 	{
613
 		return intval($str);
614
 	}
615
616
	$hour = (int) substr($str, 8, 2);
617
	$min = (int) substr($str, 10, 2);
618
	$sec = (int) substr($str, 12, 2);
619
	$year = (int) substr($str, 0, 4);
620
	$month = (int) substr($str, 4, 2);
621
	$day = (int) substr($str, 6, 2);
622
	if(strlen($str) <= 8)
623
	{
624
		$gap = 0;
625
	}
626
	else
627
	{
628
		$gap = zgap();
629
	}
630
631
	return mktime($hour, $min, $sec, $month ? $month : 1, $day ? $day : 1, $year) + $gap;
632
}
633
634
/**
635
 * If the recent post within a day, output format of YmdHis is "min/hours ago from now". If not within a day, it return format string.
636
 *
637
 * @param string $date Time value in format of YYYYMMDDHHIISS
638
 * @param string $format If gap is within a day, returns this format.
639
 * @return string
640
 */
641
function getTimeGap($date, $format = 'Y.m.d')
642
{
643
	$gap = $_SERVER['REQUEST_TIME'] + zgap() - ztime($date);
644
645
	$lang_time_gap = Context::getLang('time_gap');
646
	if($gap < 60)
647
	{
648
		$buff = sprintf($lang_time_gap['min'], (int) ($gap / 60) + 1);
649
	}
650
	elseif($gap < 60 * 60)
651
	{
652
		$buff = sprintf($lang_time_gap['mins'], (int) ($gap / 60) + 1);
653
	}
654 View Code Duplication
	elseif($gap < 60 * 60 * 2)
655
	{
656
		$buff = sprintf($lang_time_gap['hour'], (int) ($gap / 60 / 60) + 1);
657
	}
658 View Code Duplication
	elseif($gap < 60 * 60 * 24)
659
	{
660
		$buff = sprintf($lang_time_gap['hours'], (int) ($gap / 60 / 60) + 1);
661
	}
662
	else
663
	{
664
		$buff = zdate($date, $format);
665
	}
666
667
	return $buff;
668
}
669
670
/**
671
 * Name of the month return
672
 *
673
 * @param int $month Month
674
 * @param boot $short If set, returns short string
675
 * @return string
676
 */
677
function getMonthName($month, $short = TRUE)
678
{
679
	$short_month = array('', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
680
	$long_month = array('', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
681
	return !$short ? $long_month[$month] : $short_month[$month];
682
}
683
684
/**
685
 * Change the time format YYYYMMDDHHIISS to the user defined format
686
 *
687
 * @param string|int $str YYYYMMDDHHIISS format time values
688
 * @param string $format Time format of php date() function
689
 * @param bool $conversion Means whether to convert automatically according to the language
690
 * @return string
691
 */
692
function zdate($str, $format = 'Y-m-d H:i:s', $conversion = TRUE)
693
{
694
	// return null if no target time is specified
695
	if(!$str)
696
	{
697
		return;
698
	}
699
	// convert the date format according to the language
700
	if($conversion == TRUE)
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...
701
	{
702
		switch(Context::getLangType())
703
		{
704
			case 'en' :
705
			case 'es' :
706 View Code Duplication
				if($format == 'Y-m-d')
707
				{
708
					$format = 'M d, Y';
709
				}
710
				elseif($format == 'Y-m-d H:i:s')
711
				{
712
					$format = 'M d, Y H:i:s';
713
				}
714
				elseif($format == 'Y-m-d H:i')
715
				{
716
					$format = 'M d, Y H:i';
717
				}
718
				break;
719
			case 'vi' :
720 View Code Duplication
				if($format == 'Y-m-d')
721
				{
722
					$format = 'd-m-Y';
723
				}
724
				elseif($format == 'Y-m-d H:i:s')
725
				{
726
					$format = 'H:i:s d-m-Y';
727
				}
728
				elseif($format == 'Y-m-d H:i')
729
				{
730
					$format = 'H:i d-m-Y';
731
				}
732
				break;
733
		}
734
	}
735
736
	// If year value is less than 1970, handle it separately.
737
	if((int) substr($str, 0, 4) < 1970)
738
	{
739
		$hour = (int) substr($str, 8, 2);
740
		$min = (int) substr($str, 10, 2);
741
		$sec = (int) substr($str, 12, 2);
742
		$year = (int) substr($str, 0, 4);
743
		$month = (int) substr($str, 4, 2);
744
		$day = (int) substr($str, 6, 2);
745
746
		$trans = array(
747
			'Y' => $year,
748
			'y' => sprintf('%02d', $year % 100),
749
			'm' => sprintf('%02d', $month),
750
			'n' => $month,
751
			'd' => sprintf('%02d', $day),
752
			'j' => $day,
753
			'G' => $hour,
754
			'H' => sprintf('%02d', $hour),
755
			'g' => $hour % 12,
756
			'h' => sprintf('%02d', $hour % 12),
757
			'i' => sprintf('%02d', $min),
758
			's' => sprintf('%02d', $sec),
759
			'M' => getMonthName($month),
760
			'F' => getMonthName($month, FALSE)
761
		);
762
763
		$string = strtr($format, $trans);
764
	}
765
	else
766
	{
767
		// if year value is greater than 1970, get unixtime by using ztime() for date() function's argument. 
768
		$string = date($format, ztime($str));
769
	}
770
	// change day and am/pm for each language
771
	$unit_week = Context::getLang('unit_week');
772
	$unit_meridiem = Context::getLang('unit_meridiem');
773
	$string = str_replace(array('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'), $unit_week, $string);
774
	$string = str_replace(array('am', 'pm', 'AM', 'PM'), $unit_meridiem, $string);
775
	return $string;
776
}
777
778
/**
779
 * Returns encoded value of given email address for email scraping
780
 *
781
 * @param string $email The email
782
 * @return string
783
 */
784
function getEncodeEmailAddress($email)
785
{
786
	$return = '';
787
	for($i = 0, $c = strlen($email); $i < $c; $i++)
788
	{
789
		$return .= '&#' . (rand(0, 1) == 0 ? ord($email[$i]) : 'X' . dechex(ord($email[$i]))) . ';';
790
	}
791
	return $return;
792
}
793
794
/**
795
 * Prints debug messages 
796
 *
797
 * Display $buff contents into the file ./files/_debug_message.php.
798
 * You can see the file on your prompt by command: tail-f./files/_debug_message.php
799
 *
800
 * @param mixed $debug_output Target object to be printed
801
 * @param bool $display_option boolean Flag whether to print seperator (default:true)
802
 * @param string $file Target file name
803
 * @return void
804
 */
805
function debugPrint($debug_output = NULL, $display_option = TRUE, $file = '_debug_message.php')
806
{
807
	static $debug_file;
808
809
	if(!(__DEBUG__ & 1))
810
	{
811
		return;
812
	}
813
814
	static $firephp;
815
	$bt = debug_backtrace();
816
	if(is_array($bt))
817
	{
818
		$bt_debug_print = array_shift($bt);
819
		$bt_called_function = array_shift($bt);
820
	}
821
	$file_name = str_replace(_XE_PATH_, '', $bt_debug_print['file']);
0 ignored issues
show
Bug introduced by
The variable $bt_debug_print does not seem to be defined for all execution paths leading up to this point.

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
822
	$line_num = $bt_debug_print['line'];
823
	$function = $bt_called_function['class'] . $bt_called_function['type'] . $bt_called_function['function'];
0 ignored issues
show
Bug introduced by
The variable $bt_called_function 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...
824
825
	if(__DEBUG_OUTPUT__ == 2 && version_compare(PHP_VERSION, '6.0.0') === -1)
826
	{
827
		if(!isset($firephp))
828
		{
829
			$firephp = FirePHP::getInstance(TRUE);
830
		}
831
		$type = FirePHP::INFO;
832
833
		$label = sprintf('[%s:%d] %s() (Memory usage: current=%s, peak=%s)', $file_name, $line_num, $function, FileHandler::filesize(memory_get_usage()), FileHandler::filesize(memory_get_peak_usage()));
834
835
		// Check a FirePHP option
836
		if($display_option === 'TABLE')
837
		{
838
			$label = $display_option;
839
		}
840
		if($display_option === 'ERROR')
841
		{
842
			$type = $display_option;
843
		}
844
		// Check if the IP specified by __DEBUG_PROTECT__ option is same as the access IP.
845
		if(__DEBUG_PROTECT__ === 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR'])
846
		{
847
			$debug_output = 'The IP address is not allowed. Change the value of __DEBUG_PROTECT_IP__ into your IP address in config/config.user.inc.php or config/config.inc.php';
848
			$label = NULL;
849
		}
850
851
		$firephp->fb($debug_output, $label, $type);
852
	}
853
	else
854
	{
855
		if(__DEBUG_PROTECT__ === 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR'])
856
		{
857
			return;
858
		}
859
860
		$print = array();
861
		if(!$debug_file)
862
		{
863
			$debug_file = _XE_PATH_ . 'files/' . $file;
864
		}
865
		if(!file_exists($debug_file)) $print[] = '<?php exit() ?>';
866
867
		if($display_option === TRUE || $display_option === 'ERROR')
868
		{
869
			$print[] = sprintf("[%s %s:%d] %s() - mem(%s)", date('Y-m-d H:i:s'), $file_name, $line_num, $function, FileHandler::filesize(memory_get_usage()));;
870
			$print[] = str_repeat('=', 80);
871
		}
872
		$type = gettype($debug_output);
873
		if(!in_array($type, array('array', 'object', 'resource')))
874
		{
875
			if($display_option === 'ERROR')
876
			{
877
				$print[] = 'ERROR : ' . var_export($debug_output, TRUE);
878
			}
879
			else
880
			{
881
				$print[] = 'DEBUG : ' . $type . '(' . var_export($debug_output, TRUE) . ')';
882
			}
883
		}
884
		else
885
		{
886
			$print[] = 'DEBUG : ' . trim(preg_replace('/\r?\n/', "\n" . '        ', print_r($debug_output, true)));
887
		}
888
		$backtrace_args = defined('\DEBUG_BACKTRACE_IGNORE_ARGS') ? \DEBUG_BACKTRACE_IGNORE_ARGS : 0;
889
		$backtrace = debug_backtrace($backtrace_args);
890
891 View Code Duplication
		if(count($backtrace) > 1 && $backtrace[1]['function'] === 'debugPrint' && !$backtrace[1]['class'])
892
		{
893
			array_shift($backtrace);
894
		}
895
		foreach($backtrace as $val)
896
		{
897
			$print[] = '        - ' . $val['file'] . ' : ' . $val['line'];
898
		}
899
		$print[] = PHP_EOL;
900
		@file_put_contents($debug_file, implode(PHP_EOL, $print), FILE_APPEND|LOCK_EX);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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

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

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
901
	}
902
}
903
904
/**
905
 * @param string $type query, trigger
906
 * @param float $elapsed_time
907
 * @param object $obj
908
 */
909
function writeSlowlog($type, $elapsed_time, $obj)
910
{
911
	if(!__LOG_SLOW_TRIGGER__ && !__LOG_SLOW_ADDON__ && !__LOG_SLOW_WIDGET__ && !__LOG_SLOW_QUERY__) return;
912
913
	static $log_filename = array(
914
		'query' => 'files/_slowlog_query.php',
915
		'trigger' => 'files/_slowlog_trigger.php',
916
		'addon' => 'files/_slowlog_addon.php',
917
		'widget' => 'files/_slowlog_widget.php'
918
	);
919
	$write_file = true;
920
921
	$log_file = _XE_PATH_ . $log_filename[$type];
922
923
	$buff = array();
924
	$buff[] = '<?php exit(); ?>';
925
	$buff[] = date('c');
926
927
	if($type == 'trigger' && __LOG_SLOW_TRIGGER__ > 0 && $elapsed_time > __LOG_SLOW_TRIGGER__)
928
	{
929
		$buff[] = "\tCaller : " . $obj->caller;
930
		$buff[] = "\tCalled : " . $obj->called;
931
	}
932
	else if($type == 'addon' && __LOG_SLOW_ADDON__ > 0 && $elapsed_time > __LOG_SLOW_ADDON__)
933
	{
934
		$buff[] = "\tAddon : " . $obj->called;
935
		$buff[] = "\tCalled position : " . $obj->caller;
936
	}
937
	else if($type == 'widget' && __LOG_SLOW_WIDGET__ > 0 && $elapsed_time > __LOG_SLOW_WIDGET__)
938
	{
939
		$buff[] = "\tWidget : " . $obj->called;
940
	}
941
	else if($type == 'query' && __LOG_SLOW_QUERY__ > 0 && $elapsed_time > __LOG_SLOW_QUERY__)
942
	{
943
944
		$buff[] = $obj->query;
945
		$buff[] = "\tQuery ID   : " . $obj->query_id;
946
		$buff[] = "\tCaller     : " . $obj->caller;
947
		$buff[] = "\tConnection : " . $obj->connection;
948
	}
949
	else
950
	{
951
		$write_file = false;
952
	}
953
954
	if($write_file)
955
	{
956
		$buff[] = sprintf("\t%0.6f sec", $elapsed_time);
957
		$buff[] = PHP_EOL . PHP_EOL;
958
		file_put_contents($log_file, implode(PHP_EOL, $buff), FILE_APPEND);
959
	}
960
961
	if($type != 'query')
962
	{
963
		$trigger_args = $obj;
964
		$trigger_args->_log_type = $type;
965
		$trigger_args->_elapsed_time = $elapsed_time;
966
		ModuleHandler::triggerCall('XE.writeSlowlog', 'after', $trigger_args);
967
	}
968
}
969
970
/**
971
 * @param void
972
 */
973
function flushSlowlog()
974
{
975
	$trigger_args = new stdClass();
976
	$trigger_args->_log_type = 'flush';
977
	$trigger_args->_elapsed_time = 0;
978
	ModuleHandler::triggerCall('XE.writeSlowlog', 'after', $trigger_args);
979
}
980
981
/**
982
 * microtime() return
983
 *
984
 * @return float
985
 */
986
function getMicroTime()
987
{
988
	list($time1, $time2) = explode(' ', microtime());
989
	return (float) $time1 + (float) $time2;
990
}
991
992
/**
993
 * Delete the second object vars from the first argument
994
 *
995
 * @param object $target_obj An original object
996
 * @param object $del_obj BaseObject vars to delete from the original object
997
 * @return object
998
 */
999
function delObjectVars($target_obj, $del_obj)
1000
{
1001
	if(!is_object($target_obj))
1002
	{
1003
		return;
1004
	}
1005
	if(!is_object($del_obj))
1006
	{
1007
		return;
1008
	}
1009
1010
	$target_vars = get_object_vars($target_obj);
1011
	$del_vars = get_object_vars($del_obj);
1012
1013
	$target = array_keys($target_vars);
1014
	$del = array_keys($del_vars);
1015
	if(!count($target) || !count($del))
1016
	{
1017
		return $target_obj;
1018
	}
1019
1020
	$return_obj = new stdClass();
1021
1022
	$target_count = count($target);
1023
	for($i = 0; $i < $target_count; $i++)
1024
	{
1025
		$target_key = $target[$i];
1026
		if(!in_array($target_key, $del))
1027
		{
1028
			$return_obj->{$target_key} = $target_obj->{$target_key};
1029
		}
1030
	}
1031
1032
	return $return_obj;
1033
}
1034
1035
function getDestroyXeVars(&$vars)
1036
{
1037
	$del_vars = array('error_return_url', 'success_return_url', 'ruleset', 'xe_validator_id');
1038
1039
	foreach($del_vars as $var)
1040
	{
1041
		if(is_array($vars)) unset($vars[$var]);
1042
		else if(is_object($vars)) unset($vars->$var);
1043
	}
1044
1045
	return $vars;
1046
}
1047
1048
/**
1049
 * Change error_handing to debugPrint on php5 higher 
1050
 *
1051
 * @param int $errno
1052
 * @param string $errstr
1053
 * @param string $file
1054
 * @param int $line
1055
 * @return void
1056
 */
1057
function handleError($errno, $errstr, $file, $line)
1058
{
1059
	if(!__DEBUG__)
1060
	{
1061
		return;
1062
	}
1063
	$errors = array(E_USER_ERROR, E_ERROR, E_PARSE);
1064
	if(!in_array($errno, $errors))
1065
	{
1066
		return;
1067
	}
1068
1069
	$output = sprintf("Fatal error : %s - %d", $file, $line);
1070
	$output .= sprintf("%d - %s", $errno, $errstr);
1071
1072
	debugPrint($output);
1073
}
1074
1075
/**
1076
 * Trim a given number to a fiven size recursively
1077
 *
1078
 * @param int $no A given number
1079
 * @param int $size A given digits
1080
 */
1081
function getNumberingPath($no, $size = 3)
1082
{
1083
	$mod = pow(10, $size);
1084
	$output = sprintf('%0' . $size . 'd/', $no % $mod);
1085
	if($no >= $mod)
1086
	{
1087
		$output .= getNumberingPath((int) $no / $mod, $size);
1088
	}
1089
	return $output;
1090
}
1091
1092
/**
1093
 * Decode the URL in Korean
1094
 *
1095
 * @param string $str The url
1096
 * @return string
1097
 */
1098
function url_decode($str)
1099
{
1100
	return preg_replace('/%u([[:alnum:]]{4})/', '&#x\\1;', $str);
1101
}
1102
1103
function purifierHtml(&$content)
1104
{
1105
	require_once(_XE_PATH_ . 'classes/security/Purifier.class.php');
1106
	$oPurifier = Purifier::getInstance();
1107
1108
	// @see https://github.com/xpressengine/xe-core/issues/2278
1109
	$logged_info = Context::get('logged_info');
1110
	if($logged_info->is_admin !== 'Y') {
1111
		$oPurifier->setConfig('HTML.Nofollow', true);
1112
	}
1113
1114
	$oPurifier->purify($content);
1115
}
1116
1117
/**
1118
 * Pre-block the codes which may be hacking attempts
1119
 *
1120
 * @param string $content Taget content
1121
 * @return string
1122
 */
1123
function removeHackTag($content)
1124
{
1125
	require_once(_XE_PATH_ . 'classes/security/EmbedFilter.class.php');
1126
	$oEmbedFilter = EmbedFilter::getInstance();
1127
	$oEmbedFilter->check($content);
1128
1129
	purifierHtml($content);
1130
1131
	// change the specific tags to the common texts
1132
	$content = preg_replace('@<(\/?(?:html|body|head|title|meta|base|link|script|style|applet)(/*).*?>)@i', '&lt;$1', $content);
1133
1134
	/**
1135
	 * Remove codes to abuse the admin session in src by tags of imaages and video postings
1136
	 * - Issue reported by Sangwon Kim
1137
	 */
1138
	$content = preg_replace_callback('@<(/?)([a-z]+[0-9]?)((?>"[^"]*"|\'[^\']*\'|[^>])*?\b(?:on[a-z]+|data|style|background|href|(?:dyn|low)?src)\s*=[\s\S]*?)(/?)($|>|<)@i', 'removeSrcHack', $content);
1139
1140
	$content = checkXmpTag($content);
1141
	$content = blockWidgetCode($content);
1142
1143
	return $content;
1144
}
1145
1146
/**
1147
 * blocking widget code
1148
 *
1149
 * @param string $content Taget content
1150
 * @return string
1151
 **/
1152
function blockWidgetCode($content)
1153
{
1154
	$content = preg_replace('/(<(?:img|div)(?:[^>]*))(widget)(?:(=([^>]*?)>))/is', '$1blocked-widget$3', $content);
1155
1156
	return $content;
1157
}
1158
1159
/**
1160
 * check uploaded file which may be hacking attempts
1161
 *
1162
 * @param string $file Taget file path
1163
 * @return bool
1164
 */
1165
function checkUploadedFile($file, $filename = null)
1166
{
1167
	require_once(_XE_PATH_ . 'classes/security/UploadFileFilter.class.php');
1168
	return UploadFileFilter::check($file, $filename);
1169
}
1170
1171
/**
1172
 * Check xmp tag, close it.
1173
 *
1174
 * @param string $content Target content
1175
 * @return string
1176
 */
1177
function checkXmpTag($content)
1178
{
1179
	$content = preg_replace('@<(/?)xmp.*?>@i', '<\1xmp>', $content);
1180
1181
	if(($start_xmp = strrpos($content, '<xmp>')) !== FALSE)
1182
	{
1183
		if(($close_xmp = strrpos($content, '</xmp>')) === FALSE)
1184
		{
1185
			$content .= '</xmp>';
1186
		}
1187
		else if($close_xmp < $start_xmp)
1188
		{
1189
			$content .= '</xmp>';
1190
		}
1191
	}
1192
1193
	return $content;
1194
}
1195
1196
/**
1197
 * Remove src hack(preg_replace_callback)
1198
 *
1199
 * @param array $match
1200
 * @return string
1201
 */
1202
function removeSrcHack($match)
1203
{
1204
	$tag = strtolower($match[2]);
1205
1206
	// xmp tag ?뺣━
1207
	if($tag == 'xmp')
1208
	{
1209
		return "<{$match[1]}xmp>";
1210
	}
1211
	if($match[1])
1212
	{
1213
		return $match[0];
1214
	}
1215
	if($match[4])
1216
	{
1217
		$match[4] = ' ' . $match[4];
1218
	}
1219
1220
	$attrs = array();
1221
	if(preg_match_all('/([\w:-]+)\s*=(?:\s*(["\']))?(?(2)(.*?)\2|([^ ]+))/s', $match[3], $m))
1222
	{
1223
		foreach($m[1] as $idx => $name)
1224
		{
1225
			if(strlen($name) >= 2 && substr_compare($name, 'on', 0, 2) === 0)
1226
			{
1227
				continue;
1228
			}
1229
1230
			$val = preg_replace_callback('/&#(?:x([a-fA-F0-9]+)|0*(\d+));/', function($n) {return chr($n[1] ? ('0x00' . $n[1]) : ($n[2] + 0)); }, $m[3][$idx] . $m[4][$idx]);
1231
			$val = preg_replace('/^\s+|[\t\n\r]+/', '', $val);
1232
1233
			if(preg_match('/^[a-z]+script:/i', $val))
1234
			{
1235
				continue;
1236
			}
1237
1238
			$attrs[$name] = $val;
1239
		}
1240
	}
1241
1242
	$filter_arrts = array('style', 'src', 'href');
1243
1244
	if($tag === 'object') array_push($filter_arrts, 'data');
1245
	if($tag === 'param') array_push($filter_arrts, 'value');
1246
1247
	foreach($filter_arrts as $attr)
1248
	{
1249
		if(!isset($attrs[$attr])) continue;
1250
1251
		$attr_value = rawurldecode($attrs[$attr]);
1252
		$attr_value = htmlspecialchars_decode($attr_value, ENT_COMPAT);
1253
		$attr_value = preg_replace('/\s+|[\t\n\r]+/', '', $attr_value);
1254
		if(preg_match('@(\?|&|;)(act=(\w+))@i', $attr_value, $m) && $m[3] !== 'procFileDownload')
1255
		{
1256
			unset($attrs[$attr]);
1257
		}
1258
	}
1259
1260
	if(isset($attrs['style']) && preg_match('@(?:/\*|\*/|\n|:\s*expression\s*\()@i', $attrs['style']))
1261
	{
1262
		unset($attrs['style']);
1263
	}
1264
1265
	$attr = array();
1266
	foreach($attrs as $name => $val)
1267
	{
1268
		if($tag == 'object' || $tag == 'embed' || $tag == 'a')
1269
		{
1270
			$attribute = strtolower(trim($name));
1271
			if($attribute == 'data' || $attribute == 'src' || $attribute == 'href')
1272
			{
1273
				if(stripos($val, 'data:') === 0)
1274
				{
1275
					continue;
1276
				}
1277
			}
1278
		}
1279
1280
		if($tag == 'img')
1281
		{
1282
			$attribute = strtolower(trim($name));
0 ignored issues
show
Unused Code introduced by
$attribute 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...
1283
			if(stripos($val, 'data:') === 0)
1284
			{
1285
				continue;
1286
			}
1287
		}
1288
		$val = str_replace('"', '&quot;', $val);
1289
		$attr[] = $name . "=\"{$val}\"";
1290
	}
1291
	$attr = count($attr) ? ' ' . implode(' ', $attr) : '';
1292
1293
	return "<{$match[1]}{$tag}{$attr}{$match[4]}>";
1294
}
1295
1296
// convert hexa value to RGB
1297
if(!function_exists('hexrgb'))
1298
{
1299
1300
	/**
1301
	 * Convert hexa value to RGB
1302
	 *
1303
	 * @param string $hexstr
1304
	 * @return array
1305
	 */
1306
	function hexrgb($hexstr)
1307
	{
1308
		$int = hexdec($hexstr);
1309
1310
		return array('red' => 0xFF & ($int >> 0x10),
1311
			'green' => 0xFF & ($int >> 0x8),
1312
			'blue' => 0xFF & $int);
1313
	}
1314
1315
}
1316
1317
/**
1318
 * Php function for mysql old_password()
1319
 * provides backward compatibility for zero board4 which uses old_password() of mysql 4.1 earlier versions. 
1320
 * the function implemented by referring to the source codes of password.c file in mysql
1321
 *
1322
 * @param string $password
1323
 * @return string
1324
 */
1325
function mysql_pre4_hash_password($password)
1326
{
1327
	$nr = 1345345333;
1328
	$add = 7;
1329
	$nr2 = 0x12345671;
1330
1331
	settype($password, "string");
1332
1333
	for($i = 0; $i < strlen($password); $i++)
1334
	{
1335
		if($password[$i] == ' ' || $password[$i] == '\t')
1336
		{
1337
			continue;
1338
		}
1339
		$tmp = ord($password[$i]);
1340
		$nr ^= ((($nr & 63) + $add) * $tmp) + ($nr << 8);
1341
		$nr2 += ($nr2 << 8) ^ $nr;
1342
		$add += $tmp;
1343
	}
1344
	$result1 = sprintf("%08lx", $nr & ((1 << 31) - 1));
1345
	$result2 = sprintf("%08lx", $nr2 & ((1 << 31) - 1));
1346
1347
	if($result1 == '80000000')
1348
	{
1349
		$nr += 0x80000000;
1350
	}
1351
	if($result2 == '80000000')
1352
	{
1353
		$nr2 += 0x80000000;
1354
	}
1355
1356
	return sprintf("%08lx%08lx", $nr, $nr2);
1357
}
1358
1359
/**
1360
 * Return the requested script path
1361
 *
1362
 * @return string
1363
 */
1364
function getScriptPath()
1365
{
1366
	static $url = NULL;
1367
	if($url == NULL)
1368
	{
1369
		$script_path = filter_var($_SERVER['SCRIPT_NAME'], FILTER_SANITIZE_STRING);
1370
		$url = str_ireplace('/tools/', '/', preg_replace('/index.php.*/i', '', str_replace('\\', '/', $script_path)));
1371
	}
1372
	return $url;
1373
}
1374
1375
/**
1376
 * Return the requested script path
1377
 *
1378
 * @return string
1379
 */
1380
function getRequestUriByServerEnviroment()
1381
{
1382
	return str_replace('<', '&lt;', preg_replace('/[<>"]/', '', $_SERVER['REQUEST_URI']));
1383
}
1384
1385
/**
1386
 * PHP unescape function of javascript's escape
1387
 * Function converts an Javascript escaped string back into a string with specified charset (default is UTF-8).
1388
 * Modified function from http://pure-essence.net/stuff/code/utf8RawUrlDecode.phps
1389
 *
1390
 * @param string $source
1391
 * @return string
1392
 */
1393
function utf8RawUrlDecode($source)
1394
{
1395
	$decodedStr = '';
1396
	$pos = 0;
1397
	$len = strlen($source);
1398
	while($pos < $len)
1399
	{
1400
		$charAt = substr($source, $pos, 1);
1401
		if($charAt == '%')
1402
		{
1403
			$pos++;
1404
			$charAt = substr($source, $pos, 1);
1405
			if($charAt == 'u')
1406
			{
1407
				// we got a unicode character
1408
				$pos++;
1409
				$unicodeHexVal = substr($source, $pos, 4);
1410
				$unicode = hexdec($unicodeHexVal);
1411
				$decodedStr .= _code2utf($unicode);
1412
				$pos += 4;
1413
			}
1414
			else
1415
			{
1416
				// we have an escaped ascii character
1417
				$hexVal = substr($source, $pos, 2);
1418
				$decodedStr .= chr(hexdec($hexVal));
1419
				$pos += 2;
1420
			}
1421
		}
1422
		else
1423
		{
1424
			$decodedStr .= $charAt;
1425
			$pos++;
1426
		}
1427
	}
1428
	return $decodedStr;
1429
}
1430
1431
/**
1432
 * Returns utf-8 string of given code
1433
 *
1434
 * @param int $num
1435
 * @return string
1436
 */
1437
function _code2utf($num)
1438
{
1439
	if($num < 128)
1440
	{
1441
		return chr($num);
1442
	}
1443
	if($num < 2048)
1444
	{
1445
		return chr(($num >> 6) + 192) . chr(($num & 63) + 128);
1446
	}
1447
	if($num < 65536)
1448
	{
1449
		return chr(($num >> 12) + 224) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
1450
	}
1451
	if($num < 2097152)
1452
	{
1453
		return chr(($num >> 18) + 240) . chr((($num >> 12) & 63) + 128) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
1454
	}
1455
	return '';
1456
}
1457
1458
/**
1459
 * Get whether utf8 or not given string
1460
 *
1461
 * @param string $string
1462
 * @param bool $return_convert If set, returns converted string
1463
 * @param bool $urldecode
1464
 * @return bool|string
1465
 */
1466
function detectUTF8($string, $return_convert = FALSE, $urldecode = TRUE)
1467
{
1468
	if($urldecode)
1469
	{
1470
		$string = urldecode($string);
1471
	}
1472
1473
	$sample = iconv('utf-8', 'utf-8', $string);
1474
	$is_utf8 = (md5($sample) === md5($string));
1475
1476
	if(!$urldecode)
1477
	{
1478
		$string = urldecode($string);
1479
	}
1480
1481
	if($return_convert)
1482
	{
1483
		return ($is_utf8) ? $string : iconv('euc-kr', 'utf-8', $string);
1484
	}
1485
1486
	return $is_utf8;
1487
}
1488
1489
/**
1490
 * get json encoded string of data
1491
 *
1492
 * @param mixed $data
1493
 * @return string
1494
 */
1495
function json_encode2($data)
1496
{
1497
	switch(gettype($data))
1498
	{
1499
		case 'boolean':
1500
			return $data ? 'true' : 'false';
1501
		case 'integer':
1502
		case 'double':
1503
			return $data;
1504
		case 'string':
1505
			return '"' . strtr($data, array('\\' => '\\\\', '"' => '\\"')) . '"';
1506
		case 'object':
1507
			$data = get_object_vars($data);
1508
		case 'array':
1509
			$rel = FALSE; // relative array?
1510
			$key = array_keys($data);
1511
			foreach($key as $v)
1512
			{
1513
				if(!is_int($v))
1514
				{
1515
					$rel = TRUE;
1516
					break;
1517
				}
1518
			}
1519
1520
			$arr = array();
1521
			foreach($data as $k => $v)
1522
			{
1523
				$arr[] = ($rel ? '"' . strtr($k, array('\\' => '\\\\', '"' => '\\"')) . '":' : '') . json_encode2($v);
1524
			}
1525
1526
			return $rel ? '{' . join(',', $arr) . '}' : '[' . join(',', $arr) . ']';
1527
		default:
1528
			return '""';
1529
	}
1530
}
1531
1532
/**
1533
 * Get is current user crawler
1534
 *
1535
 * @param string $agent if set, use this value instead HTTP_USER_AGENT
1536
 * @return bool
1537
 */
1538
function isCrawler($agent = NULL)
1539
{
1540
	if(!$agent)
0 ignored issues
show
Bug Best Practice introduced by
The expression $agent 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...
1541
	{
1542
		$agent = $_SERVER['HTTP_USER_AGENT'];
1543
	}
1544
1545
	$check_agent = array('bot', 'spider', 'spyder', 'crawl', 'http://', 'google', 'yahoo', 'slurp', 'yeti', 'daum', 'teoma', 'fish', 'hanrss', 'facebook', 'yandex', 'infoseek', 'askjeeves', 'stackrambler');
1546
	$check_ip = array(
1547
		/*'211.245.21.110-211.245.21.119' mixsh is closed */
1548
	);
1549
1550
	foreach($check_agent as $str)
1551
	{
1552
		if(stristr($agent, $str) != FALSE)
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing stristr($agent, $str) of type string to the boolean FALSE. If you are specifically checking for a non-empty string, consider using the more explicit !== '' instead.
Loading history...
1553
		{
1554
			return TRUE;
1555
		}
1556
	}
1557
1558
	return IpFilter::filter($check_ip);
1559
}
1560
1561
/**
1562
 * Remove embed media for admin
1563
 *
1564
 * @param string $content
1565
 * @param int $writer_member_srl
1566
 * @return void
1567
 */
1568
function stripEmbedTagForAdmin(&$content, $writer_member_srl)
1569
{
1570
	if(!Context::get('is_logged'))
1571
	{
1572
		return;
1573
	}
1574
1575
	$oModuleModel = getModel('module');
1576
	$logged_info = Context::get('logged_info');
1577
1578
	if($writer_member_srl != $logged_info->member_srl && ($logged_info->is_admin == "Y" || $oModuleModel->isSiteAdmin($logged_info)))
1579
	{
1580
		if($writer_member_srl)
1581
		{
1582
			$oMemberModel = getModel('member');
1583
			$member_info = $oMemberModel->getMemberInfoByMemberSrl($writer_member_srl);
1584
			if($member_info->is_admin == "Y")
1585
			{
1586
				return;
1587
			}
1588
		}
1589
		$security_msg = "<div style='border: 1px solid #DDD; background: #FAFAFA; text-align:center; margin: 1em 0;'><p style='margin: 1em;'>" . Context::getLang('security_warning_embed') . "</p></div>";
1590
		$content = preg_replace('/<object[^>]+>(.*?<\/object>)?/is', $security_msg, $content);
1591
		$content = preg_replace('/<embed[^>]+>(\s*<\/embed>)?/is', $security_msg, $content);
1592
		$content = preg_replace('/<img[^>]+editor_component="multimedia_link"[^>]*>(\s*<\/img>)?/is', $security_msg, $content);
1593
	}
1594
1595
	return;
1596
}
1597
1598
/**
1599
 * Require pear
1600
 *
1601
 * @return void
1602
 */
1603
function requirePear()
1604
{
1605
	static $required = false;
1606
	if($required)
1607
	{
1608
		return;
1609
	}
1610
1611
	if(version_compare(PHP_VERSION, "5.3.0") < 0)
1612
	{
1613
		set_include_path(_XE_PATH_ . "libs/PEAR" . PATH_SEPARATOR . get_include_path());
1614
	}
1615
	else
1616
	{
1617
		set_include_path(_XE_PATH_ . "libs/PEAR.1.9.5" . PATH_SEPARATOR . get_include_path());
1618
	}
1619
1620
	$required = true;
1621
}
1622
1623
function checkCSRF()
1624
{
1625
	if($_SERVER['REQUEST_METHOD'] != 'POST')
1626
	{
1627
		return FALSE;
1628
	}
1629
1630
	$default_url = Context::getDefaultUrl();
1631
	$referer = $_SERVER["HTTP_REFERER"];
1632
1633
	if(strpos($default_url, 'xn--') !== FALSE && strpos($referer, 'xn--') === FALSE)
1634
	{
1635
		require_once(_XE_PATH_ . 'libs/idna_convert/idna_convert.class.php');
1636
		$IDN = new idna_convert(array('idn_version' => 2008));
1637
		$referer = $IDN->encode($referer);
1638
	}
1639
1640
	$default_url = parse_url($default_url);
1641
	$referer = parse_url($referer);
1642
1643
	$oModuleModel = getModel('module');
1644
	$siteModuleInfo = $oModuleModel->getDefaultMid();
1645
1646
	if($siteModuleInfo->site_srl == 0)
1647
	{
1648
		if($default_url['host'] !== $referer['host'])
1649
		{
1650
			return FALSE;
1651
		}
1652
	}
1653
	else
1654
	{
1655
		$virtualSiteInfo = $oModuleModel->getSiteInfo($siteModuleInfo->site_srl);
1656
		if(strtolower($virtualSiteInfo->domain) != strtolower(Context::get('vid')) && !strstr(strtolower($virtualSiteInfo->domain), strtolower($referer['host'])))
1657
		{
1658
			return FALSE;
1659
		}
1660
	}
1661
1662
	return TRUE;
1663
}
1664
1665
/**
1666
 * menu exposure check by isShow column
1667
 * @param array $menu
1668
 * @return void
1669
 */
1670
function recurciveExposureCheck(&$menu)
1671
{
1672
	if(is_array($menu))
1673
	{
1674
		foreach($menu AS $key=>$value)
1675
		{
1676
			if(!$value['isShow'])
1677
			{
1678
				unset($menu[$key]);
1679
			}
1680
			if(is_array($value['list']) && count($value['list']) > 0)
1681
			{
1682
				recurciveExposureCheck($menu[$key]['list']);
1683
			}
1684
		}
1685
	}
1686
}
1687
1688
function changeValueInUrl($key, $requestKey, $dbKey, $urlName = 'success_return_url')
1689
{
1690
	if($requestKey != $dbKey)
1691
	{
1692
		$arrayUrl = parse_url(Context::get('success_return_url'));
1693
		if($arrayUrl['query'])
1694
		{
1695
			parse_str($arrayUrl['query'], $parsedStr);
1696
1697
			if(isset($parsedStr[$key]))
1698
			{
1699
				$parsedStr[$key] = $requestKey;
1700
				$successReturnUrl .= $arrayUrl['path'].'?'.http_build_query($parsedStr);
0 ignored issues
show
Bug introduced by
The variable $successReturnUrl does not exist. Did you forget to declare it?

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

Loading history...
1701
				Context::set($urlName, $successReturnUrl);
1702
			}
1703
		}
1704
	}
1705
}
1706
1707
/**
1708
 * Print raw html header
1709
 *
1710
 * @return void
1711
 */
1712
function htmlHeader()
1713
{
1714
	echo '<!DOCTYPE html>
1715
<html lang="ko">
1716
<head>
1717
<meta charset="utf-8" />
1718
</head>
1719
<body>';
1720
}
1721
1722
/**
1723
 * Print raw html footer
1724
 *
1725
 * @return void
1726
 */
1727
function htmlFooter()
1728
{
1729
	echo '</body></html>';
1730
}
1731
1732
/**
1733
 * Print raw alert message script
1734
 *
1735
 * @param string $msg
1736
 * @return void
1737
 */
1738
function alertScript($msg)
1739
{
1740
	if(!$msg)
1741
	{
1742
		return;
1743
	}
1744
1745
	echo '<script type="text/javascript">
1746
//<![CDATA[
1747
alert("' . $msg . '");
1748
//]]>
1749
</script>';
1750
}
1751
1752
/**
1753
 * Print raw close window script
1754
 *
1755
 * @return void
1756
 */
1757
function closePopupScript()
1758
{
1759
	echo '<script type="text/javascript">
1760
//<![CDATA[
1761
window.close();
1762
//]]>
1763
</script>';
1764
}
1765
1766
/**
1767
 * Print raw reload script
1768
 *
1769
 * @param bool $isOpener
1770
 * @return void
1771
 */
1772
function reload($isOpener = FALSE)
1773
{
1774
	$reloadScript = $isOpener ? 'window.opener.location.reload()' : 'document.location.reload()';
1775
1776
	echo '<script type="text/javascript">
1777
//<![CDATA[
1778
' . $reloadScript . '
1779
//]]>
1780
</script>';
1781
}
1782
1783
1784
function isDefinedLangCode($str)
1785
{
1786
	return preg_match('!^\$user_lang->([a-z0-9\_]+)$!is', trim($str));
1787
}
1788
1789
/**
1790
 * This function is a shortcut to htmlspecialchars().
1791
 *
1792
 * @copyright Rhymix Developers and Contributors
1793
 * @link https://github.com/rhymix/rhymix
1794
 *
1795
 * @param string $str The string to escape
1796
 * @param bool $double_escape Set this to false to skip symbols that are already escaped (default: true)
1797
 * @return string
1798
 */
1799
function escape($str, $double_escape = true, $escape_defined_lang_code = false)
1800
{
1801
	if(!$escape_defined_lang_code && isDefinedLangCode($str)) return $str;
1802
1803
	$flags = ENT_QUOTES | ENT_SUBSTITUTE;
1804
	return htmlspecialchars($str, $flags, 'UTF-8', $double_escape);
1805
}
1806
1807
/**
1808
 * This function escapes a string to be used in a CSS property.
1809
 *
1810
 * @copyright Rhymix Developers and Contributors
1811
 * @link https://github.com/rhymix/rhymix
1812
 *
1813
 * @param string $str The string to escape
1814
 * @return string
1815
 */
1816
function escape_css($str)
1817
{
1818
	return preg_replace('/[^a-zA-Z0-9_.#\/-]/', '', $str);
1819
}
1820
1821
/**
1822
 * This function escapes a string to be used in a JavaScript string literal.
1823
 *
1824
 * @copyright Rhymix Developers and Contributors
1825
 * @link https://github.com/rhymix/rhymix
1826
 *
1827
 * @param string $str The string to escape
1828
 * @return string
1829
 */
1830
function escape_js($str)
1831
{
1832
	$flags = JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_UNESCAPED_UNICODE;
1833
	$str = json_encode((string)$str, $flags);
1834
	return substr($str, 1, strlen($str) - 2);
1835
}
1836
1837
/**
1838
 * This function escapes a string to be used in a 'single-quoted' PHP string literal.
1839
 * Null bytes are removed.
1840
 *
1841
 * @copyright Rhymix Developers and Contributors
1842
 * @link https://github.com/rhymix/rhymix
1843
 *
1844
 * @param string $str The string to escape
1845
 * @return string
1846
 */
1847
function escape_sqstr($str)
1848
{
1849
	return str_replace(array('\\0', '\\"'), array('', '"'), addslashes($str));
1850
}
1851
1852
/**
1853
 * This function escapes a string to be used in a "double-quoted" PHP string literal.
1854
 * Null bytes are removed.
1855
 *
1856
 * @copyright Rhymix Developers and Contributors
1857
 * @link https://github.com/rhymix/rhymix
1858
 *
1859
 * @param string $str The string to escape
1860
 * @return string
1861
 */
1862
function escape_dqstr($str)
1863
{
1864
	return str_replace(array('\\0', "\\'", '$'), array('', "'", '\\$'), addslashes($str));
1865
}
1866
1867
/**
1868
 * This function splits a string into an array, but allows the delimter to be escaped.
1869
 * For example, 'A|B\|C|D' will be split into 'A', 'B|C', and 'D'
1870
 * because the bar between B and C is escaped.
1871
 *
1872
 * @copyright Rhymix Developers and Contributors
1873
 * @link https://github.com/rhymix/rhymix
1874
 *
1875
 * @param string $delimiter The delimiter
1876
 * @param string $str The string to split
1877
 * @param int $limit The maximum number of items to return, 0 for unlimited (default: 0)
1878
 * @param string $escape_char The escape character (default: backslash)
1879
 * @return array
1880
 */
1881
function explode_with_escape($delimiter, $str, $limit = 0, $escape_char = '\\')
1882
{
1883
	if ($limit < 1) $limit = null;
1884
	$result = array();
1885
	$split = preg_split('/(?<!' . preg_quote($escape_char, '/') . ')' . preg_quote($delimiter, '/') . '/', $str, $limit);
1886
	foreach ($split as $piece)
1887
	{
1888
		if (trim($piece) !== '')
1889
		{
1890
			$result[] = trim(str_replace($escape_char . $delimiter, $delimiter, $piece));
1891
		}
1892
	}
1893
	return $result;
1894
}
1895
1896
1897
/* End of file func.inc.php */
1898
/* Location: ./config/func.inc.php */
1899