bb-legacy/app/Tools.php line 1568

Open in your IDE?
  1.         return substr($str$start$length === false Tools::strlen($str) : (int)$length);
  2.     }
  3.     /**
  4.      * Comprobamos un VAT Number
  5.      *
  6.      * @param string $vatid VAT Number a validar
  7.      * @param string $cc codigo ISO del pais
  8.      * @param int $idCustomer Identificador del usuario
  9.      *
  10.      * @return bool
  11.      * @deprecated use TaxService::isValidVies() instead
  12.      */
  13.     public static function checkVATNumber($vatid$cc$idCustomer)
  14.     {
  15.         if (!$vatid || !$cc) {
  16.             return false;
  17.         }
  18.         $taxService self::getSfService(TaxService::class);
  19.         return $taxService->isValidVies($idCustomer$vatid$cc);
  20.     }
  21.     /**
  22.      * returns the rounded value of $value to specified precision, according to your configuration;
  23.      *
  24.      * @note : PHP 5.3.0 introduce a 3rd parameter mode in round function
  25.      *
  26.      * @param float $value
  27.      * @param int $precision
  28.      *
  29.      * @return float
  30.      *
  31.      * @deprecated use round() instead
  32.      */
  33.     public static function ps_round($value$precision 0)
  34.     {
  35.         return round($value$precision);
  36.     }
  37.     public static function getRealIP()
  38.     {
  39.         if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
  40.             return $_SERVER['HTTP_CLIENT_IP'];
  41.         }
  42.         // TODO quitar este if y descomentar las líneas
  43.         if (!empty($_SERVER['REMOTE_ADDR'])) {
  44.             return $_SERVER['REMOTE_ADDR'];
  45.         }
  46.         return $_SERVER['HTTP_X_FORWARDED_FOR'];
  47.     }
  48.     public static function getCoordsIP()
  49.     {
  50.         // Obtenemos localización del usuario por su ip
  51.         $ip Tools::getRealIP();
  52.         // $ip = '88.0.57.88';
  53.         $url 'http://www.geoplugin.net/php.gp?ip='.$ip// echo $url;
  54.         $datos = @unserialize(file_get_contents($url));
  55.         $resp = [];
  56.         if ($datos) {
  57.             // $iso_code = $datos['geoplugin_countryCode'];
  58.             // $city = $datos['geoplugin_city'];
  59.             $resp['latitud'] = (isset($datos['geoplugin_latitude'])) ? $datos['geoplugin_latitude'] : '';
  60.             $resp['longitud'] = (isset($datos['geoplugin_longitude'])) ? $datos['geoplugin_longitude'] : '';
  61.             $resp['country_code'] = (isset($datos['geoplugin_countryCode'])) ? $datos['geoplugin_countryCode'] : '';
  62.             $resp['geoplugin_request'] = (isset($datos['geoplugin_request'])) ? $datos['geoplugin_request'] : '';
  63.         } else {
  64.             $resp['latitud'] = '';
  65.             $resp['longitud'] = '';
  66.             $resp['country_code'] = '';
  67.             $resp['geoplugin_request'] = '';
  68.         }
  69.         return $resp;
  70.     }
  71.     /**
  72.      * Modifies a string to remove all non ASCII characters and spaces.
  73.      */
  74.     public static function slugify($text)
  75.     {
  76.         // replace non letter or digits by -
  77.         $text preg_replace('~[^\\pL\d]+~u''-'$text);
  78.         // trim
  79.         $text trim($text'-');
  80.         // transliterate
  81.         if (function_exists('iconv')) {
  82.             $text iconv('utf-8''us-ascii//TRANSLIT'$text);
  83.         }
  84.         // lowercase
  85.         $text strtolower($text);
  86.         // remove unwanted characters
  87.         $text preg_replace('~[^-\w]+~'''$text);
  88.         if (empty($text)) {
  89.             return 'n-a';
  90.         }
  91.         return $text;
  92.     }
  93.     /**
  94.      * @deprecated use guzzle instead
  95.      */
  96.     public static function httpPost($url$params$return_http_code false$follow false$sslVerification true)
  97.     {
  98.         $postData '';
  99.         if (!empty($params)) {
  100.             $postData http_build_query($params);
  101.         }
  102.         $ch curl_init();
  103.         curl_setopt($chCURLOPT_URL$url);
  104.         curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  105.         curl_setopt($chCURLOPT_HEADERfalse);
  106.         // NO VERIFICAR SSL SI ESTAMOS EN MODO DESARROLLO
  107.         if (Tools::getSfService(\App\Service\EnvironmentService::class)->isDev() || !$sslVerification) {
  108.             curl_setopt($chCURLOPT_SSL_VERIFYHOSTfalse);
  109.             curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
  110.         }
  111.         if (!empty($params)) {
  112.             curl_setopt($chCURLOPT_POSTis_array($postData) && count($postData) ? true false);
  113.             curl_setopt($chCURLOPT_POSTFIELDS$postData);
  114.         }
  115.         if ($follow) {
  116.             curl_setopt($chCURLOPT_FOLLOWLOCATIONtrue);
  117.         }
  118.         //        DESCOMENTAR PARA DEPURAR LLAMADAS CURL DESDE NETBEANS
  119.         //        curl_setopt($ch, CURLOPT_COOKIE,"XDEBUG_SESSION=netbeans-xdebug");
  120.         $output curl_exec($ch);
  121.         if ($output == false) {
  122.             $output curl_error($ch);
  123.         }
  124.         // DEVOLVEMOS EL CODIGO HTTP (404, 500, 200...)
  125.         if ($return_http_code) {
  126.             $output curl_getinfo($chCURLINFO_HTTP_CODE);
  127.         }
  128.         curl_close($ch);
  129.         return $output;
  130.     }
  131.     /**
  132.      * Truncate strings
  133.      *
  134.      * @param string $str
  135.      * @param int $max_length Max length
  136.      * @param string $suffix Suffix optional
  137.      *
  138.      * @return string $str truncated
  139.      */
  140.     /* CAUTION : Use it only on module hookEvents.
  141.      * * For other purposes use the smarty function instead */
  142.     public static function truncate($str$max_length$suffix '...')
  143.     {
  144.         if (Tools::strlen($str) <= $max_length) {
  145.             return $str;
  146.         }
  147.         $str utf8_decode($str);
  148.         return utf8_encode(substr($str0$max_length Tools::strlen($suffix)).$suffix);
  149.     }
  150.     public static function isMobile()
  151.     {// return true;
  152.         if (defined('IS_MOBILE')) {
  153.             return IS_MOBILE;
  154.         }
  155.         return false;
  156.     }
  157.     public static function generarCodigo($longitud)
  158.     {
  159.         $key '';
  160.         $pattern '1234567890abcdefghijklmnopqrstuvwxyz';
  161.         $max strlen($pattern) - 1;
  162.         for ($i 0$i $longitud$i++) {
  163.             $key .= $pattern[mt_rand(0$max)];
  164.         }
  165.         return $key;
  166.     }
  167.     public static function calculateDaysTransit($days$productId null$extern false)
  168.     {
  169.         $syncronisedException = ($extern) ? Product::isSincronisedSendException($productId) : false;
  170.         if ($days <= 2) {
  171.             return [
  172.                 'days' => 1,
  173.                 'text_product' => self::l('%s uds.''Tools'),
  174.                 'text_cart' => (!$syncronisedException) ? self::l('Envío inmediato''Tools') : self::l('24/48h''Tools'),
  175.             ];
  176.         }
  177.         $tmpDays = (int)ceil($days 5);
  178.         switch ($tmpDays) {
  179.             case 0:
  180.             case 1:
  181.                 $days_range '2/5';
  182.                 $tmpDays 1;
  183.                 break;
  184.             case 2:
  185.                 $days_range '5/10';
  186.                 break;
  187.             case 3:
  188.                 $days_range '10/15';
  189.                 break;
  190.             case 4:
  191.                 $days_range '15/20';
  192.                 break;
  193.             default:
  194.                 $days_range '20/30';
  195.         }
  196.         return [
  197.             'days' => $tmpDays 5,
  198.             'text_product' => sprintf(self::l('%s uds. envío %s días''Tools'), '%s'$days_range),
  199.             'text_cart' => sprintf(self::l('%s días''Tools'), $days_range),
  200.         ];
  201.     }
  202.     public static function divideString($name$separador '<br />'$num_lines 2)
  203.     {
  204.         $blank_spaces ceil(substr_count($name' ') / $num_lines);
  205.         $nameEnd '';
  206.         $count_spaces 0;
  207.         $nameTmp str_split($name);
  208.         $br false;
  209.         foreach ($nameTmp as $c) {
  210.             if ($c == ' ') {
  211.                 $count_spaces++;
  212.             }
  213.             if ($count_spaces == $blank_spaces && $blank_spaces && !$br) {
  214.                 $nameEnd .= $separador;
  215.                 $br true;
  216.             } else {
  217.                 $nameEnd .= $c;
  218.             }
  219.         }
  220.         return $nameEnd;
  221.     }
  222.     public static function convertTable($txt$titulo '')
  223.     {
  224.         $_convertTable = [
  225.         '&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', ];
  226.         if ($txt == '') {
  227.             $txt $titulo;
  228.         }
  229.         $temp =  strtr($txt$_convertTable);
  230.         $urlKey preg_replace('#[^0-9a-z]+#i''-'$temp);
  231.         $urlKey strtolower($urlKey);
  232.         $urlKey trim($urlKey'-');
  233.         return $urlKey;
  234.     }
  235.     public static function convertDateToEpoch($date)
  236.     {
  237.         $tmp explode(' '$date);
  238.         $dateArray explode('-'$tmp[0]);
  239.         $hourArray explode(':'$tmp[1]);
  240.         if (empty($dateArray[1]) || empty($hourArray[2]) || empty($hourArray[1]) || empty($hourArray[2])) {
  241.             return 0;
  242.         }
  243.         $epoch mktime($hourArray[0], $hourArray[1], $hourArray[2], $dateArray[1], $dateArray[2], $dateArray[0]);
  244.         return $epoch;
  245.     }
  246.     /**
  247.      * Añadimos la cookie de la secure Key del carriro
  248.      */
  249.     public static function processCookieSecureKey()
  250.     {
  251.         if (empty($_COOKIE['secure_key'])) {
  252.             $secureKey uniqid(rand(09).rand(09).rand(09), true);
  253.             setcookie('secure_key'$secureKeytime() + (60 60 24 7), '/');
  254.             Session::set('secure_key'$secureKey);
  255.         }
  256.     }
  257.     /**
  258.      * @param $timestamp
  259.      * @param $supplierId
  260.      *
  261.      * @return int
  262.      */
  263.     public static function getClosestNonHolidayTimestampInFuture($timestamp$supplierId$additionalDaysToSkip 0): int
  264.     {
  265.         $dateTimeHelper = new DatetimeHelper();
  266.         $dateTime $dateTimeHelper->getDatetimeFromTimestamp($timestamp);
  267.         $weekendDays = [DatetimeHelper::SATURDAYDatetimeHelper::SUNDAY];
  268.         $dateHolidays Tools::jsonDecode(Configuration::get('HOLIDAYS'true), true);
  269.         if ($supplierId) {
  270.             /** @var SupplierHolidaysManager $supplierHolidayManager */
  271.             $supplierHolidayManager Tools::getSfService(SupplierHolidaysManager::class);
  272.             $supplierHoliday $supplierHolidayManager->findOneById((int)$supplierId);
  273.             $dateSupplierHolidays = ($supplierHoliday) ? json_decode($supplierHoliday->getHolidays(), true) : [];
  274.         }
  275.         while (true) {
  276.             $isHoliday = isset($dateHolidays[$dateTime->format('Y-m-d')]);
  277.             $isWeekend in_array($dateTime->format('w'), $weekendDays);
  278.             if ($supplierId) {
  279.                 $isHolidaySuplier in_array($dateTime->format('Y-m-d'), $dateSupplierHolidays);
  280.                 if (!$isHoliday && !$isWeekend && !$isHolidaySuplier) {
  281.                     if ($additionalDaysToSkip === 0) {
  282.                         return $dateTime->getTimestamp();
  283.                     } else {
  284.                         $additionalDaysToSkip--;
  285.                     }
  286.                 }
  287.             } else {
  288.                 if (!$isHoliday && !$isWeekend) {
  289.                     if ($additionalDaysToSkip === 0) {
  290.                         return $dateTime->getTimestamp();
  291.                     } else {
  292.                         $additionalDaysToSkip--;
  293.                     }
  294.                 }
  295.             }
  296.             $dateTime->modify('+1 day');
  297.         }
  298.     }
  299.     /**
  300.      * @return int
  301.      *
  302.      * @throws Exception
  303.      *
  304.      * @var
  305.      */
  306.     public static function getExpeditionTimestampByDefault(?int $customerId$supplierId): int
  307.     {
  308.         return self::calculateExpeditionTimestamp($customerIdShippingDateService::DEFAULT_EXPEDITION_MESSAGE_TIME$supplierId00false);
  309.     }
  310.     /**
  311.      * @param int $idSupplier
  312.      * @param int|null $timestampToCompare
  313.      *
  314.      * @return int
  315.      *
  316.      * @throws Exception
  317.      */
  318.     public static function getExpeditionTimestampBySupplier(?int $customerIdint $idSupplier, ?int $timestampToComparebool $stock_3_5): int
  319.     {
  320.         $supplierExpeditionConfig plazo_aprovisionamiento_proveedor::getExpeditionInformation($idSupplier);
  321.         $cutTimeString $supplierExpeditionConfig['expedition_message_time'];
  322.         $expeditionAdditionalDaysDelay = (int)$supplierExpeditionConfig['expedition_days'];
  323.         if ($stock_3_5) {
  324.             $expeditionAdditionalDaysDelay = (int)$supplierExpeditionConfig['expedition_days_3_5'];
  325.         }
  326.         return self::calculateExpeditionTimestamp($customerId$cutTimeString$idSupplier$expeditionAdditionalDaysDelay$timestampToComparetrue);
  327.     }
  328.     /**
  329.      * @param array $product
  330.      *
  331.      * @return int
  332.      *
  333.      * @throws Exception
  334.      */
  335.     public static function getExpeditionTimestampForFutureStock(array $product): int
  336.     {
  337.         $daysUntilStockWillBeHere = \stock_venideros::calculateDaysTransit($product['id_product'], $product['id_product_attribute']);
  338.         if (!$daysUntilStockWillBeHere) {
  339.             $daysUntilStockWillBeHere = (int)self::jsonDecode(Configuration::get('STOCK_VENIDERO_DIAS_CORTESIA'), true);
  340.         }
  341.         $transitDaysData self::calculateDaysTransit($daysUntilStockWillBeHere$product['id_product']);
  342.         $datetimeHelper = new DatetimeHelper();
  343.         $tmpExpeditionTimestamp $datetimeHelper->getCurrentTimestamp();
  344.         // Add
  345.         $tmpExpeditionTimestamp += $transitDaysData['days'] * DatetimeHelper::SECONDS_A_DAY;
  346.         return self::getClosestNonHolidayTimestampInFuture($tmpExpeditionTimestampnull);
  347.     }
  348.     /**
  349.      * @param string $cutTimeString
  350.      * @param int $supplierId
  351.      * @param int $supplierAdditionalDaysDelay
  352.      * @param int|null $timestampToCompare
  353.      *
  354.      * @return int
  355.      *
  356.      * @throws Exception Calculates expedition timestamp taking into account:
  357.      *                   1. Customer specific delays (Ex: Workhuman 3 hour delay)
  358.      *                   2. Whether cut time has passed or not
  359.      *                   3. Supplier specific delays
  360.      *                   4. Skip holidays and weekends
  361.      *
  362.      * Accepts a $timestampToCompare argument that will be returned if its greater than the value calculated by the function
  363.      */
  364.     private static function calculateExpeditionTimestamp(
  365.         ?int $customerId,
  366.         string $cutTimeString,
  367.         int $supplierId,
  368.         int $supplierAdditionalDaysDelay,
  369.         ?int $timestampToCompare,
  370.         bool $includeSupplierHolidays
  371.     ): int {
  372.         $datetimeHelper = new DatetimeHelper();
  373.         $currentTimestamp $datetimeHelper->getCurrentTimestamp();
  374.         // Init to current timestamp
  375.         $tmpExpeditionTimestamp $currentTimestamp;
  376.         // Apply customer-defined delay
  377.         if (!empty($customerId)) {
  378.             $tmpExpeditionTimestamp self::addCustomerSpecificDelay($tmpExpeditionTimestamp$customerId);
  379.         }
  380.         // If the temporary expedition timestamp exceeds the cut time, add a day
  381.         if (self::timestampExceedsCutTime($tmpExpeditionTimestamp$cutTimeString)) {
  382.             $tmpExpeditionTimestamp $tmpExpeditionTimestamp DatetimeHelper::SECONDS_A_DAY;
  383.         }
  384.         // if $tmpExpeditionTimestamp is not a working day, get closest one
  385.         $closestNonHolidayTimestampInFuture Tools::getClosestNonHolidayTimestampInFuture($tmpExpeditionTimestamp$includeSupplierHolidays $supplierId null0);
  386.         // Add as many more days as 'expedition_days' value and get closest working day again
  387.         if ($supplierAdditionalDaysDelay 0) {
  388.             $closestNonHolidayTimestampInFuture Tools::getClosestNonHolidayTimestampInFuture($tmpExpeditionTimestamp$includeSupplierHolidays $supplierId null$supplierAdditionalDaysDelay);
  389.         }
  390.         if ($timestampToCompare $closestNonHolidayTimestampInFuture) {
  391.             return $timestampToCompare;
  392.         }
  393.         return $closestNonHolidayTimestampInFuture;
  394.     }
  395.     public static function replaceByAbsoluteURL($matches)
  396.     {
  397.         if (array_key_exists(1$matches) && array_key_exists(2$matches)) {
  398.             if (!preg_match('/^(?:https?:)?\/\//iUs'$matches[2])) {
  399.                 return $matches[1].BASE_URL.'public/css/'.$matches[2];
  400.             }
  401.             return $matches[0];
  402.         }
  403.         return false;
  404.     }
  405.     /**
  406.      * @param int $tmpExpeditionTimestamp
  407.      * @param string $cutTimeString
  408.      *
  409.      * @return bool
  410.      */
  411.     private static function timestampExceedsCutTime(int $tmpExpeditionTimestampstring $cutTimeString): bool
  412.     {
  413.         $datetimeHelper = new DatetimeHelper();
  414.         $tmpDatetime $datetimeHelper->getDatetimeFromTimestamp($tmpExpeditionTimestamp);
  415.         $cutTimeComponents explode(':'$cutTimeString);
  416.         $cutTimeHours = (int)trim($cutTimeComponents[0]);
  417.         $cutTimeMinutes = (int)trim($cutTimeComponents[1]);
  418.         $cutTimeSeconds = (int)trim($cutTimeComponents[2]);
  419.         $cutDatetime $datetimeHelper->getCurrentDateTime()->setTime($cutTimeHours$cutTimeMinutes$cutTimeSeconds);
  420.         return $tmpDatetime $cutDatetime;
  421.     }
  422.     /**
  423.      * Retornamos un array con la lista de todos los productos tienda disponibles
  424.      *
  425.      * @return array Listado de productos tienda
  426.      */
  427.     public static function getProductShopListArray()
  428.     {
  429.         $prestashopList explode(','Configuration::get('ID_SHOPS'));
  430.         return array_merge(\App\Entity\System\Product::SHOPIFY_PRODUCTS_IDS$prestashopList);
  431.     }
  432.     public static function getPackName($packName$subscriptionName '')
  433.     {
  434.         if ($packName == $subscriptionName) {
  435.             return $subscriptionName;
  436.         }
  437.         return $packName.' '.$subscriptionName;
  438.     }
  439.     public static function getGenericServerError($errorCode)
  440.     {
  441.         return sprintf(
  442.             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'),
  443.             '<a href="'.Link::getFrontLink('contact#tabpanel3').'" class="link color-blue">',
  444.             '</a>',
  445.             $errorCode
  446.         );
  447.     }
  448.     /**
  449.      * Clean Url of <script> tags
  450.      * This method use HTMLPurifier lib from composer
  451.      *
  452.      * @param string $url
  453.      */
  454.     public static function htmlPurifier($url): string
  455.     {
  456.         $config HTMLPurifier_Config::createDefault();
  457.         $config->set('Cache.DefinitionImpl'null);
  458.         $purifier = new HTMLPurifier($config);
  459.         $newParam $purifier->purify($url); // this convert
  460.         $searchParams = ['&lt;script&gt;''&lt;/script&gt;'];
  461.         $replaceParams '';
  462.         $newParam str_ireplace($searchParams$replaceParams$newParam);
  463.         $newParam trim($newParam);
  464.         return $newParam;
  465.     }
  466.     /**
  467.      * @template T
  468.      *
  469.      * @param class-string<T> $serviceFqn
  470.      *
  471.      * @return T
  472.      */
  473.     public static function getSfService(string $serviceFqn)
  474.     {
  475.         /** @var ContainerInterface $container */
  476.         $container $GLOBALS['kernel']->getContainer();
  477.         return $container->get($serviceFqn);
  478.     }
  479.     public static function getSfParameter(string $parameterName)
  480.     {
  481.         /** @var ContainerInterface $container */
  482.         $container $GLOBALS['kernel']->getContainer();
  483.         return $container->getParameter($parameterName);
  484.     }
  485.     /**
  486.      * @throws Exception
  487.      */
  488.     public static function getExpeditionDateTextForAvailableStock(?int $customerId$supplierId$languageId): string
  489.     {
  490.         $expeditionTimestamp self::getExpeditionTimestampByDefault($customerId$supplierId);
  491.         /** @var \App\Application\Service\Helper\ShippingDateService $shippingDateService */
  492.         $shippingDateService self::getSfService(ShippingDateService::class);
  493.         return $shippingDateService->getBuyItNowAndWeSendItOnDateText($expeditionTimestampfalse$languageId);
  494.     }
  495.     /**
  496.      * @throws Exception
  497.      */
  498.     public static function getExpeditionDateTextForSupplierStock($customerId$idSupplier$dateToCompare$stockSupplier_3_5$languageId): string
  499.     {
  500.         $expeditionTimestamp self::getExpeditionTimestampBySupplier($customerId$idSupplier$dateToCompare$stockSupplier_3_5);
  501.         $shippingDateService self::getSfService(ShippingDateService::class);
  502.         return $shippingDateService->getBuyItNowAndWeSendItOnDateText($expeditionTimestampfalse$languageId);
  503.     }
  504.     /**
  505.      * @param string $data
  506.      *
  507.      * @return string|null
  508.      */
  509.     public static function cleanNonPrintableCharacters(string $data): ?string
  510.     {
  511.         return preg_replace('/[[:^print:]]/'''$data);
  512.     }
  513.     /**
  514.      * @deprecated use Symfony translator instead
  515.      */
  516.     public static function trans(string $key, ?array $parameters = [], ?string $domain 'messages'): ?string
  517.     {
  518.         return Tools::getSfService('translator')->trans($key$parameters$domain);
  519.     }
  520.     public static function displayIban(string $iban)
  521.     {
  522.         return self::substr($iban04).' ****** '.self::substr($iban, -44);
  523.     }
  524.     /**
  525.      * @param int $tmpExpeditionTimestamp
  526.      * @param int $customerId
  527.      * @return float|int
  528.      */
  529.     protected static function addCustomerSpecificDelay(int $tmpExpeditionTimestampint $customerId): int
  530.     {
  531.         // If customer order confirmation delay exists, add to the timestamp
  532.         $customerManager self::getSfService(CustomerManager::class);
  533.         $customer $customerManager->findOneById($customerId);
  534.         if (!empty($customer->getOrderConfirmationDelay())) {
  535.             $tmpExpeditionTimestamp $tmpExpeditionTimestamp + ($customer->getOrderConfirmationDelay() * DatetimeHelper::SECONDS_AN_HOUR);
  536.         }
  537.         return $tmpExpeditionTimestamp;
  538.     }
  539. }