2015-07-06 16:58:50 +02:00
< ? php
/**
* 2007 - 2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License ( OSL 3.0 )
* that is bundled with this package in the file LICENSE . txt .
* It is also available through the world - wide - web at this URL :
* http :// opensource . org / licenses / osl - 3.0 . php
* If you did not receive a copy of the license and are unable to
* obtain it through the world - wide - web , please send an email
* to license @ prestashop . com so we can send you a copy immediately .
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future . If you wish to customize PrestaShop for your
* needs please refer to http :// www . prestashop . com for more information .
*
* @ author PrestaShop SA < contact @ prestashop . com >
* @ copyright 2007 - 2015 PrestaShop SA
* @ license http :// opensource . org / licenses / osl - 3.0 . php Open Software License ( OSL 3.0 )
* International Registered Trademark & Property of PrestaShop SA
*/
class ToolsCore
{
protected static $file_exists_cache = array ();
protected static $_forceCompile ;
protected static $_caching ;
protected static $_user_plateform ;
protected static $_user_browser ;
public static $round_mode = null ;
/**
* Random password generator
*
* @ param int $length Desired length ( optional )
* @ param string $flag Output type ( NUMERIC , ALPHANUMERIC , NO_NUMERIC , RANDOM )
* @ return bool | string Password
*/
public static function passwdGen ( $length = 8 , $flag = 'ALPHANUMERIC' )
{
$length = ( int ) $length ;
if ( $length <= 0 )
return false ;
switch ( $flag )
{
case 'NUMERIC' :
$str = '0123456789' ;
break ;
case 'NO_NUMERIC' :
$str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ;
break ;
case 'RANDOM' :
$num_bytes = ceil ( $length * 0.75 );
$bytes = self :: getBytes ( $num_bytes );
return substr ( rtrim ( base64_encode ( $bytes ), '=' ), 0 , $length );
case 'ALPHANUMERIC' :
default :
$str = 'abcdefghijkmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' ;
break ;
}
$bytes = Tools :: getBytes ( $length );
$position = 0 ;
$result = '' ;
for ( $i = 0 ; $i < $length ; $i ++ )
{
$position = ( $position + ord ( $bytes [ $i ])) % strlen ( $str );
$result .= $str [ $position ];
}
return $result ;
}
/**
* Random bytes generator
*
* Thanks to Zend for entropy
*
* @ param $length Desired length of random bytes
* @ return bool | string Random bytes
*/
public static function getBytes ( $length )
{
$length = ( int ) $length ;
if ( $length <= 0 )
return false ;
if ( function_exists ( 'openssl_random_pseudo_bytes' ))
{
$bytes = openssl_random_pseudo_bytes ( $length , $crypto_strong );
if ( $crypto_strong === true )
return $bytes ;
}
if ( function_exists ( 'mcrypt_create_iv' ))
{
$bytes = mcrypt_create_iv ( $length , MCRYPT_DEV_URANDOM );
if ( $bytes !== false && strlen ( $bytes ) === $length )
return $bytes ;
}
// Else try to get $length bytes of entropy.
// Thanks to Zend
$result = '' ;
$entropy = '' ;
$msec_per_round = 400 ;
$bits_per_round = 2 ;
$total = $length ;
$hash_length = 20 ;
while ( strlen ( $result ) < $length )
{
$bytes = ( $total > $hash_length ) ? $hash_length : $total ;
$total -= $bytes ;
for ( $i = 1 ; $i < 3 ; $i ++ )
{
$t1 = microtime ( true );
$seed = mt_rand ();
for ( $j = 1 ; $j < 50 ; $j ++ )
$seed = sha1 ( $seed );
$t2 = microtime ( true );
$entropy .= $t1 . $t2 ;
}
$div = ( int ) (( $t2 - $t1 ) * 1000000 );
if ( $div <= 0 )
$div = 400 ;
$rounds = ( int ) ( $msec_per_round * 50 / $div );
$iter = $bytes * ( int ) ( ceil ( 8 / $bits_per_round ));
for ( $i = 0 ; $i < $iter ; $i ++ )
{
$t1 = microtime ();
$seed = sha1 ( mt_rand ());
for ( $j = 0 ; $j < $rounds ; $j ++ )
$seed = sha1 ( $seed );
$t2 = microtime ();
$entropy .= $t1 . $t2 ;
}
$result .= sha1 ( $entropy , true );
}
return substr ( $result , 0 , $length );
}
public static function strReplaceFirst ( $search , $replace , $subject , $cur = 0 )
{
return ( strpos ( $subject , $search , $cur )) ? substr_replace ( $subject , $replace , ( int ) strpos ( $subject , $search , $cur ), strlen ( $search )) : $subject ;
}
/**
* Redirect user to another page
*
* @ param string $url Desired URL
* @ param string $base_uri Base URI ( optional )
* @ param Link $link
* @ param string | array $headers A list of headers to send before redirection
*/
public static function redirect ( $url , $base_uri = __PS_BASE_URI__ , Link $link = null , $headers = null )
{
if ( ! $link )
$link = Context :: getContext () -> link ;
if ( strpos ( $url , 'http://' ) === false && strpos ( $url , 'https://' ) === false && $link )
{
if ( strpos ( $url , $base_uri ) === 0 )
$url = substr ( $url , strlen ( $base_uri ));
if ( strpos ( $url , 'index.php?controller=' ) !== false && strpos ( $url , 'index.php/' ) == 0 )
{
$url = substr ( $url , strlen ( 'index.php?controller=' ));
if ( Configuration :: get ( 'PS_REWRITING_SETTINGS' ))
$url = Tools :: strReplaceFirst ( '&' , '?' , $url );
}
$explode = explode ( '?' , $url );
// don't use ssl if url is home page
// used when logout for example
$use_ssl = ! empty ( $url );
$url = $link -> getPageLink ( $explode [ 0 ], $use_ssl );
if ( isset ( $explode [ 1 ]))
$url .= '?' . $explode [ 1 ];
}
// Send additional headers
if ( $headers )
{
if ( ! is_array ( $headers ))
$headers = array ( $headers );
foreach ( $headers as $header )
header ( $header );
}
header ( 'Location: ' . $url );
exit ;
}
/**
* Redirect URLs already containing PS_BASE_URI
*
* @ param string $url Desired URL
*/
public static function redirectLink ( $url )
{
if ( ! preg_match ( '@^https?://@i' , $url ))
{
if ( strpos ( $url , __PS_BASE_URI__ ) !== false && strpos ( $url , __PS_BASE_URI__ ) == 0 )
$url = substr ( $url , strlen ( __PS_BASE_URI__ ));
if ( strpos ( $url , 'index.php?controller=' ) !== false && strpos ( $url , 'index.php/' ) == 0 )
$url = substr ( $url , strlen ( 'index.php?controller=' ));
$explode = explode ( '?' , $url );
$url = Context :: getContext () -> link -> getPageLink ( $explode [ 0 ]);
if ( isset ( $explode [ 1 ]))
$url .= '?' . $explode [ 1 ];
}
header ( 'Location: ' . $url );
exit ;
}
/**
* Redirect user to another admin page
*
* @ param string $url Desired URL
*/
public static function redirectAdmin ( $url )
{
header ( 'Location: ' . $url );
exit ;
}
/**
* getShopProtocol return the available protocol for the current shop in use
* SSL if Configuration is set on and available for the server
*
* @ return String
*/
public static function getShopProtocol ()
{
$protocol = ( Configuration :: get ( 'PS_SSL_ENABLED' ) || ( ! empty ( $_SERVER [ 'HTTPS' ])
&& Tools :: strtolower ( $_SERVER [ 'HTTPS' ]) != 'off' )) ? 'https://' : 'http://' ;
return $protocol ;
}
/**
* getProtocol return the set protocol according to configuration ( http [ s ])
* @ param bool $use_ssl true if require ssl
* @ return String ( http | https )
*/
public static function getProtocol ( $use_ssl = null )
{
return ( ! is_null ( $use_ssl ) && $use_ssl ? 'https://' : 'http://' );
}
/**
* getHttpHost return the < b > current </ b > host used , with the protocol ( http or https ) if $http is true
* This function should not be used to choose http or https domain name .
* Use Tools :: getShopDomain () or Tools :: getShopDomainSsl instead
*
* @ param bool $http
* @ param bool $entities
* @ return string host
*/
public static function getHttpHost ( $http = false , $entities = false , $ignore_port = false )
{
$host = ( isset ( $_SERVER [ 'HTTP_X_FORWARDED_HOST' ]) ? $_SERVER [ 'HTTP_X_FORWARDED_HOST' ] : $_SERVER [ 'HTTP_HOST' ]);
if ( $ignore_port && $pos = strpos ( $host , ':' ))
$host = substr ( $host , 0 , $pos );
if ( $entities )
$host = htmlspecialchars ( $host , ENT_COMPAT , 'UTF-8' );
if ( $http )
$host = ( Configuration :: get ( 'PS_SSL_ENABLED' ) ? 'https://' : 'http://' ) . $host ;
return $host ;
}
/**
* getShopDomain returns domain name according to configuration and ignoring ssl
*
* @ param bool $http if true , return domain name with protocol
* @ param bool $entities if true , convert special chars to HTML entities
* @ return string domain
*/
public static function getShopDomain ( $http = false , $entities = false )
{
if ( ! $domain = ShopUrl :: getMainShopDomain ())
$domain = Tools :: getHttpHost ();
if ( $entities )
$domain = htmlspecialchars ( $domain , ENT_COMPAT , 'UTF-8' );
if ( $http )
$domain = 'http://' . $domain ;
return $domain ;
}
/**
* getShopDomainSsl returns domain name according to configuration and depending on ssl activation
*
* @ param bool $http if true , return domain name with protocol
* @ param bool $entities if true , convert special chars to HTML entities
* @ return string domain
*/
public static function getShopDomainSsl ( $http = false , $entities = false )
{
if ( ! $domain = ShopUrl :: getMainShopDomainSSL ())
$domain = Tools :: getHttpHost ();
if ( $entities )
$domain = htmlspecialchars ( $domain , ENT_COMPAT , 'UTF-8' );
if ( $http )
$domain = ( Configuration :: get ( 'PS_SSL_ENABLED' ) ? 'https://' : 'http://' ) . $domain ;
return $domain ;
}
/**
* Get the server variable SERVER_NAME
*
* @ return string server name
*/
public static function getServerName ()
{
if ( isset ( $_SERVER [ 'HTTP_X_FORWARDED_SERVER' ]) && $_SERVER [ 'HTTP_X_FORWARDED_SERVER' ])
return $_SERVER [ 'HTTP_X_FORWARDED_SERVER' ];
return $_SERVER [ 'SERVER_NAME' ];
}
/**
* Get the server variable REMOTE_ADDR , or the first ip of HTTP_X_FORWARDED_FOR ( when using proxy )
*
* @ return string $remote_addr ip of client
*/
public static function getRemoteAddr ()
{
if ( function_exists ( 'apache_request_headers' ))
$headers = apache_request_headers ();
else
$headers = $_SERVER ;
if ( array_key_exists ( 'X-Forwarded-For' , $headers ))
$_SERVER [ 'HTTP_X_FORWARDED_FOR' ] = $headers [ 'X-Forwarded-For' ];
if ( isset ( $_SERVER [ 'HTTP_X_FORWARDED_FOR' ]) && $_SERVER [ 'HTTP_X_FORWARDED_FOR' ] && ( ! isset ( $_SERVER [ 'REMOTE_ADDR' ])
|| preg_match ( '/^127\..*/i' , trim ( $_SERVER [ 'REMOTE_ADDR' ])) || preg_match ( '/^172\.16.*/i' , trim ( $_SERVER [ 'REMOTE_ADDR' ]))
|| preg_match ( '/^192\.168\.*/i' , trim ( $_SERVER [ 'REMOTE_ADDR' ])) || preg_match ( '/^10\..*/i' , trim ( $_SERVER [ 'REMOTE_ADDR' ]))))
{
if ( strpos ( $_SERVER [ 'HTTP_X_FORWARDED_FOR' ], ',' ))
{
$ips = explode ( ',' , $_SERVER [ 'HTTP_X_FORWARDED_FOR' ]);
return $ips [ 0 ];
}
else
return $_SERVER [ 'HTTP_X_FORWARDED_FOR' ];
}
else
return $_SERVER [ 'REMOTE_ADDR' ];
}
/**
* Check if the current page use SSL connection on not
*
* @ return bool uses SSL
*/
public static function usingSecureMode ()
{
if ( isset ( $_SERVER [ 'HTTPS' ]))
return in_array ( Tools :: strtolower ( $_SERVER [ 'HTTPS' ]), array ( 1 , 'on' ));
// $_SERVER['SSL'] exists only in some specific configuration
if ( isset ( $_SERVER [ 'SSL' ]))
return in_array ( Tools :: strtolower ( $_SERVER [ 'SSL' ]), array ( 1 , 'on' ));
// $_SERVER['REDIRECT_HTTPS'] exists only in some specific configuration
if ( isset ( $_SERVER [ 'REDIRECT_HTTPS' ]))
return in_array ( Tools :: strtolower ( $_SERVER [ 'REDIRECT_HTTPS' ]), array ( 1 , 'on' ));
if ( isset ( $_SERVER [ 'HTTP_SSL' ]))
return in_array ( Tools :: strtolower ( $_SERVER [ 'HTTP_SSL' ]), array ( 1 , 'on' ));
if ( isset ( $_SERVER [ 'HTTP_X_FORWARDED_PROTO' ]))
return Tools :: strtolower ( $_SERVER [ 'HTTP_X_FORWARDED_PROTO' ]) == 'https' ;
return false ;
}
/**
* Get the current url prefix protocol ( https / http )
*
* @ return string protocol
*/
public static function getCurrentUrlProtocolPrefix ()
{
if ( Tools :: usingSecureMode ())
return 'https://' ;
else
return 'http://' ;
}
/**
* Secure an URL referrer
*
* @ param string $referrer URL referrer
* @ return string secured referrer
*/
public static function secureReferrer ( $referrer )
{
if ( preg_match ( '/^http[s]?:\/\/' . Tools :: getServerName () . '(:' . _PS_SSL_PORT_ . ')?\/.*$/Ui' , $referrer ))
return $referrer ;
return __PS_BASE_URI__ ;
}
/**
* Get a value from $_POST / $_GET
* if unavailable , take a default value
*
* @ param string $key Value key
* @ param mixed $default_value ( optional )
* @ return mixed Value
*/
public static function getValue ( $key , $default_value = false )
{
if ( ! isset ( $key ) || empty ( $key ) || ! is_string ( $key ))
return false ;
$ret = ( isset ( $_POST [ $key ]) ? $_POST [ $key ] : ( isset ( $_GET [ $key ]) ? $_GET [ $key ] : $default_value ));
if ( is_string ( $ret ))
return stripslashes ( urldecode ( preg_replace ( '/((\%5C0+)|(\%00+))/i' , '' , urlencode ( $ret ))));
return $ret ;
}
/**
* Get all values from $_POST / $_GET
* @ return mixed
*/
public static function getAllValues ()
{
return $_POST + $_GET ;
}
public static function getIsset ( $key )
{
if ( ! isset ( $key ) || empty ( $key ) || ! is_string ( $key ))
return false ;
return isset ( $_POST [ $key ]) ? true : ( isset ( $_GET [ $key ]) ? true : false );
}
/**
* Change language in cookie while clicking on a flag
*
* @ return string iso code
*/
public static function setCookieLanguage ( $cookie = null )
{
if ( ! $cookie )
$cookie = Context :: getContext () -> cookie ;
/* If language does not exist or is disabled, erase it */
if ( $cookie -> id_lang )
{
$lang = new Language (( int ) $cookie -> id_lang );
if ( ! Validate :: isLoadedObject ( $lang ) || ! $lang -> active || ! $lang -> isAssociatedToShop ())
$cookie -> id_lang = null ;
}
if ( ! Configuration :: get ( 'PS_DETECT_LANG' ))
unset ( $cookie -> detect_language );
/* Automatically detect language if not already defined, detect_language is set in Cookie::update */
if ( ! Tools :: getValue ( 'isolang' ) && ! Tools :: getValue ( 'id_lang' ) && ( ! $cookie -> id_lang || isset ( $cookie -> detect_language ))
&& isset ( $_SERVER [ 'HTTP_ACCEPT_LANGUAGE' ]))
{
$array = explode ( ',' , Tools :: strtolower ( $_SERVER [ 'HTTP_ACCEPT_LANGUAGE' ]));
$string = $array [ 0 ];
if ( Validate :: isLanguageCode ( $string ))
{
$lang = Language :: getLanguageByIETFCode ( $string );
if ( Validate :: isLoadedObject ( $lang ) && $lang -> active && $lang -> isAssociatedToShop ())
{
Context :: getContext () -> language = $lang ;
$cookie -> id_lang = ( int ) $lang -> id ;
}
}
}
if ( isset ( $cookie -> detect_language ))
unset ( $cookie -> detect_language );
/* If language file not present, you must use default language file */
if ( ! $cookie -> id_lang || ! Validate :: isUnsignedId ( $cookie -> id_lang ))
$cookie -> id_lang = ( int ) Configuration :: get ( 'PS_LANG_DEFAULT' );
$iso = Language :: getIsoById (( int ) $cookie -> id_lang );
@ include_once ( _PS_THEME_DIR_ . 'lang/' . $iso . '.php' );
return $iso ;
}
/**
* Set cookie id_lang
*/
public static function switchLanguage ( Context $context = null )
{
if ( ! $context )
$context = Context :: getContext ();
// Install call the dispatcher and so the switchLanguage
// Stop this method by checking the cookie
if ( ! isset ( $context -> cookie ))
return ;
if (( $iso = Tools :: getValue ( 'isolang' )) && Validate :: isLanguageIsoCode ( $iso ) && ( $id_lang = ( int ) Language :: getIdByIso ( $iso )))
$_GET [ 'id_lang' ] = $id_lang ;
// update language only if new id is different from old id
// or if default language changed
$cookie_id_lang = $context -> cookie -> id_lang ;
$configuration_id_lang = Configuration :: get ( 'PS_LANG_DEFAULT' );
if ((( $id_lang = ( int ) Tools :: getValue ( 'id_lang' )) && Validate :: isUnsignedId ( $id_lang ) && $cookie_id_lang != ( int ) $id_lang )
|| (( $id_lang == $configuration_id_lang ) && Validate :: isUnsignedId ( $id_lang ) && $id_lang != $cookie_id_lang ))
{
$context -> cookie -> id_lang = $id_lang ;
$language = new Language ( $id_lang );
if ( Validate :: isLoadedObject ( $language ) && $language -> active )
$context -> language = $language ;
$params = $_GET ;
if ( Configuration :: get ( 'PS_REWRITING_SETTINGS' ) || ! Language :: isMultiLanguageActivated ())
unset ( $params [ 'id_lang' ]);
}
}
public static function getCountry ( $address = null )
{
if ( $id_country = Tools :: getValue ( 'id_country' ));
elseif ( isset ( $address ) && isset ( $address -> id_country ) && $address -> id_country )
$id_country = $address -> id_country ;
elseif ( Configuration :: get ( 'PS_DETECT_COUNTRY' ) && isset ( $_SERVER [ 'HTTP_ACCEPT_LANGUAGE' ]))
{
preg_match ( '#(?<=-)\w\w|\w\w(?!-)#' , $_SERVER [ 'HTTP_ACCEPT_LANGUAGE' ], $array );
if ( is_array ( $array ) && isset ( $array [ 0 ]) && Validate :: isLanguageIsoCode ( $array [ 0 ]))
$id_country = Country :: getByIso ( $array [ 0 ], true );
}
if ( ! isset ( $id_country ) || ! $id_country )
$id_country = Configuration :: get ( 'PS_COUNTRY_DEFAULT' );
return ( int ) $id_country ;
}
/**
* Set cookie currency from POST or default currency
*
* @ return Currency object
*/
public static function setCurrency ( $cookie )
{
if ( Tools :: isSubmit ( 'SubmitCurrency' ) && ( $id_currency = Tools :: getValue ( 'id_currency' )))
{
/** @var Currency $currency */
$currency = Currency :: getCurrencyInstance (( int ) $id_currency );
if ( is_object ( $currency ) && $currency -> id && ! $currency -> deleted && $currency -> isAssociatedToShop ())
$cookie -> id_currency = ( int ) $currency -> id ;
}
$currency = null ;
if (( int ) $cookie -> id_currency )
$currency = Currency :: getCurrencyInstance (( int ) $cookie -> id_currency );
if ( ! Validate :: isLoadedObject ( $currency ) || ( bool ) $currency -> deleted || ! ( bool ) $currency -> active )
$currency = Currency :: getCurrencyInstance ( Configuration :: get ( 'PS_CURRENCY_DEFAULT' ));
$cookie -> id_currency = ( int ) $currency -> id ;
if ( $currency -> isAssociatedToShop ())
return $currency ;
else
{
// get currency from context
$currency = Shop :: getEntityIds ( 'currency' , Context :: getContext () -> shop -> id , true , true );
if ( isset ( $currency [ 0 ]) && $currency [ 0 ][ 'id_currency' ])
{
$cookie -> id_currency = $currency [ 0 ][ 'id_currency' ];
return Currency :: getCurrencyInstance (( int ) $cookie -> id_currency );
}
}
return $currency ;
}
/**
* Return price with currency sign for a given product
*
* @ param float $price Product price
* @ param object | array $currency Current currency ( object , id_currency , NULL => context currency )
* @ return string Price correctly formated ( sign , decimal separator ... )
*/
public static function displayPrice ( $price , $currency = null , $no_utf8 = false , Context $context = null )
{
if ( ! is_numeric ( $price ))
return $price ;
if ( ! $context )
$context = Context :: getContext ();
if ( $currency === null )
$currency = $context -> currency ;
// if you modified this function, don't forget to modify the Javascript function formatCurrency (in tools.js)
elseif ( is_int ( $currency ))
$currency = Currency :: getCurrencyInstance (( int ) $currency );
if ( is_array ( $currency ))
{
$c_char = $currency [ 'sign' ];
$c_format = $currency [ 'format' ];
$c_decimals = ( int ) $currency [ 'decimals' ] * _PS_PRICE_DISPLAY_PRECISION_ ;
$c_blank = $currency [ 'blank' ];
}
elseif ( is_object ( $currency ))
{
$c_char = $currency -> sign ;
$c_format = $currency -> format ;
$c_decimals = ( int ) $currency -> decimals * _PS_PRICE_DISPLAY_PRECISION_ ;
$c_blank = $currency -> blank ;
}
else
return false ;
$blank = ( $c_blank ? ' ' : '' );
$ret = 0 ;
if (( $is_negative = ( $price < 0 )))
$price *= - 1 ;
$price = Tools :: ps_round ( $price , $c_decimals );
/*
* If the language is RTL and the selected currency format contains spaces as thousands separator
* then the number will be printed in reverse since the space is interpreted as separating words .
* To avoid this we replace the currency format containing a space with the one containing a comma (,) as thousand
* separator when the language is RTL .
*
* TODO : This is not ideal , a currency format should probably be tied to a language , not to a currency .
*/
if (( $c_format == 2 ) && ( $context -> language -> is_rtl == 1 ))
$c_format = 4 ;
switch ( $c_format )
{
/* X 0,000.00 */
case 1 :
$ret = $c_char . $blank . number_format ( $price , $c_decimals , '.' , ',' );
break ;
/* 0 000,00 X*/
case 2 :
$ret = number_format ( $price , $c_decimals , ',' , ' ' ) . $blank . $c_char ;
break ;
/* X 0.000,00 */
case 3 :
$ret = $c_char . $blank . number_format ( $price , $c_decimals , ',' , '.' );
break ;
/* 0,000.00 X */
case 4 :
$ret = number_format ( $price , $c_decimals , '.' , ',' ) . $blank . $c_char ;
break ;
/* X 0'000.00 Added for the switzerland currency */
case 5 :
$ret = number_format ( $price , $c_decimals , '.' , " ' " ) . $blank . $c_char ;
break ;
}
if ( $is_negative )
$ret = '-' . $ret ;
if ( $no_utf8 )
return str_replace ( '€' , chr ( 128 ), $ret );
return $ret ;
}
/* Just to fix a bug
* Need real CLDR functions
*/
public static function displayNumber ( $number , $currency )
{
if ( is_array ( $currency ))
$format = $currency [ 'format' ];
elseif ( is_object ( $currency ))
$format = $currency -> format ;
return number_format ( $number , 0 , '.' , in_array ( $format , array ( 1 , 4 )) ? ',' : ' ' );
}
public static function displayPriceSmarty ( $params , & $smarty )
{
if ( array_key_exists ( 'currency' , $params ))
{
$currency = Currency :: getCurrencyInstance (( int ) $params [ 'currency' ]);
if ( Validate :: isLoadedObject ( $currency ))
return Tools :: displayPrice ( $params [ 'price' ], $currency , false );
}
return Tools :: displayPrice ( $params [ 'price' ]);
}
/**
* Return price converted
*
* @ param float $price Product price
* @ param object | array $currency Current currency object
* @ param bool $to_currency convert to currency or from currency to default currency
* @ param Context $context
* @ return float Price
*/
public static function convertPrice ( $price , $currency = null , $to_currency = true , Context $context = null )
{
static $default_currency = null ;
if ( $default_currency === null )
$default_currency = ( int ) Configuration :: get ( 'PS_CURRENCY_DEFAULT' );
if ( ! $context )
$context = Context :: getContext ();
if ( $currency === null )
$currency = $context -> currency ;
elseif ( is_numeric ( $currency ))
$currency = Currency :: getCurrencyInstance ( $currency );
$c_id = ( is_array ( $currency ) ? $currency [ 'id_currency' ] : $currency -> id );
$c_rate = ( is_array ( $currency ) ? $currency [ 'conversion_rate' ] : $currency -> conversion_rate );
if ( $c_id != $default_currency )
{
if ( $to_currency )
$price *= $c_rate ;
else
$price /= $c_rate ;
}
return $price ;
}
/**
* Implement array_replace for PHP <= 5.2
*
* @ return array | mixed | null
*/
public static function array_replace ()
{
if ( ! function_exists ( 'array_replace' ))
{
$args = func_get_args ();
$num_args = func_num_args ();
$res = array ();
for ( $i = 0 ; $i < $num_args ; $i ++ )
{
if ( is_array ( $args [ $i ]))
{
foreach ( $args [ $i ] as $key => $val )
$res [ $key ] = $val ;
}
else
{
trigger_error ( __FUNCTION__ . '(): Argument #' . ( $i + 1 ) . ' is not an array' , E_USER_WARNING );
return null ;
}
}
return $res ;
}
else
{
return call_user_func_array ( 'array_replace' , func_get_args ());
}
}
/**
*
* Convert amount from a currency to an other currency automatically
* @ param float $amount
* @ param Currency $currency_from if null we used the default currency
* @ param Currency $currency_to if null we used the default currency
*/
public static function convertPriceFull ( $amount , Currency $currency_from = null , Currency $currency_to = null )
{
if ( $currency_from === $currency_to )
return $amount ;
if ( $currency_from === null )
$currency_from = new Currency ( Configuration :: get ( 'PS_CURRENCY_DEFAULT' ));
if ( $currency_to === null )
$currency_to = new Currency ( Configuration :: get ( 'PS_CURRENCY_DEFAULT' ));
if ( $currency_from -> id == Configuration :: get ( 'PS_CURRENCY_DEFAULT' ))
$amount *= $currency_to -> conversion_rate ;
else
{
$conversion_rate = ( $currency_from -> conversion_rate == 0 ? 1 : $currency_from -> conversion_rate );
// Convert amount to default currency (using the old currency rate)
$amount = $amount / $conversion_rate ;
// Convert to new currency
$amount *= $currency_to -> conversion_rate ;
}
return Tools :: ps_round ( $amount , _PS_PRICE_COMPUTE_PRECISION_ );
}
/**
* Display date regarding to language preferences
*
* @ param array $params Date , format ...
* @ param object $smarty Smarty object for language preferences
* @ return string Date
*/
public static function dateFormat ( $params , & $smarty )
{
return Tools :: displayDate ( $params [ 'date' ], null , ( isset ( $params [ 'full' ]) ? $params [ 'full' ] : false ));
}
/**
* Display date regarding to language preferences
*
* @ param string $date Date to display format UNIX
* @ param int $id_lang Language id DEPRECATED
* @ param bool $full With time or not ( optional )
* @ param string $separator DEPRECATED
* @ return string Date
*/
public static function displayDate ( $date , $id_lang = null , $full = false , $separator = null )
{
if ( $id_lang !== null )
Tools :: displayParameterAsDeprecated ( 'id_lang' );
if ( $separator !== null )
Tools :: displayParameterAsDeprecated ( 'separator' );
if ( ! $date || ! ( $time = strtotime ( $date )))
return $date ;
if ( $date == '0000-00-00 00:00:00' || $date == '0000-00-00' )
return '' ;
if ( ! Validate :: isDate ( $date ) || ! Validate :: isBool ( $full ))
throw new PrestaShopException ( 'Invalid date' );
$context = Context :: getContext ();
$date_format = ( $full ? $context -> language -> date_format_full : $context -> language -> date_format_lite );
return date ( $date_format , $time );
}
/**
* Sanitize a string
*
* @ param string $string String to sanitize
* @ param bool $full String contains HTML or not ( optional )
* @ return string Sanitized string
*/
public static function safeOutput ( $string , $html = false )
{
if ( ! $html )
$string = strip_tags ( $string );
return @ Tools :: htmlentitiesUTF8 ( $string , ENT_QUOTES );
}
public static function htmlentitiesUTF8 ( $string , $type = ENT_QUOTES )
{
if ( is_array ( $string ))
return array_map ( array ( 'Tools' , 'htmlentitiesUTF8' ), $string );
return htmlentities (( string ) $string , $type , 'utf-8' );
}
public static function htmlentitiesDecodeUTF8 ( $string )
{
if ( is_array ( $string ))
{
$string = array_map ( array ( 'Tools' , 'htmlentitiesDecodeUTF8' ), $string );
return ( string ) array_shift ( $string );
}
return html_entity_decode (( string ) $string , ENT_QUOTES , 'utf-8' );
}
public static function safePostVars ()
{
if ( ! isset ( $_POST ) || ! is_array ( $_POST ))
$_POST = array ();
else
$_POST = array_map ( array ( 'Tools' , 'htmlentitiesUTF8' ), $_POST );
}
/**
* Delete directory and subdirectories
*
* @ param string $dirname Directory name
*/
public static function deleteDirectory ( $dirname , $delete_self = true )
{
$dirname = rtrim ( $dirname , '/' ) . '/' ;
if ( file_exists ( $dirname ))
if ( $files = scandir ( $dirname ))
{
foreach ( $files as $file )
if ( $file != '.' && $file != '..' && $file != '.svn' )
{
if ( is_dir ( $dirname . $file ))
Tools :: deleteDirectory ( $dirname . $file , true );
elseif ( file_exists ( $dirname . $file ))
{
@ chmod ( $dirname . $file , 0777 ); // NT ?
unlink ( $dirname . $file );
}
}
if ( $delete_self && file_exists ( $dirname ))
if ( ! rmdir ( $dirname ))
{
@ chmod ( $dirname , 0777 ); // NT ?
return false ;
}
return true ;
}
return false ;
}
/**
* Delete file
*
* @ param string $file File path
* @ param array $exclude_files Excluded files
*/
public static function deleteFile ( $file , $exclude_files = array ())
{
if ( isset ( $exclude_files ) && ! is_array ( $exclude_files ))
$exclude_files = array ( $exclude_files );
if ( file_exists ( $file ) && is_file ( $file ) && array_search ( basename ( $file ), $exclude_files ) === false )
{
@ chmod ( $file , 0777 ); // NT ?
unlink ( $file );
}
}
/**
* Clear XML cache folder
*/
public static function clearXMLCache ()
{
$themes = array ();
foreach ( Theme :: getThemes () as $theme )
{
/** @var Theme $theme */
$themes [] = $theme -> directory ;
}
foreach ( scandir ( _PS_ROOT_DIR_ . '/config/xml' ) as $file )
{
$path_info = pathinfo ( $file , PATHINFO_EXTENSION );
if (( $path_info == 'xml' ) && ( $file != 'default.xml' ) && ! in_array ( basename ( $file , '.' . $path_info ), $themes ))
self :: deleteFile ( _PS_ROOT_DIR_ . '/config/xml/' . $file );
}
}
/**
* Display an error according to an error code
*
* @ param string $string Error message
* @ param bool $htmlentities By default at true for parsing error message with htmlentities
*/
public static function displayError ( $string = 'Fatal error' , $htmlentities = true , Context $context = null )
{
global $_ERRORS ;
if ( is_null ( $context ))
$context = Context :: getContext ();
@ include_once ( _PS_TRANSLATIONS_DIR_ . $context -> language -> iso_code . '/errors.php' );
if ( defined ( '_PS_MODE_DEV_' ) && _PS_MODE_DEV_ && $string == 'Fatal error' )
return ( '<pre>' . print_r ( debug_backtrace (), true ) . '</pre>' );
if ( ! is_array ( $_ERRORS ))
return $htmlentities ? Tools :: htmlentitiesUTF8 ( $string ) : $string ;
$key = md5 ( str_replace ( '\'' , '\\\'' , $string ));
$str = ( isset ( $_ERRORS ) && is_array ( $_ERRORS ) && array_key_exists ( $key , $_ERRORS )) ? $_ERRORS [ $key ] : $string ;
return $htmlentities ? Tools :: htmlentitiesUTF8 ( stripslashes ( $str )) : $str ;
}
/**
* Display an error with detailed object
*
* @ param mixed $object
* @ param bool $kill
* @ return $object if $kill = false ;
*/
public static function dieObject ( $object , $kill = true )
{
echo '<xmp style="text-align: left;">' ;
print_r ( $object );
echo '</xmp><br />' ;
if ( $kill )
die ( 'END' );
return $object ;
}
/**
* Display a var dump in firebug console
*
* @ param object $object Object to display
*/
public static function fd ( $object , $type = 'log' )
{
$types = array ( 'log' , 'debug' , 'info' , 'warn' , 'error' , 'assert' );
if ( ! in_array ( $type , $types ))
$type = 'log' ;
echo '
< script type = " text/javascript " >
console . '.$type.' ( '.Tools::jsonEncode($object).' );
</ script >
' ;
}
/**
* ALIAS OF dieObject () - Display an error with detailed object
*
* @ param object $object Object to display
*/
public static function d ( $object , $kill = true )
{
return ( Tools :: dieObject ( $object , $kill ));
}
public static function debug_backtrace ( $start = 0 , $limit = null )
{
$backtrace = debug_backtrace ();
array_shift ( $backtrace );
for ( $i = 0 ; $i < $start ; ++ $i )
array_shift ( $backtrace );
echo '
< div style = " margin:10px;padding:10px;border:1px solid #666666 " >
< ul > ' ;
$i = 0 ;
foreach ( $backtrace as $id => $trace )
{
if (( int ) $limit && ( ++ $i > $limit ))
break ;
$relative_file = ( isset ( $trace [ 'file' ])) ? 'in /' . ltrim ( str_replace ( array ( _PS_ROOT_DIR_ , '\\' ), array ( '' , '/' ), $trace [ 'file' ]), '/' ) : '' ;
$current_line = ( isset ( $trace [ 'line' ])) ? ':' . $trace [ 'line' ] : '' ;
echo ' < li >
< b > '.((isset($trace[' class '])) ? $trace[' class '] : ' ').((isset($trace[' type '])) ? $trace[' type '] : ' ').$trace[' function '].' </ b >
'.$relative_file.$current_line.'
</ li > ' ;
}
echo ' </ ul >
</ div > ' ;
}
/**
* ALIAS OF dieObject () - Display an error with detailed object but don ' t stop the execution
*
* @ param object $object Object to display
*/
public static function p ( $object )
{
return ( Tools :: dieObject ( $object , false ));
}
/**
* Prints object information into error log
*
* @ see error_log ()
* @ param mixed $object
* @ param int | null $message_type
* @ param string | null $destination
* @ param string | null $extra_headers
* @ return bool
*/
public static function error_log ( $object , $message_type = null , $destination = null , $extra_headers = null )
{
return error_log ( print_r ( $object , true ), $message_type , $destination , $extra_headers );
}
/**
* Check if submit has been posted
*
* @ param string $submit submit name
*/
public static function isSubmit ( $submit )
{
return (
isset ( $_POST [ $submit ]) || isset ( $_POST [ $submit . '_x' ]) || isset ( $_POST [ $submit . '_y' ])
|| isset ( $_GET [ $submit ]) || isset ( $_GET [ $submit . '_x' ]) || isset ( $_GET [ $submit . '_y' ])
);
}
/**
* @ deprecated 1.5 . 0
*/
public static function getMetaTags ( $id_lang , $page_name , $title = '' )
{
Tools :: displayAsDeprecated ();
return Meta :: getMetaTags ( $id_lang , $page_name , $title );
}
/**
* @ deprecated 1.5 . 0
*/
public static function getHomeMetaTags ( $id_lang , $page_name )
{
Tools :: displayAsDeprecated ();
return Meta :: getHomeMetas ( $id_lang , $page_name );
}
/**
* @ deprecated 1.5 . 0
*/
public static function completeMetaTags ( $meta_tags , $default_value , Context $context = null )
{
Tools :: displayAsDeprecated ();
return Meta :: completeMetaTags ( $meta_tags , $default_value , $context );
}
/**
* Encrypt password
*
* @ param string $passwd String to encrypt
*/
public static function encrypt ( $passwd )
{
return md5 ( _COOKIE_KEY_ . $passwd );
}
/**
* Encrypt data string
*
* @ param string $data String to encrypt
*/
public static function encryptIV ( $data )
{
return md5 ( _COOKIE_IV_ . $data );
}
/**
* Get token to prevent CSRF
*
* @ param string $token token to encrypt
*/
public static function getToken ( $page = true , Context $context = null )
{
if ( ! $context )
$context = Context :: getContext ();
if ( $page === true )
return ( Tools :: encrypt ( $context -> customer -> id . $context -> customer -> passwd . $_SERVER [ 'SCRIPT_NAME' ]));
else
return ( Tools :: encrypt ( $context -> customer -> id . $context -> customer -> passwd . $page ));
}
/**
* Tokenize a string
*
* @ param string $string string to encript
*/
public static function getAdminToken ( $string )
{
return ! empty ( $string ) ? Tools :: encrypt ( $string ) : false ;
}
public static function getAdminTokenLite ( $tab , Context $context = null )
{
if ( ! $context )
$context = Context :: getContext ();
return Tools :: getAdminToken ( $tab . ( int ) Tab :: getIdFromClassName ( $tab ) . ( int ) $context -> employee -> id );
}
public static function getAdminTokenLiteSmarty ( $params , & $smarty )
{
$context = Context :: getContext ();
return Tools :: getAdminToken ( $params [ 'tab' ] . ( int ) Tab :: getIdFromClassName ( $params [ 'tab' ]) . ( int ) $context -> employee -> id );
}
/**
* Get a valid URL to use from BackOffice
*
* @ param string $url An URL to use in BackOffice
* @ param bool $entites Set to true to use htmlentities function on URL param
*/
public static function getAdminUrl ( $url = null , $entities = false )
{
$link = Tools :: getHttpHost ( true ) . __PS_BASE_URI__ ;
if ( isset ( $url ))
$link .= ( $entities ? Tools :: htmlentitiesUTF8 ( $url ) : $url );
return $link ;
}
/**
* Get a valid image URL to use from BackOffice
*
* @ param string $image Image name
* @ param bool $entites Set to true to use htmlentities function on image param
*/
public static function getAdminImageUrl ( $image = null , $entities = false )
{
return Tools :: getAdminUrl ( basename ( _PS_IMG_DIR_ ) . '/' . $image , $entities );
}
/**
* Get the user ' s journey
*
* @ param int $id_category Category ID
* @ param string $path Path end
* @ param bool $linkOntheLastItem Put or not a link on the current category
* @ param string [ optionnal ] $categoryType defined what type of categories is used ( products or cms )
*/
public static function getPath ( $id_category , $path = '' , $link_on_the_item = false , $category_type = 'products' , Context $context = null )
{
if ( ! $context )
$context = Context :: getContext ();
$id_category = ( int ) $id_category ;
if ( $id_category == 1 )
return '<span class="navigation_end">' . $path . '</span>' ;
$pipe = Configuration :: get ( 'PS_NAVIGATION_PIPE' );
if ( empty ( $pipe ))
$pipe = '>' ;
$full_path = '' ;
if ( $category_type === 'products' )
{
$interval = Category :: getInterval ( $id_category );
$id_root_category = $context -> shop -> getCategory ();
$interval_root = Category :: getInterval ( $id_root_category );
if ( $interval )
{
$sql = ' SELECT c . id_category , cl . name , cl . link_rewrite
FROM '._DB_PREFIX_.' category c
LEFT JOIN '._DB_PREFIX_.' category_lang cl ON ( cl . id_category = c . id_category '.Shop::addSqlRestrictionOnLang(' cl ').' )
'.Shop::addSqlAssociation(' category ', ' c ').'
WHERE c . nleft <= '.$interval[' nleft '].'
AND c . nright >= '.$interval[' nright '].'
AND c . nleft >= '.$interval_root[' nleft '].'
AND c . nright <= '.$interval_root[' nright '].'
AND cl . id_lang = '.(int)$context->language->id.'
AND c . active = 1
AND c . level_depth > '.(int)$interval_root[' level_depth '].'
ORDER BY c . level_depth ASC ' ;
$categories = Db :: getInstance () -> executeS ( $sql );
$n = 1 ;
$n_categories = count ( $categories );
foreach ( $categories as $category )
{
$full_path .=
(( $n < $n_categories || $link_on_the_item ) ? '<a href="' . Tools :: safeOutput ( $context -> link -> getCategoryLink (( int ) $category [ 'id_category' ], $category [ 'link_rewrite' ])) . '" title="' . htmlentities ( $category [ 'name' ], ENT_NOQUOTES , 'UTF-8' ) . '" data-gg="">' : '' ) .
htmlentities ( $category [ 'name' ], ENT_NOQUOTES , 'UTF-8' ) .
(( $n < $n_categories || $link_on_the_item ) ? '</a>' : '' ) .
(( $n ++ != $n_categories || ! empty ( $path )) ? '<span class="navigation-pipe">' . $pipe . '</span>' : '' );
}
return $full_path . $path ;
}
}
elseif ( $category_type === 'CMS' )
{
$category = new CMSCategory ( $id_category , $context -> language -> id );
if ( ! Validate :: isLoadedObject ( $category ))
die ( Tools :: displayError ());
$category_link = $context -> link -> getCMSCategoryLink ( $category );
if ( $path != $category -> name )
$full_path .= '<a href="' . Tools :: safeOutput ( $category_link ) . '" data-gg="">' . htmlentities ( $category -> name , ENT_NOQUOTES , 'UTF-8' ) . '</a><span class="navigation-pipe">' . $pipe . '</span>' . $path ;
else
$full_path = ( $link_on_the_item ? '<a href="' . Tools :: safeOutput ( $category_link ) . '" data-gg="">' : '' ) . htmlentities ( $path , ENT_NOQUOTES , 'UTF-8' ) . ( $link_on_the_item ? '</a>' : '' );
return Tools :: getPath ( $category -> id_parent , $full_path , $link_on_the_item , $category_type );
}
}
/**
* @ param string [ optionnal ] $type_cat defined what type of categories is used ( products or cms )
*/
public static function getFullPath ( $id_category , $end , $type_cat = 'products' , Context $context = null )
{
if ( ! $context )
$context = Context :: getContext ();
$id_category = ( int ) $id_category ;
$pipe = ( Configuration :: get ( 'PS_NAVIGATION_PIPE' ) ? Configuration :: get ( 'PS_NAVIGATION_PIPE' ) : '>' );
$default_category = 1 ;
if ( $type_cat === 'products' )
{
$default_category = $context -> shop -> getCategory ();
$category = new Category ( $id_category , $context -> language -> id );
}
elseif ( $type_cat === 'CMS' )
$category = new CMSCategory ( $id_category , $context -> language -> id );
if ( ! Validate :: isLoadedObject ( $category ))
$id_category = $default_category ;
if ( $id_category == $default_category )
return htmlentities ( $end , ENT_NOQUOTES , 'UTF-8' );
return Tools :: 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>' ;
}
/**
* Return the friendly url from the provided string
*
* @ param string $str
* @ param bool $utf8_decode ( deprecated )
* @ return string
*/
public static function link_rewrite ( $str , $utf8_decode = null )
{
if ( $utf8_decode !== null )
Tools :: displayParameterAsDeprecated ( 'utf8_decode' );
return Tools :: str2url ( $str );
}
/**
* Return a friendly url made from the provided string
* If the mbstring library is available , the output is the same as the js function of the same name
*
* @ param string $str
* @ return string
*/
public static function str2url ( $str )
{
static $array_str = array ();
static $allow_accented_chars = null ;
static $has_mb_strtolower = null ;
if ( $has_mb_strtolower === null )
$has_mb_strtolower = function_exists ( 'mb_strtolower' );
if ( isset ( $array_str [ $str ]))
return $array_str [ $str ];
if ( ! is_string ( $str ))
return false ;
if ( $str == '' )
return '' ;
if ( $allow_accented_chars === null )
$allow_accented_chars = Configuration :: get ( 'PS_ALLOW_ACCENTED_CHARS_URL' );
$return_str = trim ( $str );
if ( $has_mb_strtolower )
$return_str = mb_strtolower ( $return_str , 'utf-8' );
if ( ! $allow_accented_chars )
$return_str = Tools :: replaceAccentedChars ( $return_str );
// Remove all non-whitelist chars.
if ( $allow_accented_chars )
$return_str = preg_replace ( '/[^a-zA-Z0-9\s\'\:\/\[\]\-\p{L}]/u' , '' , $return_str );
else
$return_str = preg_replace ( '/[^a-zA-Z0-9\s\'\:\/\[\]\-]/' , '' , $return_str );
$return_str = preg_replace ( '/[\s\'\:\/\[\]\-]+/' , ' ' , $return_str );
$return_str = str_replace ( array ( ' ' , '/' ), '-' , $return_str );
// If it was not possible to lowercase the string with mb_strtolower, we do it after the transformations.
// This way we lose fewer special chars.
if ( ! $has_mb_strtolower )
$return_str = Tools :: strtolower ( $return_str );
$array_str [ $str ] = $return_str ;
return $return_str ;
}
/**
* Replace all accented chars by their equivalent non accented chars .
*
* @ param string $str
* @ return string
*/
public static function replaceAccentedChars ( $str )
{
/* One source among others :
http :// www . tachyonsoft . com / uc0000 . htm
http :// www . tachyonsoft . com / uc0001 . htm
http :// www . tachyonsoft . com / uc0004 . htm
*/
$patterns = array (
/* Lowercase */
/* a */ '/[\x{00E0}\x{00E1}\x{00E2}\x{00E3}\x{00E4}\x{00E5}\x{0101}\x{0103}\x{0105}\x{0430}\x{00C0}-\x{00C3}\x{1EA0}-\x{1EB7}]/u' ,
/* b */ '/[\x{0431}]/u' ,
/* c */ '/[\x{00E7}\x{0107}\x{0109}\x{010D}\x{0446}]/u' ,
/* d */ '/[\x{010F}\x{0111}\x{0434}\x{0110}]/u' ,
/* e */ '/[\x{00E8}\x{00E9}\x{00EA}\x{00EB}\x{0113}\x{0115}\x{0117}\x{0119}\x{011B}\x{0435}\x{044D}\x{00C8}-\x{00CA}\x{1EB8}-\x{1EC7}]/u' ,
/* f */ '/[\x{0444}]/u' ,
/* g */ '/[\x{011F}\x{0121}\x{0123}\x{0433}\x{0491}]/u' ,
/* h */ '/[\x{0125}\x{0127}]/u' ,
/* i */ '/[\x{00EC}\x{00ED}\x{00EE}\x{00EF}\x{0129}\x{012B}\x{012D}\x{012F}\x{0131}\x{0438}\x{0456}\x{00CC}\x{00CD}\x{1EC8}-\x{1ECB}\x{0128}]/u' ,
/* j */ '/[\x{0135}\x{0439}]/u' ,
/* k */ '/[\x{0137}\x{0138}\x{043A}]/u' ,
/* l */ '/[\x{013A}\x{013C}\x{013E}\x{0140}\x{0142}\x{043B}]/u' ,
/* m */ '/[\x{043C}]/u' ,
/* n */ '/[\x{00F1}\x{0144}\x{0146}\x{0148}\x{0149}\x{014B}\x{043D}]/u' ,
/* o */ '/[\x{00F2}\x{00F3}\x{00F4}\x{00F5}\x{00F6}\x{00F8}\x{014D}\x{014F}\x{0151}\x{043E}\x{00D2}-\x{00D5}\x{01A0}\x{01A1}\x{1ECC}-\x{1EE3}]/u' ,
/* p */ '/[\x{043F}]/u' ,
/* r */ '/[\x{0155}\x{0157}\x{0159}\x{0440}]/u' ,
/* s */ '/[\x{015B}\x{015D}\x{015F}\x{0161}\x{0441}]/u' ,
/* ss */ '/[\x{00DF}]/u' ,
/* t */ '/[\x{0163}\x{0165}\x{0167}\x{0442}]/u' ,
/* u */ '/[\x{00F9}\x{00FA}\x{00FB}\x{00FC}\x{0169}\x{016B}\x{016D}\x{016F}\x{0171}\x{0173}\x{0443}\x{00D9}-\x{00DA}\x{0168}\x{01AF}\x{01B0}\x{1EE4}-\x{1EF1}]/u' ,
/* v */ '/[\x{0432}]/u' ,
/* w */ '/[\x{0175}]/u' ,
/* y */ '/[\x{00FF}\x{0177}\x{00FD}\x{044B}\x{1EF2}-\x{1EF9}\x{00DD}]/u' ,
/* z */ '/[\x{017A}\x{017C}\x{017E}\x{0437}]/u' ,
/* ae */ '/[\x{00E6}]/u' ,
/* ch */ '/[\x{0447}]/u' ,
/* kh */ '/[\x{0445}]/u' ,
/* oe */ '/[\x{0153}]/u' ,
/* sh */ '/[\x{0448}]/u' ,
/* shh*/ '/[\x{0449}]/u' ,
/* ya */ '/[\x{044F}]/u' ,
/* ye */ '/[\x{0454}]/u' ,
/* yi */ '/[\x{0457}]/u' ,
/* yo */ '/[\x{0451}]/u' ,
/* yu */ '/[\x{044E}]/u' ,
/* zh */ '/[\x{0436}]/u' ,
/* Uppercase */
/* A */ '/[\x{0100}\x{0102}\x{0104}\x{00C0}\x{00C1}\x{00C2}\x{00C3}\x{00C4}\x{00C5}\x{0410}]/u' ,
/* B */ '/[\x{0411}]]/u' ,
/* C */ '/[\x{00C7}\x{0106}\x{0108}\x{010A}\x{010C}\x{0426}]/u' ,
/* D */ '/[\x{010E}\x{0110}\x{0414}]/u' ,
/* E */ '/[\x{00C8}\x{00C9}\x{00CA}\x{00CB}\x{0112}\x{0114}\x{0116}\x{0118}\x{011A}\x{0415}\x{042D}]/u' ,
/* F */ '/[\x{0424}]/u' ,
/* G */ '/[\x{011C}\x{011E}\x{0120}\x{0122}\x{0413}\x{0490}]/u' ,
/* H */ '/[\x{0124}\x{0126}]/u' ,
/* I */ '/[\x{0128}\x{012A}\x{012C}\x{012E}\x{0130}\x{0418}\x{0406}]/u' ,
/* J */ '/[\x{0134}\x{0419}]/u' ,
/* K */ '/[\x{0136}\x{041A}]/u' ,
/* L */ '/[\x{0139}\x{013B}\x{013D}\x{0139}\x{0141}\x{041B}]/u' ,
/* M */ '/[\x{041C}]/u' ,
/* N */ '/[\x{00D1}\x{0143}\x{0145}\x{0147}\x{014A}\x{041D}]/u' ,
/* O */ '/[\x{00D3}\x{014C}\x{014E}\x{0150}\x{041E}]/u' ,
/* P */ '/[\x{041F}]/u' ,
/* R */ '/[\x{0154}\x{0156}\x{0158}\x{0420}]/u' ,
/* S */ '/[\x{015A}\x{015C}\x{015E}\x{0160}\x{0421}]/u' ,
/* T */ '/[\x{0162}\x{0164}\x{0166}\x{0422}]/u' ,
/* U */ '/[\x{00D9}\x{00DA}\x{00DB}\x{00DC}\x{0168}\x{016A}\x{016C}\x{016E}\x{0170}\x{0172}\x{0423}]/u' ,
/* V */ '/[\x{0412}]/u' ,
/* W */ '/[\x{0174}]/u' ,
/* Y */ '/[\x{0176}\x{042B}]/u' ,
/* Z */ '/[\x{0179}\x{017B}\x{017D}\x{0417}]/u' ,
/* AE */ '/[\x{00C6}]/u' ,
/* CH */ '/[\x{0427}]/u' ,
/* KH */ '/[\x{0425}]/u' ,
/* OE */ '/[\x{0152}]/u' ,
/* SH */ '/[\x{0428}]/u' ,
/* SHH*/ '/[\x{0429}]/u' ,
/* YA */ '/[\x{042F}]/u' ,
/* YE */ '/[\x{0404}]/u' ,
/* YI */ '/[\x{0407}]/u' ,
/* YO */ '/[\x{0401}]/u' ,
/* YU */ '/[\x{042E}]/u' ,
/* ZH */ '/[\x{0416}]/u' );
// ö to oe
// å to aa
// ä to ae
$replacements = array (
'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'i' , 'j' , 'k' , 'l' , 'm' , 'n' , 'o' , 'p' , 'r' , 's' , 'ss' , 't' , 'u' , 'v' , 'w' , 'y' , 'z' , 'ae' , 'ch' , 'kh' , 'oe' , 'sh' , 'shh' , 'ya' , 'ye' , 'yi' , 'yo' , 'yu' , 'zh' ,
'A' , 'B' , 'C' , 'D' , 'E' , 'F' , 'G' , 'H' , 'I' , 'J' , 'K' , 'L' , 'M' , 'N' , 'O' , 'P' , 'R' , 'S' , 'T' , 'U' , 'V' , 'W' , 'Y' , 'Z' , 'AE' , 'CH' , 'KH' , 'OE' , 'SH' , 'SHH' , 'YA' , 'YE' , 'YI' , 'YO' , 'YU' , 'ZH'
);
return preg_replace ( $patterns , $replacements , $str );
}
/**
* Truncate strings
*
* @ param string $str
* @ param int $max_length Max length
* @ param string $suffix Suffix optional
* @ return string $str truncated
*/
/* CAUTION : Use it only on module hookEvents .
** For other purposes use the smarty function instead */
public static function truncate ( $str , $max_length , $suffix = '...' )
{
if ( Tools :: strlen ( $str ) <= $max_length )
return $str ;
$str = utf8_decode ( $str );
return ( utf8_encode ( substr ( $str , 0 , $max_length - Tools :: strlen ( $suffix )) . $suffix ));
}
/*Copied from CakePHP String utility file*/
public static function truncateString ( $text , $length = 120 , $options = array ())
{
$default = array (
'ellipsis' => '...' , 'exact' => true , 'html' => true
);
$options = array_merge ( $default , $options );
extract ( $options );
/**
* @ var string $ellipsis
* @ var bool $exact
* @ var bool $html
*/
if ( $html )
{
if ( Tools :: strlen ( preg_replace ( '/<.*?>/' , '' , $text )) <= $length )
return $text ;
$total_length = Tools :: strlen ( strip_tags ( $ellipsis ));
$open_tags = array ();
$truncate = '' ;
preg_match_all ( '/(<\/?([\w+]+)[^>]*>)?([^<>]*)/' , $text , $tags , PREG_SET_ORDER );
foreach ( $tags as $tag )
{
if ( ! preg_match ( '/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/s' , $tag [ 2 ]))
{
if ( preg_match ( '/<[\w]+[^>]*>/s' , $tag [ 0 ]))
array_unshift ( $open_tags , $tag [ 2 ]);
elseif ( preg_match ( '/<\/([\w]+)[^>]*>/s' , $tag [ 0 ], $close_tag ))
{
$pos = array_search ( $close_tag [ 1 ], $open_tags );
if ( $pos !== false )
array_splice ( $open_tags , $pos , 1 );
}
}
$truncate .= $tag [ 1 ];
$content_length = Tools :: strlen ( preg_replace ( '/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i' , ' ' , $tag [ 3 ]));
if ( $content_length + $total_length > $length )
{
$left = $length - $total_length ;
$entities_length = 0 ;
if ( preg_match_all ( '/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i' , $tag [ 3 ], $entities , PREG_OFFSET_CAPTURE ))
{
foreach ( $entities [ 0 ] as $entity )
{
if ( $entity [ 1 ] + 1 - $entities_length <= $left )
{
$left -- ;
$entities_length += Tools :: strlen ( $entity [ 0 ]);
}
else
break ;
}
}
$truncate .= Tools :: substr ( $tag [ 3 ], 0 , $left + $entities_length );
break ;
}
else
{
$truncate .= $tag [ 3 ];
$total_length += $content_length ;
}
if ( $total_length >= $length )
break ;
}
}
else
{
if ( Tools :: strlen ( $text ) <= $length )
return $text ;
$truncate = Tools :: substr ( $text , 0 , $length - Tools :: strlen ( $ellipsis ));
}
if ( ! $exact )
{
$spacepos = Tools :: strrpos ( $truncate , ' ' );
if ( $html )
{
$truncate_check = Tools :: substr ( $truncate , 0 , $spacepos );
$last_open_tag = Tools :: strrpos ( $truncate_check , '<' );
$last_close_tag = Tools :: strrpos ( $truncate_check , '>' );
if ( $last_open_tag > $last_close_tag )
{
preg_match_all ( '/<[\w]+[^>]*>/s' , $truncate , $last_tag_matches );
$last_tag = array_pop ( $last_tag_matches [ 0 ]);
$spacepos = Tools :: strrpos ( $truncate , $last_tag ) + Tools :: strlen ( $last_tag );
}
$bits = Tools :: substr ( $truncate , $spacepos );
preg_match_all ( '/<\/([a-z]+)>/' , $bits , $dropped_tags , PREG_SET_ORDER );
if ( ! empty ( $dropped_tags ))
{
if ( ! empty ( $open_tags ))
{
foreach ( $dropped_tags as $closing_tag )
if ( ! in_array ( $closing_tag [ 1 ], $open_tags ))
array_unshift ( $open_tags , $closing_tag [ 1 ]);
}
else
{
foreach ( $dropped_tags as $closing_tag )
$open_tags [] = $closing_tag [ 1 ];
}
}
}
$truncate = Tools :: substr ( $truncate , 0 , $spacepos );
}
$truncate .= $ellipsis ;
if ( $html )
foreach ( $open_tags as $tag )
$truncate .= '</' . $tag . '>' ;
return $truncate ;
}
public static function normalizeDirectory ( $directory )
{
return rtrim ( $directory , '/\\' ) . DIRECTORY_SEPARATOR ;
}
/**
* Generate date form
*
* @ param int $year Year to select
* @ param int $month Month to select
* @ param int $day Day to select
* @ return array $tab html data with 3 cells : [ 'days' ], [ 'months' ], [ 'years' ]
*
*/
public static function dateYears ()
{
$tab = array ();
for ( $i = date ( 'Y' ); $i >= 1900 ; $i -- )
$tab [] = $i ;
return $tab ;
}
public static function dateDays ()
{
$tab = array ();
for ( $i = 1 ; $i != 32 ; $i ++ )
$tab [] = $i ;
return $tab ;
}
public static function dateMonths ()
{
$tab = array ();
for ( $i = 1 ; $i != 13 ; $i ++ )
$tab [ $i ] = date ( 'F' , mktime ( 0 , 0 , 0 , $i , date ( 'm' ), date ( 'Y' )));
return $tab ;
}
public static function hourGenerate ( $hours , $minutes , $seconds )
{
return implode ( ':' , array ( $hours , $minutes , $seconds ));
}
public static function dateFrom ( $date )
{
$tab = explode ( ' ' , $date );
if ( ! isset ( $tab [ 1 ]))
$date .= ' ' . Tools :: hourGenerate ( 0 , 0 , 0 );
return $date ;
}
public static function dateTo ( $date )
{
$tab = explode ( ' ' , $date );
if ( ! isset ( $tab [ 1 ]))
$date .= ' ' . Tools :: hourGenerate ( 23 , 59 , 59 );
return $date ;
}
public static function strtolower ( $str )
{
if ( is_array ( $str ))
return false ;
if ( function_exists ( 'mb_strtolower' ))
return mb_strtolower ( $str , 'utf-8' );
return strtolower ( $str );
}
public static function strlen ( $str , $encoding = 'UTF-8' )
{
if ( is_array ( $str ))
return false ;
$str = html_entity_decode ( $str , ENT_COMPAT , 'UTF-8' );
if ( function_exists ( 'mb_strlen' ))
return mb_strlen ( $str , $encoding );
return strlen ( $str );
}
public static function stripslashes ( $string )
{
if ( _PS_MAGIC_QUOTES_GPC_ )
$string = stripslashes ( $string );
return $string ;
}
public static function strtoupper ( $str )
{
if ( is_array ( $str ))
return false ;
if ( function_exists ( 'mb_strtoupper' ))
return mb_strtoupper ( $str , 'utf-8' );
return strtoupper ( $str );
}
public static function substr ( $str , $start , $length = false , $encoding = 'utf-8' )
{
if ( is_array ( $str ))
return false ;
if ( function_exists ( 'mb_substr' ))
return mb_substr ( $str , ( int ) $start , ( $length === false ? Tools :: strlen ( $str ) : ( int ) $length ), $encoding );
return substr ( $str , $start , ( $length === false ? Tools :: strlen ( $str ) : ( int ) $length ));
}
public static function strpos ( $str , $find , $offset = 0 , $encoding = 'UTF-8' )
{
if ( function_exists ( 'mb_strpos' ))
return mb_strpos ( $str , $find , $offset , $encoding );
return strpos ( $str , $find , $offset );
}
public static function strrpos ( $str , $find , $offset = 0 , $encoding = 'utf-8' )
{
if ( function_exists ( 'mb_strrpos' ))
return mb_strrpos ( $str , $find , $offset , $encoding );
return strrpos ( $str , $find , $offset );
}
public static function ucfirst ( $str )
{
return Tools :: strtoupper ( Tools :: substr ( $str , 0 , 1 )) . Tools :: substr ( $str , 1 );
}
public static function ucwords ( $str )
{
if ( function_exists ( 'mb_convert_case' ))
return mb_convert_case ( $str , MB_CASE_TITLE );
return ucwords ( Tools :: strtolower ( $str ));
}
public static function orderbyPrice ( & $array , $order_way )
{
foreach ( $array as & $row )
$row [ 'price_tmp' ] = Product :: getPriceStatic ( $row [ 'id_product' ], true , (( isset ( $row [ 'id_product_attribute' ]) && ! empty ( $row [ 'id_product_attribute' ])) ? ( int ) $row [ 'id_product_attribute' ] : null ), 2 );
unset ( $row );
if ( Tools :: strtolower ( $order_way ) == 'desc' )
uasort ( $array , 'cmpPriceDesc' );
else
uasort ( $array , 'cmpPriceAsc' );
foreach ( $array as & $row )
unset ( $row [ 'price_tmp' ]);
}
public static function iconv ( $from , $to , $string )
{
if ( function_exists ( 'iconv' ))
return iconv ( $from , $to . '//TRANSLIT' , str_replace ( '¥' , '¥' , str_replace ( '£' , '£' , str_replace ( '€' , '€' , $string ))));
return html_entity_decode ( htmlentities ( $string , ENT_NOQUOTES , $from ), ENT_NOQUOTES , $to );
}
public static function isEmpty ( $field )
{
return ( $field === '' || $field === null );
}
/**
* returns the rounded value of $value to specified precision , according to your configuration ;
*
* @ note : PHP 5.3 . 0 introduce a 3 rd parameter mode in round function
*
* @ param float $value
* @ param int $precision
* @ return float
*/
public static function ps_round ( $value , $precision = 0 , $round_mode = null )
{
if ( $round_mode === null )
{
if ( Tools :: $round_mode == null )
Tools :: $round_mode = ( int ) Configuration :: get ( 'PS_PRICE_ROUND_MODE' );
$round_mode = Tools :: $round_mode ;
}
switch ( $round_mode )
{
case PS_ROUND_UP :
return Tools :: ceilf ( $value , $precision );
case PS_ROUND_DOWN :
return Tools :: floorf ( $value , $precision );
case PS_ROUND_HALF_DOWN :
case PS_ROUND_HALF_EVEN :
case PS_ROUND_HALF_ODD :
return Tools :: math_round ( $value , $precision , $round_mode );
case PS_ROUND_HALF_UP :
default :
return Tools :: math_round ( $value , $precision , PS_ROUND_HALF_UP );
}
}
public static function math_round ( $value , $places , $mode = PS_ROUND_HALF_UP )
{
//If PHP_ROUND_HALF_UP exist (PHP 5.3) use it and pass correct mode value (PrestaShop define - 1)
if ( defined ( 'PHP_ROUND_HALF_UP' ))
return round ( $value , $places , $mode - 1 );
$precision_places = 14 - floor ( log10 ( abs ( $value )));
$f1 = pow ( 10.0 , ( double ) abs ( $places ));
/* If the decimal precision guaranteed by FP arithmetic is higher than
* the requested places BUT is small enough to make sure a non - zero value
* is returned , pre - round the result to the precision */
if ( $precision_places > $places && $precision_places - $places < 15 )
{
$f2 = pow ( 10.0 , ( double ) abs ( $precision_places ));
if ( $precision_places >= 0 )
$tmp_value = $value * $f2 ;
else
$tmp_value = $value / $f2 ;
/* preround the result ( tmp_value will always be something * 1e14 ,
* thus never larger than 1e15 here ) */
$tmp_value = Tools :: round_helper ( $tmp_value , $mode );
/* now correctly move the decimal point */
$f2 = pow ( 10.0 , ( double ) abs ( $places - $precision_places ));
/* because places < precision_places */
$tmp_value = $tmp_value / $f2 ;
}
else
{
/* adjust the value */
if ( $places >= 0 )
$tmp_value = $value * $f1 ;
else
$tmp_value = $value / $f1 ;
/* This value is beyond our precision, so rounding it is pointless */
if ( abs ( $tmp_value ) >= 1e15 )
return $value ;
}
/* round the temp value */
$tmp_value = Tools :: round_helper ( $tmp_value , $mode );
/* see if it makes sense to use simple division to round the value */
if ( abs ( $places ) < 23 )
{
if ( $places > 0 )
$tmp_value /= $f1 ;
else
$tmp_value *= $f1 ;
}
return $tmp_value ;
}
public static function round_helper ( $value , $mode )
{
if ( $value >= 0.0 )
{
$tmp_value = floor ( $value + 0.5 );
if (( $mode == PS_ROUND_HALF_DOWN && $value == ( - 0.5 + $tmp_value )) ||
( $mode == PS_ROUND_HALF_EVEN && $value == ( 0.5 + 2 * floor ( $tmp_value / 2.0 ))) ||
( $mode == PS_ROUND_HALF_ODD && $value == ( 0.5 + 2 * floor ( $tmp_value / 2.0 ) - 1.0 )))
$tmp_value = $tmp_value - 1.0 ;
}
else
{
$tmp_value = ceil ( $value - 0.5 );
if (( $mode == PS_ROUND_HALF_DOWN && $value == ( 0.5 + $tmp_value )) ||
( $mode == PS_ROUND_HALF_EVEN && $value == ( - 0.5 + 2 * ceil ( $tmp_value / 2.0 ))) ||
( $mode == PS_ROUND_HALF_ODD && $value == ( - 0.5 + 2 * ceil ( $tmp_value / 2.0 ) + 1.0 )))
$tmp_value = $tmp_value + 1.0 ;
}
return $tmp_value ;
}
/**
* returns the rounded value down of $value to specified precision
*
* @ param float $value
* @ param int $precision
* @ return float
*/
public static function ceilf ( $value , $precision = 0 )
{
$precision_factor = $precision == 0 ? 1 : pow ( 10 , $precision );
$tmp = $value * $precision_factor ;
$tmp2 = ( string ) $tmp ;
// If the current value has already the desired precision
if ( strpos ( $tmp2 , '.' ) === false )
return ( $value );
if ( $tmp2 [ strlen ( $tmp2 ) - 1 ] == 0 )
return $value ;
return ceil ( $tmp ) / $precision_factor ;
}
/**
* returns the rounded value up of $value to specified precision
*
* @ param float $value
* @ param int $precision
* @ return float
*/
public static function floorf ( $value , $precision = 0 )
{
$precision_factor = $precision == 0 ? 1 : pow ( 10 , $precision );
$tmp = $value * $precision_factor ;
$tmp2 = ( string ) $tmp ;
// If the current value has already the desired precision
if ( strpos ( $tmp2 , '.' ) === false )
return ( $value );
if ( $tmp2 [ strlen ( $tmp2 ) - 1 ] == 0 )
return $value ;
return floor ( $tmp ) / $precision_factor ;
}
/**
* file_exists () wrapper with cache to speedup performance
*
* @ param string $filename File name
* @ return bool Cached result of file_exists ( $filename )
*/
public static function file_exists_cache ( $filename )
{
if ( ! isset ( self :: $file_exists_cache [ $filename ]))
self :: $file_exists_cache [ $filename ] = file_exists ( $filename );
return self :: $file_exists_cache [ $filename ];
}
/**
* file_exists () wrapper with a call to clearstatcache prior
*
* @ param string $filename File name
* @ return bool Cached result of file_exists ( $filename )
*/
public static function file_exists_no_cache ( $filename )
{
clearstatcache ();
return file_exists ( $filename );
}
public static function file_get_contents ( $url , $use_include_path = false , $stream_context = null , $curl_timeout = 5 )
{
if ( $stream_context == null && preg_match ( '/^https?:\/\//' , $url ))
$stream_context = @ stream_context_create ( array ( 'http' => array ( 'timeout' => $curl_timeout )));
if ( in_array ( ini_get ( 'allow_url_fopen' ), array ( 'On' , 'on' , '1' )) || ! preg_match ( '/^https?:\/\//' , $url ))
return @ file_get_contents ( $url , $use_include_path , $stream_context );
elseif ( function_exists ( 'curl_init' ))
{
$curl = curl_init ();
curl_setopt ( $curl , CURLOPT_RETURNTRANSFER , 1 );
curl_setopt ( $curl , CURLOPT_URL , $url );
curl_setopt ( $curl , CURLOPT_CONNECTTIMEOUT , 5 );
curl_setopt ( $curl , CURLOPT_TIMEOUT , $curl_timeout );
curl_setopt ( $curl , CURLOPT_SSL_VERIFYPEER , 0 );
if ( $stream_context != null )
{
$opts = stream_context_get_options ( $stream_context );
if ( isset ( $opts [ 'http' ][ 'method' ]) && Tools :: strtolower ( $opts [ 'http' ][ 'method' ]) == 'post' )
{
curl_setopt ( $curl , CURLOPT_POST , true );
if ( isset ( $opts [ 'http' ][ 'content' ]))
{
parse_str ( $opts [ 'http' ][ 'content' ], $post_data );
curl_setopt ( $curl , CURLOPT_POSTFIELDS , $post_data );
}
}
}
$content = curl_exec ( $curl );
curl_close ( $curl );
return $content ;
}
else
return false ;
}
public static function simplexml_load_file ( $url , $class_name = null )
{
$cache_id = 'Tools::simplexml_load_file' . $url ;
if ( ! Cache :: isStored ( $cache_id ))
{
$result = @ simplexml_load_string ( Tools :: file_get_contents ( $url ), $class_name );
Cache :: store ( $cache_id , $result );
return $result ;
}
return Cache :: retrieve ( $cache_id );
}
public static function copy ( $source , $destination , $stream_context = null )
{
if ( is_null ( $stream_context ) && ! preg_match ( '/^https?:\/\//' , $source ))
return @ copy ( $source , $destination );
return @ file_put_contents ( $destination , Tools :: file_get_contents ( $source , false , $stream_context ));
}
/**
* @ deprecated as of 1.5 use Media :: minifyHTML ()
*/
public static function minifyHTML ( $html_content )
{
Tools :: displayAsDeprecated ();
return Media :: minifyHTML ( $html_content );
}
/**
* Translates a string with underscores into camel case ( e . g . first_name -> firstName )
* @ prototype string public static function toCamelCase ( string $str [, bool $capitalise_first_char = false ])
*/
public static function toCamelCase ( $str , $catapitalise_first_char = false )
{
$str = Tools :: strtolower ( $str );
if ( $catapitalise_first_char )
$str = Tools :: ucfirst ( $str );
return preg_replace_callback ( '/_+([a-z])/' , create_function ( '$c' , 'return strtoupper($c[1]);' ), $str );
}
/**
* Transform a CamelCase string to underscore_case string
*
* @ param string $string
* @ return string
*/
public static function toUnderscoreCase ( $string )
{
// 'CMSCategories' => 'cms_categories'
// 'RangePrice' => 'range_price'
return Tools :: strtolower ( trim ( preg_replace ( '/([A-Z][a-z])/' , '_$1' , $string ), '_' ));
}
public static function getBrightness ( $hex )
{
if ( Tools :: strtolower ( $hex ) == 'transparent' )
return '129' ;
$hex = str_replace ( '#' , '' , $hex );
$r = hexdec ( substr ( $hex , 0 , 2 ));
$g = hexdec ( substr ( $hex , 2 , 2 ));
$b = hexdec ( substr ( $hex , 4 , 2 ));
return (( $r * 299 ) + ( $g * 587 ) + ( $b * 114 )) / 1000 ;
}
/**
* @ deprecated as of 1.5 use Media :: minifyHTMLpregCallback ()
*/
public static function minifyHTMLpregCallback ( $preg_matches )
{
Tools :: displayAsDeprecated ();
return Media :: minifyHTMLpregCallback ( $preg_matches );
}
/**
* @ deprecated as of 1.5 use Media :: packJSinHTML ()
*/
public static function packJSinHTML ( $html_content )
{
Tools :: displayAsDeprecated ();
return Media :: packJSinHTML ( $html_content );
}
/**
* @ deprecated as of 1.5 use Media :: packJSinHTMLpregCallback ()
*/
public static function packJSinHTMLpregCallback ( $preg_matches )
{
Tools :: displayAsDeprecated ();
return Media :: packJSinHTMLpregCallback ( $preg_matches );
}
/**
* @ deprecated as of 1.5 use Media :: packJS ()
*/
public static function packJS ( $js_content )
{
Tools :: displayAsDeprecated ();
return Media :: packJS ( $js_content );
}
public static function parserSQL ( $sql )
{
if ( strlen ( $sql ) > 0 )
{
require_once ( _PS_TOOL_DIR_ . 'parser_sql/PHPSQLParser.php' );
$parser = new PHPSQLParser ( $sql );
return $parser -> parsed ;
}
return false ;
}
/**
* @ deprecated as of 1.5 use Media :: minifyCSS ()
*/
public static function minifyCSS ( $css_content , $fileuri = false )
{
Tools :: displayAsDeprecated ();
return Media :: minifyCSS ( $css_content , $fileuri );
}
public static function replaceByAbsoluteURL ( $matches )
{
global $current_css_file ;
$protocol_link = Tools :: getCurrentUrlProtocolPrefix ();
if ( array_key_exists ( 1 , $matches ) && array_key_exists ( 2 , $matches ))
{
if ( ! preg_match ( '/^(?:https?:)?\/\//iUs' , $matches [ 2 ]))
{
$sep = '/' ;
$tmp = substr ( $matches [ 2 ], 0 , 1 ) == $sep ? $matches [ 2 ] : dirname ( $current_css_file ) . $sep . ltrim ( $matches [ 2 ], $sep );
$server = Tools :: getMediaServer ( $tmp );
return $matches [ 1 ] . $protocol_link . $server . $tmp ;
}
else
return $matches [ 0 ];
}
return false ;
}
/**
* addJS load a javascript file in the header
*
* @ deprecated as of 1.5 use FrontController -> addJS ()
* @ param mixed $js_uri
* @ return void
*/
public static function addJS ( $js_uri )
{
Tools :: displayAsDeprecated ();
$context = Context :: getContext ();
$context -> controller -> addJs ( $js_uri );
}
/**
* @ deprecated as of 1.5 use FrontController -> addCSS ()
*/
public static function addCSS ( $css_uri , $css_media_type = 'all' )
{
Tools :: displayAsDeprecated ();
$context = Context :: getContext ();
$context -> controller -> addCSS ( $css_uri , $css_media_type );
}
/**
* @ deprecated as of 1.5 use Media :: cccCss ()
*/
public static function cccCss ( $css_files )
{
Tools :: displayAsDeprecated ();
return Media :: cccCss ( $css_files );
}
/**
* @ deprecated as of 1.5 use Media :: cccJS ()
*/
public static function cccJS ( $js_files )
{
Tools :: displayAsDeprecated ();
return Media :: cccJS ( $js_files );
}
protected static $_cache_nb_media_servers = null ;
public static function getMediaServer ( $filename )
{
if ( self :: $_cache_nb_media_servers === null && defined ( '_MEDIA_SERVER_1_' ) && defined ( '_MEDIA_SERVER_2_' ) && defined ( '_MEDIA_SERVER_3_' ))
{
if ( _MEDIA_SERVER_1_ == '' )
self :: $_cache_nb_media_servers = 0 ;
elseif ( _MEDIA_SERVER_2_ == '' )
self :: $_cache_nb_media_servers = 1 ;
elseif ( _MEDIA_SERVER_3_ == '' )
self :: $_cache_nb_media_servers = 2 ;
else
self :: $_cache_nb_media_servers = 3 ;
}
if ( $filename && self :: $_cache_nb_media_servers && ( $id_media_server = ( abs ( crc32 ( $filename )) % self :: $_cache_nb_media_servers + 1 )))
return constant ( '_MEDIA_SERVER_' . $id_media_server . '_' );
return Tools :: usingSecureMode () ? Tools :: getShopDomainSSL () : Tools :: getShopDomain ();
}
public static function generateHtaccess ( $path = null , $rewrite_settings = null , $cache_control = null , $specific = '' , $disable_multiviews = null , $medias = false , $disable_modsec = null )
{
if ( defined ( 'PS_INSTALLATION_IN_PROGRESS' ) && $rewrite_settings === null )
return true ;
// Default values for parameters
if ( is_null ( $path ))
$path = _PS_ROOT_DIR_ . '/.htaccess' ;
if ( is_null ( $cache_control ))
$cache_control = ( int ) Configuration :: get ( 'PS_HTACCESS_CACHE_CONTROL' );
if ( is_null ( $disable_multiviews ))
$disable_multiviews = ( int ) Configuration :: get ( 'PS_HTACCESS_DISABLE_MULTIVIEWS' );
if ( $disable_modsec === null )
$disable_modsec = ( int ) Configuration :: get ( 'PS_HTACCESS_DISABLE_MODSEC' );
// Check current content of .htaccess and save all code outside of prestashop comments
$specific_before = $specific_after = '' ;
if ( file_exists ( $path ))
{
$content = file_get_contents ( $path );
if ( preg_match ( '#^(.*)\# ~~start~~.*\# ~~end~~[^\n]*(.*)$#s' , $content , $m ))
{
$specific_before = $m [ 1 ];
$specific_after = $m [ 2 ];
}
else
{
// For retrocompatibility
if ( preg_match ( '#\# http://www\.prestashop\.com - http://www\.prestashop\.com/forums\s*(.*)<IfModule mod_rewrite\.c>#si' , $content , $m ))
$specific_before = $m [ 1 ];
else
$specific_before = $content ;
}
}
// Write .htaccess data
if ( ! $write_fd = @ fopen ( $path , 'w' ))
return false ;
if ( $specific_before )
fwrite ( $write_fd , trim ( $specific_before ) . " \n \n " );
$domains = array ();
foreach ( ShopUrl :: getShopUrls () as $shop_url )
{
/** @var ShopUrl $shop_url */
if ( ! isset ( $domains [ $shop_url -> domain ]))
$domains [ $shop_url -> domain ] = array ();
$domains [ $shop_url -> domain ][] = array (
'physical' => $shop_url -> physical_uri ,
'virtual' => $shop_url -> virtual_uri ,
'id_shop' => $shop_url -> id_shop
);
if ( $shop_url -> domain == $shop_url -> domain_ssl )
continue ;
if ( ! isset ( $domains [ $shop_url -> domain_ssl ]))
$domains [ $shop_url -> domain_ssl ] = array ();
$domains [ $shop_url -> domain_ssl ][] = array (
'physical' => $shop_url -> physical_uri ,
'virtual' => $shop_url -> virtual_uri ,
'id_shop' => $shop_url -> id_shop
);
}
// Write data in .htaccess file
fwrite ( $write_fd , " # ~~start~~ Do not remove this comment, Prestashop will keep automatically the code outside this comment when .htaccess will be generated again \n " );
fwrite ( $write_fd , " # .htaccess automaticaly generated by PrestaShop e-commerce open-source solution \n " );
fwrite ( $write_fd , " # http://www.prestashop.com - http://www.prestashop.com/forums \n \n " );
if ( $disable_modsec )
fwrite ( $write_fd , " <IfModule mod_security.c> \n SecFilterEngine Off \n SecFilterScanPOST Off \n </IfModule> \n \n " );
// RewriteEngine
fwrite ( $write_fd , " <IfModule mod_rewrite.c> \n " );
// Ensure HTTP_MOD_REWRITE variable is set in environment
fwrite ( $write_fd , " <IfModule mod_env.c> \n " );
fwrite ( $write_fd , " SetEnv HTTP_MOD_REWRITE On \n " );
fwrite ( $write_fd , " </IfModule> \n \n " );
// Disable multiviews ?
if ( $disable_multiviews )
fwrite ( $write_fd , " \n # Disable Multiviews \n Options -Multiviews \n \n " );
fwrite ( $write_fd , " RewriteEngine on \n " );
if ( ! $medias && defined ( '_MEDIA_SERVER_1_' ) && defined ( '_MEDIA_SERVER_2_' ) && defined ( '_MEDIA_SERVER_3_' ))
$medias = array ( _MEDIA_SERVER_1_ , _MEDIA_SERVER_2_ , _MEDIA_SERVER_3_ );
$media_domains = '' ;
if ( $medias [ 0 ] != '' )
$media_domains = 'RewriteCond %{HTTP_HOST} ^' . $medias [ 0 ] . '$ [OR]' . " \n " ;
if ( $medias [ 1 ] != '' )
$media_domains .= 'RewriteCond %{HTTP_HOST} ^' . $medias [ 1 ] . '$ [OR]' . " \n " ;
if ( $medias [ 2 ] != '' )
$media_domains .= 'RewriteCond %{HTTP_HOST} ^' . $medias [ 2 ] . '$ [OR]' . " \n " ;
if ( Configuration :: get ( 'PS_WEBSERVICE_CGI_HOST' ))
fwrite ( $write_fd , " RewriteCond % { HTTP:Authorization} ^(.*) \n RewriteRule . - [E=HTTP_AUTHORIZATION:%1] \n \n " );
foreach ( $domains as $domain => $list_uri )
{
$physicals = array ();
foreach ( $list_uri as $uri )
{
fwrite ( $write_fd , PHP_EOL . PHP_EOL . '#Domain: ' . $domain . PHP_EOL );
if ( Shop :: isFeatureActive ())
fwrite ( $write_fd , 'RewriteCond %{HTTP_HOST} ^' . $domain . '$' . " \n " );
fwrite ( $write_fd , 'RewriteRule . - [E=REWRITEBASE:' . $uri [ 'physical' ] . ']' . " \n " );
// Webservice
fwrite ( $write_fd , 'RewriteRule ^api$ api/ [L]' . " \n \n " );
fwrite ( $write_fd , 'RewriteRule ^api/(.*)$ %{ENV:REWRITEBASE}webservice/dispatcher.php?url=$1 [QSA,L]' . " \n \n " );
if ( ! $rewrite_settings )
$rewrite_settings = ( int ) Configuration :: get ( 'PS_REWRITING_SETTINGS' , null , null , ( int ) $uri [ 'id_shop' ]);
$domain_rewrite_cond = 'RewriteCond %{HTTP_HOST} ^' . $domain . '$' . " \n " ;
// Rewrite virtual multishop uri
if ( $uri [ 'virtual' ])
{
if ( ! $rewrite_settings )
{
fwrite ( $write_fd , $media_domains );
if ( Shop :: isFeatureActive ())
fwrite ( $write_fd , $domain_rewrite_cond );
fwrite ( $write_fd , 'RewriteRule ^' . trim ( $uri [ 'virtual' ], '/' ) . '/?$ ' . $uri [ 'physical' ] . $uri [ 'virtual' ] . " index.php [L,R] \n " );
}
else
{
fwrite ( $write_fd , $media_domains );
if ( Shop :: isFeatureActive ())
fwrite ( $write_fd , $domain_rewrite_cond );
fwrite ( $write_fd , 'RewriteRule ^' . trim ( $uri [ 'virtual' ], '/' ) . '$ ' . $uri [ 'physical' ] . $uri [ 'virtual' ] . " [L,R] \n " );
}
fwrite ( $write_fd , $media_domains );
if ( Shop :: isFeatureActive ())
fwrite ( $write_fd , $domain_rewrite_cond );
fwrite ( $write_fd , 'RewriteRule ^' . ltrim ( $uri [ 'virtual' ], '/' ) . '(.*) ' . $uri [ 'physical' ] . " $ 1 [L] \n \n " );
}
if ( $rewrite_settings )
{
// Compatibility with the old image filesystem
fwrite ( $write_fd , " # Images \n " );
if ( Configuration :: get ( 'PS_LEGACY_IMAGES' ))
{
fwrite ( $write_fd , $media_domains );
if ( Shop :: isFeatureActive ())
fwrite ( $write_fd , $domain_rewrite_cond );
fwrite ( $write_fd , 'RewriteRule ^([a-z0-9]+)\-([a-z0-9]+)(\-[_a-zA-Z0-9-]*)(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1-$2$3$4.jpg [L]' . " \n " );
fwrite ( $write_fd , $media_domains );
if ( Shop :: isFeatureActive ())
fwrite ( $write_fd , $domain_rewrite_cond );
fwrite ( $write_fd , 'RewriteRule ^([0-9]+)\-([0-9]+)(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1-$2$3.jpg [L]' . " \n " );
}
// Rewrite product images < 100 millions
for ( $i = 1 ; $i <= 8 ; $i ++ )
{
$img_path = $img_name = '' ;
for ( $j = 1 ; $j <= $i ; $j ++ )
{
$img_path .= '$' . $j . '/' ;
$img_name .= '$' . $j ;
}
$img_name .= '$' . $j ;
fwrite ( $write_fd , $media_domains );
if ( Shop :: isFeatureActive ())
fwrite ( $write_fd , $domain_rewrite_cond );
fwrite ( $write_fd , 'RewriteRule ^' . str_repeat ( '([0-9])' , $i ) . '(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/' . $img_path . $img_name . '$' . ( $j + 1 ) . " .jpg [L] \n " );
}
fwrite ( $write_fd , $media_domains );
if ( Shop :: isFeatureActive ())
fwrite ( $write_fd , $domain_rewrite_cond );
fwrite ( $write_fd , 'RewriteRule ^c/([0-9]+)(\-[\.*_a-zA-Z0-9-]*)(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/c/$1$2$3.jpg [L]' . " \n " );
fwrite ( $write_fd , $media_domains );
if ( Shop :: isFeatureActive ())
fwrite ( $write_fd , $domain_rewrite_cond );
fwrite ( $write_fd , 'RewriteRule ^c/([a-zA-Z_-]+)(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/c/$1$2.jpg [L]' . " \n " );
}
fwrite ( $write_fd , " # AlphaImageLoader for IE and fancybox \n " );
if ( Shop :: isFeatureActive ())
fwrite ( $write_fd , $domain_rewrite_cond );
fwrite ( $write_fd , 'RewriteRule ^images_ie/?([^/]+)\.(jpe?g|png|gif)$ js/jquery/plugins/fancybox/images/$1.$2 [L]' . " \n " );
}
// Redirections to dispatcher
if ( $rewrite_settings )
{
fwrite ( $write_fd , " \n # Dispatcher \n " );
fwrite ( $write_fd , " RewriteCond % { REQUEST_FILENAME} -s [OR] \n " );
fwrite ( $write_fd , " RewriteCond % { REQUEST_FILENAME} -l [OR] \n " );
fwrite ( $write_fd , " RewriteCond % { REQUEST_FILENAME} -d \n " );
if ( Shop :: isFeatureActive ())
fwrite ( $write_fd , $domain_rewrite_cond );
fwrite ( $write_fd , " RewriteRule ^.* $ - [NC,L] \n " );
if ( Shop :: isFeatureActive ())
fwrite ( $write_fd , $domain_rewrite_cond );
fwrite ( $write_fd , " RewriteRule ^.* \$ % { ENV:REWRITEBASE}index.php [NC,L] \n " );
}
}
fwrite ( $write_fd , " </IfModule> \n \n " );
fwrite ( $write_fd , " AddType application/vnd.ms-fontobject .eot \n " );
fwrite ( $write_fd , " AddType font/ttf .ttf \n " );
fwrite ( $write_fd , " AddType font/otf .otf \n " );
fwrite ( $write_fd , " AddType application/x-font-woff .woff \n " );
fwrite ( $write_fd , " <IfModule mod_headers.c>
< FilesMatch \ " \ .(ttf|ttc|otf|eot|woff|svg) $\ " >
Header add Access - Control - Allow - Origin \ " * \"
</ FilesMatch >
</ IfModule > \n\n " );
// Cache control
if ( $cache_control )
{
$cache_control = " <IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image / gif \ " access plus 1 month \"
ExpiresByType image / jpeg \ " access plus 1 month \"
ExpiresByType image / png \ " access plus 1 month \"
ExpiresByType text / css \ " access plus 1 week \"
ExpiresByType text / javascript \ " access plus 1 week \"
ExpiresByType application / javascript \ " access plus 1 week \"
ExpiresByType application / x - javascript \ " access plus 1 week \"
ExpiresByType image / x - icon \ " access plus 1 year \"
ExpiresByType image / svg + xml \ " access plus 1 year \"
ExpiresByType image / vnd . microsoft . icon \ " access plus 1 year \"
ExpiresByType application / font - woff \ " access plus 1 year \"
ExpiresByType application / x - font - woff \ " access plus 1 year \"
ExpiresByType application / vnd . ms - fontobject \ " access plus 1 year \"
ExpiresByType font / opentype \ " access plus 1 year \"
ExpiresByType font / ttf \ " access plus 1 year \"
ExpiresByType font / otf \ " access plus 1 year \"
ExpiresByType application / x - font - ttf \ " access plus 1 year \"
ExpiresByType application / x - font - otf \ " access plus 1 year \"
</ IfModule >
< IfModule mod_headers . c >
Header unset Etag
</ IfModule >
FileETag none
< IfModule mod_deflate . c >
< IfModule mod_filter . c >
AddOutputFilterByType DEFLATE text / html text / css text / javascript application / javascript application / x - javascript font / ttf application / x - font - ttf font / otf application / x - font - otf font / opentype
</ IfModule >
</ IfModule > \n\n " ;
fwrite ( $write_fd , $cache_control );
}
// In case the user hasn't rewrite mod enabled
fwrite ( $write_fd , " #If rewrite mod isn't enabled \n " );
// Do not remove ($domains is already iterated upper)
reset ( $domains );
$domain = current ( $domains );
fwrite ( $write_fd , 'ErrorDocument 404 ' . $domain [ 0 ][ 'physical' ] . " index.php?controller=404 \n \n " );
fwrite ( $write_fd , " # ~~end~~ Do not remove this comment, Prestashop will keep automatically the code outside this comment when .htaccess will be generated again " );
if ( $specific_after )
fwrite ( $write_fd , " \n \n " . trim ( $specific_after ));
fclose ( $write_fd );
if ( ! defined ( 'PS_INSTALLATION_IN_PROGRESS' ))
Hook :: exec ( 'actionHtaccessCreate' );
return true ;
}
public static function generateIndex ()
{
if ( defined ( '_DB_PREFIX_' ) && Configuration :: get ( 'PS_DISABLE_OVERRIDES' ))
PrestaShopAutoload :: getInstance () -> _include_override_path = false ;
PrestaShopAutoload :: getInstance () -> generateIndex ();
}
public static function getDefaultIndexContent ()
{
return ' < ? php
/**
* 2007 - '.date(' Y ').' PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License ( OSL 3.0 )
* that is bundled with this package in the file LICENSE . txt .
* It is also available through the world - wide - web at this URL :
* http :// opensource . org / licenses / osl - 3.0 . php
* If you did not receive a copy of the license and are unable to
* obtain it through the world - wide - web , please send an email
* to license @ prestashop . com so we can send you a copy immediately .
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future . If you wish to customize PrestaShop for your
* needs please refer to http :// www . prestashop . com for more information .
*
* @ author PrestaShop SA < contact @ prestashop . com >
* @ copyright 2007 - '.date(' Y ').' PrestaShop SA
* @ license http :// opensource . org / licenses / osl - 3.0 . php Open Software License ( OSL 3.0 )
* International Registered Trademark & Property of PrestaShop SA
*/
header ( " Expires: Mon, 26 Jul 1997 05:00:00 GMT " );
header ( " Last-Modified: " . gmdate ( " D, d M Y H:i:s " ) . " GMT " );
header ( " Cache-Control: no-store, no-cache, must-revalidate " );
header ( " Cache-Control: post-check=0, pre-check=0 " , false );
header ( " Pragma: no-cache " );
header ( " Location: ../ " );
exit ;
' ;
}
/**
* jsonDecode convert json string to php array / object
*
* @ param string $json
* @ param bool $assoc ( since 1.4 . 2.4 ) if true , convert to associativ array
* @ return array
*/
public static function jsonDecode ( $json , $assoc = false )
{
if ( function_exists ( 'json_decode' ))
return json_decode ( $json , $assoc );
else
{
include_once ( _PS_TOOL_DIR_ . 'json/json.php' );
$pear_json = new Services_JSON (( $assoc ) ? SERVICES_JSON_LOOSE_TYPE : 0 );
return $pear_json -> decode ( $json );
}
}
/**
* Convert an array to json string
*
* @ param array $data
* @ return string json
*/
public static function jsonEncode ( $data )
{
if ( function_exists ( 'json_encode' ))
return json_encode ( $data );
else
{
include_once ( _PS_TOOL_DIR_ . 'json/json.php' );
$pear_json = new Services_JSON ();
return $pear_json -> encode ( $data );
}
}
/**
* Display a warning message indicating that the method is deprecated
*/
public static function displayAsDeprecated ( $message = null )
{
$backtrace = debug_backtrace ();
$callee = next ( $backtrace );
$class = isset ( $callee [ 'class' ]) ? $callee [ 'class' ] : null ;
if ( $message === null )
$message = 'The function ' . $callee [ 'function' ] . ' (Line ' . $callee [ 'line' ] . ') is deprecated and will be removed in the next major version.' ;
$error = 'Function <b>' . $callee [ 'function' ] . '()</b> is deprecated in <b>' . $callee [ 'file' ] . '</b> on line <b>' . $callee [ 'line' ] . '</b><br />' ;
Tools :: throwDeprecated ( $error , $message , $class );
}
/**
* Display a warning message indicating that the parameter is deprecated
*/
public static function displayParameterAsDeprecated ( $parameter )
{
$backtrace = debug_backtrace ();
$callee = next ( $backtrace );
$error = 'Parameter <b>' . $parameter . '</b> in function <b>' . ( isset ( $callee [ 'function' ]) ? $callee [ 'function' ] : '' ) . '()</b> is deprecated in <b>' . $callee [ 'file' ] . '</b> on line <b>' . ( isset ( $callee [ 'line' ]) ? $callee [ 'line' ] : '(undefined)' ) . '</b><br />' ;
$message = 'The parameter ' . $parameter . ' in function ' . $callee [ 'function' ] . ' (Line ' . ( isset ( $callee [ 'line' ]) ? $callee [ 'line' ] : 'undefined' ) . ') is deprecated and will be removed in the next major version.' ;
$class = isset ( $callee [ 'class' ]) ? $callee [ 'class' ] : null ;
Tools :: throwDeprecated ( $error , $message , $class );
}
public static function displayFileAsDeprecated ()
{
$backtrace = debug_backtrace ();
$callee = current ( $backtrace );
$error = 'File <b>' . $callee [ 'file' ] . '</b> is deprecated<br />' ;
$message = 'The file ' . $callee [ 'file' ] . ' is deprecated and will be removed in the next major version.' ;
$class = isset ( $callee [ 'class' ]) ? $callee [ 'class' ] : null ;
Tools :: throwDeprecated ( $error , $message , $class );
}
protected static function throwDeprecated ( $error , $message , $class )
{
if ( _PS_DISPLAY_COMPATIBILITY_WARNING_ )
{
trigger_error ( $error , E_USER_WARNING );
PrestaShopLogger :: addLog ( $message , 3 , $class );
}
}
public static function enableCache ( $level = 1 , Context $context = null )
{
if ( ! $context )
$context = Context :: getContext ();
$smarty = $context -> smarty ;
if ( ! Configuration :: get ( 'PS_SMARTY_CACHE' ))
return ;
if ( $smarty -> force_compile == 0 && $smarty -> caching == $level )
return ;
self :: $_forceCompile = ( int ) $smarty -> force_compile ;
self :: $_caching = ( int ) $smarty -> caching ;
$smarty -> force_compile = 0 ;
$smarty -> caching = ( int ) $level ;
$smarty -> cache_lifetime = 31536000 ; // 1 Year
}
public static function restoreCacheSettings ( Context $context = null )
{
if ( ! $context )
$context = Context :: getContext ();
if ( isset ( self :: $_forceCompile ))
$context -> smarty -> force_compile = ( int ) self :: $_forceCompile ;
if ( isset ( self :: $_caching ))
$context -> smarty -> caching = ( int ) self :: $_caching ;
}
public static function isCallable ( $function )
{
$disabled = explode ( ',' , ini_get ( 'disable_functions' ));
return ( ! in_array ( $function , $disabled ) && is_callable ( $function ));
}
public static function pRegexp ( $s , $delim )
{
$s = str_replace ( $delim , '\\' . $delim , $s );
foreach ( array ( '?' , '[' , ']' , '(' , ')' , '{' , '}' , '-' , '.' , '+' , '*' , '^' , '$' , '`' , '"' , '%' ) as $char )
$s = str_replace ( $char , '\\' . $char , $s );
return $s ;
}
public static function str_replace_once ( $needle , $replace , $haystack )
{
$pos = false ;
if ( $needle )
$pos = strpos ( $haystack , $needle );
if ( $pos === false )
return $haystack ;
return substr_replace ( $haystack , $replace , $pos , strlen ( $needle ));
}
/**
* Function property_exists does not exist in PHP < 5.1
*
* @ deprecated since 1.5 . 0 ( PHP 5.1 required , so property_exists () is now natively supported )
* @ param object $class
* @ param string $property
* @ return bool
*/
public static function property_exists ( $class , $property )
{
Tools :: displayAsDeprecated ();
if ( function_exists ( 'property_exists' ))
return property_exists ( $class , $property );
if ( is_object ( $class ))
$vars = get_object_vars ( $class );
else
$vars = get_class_vars ( $class );
return array_key_exists ( $property , $vars );
}
/**
* @ desc identify the version of php
* @ return string
*/
public static function checkPhpVersion ()
{
$version = null ;
if ( defined ( 'PHP_VERSION' ))
$version = PHP_VERSION ;
else
$version = phpversion ( '' );
//Case management system of ubuntu, php version return 5.2.4-2ubuntu5.2
if ( strpos ( $version , '-' ) !== false )
$version = substr ( $version , 0 , strpos ( $version , '-' ));
return $version ;
}
/**
* @ desc try to open a zip file in order to check if it ' s valid
* @ return bool success
*/
public static function ZipTest ( $from_file )
{
if ( class_exists ( 'ZipArchive' , false ))
{
$zip = new ZipArchive ();
return ( $zip -> open ( $from_file , ZIPARCHIVE :: CHECKCONS ) === true );
}
else
{
require_once ( _PS_ROOT_DIR_ . '/tools/pclzip/pclzip.lib.php' );
$zip = new PclZip ( $from_file );
return ( $zip -> privCheckFormat () === true );
}
}
public static function getSafeModeStatus ()
{
if ( ! $safe_mode = @ ini_get ( 'safe_mode' ))
$safe_mode = '' ;
return in_array ( Tools :: strtolower ( $safe_mode ), array ( 1 , 'on' ));
}
/**
* @ desc extract a zip file to the given directory
* @ return bool success
*/
public static function ZipExtract ( $from_file , $to_dir )
{
if ( ! file_exists ( $to_dir ))
mkdir ( $to_dir , 0777 );
if ( class_exists ( 'ZipArchive' , false ))
{
$zip = new ZipArchive ();
if ( $zip -> open ( $from_file ) === true && $zip -> extractTo ( $to_dir ) && $zip -> close ())
return true ;
return false ;
}
else
{
require_once ( _PS_ROOT_DIR_ . '/tools/pclzip/pclzip.lib.php' );
$zip = new PclZip ( $from_file );
$list = $zip -> extract ( PCLZIP_OPT_PATH , $to_dir , PCLZIP_OPT_REPLACE_NEWER );
foreach ( $list as $file )
if ( $file [ 'status' ] != 'ok' && $file [ 'status' ] != 'already_a_directory' )
return false ;
return true ;
}
}
public static function chmodr ( $path , $filemode )
{
if ( ! is_dir ( $path ))
return @ chmod ( $path , $filemode );
$dh = opendir ( $path );
while (( $file = readdir ( $dh )) !== false )
{
if ( $file != '.' && $file != '..' )
{
$fullpath = $path . '/' . $file ;
if ( is_link ( $fullpath ))
return false ;
elseif ( ! is_dir ( $fullpath ) && !@ chmod ( $fullpath , $filemode ))
return false ;
elseif ( ! Tools :: chmodr ( $fullpath , $filemode ))
return false ;
}
}
closedir ( $dh );
if ( @ chmod ( $path , $filemode ))
return true ;
else
return false ;
}
/**
* Get products order field name for queries .
*
* @ param string $type by | way
* @ param string $value If no index given , use default order from admin -> pref -> products
* @ param bool | \bool ( false ) | string $prefix
*
* @ return string Order by sql clause
*/
public static function getProductsOrder ( $type , $value = null , $prefix = false )
{
switch ( $type )
{
case 'by' :
$list = array ( 0 => 'name' , 1 => 'price' , 2 => 'date_add' , 3 => 'date_upd' , 4 => 'position' , 5 => 'manufacturer_name' , 6 => 'quantity' , 7 => 'reference' );
$value = ( is_null ( $value ) || $value === false || $value === '' ) ? ( int ) Configuration :: get ( 'PS_PRODUCTS_ORDER_BY' ) : $value ;
$value = ( isset ( $list [ $value ])) ? $list [ $value ] : (( in_array ( $value , $list )) ? $value : 'position' );
$order_by_prefix = '' ;
if ( $prefix )
{
if ( $value == 'id_product' || $value == 'date_add' || $value == 'date_upd' || $value == 'price' )
$order_by_prefix = 'p.' ;
elseif ( $value == 'name' )
$order_by_prefix = 'pl.' ;
elseif ( $value == 'manufacturer_name' && $prefix )
{
$order_by_prefix = 'm.' ;
$value = 'name' ;
}
elseif ( $value == 'position' || empty ( $value ))
$order_by_prefix = 'cp.' ;
}
return $order_by_prefix . $value ;
break ;
case 'way' :
$value = ( is_null ( $value ) || $value === false || $value === '' ) ? ( int ) Configuration :: get ( 'PS_PRODUCTS_ORDER_WAY' ) : $value ;
$list = array ( 0 => 'asc' , 1 => 'desc' );
return (( isset ( $list [ $value ])) ? $list [ $value ] : (( in_array ( $value , $list )) ? $value : 'asc' ));
break ;
}
}
/**
* Convert a shorthand byte value from a PHP configuration directive to an integer value
* @ param string $value value to convert
* @ return int
*/
public static function convertBytes ( $value )
{
if ( is_numeric ( $value ))
return $value ;
else
{
$value_length = strlen ( $value );
$qty = ( int ) substr ( $value , 0 , $value_length - 1 );
$unit = Tools :: strtolower ( substr ( $value , $value_length - 1 ));
switch ( $unit )
{
case 'k' :
$qty *= 1024 ;
break ;
case 'm' :
$qty *= 1048576 ;
break ;
case 'g' :
$qty *= 1073741824 ;
break ;
}
return $qty ;
}
}
/**
* @ deprecated as of 1.5 use Controller :: getController ( 'PageNotFoundController' ) -> run ();
*/
public static function display404Error ()
{
header ( 'HTTP/1.1 404 Not Found' );
header ( 'Status: 404 Not Found' );
include ( dirname ( __FILE__ ) . '/../404.php' );
die ;
}
/**
* Concat $begin and $end , add ? or & between strings
*
* @ since 1.5 . 0
* @ param string $begin
* @ param string $end
* @ return string
*/
public static function url ( $begin , $end )
{
return $begin . (( strpos ( $begin , '?' ) !== false ) ? '&' : '?' ) . $end ;
}
/**
* Display error and dies or silently log the error .
*
* @ param string $msg
* @ param bool $die
* @ return bool success of logging
*/
public static function dieOrLog ( $msg , $die = true )
{
if ( $die || ( defined ( '_PS_MODE_DEV_' ) && _PS_MODE_DEV_ ))
die ( $msg );
return PrestaShopLogger :: addLog ( $msg );
}
/**
* Convert \n and \r\n and \r to < br />
*
* @ param string $string String to transform
* @ return string New string
*/
public static function nl2br ( $str )
{
return str_replace ( array ( " \r \n " , " \r " , " \n " ), '<br />' , $str );
}
/**
* Clear cache for Smarty
*
* @ param Smarty $smarty
*/
public static function clearCache ( $smarty = null , $tpl = false , $cache_id = null , $compile_id = null )
{
if ( $smarty === null )
$smarty = Context :: getContext () -> smarty ;
if ( $smarty === null )
return ;
if ( ! $tpl && $cache_id === null && $compile_id === null )
return $smarty -> clearAllCache ();
return $smarty -> clearCache ( $tpl , $cache_id , $compile_id );
}
/**
* Clear compile for Smarty
*/
public static function clearCompile ( $smarty = null )
{
if ( $smarty === null )
$smarty = Context :: getContext () -> smarty ;
if ( $smarty === null )
return ;
return $smarty -> clearCompiledTemplate ();
}
/**
* Clear Smarty cache and compile folders
*/
public static function clearSmartyCache ()
{
$smarty = Context :: getContext () -> smarty ;
Tools :: clearCache ( $smarty );
Tools :: clearCompile ( $smarty );
}
public static function clearColorListCache ( $id_product = false )
{
// Change template dir if called from the BackOffice
$current_template_dir = Context :: getContext () -> smarty -> getTemplateDir ();
Context :: getContext () -> smarty -> setTemplateDir ( _PS_THEME_DIR_ );
Tools :: clearCache ( null , 'product-list-colors.tpl' ,
( $id_product ? 'productlist_colors|' . ( int ) $id_product . '|' . ( int ) Context :: getContext () -> shop -> id : 'productlist_colors' ));
Context :: getContext () -> smarty -> setTemplateDir ( $current_template_dir );
}
/**
* getMemoryLimit allow to get the memory limit in octet
*
* @ since 1.4 . 5.0
* @ return int the memory limit value in octet
*/
public static function getMemoryLimit ()
{
$memory_limit = @ ini_get ( 'memory_limit' );
return Tools :: getOctets ( $memory_limit );
}
/**
* getOctet allow to gets the value of a configuration option in octet
*
* @ since 1.5 . 0
* @ return int the value of a configuration option in octet
*/
public static function getOctets ( $option )
{
if ( preg_match ( '/[0-9]+k/i' , $option ))
return 1024 * ( int ) $option ;
if ( preg_match ( '/[0-9]+m/i' , $option ))
return 1024 * 1024 * ( int ) $option ;
if ( preg_match ( '/[0-9]+g/i' , $option ))
return 1024 * 1024 * 1024 * ( int ) $option ;
return $option ;
}
/**
*
* @ return bool true if the server use 64 bit arch
*/
public static function isX86_64arch ()
{
return ( PHP_INT_MAX == '9223372036854775807' );
}
/**
*
* @ return bool true if php - cli is used
*/
public static function isPHPCLI ()
{
return ( defined ( 'STDIN' ) || ( Tools :: strtolower ( php_sapi_name ()) == 'cli' && ( ! isset ( $_SERVER [ 'REMOTE_ADDR' ]) || empty ( $_SERVER [ 'REMOTE_ADDR' ]))));
}
public static function argvToGET ( $argc , $argv )
{
if ( $argc <= 1 )
return ;
// get the first argument and parse it like a query string
parse_str ( $argv [ 1 ], $args );
if ( ! is_array ( $args ) || ! count ( $args ))
return ;
$_GET = array_merge ( $args , $_GET );
$_SERVER [ 'QUERY_STRING' ] = $argv [ 1 ];
}
/**
* Get max file upload size considering server settings and optional max value
*
* @ param int $max_size optional max file size
* @ return int max file size in bytes
*/
public static function getMaxUploadSize ( $max_size = 0 )
{
$post_max_size = Tools :: convertBytes ( ini_get ( 'post_max_size' ));
$upload_max_filesize = Tools :: convertBytes ( ini_get ( 'upload_max_filesize' ));
if ( $max_size > 0 )
$result = min ( $post_max_size , $upload_max_filesize , $max_size );
else
$result = min ( $post_max_size , $upload_max_filesize );
return $result ;
}
/**
* apacheModExists return true if the apache module $name is loaded
* @ TODO move this method in class Information ( when it will exist )
*
* Notes : This method requires either apache_get_modules or phpinfo ()
* to be available . With CGI mod , we cannot get php modules
*
* @ param string $name module name
* @ return bool true if exists
* @ since 1.4 . 5.0
*/
public static function apacheModExists ( $name )
{
if ( function_exists ( 'apache_get_modules' ))
{
static $apache_module_list = null ;
if ( ! is_array ( $apache_module_list ))
$apache_module_list = apache_get_modules ();
// we need strpos (example, evasive can be evasive20)
foreach ( $apache_module_list as $module )
{
if ( strpos ( $module , $name ) !== false )
return true ;
}
}
return false ;
}
/**
* Copy the folder $src into $dst , $dst is created if it do not exist
* @ param $src
* @ param $dst
* @ param bool $del if true , delete the file after copy
*/
public static function recurseCopy ( $src , $dst , $del = false )
{
if ( ! Tools :: file_exists_cache ( $src ))
return false ;
$dir = opendir ( $src );
if ( ! Tools :: file_exists_cache ( $dst ))
mkdir ( $dst );
while ( false !== ( $file = readdir ( $dir )))
{
if (( $file != '.' ) && ( $file != '..' ))
{
if ( is_dir ( $src . DIRECTORY_SEPARATOR . $file ))
self :: recurseCopy ( $src . DIRECTORY_SEPARATOR . $file , $dst . DIRECTORY_SEPARATOR . $file , $del );
else
{
copy ( $src . DIRECTORY_SEPARATOR . $file , $dst . DIRECTORY_SEPARATOR . $file );
if ( $del && is_writable ( $src . DIRECTORY_SEPARATOR . $file ))
unlink ( $src . DIRECTORY_SEPARATOR . $file );
}
}
}
closedir ( $dir );
if ( $del && is_writable ( $src ))
rmdir ( $src );
}
/**
* @ params string $path Path to scan
* @ params string $ext Extention to filter files
* @ params string $dir Add this to prefix output for example / path / dir /*
*
* @ return array List of file found
* @ since 1.5 . 0
*/
public static function scandir ( $path , $ext = 'php' , $dir = '' , $recursive = false )
{
$path = rtrim ( rtrim ( $path , '\\' ), '/' ) . '/' ;
$real_path = rtrim ( rtrim ( $path . $dir , '\\' ), '/' ) . '/' ;
$files = scandir ( $real_path );
if ( ! $files )
return array ();
$filtered_files = array ();
$real_ext = false ;
if ( ! empty ( $ext ))
$real_ext = '.' . $ext ;
$real_ext_length = strlen ( $real_ext );
$subdir = ( $dir ) ? $dir . '/' : '' ;
foreach ( $files as $file )
{
if ( ! $real_ext || ( strpos ( $file , $real_ext ) && strpos ( $file , $real_ext ) == ( strlen ( $file ) - $real_ext_length )))
$filtered_files [] = $subdir . $file ;
if ( $recursive && $file [ 0 ] != '.' && is_dir ( $real_path . $file ))
foreach ( Tools :: scandir ( $path , $ext , $subdir . $file , $recursive ) as $subfile )
$filtered_files [] = $subfile ;
}
return $filtered_files ;
}
/**
* Align version sent and use internal function
*
* @ param $v1
* @ param $v2
* @ param string $operator
* @ return mixed
*/
public static function version_compare ( $v1 , $v2 , $operator = '<' )
{
Tools :: alignVersionNumber ( $v1 , $v2 );
return version_compare ( $v1 , $v2 , $operator );
}
/**
* Align 2 version with the same number of sub version
* version_compare will work better for its comparison : )
* ( Means : '1.8' to '1.9.3' will change '1.8' to '1.8.0' )
*
* @ param $v1
* @ param $v2
*/
public static function alignVersionNumber ( & $v1 , & $v2 )
{
$len1 = count ( explode ( '.' , trim ( $v1 , '.' )));
$len2 = count ( explode ( '.' , trim ( $v2 , '.' )));
$len = 0 ;
$str = '' ;
if ( $len1 > $len2 )
{
$len = $len1 - $len2 ;
$str = & $v2 ;
}
elseif ( $len2 > $len1 )
{
$len = $len2 - $len1 ;
$str = & $v1 ;
}
for ( $len ; $len > 0 ; $len -- )
$str .= '.0' ;
}
public static function modRewriteActive ()
{
if ( Tools :: apacheModExists ( 'mod_rewrite' ))
return true ;
if (( isset ( $_SERVER [ 'HTTP_MOD_REWRITE' ]) && Tools :: strtolower ( $_SERVER [ 'HTTP_MOD_REWRITE' ]) == 'on' ) || Tools :: strtolower ( getenv ( 'HTTP_MOD_REWRITE' )) == 'on' )
return true ;
return false ;
}
public static function unSerialize ( $serialized , $object = false )
{
if ( is_string ( $serialized ) && ( strpos ( $serialized , 'O:' ) === false || ! preg_match ( '/(^|;|{|})O:[0-9]+:"/' , $serialized )) && ! $object || $object )
return @ unserialize ( $serialized );
return false ;
}
/**
* Reproduce array_unique working before php version 5.2 . 9
* @ param array $array
* @ return array
*/
public static function arrayUnique ( $array )
{
if ( version_compare ( phpversion (), '5.2.9' , '<' ))
return array_unique ( $array );
else
return array_unique ( $array , SORT_REGULAR );
}
/**
* Delete unicode class from regular expression patterns
* @ param string $pattern
* @ return string pattern
*/
public static function cleanNonUnicodeSupport ( $pattern )
{
if ( ! defined ( 'PREG_BAD_UTF8_OFFSET' ))
return $pattern ;
return preg_replace ( '/\\\[px]\{[a-z]{1,2}\}|(\/[a-z]*)u([a-z]*)$/i' , '$1$2' , $pattern );
}
protected static $is_addons_up = true ;
2015-08-12 14:10:25 +02:00
public static function addonsRequest
( $request , $params = array ())
2015-07-06 16:58:50 +02:00
{
if ( ! self :: $is_addons_up )
return false ;
$post_data = http_build_query ( array (
'version' => isset ( $params [ 'version' ]) ? $params [ 'version' ] : _PS_VERSION_ ,
'iso_lang' => Tools :: strtolower ( isset ( $params [ 'iso_lang' ]) ? $params [ 'iso_lang' ] : Context :: getContext () -> language -> iso_code ),
'iso_code' => Tools :: strtolower ( isset ( $params [ 'iso_country' ]) ? $params [ 'iso_country' ] : Country :: getIsoById ( Configuration :: get ( 'PS_COUNTRY_DEFAULT' ))),
'shop_url' => isset ( $params [ 'shop_url' ]) ? $params [ 'shop_url' ] : Tools :: getShopDomain (),
'mail' => isset ( $params [ 'email' ]) ? $params [ 'email' ] : Configuration :: get ( 'PS_SHOP_EMAIL' )
));
$protocols = array ( 'https' );
$end_point = 'api.addons.prestashop.com' ;
switch ( $request )
{
case 'native' :
$protocols [] = 'http' ;
$post_data .= '&method=listing&action=native' ;
break ;
case 'native_all' :
$protocols [] = 'http' ;
$post_data .= '&method=listing&action=native&iso_code=all' ;
break ;
case 'must-have' :
$protocols [] = 'http' ;
$post_data .= '&method=listing&action=must-have' ;
break ;
case 'must-have-themes' :
$protocols [] = 'http' ;
$post_data .= '&method=listing&action=must-have-themes' ;
break ;
case 'customer' :
$post_data .= '&method=listing&action=customer&username=' . urlencode ( trim ( Context :: getContext () -> cookie -> username_addons ))
. '&password=' . urlencode ( trim ( Context :: getContext () -> cookie -> password_addons ));
break ;
case 'customer_themes' :
$post_data .= '&method=listing&action=customer-themes&username=' . urlencode ( trim ( Context :: getContext () -> cookie -> username_addons ))
. '&password=' . urlencode ( trim ( Context :: getContext () -> cookie -> password_addons ));
break ;
case 'check_customer' :
$post_data .= '&method=check_customer&username=' . urlencode ( $params [ 'username_addons' ]) . '&password=' . urlencode ( $params [ 'password_addons' ]);
break ;
case 'check_module' :
$post_data .= '&method=check&module_name=' . urlencode ( $params [ 'module_name' ]) . '&module_key=' . urlencode ( $params [ 'module_key' ]);
break ;
case 'module' :
$post_data .= '&method=module&id_module=' . urlencode ( $params [ 'id_module' ]);
if ( isset ( $params [ 'username_addons' ]) && isset ( $params [ 'password_addons' ]))
$post_data .= '&username=' . urlencode ( $params [ 'username_addons' ]) . '&password=' . urlencode ( $params [ 'password_addons' ]);
else
$protocols [] = 'http' ;
break ;
case 'hosted_module' :
$post_data .= '&method=module&id_module=' . urlencode (( int ) $params [ 'id_module' ]) . '&username=' . urlencode ( $params [ 'hosted_email' ])
. '&password=' . urlencode ( $params [ 'password_addons' ])
. '&shop_url=' . urlencode ( isset ( $params [ 'shop_url' ]) ? $params [ 'shop_url' ] : Tools :: getShopDomain ())
. '&mail=' . urlencode ( isset ( $params [ 'email' ]) ? $params [ 'email' ] : Configuration :: get ( 'PS_SHOP_EMAIL' ));
$protocols [] = 'https' ;
break ;
case 'install-modules' :
$protocols [] = 'http' ;
$post_data .= '&method=listing&action=install-modules' ;
$post_data .= defined ( '_PS_HOST_MODE_' ) ? '-od' : '' ;
break ;
default :
return false ;
}
2015-08-12 14:10:25 +02:00
d ( $post_data );
2015-07-06 16:58:50 +02:00
$context = stream_context_create ( array (
'http' => array (
'method' => 'POST' ,
'content' => $post_data ,
'header' => 'Content-type: application/x-www-form-urlencoded' ,
'timeout' => 5 ,
)
));
foreach ( $protocols as $protocol )
if ( $content = Tools :: file_get_contents ( $protocol . '://' . $end_point , false , $context ))
return $content ;
self :: $is_addons_up = false ;
return false ;
}
/**
* Returns an array containing information about
* HTTP file upload variable ( $_FILES )
*
* @ param string $input File upload field name
* @ param bool $return_content If true , returns uploaded file contents
*
* @ return array | null
*/
public static function fileAttachment ( $input = 'fileUpload' , $return_content = true )
{
$file_attachment = null ;
if ( isset ( $_FILES [ $input ][ 'name' ]) && ! empty ( $_FILES [ $input ][ 'name' ]) && ! empty ( $_FILES [ $input ][ 'tmp_name' ]))
{
$file_attachment [ 'rename' ] = uniqid () . Tools :: strtolower ( substr ( $_FILES [ $input ][ 'name' ], - 5 ));
if ( $return_content )
$file_attachment [ 'content' ] = file_get_contents ( $_FILES [ $input ][ 'tmp_name' ]);
$file_attachment [ 'tmp_name' ] = $_FILES [ $input ][ 'tmp_name' ];
$file_attachment [ 'name' ] = $_FILES [ $input ][ 'name' ];
$file_attachment [ 'mime' ] = $_FILES [ $input ][ 'type' ];
$file_attachment [ 'error' ] = $_FILES [ $input ][ 'error' ];
$file_attachment [ 'size' ] = $_FILES [ $input ][ 'size' ];
}
return $file_attachment ;
}
public static function changeFileMTime ( $file_name )
{
@ touch ( $file_name );
}
public static function waitUntilFileIsModified ( $file_name , $timeout = 180 )
{
@ ini_set ( 'max_execution_time' , $timeout );
if (( $time_limit = ini_get ( 'max_execution_time' )) === null )
$time_limit = 30 ;
$time_limit -= 5 ;
$start_time = microtime ( true );
$last_modified = @ filemtime ( $file_name );
while ( true )
{
if ((( microtime ( true ) - $start_time ) > $time_limit ) || @ filemtime ( $file_name ) > $last_modified )
break ;
clearstatcache ();
usleep ( 300 );
}
}
/**
* Delete a substring from another one starting from the right
* @ param string $str
* @ param string $str_search
* @ return string
*/
public static function rtrimString ( $str , $str_search )
{
$length_str = strlen ( $str_search );
if ( strlen ( $str ) >= $length_str && substr ( $str , - $length_str ) == $str_search )
$str = substr ( $str , 0 , - $length_str );
return $str ;
}
/**
* Format a number into a human readable format
* e . g . 24962496 => 23.81 M
* @ param $size
* @ param int $precision
*
* @ return string
*/
public static function formatBytes ( $size , $precision = 2 )
{
if ( ! $size )
return '0' ;
$base = log ( $size ) / log ( 1024 );
$suffixes = array ( '' , 'k' , 'M' , 'G' , 'T' );
return round ( pow ( 1024 , $base - floor ( $base )), $precision ) . $suffixes [ floor ( $base )];
}
public static function boolVal ( $value )
{
if ( empty ( $value ))
$value = false ;
return ( bool ) $value ;
}
public static function getUserPlatform ()
{
if ( isset ( self :: $_user_plateform ))
return self :: $_user_plateform ;
$user_agent = $_SERVER [ 'HTTP_USER_AGENT' ];
self :: $_user_plateform = 'unknown' ;
if ( preg_match ( '/linux/i' , $user_agent ))
self :: $_user_plateform = 'Linux' ;
elseif ( preg_match ( '/macintosh|mac os x/i' , $user_agent ))
self :: $_user_plateform = 'Mac' ;
elseif ( preg_match ( '/windows|win32/i' , $user_agent ))
self :: $_user_plateform = 'Windows' ;
return self :: $_user_plateform ;
}
public static function getUserBrowser ()
{
if ( isset ( self :: $_user_browser ))
return self :: $_user_browser ;
$user_agent = $_SERVER [ 'HTTP_USER_AGENT' ];
self :: $_user_browser = 'unknown' ;
if ( preg_match ( '/MSIE/i' , $user_agent ) && ! preg_match ( '/Opera/i' , $user_agent ))
self :: $_user_browser = 'Internet Explorer' ;
elseif ( preg_match ( '/Firefox/i' , $user_agent ))
self :: $_user_browser = 'Mozilla Firefox' ;
elseif ( preg_match ( '/Chrome/i' , $user_agent ))
self :: $_user_browser = 'Google Chrome' ;
elseif ( preg_match ( '/Safari/i' , $user_agent ))
self :: $_user_browser = 'Apple Safari' ;
elseif ( preg_match ( '/Opera/i' , $user_agent ))
self :: $_user_browser = 'Opera' ;
elseif ( preg_match ( '/Netscape/i' , $user_agent ))
self :: $_user_browser = 'Netscape' ;
return self :: $_user_browser ;
}
/**
* Allows to display the category description without HTML tags and slashes
* @ return string
*/
public static function getDescriptionClean ( $description )
{
return strip_tags ( stripslashes ( $description ));
}
public static function purifyHTML ( $html , $uri_unescape = null , $allow_style = false )
{
require_once ( _PS_TOOL_DIR_ . 'htmlpurifier/HTMLPurifier.standalone.php' );
static $use_html_purifier = null ;
static $purifier = null ;
if ( defined ( 'PS_INSTALLATION_IN_PROGRESS' ) || ! Configuration :: configurationIsLoaded ())
return $html ;
if ( $use_html_purifier === null )
$use_html_purifier = ( bool ) Configuration :: get ( 'PS_USE_HTMLPURIFIER' );
if ( $use_html_purifier )
{
if ( $purifier === null )
{
$config = HTMLPurifier_Config :: createDefault ();
$config -> set ( 'Attr.EnableID' , true );
$config -> set ( 'HTML.Trusted' , true );
$config -> set ( 'Cache.SerializerPath' , _PS_CACHE_DIR_ . 'purifier' );
$config -> set ( 'Attr.AllowedFrameTargets' , array ( '_blank' , '_self' , '_parent' , '_top' ));
if ( is_array ( $uri_unescape ))
$config -> set ( 'URI.UnescapeCharacters' , implode ( '' , $uri_unescape ));
if ( Configuration :: get ( 'PS_ALLOW_HTML_IFRAME' ))
{
$config -> set ( 'HTML.SafeIframe' , true );
$config -> set ( 'HTML.SafeObject' , true );
$config -> set ( 'URI.SafeIframeRegexp' , '/.*/' );
}
/** @var HTMLPurifier_HTMLDefinition|HTMLPurifier_HTMLModule $def */
// http://developers.whatwg.org/the-video-element.html#the-video-element
if ( $def = $config -> getHTMLDefinition ( true ))
{
$def -> addElement ( 'video' , 'Block' , 'Optional: (source, Flow) | (Flow, source) | Flow' , 'Common' , array (
'src' => 'URI' ,
'type' => 'Text' ,
'width' => 'Length' ,
'height' => 'Length' ,
'poster' => 'URI' ,
'preload' => 'Enum#auto,metadata,none' ,
'controls' => 'Bool' ,
));
$def -> addElement ( 'source' , 'Block' , 'Flow' , 'Common' , array (
'src' => 'URI' ,
'type' => 'Text' ,
));
if ( $allow_style )
$def -> addElement ( 'style' , 'Block' , 'Flow' , 'Common' , array (
'type' => 'Text' ,
));
}
$purifier = new HTMLPurifier ( $config );
}
if ( _PS_MAGIC_QUOTES_GPC_ )
$html = stripslashes ( $html );
$html = $purifier -> purify ( $html );
if ( _PS_MAGIC_QUOTES_GPC_ )
$html = addslashes ( $html );
}
return $html ;
}
/**
* Check if a constant was already defined
* @ param string $constant Constant name
* @ param mixed $value Default value to set if not defined
*/
public static function safeDefine ( $constant , $value )
{
if ( ! defined ( $constant ))
define ( $constant , $value );
}
/**
* Spread an amount on lines , adjusting the $column field ,
* with the biggest adjustments going to the rows having the
* highest $sort_column .
*
* E . g .:
*
* $rows = [[ 'a' => 5.1 ], [ 'a' => 8.2 ]];
*
* spreadAmount ( 0.3 , 1 , $rows , 'a' );
*
* => $rows is [[ 'a' => 8.4 ], [ 'a' => 5.2 ]]
*
* @ param $amount float The amount to spread across the rows
* @ param $precision int Rounding precision
* e . g . if $amount is 1 , $precision is 0 and $rows = [[ 'a' => 2 ], [ 'a' => 1 ]]
* then the resulting $rows will be [[ 'a' => 3 ], [ 'a' => 1 ]]
* But if $precision were 1 , then the resulting $rows would be [[ 'a' => 2.5 ], [ 'a' => 1.5 ]]
* @ param & $rows array An array , associative or not , containing arrays that have at least $column and $sort_column fields
* @ param $column string The column on which to perform adjustments
*/
public static function spreadAmount ( $amount , $precision , & $rows , $column )
{
if ( ! is_array ( $rows ) || empty ( $rows ))
return ;
$sort_function = create_function ( '$a, $b' , " return \$ b[' $column '] > \$ a[' $column '] ? 1 : -1; " );
uasort ( $rows , $sort_function );
$unit = pow ( 10 , $precision );
$int_amount = ( int ) round ( $unit * $amount );
$remainder = $int_amount % count ( $rows );
$amount_to_spread = ( $int_amount - $remainder ) / count ( $rows ) / $unit ;
$sign = ( $amount >= 0 ? 1 : - 1 );
$position = 0 ;
foreach ( $rows as & $row )
{
$adjustment_factor = $amount_to_spread ;
if ( $position < abs ( $remainder ))
$adjustment_factor += $sign * 1 / $unit ;
$row [ $column ] += $adjustment_factor ;
++ $position ;
}
unset ( $row );
}
/**
* Replaces elements from passed arrays into the first array recursively
* @ param array $base The array in which elements are replaced .
* @ param array $replacements The array from which elements will be extracted .
*/
public static function arrayReplaceRecursive ( $base , $replacements )
{
if ( function_exists ( 'array_replace_recursive' ))
return array_replace_recursive ( $base , $replacements );
foreach ( array_slice ( func_get_args (), 1 ) as $replacements )
{
$bref_stack = array ( & $base );
$head_stack = array ( $replacements );
do
{
end ( $bref_stack );
$bref = & $bref_stack [ key ( $bref_stack )];
$head = array_pop ( $head_stack );
unset ( $bref_stack [ key ( $bref_stack )]);
foreach ( array_keys ( $head ) as $key )
if ( isset ( $key , $bref ) && is_array ( $bref [ $key ]) && is_array ( $head [ $key ]))
{
$bref_stack [] = & $bref [ $key ];
$head_stack [] = $head [ $key ];
}
else
$bref [ $key ] = $head [ $key ];
}
while ( count ( $head_stack ));
}
return $base ;
}
}
/**
* Compare 2 prices to sort products
*
* @ param float $a
* @ param float $b
* @ return int
*/
/* Externalized because of a bug in PHP 5.1.6 when inside an object */
function cmpPriceAsc ( $a , $b )
{
if (( float ) $a [ 'price_tmp' ] < ( float ) $b [ 'price_tmp' ])
return ( - 1 );
elseif (( float ) $a [ 'price_tmp' ] > ( float ) $b [ 'price_tmp' ])
return ( 1 );
return 0 ;
}
function cmpPriceDesc ( $a , $b )
{
if (( float ) $a [ 'price_tmp' ] < ( float ) $b [ 'price_tmp' ])
return 1 ;
elseif (( float ) $a [ 'price_tmp' ] > ( float ) $b [ 'price_tmp' ])
return - 1 ;
return 0 ;
}