bb-legacy/app/Tools.php line 1568

Open in your IDE?
  1.      */
  2.     public static function displayPrice($price$show_currency true$decimal 2$no_utf8 false)
  3.     {
  4.         if (!is_numeric($price)) {
  5.             return $price;
  6.         }
  7.         $c_char '';
  8.         $blank '';
  9.         if ($show_currency) {
  10.             $c_char '€';
  11.             $blank ' ';
  12.         }
  13.         $c_format Session::get('currency_format');
  14.         $c_decimals $decimal;
  15.         $ret 0;
  16.         if ($is_negative = ($price 0)) {
  17.             $price *= -1;
  18.         }
  19.         $price Tools::ps_round($price$c_decimals);
  20.         switch ($c_format) {
  21.             /* 0.000,00 X */
  22.             case 1:
  23.                 $ret number_format($price$c_decimals',''.').$blank.$c_char;
  24.                 break;
  25.                 /* X 0,000.00 X */
  26.             case 2:
  27.                 $ret $c_char.number_format($price$c_decimals'.'',');
  28.                 break;
  29.         }
  30.         if ($is_negative) {
  31.             $ret '-'.$ret;
  32.         }
  33.         if ($no_utf8) {
  34.             return str_replace('€'chr(128), $ret);
  35.         }
  36.         return $ret;
  37.     }
  38.     /**
  39.      * Return price with currency sign for a given product
  40.      *
  41.      * @deprecated use displayNumber from ToolsService instead
  42.      *
  43.      * @param float $price Product price
  44.      *
  45.      * @return string Price correctly formated (sign, decimal separator...)
  46.      */
  47.     public static function displayNumber($number$decimal 2)
  48.     {
  49.         if (!is_numeric($number)) {
  50.             return $number;
  51.         }
  52.         $c_format Session::get('currency_format');
  53.         $c_decimals $decimal;
  54.         $ret 0;
  55.         if ($is_negative = ($number 0)) {
  56.             $number *= -1;
  57.         }
  58.         $number Tools::ps_round($number$c_decimals);
  59.         switch ($c_format) {
  60.             /* 0.000,00 */
  61.             case 1:
  62.                 $ret number_format($number$c_decimals',''.');
  63.                 break;
  64.                 /* 0,000.00 */
  65.             case 2:
  66.                 $ret number_format($number$c_decimals'.'',');
  67.                 break;
  68.         }
  69.         if ($is_negative) {
  70.             $ret '-'.$ret;
  71.         }
  72.         return $ret;
  73.     }
  74.     public static function strtolower($str)
  75.     {
  76.         if (is_array($str)) {
  77.             return false;
  78.         }
  79.         if (function_exists('mb_strtolower')) {
  80.             return mb_strtolower($str'utf-8');
  81.         }
  82.         return strtolower($str);
  83.     }
  84.     public static function substr($str$start$length false$encoding 'utf-8')
  85.     {
  86.         if (is_array($str)) {
  87.             return false;
  88.         }
  89.         if (function_exists('mb_substr')) {
  90.             return mb_substr($str, (int)$start$length === false Tools::strlen($str) : (int)$length$encoding);
  91.         }
  92.         return substr($str$start$length === false Tools::strlen($str) : (int)$length);
  93.     }
  94.     /**
  95.      * Comprobamos un VAT Number
  96.      *
  97.      * @param string $vatid VAT Number a validar
  98.      * @param string $cc codigo ISO del pais
  99.      * @param int $idCustomer Identificador del usuario
  100.      *
  101.      * @return bool
  102.      * @deprecated use TaxService::isValidVies() instead
  103.      */
  104.     public static function checkVATNumber($vatid$cc$idCustomer)
  105.     {
  106.         if (!$vatid || !$cc) {
  107.             return false;
  108.         }
  109.         $taxService self::getSfService(TaxService::class);
  110.         return $taxService->isValidVies($idCustomer$vatid$cc);
  111.     }
  112.     /**
  113.      * returns the rounded value of $value to specified precision, according to your configuration;
  114.      *
  115.      * @note : PHP 5.3.0 introduce a 3rd parameter mode in round function
  116.      *
  117.      * @param float $value
  118.      * @param int $precision
  119.      *
  120.      * @return float
  121.      *
  122.      * @deprecated use round() instead
  123.      */
  124.     public static function ps_round($value$precision 0)
  125.     {
  126.         return round($value$precision);
  127.     }
  128.     public static function getRealIP()
  129.     {
  130.         if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
  131.             return $_SERVER['HTTP_CLIENT_IP'];
  132.         }
  133.         // TODO quitar este if y descomentar las líneas
  134.         if (!empty($_SERVER['REMOTE_ADDR'])) {
  135.             return $_SERVER['REMOTE_ADDR'];
  136.         }
  137.         return $_SERVER['HTTP_X_FORWARDED_FOR'];
  138.     }
  139.     public static function getCoordsIP()
  140.     {
  141.         // Obtenemos localización del usuario por su ip
  142.         $ip Tools::getRealIP();
  143.         // $ip = '88.0.57.88';
  144.         $url 'http://www.geoplugin.net/php.gp?ip='.$ip// echo $url;
  145.         $datos = @unserialize(file_get_contents($url));
  146.         $resp = [];
  147.         if ($datos) {
  148.             // $iso_code = $datos['geoplugin_countryCode'];
  149.             // $city = $datos['geoplugin_city'];
  150.             $resp['latitud'] = (isset($datos['geoplugin_latitude'])) ? $datos['geoplugin_latitude'] : '';
  151.             $resp['longitud'] = (isset($datos['geoplugin_longitude'])) ? $datos['geoplugin_longitude'] : '';
  152.             $resp['country_code'] = (isset($datos['geoplugin_countryCode'])) ? $datos['geoplugin_countryCode'] : '';
  153.             $resp['geoplugin_request'] = (isset($datos['geoplugin_request'])) ? $datos['geoplugin_request'] : '';
  154.         } else {
  155.             $resp['latitud'] = '';
  156.             $resp['longitud'] = '';
  157.             $resp['country_code'] = '';
  158.             $resp['geoplugin_request'] = '';
  159.         }
  160.         return $resp;
  161.     }
  162.     /**
  163.      * Modifies a string to remove all non ASCII characters and spaces.
  164.      */
  165.     public static function slugify($text)
  166.     {
  167.         // replace non letter or digits by -
  168.         $text preg_replace('~[^\\pL\d]+~u''-'$text);
  169.         // trim
  170.         $text trim($text'-');
  171.         // transliterate
  172.         if (function_exists('iconv')) {
  173.             $text iconv('utf-8''us-ascii//TRANSLIT'$text);
  174.         }
  175.         // lowercase
  176.         $text strtolower($text);
  177.         // remove unwanted characters
  178.         $text preg_replace('~[^-\w]+~'''$text);
  179.         if (empty($text)) {
  180.             return 'n-a';
  181.         }
  182.         return $text;
  183.     }
  184.     /**
  185.      * @deprecated use guzzle instead
  186.      */
  187.     public static function httpPost($url$params$return_http_code false$follow false$sslVerification true)
  188.     {
  189.         $postData '';
  190.         if (!empty($params)) {
  191.             $postData http_build_query($params);
  192.         }
  193.         $ch curl_init();
  194.         curl_setopt($chCURLOPT_URL$url);
  195.         curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  196.         curl_setopt($chCURLOPT_HEADERfalse);
  197.         // NO VERIFICAR SSL SI ESTAMOS EN MODO DESARROLLO
  198.         if (Tools::getSfService(\App\Service\EnvironmentService::class)->isDev() || !$sslVerification) {
  199.             curl_setopt($chCURLOPT_SSL_VERIFYHOSTfalse);
  200.             curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
  201.         }
  202.         if (!empty($params)) {
  203.             curl_setopt($chCURLOPT_POSTis_array($postData) && count($postData) ? true false);
  204.             curl_setopt($chCURLOPT_POSTFIELDS$postData);
  205.         }
  206.         if ($follow) {
  207.             curl_setopt($chCURLOPT_FOLLOWLOCATIONtrue);
  208.         }
  209.         //        DESCOMENTAR PARA DEPURAR LLAMADAS CURL DESDE NETBEANS
  210.         //        curl_setopt($ch, CURLOPT_COOKIE,"XDEBUG_SESSION=netbeans-xdebug");
  211.         $output curl_exec($ch);
  212.         if ($output == false) {
  213.             $output curl_error($ch);
  214.         }
  215.         // DEVOLVEMOS EL CODIGO HTTP (404, 500, 200...)
  216.         if ($return_http_code) {
  217.             $output curl_getinfo($chCURLINFO_HTTP_CODE);
  218.         }
  219.         curl_close($ch);
  220.         return $output;
  221.     }
  222.     /**
  223.      * Truncate strings
  224.      *
  225.      * @param string $str
  226.      * @param int $max_length Max length
  227.      * @param string $suffix Suffix optional
  228.      *
  229.      * @return string $str truncated
  230.      */
  231.     /* CAUTION : Use it only on module hookEvents.
  232.      * * For other purposes use the smarty function instead */
  233.     public static function truncate($str$max_length$suffix '...')
  234.     {
  235.         if (Tools::strlen($str) <= $max_length) {
  236.             return $str;
  237.         }
  238.         $str utf8_decode($str);
  239.         return utf8_encode(substr($str0$max_length Tools::strlen($suffix)).$suffix);
  240.     }
  241.     public static function isMobile()
  242.     {// return true;
  243.         if (defined('IS_MOBILE')) {
  244.             return IS_MOBILE;
  245.         }
  246.         return false;
  247.     }
  248.     public static function getPassword()
  249.     {
  250.         // Se define una cadena de caractares. Te recomiendo que uses esta.
  251.         $cadena 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890';
  252.         // Obtenemos la longitud de la cadena de caracteres
  253.         $longitudCadena strlen($cadena);
  254.         // Se define la variable que va a contener la contraseña
  255.         $pass '';
  256.         // Se define la longitud de la contraseña, en mi caso 10, pero puedes poner la longitud que quieras
  257.         $longitudPass 10;
  258.         // Creamos la contraseña
  259.         for ($i 1$i <= $longitudPass$i++) {
  260.             // Definimos numero aleatorio entre 0 y la longitud de la cadena de caracteres-1
  261.             $pos rand(0$longitudCadena 1);
  262.             // Vamos formando la contraseña en cada iteraccion del bucle, añadiendo a la cadena $pass la letra correspondiente a la posicion $pos en la cadena de caracteres definida.
  263.             $pass .= substr($cadena$pos1);
  264.         }
  265.         return $pass;
  266.     }
  267.     public static function generarCodigo($longitud)
  268.     {
  269.         $key '';
  270.         $pattern '1234567890abcdefghijklmnopqrstuvwxyz';
  271.         $max strlen($pattern) - 1;
  272.         for ($i 0$i $longitud$i++) {
  273.             $key .= $pattern[mt_rand(0$max)];
  274.         }
  275.         return $key;
  276.     }
  277.     public static function calculateDaysTransit($days$productId null$extern false)
  278.     {
  279.         $syncronisedException = ($extern) ? Product::isSincronisedSendException($productId) : false;
  280.         if ($days <= 2) {
  281.             return [
  282.                 'days' => 1,
  283.                 'text_product' => self::l('%s uds.''Tools'),
  284.                 'text_cart' => (!$syncronisedException) ? self::l('Envío inmediato''Tools') : self::l('24/48h''Tools'),
  285.             ];
  286.         }
  287.         $tmpDays = (int)ceil($days 5);
  288.         switch ($tmpDays) {
  289.             case 0:
  290.             case 1:
  291.                 $days_range '2/5';
  292.                 $tmpDays 1;
  293.                 break;
  294.             case 2:
  295.                 $days_range '5/10';
  296.                 break;
  297.             case 3:
  298.                 $days_range '10/15';
  299.                 break;
  300.             case 4:
  301.                 $days_range '15/20';
  302.                 break;
  303.             default:
  304.                 $days_range '20/30';
  305.         }
  306.         return [
  307.             'days' => $tmpDays 5,
  308.             'text_product' => sprintf(self::l('%s uds. envío %s días''Tools'), '%s'$days_range),
  309.             'text_cart' => sprintf(self::l('%s días''Tools'), $days_range),
  310.         ];
  311.     }
  312.     public static function divideString($name$separador '<br />'$num_lines 2)
  313.     {
  314.         $blank_spaces ceil(substr_count($name' ') / $num_lines);
  315.         $nameEnd '';
  316.         $count_spaces 0;
  317.         $nameTmp str_split($name);
  318.         $br false;
  319.         foreach ($nameTmp as $c) {
  320.             if ($c == ' ') {
  321.                 $count_spaces++;
  322.             }
  323.             if ($count_spaces == $blank_spaces && $blank_spaces && !$br) {
  324.                 $nameEnd .= $separador;
  325.                 $br true;
  326.             } else {
  327.                 $nameEnd .= $c;
  328.             }
  329.         }
  330.         return $nameEnd;
  331.     }
  332.     public static function convertTable($txt$titulo '')
  333.     {
  334.         $_convertTable = [
  335.         '&amp;' => 'and''@' => 'at''©' => 'c''®' => 'r''À' => 'a''Á' => 'a''Â' => 'a''Ä' => 'a''Å' => 'a''Æ' => 'ae''Ç' => 'c''È' => 'e''É' => 'e''Ë' => 'e''Ì' => 'i''Í' => 'i''Î' => 'i''Ï' => 'i''Ò' => 'o''Ó' => 'o''Ô' => 'o''Õ' => 'o''Ö' => 'o''Ø' => 'o''Ù' => 'u''Ú' => 'u''Û' => 'u''Ü' => 'u''Ý' => 'y''ß' => 'ss''à' => 'a''á' => 'a''â' => 'a''ä' => 'a''å' => 'a''æ' => 'ae''ç' => 'c''è' => 'e''é' => 'e''ê' => 'e''ë' => 'e''ì' => 'i''í' => 'i''î' => 'i''ï' => 'i''ò' => 'o''ó' => 'o''ô' => 'o''õ' => 'o''ö' => 'o''ø' => 'o''ù' => 'u''ú' => 'u''û' => 'u''ü' => 'u''ý' => 'y''þ' => 'p''ÿ' => 'y''Ā' => 'a''ā' => 'a''Ă' => 'a''ă' => 'a''Ą' => 'a''ą' => 'a''Ć' => 'c''ć' => 'c''Ĉ' => 'c''ĉ' => 'c''Ċ' => 'c''ċ' => 'c''Č' => 'c''č' => 'c''Ď' => 'd''ď' => 'd''Đ' => 'd''đ' => 'd''Ē' => 'e''ē' => 'e''Ĕ' => 'e''ĕ' => 'e''Ė' => 'e''ė' => 'e''Ę' => 'e''ę' => 'e''Ě' => 'e''ě' => 'e''Ĝ' => 'g''ĝ' => 'g''Ğ' => 'g''ğ' => 'g''Ġ' => 'g''ġ' => 'g''Ģ' => 'g''ģ' => 'g''Ĥ' => 'h''ĥ' => 'h''Ħ' => 'h''ħ' => 'h''Ĩ' => 'i''ĩ' => 'i''Ī' => 'i''ī' => 'i''Ĭ' => 'i''ĭ' => 'i''Į' => 'i''į' => 'i''İ' => 'i''ı' => 'i''IJ' => 'ij''ij' => 'ij''Ĵ' => 'j''ĵ' => 'j''Ķ' => 'k''ķ' => 'k''ĸ' => 'k''Ĺ' => 'l''ĺ' => 'l''Ļ' => 'l''ļ' => 'l''Ľ' => 'l''ľ' => 'l''Ŀ' => 'l''ŀ' => 'l''Ł' => 'l''ł' => 'l''Ń' => 'n''ń' => 'n''Ņ' => 'n''ņ' => 'n''Ň' => 'n''ň' => 'n''ʼn' => 'n''Ŋ' => 'n''ŋ' => 'n''Ō' => 'o''ō' => 'o''Ŏ' => 'o''ŏ' => 'o''Ő' => 'o''ő' => 'o''Œ' => 'oe''œ' => 'oe''Ŕ' => 'r''ŕ' => 'r''Ŗ' => 'r''ŗ' => 'r''Ř' => 'r''ř' => 'r''Ś' => 's''ś' => 's''Ŝ' => 's''ŝ' => 's''Ş' => 's''ş' => 's''Š' => 's''š' => 's''Ţ' => 't''ţ' => 't''Ť' => 't''ť' => 't''Ŧ' => 't''ŧ' => 't''Ũ' => 'u''ũ' => 'u''Ū' => 'u''ū' => 'u''Ŭ' => 'u''ŭ' => 'u''Ů' => 'u''ů' => 'u''Ű' => 'u''ű' => 'u''Ų' => 'u''ų' => 'u''Ŵ' => 'w''ŵ' => 'w''Ŷ' => 'y''ŷ' => 'y''Ÿ' => 'y''Ź' => 'z''ź' => 'z''Ż' => 'z''ż' => 'z''Ž' => 'z''ž' => 'z''ſ' => 'z''Ə' => 'e''ƒ' => 'f''Ơ' => 'o''ơ' => 'o''Ư' => 'u''ư' => 'u''Ǎ' => 'a''ǎ' => 'a''Ǐ' => 'i''ǐ' => 'i''Ǒ' => 'o''ǒ' => 'o''Ǔ' => 'u''ǔ' => 'u''Ǖ' => 'u''ǖ' => 'u''Ǘ' => 'u''ǘ' => 'u''Ǚ' => 'u''ǚ' => 'u''Ǜ' => 'u''ǜ' => 'u''Ǻ' => 'a''ǻ' => 'a''Ǽ' => 'ae''ǽ' => 'ae''Ǿ' => 'o''ǿ' => 'o''ə' => 'e''Ё' => 'jo''Є' => 'e''І' => 'i''Ї' => 'i''А' => 'a''Б' => 'b''В' => 'v''Г' => 'g''Д' => 'd''Е' => 'e''Ж' => 'zh''З' => 'z''И' => 'i''Й' => 'j''К' => 'k''Л' => 'l''М' => 'm''Н' => 'n''О' => 'o''П' => 'p''Р' => 'r''С' => 's''Т' => 't''У' => 'u''Ф' => 'f''Х' => 'h''Ц' => 'c''Ч' => 'ch''Ш' => 'sh''Щ' => 'sch''Ъ' => '-''Ы' => 'y''Ь' => '-''Э' => 'je''Ю' => 'ju''Я' => 'ja''а' => 'a''б' => 'b''в' => 'v''г' => 'g''д' => 'd''е' => 'e''ж' => 'zh''з' => 'z''и' => 'i''й' => 'j''к' => 'k''л' => 'l''м' => 'm''н' => 'n''о' => 'o''п' => 'p''р' => 'r''с' => 's''т' => 't''у' => 'u''ф' => 'f''х' => 'h''ц' => 'c''ч' => 'ch''ш' => 'sh''щ' => 'sch''ъ' => '-''ы' => 'y''ь' => '-''э' => 'je''ю' => 'ju''я' => 'ja''ё' => 'jo''є' => 'e''і' => 'i''ї' => 'i''Ґ' => 'g''ґ' => 'g''א' => 'a''ב' => 'b''ג' => 'g''ד' => 'd''ה' => 'h''ו' => 'v''ז' => 'z''ח' => 'h''ט' => 't''י' => 'i''ך' => 'k''כ' => 'k''ל' => 'l''ם' => 'm''מ' => 'm''ן' => 'n''נ' => 'n''ס' => 's''ע' => 'e''ף' => 'p''פ' => 'p''ץ' => 'C''צ' => 'c''ק' => 'q''ר' => 'r''ש' => 'w''ת' => 't''™' => 'tm''Α' => 'a''α' => 'a''Β' => 'v''β' => 'v''Γ' => 'g''γ' => 'g''Δ' => 'd''δ' => 'd''Ε' => 'e''ε' => 'e''Ζ' => 'z''ζ' => 'z''Η' => 'i''η' => 'i''Θ' => 'th''θ' => 'th''Ι' => 'i''ι' => 'i''Κ'    => 'k''κ'    => 'k''Λ'    => 'l''λ'    => 'l''Μ'    => 'm',    'μ'    => 'm''Ν'    => 'n',    'ν'    => 'n''Ξ'    => 'ks''ξ' => 'ks''Ο' => 'o''ο' => 'o''Π' => 'p''π' => 'p''Ρ' => 'r''ρ' => 'r''Σ' => 's''σ' => 's''ς' => 's''Τ' => 't''τ' => 't''Υ' => 'u''υ' => 'u''Φ' => 'ph''φ' => 'ph''Χ' => 'x''χ' => 'x''Ψ' => 'ps''ψ'    => 'ps''Ω' => 'o''ω' => 'o',    'Ά' => 'a''ά' => 'a''Έ' => 'e''έ' => 'e''Ή' => 'i''ή' => 'i''Ί' => 'i''ί' => 'i''Ό' => 'o''ό' => 'o''Ώ' => 'o''ώ' => 'o''Ύ' => 'u''ύ' => 'u', ];
  336.         if ($txt == '') {
  337.             $txt $titulo;
  338.         }
  339.         $temp =  strtr($txt$_convertTable);
  340.         $urlKey preg_replace('#[^0-9a-z]+#i''-'$temp);
  341.         $urlKey strtolower($urlKey);
  342.         $urlKey trim($urlKey'-');
  343.         return $urlKey;
  344.     }
  345.     public static function convertDateToEpoch($date)
  346.     {
  347.         $tmp explode(' '$date);
  348.         $dateArray explode('-'$tmp[0]);
  349.         $hourArray explode(':'$tmp[1]);
  350.         if (empty($dateArray[1]) || empty($hourArray[2]) || empty($hourArray[1]) || empty($hourArray[2])) {
  351.             return 0;
  352.         }
  353.         $epoch mktime($hourArray[0], $hourArray[1], $hourArray[2], $dateArray[1], $dateArray[2], $dateArray[0]);
  354.         return $epoch;
  355.     }
  356.     /**
  357.      * Añadimos la cookie de la secure Key del carriro
  358.      */
  359.     public static function processCookieSecureKey()
  360.     {
  361.         if (empty($_COOKIE['secure_key'])) {
  362.             $secureKey uniqid(rand(09).rand(09).rand(09), true);
  363.             setcookie('secure_key'$secureKeytime() + (60 60 24 7), '/');
  364.             Session::set('secure_key'$secureKey);
  365.         }
  366.     }
  367.     /**
  368.      * @param $timestamp
  369.      * @param $supplierId
  370.      *
  371.      * @return int
  372.      */
  373.     public static function getClosestNonHolidayTimestampInFuture($timestamp$supplierId$additionalDaysToSkip 0): int
  374.     {
  375.         $dateTimeHelper = new DatetimeHelper();
  376.         $dateTime $dateTimeHelper->getDatetimeFromTimestamp($timestamp);
  377.         $weekendDays = [DatetimeHelper::SATURDAYDatetimeHelper::SUNDAY];
  378.         $dateHolidays Tools::jsonDecode(Configuration::get('HOLIDAYS'true), true);
  379.         if ($supplierId) {
  380.             /** @var SupplierHolidaysManager $supplierHolidayManager */
  381.             $supplierHolidayManager Tools::getSfService(SupplierHolidaysManager::class);
  382.             $supplierHoliday $supplierHolidayManager->findOneById((int)$supplierId);
  383.             $dateSupplierHolidays = ($supplierHoliday) ? json_decode($supplierHoliday->getHolidays(), true) : [];
  384.         }
  385.         while (true) {
  386.             $isHoliday = isset($dateHolidays[$dateTime->format('Y-m-d')]);
  387.             $isWeekend in_array($dateTime->format('w'), $weekendDays);
  388.             if ($supplierId) {
  389.                 $isHolidaySuplier in_array($dateTime->format('Y-m-d'), $dateSupplierHolidays);
  390.                 if (!$isHoliday && !$isWeekend && !$isHolidaySuplier) {
  391.                     if ($additionalDaysToSkip === 0) {
  392.                         return $dateTime->getTimestamp();
  393.                     } else {
  394.                         $additionalDaysToSkip--;
  395.                     }
  396.                 }
  397.             } else {
  398.                 if (!$isHoliday && !$isWeekend) {
  399.                     if ($additionalDaysToSkip === 0) {
  400.                         return $dateTime->getTimestamp();
  401.                     } else {
  402.                         $additionalDaysToSkip--;
  403.                     }
  404.                 }
  405.             }
  406.             $dateTime->modify('+1 day');
  407.         }
  408.     }
  409.     /**
  410.      * @return int
  411.      *
  412.      * @throws Exception
  413.      *
  414.      * @var
  415.      */
  416.     public static function getExpeditionTimestampByDefault(?int $customerId$supplierId): int
  417.     {
  418.         return self::calculateExpeditionTimestamp($customerIdShippingDateService::DEFAULT_EXPEDITION_MESSAGE_TIME$supplierId00false);
  419.     }
  420.     /**
  421.      * @param int $idSupplier
  422.      * @param int|null $timestampToCompare
  423.      *
  424.      * @return int
  425.      *
  426.      * @throws Exception
  427.      */
  428.     public static function getExpeditionTimestampBySupplier(?int $customerIdint $idSupplier, ?int $timestampToComparebool $stock_3_5): int
  429.     {
  430.         $supplierExpeditionConfig plazo_aprovisionamiento_proveedor::getExpeditionInformation($idSupplier);
  431.         $cutTimeString $supplierExpeditionConfig['expedition_message_time'];
  432.         $expeditionAdditionalDaysDelay = (int)$supplierExpeditionConfig['expedition_days'];
  433.         if ($stock_3_5) {
  434.             $expeditionAdditionalDaysDelay = (int)$supplierExpeditionConfig['expedition_days_3_5'];
  435.         }
  436.         return self::calculateExpeditionTimestamp($customerId$cutTimeString$idSupplier$expeditionAdditionalDaysDelay$timestampToComparetrue);
  437.     }
  438.     /**
  439.      * @param array $product
  440.      *
  441.      * @return int
  442.      *
  443.      * @throws Exception
  444.      */
  445.     public static function getExpeditionTimestampForFutureStock(array $product): int
  446.     {
  447.         $daysUntilStockWillBeHere = \stock_venideros::calculateDaysTransit($product['id_product'], $product['id_product_attribute']);
  448.         if (!$daysUntilStockWillBeHere) {
  449.             $daysUntilStockWillBeHere = (int)self::jsonDecode(Configuration::get('STOCK_VENIDERO_DIAS_CORTESIA'), true);
  450.         }
  451.         $transitDaysData self::calculateDaysTransit($daysUntilStockWillBeHere$product['id_product']);
  452.         $datetimeHelper = new DatetimeHelper();
  453.         $tmpExpeditionTimestamp $datetimeHelper->getCurrentTimestamp();
  454.         // Add
  455.         $tmpExpeditionTimestamp += $transitDaysData['days'] * DatetimeHelper::SECONDS_A_DAY;
  456.         return self::getClosestNonHolidayTimestampInFuture($tmpExpeditionTimestampnull);
  457.     }
  458.     /**
  459.      * @param string $cutTimeString
  460.      * @param int $supplierId
  461.      * @param int $supplierAdditionalDaysDelay
  462.      * @param int|null $timestampToCompare
  463.      *
  464.      * @return int
  465.      *
  466.      * @throws Exception Calculates expedition timestamp taking into account:
  467.      *                   1. Customer specific delays (Ex: Workhuman 3 hour delay)
  468.      *                   2. Whether cut time has passed or not
  469.      *                   3. Supplier specific delays
  470.      *                   4. Skip holidays and weekends
  471.      *
  472.      * Accepts a $timestampToCompare argument that will be returned if its greater than the value calculated by the function
  473.      */
  474.     private static function calculateExpeditionTimestamp(
  475.         ?int $customerId,
  476.         string $cutTimeString,
  477.         int $supplierId,
  478.         int $supplierAdditionalDaysDelay,
  479.         ?int $timestampToCompare,
  480.         bool $includeSupplierHolidays
  481.     ): int {
  482.         $datetimeHelper = new DatetimeHelper();
  483.         $currentTimestamp $datetimeHelper->getCurrentTimestamp();
  484.         // Init to current timestamp
  485.         $tmpExpeditionTimestamp $currentTimestamp;
  486.         // Apply customer-defined delay
  487.         if (!empty($customerId)) {
  488.             $tmpExpeditionTimestamp self::addCustomerSpecificDelay($tmpExpeditionTimestamp$customerId);
  489.         }
  490.         // If the temporary expedition timestamp exceeds the cut time, add a day
  491.         if (self::timestampExceedsCutTime($tmpExpeditionTimestamp$cutTimeString)) {
  492.             $tmpExpeditionTimestamp $tmpExpeditionTimestamp DatetimeHelper::SECONDS_A_DAY;
  493.         }
  494.         // if $tmpExpeditionTimestamp is not a working day, get closest one
  495.         $closestNonHolidayTimestampInFuture Tools::getClosestNonHolidayTimestampInFuture($tmpExpeditionTimestamp$includeSupplierHolidays $supplierId null0);
  496.         // Add as many more days as 'expedition_days' value and get closest working day again
  497.         if ($supplierAdditionalDaysDelay 0) {
  498.             $closestNonHolidayTimestampInFuture Tools::getClosestNonHolidayTimestampInFuture($tmpExpeditionTimestamp$includeSupplierHolidays $supplierId null$supplierAdditionalDaysDelay);
  499.         }
  500.         if ($timestampToCompare $closestNonHolidayTimestampInFuture) {
  501.             return $timestampToCompare;
  502.         }
  503.         return $closestNonHolidayTimestampInFuture;
  504.     }
  505.     public static function replaceByAbsoluteURL($matches)
  506.     {
  507.         if (array_key_exists(1$matches) && array_key_exists(2$matches)) {
  508.             if (!preg_match('/^(?:https?:)?\/\//iUs'$matches[2])) {
  509.                 return $matches[1].BASE_URL.'public/css/'.$matches[2];
  510.             }
  511.             return $matches[0];
  512.         }
  513.         return false;
  514.     }
  515.     /**
  516.      * @param int $tmpExpeditionTimestamp
  517.      * @param string $cutTimeString
  518.      *
  519.      * @return bool
  520.      */
  521.     private static function timestampExceedsCutTime(int $tmpExpeditionTimestampstring $cutTimeString): bool
  522.     {
  523.         $datetimeHelper = new DatetimeHelper();
  524.         $tmpDatetime $datetimeHelper->getDatetimeFromTimestamp($tmpExpeditionTimestamp);
  525.         $cutTimeComponents explode(':'$cutTimeString);
  526.         $cutTimeHours = (int)trim($cutTimeComponents[0]);
  527.         $cutTimeMinutes = (int)trim($cutTimeComponents[1]);
  528.         $cutTimeSeconds = (int)trim($cutTimeComponents[2]);
  529.         $cutDatetime $datetimeHelper->getCurrentDateTime()->setTime($cutTimeHours$cutTimeMinutes$cutTimeSeconds);
  530.         return $tmpDatetime $cutDatetime;
  531.     }
  532.     /**
  533.      * Retornamos un array con la lista de todos los productos tienda disponibles
  534.      *
  535.      * @return array Listado de productos tienda
  536.      */
  537.     public static function getProductShopListArray()
  538.     {
  539.         $prestashopList explode(','Configuration::get('ID_SHOPS'));
  540.         return array_merge(\App\Entity\System\Product::SHOPIFY_PRODUCTS_IDS$prestashopList);
  541.     }
  542.     public static function getPackName($packName$subscriptionName '')
  543.     {
  544.         if ($packName == $subscriptionName) {
  545.             return $subscriptionName;
  546.         }
  547.         return $packName.' '.$subscriptionName;
  548.     }
  549.     public static function getGenericServerError($errorCode)
  550.     {
  551.         return sprintf(
  552.             self::l('Ha habido una incidencia y no ha podido completarse su pedido. Vaya a la sección %sContacto > Soporte técnico%s, seleccione Web BigBuy e indíquenos el código de la incidencia %s para poder ayudarle.''subscriptionController'),
  553.             '<a href="'.Link::getFrontLink('contact#tabpanel3').'" class="link color-blue">',
  554.             '</a>',
  555.             $errorCode
  556.         );
  557.     }
  558.     /**
  559.      * Clean Url of <script> tags
  560.      * This method use HTMLPurifier lib from composer
  561.      *
  562.      * @param string $url
  563.      */
  564.     public static function htmlPurifier($url): string
  565.     {
  566.         $config HTMLPurifier_Config::createDefault();
  567.         $config->set('Cache.DefinitionImpl'null);
  568.         $purifier = new HTMLPurifier($config);
  569.         $newParam $purifier->purify($url); // this convert
  570.         $searchParams = ['&lt;script&gt;''&lt;/script&gt;'];
  571.         $replaceParams '';
  572.         $newParam str_ireplace($searchParams$replaceParams$newParam);
  573.         $newParam trim($newParam);
  574.         return $newParam;
  575.     }
  576.     public static function getResultsElasticSearch($lang$init$limit$ajax$filters$isWholeSaler$searchText null)
  577.     {
  578.         $customerId Session::get('id_customer');
  579.         $filters['catalogs'] = Session::get(SessionService::ALLOWED_CATALOGS_KEY);
  580.         if (empty($customerId)) {
  581.             $customerId null;
  582.         }
  583.         if (isset($filters['rangeStock']) && is_array($filters['rangeStock'])) {
  584.             $minStock $filters['rangeStock'][0] ?? 0;
  585.             if (!\is_numeric($minStock)) {
  586.                 $minStock 0;
  587.             }
  588.             $maxStock $filters['rangeStock'][1] ?? $minStock 1000;
  589.             if (!\is_numeric($maxStock)) {
  590.                 $maxStock $minStock 1000;
  591.             }
  592.             $filters['minStock'] = $minStock;
  593.             $filters['maxStock'] = $maxStock;
  594.         }
  595.         if (isset($filters['category']) && is_array($filters['category'])) {
  596.             $filters['taxonomy'] = [];
  597.             foreach ($filters['category'] as $categoryId) {
  598.                 $filters['taxonomy'][] = $categoryId;
  599.             }
  600.             unset($filters['category']);
  601.         }
  602.         // TODO comprobar si esta definida la sesion
  603.         if (empty(Session::get('list_products_rand_seed'))) {
  604.             $randSeed rand(1MAX_RANDOM_SEED);
  605.             Session::set('list_products_rand_seed'$randSeed);
  606.         }
  607.         $randOrderingSeed null;
  608.         if (isset($filters['order'])) {
  609.             if ((\is_array($filters['order']) && (int)$filters['order'][0] === 6)
  610.                 || (int)$filters['order'] === 6) {
  611.                 if (!isset($filters['randOrderingSeed'])) {
  612.                     // If user selected "Selección BigBuy" we use a fixed seed so pagination won't repeat results
  613.                     $randOrderingSeed Session::get('list_products_rand_seed');
  614.                 } else {
  615.                     // True randomness
  616.                     $randOrderingSeed $filters['randOrderingSeed'];
  617.                 }
  618.             }
  619.         }
  620.         $factory self::getSfService(\App\Factory\Search\FindProductsRequestFactory::class);
  621.         $findProductsRequest $factory->buildFromWebProductListsCriteria(
  622.             $customerId,
  623.             $lang,
  624.             $init,
  625.             $limit,
  626.             $ajax,
  627.             $filters,
  628.             (bool)$isWholeSaler,
  629.             self::getRealIP(),
  630.             $searchText,
  631.             $randOrderingSeed
  632.         );
  633.         $productRepositoryAdapter self::getSfService(ProductRepositoryAdapter::class);
  634.         return  $productRepositoryAdapter->search($findProductsRequest);
  635.     }
  636.     /**
  637.      * @template T
  638.      *
  639.      * @param class-string<T> $serviceFqn
  640.      *
  641.      * @return T
  642.      */
  643.     public static function getSfService(string $serviceFqn)
  644.     {
  645.         /** @var ContainerInterface $container */
  646.         $container $GLOBALS['kernel']->getContainer();
  647.         return $container->get($serviceFqn);
  648.     }
  649.     public static function getSfParameter(string $parameterName)
  650.     {
  651.         /** @var ContainerInterface $container */
  652.         $container $GLOBALS['kernel']->getContainer();
  653.         return $container->getParameter($parameterName);
  654.     }
  655.     /**
  656.      * @throws Exception
  657.      */
  658.     public static function getExpeditionDateTextForAvailableStock(?int $customerId$supplierId$languageId): string
  659.     {
  660.         $expeditionTimestamp self::getExpeditionTimestampByDefault($customerId$supplierId);
  661.         /** @var \App\Application\Service\Helper\ShippingDateService $shippingDateService */
  662.         $shippingDateService self::getSfService(ShippingDateService::class);
  663.         return $shippingDateService->getBuyItNowAndWeSendItOnDateText($expeditionTimestampfalse$languageId);
  664.     }
  665.     /**
  666.      * @throws Exception
  667.      */
  668.     public static function getExpeditionDateTextForSupplierStock($customerId$idSupplier$dateToCompare$stockSupplier_3_5$languageId): string
  669.     {
  670.         $expeditionTimestamp self::getExpeditionTimestampBySupplier($customerId$idSupplier$dateToCompare$stockSupplier_3_5);
  671.         $shippingDateService self::getSfService(ShippingDateService::class);
  672.         return $shippingDateService->getBuyItNowAndWeSendItOnDateText($expeditionTimestampfalse$languageId);
  673.     }
  674.     /**
  675.      * @param string $data
  676.      *
  677.      * @return string|null
  678.      */
  679.     public static function cleanNonPrintableCharacters(string $data): ?string
  680.     {
  681.         return preg_replace('/[[:^print:]]/'''$data);
  682.     }
  683.     /**
  684.      * @deprecated use Symfony translator instead
  685.      */
  686.     public static function trans(string $key, ?array $parameters = [], ?string $domain 'messages'): ?string
  687.     {
  688.         return Tools::getSfService('translator')->trans($key$parameters$domain);
  689.     }
  690.     public static function displayIban(string $iban)
  691.     {
  692.         return self::substr($iban04).' ****** '.self::substr($iban, -44);
  693.     }
  694.     /**
  695.      * @param int $tmpExpeditionTimestamp
  696.      * @param int $customerId
  697.      * @return float|int
  698.      */
  699.     protected static function addCustomerSpecificDelay(int $tmpExpeditionTimestampint $customerId): int
  700.     {
  701.         // If customer order confirmation delay exists, add to the timestamp
  702.         $customerManager self::getSfService(CustomerManager::class);
  703.         $customer $customerManager->findOneById($customerId);
  704.         if (!empty($customer->getOrderConfirmationDelay())) {
  705.             $tmpExpeditionTimestamp $tmpExpeditionTimestamp + ($customer->getOrderConfirmationDelay() * DatetimeHelper::SECONDS_AN_HOUR);
  706.         }
  707.         return $tmpExpeditionTimestamp;
  708.     }
  709. }