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 & 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() |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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) |
|
|
|
|
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']); |
|
|
|
|
822
|
|
|
$line_num = $bt_debug_print['line']; |
823
|
|
|
$function = $bt_called_function['class'] . $bt_called_function['type'] . $bt_called_function['function']; |
|
|
|
|
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); |
|
|
|
|
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', '<$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)); |
|
|
|
|
1283
|
|
|
if(stripos($val, 'data:') === 0) |
1284
|
|
|
{ |
1285
|
|
|
continue; |
1286
|
|
|
} |
1287
|
|
|
} |
1288
|
|
|
$val = str_replace('"', '"', $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('<', '<', 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) |
|
|
|
|
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) |
|
|
|
|
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); |
|
|
|
|
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
|
|
|
|
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.