1
|
|
|
<?php |
2
|
|
|
/* |
3
|
|
|
* 2007-2012 PrestaShop |
4
|
|
|
* |
5
|
|
|
* NOTICE OF LICENSE |
6
|
|
|
* |
7
|
|
|
* This source file is subject to the Open Software License (OSL 3.0) |
8
|
|
|
* that is bundled with this package in the file LICENSE.txt. |
9
|
|
|
* It is also available through the world-wide-web at this URL: |
10
|
|
|
* http://opensource.org/licenses/osl-3.0.php |
11
|
|
|
* If you did not receive a copy of the license and are unable to |
12
|
|
|
* obtain it through the world-wide-web, please send an email |
13
|
|
|
* to [email protected] so we can send you a copy immediately. |
14
|
|
|
* |
15
|
|
|
* DISCLAIMER |
16
|
|
|
* |
17
|
|
|
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer |
18
|
|
|
* versions in the future. If you wish to customize PrestaShop for your |
19
|
|
|
* needs please refer to http://www.prestashop.com for more information. |
20
|
|
|
* |
21
|
|
|
* @author PrestaShop SA <[email protected]> |
22
|
|
|
* @copyright 2007-2012 PrestaShop SA |
23
|
|
|
* @version Release: $Revision: 14204 $ |
24
|
|
|
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) |
25
|
|
|
* International Registered Trademark & Property of PrestaShop SA |
26
|
|
|
*/ |
27
|
|
|
|
28
|
|
|
class Tools |
29
|
|
|
{ |
30
|
|
|
protected static $file_exists_cache = array(); |
31
|
|
|
protected static $_forceCompile; |
32
|
|
|
protected static $_caching; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* Random password generator |
36
|
|
|
* |
37
|
|
|
* @param integer $length Desired length (optional) |
38
|
|
|
* @return string Password |
39
|
|
|
*/ |
40
|
|
|
public static function passwdGen($length = 8) |
41
|
|
|
{ |
42
|
|
|
$str = 'abcdefghijkmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; |
43
|
|
|
for ($i = 0, $passwd = ''; $i < $length; $i++) |
44
|
|
|
$passwd .= self::substr($str, mt_rand(0, self::strlen($str) - 1), 1); |
|
|
|
|
45
|
|
|
return $passwd; |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* Redirect user to another page |
50
|
|
|
* |
51
|
|
|
* @param string $url Desired URL |
52
|
|
|
* @param string $baseUri Base URI (optional) |
53
|
|
|
*/ |
54
|
|
|
public static function redirect($url, $baseUri = __PS_BASE_URI__) |
|
|
|
|
55
|
|
|
{ |
56
|
|
|
if (strpos($url, 'http://') === FALSE && strpos($url, 'https://') === FALSE) |
57
|
|
|
{ |
58
|
|
|
global $link; |
59
|
|
|
if (strpos($url, $baseUri) !== FALSE && strpos($url, $baseUri) == 0) |
60
|
|
|
$url = substr($url, strlen($baseUri)); |
61
|
|
|
$explode = explode('?', $url, 2); |
62
|
|
|
// don't use ssl if url is home page |
63
|
|
|
// used when logout for example |
64
|
|
|
$useSSL = !empty($url); |
65
|
|
|
$url = $link->getPageLink($explode[0], $useSSL); |
66
|
|
|
if (isset($explode[1])) |
67
|
|
|
$url .= '?'.$explode[1]; |
68
|
|
|
$baseUri = ''; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
if (isset($_SERVER['HTTP_REFERER']) AND ($url == $_SERVER['HTTP_REFERER'])) |
72
|
|
|
header('Location: '.$_SERVER['HTTP_REFERER']); |
73
|
|
|
else |
74
|
|
|
header('Location: '.$baseUri.$url); |
75
|
|
|
exit; |
|
|
|
|
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* Redirect url wich allready PS_BASE_URI |
80
|
|
|
* |
81
|
|
|
* @param string $url Desired URL |
82
|
|
|
*/ |
83
|
|
|
public static function redirectLink($url) |
84
|
|
|
{ |
85
|
|
|
if (!preg_match('@^https?://@i', $url)) |
86
|
|
|
{ |
87
|
|
|
global $link; |
88
|
|
|
if (strpos($url, __PS_BASE_URI__) !== FALSE && strpos($url, __PS_BASE_URI__) == 0) |
89
|
|
|
$url = substr($url, strlen(__PS_BASE_URI__)); |
90
|
|
|
$explode = explode('?', $url, 2); |
91
|
|
|
$url = $link->getPageLink($explode[0]); |
92
|
|
|
if (isset($explode[1])) |
93
|
|
|
$url .= '?'.$explode[1]; |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
header('Location: '.$url); |
97
|
|
|
exit; |
|
|
|
|
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* Redirect user to another admin page |
102
|
|
|
* |
103
|
|
|
* @param string $url Desired URL |
104
|
|
|
*/ |
105
|
|
|
public static function redirectAdmin($url) |
106
|
|
|
{ |
107
|
|
|
header('Location: '.$url); |
108
|
|
|
exit; |
|
|
|
|
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* getProtocol return the set protocol according to configuration (http[s]) |
113
|
|
|
* @param Boolean true if require ssl |
114
|
|
|
* @return String (http|https) |
115
|
|
|
*/ |
116
|
|
|
public static function getProtocol($use_ssl = null) |
117
|
|
|
{ |
118
|
|
|
return (!is_null($use_ssl) && $use_ssl ? 'https://' : 'http://'); |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* getHttpHost return the <b>current</b> host used, with the protocol (http or https) if $http is true |
123
|
|
|
* This function should not be used to choose http or https domain name. |
124
|
|
|
* Use Tools::getShopDomain() or Tools::getShopDomainSsl instead |
125
|
|
|
* |
126
|
|
|
* @param boolean $http |
127
|
|
|
* @param boolean $entities |
128
|
|
|
* @return string host |
129
|
|
|
*/ |
130
|
|
|
public static function getHttpHost($http = false, $entities = false) |
|
|
|
|
131
|
|
|
{ |
132
|
|
|
$host = (isset($_SERVER['HTTP_X_FORWARDED_HOST']) ? $_SERVER['HTTP_X_FORWARDED_HOST'] : $_SERVER['HTTP_HOST']); |
133
|
|
|
if ($entities) |
134
|
|
|
$host = htmlspecialchars($host, ENT_COMPAT, 'UTF-8'); |
135
|
|
|
if ($http) |
136
|
|
|
$host = (Configuration::get('PS_SSL_ENABLED') ? 'https://' : 'http://').$host; |
137
|
|
|
return $host; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* getShopDomain returns domain name according to configuration and ignoring ssl |
142
|
|
|
* |
143
|
|
|
* @param boolean $http if true, return domain name with protocol |
144
|
|
|
* @param boolean $entities if true, |
145
|
|
|
* @return string domain |
146
|
|
|
*/ |
147
|
|
|
public static function getShopDomain($http = false, $entities = false) |
148
|
|
|
{ |
149
|
|
|
if (!($domain = Configuration::get('PS_SHOP_DOMAIN'))) |
150
|
|
|
$domain = self::getHttpHost(); |
151
|
|
|
if ($entities) |
152
|
|
|
$domain = htmlspecialchars($domain, ENT_COMPAT, 'UTF-8'); |
153
|
|
|
if ($http) |
154
|
|
|
$domain = 'http://'.$domain; |
155
|
|
|
return $domain; |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* getShopDomainSsl returns domain name according to configuration and depending on ssl activation |
160
|
|
|
* |
161
|
|
|
* @param boolean $http if true, return domain name with protocol |
162
|
|
|
* @param boolean $entities if true, |
163
|
|
|
* @return string domain |
164
|
|
|
*/ |
165
|
|
|
public static function getShopDomainSsl($http = false, $entities = false) |
166
|
|
|
{ |
167
|
|
|
if (!($domain = Configuration::get('PS_SHOP_DOMAIN_SSL'))) |
168
|
|
|
$domain = self::getHttpHost(); |
169
|
|
|
if ($entities) |
170
|
|
|
$domain = htmlspecialchars($domain, ENT_COMPAT, 'UTF-8'); |
171
|
|
|
if ($http) |
172
|
|
|
$domain = (Configuration::get('PS_SSL_ENABLED') ? 'https://' : 'http://').$domain; |
173
|
|
|
return $domain; |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
/** |
177
|
|
|
* Get the server variable SERVER_NAME |
178
|
|
|
* |
179
|
|
|
* @return string server name |
180
|
|
|
*/ |
181
|
|
|
static function getServerName() |
|
|
|
|
182
|
|
|
{ |
183
|
|
|
if (isset($_SERVER['HTTP_X_FORWARDED_SERVER']) AND $_SERVER['HTTP_X_FORWARDED_SERVER']) |
184
|
|
|
return $_SERVER['HTTP_X_FORWARDED_SERVER']; |
185
|
|
|
return $_SERVER['SERVER_NAME']; |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* Get the server variable REMOTE_ADDR, or the first ip of HTTP_X_FORWARDED_FOR (when using proxy) |
190
|
|
|
* |
191
|
|
|
* @return string $remote_addr ip of client |
192
|
|
|
*/ |
193
|
|
|
static function getRemoteAddr() |
|
|
|
|
194
|
|
|
{ |
195
|
|
|
// This condition is necessary when using CDN, don't remove it. |
196
|
|
|
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND $_SERVER['HTTP_X_FORWARDED_FOR'] AND (!isset($_SERVER['REMOTE_ADDR']) OR preg_match('/^127\..*/i', trim($_SERVER['REMOTE_ADDR'])) OR preg_match('/^172\.16.*/i', trim($_SERVER['REMOTE_ADDR'])) OR preg_match('/^192\.168\.*/i', trim($_SERVER['REMOTE_ADDR'])) OR preg_match('/^10\..*/i', trim($_SERVER['REMOTE_ADDR'])))) |
197
|
|
|
{ |
198
|
|
|
if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',')) |
199
|
|
|
{ |
200
|
|
|
$ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); |
201
|
|
|
return $ips[0]; |
202
|
|
|
} |
203
|
|
|
else |
204
|
|
|
return $_SERVER['HTTP_X_FORWARDED_FOR']; |
205
|
|
|
} |
206
|
|
|
return $_SERVER['REMOTE_ADDR']; |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
/** |
210
|
|
|
* Check if the current page use SSL connection on not |
211
|
|
|
* |
212
|
|
|
* @return bool uses SSL |
213
|
|
|
*/ |
214
|
|
|
public static function usingSecureMode() |
|
|
|
|
215
|
|
|
{ |
216
|
|
|
if (isset($_SERVER['HTTPS'])) |
217
|
|
|
return ($_SERVER['HTTPS'] == 1 || strtolower($_SERVER['HTTPS']) == 'on'); |
218
|
|
|
// $_SERVER['SSL'] exists only in some specific configuration |
219
|
|
|
if (isset($_SERVER['SSL'])) |
220
|
|
|
return ($_SERVER['SSL'] == 1 || strtolower($_SERVER['SSL']) == 'on'); |
221
|
|
|
|
222
|
|
|
return false; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* Get the current url prefix protocol (https/http) |
227
|
|
|
* |
228
|
|
|
* @return string protocol |
229
|
|
|
*/ |
230
|
|
|
public static function getCurrentUrlProtocolPrefix() |
231
|
|
|
{ |
232
|
|
|
if (self::usingSecureMode()) |
233
|
|
|
return 'https://'; |
234
|
|
|
else |
235
|
|
|
return 'http://'; |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
/** |
239
|
|
|
* Secure an URL referrer |
240
|
|
|
* |
241
|
|
|
* @param string $referrer URL referrer |
242
|
|
|
* @return secured referrer |
243
|
|
|
*/ |
244
|
|
|
public static function secureReferrer($referrer) |
245
|
|
|
{ |
246
|
|
|
if (preg_match('/^http[s]?:\/\/'.self::getServerName().'(:'._PS_SSL_PORT_.')?\/.*$/Ui', $referrer)) |
247
|
|
|
return $referrer; |
|
|
|
|
248
|
|
|
return __PS_BASE_URI__; |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
/** |
252
|
|
|
* Get a value from $_POST / $_GET |
253
|
|
|
* if unavailable, take a default value |
254
|
|
|
* |
255
|
|
|
* @param string $key Value key |
256
|
|
|
* @param mixed $defaultValue (optional) |
257
|
|
|
* @return mixed Value |
258
|
|
|
*/ |
259
|
|
|
public static function getValue($key, $defaultValue = false) |
|
|
|
|
260
|
|
|
{ |
261
|
|
|
if (!isset($key) OR empty($key) OR !is_string($key)) |
262
|
|
|
return false; |
263
|
|
|
$ret = (isset($_POST[$key]) ? $_POST[$key] : (isset($_GET[$key]) ? $_GET[$key] : $defaultValue)); |
264
|
|
|
|
265
|
|
|
if (is_string($ret) === true) |
266
|
|
|
$ret = stripslashes(urldecode(preg_replace('/((\%5C0+)|(\%00+))/i', '', urlencode($ret)))); |
267
|
|
|
elseif (is_array($ret)) |
268
|
|
|
$ret = Tools::getArrayValue($ret); |
269
|
|
|
|
270
|
|
|
return $ret; |
271
|
|
|
} |
272
|
|
|
|
273
|
|
|
/** |
274
|
|
|
* Escape values contained in an array |
275
|
|
|
* |
276
|
|
|
* @param array $array Value array |
277
|
|
|
* @return mixed Value |
278
|
|
|
*/ |
279
|
|
|
public static function getArrayValue($array) |
280
|
|
|
{ |
281
|
|
|
foreach ($array as &$row) |
282
|
|
|
{ |
283
|
|
|
if (is_array($row)) |
284
|
|
|
$row = Tools::getArrayValue($row); |
285
|
|
|
else |
286
|
|
|
$row = stripslashes(urldecode(preg_replace('/((\%5C0+)|(\%00+))/i', '', urlencode($row)))); |
287
|
|
|
} |
288
|
|
|
|
289
|
|
|
return $array; |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
public static function getIsset($key) |
|
|
|
|
293
|
|
|
{ |
294
|
|
|
if (!isset($key) OR empty($key) OR !is_string($key)) |
295
|
|
|
return false; |
296
|
|
|
return isset($_POST[$key]) ? true : (isset($_GET[$key]) ? true : false); |
297
|
|
|
} |
298
|
|
|
|
299
|
|
|
/** |
300
|
|
|
* Change language in cookie while clicking on a flag |
301
|
|
|
* |
302
|
|
|
* @return string iso code |
303
|
|
|
*/ |
304
|
|
|
public static function setCookieLanguage() |
|
|
|
|
305
|
|
|
{ |
306
|
|
|
global $cookie; |
307
|
|
|
|
308
|
|
|
/* If language does not exist or is disabled, erase it */ |
309
|
|
|
if ($cookie->id_lang) |
310
|
|
|
{ |
311
|
|
|
$lang = new Language((int)$cookie->id_lang); |
312
|
|
|
if (!Validate::isLoadedObject($lang) OR !$lang->active) |
313
|
|
|
$cookie->id_lang = NULL; |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
/* Automatically detect language if not already defined */ |
317
|
|
|
if (!$cookie->id_lang AND isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) |
318
|
|
|
{ |
319
|
|
|
$array = explode(',', self::strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE'])); |
320
|
|
|
if (self::strlen($array[0]) > 2) |
321
|
|
|
{ |
322
|
|
|
$tab = explode('-', $array[0]); |
323
|
|
|
$string = $tab[0]; |
324
|
|
|
} |
325
|
|
|
else |
326
|
|
|
$string = $array[0]; |
327
|
|
|
if (Validate::isLanguageIsoCode($string)) |
328
|
|
|
{ |
329
|
|
|
$lang = new Language((int)(Language::getIdByIso($string))); |
330
|
|
|
if (Validate::isLoadedObject($lang) AND $lang->active) |
331
|
|
|
$cookie->id_lang = (int)($lang->id); |
332
|
|
|
} |
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
/* If language file not present, you must use default language file */ |
336
|
|
|
if (!$cookie->id_lang OR !Validate::isUnsignedId($cookie->id_lang)) |
337
|
|
|
$cookie->id_lang = (int)(Configuration::get('PS_LANG_DEFAULT')); |
338
|
|
|
|
339
|
|
|
$iso = Language::getIsoById((int)$cookie->id_lang); |
340
|
|
|
@include_once(_PS_THEME_DIR_.'lang/'.$iso.'.php'); |
|
|
|
|
341
|
|
|
|
342
|
|
|
return $iso; |
343
|
|
|
} |
344
|
|
|
|
345
|
|
|
/** |
346
|
|
|
* Set cookie id_lang |
347
|
|
|
*/ |
348
|
|
|
public static function switchLanguage() |
349
|
|
|
{ |
350
|
|
|
global $cookie; |
351
|
|
|
|
352
|
|
|
if ($id_lang = (int)(self::getValue('id_lang')) AND Validate::isUnsignedId($id_lang)) |
353
|
|
|
$cookie->id_lang = $id_lang; |
354
|
|
|
} |
355
|
|
|
|
356
|
|
|
/** |
357
|
|
|
* Set cookie currency from POST or default currency |
358
|
|
|
* |
359
|
|
|
* @return Currency object |
360
|
|
|
*/ |
361
|
|
|
public static function setCurrency() |
|
|
|
|
362
|
|
|
{ |
363
|
|
|
global $cookie; |
364
|
|
|
|
365
|
|
|
if (self::isSubmit('SubmitCurrency')) |
366
|
|
|
if (isset($_POST['id_currency']) AND is_numeric($_POST['id_currency'])) |
367
|
|
|
{ |
368
|
|
|
$currency = Currency::getCurrencyInstance((int)($_POST['id_currency'])); |
369
|
|
|
if (is_object($currency) AND $currency->id AND !$currency->deleted) |
370
|
|
|
$cookie->id_currency = (int)($currency->id); |
371
|
|
|
} |
372
|
|
|
|
373
|
|
|
if ((int)$cookie->id_currency) |
374
|
|
|
{ |
375
|
|
|
$currency = Currency::getCurrencyInstance((int)$cookie->id_currency); |
376
|
|
|
if (is_object($currency) AND (int)$currency->id AND (int)$currency->deleted != 1 AND $currency->active) |
377
|
|
|
return $currency; |
378
|
|
|
} |
379
|
|
|
$currency = Currency::getCurrencyInstance((int)(Configuration::get('PS_CURRENCY_DEFAULT'))); |
380
|
|
|
if (is_object($currency) AND $currency->id) |
381
|
|
|
$cookie->id_currency = (int)($currency->id); |
382
|
|
|
return $currency; |
383
|
|
|
} |
384
|
|
|
|
385
|
|
|
/** |
386
|
|
|
* Return price with currency sign for a given product |
387
|
|
|
* |
388
|
|
|
* @param float $price Product price |
389
|
|
|
* @param object $currency Current currency (object, id_currency, NULL => getCurrent()) |
390
|
|
|
* @return string Price correctly formated (sign, decimal separator...) |
391
|
|
|
*/ |
392
|
|
|
public static function displayPrice($price, $currency = NULL, $no_utf8 = false) |
393
|
|
|
{ |
394
|
|
|
if ($currency === NULL) |
395
|
|
|
$currency = Currency::getCurrent(); |
396
|
|
|
/* if you modified this function, don't forget to modify the Javascript function formatCurrency (in tools.js) */ |
397
|
|
|
if (is_int($currency)) |
398
|
|
|
$currency = Currency::getCurrencyInstance((int)$currency); |
399
|
|
|
|
400
|
|
|
if (is_array($currency)) |
401
|
|
|
{ |
402
|
|
|
$c_char = $currency['sign']; |
403
|
|
|
$c_format = $currency['format']; |
404
|
|
|
$c_decimals = (int)$currency['decimals'] * _PS_PRICE_DISPLAY_PRECISION_; |
405
|
|
|
$c_blank = $currency['blank']; |
406
|
|
|
} |
407
|
|
|
elseif (is_object($currency)) |
408
|
|
|
{ |
409
|
|
|
$c_char = $currency->sign; |
410
|
|
|
$c_format = $currency->format; |
411
|
|
|
$c_decimals = (int)$currency->decimals * _PS_PRICE_DISPLAY_PRECISION_; |
412
|
|
|
$c_blank = $currency->blank; |
413
|
|
|
} |
414
|
|
|
else |
415
|
|
|
return false; |
416
|
|
|
|
417
|
|
|
$blank = ($c_blank ? ' ' : ''); |
418
|
|
|
$ret = 0; |
419
|
|
|
if (($isNegative = ($price < 0))) |
420
|
|
|
$price *= -1; |
421
|
|
|
$price = self::ps_round($price, $c_decimals); |
422
|
|
|
switch ($c_format) |
423
|
|
|
{ |
424
|
|
|
/* X 0,000.00 */ |
425
|
|
|
case 1: |
426
|
|
|
$ret = $c_char.$blank.number_format($price, $c_decimals, '.', ','); |
427
|
|
|
break; |
428
|
|
|
/* 0 000,00 X*/ |
429
|
|
|
case 2: |
430
|
|
|
$ret = number_format($price, $c_decimals, ',', ' ').$blank.$c_char; |
431
|
|
|
break; |
432
|
|
|
/* X 0.000,00 */ |
433
|
|
|
case 3: |
434
|
|
|
$ret = $c_char.$blank.number_format($price, $c_decimals, ',', '.'); |
435
|
|
|
break; |
436
|
|
|
/* 0,000.00 X */ |
437
|
|
|
case 4: |
438
|
|
|
$ret = number_format($price, $c_decimals, '.', ',').$blank.$c_char; |
439
|
|
|
break; |
440
|
|
|
} |
441
|
|
|
if ($isNegative) |
442
|
|
|
$ret = '-'.$ret; |
443
|
|
|
if ($no_utf8) |
444
|
|
|
return str_replace('€', chr(128), $ret); |
445
|
|
|
return $ret; |
446
|
|
|
} |
447
|
|
|
|
448
|
|
|
public static function displayPriceSmarty($params, &$smarty) |
|
|
|
|
449
|
|
|
{ |
450
|
|
|
if (array_key_exists('currency', $params)) |
451
|
|
|
{ |
452
|
|
|
$currency = Currency::getCurrencyInstance((int)($params['currency'])); |
453
|
|
|
if (Validate::isLoadedObject($currency)) |
454
|
|
|
return self::displayPrice($params['price'], $currency, false); |
455
|
|
|
} |
456
|
|
|
return self::displayPrice($params['price']); |
457
|
|
|
} |
458
|
|
|
|
459
|
|
|
/** |
460
|
|
|
* Return price converted |
461
|
|
|
* |
462
|
|
|
* @param float $price Product price |
463
|
|
|
* @param object $currency Current currency object |
464
|
|
|
* @param boolean $to_currency convert to currency or from currency to default currency |
465
|
|
|
*/ |
466
|
|
|
public static function convertPrice($price, $currency = NULL, $to_currency = true) |
467
|
|
|
{ |
468
|
|
|
if ($currency === NULL) |
469
|
|
|
$currency = Currency::getCurrent(); |
470
|
|
|
elseif (is_numeric($currency)) |
471
|
|
|
$currency = Currency::getCurrencyInstance($currency); |
472
|
|
|
|
473
|
|
|
$c_id = (is_array($currency) ? $currency['id_currency'] : $currency->id); |
474
|
|
|
$c_rate = (is_array($currency) ? $currency['conversion_rate'] : $currency->conversion_rate); |
475
|
|
|
|
476
|
|
|
if ($c_id != (int)(Configuration::get('PS_CURRENCY_DEFAULT'))) |
477
|
|
|
{ |
478
|
|
|
if ($to_currency) |
479
|
|
|
$price *= $c_rate; |
480
|
|
|
else |
481
|
|
|
$price /= $c_rate; |
482
|
|
|
} |
483
|
|
|
|
484
|
|
|
return $price; |
485
|
|
|
} |
486
|
|
|
|
487
|
|
|
|
488
|
|
|
|
489
|
|
|
/** |
490
|
|
|
* Display date regarding to language preferences |
491
|
|
|
* |
492
|
|
|
* @param array $params Date, format... |
493
|
|
|
* @param object $smarty Smarty object for language preferences |
494
|
|
|
* @return string Date |
495
|
|
|
*/ |
496
|
|
|
public static function dateFormat($params, &$smarty) |
497
|
|
|
{ |
498
|
|
|
return self::displayDate($params['date'], $smarty->ps_language->id, (isset($params['full']) ? $params['full'] : false)); |
499
|
|
|
} |
500
|
|
|
|
501
|
|
|
/** |
502
|
|
|
* Display date regarding to language preferences |
503
|
|
|
* |
504
|
|
|
* @param string $date Date to display format UNIX |
505
|
|
|
* @param integer $id_lang Language id |
506
|
|
|
* @param boolean $full With time or not (optional) |
507
|
|
|
* @return string Date |
508
|
|
|
*/ |
509
|
|
|
public static function displayDate($date, $id_lang, $full = false, $separator = '-') |
|
|
|
|
510
|
|
|
{ |
511
|
|
|
if (!$date OR !($time = strtotime($date))) |
512
|
|
|
return $date; |
513
|
|
|
if (!Validate::isDate($date) OR !Validate::isBool($full)) |
514
|
|
|
die (self::displayError('Invalid date')); |
|
|
|
|
515
|
|
|
|
516
|
|
|
$language = Language::getLanguage((int)$id_lang); |
517
|
|
|
return date($full ? $language['date_format_full'] : $language['date_format_lite'], $time); |
518
|
|
|
} |
519
|
|
|
|
520
|
|
|
/** |
521
|
|
|
* Sanitize a string |
522
|
|
|
* |
523
|
|
|
* @param string $string String to sanitize |
524
|
|
|
* @param boolean $full String contains HTML or not (optional) |
|
|
|
|
525
|
|
|
* @return string Sanitized string |
526
|
|
|
*/ |
527
|
|
|
public static function safeOutput($string, $html = false) |
528
|
|
|
{ |
529
|
|
|
if (!$html) |
530
|
|
|
$string = strip_tags($string); |
531
|
|
|
return @Tools::htmlentitiesUTF8($string, ENT_QUOTES); |
532
|
|
|
} |
533
|
|
|
|
534
|
|
|
public static function htmlentitiesUTF8($string, $type = ENT_QUOTES) |
535
|
|
|
{ |
536
|
|
|
if (is_array($string)) |
537
|
|
|
return array_map(array('Tools', 'htmlentitiesUTF8'), $string); |
538
|
|
|
return htmlentities($string, $type, 'utf-8'); |
539
|
|
|
} |
540
|
|
|
|
541
|
|
|
public static function htmlentitiesDecodeUTF8($string) |
542
|
|
|
{ |
543
|
|
|
if (is_array($string)) |
544
|
|
|
return array_map(array('Tools', 'htmlentitiesDecodeUTF8'), $string); |
545
|
|
|
return html_entity_decode($string, ENT_QUOTES, 'utf-8'); |
546
|
|
|
} |
547
|
|
|
|
548
|
|
|
public static function safePostVars() |
|
|
|
|
549
|
|
|
{ |
550
|
|
|
$_POST = array_map(array('Tools', 'htmlentitiesUTF8'), $_POST); |
551
|
|
|
} |
552
|
|
|
|
553
|
|
|
/** |
554
|
|
|
* Delete directory and subdirectories |
555
|
|
|
* |
556
|
|
|
* @param string $dirname Directory name |
557
|
|
|
*/ |
558
|
|
|
public static function deleteDirectory($dirname, $delete_self = true) |
559
|
|
|
{ |
560
|
|
|
$dirname = rtrim($dirname, '/').'/'; |
561
|
|
|
$files = scandir($dirname); |
562
|
|
|
foreach ($files as $file) |
563
|
|
|
if ($file != '.' AND $file != '..') |
564
|
|
|
{ |
565
|
|
|
if (is_dir($dirname.$file)) |
566
|
|
|
self::deleteDirectory($dirname.$file, true); |
567
|
|
|
elseif (file_exists($dirname.$file)) |
568
|
|
|
unlink($dirname.$file); |
569
|
|
|
} |
570
|
|
|
if ($delete_self) |
571
|
|
|
rmdir($dirname); |
572
|
|
|
} |
573
|
|
|
|
574
|
|
|
/** |
575
|
|
|
* Display an error according to an error code |
576
|
|
|
* |
577
|
|
|
* @param string $string Error message |
578
|
|
|
* @param boolean $htmlentities By default at true for parsing error message with htmlentities |
579
|
|
|
*/ |
580
|
|
|
public static function displayError($string = 'Fatal error', $htmlentities = true) |
581
|
|
|
{ |
582
|
|
|
global $_ERRORS, $cookie; |
583
|
|
|
|
584
|
|
|
$iso = strtolower(Language::getIsoById((is_object($cookie) AND $cookie->id_lang) ? (int)$cookie->id_lang : (int)Configuration::get('PS_LANG_DEFAULT'))); |
585
|
|
|
@include_once(_PS_TRANSLATIONS_DIR_.$iso.'/errors.php'); |
|
|
|
|
586
|
|
|
|
587
|
|
|
if (defined('_PS_MODE_DEV_') AND _PS_MODE_DEV_ AND $string == 'Fatal error') |
588
|
|
|
return ('<pre>'.print_r(debug_backtrace(), true).'</pre>'); |
589
|
|
|
if (!is_array($_ERRORS)) |
590
|
|
|
return str_replace('"', '"', $string); |
591
|
|
|
$key = md5(str_replace('\'', '\\\'', $string)); |
592
|
|
|
$str = (isset($_ERRORS) AND is_array($_ERRORS) AND key_exists($key, $_ERRORS)) ? ($htmlentities ? htmlentities($_ERRORS[$key], ENT_COMPAT, 'UTF-8') : $_ERRORS[$key]) : $string; |
593
|
|
|
return str_replace('"', '"', stripslashes($str)); |
594
|
|
|
} |
595
|
|
|
|
596
|
|
|
/** |
597
|
|
|
* Display an error with detailed object |
598
|
|
|
* |
599
|
|
|
* @param mixed $object |
600
|
|
|
* @param boolean $kill |
601
|
|
|
* @return $object if $kill = false; |
|
|
|
|
602
|
|
|
*/ |
603
|
|
|
public static function dieObject($object, $kill = true) |
604
|
|
|
{ |
605
|
|
|
echo '<pre style="text-align: left;">'; |
606
|
|
|
print_r($object); |
607
|
|
|
echo '</pre><br />'; |
608
|
|
|
if ($kill) |
609
|
|
|
die('END'); |
|
|
|
|
610
|
|
|
return $object; |
611
|
|
|
} |
612
|
|
|
|
613
|
|
|
/** |
614
|
|
|
* ALIAS OF dieObject() - Display an error with detailed object |
615
|
|
|
* |
616
|
|
|
* @param object $object Object to display |
617
|
|
|
*/ |
618
|
|
|
public static function d($object, $kill = true) |
619
|
|
|
{ |
620
|
|
|
return (self::dieObject($object, $kill)); |
621
|
|
|
} |
622
|
|
|
|
623
|
|
|
/** |
624
|
|
|
* ALIAS OF dieObject() - Display an error with detailed object but don't stop the execution |
625
|
|
|
* |
626
|
|
|
* @param object $object Object to display |
627
|
|
|
*/ |
628
|
|
|
public static function p($object) |
629
|
|
|
{ |
630
|
|
|
return (self::dieObject($object, false)); |
631
|
|
|
} |
632
|
|
|
|
633
|
|
|
/** |
634
|
|
|
* Check if submit has been posted |
635
|
|
|
* |
636
|
|
|
* @param string $submit submit name |
637
|
|
|
*/ |
638
|
|
|
public static function isSubmit($submit) |
|
|
|
|
639
|
|
|
{ |
640
|
|
|
return ( |
641
|
|
|
isset($_POST[$submit]) OR isset($_POST[$submit.'_x']) OR isset($_POST[$submit.'_y']) |
642
|
|
|
OR isset($_GET[$submit]) OR isset($_GET[$submit.'_x']) OR isset($_GET[$submit.'_y']) |
643
|
|
|
); |
644
|
|
|
} |
645
|
|
|
|
646
|
|
|
/** |
647
|
|
|
* Get meta tages for a given page |
648
|
|
|
* |
649
|
|
|
* @param integer $id_lang Language id |
650
|
|
|
* @return array Meta tags |
651
|
|
|
*/ |
652
|
|
|
public static function getMetaTags($id_lang, $page_name, $title = '') |
653
|
|
|
{ |
654
|
|
|
global $maintenance; |
655
|
|
|
|
656
|
|
|
if (!(isset($maintenance) AND (!in_array(self::getRemoteAddr(), explode(',', Configuration::get('PS_MAINTENANCE_IP')))))) |
657
|
|
|
{ |
658
|
|
|
/* Products specifics meta tags */ |
659
|
|
|
if ($id_product = self::getValue('id_product')) |
660
|
|
|
{ |
661
|
|
|
$row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow(' |
662
|
|
|
SELECT `name`, `meta_title`, `meta_description`, `meta_keywords`, `description_short` |
663
|
|
|
FROM `'._DB_PREFIX_.'product` p |
664
|
|
|
LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (pl.`id_product` = p.`id_product`) |
665
|
|
|
WHERE pl.id_lang = '.(int)($id_lang).' AND pl.id_product = '.(int)($id_product).' AND p.active = 1'); |
666
|
|
|
if ($row) |
667
|
|
|
{ |
668
|
|
|
if (empty($row['meta_description'])) |
669
|
|
|
$row['meta_description'] = strip_tags($row['description_short']); |
670
|
|
|
return self::completeMetaTags($row, $row['name']); |
671
|
|
|
} |
672
|
|
|
} |
673
|
|
|
|
674
|
|
|
/* Categories specifics meta tags */ |
675
|
|
|
elseif ($id_category = self::getValue('id_category')) |
676
|
|
|
{ |
677
|
|
|
if (!empty($title)) |
678
|
|
|
$title = ' - '.$title; |
679
|
|
|
$page_number = (int)self::getValue('p'); |
680
|
|
|
$row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow(' |
681
|
|
|
SELECT `name`, `meta_title`, `meta_description`, `meta_keywords`, `description` |
682
|
|
|
FROM `'._DB_PREFIX_.'category_lang` |
683
|
|
|
WHERE id_lang = '.(int)($id_lang).' AND id_category = '.(int)($id_category)); |
684
|
|
|
if ($row) |
685
|
|
|
{ |
686
|
|
|
if (empty($row['meta_description'])) |
687
|
|
|
$row['meta_description'] = strip_tags($row['description']); |
688
|
|
|
|
689
|
|
|
// Paginate title |
690
|
|
|
if (!empty($row['meta_title'])) |
691
|
|
|
$row['meta_title'] = $title.$row['meta_title'].(!empty($page_number) ? ' ('.$page_number.')' : '').' - '.Configuration::get('PS_SHOP_NAME'); |
692
|
|
|
else |
693
|
|
|
$row['meta_title'] = $row['name'].(!empty($page_number) ? ' ('.$page_number.')' : '').' - '.Configuration::get('PS_SHOP_NAME'); |
694
|
|
|
|
695
|
|
|
if (!empty($title)) |
696
|
|
|
$row['meta_title'] = $title.(!empty($page_number) ? ' ('.$page_number.')' : '').' - '.Configuration::get('PS_SHOP_NAME'); |
697
|
|
|
|
698
|
|
|
return self::completeMetaTags($row, $row['name']); |
699
|
|
|
} |
700
|
|
|
} |
701
|
|
|
|
702
|
|
|
/* Manufacturers specifics meta tags */ |
703
|
|
|
elseif ($id_manufacturer = self::getValue('id_manufacturer')) |
704
|
|
|
{ |
705
|
|
|
$page_number = (int)self::getValue('p'); |
706
|
|
|
$row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow(' |
707
|
|
|
SELECT `name`, `meta_title`, `meta_description`, `meta_keywords` |
708
|
|
|
FROM `'._DB_PREFIX_.'manufacturer_lang` ml |
709
|
|
|
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON (ml.`id_manufacturer` = m.`id_manufacturer`) |
710
|
|
|
WHERE ml.id_lang = '.(int)($id_lang).' AND ml.id_manufacturer = '.(int)($id_manufacturer)); |
711
|
|
|
if ($row) |
712
|
|
|
{ |
713
|
|
|
if (empty($row['meta_description'])) |
714
|
|
|
$row['meta_description'] = strip_tags($row['meta_description']); |
715
|
|
|
$row['meta_title'] .= $row['name'] . (!empty($page_number) ? ' ('.$page_number.')' : ''); |
716
|
|
|
$row['meta_title'] .= ' - '.Configuration::get('PS_SHOP_NAME'); |
717
|
|
|
return self::completeMetaTags($row, $row['meta_title']); |
718
|
|
|
} |
719
|
|
|
} |
720
|
|
|
|
721
|
|
|
/* Suppliers specifics meta tags */ |
722
|
|
|
elseif ($id_supplier = self::getValue('id_supplier')) |
723
|
|
|
{ |
724
|
|
|
$row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow(' |
725
|
|
|
SELECT `name`, `meta_title`, `meta_description`, `meta_keywords` |
726
|
|
|
FROM `'._DB_PREFIX_.'supplier_lang` sl |
727
|
|
|
LEFT JOIN `'._DB_PREFIX_.'supplier` s ON (sl.`id_supplier` = s.`id_supplier`) |
728
|
|
|
WHERE sl.id_lang = '.(int)($id_lang).' AND sl.id_supplier = '.(int)($id_supplier)); |
729
|
|
|
|
730
|
|
|
if ($row) |
731
|
|
|
{ |
732
|
|
|
if (empty($row['meta_description'])) |
733
|
|
|
$row['meta_description'] = strip_tags($row['meta_description']); |
734
|
|
|
if (!empty($row['meta_title'])) |
735
|
|
|
$row['meta_title'] = $row['meta_title'].' - '.Configuration::get('PS_SHOP_NAME'); |
736
|
|
|
return self::completeMetaTags($row, $row['name']); |
737
|
|
|
} |
738
|
|
|
} |
739
|
|
|
|
740
|
|
|
/* CMS specifics meta tags */ |
741
|
|
|
elseif ($id_cms = self::getValue('id_cms')) |
742
|
|
|
{ |
743
|
|
|
$row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow(' |
744
|
|
|
SELECT `meta_title`, `meta_description`, `meta_keywords` |
745
|
|
|
FROM `'._DB_PREFIX_.'cms_lang` |
746
|
|
|
WHERE id_lang = '.(int)($id_lang).' AND id_cms = '.(int)($id_cms)); |
747
|
|
|
if ($row) |
748
|
|
|
{ |
749
|
|
|
$row['meta_title'] = $row['meta_title'].' - '.Configuration::get('PS_SHOP_NAME'); |
750
|
|
|
return self::completeMetaTags($row, $row['meta_title']); |
751
|
|
|
} |
752
|
|
|
} |
753
|
|
|
|
754
|
|
|
/* CMS category specifics meta tags */ |
755
|
|
|
elseif ($id_cms = self::getValue('id_cms_category')) |
756
|
|
|
{ |
757
|
|
|
$row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow(' |
758
|
|
|
SELECT `meta_title`, `meta_description`, `meta_keywords` |
759
|
|
|
FROM `'._DB_PREFIX_.'cms_category_lang` |
760
|
|
|
WHERE id_lang = '.(int)($id_lang).' AND id_cms_category = '.(int)($id_cms)); |
761
|
|
|
if ($row) |
762
|
|
|
{ |
763
|
|
|
$row['meta_title'] = $row['meta_title'].' - '.Configuration::get('PS_SHOP_NAME'); |
764
|
|
|
return self::completeMetaTags($row, $row['meta_title']); |
765
|
|
|
} |
766
|
|
|
} |
767
|
|
|
} |
768
|
|
|
|
769
|
|
|
/* Default meta tags */ |
770
|
|
|
return self::getHomeMetaTags($id_lang, $page_name); |
771
|
|
|
} |
772
|
|
|
|
773
|
|
|
/** |
774
|
|
|
* Get meta tags for a given page |
775
|
|
|
* |
776
|
|
|
* @param integer $id_lang Language id |
777
|
|
|
* @return array Meta tags |
778
|
|
|
*/ |
779
|
|
|
public static function getHomeMetaTags($id_lang, $page_name) |
780
|
|
|
{ |
781
|
|
|
/* Metas-tags */ |
782
|
|
|
$metas = Meta::getMetaByPage($page_name, $id_lang); |
783
|
|
|
$ret['meta_title'] = (isset($metas['title']) AND $metas['title']) ? $metas['title'].' - '.Configuration::get('PS_SHOP_NAME') : Configuration::get('PS_SHOP_NAME'); |
|
|
|
|
784
|
|
|
$ret['meta_description'] = (isset($metas['description']) AND $metas['description']) ? $metas['description'] : ''; |
785
|
|
|
$ret['meta_keywords'] = (isset($metas['keywords']) AND $metas['keywords']) ? $metas['keywords'] : ''; |
786
|
|
|
return $ret; |
787
|
|
|
} |
788
|
|
|
|
789
|
|
|
|
790
|
|
|
public static function completeMetaTags($metaTags, $defaultValue) |
791
|
|
|
{ |
792
|
|
|
global $cookie; |
793
|
|
|
|
794
|
|
|
if (empty($metaTags['meta_title'])) |
795
|
|
|
$metaTags['meta_title'] = $defaultValue.' - '.Configuration::get('PS_SHOP_NAME'); |
796
|
|
|
if (empty($metaTags['meta_description'])) |
797
|
|
|
$metaTags['meta_description'] = Configuration::get('PS_META_DESCRIPTION', (int)($cookie->id_lang)) ? Configuration::get('PS_META_DESCRIPTION', (int)($cookie->id_lang)) : ''; |
798
|
|
|
if (empty($metaTags['meta_keywords'])) |
799
|
|
|
$metaTags['meta_keywords'] = Configuration::get('PS_META_KEYWORDS', (int)($cookie->id_lang)) ? Configuration::get('PS_META_KEYWORDS', (int)($cookie->id_lang)) : ''; |
800
|
|
|
return $metaTags; |
801
|
|
|
} |
802
|
|
|
|
803
|
|
|
/** |
804
|
|
|
* Encrypt password |
805
|
|
|
* |
806
|
|
|
* @param object $object Object to display |
|
|
|
|
807
|
|
|
*/ |
808
|
|
|
public static function encrypt($passwd) |
809
|
|
|
{ |
810
|
|
|
return md5(pSQL(_COOKIE_KEY_.$passwd)); |
811
|
|
|
} |
812
|
|
|
|
813
|
|
|
/** |
814
|
|
|
* Get token to prevent CSRF |
815
|
|
|
* |
816
|
|
|
* @param string $token token to encrypt |
|
|
|
|
817
|
|
|
*/ |
818
|
|
|
public static function getToken($page = true) |
|
|
|
|
819
|
|
|
{ |
820
|
|
|
global $cookie; |
821
|
|
|
if ($page === true) |
822
|
|
|
return (self::encrypt($cookie->id_customer.$cookie->passwd.$_SERVER['SCRIPT_NAME'])); |
823
|
|
|
else |
824
|
|
|
return (self::encrypt($cookie->id_customer.$cookie->passwd.$page)); |
825
|
|
|
} |
826
|
|
|
|
827
|
|
|
/** |
828
|
|
|
* Encrypt password |
829
|
|
|
* |
830
|
|
|
* @param object $object Object to display |
|
|
|
|
831
|
|
|
*/ |
832
|
|
|
public static function getAdminToken($string) |
833
|
|
|
{ |
834
|
|
|
return !empty($string) ? self::encrypt($string) : false; |
835
|
|
|
} |
836
|
|
|
public static function getAdminTokenLite($tab) |
837
|
|
|
{ |
838
|
|
|
global $cookie; |
839
|
|
|
return self::getAdminToken($tab.(int)Tab::getIdFromClassName($tab).(int)$cookie->id_employee); |
840
|
|
|
} |
841
|
|
|
|
842
|
|
|
/** |
843
|
|
|
* Get the user's journey |
844
|
|
|
* |
845
|
|
|
* @param integer $id_category Category ID |
846
|
|
|
* @param string $path Path end |
847
|
|
|
* @param boolean $linkOntheLastItem Put or not a link on the current category |
848
|
|
|
* @param string [optionnal] $categoryType defined what type of categories is used (products or cms) |
849
|
|
|
*/ |
850
|
|
|
public static function getPath($id_category, $path = '', $linkOntheLastItem = false, $categoryType = 'products') |
851
|
|
|
{ |
852
|
|
|
global $link, $cookie; |
853
|
|
|
|
854
|
|
|
if ($id_category == 1) |
855
|
|
|
return '<span class="navigation_end">'.$path.'</span>'; |
856
|
|
|
|
857
|
|
|
$pipe = Configuration::get('PS_NAVIGATION_PIPE'); |
858
|
|
|
if (empty($pipe)) |
859
|
|
|
$pipe = '>'; |
860
|
|
|
|
861
|
|
|
$fullPath = ''; |
862
|
|
|
|
863
|
|
|
if ($categoryType === 'products') |
864
|
|
|
{ |
865
|
|
|
$category = Db::getInstance()->getRow(' |
866
|
|
|
SELECT id_category, level_depth, nleft, nright |
867
|
|
|
FROM '._DB_PREFIX_.'category |
868
|
|
|
WHERE id_category = '.(int)$id_category); |
869
|
|
|
|
870
|
|
|
if (isset($category['id_category'])) |
871
|
|
|
{ |
872
|
|
|
$categories = Db::getInstance()->ExecuteS(' |
873
|
|
|
SELECT c.id_category, cl.name, cl.link_rewrite |
874
|
|
|
FROM '._DB_PREFIX_.'category c |
875
|
|
|
LEFT JOIN '._DB_PREFIX_.'category_lang cl ON (cl.id_category = c.id_category) |
876
|
|
|
WHERE c.nleft <= '.(int)$category['nleft'].' AND c.nright >= '.(int)$category['nright'].' AND cl.id_lang = '.(int)($cookie->id_lang).' AND c.id_category != 1 |
877
|
|
|
ORDER BY c.level_depth ASC |
878
|
|
|
LIMIT '.(int)$category['level_depth']); |
879
|
|
|
|
880
|
|
|
$n = 1; |
881
|
|
|
$nCategories = (int)sizeof($categories); |
882
|
|
|
foreach ($categories AS $category) |
883
|
|
|
{ |
884
|
|
|
$fullPath .= |
885
|
|
|
(($n < $nCategories OR $linkOntheLastItem) ? '<a href="'.self::safeOutput($link->getCategoryLink((int)$category['id_category'], $category['link_rewrite'])).'" title="'.htmlentities($category['name'], ENT_NOQUOTES, 'UTF-8').'">' : ''). |
886
|
|
|
htmlentities($category['name'], ENT_NOQUOTES, 'UTF-8'). |
887
|
|
|
(($n < $nCategories OR $linkOntheLastItem) ? '</a>' : ''). |
888
|
|
|
(($n++ != $nCategories OR !empty($path)) ? '<span class="navigation-pipe">'.$pipe.'</span>' : ''); |
889
|
|
|
} |
890
|
|
|
|
891
|
|
|
return $fullPath.$path; |
892
|
|
|
} |
893
|
|
|
} |
894
|
|
|
elseif ($categoryType === 'CMS') |
895
|
|
|
{ |
896
|
|
|
$category = new CMSCategory((int)($id_category), (int)($cookie->id_lang)); |
897
|
|
|
if (!Validate::isLoadedObject($category)) |
898
|
|
|
die(self::displayError()); |
|
|
|
|
899
|
|
|
$categoryLink = $link->getCMSCategoryLink($category); |
900
|
|
|
|
901
|
|
|
if ($path != $category->name) |
902
|
|
|
$fullPath .= '<a href="'.self::safeOutput($categoryLink).'">'.htmlentities($category->name, ENT_NOQUOTES, 'UTF-8').'</a><span class="navigation-pipe">'.$pipe.'</span>'.$path; |
903
|
|
|
else |
904
|
|
|
$fullPath = ($linkOntheLastItem ? '<a href="'.self::safeOutput($categoryLink).'">' : '').htmlentities($path, ENT_NOQUOTES, 'UTF-8').($linkOntheLastItem ? '</a>' : ''); |
905
|
|
|
|
906
|
|
|
return self::getPath((int)($category->id_parent), $fullPath, $linkOntheLastItem, $categoryType); |
907
|
|
|
} |
908
|
|
|
} |
909
|
|
|
|
910
|
|
|
/** |
911
|
|
|
* @param string [optionnal] $type_cat defined what type of categories is used (products or cms) |
912
|
|
|
*/ |
913
|
|
|
public static function getFullPath($id_category, $end, $type_cat = 'products') |
914
|
|
|
{ |
915
|
|
|
global $cookie; |
916
|
|
|
|
917
|
|
|
$pipe = (Configuration::get('PS_NAVIGATION_PIPE') ? Configuration::get('PS_NAVIGATION_PIPE') : '>'); |
918
|
|
|
|
919
|
|
|
if ($type_cat === 'products') |
920
|
|
|
$category = new Category((int)($id_category), (int)($cookie->id_lang)); |
921
|
|
|
elseif ($type_cat === 'CMS') |
922
|
|
|
$category = new CMSCategory((int)($id_category), (int)($cookie->id_lang)); |
923
|
|
|
|
924
|
|
|
if (!Validate::isLoadedObject($category)) |
|
|
|
|
925
|
|
|
$id_category = 1; |
926
|
|
|
if ($id_category == 1) |
927
|
|
|
return htmlentities($end, ENT_NOQUOTES, 'UTF-8'); |
928
|
|
|
|
929
|
|
|
return self::getPath($id_category, $category->name, true, $type_cat).'<span class="navigation-pipe">'.$pipe.'</span> <span class="navigation_product">'.htmlentities($end, ENT_NOQUOTES, 'UTF-8').'</span>'; |
930
|
|
|
} |
931
|
|
|
|
932
|
|
|
/** |
933
|
|
|
* @deprecated |
934
|
|
|
*/ |
935
|
|
|
public static function getCategoriesTotal() |
936
|
|
|
{ |
937
|
|
|
Tools::displayAsDeprecated(); |
938
|
|
|
$row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('SELECT COUNT(`id_category`) AS total FROM `'._DB_PREFIX_.'category`'); |
939
|
|
|
return (int)($row['total']); |
940
|
|
|
} |
941
|
|
|
|
942
|
|
|
/** |
943
|
|
|
* @deprecated |
944
|
|
|
*/ |
945
|
|
|
public static function getProductsTotal() |
946
|
|
|
{ |
947
|
|
|
Tools::displayAsDeprecated(); |
948
|
|
|
$row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('SELECT COUNT(`id_product`) AS total FROM `'._DB_PREFIX_.'product`'); |
949
|
|
|
return (int)($row['total']); |
950
|
|
|
} |
951
|
|
|
|
952
|
|
|
/** |
953
|
|
|
* @deprecated |
954
|
|
|
*/ |
955
|
|
|
public static function getCustomersTotal() |
956
|
|
|
{ |
957
|
|
|
Tools::displayAsDeprecated(); |
958
|
|
|
$row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('SELECT COUNT(`id_customer`) AS total FROM `'._DB_PREFIX_.'customer`'); |
959
|
|
|
return (int)($row['total']); |
960
|
|
|
} |
961
|
|
|
|
962
|
|
|
/** |
963
|
|
|
* @deprecated |
964
|
|
|
*/ |
965
|
|
|
public static function getOrdersTotal() |
966
|
|
|
{ |
967
|
|
|
Tools::displayAsDeprecated(); |
968
|
|
|
$row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('SELECT COUNT(`id_order`) AS total FROM `'._DB_PREFIX_.'orders`'); |
969
|
|
|
return (int)($row['total']); |
970
|
|
|
} |
971
|
|
|
|
972
|
|
|
/* |
973
|
|
|
** Historyc translation function kept for compatibility |
974
|
|
|
** Removing soon |
975
|
|
|
*/ |
976
|
|
|
public static function historyc_l($key, $translations) |
977
|
|
|
{ |
978
|
|
|
global $cookie; |
979
|
|
|
if (!$translations OR !is_array($translations)) |
980
|
|
|
die(self::displayError()); |
|
|
|
|
981
|
|
|
$iso = strtoupper(Language::getIsoById($cookie->id_lang)); |
982
|
|
|
$lang = key_exists($iso, $translations) ? $translations[$iso] : false; |
983
|
|
|
return (($lang AND is_array($lang) AND key_exists($key, $lang)) ? stripslashes($lang[$key]) : $key); |
984
|
|
|
} |
985
|
|
|
|
986
|
|
|
|
987
|
|
|
/** |
988
|
|
|
* Return the friendly url from the provided string |
989
|
|
|
* |
990
|
|
|
* @param string $str |
991
|
|
|
* @param bool $utf8_decode => needs to be marked as deprecated |
992
|
|
|
* @return string |
993
|
|
|
*/ |
994
|
|
|
public static function link_rewrite($str, $utf8_decode = false) |
|
|
|
|
995
|
|
|
{ |
996
|
|
|
return self::str2url($str); |
997
|
|
|
} |
998
|
|
|
|
999
|
|
|
/** |
1000
|
|
|
* Return a friendly url made from the provided string |
1001
|
|
|
* If the mbstring library is available, the output is the same as the js function of the same name |
1002
|
|
|
* |
1003
|
|
|
* @param string $str |
1004
|
|
|
* @return string |
1005
|
|
|
*/ |
1006
|
|
|
public static function str2url($str) |
1007
|
|
|
{ |
1008
|
|
|
if (function_exists('mb_strtolower')) |
1009
|
|
|
$str = mb_strtolower($str, 'utf-8'); |
1010
|
|
|
|
1011
|
|
|
$str = trim($str); |
1012
|
|
|
$str = self::replaceAccentedChars($str); |
1013
|
|
|
|
1014
|
|
|
// Remove all non-whitelist chars. |
1015
|
|
|
$str = preg_replace('/[^a-zA-Z0-9\s\'\:\/\[\]-]/','', $str); |
1016
|
|
|
$str = preg_replace('/[\s\'\:\/\[\]-]+/',' ', $str); |
1017
|
|
|
$str = preg_replace('/[ ]/','-', $str); |
1018
|
|
|
$str = preg_replace('/[\/]/','-', $str); |
1019
|
|
|
|
1020
|
|
|
// If it was not possible to lowercase the string with mb_strtolower, we do it after the transformations. |
1021
|
|
|
// This way we lose fewer special chars. |
1022
|
|
|
$str = strtolower($str); |
1023
|
|
|
|
1024
|
|
|
return $str; |
1025
|
|
|
} |
1026
|
|
|
|
1027
|
|
|
/** |
1028
|
|
|
* Replace all accented chars by their equivalent non accented chars. |
1029
|
|
|
* |
1030
|
|
|
* @param string $str |
1031
|
|
|
* @return string |
1032
|
|
|
*/ |
1033
|
|
|
public static function replaceAccentedChars($str) |
1034
|
|
|
{ |
1035
|
|
|
$str = preg_replace('/[\x{0105}\x{0104}\x{00E0}\x{00E1}\x{00E2}\x{00E3}\x{00E4}\x{00E5}]/u','a', $str); |
1036
|
|
|
$str = preg_replace('/[\x{00E7}\x{010D}\x{0107}\x{0106}]/u','c', $str); |
1037
|
|
|
$str = preg_replace('/[\x{010F}]/u','d', $str); |
1038
|
|
|
$str = preg_replace('/[\x{00E8}\x{00E9}\x{00EA}\x{00EB}\x{011B}\x{0119}\x{0118}]/u','e', $str); |
1039
|
|
|
$str = preg_replace('/[\x{00EC}\x{00ED}\x{00EE}\x{00EF}]/u','i', $str); |
1040
|
|
|
$str = preg_replace('/[\x{0142}\x{0141}\x{013E}\x{013A}]/u','l', $str); |
1041
|
|
|
$str = preg_replace('/[\x{00F1}\x{0148}]/u','n', $str); |
1042
|
|
|
$str = preg_replace('/[\x{00F2}\x{00F3}\x{00F4}\x{00F5}\x{00F6}\x{00F8}\x{00D3}]/u','o', $str); |
1043
|
|
|
$str = preg_replace('/[\x{0159}\x{0155}]/u','r', $str); |
1044
|
|
|
$str = preg_replace('/[\x{015B}\x{015A}\x{0161}]/u','s', $str); |
1045
|
|
|
$str = preg_replace('/[\x{00DF}]/u','ss', $str); |
1046
|
|
|
$str = preg_replace('/[\x{0165}]/u','t', $str); |
1047
|
|
|
$str = preg_replace('/[\x{00F9}\x{00FA}\x{00FB}\x{00FC}\x{016F}]/u','u', $str); |
1048
|
|
|
$str = preg_replace('/[\x{00FD}\x{00FF}]/u','y', $str); |
1049
|
|
|
$str = preg_replace('/[\x{017C}\x{017A}\x{017B}\x{0179}\x{017E}]/u','z', $str); |
1050
|
|
|
$str = preg_replace('/[\x{00E6}]/u','ae', $str); |
1051
|
|
|
$str = preg_replace('/[\x{0153}]/u','oe', $str); |
1052
|
|
|
return $str; |
1053
|
|
|
} |
1054
|
|
|
|
1055
|
|
|
/** |
1056
|
|
|
* Truncate strings |
1057
|
|
|
* |
1058
|
|
|
* @param string $str |
1059
|
|
|
* @param integer $maxLen Max length |
1060
|
|
|
* @param string $suffix Suffix optional |
1061
|
|
|
* @return string $str truncated |
1062
|
|
|
*/ |
1063
|
|
|
/* CAUTION : Use it only on module hookEvents. |
1064
|
|
|
** For other purposes use the smarty function instead */ |
1065
|
|
|
public static function truncate($str, $maxLen, $suffix = '...') |
1066
|
|
|
{ |
1067
|
|
|
if (self::strlen($str) <= $maxLen) |
1068
|
|
|
return $str; |
1069
|
|
|
$str = utf8_decode($str); |
1070
|
|
|
return (utf8_encode(substr($str, 0, $maxLen - self::strlen($suffix)).$suffix)); |
1071
|
|
|
} |
1072
|
|
|
|
1073
|
|
|
/** |
1074
|
|
|
* Generate date form |
1075
|
|
|
* |
1076
|
|
|
* @param integer $year Year to select |
|
|
|
|
1077
|
|
|
* @param integer $month Month to select |
|
|
|
|
1078
|
|
|
* @param integer $day Day to select |
|
|
|
|
1079
|
|
|
* @return array $tab html data with 3 cells :['days'], ['months'], ['years'] |
1080
|
|
|
* |
1081
|
|
|
*/ |
1082
|
|
|
public static function dateYears() |
1083
|
|
|
{ |
1084
|
|
|
for ($i = date('Y') - 10; $i >= 1900; $i--) |
1085
|
|
|
$tab[] = $i; |
|
|
|
|
1086
|
|
|
return $tab; |
|
|
|
|
1087
|
|
|
} |
1088
|
|
|
|
1089
|
|
|
public static function dateDays() |
1090
|
|
|
{ |
1091
|
|
|
for ($i = 1; $i != 32; $i++) |
1092
|
|
|
$tab[] = $i; |
|
|
|
|
1093
|
|
|
return $tab; |
|
|
|
|
1094
|
|
|
} |
1095
|
|
|
|
1096
|
|
|
public static function dateMonths() |
1097
|
|
|
{ |
1098
|
|
|
for ($i = 1; $i != 13; $i++) |
1099
|
|
|
$tab[$i] = date('F', mktime(0, 0, 0, $i, date('m'), date('Y'))); |
|
|
|
|
1100
|
|
|
return $tab; |
|
|
|
|
1101
|
|
|
} |
1102
|
|
|
|
1103
|
|
|
public static function hourGenerate($hours, $minutes, $seconds) |
1104
|
|
|
{ |
1105
|
|
|
return implode(':', array($hours, $minutes, $seconds)); |
1106
|
|
|
} |
1107
|
|
|
|
1108
|
|
|
public static function dateFrom($date) |
1109
|
|
|
{ |
1110
|
|
|
$tab = explode(' ', $date); |
1111
|
|
|
if (!isset($tab[1])) |
1112
|
|
|
$date .= ' ' . self::hourGenerate(0, 0, 0); |
1113
|
|
|
return $date; |
1114
|
|
|
} |
1115
|
|
|
|
1116
|
|
|
public static function dateTo($date) |
1117
|
|
|
{ |
1118
|
|
|
$tab = explode(' ', $date); |
1119
|
|
|
if (!isset($tab[1])) |
1120
|
|
|
$date .= ' ' . self::hourGenerate(23, 59, 59); |
1121
|
|
|
return $date; |
1122
|
|
|
} |
1123
|
|
|
|
1124
|
|
|
/** |
1125
|
|
|
* @deprecated |
1126
|
|
|
*/ |
1127
|
|
|
public static function getExactTime() |
1128
|
|
|
{ |
1129
|
|
|
Tools::displayAsDeprecated(); |
1130
|
|
|
return time()+microtime(); |
1131
|
|
|
} |
1132
|
|
|
|
1133
|
|
|
static function strtolower($str) |
|
|
|
|
1134
|
|
|
{ |
1135
|
|
|
if (is_array($str)) |
1136
|
|
|
return false; |
1137
|
|
|
if (function_exists('mb_strtolower')) |
1138
|
|
|
return mb_strtolower($str, 'utf-8'); |
1139
|
|
|
return strtolower($str); |
1140
|
|
|
} |
1141
|
|
|
|
1142
|
|
|
static function strlen($str, $encoding = 'UTF-8') |
|
|
|
|
1143
|
|
|
{ |
1144
|
|
|
if (is_array($str)) |
1145
|
|
|
return false; |
1146
|
|
|
$str = html_entity_decode($str, ENT_COMPAT, 'UTF-8'); |
1147
|
|
|
if (function_exists('mb_strlen')) |
1148
|
|
|
return mb_strlen($str, $encoding); |
1149
|
|
|
return strlen($str); |
1150
|
|
|
} |
1151
|
|
|
|
1152
|
|
|
static function stripslashes($string) |
|
|
|
|
1153
|
|
|
{ |
1154
|
|
|
if (_PS_MAGIC_QUOTES_GPC_) |
1155
|
|
|
$string = stripslashes($string); |
1156
|
|
|
return $string; |
1157
|
|
|
} |
1158
|
|
|
|
1159
|
|
|
static function strtoupper($str) |
|
|
|
|
1160
|
|
|
{ |
1161
|
|
|
if (is_array($str)) |
1162
|
|
|
return false; |
1163
|
|
|
if (function_exists('mb_strtoupper')) |
1164
|
|
|
return mb_strtoupper($str, 'utf-8'); |
1165
|
|
|
return strtoupper($str); |
1166
|
|
|
} |
1167
|
|
|
|
1168
|
|
|
static function substr($str, $start, $length = false, $encoding = 'utf-8') |
|
|
|
|
1169
|
|
|
{ |
1170
|
|
|
if (is_array($str)) |
1171
|
|
|
return false; |
1172
|
|
|
if (function_exists('mb_substr')) |
1173
|
|
|
return mb_substr($str, (int)($start), ($length === false ? self::strlen($str) : (int)($length)), $encoding); |
1174
|
|
|
return substr($str, $start, ($length === false ? self::strlen($str) : (int)($length))); |
1175
|
|
|
} |
1176
|
|
|
|
1177
|
|
|
static function ucfirst($str) |
|
|
|
|
1178
|
|
|
{ |
1179
|
|
|
return self::strtoupper(self::substr($str, 0, 1)).self::substr($str, 1); |
|
|
|
|
1180
|
|
|
} |
1181
|
|
|
|
1182
|
|
|
public static function orderbyPrice(&$array, $orderWay) |
1183
|
|
|
{ |
1184
|
|
|
foreach ($array as &$row) |
1185
|
|
|
$row['price_tmp'] = Product::getPriceStatic($row['id_product'], true, ((isset($row['id_product_attribute']) AND !empty($row['id_product_attribute'])) ? (int)($row['id_product_attribute']) : NULL), 2); |
1186
|
|
|
if (strtolower($orderWay) == 'desc') |
1187
|
|
|
uasort($array, 'cmpPriceDesc'); |
1188
|
|
|
else |
1189
|
|
|
uasort($array, 'cmpPriceAsc'); |
1190
|
|
|
foreach ($array as &$row) |
1191
|
|
|
unset($row['price_tmp']); |
1192
|
|
|
} |
1193
|
|
|
|
1194
|
|
|
public static function iconv($from, $to, $string) |
1195
|
|
|
{ |
1196
|
|
|
if (function_exists('iconv')) |
1197
|
|
|
return iconv($from, $to.'//TRANSLIT', str_replace('¥', '¥', str_replace('£', '£', str_replace('€', '€', $string)))); |
1198
|
|
|
return html_entity_decode(htmlentities($string, ENT_NOQUOTES, $from), ENT_NOQUOTES, $to); |
1199
|
|
|
} |
1200
|
|
|
|
1201
|
|
|
public static function isEmpty($field) |
1202
|
|
|
{ |
1203
|
|
|
return ($field === '' OR $field === NULL); |
1204
|
|
|
} |
1205
|
|
|
|
1206
|
|
|
/** |
1207
|
|
|
* @deprecated |
1208
|
|
|
**/ |
1209
|
|
|
public static function getTimezones($select = false) |
1210
|
|
|
{ |
1211
|
|
|
Tools::displayAsDeprecated(); |
1212
|
|
|
|
1213
|
|
|
static $_cache = 0; |
1214
|
|
|
|
1215
|
|
|
// One select |
1216
|
|
|
if ($select) |
1217
|
|
|
{ |
1218
|
|
|
// No cache |
1219
|
|
|
if (!$_cache) |
1220
|
|
|
{ |
1221
|
|
|
$tmz = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('SELECT `name` FROM '._DB_PREFIX_.'timezone WHERE id_timezone = '.(int)($select)); |
1222
|
|
|
$_cache = $tmz['name']; |
1223
|
|
|
} |
1224
|
|
|
return $_cache; |
1225
|
|
|
} |
1226
|
|
|
|
1227
|
|
|
// Multiple select |
1228
|
|
|
$tmz = Db::getInstance(_PS_USE_SQL_SLAVE_)->s('SELECT * FROM '._DB_PREFIX_.'timezone'); |
1229
|
|
|
$tab = array(); |
1230
|
|
|
foreach ($tmz as $timezone) |
1231
|
|
|
$tab[$timezone['id_timezone']] = str_replace('_', ' ', $timezone['name']); |
1232
|
|
|
return $tab; |
1233
|
|
|
} |
1234
|
|
|
|
1235
|
|
|
/** |
1236
|
|
|
* @deprecated |
1237
|
|
|
**/ |
1238
|
|
|
public static function ps_set_magic_quotes_runtime($var) |
1239
|
|
|
{ |
1240
|
|
|
Tools::displayAsDeprecated(); |
1241
|
|
|
|
1242
|
|
|
if (function_exists('set_magic_quotes_runtime')) |
1243
|
|
|
set_magic_quotes_runtime($var); |
|
|
|
|
1244
|
|
|
} |
1245
|
|
|
|
1246
|
|
|
public static function ps_round($value, $precision = 0) |
1247
|
|
|
{ |
1248
|
|
|
$method = (int)(Configuration::get('PS_PRICE_ROUND_MODE')); |
1249
|
|
|
if ($method == PS_ROUND_UP) |
1250
|
|
|
return self::ceilf($value, $precision); |
1251
|
|
|
elseif ($method == PS_ROUND_DOWN) |
1252
|
|
|
return self::floorf($value, $precision); |
1253
|
|
|
return round($value, $precision); |
1254
|
|
|
} |
1255
|
|
|
|
1256
|
|
|
public static function ceilf($value, $precision = 0) |
1257
|
|
|
{ |
1258
|
|
|
$precisionFactor = $precision == 0 ? 1 : pow(10, $precision); |
1259
|
|
|
$tmp = $value * $precisionFactor; |
1260
|
|
|
$tmp2 = (string)$tmp; |
1261
|
|
|
// If the current value has already the desired precision |
1262
|
|
|
if (strpos($tmp2, '.') === false) |
1263
|
|
|
return ($value); |
1264
|
|
|
if ($tmp2[strlen($tmp2) - 1] == 0) |
1265
|
|
|
return $value; |
1266
|
|
|
return ceil($tmp) / $precisionFactor; |
1267
|
|
|
} |
1268
|
|
|
|
1269
|
|
|
public static function floorf($value, $precision = 0) |
1270
|
|
|
{ |
1271
|
|
|
$precisionFactor = $precision == 0 ? 1 : pow(10, $precision); |
1272
|
|
|
$tmp = $value * $precisionFactor; |
1273
|
|
|
$tmp2 = (string)$tmp; |
1274
|
|
|
// If the current value has already the desired precision |
1275
|
|
|
if (strpos($tmp2, '.') === false) |
1276
|
|
|
return ($value); |
1277
|
|
|
if ($tmp2[strlen($tmp2) - 1] == 0) |
1278
|
|
|
return $value; |
1279
|
|
|
return floor($tmp) / $precisionFactor; |
1280
|
|
|
} |
1281
|
|
|
|
1282
|
|
|
/** |
1283
|
|
|
* file_exists() wrapper with cache to speedup performance |
1284
|
|
|
* |
1285
|
|
|
* @param string $filename File name |
1286
|
|
|
* @return boolean Cached result of file_exists($filename) |
1287
|
|
|
*/ |
1288
|
|
|
public static function file_exists_cache($filename) |
1289
|
|
|
{ |
1290
|
|
|
if (!isset(self::$file_exists_cache[$filename])) |
1291
|
|
|
self::$file_exists_cache[$filename] = file_exists($filename); |
1292
|
|
|
return self::$file_exists_cache[$filename]; |
1293
|
|
|
} |
1294
|
|
|
|
1295
|
|
|
public static function file_get_contents($url, $useIncludePath = false, $streamContext = NULL, $curlTimeOut = 5) |
1296
|
|
|
{ |
1297
|
|
|
if ($streamContext == NULL) |
1298
|
|
|
$streamContext = @stream_context_create(array('http' => array('timeout' => 5))); |
1299
|
|
|
|
1300
|
|
|
if (in_array(ini_get('allow_url_fopen'), array('On', 'on', '1'))) |
1301
|
|
|
return @file_get_contents($url, $useIncludePath, $streamContext); |
1302
|
|
|
elseif (function_exists('curl_init') && in_array(ini_get('allow_url_fopen'), array('On', 'on', '1'))) |
1303
|
|
|
{ |
1304
|
|
|
$curl = curl_init(); |
1305
|
|
|
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); |
1306
|
|
|
curl_setopt($curl, CURLOPT_URL, $url); |
1307
|
|
|
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $curlTimeOut); |
1308
|
|
|
curl_setopt($curl, CURLOPT_TIMEOUT, $curlTimeOut); |
1309
|
|
|
$content = curl_exec($curl); |
1310
|
|
|
curl_close($curl); |
1311
|
|
|
return $content; |
1312
|
|
|
} |
1313
|
|
|
else |
1314
|
|
|
return false; |
1315
|
|
|
} |
1316
|
|
|
|
1317
|
|
|
public static function simplexml_load_file($url, $class_name = null) |
1318
|
|
|
{ |
1319
|
|
|
if (in_array(ini_get('allow_url_fopen'), array('On', 'on', '1'))) |
1320
|
|
|
return simplexml_load_string(Tools::file_get_contents($url), $class_name); |
1321
|
|
|
else |
1322
|
|
|
return false; |
1323
|
|
|
} |
1324
|
|
|
|
1325
|
|
|
public static $a = 0; |
1326
|
|
|
public static function minifyHTML($html_content) |
1327
|
|
|
{ |
1328
|
|
|
if (strlen($html_content) > 0) |
1329
|
|
|
{ |
1330
|
|
|
//set an alphabetical order for args |
1331
|
|
|
$html_content = preg_replace_callback( |
1332
|
|
|
'/(<[a-zA-Z0-9]+)((\s?[a-zA-Z0-9]+=[\"\\\'][^\"\\\']*[\"\\\']\s?)*)>/' |
1333
|
|
|
,array('Tools', 'minifyHTMLpregCallback') |
1334
|
|
|
,$html_content); |
1335
|
|
|
|
1336
|
|
|
require_once(_PS_TOOL_DIR_.'minify_html/minify_html.class.php'); |
1337
|
|
|
$html_content = str_replace(chr(194) . chr(160), ' ', $html_content); |
1338
|
|
|
$html_content = Minify_HTML::minify($html_content, array('xhtml', 'cssMinifier', 'jsMinifier')); |
1339
|
|
|
|
1340
|
|
|
if (Configuration::get('PS_HIGH_HTML_THEME_COMPRESSION')) |
|
|
|
|
1341
|
|
|
{ |
1342
|
|
|
//$html_content = preg_replace('/"([^\>\s"]*)"/i', '$1', $html_content);//FIXME create a js bug |
1343
|
|
|
$html_content = preg_replace('/<!DOCTYPE \w[^\>]*dtd\">/is', '', $html_content); |
1344
|
|
|
$html_content = preg_replace('/\s\>/is', '>', $html_content); |
1345
|
|
|
$html_content = str_replace('</li>', '', $html_content); |
1346
|
|
|
$html_content = str_replace('</dt>', '', $html_content); |
1347
|
|
|
$html_content = str_replace('</dd>', '', $html_content); |
1348
|
|
|
$html_content = str_replace('</head>', '', $html_content); |
1349
|
|
|
$html_content = str_replace('<head>', '', $html_content); |
1350
|
|
|
$html_content = str_replace('</html>', '', $html_content); |
1351
|
|
|
$html_content = str_replace('</body>', '', $html_content); |
1352
|
|
|
//$html_content = str_replace('</p>', '', $html_content);//FIXME doesnt work... |
1353
|
|
|
$html_content = str_replace("</option>\n", '', $html_content);//TODO with bellow |
1354
|
|
|
$html_content = str_replace('</option>', '', $html_content); |
1355
|
|
|
$html_content = str_replace('<script type=text/javascript>', '<script>', $html_content);//Do a better expreg |
1356
|
|
|
$html_content = str_replace("<script>\n", '<script>', $html_content);//Do a better expreg |
1357
|
|
|
} |
1358
|
|
|
|
1359
|
|
|
return $html_content; |
1360
|
|
|
} |
1361
|
|
|
return false; |
1362
|
|
|
} |
1363
|
|
|
|
1364
|
|
|
/** |
1365
|
|
|
* Translates a string with underscores into camel case (e.g. first_name -> firstName) |
1366
|
|
|
* @prototype string public static function toCamelCase(string $str[, bool $capitaliseFirstChar = false]) |
1367
|
|
|
*/ |
1368
|
|
|
public static function toCamelCase($str, $capitaliseFirstChar = false) |
1369
|
|
|
{ |
1370
|
|
|
$str = strtolower($str); |
1371
|
|
|
if ($capitaliseFirstChar) |
1372
|
|
|
$str = ucfirst($str); |
1373
|
|
|
return preg_replace_callback('/_([a-z])/', create_function('$c', 'return strtoupper($c[1]);'), $str); |
1374
|
|
|
} |
1375
|
|
|
|
1376
|
|
|
public static function getBrightness($hex) |
1377
|
|
|
{ |
1378
|
|
|
$hex = str_replace('#', '', $hex); |
1379
|
|
|
$r = hexdec(substr($hex, 0, 2)); |
1380
|
|
|
$g = hexdec(substr($hex, 2, 2)); |
1381
|
|
|
$b = hexdec(substr($hex, 4, 2)); |
1382
|
|
|
return (($r * 299) + ($g * 587) + ($b * 114)) / 1000; |
1383
|
|
|
} |
1384
|
|
|
public static function minifyHTMLpregCallback($preg_matches) |
1385
|
|
|
{ |
1386
|
|
|
$args = array(); |
1387
|
|
|
preg_match_all('/[a-zA-Z0-9]+=[\"\\\'][^\"\\\']*[\"\\\']/is', $preg_matches[2], $args); |
1388
|
|
|
$args = $args[0]; |
1389
|
|
|
sort($args); |
1390
|
|
|
// if there is no args in the balise, we don't write a space (avoid previous : <title >, now : <title>) |
1391
|
|
|
if (empty($args)) |
1392
|
|
|
$output = $preg_matches[1].'>'; |
1393
|
|
|
else |
1394
|
|
|
$output = $preg_matches[1].' '.implode(' ', $args).'>'; |
1395
|
|
|
return $output; |
1396
|
|
|
} |
1397
|
|
|
|
1398
|
|
|
public static function packJSinHTML($html_content) |
1399
|
|
|
{ |
1400
|
|
|
if (strlen($html_content) > 0) |
1401
|
|
|
{ |
1402
|
|
|
$htmlContentCopy = $html_content; |
1403
|
|
|
$html_content = preg_replace_callback( |
1404
|
|
|
'/\\s*(<script\\b[^>]*?>)([\\s\\S]*?)(<\\/script>)\\s*/i' |
1405
|
|
|
,array('Tools', 'packJSinHTMLpregCallback') |
1406
|
|
|
,$html_content); |
1407
|
|
|
|
1408
|
|
|
// If the string is too big preg_replace return null: http://php.net/manual/en/function.preg-replace-callback.php |
1409
|
|
|
// In this case, we don't compress the content |
1410
|
|
|
if ($html_content === null) |
1411
|
|
|
{ |
1412
|
|
|
error_log('Error occured in function packJSinHTML'); |
1413
|
|
|
return $htmlContentCopy; |
1414
|
|
|
} |
1415
|
|
|
return $html_content; |
1416
|
|
|
} |
1417
|
|
|
return false; |
1418
|
|
|
} |
1419
|
|
|
|
1420
|
|
|
public static function packJSinHTMLpregCallback($preg_matches) |
1421
|
|
|
{ |
1422
|
|
|
$preg_matches[1] = $preg_matches[1].'/* <![CDATA[ */'; |
1423
|
|
|
$preg_matches[2] = self::packJS($preg_matches[2]); |
1424
|
|
|
$preg_matches[count($preg_matches)-1] = '/* ]]> */'.$preg_matches[count($preg_matches)-1]; |
1425
|
|
|
unset($preg_matches[0]); |
1426
|
|
|
$output = implode('', $preg_matches); |
1427
|
|
|
return $output; |
1428
|
|
|
} |
1429
|
|
|
|
1430
|
|
|
|
1431
|
|
|
public static function packJS($js_content) |
1432
|
|
|
{ |
1433
|
|
|
if (strlen($js_content) > 0) |
1434
|
|
|
{ |
1435
|
|
|
require_once(_PS_TOOL_DIR_.'js_minify/jsmin.php'); |
1436
|
|
|
return JSMin::minify($js_content); |
1437
|
|
|
} |
1438
|
|
|
return false; |
1439
|
|
|
} |
1440
|
|
|
|
1441
|
|
|
public static function minifyCSS($css_content, $fileuri = false) |
1442
|
|
|
{ |
1443
|
|
|
global $current_css_file; |
1444
|
|
|
|
1445
|
|
|
$current_css_file = $fileuri; |
1446
|
|
|
if (strlen($css_content) > 0) |
1447
|
|
|
{ |
1448
|
|
|
$css_content = preg_replace('#/\*.*?\*/#s', '', $css_content); |
1449
|
|
|
$css_content = preg_replace_callback('#url\((?:\'|")?([^\)\'"]*)(?:\'|")?\)#s',array('Tools', 'replaceByAbsoluteURL'), $css_content); |
1450
|
|
|
|
1451
|
|
|
$css_content = preg_replace('#\s+#',' ',$css_content); |
1452
|
|
|
$css_content = str_replace("\t", '', $css_content); |
1453
|
|
|
$css_content = str_replace("\n", '', $css_content); |
1454
|
|
|
//$css_content = str_replace('}', "}\n", $css_content); |
1455
|
|
|
|
1456
|
|
|
$css_content = str_replace('; ', ';', $css_content); |
1457
|
|
|
$css_content = str_replace(': ', ':', $css_content); |
1458
|
|
|
$css_content = str_replace(' {', '{', $css_content); |
1459
|
|
|
$css_content = str_replace('{ ', '{', $css_content); |
1460
|
|
|
$css_content = str_replace(', ', ',', $css_content); |
1461
|
|
|
$css_content = str_replace('} ', '}', $css_content); |
1462
|
|
|
$css_content = str_replace(' }', '}', $css_content); |
1463
|
|
|
$css_content = str_replace(';}', '}', $css_content); |
1464
|
|
|
$css_content = str_replace(':0px', ':0', $css_content); |
1465
|
|
|
$css_content = str_replace(' 0px', ' 0', $css_content); |
1466
|
|
|
$css_content = str_replace(':0em', ':0', $css_content); |
1467
|
|
|
$css_content = str_replace(' 0em', ' 0', $css_content); |
1468
|
|
|
$css_content = str_replace(':0pt', ':0', $css_content); |
1469
|
|
|
$css_content = str_replace(' 0pt', ' 0', $css_content); |
1470
|
|
|
$css_content = str_replace(':0%', ':0', $css_content); |
1471
|
|
|
$css_content = str_replace(' 0%', ' 0', $css_content); |
1472
|
|
|
|
1473
|
|
|
return trim($css_content); |
1474
|
|
|
} |
1475
|
|
|
return false; |
1476
|
|
|
} |
1477
|
|
|
|
1478
|
|
|
public static function replaceByAbsoluteURL($matches) |
1479
|
|
|
{ |
1480
|
|
|
global $current_css_file; |
1481
|
|
|
|
1482
|
|
|
$protocol_link = self::getCurrentUrlProtocolPrefix(); |
1483
|
|
|
|
1484
|
|
|
if (array_key_exists(1, $matches)) |
1485
|
|
|
{ |
1486
|
|
|
$tmp = dirname($current_css_file).'/'.$matches[1]; |
1487
|
|
|
return 'url(\''.$protocol_link.self::getMediaServer($tmp).$tmp.'\')'; |
1488
|
|
|
} |
1489
|
|
|
return false; |
1490
|
|
|
} |
1491
|
|
|
|
1492
|
|
|
/** |
1493
|
|
|
* addJS load a javascript file in the header |
1494
|
|
|
* |
1495
|
|
|
* @param mixed $js_uri |
1496
|
|
|
* @return void |
1497
|
|
|
*/ |
1498
|
|
|
public static function addJS($js_uri) |
1499
|
|
|
{ |
1500
|
|
|
global $js_files; |
1501
|
|
|
if (!isset($js_files)) |
1502
|
|
|
$js_files = array(); |
1503
|
|
|
// avoid useless operation... |
1504
|
|
|
if (in_array($js_uri, $js_files)) |
1505
|
|
|
return true; |
1506
|
|
|
|
1507
|
|
|
// detect mass add |
1508
|
|
|
if (!is_array($js_uri) && !in_array($js_uri, $js_files)) |
1509
|
|
|
$js_uri = array($js_uri); |
1510
|
|
|
else |
1511
|
|
|
foreach ($js_uri as $key => $js) |
|
|
|
|
1512
|
|
|
if (in_array($js, $js_files)) |
1513
|
|
|
unset($js_uri[$key]); |
1514
|
|
|
|
1515
|
|
|
//overriding of modules js files |
1516
|
|
|
foreach ($js_uri AS $key => &$file) |
|
|
|
|
1517
|
|
|
{ |
1518
|
|
|
if (!preg_match('/^http(s?):\/\//i', $file)) |
1519
|
|
|
{ |
1520
|
|
|
$different = 0; |
1521
|
|
|
$override_path = str_replace(__PS_BASE_URI__.'modules/', _PS_ROOT_DIR_.'/themes/'._THEME_NAME_.'/js/modules/', $file, $different); |
1522
|
|
|
if ($different && file_exists($override_path)) |
|
|
|
|
1523
|
|
|
$file = str_replace(__PS_BASE_URI__.'modules/', __PS_BASE_URI__.'themes/'._THEME_NAME_.'/js/modules/', $file, $different); |
1524
|
|
|
else |
1525
|
|
|
{ |
1526
|
|
|
// remove PS_BASE_URI on _PS_ROOT_DIR_ for the following |
1527
|
|
|
$url_data = parse_url($file); |
1528
|
|
|
$file_uri = _PS_ROOT_DIR_.self::str_replace_once(__PS_BASE_URI__, DIRECTORY_SEPARATOR, $url_data['path']); |
1529
|
|
|
// check if js files exists |
1530
|
|
|
if (!file_exists($file_uri)) |
1531
|
|
|
unset($js_uri[$key]); |
1532
|
|
|
} |
1533
|
|
|
} |
1534
|
|
|
} |
1535
|
|
|
|
1536
|
|
|
// adding file to the big array... |
1537
|
|
|
$js_files = array_merge($js_files, $js_uri); |
1538
|
|
|
|
1539
|
|
|
return true; |
1540
|
|
|
} |
1541
|
|
|
|
1542
|
|
|
/** |
1543
|
|
|
* addCSS allows you to add stylesheet at any time. |
1544
|
|
|
* |
1545
|
|
|
* @param mixed $css_uri |
1546
|
|
|
* @param string $css_media_type |
1547
|
|
|
* @return true |
1548
|
|
|
*/ |
1549
|
|
|
public static function addCSS($css_uri, $css_media_type = 'all') |
1550
|
|
|
{ |
1551
|
|
|
global $css_files; |
1552
|
|
|
|
1553
|
|
|
if (is_array($css_uri)) |
1554
|
|
|
{ |
1555
|
|
|
foreach ($css_uri as $file => $media_type) |
1556
|
|
|
self::addCSS($file, $media_type); |
1557
|
|
|
return true; |
1558
|
|
|
} |
1559
|
|
|
|
1560
|
|
|
//overriding of modules css files |
1561
|
|
|
$different = 0; |
1562
|
|
|
$override_path = str_replace(__PS_BASE_URI__.'modules/', _PS_ROOT_DIR_.'/themes/'._THEME_NAME_.'/css/modules/', $css_uri, $different); |
1563
|
|
|
if ($different && file_exists($override_path)) |
|
|
|
|
1564
|
|
|
$css_uri = str_replace(__PS_BASE_URI__.'modules/', __PS_BASE_URI__.'themes/'._THEME_NAME_.'/css/modules/', $css_uri, $different); |
1565
|
|
|
else |
1566
|
|
|
{ |
1567
|
|
|
// remove PS_BASE_URI on _PS_ROOT_DIR_ for the following |
1568
|
|
|
$url_data = parse_url($css_uri); |
1569
|
|
|
$file_uri = _PS_ROOT_DIR_.self::str_replace_once(__PS_BASE_URI__, DIRECTORY_SEPARATOR, $url_data['path']); |
1570
|
|
|
// check if css files exists |
1571
|
|
|
if (!file_exists($file_uri)) |
1572
|
|
|
return true; |
1573
|
|
|
} |
1574
|
|
|
|
1575
|
|
|
// detect mass add |
1576
|
|
|
$css_uri = array($css_uri => $css_media_type); |
1577
|
|
|
|
1578
|
|
|
// adding file to the big array... |
1579
|
|
|
if (is_array($css_files)) |
1580
|
|
|
$css_files = array_merge($css_files, $css_uri); |
1581
|
|
|
else |
1582
|
|
|
$css_files = $css_uri; |
1583
|
|
|
|
1584
|
|
|
return true; |
1585
|
|
|
} |
1586
|
|
|
|
1587
|
|
|
|
1588
|
|
|
/** |
1589
|
|
|
* Combine Compress and Cache CSS (ccc) calls |
1590
|
|
|
* |
1591
|
|
|
*/ |
1592
|
|
|
public static function cccCss() { |
1593
|
|
|
global $css_files; |
1594
|
|
|
//inits |
1595
|
|
|
$css_files_by_media = array(); |
1596
|
|
|
$compressed_css_files = array(); |
1597
|
|
|
$compressed_css_files_not_found = array(); |
1598
|
|
|
$compressed_css_files_infos = array(); |
1599
|
|
|
$protocolLink = self::getCurrentUrlProtocolPrefix(); |
1600
|
|
|
|
1601
|
|
|
// group css files by media |
1602
|
|
|
foreach ($css_files as $filename => $media) |
1603
|
|
|
{ |
1604
|
|
|
if (!array_key_exists($media, $css_files_by_media)) |
1605
|
|
|
$css_files_by_media[$media] = array(); |
1606
|
|
|
|
1607
|
|
|
$infos = array(); |
1608
|
|
|
$infos['uri'] = $filename; |
1609
|
|
|
$url_data = parse_url($filename); |
1610
|
|
|
$infos['path'] = _PS_ROOT_DIR_.self::str_replace_once(__PS_BASE_URI__, '/', $url_data['path']); |
1611
|
|
|
$css_files_by_media[$media]['files'][] = $infos; |
1612
|
|
|
if (!array_key_exists('date', $css_files_by_media[$media])) |
1613
|
|
|
$css_files_by_media[$media]['date'] = 0; |
1614
|
|
|
$css_files_by_media[$media]['date'] = max( |
1615
|
|
|
file_exists($infos['path']) ? filemtime($infos['path']) : 0, |
1616
|
|
|
$css_files_by_media[$media]['date'] |
1617
|
|
|
); |
1618
|
|
|
|
1619
|
|
|
if (!array_key_exists($media, $compressed_css_files_infos)) |
1620
|
|
|
$compressed_css_files_infos[$media] = array('key' => ''); |
1621
|
|
|
$compressed_css_files_infos[$media]['key'] .= $filename; |
1622
|
|
|
} |
1623
|
|
|
|
1624
|
|
|
// get compressed css file infos |
1625
|
|
|
foreach ($compressed_css_files_infos as $media => &$info) |
1626
|
|
|
{ |
1627
|
|
|
$key = md5($info['key'].$protocolLink); |
1628
|
|
|
$filename = _PS_THEME_DIR_.'cache/'.$key.'_'.$media.'.css'; |
1629
|
|
|
$info = array( |
1630
|
|
|
'key' => $key, |
1631
|
|
|
'date' => file_exists($filename) ? filemtime($filename) : 0 |
1632
|
|
|
); |
1633
|
|
|
} |
1634
|
|
|
// aggregate and compress css files content, write new caches files |
1635
|
|
|
foreach ($css_files_by_media as $media => $media_infos) |
1636
|
|
|
{ |
1637
|
|
|
$cache_filename = _PS_THEME_DIR_.'cache/'.$compressed_css_files_infos[$media]['key'].'_'.$media.'.css'; |
1638
|
|
|
if ($media_infos['date'] > $compressed_css_files_infos[$media]['date']) |
1639
|
|
|
{ |
1640
|
|
|
$compressed_css_files[$media] = ''; |
1641
|
|
|
foreach ($media_infos['files'] as $file_infos) |
1642
|
|
|
{ |
1643
|
|
|
if (file_exists($file_infos['path'])) |
1644
|
|
|
$compressed_css_files[$media] .= self::minifyCSS(file_get_contents($file_infos['path']), $file_infos['uri']); |
1645
|
|
|
else |
1646
|
|
|
$compressed_css_files_not_found[] = $file_infos['path']; |
1647
|
|
|
} |
1648
|
|
|
if (!empty($compressed_css_files_not_found)) |
1649
|
|
|
$content = '/* WARNING ! file(s) not found : "'. |
1650
|
|
|
implode(',', $compressed_css_files_not_found). |
1651
|
|
|
'" */'."\n".$compressed_css_files[$media]; |
1652
|
|
|
else |
1653
|
|
|
$content = $compressed_css_files[$media]; |
1654
|
|
|
file_put_contents($cache_filename, $content); |
1655
|
|
|
chmod($cache_filename, 0777); |
1656
|
|
|
} |
1657
|
|
|
$compressed_css_files[$media] = $cache_filename; |
1658
|
|
|
} |
1659
|
|
|
|
1660
|
|
|
// rebuild the original css_files array |
1661
|
|
|
$css_files = array(); |
1662
|
|
|
foreach ($compressed_css_files as $media => $filename) |
1663
|
|
|
{ |
1664
|
|
|
$url = str_replace(_PS_THEME_DIR_, _THEMES_DIR_._THEME_NAME_.'/', $filename); |
1665
|
|
|
$css_files[$protocolLink.self::getMediaServer($url).$url] = $media; |
1666
|
|
|
} |
1667
|
|
|
} |
1668
|
|
|
|
1669
|
|
|
|
1670
|
|
|
/** |
1671
|
|
|
* Combine Compress and Cache (ccc) JS calls |
1672
|
|
|
*/ |
1673
|
|
|
public static function cccJS() { |
1674
|
|
|
global $js_files; |
1675
|
|
|
//inits |
1676
|
|
|
$compressed_js_files_not_found = array(); |
1677
|
|
|
$js_files_infos = array(); |
1678
|
|
|
$js_files_date = 0; |
1679
|
|
|
$compressed_js_file_date = 0; |
|
|
|
|
1680
|
|
|
$compressed_js_filename = ''; |
1681
|
|
|
$js_external_files = array(); |
1682
|
|
|
$protocolLink = self::getCurrentUrlProtocolPrefix(); |
1683
|
|
|
|
1684
|
|
|
// get js files infos |
1685
|
|
|
foreach ($js_files as $filename) |
1686
|
|
|
{ |
1687
|
|
|
$expr = explode(':', $filename); |
1688
|
|
|
|
1689
|
|
|
if ($expr[0] == 'http') |
1690
|
|
|
$js_external_files[] = $filename; |
1691
|
|
|
else |
1692
|
|
|
{ |
1693
|
|
|
$infos = array(); |
1694
|
|
|
$infos['uri'] = $filename; |
1695
|
|
|
$url_data = parse_url($filename); |
1696
|
|
|
$infos['path'] =_PS_ROOT_DIR_.self::str_replace_once(__PS_BASE_URI__, '/', $url_data['path']); |
1697
|
|
|
$js_files_infos[] = $infos; |
1698
|
|
|
|
1699
|
|
|
$js_files_date = max( |
1700
|
|
|
file_exists($infos['path']) ? filemtime($infos['path']) : 0, |
1701
|
|
|
$js_files_date |
1702
|
|
|
); |
1703
|
|
|
$compressed_js_filename .= $filename; |
1704
|
|
|
} |
1705
|
|
|
} |
1706
|
|
|
|
1707
|
|
|
// get compressed js file infos |
1708
|
|
|
$compressed_js_filename = md5($compressed_js_filename); |
1709
|
|
|
|
1710
|
|
|
$compressed_js_path = _PS_THEME_DIR_.'cache/'.$compressed_js_filename.'.js'; |
1711
|
|
|
$compressed_js_file_date = file_exists($compressed_js_path) ? filemtime($compressed_js_path) : 0; |
1712
|
|
|
|
1713
|
|
|
// aggregate and compress js files content, write new caches files |
1714
|
|
|
if ($js_files_date > $compressed_js_file_date) |
1715
|
|
|
{ |
1716
|
|
|
$content = ''; |
1717
|
|
|
foreach ($js_files_infos as $file_infos) |
1718
|
|
|
{ |
1719
|
|
|
if (file_exists($file_infos['path'])) |
1720
|
|
|
$content .= file_get_contents($file_infos['path']).';'; |
1721
|
|
|
else |
1722
|
|
|
$compressed_js_files_not_found[] = $file_infos['path']; |
1723
|
|
|
} |
1724
|
|
|
$content = self::packJS($content); |
1725
|
|
|
|
1726
|
|
|
if (!empty($compressed_js_files_not_found)) |
1727
|
|
|
$content = '/* WARNING ! file(s) not found : "'. |
1728
|
|
|
implode(',', $compressed_js_files_not_found). |
1729
|
|
|
'" */'."\n".$content; |
1730
|
|
|
|
1731
|
|
|
file_put_contents($compressed_js_path, $content); |
1732
|
|
|
chmod($compressed_js_path, 0777); |
1733
|
|
|
} |
1734
|
|
|
|
1735
|
|
|
// rebuild the original js_files array |
1736
|
|
|
$url = str_replace(_PS_ROOT_DIR_.'/', __PS_BASE_URI__, $compressed_js_path); |
1737
|
|
|
$js_files = array_merge(array($protocolLink.self::getMediaServer($url).$url), $js_external_files); |
1738
|
|
|
|
1739
|
|
|
} |
1740
|
|
|
|
1741
|
|
|
private static $_cache_nb_media_servers = null; |
1742
|
|
|
public static function getMediaServer($filename) |
1743
|
|
|
{ |
1744
|
|
|
if (self::$_cache_nb_media_servers === null) |
1745
|
|
|
{ |
1746
|
|
|
if (_MEDIA_SERVER_1_ == '') |
1747
|
|
|
self::$_cache_nb_media_servers = 0; |
1748
|
|
|
elseif (_MEDIA_SERVER_2_ == '') |
1749
|
|
|
self::$_cache_nb_media_servers = 1; |
1750
|
|
|
elseif (_MEDIA_SERVER_3_ == '') |
1751
|
|
|
self::$_cache_nb_media_servers = 2; |
1752
|
|
|
else |
1753
|
|
|
self::$_cache_nb_media_servers = 3; |
1754
|
|
|
} |
1755
|
|
|
|
1756
|
|
|
if (self::$_cache_nb_media_servers AND ($id_media_server = (abs(crc32($filename)) % self::$_cache_nb_media_servers + 1))) |
1757
|
|
|
return constant('_MEDIA_SERVER_'.$id_media_server.'_'); |
1758
|
|
|
return self::getHttpHost(); |
1759
|
|
|
} |
1760
|
|
|
|
1761
|
|
|
public static function generateHtaccess($path, $rewrite_settings, $cache_control, $specific = '', $disableMuliviews = false) |
1762
|
|
|
{ |
1763
|
|
|
$tab = array('ErrorDocument' => array(), 'RewriteEngine' => array(), 'RewriteRule' => array()); |
1764
|
|
|
$multilang = (Language::countActiveLanguages() > 1); |
1765
|
|
|
|
1766
|
|
|
// ErrorDocument |
1767
|
|
|
$tab['ErrorDocument']['comment'] = '# Catch 404 errors'; |
1768
|
|
|
$tab['ErrorDocument']['content'] = '404 '.__PS_BASE_URI__.'404.php'; |
1769
|
|
|
|
1770
|
|
|
// RewriteEngine |
1771
|
|
|
$tab['RewriteEngine']['comment'] = '# URL rewriting module activation'; |
1772
|
|
|
|
1773
|
|
|
// RewriteRules |
1774
|
|
|
$tab['RewriteRule']['comment'] = '# URL rewriting rules'; |
1775
|
|
|
|
1776
|
|
|
// Compatibility with the old image filesystem |
1777
|
|
|
if (Configuration::get('PS_LEGACY_IMAGES')) |
|
|
|
|
1778
|
|
|
{ |
1779
|
|
|
$tab['RewriteRule']['content']['^([a-z0-9]+)\-([a-z0-9]+)(\-[_a-zA-Z0-9-]*)/[_a-zA-Z0-9-]*\.jpg$'] = _PS_PROD_IMG_.'$1-$2$3.jpg [L]'; |
1780
|
|
|
$tab['RewriteRule']['content']['^([0-9]+)\-([0-9]+)/[_a-zA-Z0-9-]*\.jpg$'] = _PS_PROD_IMG_.'$1-$2.jpg [L]'; |
1781
|
|
|
} |
1782
|
|
|
|
1783
|
|
|
// Rewriting for product image id < 100 millions |
1784
|
|
|
$tab['RewriteRule']['content']['^([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$'] = _PS_PROD_IMG_.'$1/$1$2.jpg [L]'; |
1785
|
|
|
$tab['RewriteRule']['content']['^([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$'] = _PS_PROD_IMG_.'$1/$2/$1$2$3.jpg [L]'; |
1786
|
|
|
$tab['RewriteRule']['content']['^([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$'] = _PS_PROD_IMG_.'$1/$2/$3/$1$2$3$4.jpg [L]'; |
1787
|
|
|
$tab['RewriteRule']['content']['^([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$'] = _PS_PROD_IMG_.'$1/$2/$3/$4/$1$2$3$4$5.jpg [L]'; |
1788
|
|
|
$tab['RewriteRule']['content']['^([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$'] = _PS_PROD_IMG_.'$1/$2/$3/$4/$5/$1$2$3$4$5$6.jpg [L]'; |
1789
|
|
|
$tab['RewriteRule']['content']['^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$'] = _PS_PROD_IMG_.'$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7.jpg [L]'; |
1790
|
|
|
$tab['RewriteRule']['content']['^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$'] = _PS_PROD_IMG_.'$1/$2/$3/$4/$5/$6/$7/$1$2$3$4$5$6$7$8.jpg [L]'; |
1791
|
|
|
$tab['RewriteRule']['content']['^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$'] = _PS_PROD_IMG_.'$1/$2/$3/$4/$5/$6/$7/$8/$1$2$3$4$5$6$7$8$9.jpg [L]'; |
1792
|
|
|
|
1793
|
|
|
$tab['RewriteRule']['content']['^c/([0-9]+)(\-[_a-zA-Z0-9-]*)/[_a-zA-Z0-9-]*\.jpg$'] = 'img/c/$1$2.jpg [L]'; |
1794
|
|
|
$tab['RewriteRule']['content']['^c/([a-zA-Z-]+)/[a-zA-Z0-9-]+\.jpg$'] = 'img/c/$1.jpg [L]'; |
1795
|
|
|
|
1796
|
|
|
if ($multilang) |
1797
|
|
|
{ |
1798
|
|
|
$tab['RewriteRule']['content']['^([a-z]{2})/[a-zA-Z0-9-]*/([0-9]+)\-[a-zA-Z0-9-]*\.html'] = 'product.php?id_product=$2&isolang=$1 [QSA,L]'; |
1799
|
|
|
$tab['RewriteRule']['content']['^([a-z]{2})/([0-9]+)\-[a-zA-Z0-9-]*\.html'] = 'product.php?id_product=$2&isolang=$1 [QSA,L]'; |
1800
|
|
|
$tab['RewriteRule']['content']['^([a-z]{2})/([0-9]+)\-[a-zA-Z0-9-]*(/[a-zA-Z0-9-]*)+'] = 'category.php?id_category=$2&isolang=$1&noredirect=1 [QSA,L]'; |
1801
|
|
|
$tab['RewriteRule']['content']['^([a-z]{2})/([0-9]+)\-[a-zA-Z0-9-]*'] = 'category.php?id_category=$2&isolang=$1 [QSA,L]'; |
1802
|
|
|
$tab['RewriteRule']['content']['^([a-z]{2})/content/([0-9]+)\-[a-zA-Z0-9-]*'] = 'cms.php?isolang=$1&id_cms=$2 [QSA,L]'; |
1803
|
|
|
$tab['RewriteRule']['content']['^([a-z]{2})/content/category/([0-9]+)\-[a-zA-Z0-9-]*'] = 'cms.php?isolang=$1&id_cms_category=$2 [QSA,L]'; |
1804
|
|
|
$tab['RewriteRule']['content']['^([a-z]{2})/([0-9]+)__[a-zA-Z0-9-]*'] = 'supplier.php?isolang=$1&id_supplier=$2 [QSA,L]'; |
1805
|
|
|
$tab['RewriteRule']['content']['^([a-z]{2})/([0-9]+)_[a-zA-Z0-9-]*'] = 'manufacturer.php?isolang=$1&id_manufacturer=$2 [QSA,L]'; |
1806
|
|
|
} |
1807
|
|
|
|
1808
|
|
|
// PS BASE URI automaticaly prepend the string, do not use PS defines for the image directories |
1809
|
|
|
$tab['RewriteRule']['content']['^([0-9]+)(\-[_a-zA-Z0-9-]*)/[_a-zA-Z0-9-]*\.jpg$'] = 'img/c/$1$2.jpg [L]'; |
1810
|
|
|
|
1811
|
|
|
$tab['RewriteRule']['content']['^([0-9]+)\-[a-zA-Z0-9-]*\.html'] = 'product.php?id_product=$1 [QSA,L]'; |
1812
|
|
|
$tab['RewriteRule']['content']['^[a-zA-Z0-9-]*/([0-9]+)\-[a-zA-Z0-9-]*\.html'] = 'product.php?id_product=$1 [QSA,L]'; |
1813
|
|
|
// Notice : the id_category rule has to be after product rules. |
1814
|
|
|
// If not, category with number in their name will result a bug |
1815
|
|
|
$tab['RewriteRule']['content']['^([0-9]+)\-[a-zA-Z0-9-]*(/[a-zA-Z0-9-]*)+'] = 'category.php?id_category=$1&noredirect=1 [QSA,L]'; |
1816
|
|
|
$tab['RewriteRule']['content']['^([0-9]+)\-[a-zA-Z0-9-]*'] = 'category.php?id_category=$1 [QSA,L]'; |
1817
|
|
|
$tab['RewriteRule']['content']['^([0-9]+)__([a-zA-Z0-9-]*)'] = 'supplier.php?id_supplier=$1 [QSA,L]'; |
1818
|
|
|
$tab['RewriteRule']['content']['^([0-9]+)_([a-zA-Z0-9-]*)'] = 'manufacturer.php?id_manufacturer=$1 [QSA,L]'; |
1819
|
|
|
$tab['RewriteRule']['content']['^content/([0-9]+)\-([a-zA-Z0-9-]*)'] = 'cms.php?id_cms=$1 [QSA,L]'; |
1820
|
|
|
$tab['RewriteRule']['content']['^content/category/([0-9]+)\-([a-zA-Z0-9-]*)'] = 'cms.php?id_cms_category=$1 [QSA,L]'; |
1821
|
|
|
|
1822
|
|
|
// Compatibility with the old URLs |
1823
|
|
|
if (!Configuration::get('PS_INSTALL_VERSION') OR version_compare(Configuration::get('PS_INSTALL_VERSION'), '1.4.0.7') == -1) |
1824
|
|
|
{ |
1825
|
|
|
// This is a nasty copy/paste of the previous links, but with "lang-en" instead of "en" |
1826
|
|
|
// Do not update it when you add something in the one at the top, it's only for the old links |
1827
|
|
|
$tab['RewriteRule']['content']['^lang-([a-z]{2})/([a-zA-Z0-9-]*)/([0-9]+)\-([a-zA-Z0-9-]*)\.html'] = 'product.php?id_product=$3&isolang=$1 [QSA,L]'; |
1828
|
|
|
$tab['RewriteRule']['content']['^lang-([a-z]{2})/([0-9]+)\-([a-zA-Z0-9-]*)\.html'] = 'product.php?id_product=$2&isolang=$1 [QSA,L]'; |
1829
|
|
|
$tab['RewriteRule']['content']['^lang-([a-z]{2})/([0-9]+)\-([a-zA-Z0-9-]*)'] = 'category.php?id_category=$2&isolang=$1 [QSA,L]'; |
1830
|
|
|
$tab['RewriteRule']['content']['^content/([0-9]+)\-([a-zA-Z0-9-]*)'] = 'cms.php?id_cms=$1 [QSA,L]'; |
1831
|
|
|
$tab['RewriteRule']['content']['^content/category/([0-9]+)\-([a-zA-Z0-9-]*)'] = 'cms.php?id_cms_category=$1 [QSA,L]'; |
1832
|
|
|
} |
1833
|
|
|
|
1834
|
|
|
Language::loadLanguages(); |
1835
|
|
|
$default_meta = Meta::getMetasByIdLang((int)Configuration::get('PS_LANG_DEFAULT')); |
1836
|
|
|
|
1837
|
|
|
if ($multilang) |
1838
|
|
|
foreach (Language::getLanguages() as $language) |
1839
|
|
|
{ |
1840
|
|
|
foreach (Meta::getMetasByIdLang($language['id_lang']) as $key => $meta) |
1841
|
|
|
if (!empty($meta['url_rewrite']) AND Validate::isLinkRewrite($meta['url_rewrite'])) |
1842
|
|
|
$tab['RewriteRule']['content']['^'.$language['iso_code'].'/'.$meta['url_rewrite'].'$'] = $meta['page'].'.php?isolang='.$language['iso_code'].' [QSA,L]'; |
1843
|
|
|
elseif (array_key_exists($key, $default_meta) && $default_meta[$key]['url_rewrite'] != '') |
1844
|
|
|
$tab['RewriteRule']['content']['^'.$language['iso_code'].'/'.$default_meta[$key]['url_rewrite'].'$'] = $default_meta[$key]['page'].'.php?isolang='.$language['iso_code'].' [QSA,L]'; |
1845
|
|
|
$tab['RewriteRule']['content']['^'.$language['iso_code'].'$'] = $language['iso_code'].'/ [QSA,L]'; |
1846
|
|
|
$tab['RewriteRule']['content']['^'.$language['iso_code'].'/([^?&]*)$'] = '$1?isolang='.$language['iso_code'].' [QSA,L]'; |
1847
|
|
|
} |
1848
|
|
|
else |
1849
|
|
|
foreach ($default_meta as $key => $meta) |
1850
|
|
|
if (!empty($meta['url_rewrite'])) |
1851
|
|
|
$tab['RewriteRule']['content']['^'.$meta['url_rewrite'].'$'] = $meta['page'].'.php [QSA,L]'; |
1852
|
|
|
elseif (array_key_exists($key, $default_meta) && $default_meta[$key]['url_rewrite'] != '') |
1853
|
|
|
$tab['RewriteRule']['content']['^'.$default_meta[$key]['url_rewrite'].'$'] = $default_meta[$key]['page'].'.php [QSA,L]'; |
1854
|
|
|
|
1855
|
|
|
if (!$writeFd = @fopen($path, 'w')) |
1856
|
|
|
return false; |
1857
|
|
|
|
1858
|
|
|
// PS Comments |
1859
|
|
|
fwrite($writeFd, "# .htaccess automaticaly generated by PrestaShop e-commerce open-source solution\n"); |
1860
|
|
|
fwrite($writeFd, "# WARNING: PLEASE DO NOT MODIFY THIS FILE MANUALLY. IF NECESSARY, ADD YOUR SPECIFIC CONFIGURATION WITH THE HTACCESS GENERATOR IN BACK OFFICE\n"); |
1861
|
|
|
fwrite($writeFd, "# http://www.prestashop.com - http://www.prestashop.com/forums\n\n"); |
1862
|
|
|
if (!empty($specific)) |
1863
|
|
|
fwrite($writeFd, $specific); |
1864
|
|
|
|
1865
|
|
|
// RewriteEngine |
1866
|
|
|
fwrite($writeFd, "\n<IfModule mod_rewrite.c>\n"); |
1867
|
|
|
|
1868
|
|
|
if ($disableMuliviews) |
1869
|
|
|
fwrite($writeFd, "\n# Disable Multiviews\nOptions -Multiviews\n\n"); |
1870
|
|
|
|
1871
|
|
|
fwrite($writeFd, $tab['RewriteEngine']['comment']."\nRewriteEngine on\n\n"); |
1872
|
|
|
fwrite($writeFd, $tab['RewriteRule']['comment']."\n"); |
1873
|
|
|
// Webservice |
1874
|
|
|
if (Configuration::get('PS_WEBSERVICE')) |
|
|
|
|
1875
|
|
|
{ |
1876
|
|
|
fwrite($writeFd, 'RewriteRule ^api/?(.*)$ '.__PS_BASE_URI__."webservice/dispatcher.php?url=$1 [QSA,L]\n"); |
1877
|
|
|
if (Configuration::get('PS_WEBSERVICE_CGI_HOST')) |
|
|
|
|
1878
|
|
|
fwrite($writeFd, 'RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]'."\n"); |
1879
|
|
|
} |
1880
|
|
|
|
1881
|
|
|
// Classic URL rewriting |
1882
|
|
|
if ($rewrite_settings) |
1883
|
|
|
foreach ($tab['RewriteRule']['content'] as $rule => $url) |
1884
|
|
|
fwrite($writeFd, 'RewriteRule '.$rule.' '.__PS_BASE_URI__.$url."\n"); |
1885
|
|
|
|
1886
|
|
|
fwrite($writeFd, "</IfModule>\n\n"); |
1887
|
|
|
|
1888
|
|
|
// ErrorDocument |
1889
|
|
|
fwrite($writeFd, $tab['ErrorDocument']['comment']."\nErrorDocument ".$tab['ErrorDocument']['content']."\n"); |
1890
|
|
|
|
1891
|
|
|
// Cache control |
1892
|
|
|
if ($cache_control) |
1893
|
|
|
{ |
1894
|
|
|
$cacheControl = " |
1895
|
|
|
<IfModule mod_expires.c> |
1896
|
|
|
ExpiresActive On |
1897
|
|
|
ExpiresByType image/gif \"access plus 1 month\" |
1898
|
|
|
ExpiresByType image/jpeg \"access plus 1 month\" |
1899
|
|
|
ExpiresByType image/png \"access plus 1 month\" |
1900
|
|
|
ExpiresByType text/css \"access plus 1 week\" |
1901
|
|
|
ExpiresByType text/javascript \"access plus 1 week\" |
1902
|
|
|
ExpiresByType application/javascript \"access plus 1 week\" |
1903
|
|
|
ExpiresByType application/x-javascript \"access plus 1 week\" |
1904
|
|
|
ExpiresByType image/x-icon \"access plus 1 year\" |
1905
|
|
|
</IfModule> |
1906
|
|
|
|
1907
|
|
|
FileETag INode MTime Size |
1908
|
|
|
<IfModule mod_deflate.c> |
1909
|
|
|
AddOutputFilterByType DEFLATE text/html |
1910
|
|
|
AddOutputFilterByType DEFLATE text/css |
1911
|
|
|
AddOutputFilterByType DEFLATE text/javascript |
1912
|
|
|
AddOutputFilterByType DEFLATE application/javascript |
1913
|
|
|
AddOutputFilterByType DEFLATE application/x-javascript |
1914
|
|
|
</IfModule> |
1915
|
|
|
"; |
1916
|
|
|
fwrite($writeFd, $cacheControl); |
1917
|
|
|
} |
1918
|
|
|
fclose($writeFd); |
1919
|
|
|
|
1920
|
|
|
Module::hookExec('afterCreateHtaccess'); |
1921
|
|
|
|
1922
|
|
|
return true; |
1923
|
|
|
} |
1924
|
|
|
|
1925
|
|
|
/** |
1926
|
|
|
* jsonDecode convert json string to php array / object |
1927
|
|
|
* |
1928
|
|
|
* @param string $json |
1929
|
|
|
* @param boolean $assoc (since 1.4.2.4) if true, convert to associativ array |
1930
|
|
|
* @return array |
1931
|
|
|
*/ |
1932
|
|
|
public static function jsonDecode($json, $assoc = false) |
1933
|
|
|
{ |
1934
|
|
|
if (function_exists('json_decode')) |
1935
|
|
|
return json_decode($json, $assoc); |
1936
|
|
|
else |
1937
|
|
|
{ |
1938
|
|
|
include_once(_PS_TOOL_DIR_.'json/json.php'); |
1939
|
|
|
$pearJson = new Services_JSON(($assoc) ? SERVICES_JSON_LOOSE_TYPE : 0); |
1940
|
|
|
return $pearJson->decode($json); |
1941
|
|
|
} |
1942
|
|
|
} |
1943
|
|
|
|
1944
|
|
|
/** |
1945
|
|
|
* Convert an array to json string |
1946
|
|
|
* |
1947
|
|
|
* @param array $data |
1948
|
|
|
* @return string json |
1949
|
|
|
*/ |
1950
|
|
|
public static function jsonEncode($data) |
1951
|
|
|
{ |
1952
|
|
|
if (function_exists('json_encode')) |
1953
|
|
|
return json_encode($data); |
1954
|
|
|
else |
1955
|
|
|
{ |
1956
|
|
|
include_once(_PS_TOOL_DIR_.'json/json.php'); |
1957
|
|
|
$pearJson = new Services_JSON(); |
1958
|
|
|
return $pearJson->encode($data); |
1959
|
|
|
} |
1960
|
|
|
} |
1961
|
|
|
|
1962
|
|
|
/** |
1963
|
|
|
* Display a warning message indicating that the method is deprecated |
1964
|
|
|
*/ |
1965
|
|
|
public static function displayAsDeprecated() |
1966
|
|
|
{ |
1967
|
|
|
if (_PS_DISPLAY_COMPATIBILITY_WARNING_) |
1968
|
|
|
{ |
1969
|
|
|
$backtrace = debug_backtrace(); |
1970
|
|
|
$callee = next($backtrace); |
1971
|
|
|
trigger_error('Function <strong>'.$callee['function'].'()</strong> is deprecated in <strong>'.$callee['file'].'</strong> on line <strong>'.$callee['line'].'</strong><br />', E_USER_WARNING); |
1972
|
|
|
|
1973
|
|
|
$message = self::displayError('The function').' '.$callee['function'].' ('.self::displayError('Line').' '.$callee['line'].') '.self::displayError('is deprecated and will be removed in the next major version.'); |
1974
|
|
|
|
1975
|
|
|
Logger::addLog($message, 3, $callee['class']); |
1976
|
|
|
} |
1977
|
|
|
} |
1978
|
|
|
|
1979
|
|
|
/** |
1980
|
|
|
* Display a warning message indicating that the parameter is deprecated |
1981
|
|
|
*/ |
1982
|
|
|
public static function displayParameterAsDeprecated($parameter) |
1983
|
|
|
{ |
1984
|
|
|
if (_PS_DISPLAY_COMPATIBILITY_WARNING_) |
1985
|
|
|
{ |
1986
|
|
|
$backtrace = debug_backtrace(); |
1987
|
|
|
$callee = next($backtrace); |
1988
|
|
|
trigger_error('Parameter <strong>'.$parameter.'</strong> in function <strong>'.$callee['function'].'()</strong> is deprecated in <strong>'.$callee['file'].'</strong> on line <strong>'.$callee['Line'].'</strong><br />', E_USER_WARNING); |
1989
|
|
|
|
1990
|
|
|
$message = self::displayError('The parameter').' '.$parameter.' '.self::displayError(' in function ').' '.$callee['function'].' ('.self::displayError('Line').' '.$callee['Line'].') '.self::displayError('is deprecated and will be removed in the next major version.'); |
1991
|
|
|
Logger::addLog($message, 3, $callee['class']); |
1992
|
|
|
} |
1993
|
|
|
} |
1994
|
|
|
|
1995
|
|
|
public static function enableCache($level = 1) |
1996
|
|
|
{ |
1997
|
|
|
global $smarty; |
1998
|
|
|
|
1999
|
|
|
if (!Configuration::get('PS_SMARTY_CACHE')) |
|
|
|
|
2000
|
|
|
return; |
2001
|
|
|
if ($smarty->force_compile == 0 AND $smarty->caching == $level) |
2002
|
|
|
return ; |
2003
|
|
|
self::$_forceCompile = (int)($smarty->force_compile); |
2004
|
|
|
self::$_caching = (int)($smarty->caching); |
2005
|
|
|
$smarty->force_compile = 0; |
2006
|
|
|
$smarty->caching = (int)($level); |
2007
|
|
|
} |
2008
|
|
|
|
2009
|
|
|
public static function restoreCacheSettings() |
2010
|
|
|
{ |
2011
|
|
|
global $smarty; |
2012
|
|
|
|
2013
|
|
|
if (isset(self::$_forceCompile)) |
2014
|
|
|
$smarty->force_compile = (int)(self::$_forceCompile); |
2015
|
|
|
if (isset(self::$_caching)) |
2016
|
|
|
$smarty->caching = (int)(self::$_caching); |
2017
|
|
|
} |
2018
|
|
|
|
2019
|
|
|
public static function isCallable($function) |
2020
|
|
|
{ |
2021
|
|
|
$disabled = explode(',', ini_get('disable_functions')); |
2022
|
|
|
return (!in_array($function, $disabled) AND is_callable($function)); |
2023
|
|
|
} |
2024
|
|
|
|
2025
|
|
|
public static function pRegexp($s, $delim) |
2026
|
|
|
{ |
2027
|
|
|
$s = str_replace($delim, '\\'.$delim, $s); |
2028
|
|
|
foreach (array('?', '[', ']', '(', ')', '{', '}', '-', '.', '+', '*', '^', '$') as $char) |
2029
|
|
|
$s = str_replace($char, '\\'.$char, $s); |
2030
|
|
|
return $s; |
2031
|
|
|
} |
2032
|
|
|
|
2033
|
|
|
public static function str_replace_once($needle , $replace, $haystack) |
2034
|
|
|
{ |
2035
|
|
|
$pos = strpos($haystack, $needle); |
2036
|
|
|
if ($pos === false) |
2037
|
|
|
return $haystack; |
2038
|
|
|
return substr_replace($haystack, $replace, $pos, strlen($needle)); |
2039
|
|
|
} |
2040
|
|
|
|
2041
|
|
|
|
2042
|
|
|
/** |
2043
|
|
|
* Function property_exists does not exist in PHP < 5.1 |
2044
|
|
|
* |
2045
|
|
|
* @param object or class $class |
2046
|
|
|
* @param string $property |
2047
|
|
|
* @return boolean |
2048
|
|
|
*/ |
2049
|
|
|
public static function property_exists($class, $property) |
2050
|
|
|
{ |
2051
|
|
|
if (function_exists('property_exists')) |
2052
|
|
|
return property_exists($class, $property); |
2053
|
|
|
|
2054
|
|
|
if (is_object($class)) |
2055
|
|
|
$vars = get_object_vars($class); |
2056
|
|
|
else |
2057
|
|
|
$vars = get_class_vars($class); |
2058
|
|
|
|
2059
|
|
|
return array_key_exists($property, $vars); |
2060
|
|
|
} |
2061
|
|
|
|
2062
|
|
|
/** |
2063
|
|
|
* @desc identify the version of php |
2064
|
|
|
* @return string |
2065
|
|
|
*/ |
2066
|
|
|
public static function checkPhpVersion() |
2067
|
|
|
{ |
2068
|
|
|
$version = null; |
|
|
|
|
2069
|
|
|
|
2070
|
|
|
if (defined('PHP_VERSION')) |
2071
|
|
|
$version = PHP_VERSION; |
2072
|
|
|
else |
2073
|
|
|
$version = phpversion(''); |
2074
|
|
|
|
2075
|
|
|
//Case management system of ubuntu, php version return 5.2.4-2ubuntu5.2 |
2076
|
|
|
if (strpos($version, '-') !== false ) |
2077
|
|
|
$version = substr($version, 0, strpos($version, '-')); |
2078
|
|
|
|
2079
|
|
|
return $version; |
2080
|
|
|
} |
2081
|
|
|
|
2082
|
|
|
/** |
2083
|
|
|
* @desc selection of Smarty depending on the version of php |
2084
|
|
|
* |
2085
|
|
|
*/ |
2086
|
|
|
public static function selectionVersionSmarty() |
2087
|
|
|
{ |
2088
|
|
|
//Smarty 3 requirements PHP 5.2 + |
2089
|
|
|
if (strnatcmp(self::checkPhpVersion(),'5.2.0') >= 0) |
2090
|
|
|
Configuration::updateValue('PS_FORCE_SMARTY_2', 0); |
|
|
|
|
2091
|
|
|
else |
2092
|
|
|
Configuration::updateValue('PS_FORCE_SMARTY_2',1); |
|
|
|
|
2093
|
|
|
} |
2094
|
|
|
|
2095
|
|
|
/** |
2096
|
|
|
* @desc try to open a zip file in order to check if it's valid |
2097
|
|
|
* @return bool success |
2098
|
|
|
*/ |
2099
|
|
|
public static function ZipTest($fromFile) |
2100
|
|
|
{ |
2101
|
|
|
if (class_exists('ZipArchive', false)) |
2102
|
|
|
{ |
2103
|
|
|
$zip = new ZipArchive(); |
2104
|
|
|
return ($zip->open($fromFile, ZIPARCHIVE::CHECKCONS) === true); |
2105
|
|
|
} |
2106
|
|
|
else |
2107
|
|
|
{ |
2108
|
|
|
require_once(dirname(__FILE__).'/../tools/pclzip/pclzip.lib.php'); |
2109
|
|
|
$zip = new PclZip($fromFile); |
2110
|
|
|
return ($zip->privCheckFormat() === true); |
2111
|
|
|
} |
2112
|
|
|
} |
2113
|
|
|
|
2114
|
|
|
/** |
2115
|
|
|
* @desc extract a zip file to the given directory |
2116
|
|
|
* @return bool success |
2117
|
|
|
*/ |
2118
|
|
|
public static function ZipExtract($fromFile, $toDir) |
2119
|
|
|
{ |
2120
|
|
|
if (!file_exists($toDir)) |
2121
|
|
|
mkdir($toDir, 0777); |
2122
|
|
|
if (class_exists('ZipArchive', false)) |
2123
|
|
|
{ |
2124
|
|
|
$zip = new ZipArchive(); |
2125
|
|
|
if ($zip->open($fromFile) === true AND $zip->extractTo($toDir) AND $zip->close()) |
2126
|
|
|
return true; |
2127
|
|
|
return false; |
2128
|
|
|
} |
2129
|
|
|
else |
2130
|
|
|
{ |
2131
|
|
|
require_once(dirname(__FILE__).'/../tools/pclzip/pclzip.lib.php'); |
2132
|
|
|
$zip = new PclZip($fromFile); |
2133
|
|
|
$list = $zip->extract(PCLZIP_OPT_PATH, $toDir); |
2134
|
|
|
foreach ($list as $extractedFile) |
2135
|
|
|
if ($extractedFile['status'] != 'ok') |
2136
|
|
|
return false; |
2137
|
|
|
return true; |
2138
|
|
|
} |
2139
|
|
|
} |
2140
|
|
|
|
2141
|
|
|
/** |
2142
|
|
|
* Get products order field name for queries. |
2143
|
|
|
* |
2144
|
|
|
* @param string $type by|way |
2145
|
|
|
* @param string $value If no index given, use default order from admin -> pref -> products |
2146
|
|
|
*/ |
2147
|
|
|
public static function getProductsOrder($type, $value = null, $prefix = false) |
2148
|
|
|
{ |
2149
|
|
|
switch ($type) |
2150
|
|
|
{ |
2151
|
|
|
case 'by' : |
2152
|
|
|
$list = array(0 => 'name', 1 => 'price', 2 => 'date_add', 3 => 'date_upd', 4 => 'position', 5 => 'manufacturer_name', 6 => 'quantity'); |
2153
|
|
|
$value = (is_null($value) || $value === false || $value === '') ? (int)Configuration::get('PS_PRODUCTS_ORDER_BY') : $value; |
2154
|
|
|
$value = (isset($list[$value])) ? $list[$value] : ((in_array($value, $list)) ? $value : 'position'); |
2155
|
|
|
$orderByPrefix = ''; |
2156
|
|
|
if ($prefix) |
2157
|
|
|
{ |
2158
|
|
|
if ($value == 'id_product' || $value == 'date_add' || $value == 'date_upd' || $value == 'price') |
2159
|
|
|
$orderByPrefix = 'p.'; |
2160
|
|
|
elseif ($value == 'name') |
2161
|
|
|
$orderByPrefix = 'pl.'; |
2162
|
|
|
elseif ($value == 'manufacturer_name' && $prefix) |
2163
|
|
|
{ |
2164
|
|
|
$orderByPrefix = 'm.'; |
2165
|
|
|
$value = 'name'; |
2166
|
|
|
} |
2167
|
|
|
elseif ($value == 'position' || empty($value)) |
2168
|
|
|
$orderByPrefix = 'cp.'; |
2169
|
|
|
} |
2170
|
|
|
|
2171
|
|
|
return $orderByPrefix.$value; |
2172
|
|
|
break; |
|
|
|
|
2173
|
|
|
|
2174
|
|
|
case 'way' : |
2175
|
|
|
$value = (is_null($value) || $value === false || $value === '') ? (int)Configuration::get('PS_PRODUCTS_ORDER_WAY') : $value; |
2176
|
|
|
$list = array(0 => 'asc', 1 => 'desc'); |
2177
|
|
|
return ((isset($list[$value])) ? $list[$value] : ((in_array($value, $list)) ? $value : 'asc')); |
2178
|
|
|
break; |
|
|
|
|
2179
|
|
|
} |
2180
|
|
|
} |
2181
|
|
|
|
2182
|
|
|
/** |
2183
|
|
|
* Convert a shorthand byte value from a PHP configuration directive to an integer value |
2184
|
|
|
* @param string $value value to convert |
2185
|
|
|
* @return int |
2186
|
|
|
*/ |
2187
|
|
|
public static function convertBytes($value) |
2188
|
|
|
{ |
2189
|
|
|
if (is_numeric($value)) |
2190
|
|
|
{ |
2191
|
|
|
return $value; |
2192
|
|
|
} |
2193
|
|
|
else |
2194
|
|
|
{ |
2195
|
|
|
$value_length = strlen($value); |
2196
|
|
|
$qty = substr($value, 0, $value_length - 1 ); |
2197
|
|
|
$unit = strtolower(substr($value, $value_length - 1)); |
2198
|
|
|
switch ($unit) |
2199
|
|
|
{ |
2200
|
|
|
case 'k': |
2201
|
|
|
$qty *= 1024; |
2202
|
|
|
break; |
2203
|
|
|
case 'm': |
2204
|
|
|
$qty *= 1048576; |
2205
|
|
|
break; |
2206
|
|
|
case 'g': |
2207
|
|
|
$qty *= 1073741824; |
2208
|
|
|
break; |
2209
|
|
|
} |
2210
|
|
|
return $qty; |
2211
|
|
|
} |
2212
|
|
|
} |
2213
|
|
|
|
2214
|
|
|
public static function display404Error() |
2215
|
|
|
{ |
2216
|
|
|
header('HTTP/1.1 404 Not Found'); |
2217
|
|
|
header('Status: 404 Not Found'); |
2218
|
|
|
include(dirname(__FILE__).'/../404.php'); |
2219
|
|
|
die; |
|
|
|
|
2220
|
|
|
} |
2221
|
|
|
|
2222
|
|
|
/** |
2223
|
|
|
* Display error and dies or silently log the error. |
2224
|
|
|
* |
2225
|
|
|
* @param string $msg |
2226
|
|
|
* @param bool $die |
2227
|
|
|
* @return success of logging |
2228
|
|
|
*/ |
2229
|
|
|
public static function dieOrLog($msg, $die = true) |
2230
|
|
|
{ |
2231
|
|
|
if ($die || (defined('_PS_MODE_DEV_') && _PS_MODE_DEV_)) |
2232
|
|
|
die($msg); |
|
|
|
|
2233
|
|
|
return Logger::addLog($msg); |
2234
|
|
|
} |
2235
|
|
|
|
2236
|
|
|
/** |
2237
|
|
|
* Clear cache for Smarty |
2238
|
|
|
* |
2239
|
|
|
* @param objet $smarty |
2240
|
|
|
*/ |
2241
|
|
|
public static function clearCache($smarty) |
2242
|
|
|
{ |
2243
|
|
|
if (!Configuration::get('PS_FORCE_SMARTY_2')) |
|
|
|
|
2244
|
|
|
$smarty->clearAllCache(); |
2245
|
|
|
else |
2246
|
|
|
$smarty->clear_all_cache(); |
2247
|
|
|
} |
2248
|
|
|
|
2249
|
|
|
/** |
2250
|
|
|
* getMemoryLimit allow to get the memory limit in octet |
2251
|
|
|
* |
2252
|
|
|
* @since 1.4.5.0 |
2253
|
|
|
* @return int the memory limit value in octet |
2254
|
|
|
*/ |
2255
|
|
|
public static function getMemoryLimit() |
2256
|
|
|
{ |
2257
|
|
|
$memory_limit = @ini_get('memory_limit'); |
2258
|
|
|
|
2259
|
|
|
if (preg_match('/[0-9]+k/i', $memory_limit)) |
2260
|
|
|
return 1024 * (int)$memory_limit; |
2261
|
|
|
|
2262
|
|
|
if (preg_match('/[0-9]+m/i', $memory_limit)) |
2263
|
|
|
return 1024 * 1024 * (int)$memory_limit; |
2264
|
|
|
|
2265
|
|
|
if (preg_match('/[0-9]+g/i', $memory_limit)) |
2266
|
|
|
return 1024 * 1024 * 1024 * (int)$memory_limit; |
2267
|
|
|
|
2268
|
|
|
return $memory_limit; |
2269
|
|
|
} |
2270
|
|
|
|
2271
|
|
|
public static function isX86_64arch() |
2272
|
|
|
{ |
2273
|
|
|
return (PHP_INT_MAX == '9223372036854775807'); |
2274
|
|
|
} |
2275
|
|
|
|
2276
|
|
|
/** |
2277
|
|
|
* apacheModExists return true if the apache module $name is loaded |
2278
|
|
|
* @TODO move this method in class Information (when it will exist) |
2279
|
|
|
* |
2280
|
|
|
* @param string $name module name |
2281
|
|
|
* @return boolean true if exists |
2282
|
|
|
* @since 1.4.5.0 |
2283
|
|
|
*/ |
2284
|
|
|
public static function apacheModExists($name) |
2285
|
|
|
{ |
2286
|
|
|
if(function_exists('apache_get_modules')) |
2287
|
|
|
{ |
2288
|
|
|
static $apacheModuleList = null; |
2289
|
|
|
|
2290
|
|
|
if (!is_array($apacheModuleList)) |
2291
|
|
|
$apacheModuleList = apache_get_modules(); |
2292
|
|
|
|
2293
|
|
|
// we need strpos (example, evasive can be evasive20) |
2294
|
|
|
foreach($apacheModuleList as $module) |
2295
|
|
|
{ |
2296
|
|
|
if (strpos($module, $name) !== false) |
2297
|
|
|
return true; |
2298
|
|
|
} |
2299
|
|
|
} |
2300
|
|
|
else{ |
2301
|
|
|
// If apache_get_modules does not exists, |
2302
|
|
|
// one solution should be parsing httpd.conf, |
2303
|
|
|
// but we could simple parse phpinfo(INFO_MODULES) return string |
2304
|
|
|
ob_start(); |
2305
|
|
|
phpinfo(INFO_MODULES); |
2306
|
|
|
$phpinfo = ob_get_contents(); |
2307
|
|
|
ob_end_clean(); |
2308
|
|
|
if (strpos($phpinfo, $name) !== false) |
2309
|
|
|
return true; |
2310
|
|
|
} |
2311
|
|
|
|
2312
|
|
|
return false; |
2313
|
|
|
} |
2314
|
|
|
} |
2315
|
|
|
|
2316
|
|
|
/** |
2317
|
|
|
* Compare 2 prices to sort products |
2318
|
|
|
* |
2319
|
|
|
* @param float $a |
2320
|
|
|
* @param float $b |
2321
|
|
|
* @return integer |
2322
|
|
|
*/ |
2323
|
|
|
/* Externalized because of a bug in PHP 5.1.6 when inside an object */ |
2324
|
|
|
function cmpPriceAsc($a,$b) |
2325
|
|
|
{ |
2326
|
|
|
if ((float)($a['price_tmp']) < (float)($b['price_tmp'])) |
2327
|
|
|
return (-1); |
2328
|
|
|
elseif ((float)($a['price_tmp']) > (float)($b['price_tmp'])) |
2329
|
|
|
return (1); |
2330
|
|
|
return (0); |
2331
|
|
|
} |
2332
|
|
|
|
2333
|
|
|
function cmpPriceDesc($a,$b) |
2334
|
|
|
{ |
2335
|
|
|
if ((float)($a['price_tmp']) < (float)($b['price_tmp'])) |
2336
|
|
|
return (1); |
2337
|
|
|
elseif ((float)($a['price_tmp']) > (float)($b['price_tmp'])) |
2338
|
|
|
return (-1); |
2339
|
|
|
return (0); |
2340
|
|
|
} |
2341
|
|
|
|
2342
|
|
|
|
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: