diff --git a/classes/Search.php b/classes/Search.php index c92676774..dbdb4d767 100644 --- a/classes/Search.php +++ b/classes/Search.php @@ -150,7 +150,7 @@ class SearchCore if (!$context) $context = Context::getContext(); $db = Db::getInstance(_PS_USE_SQL_SLAVE_); - + // Only use cookie if id_customer is not present if ($useCookie) $id_customer = $context->customer->id; @@ -173,12 +173,13 @@ class SearchCore { $word = str_replace('%', '\\%', $word); $word = str_replace('_', '\\_', $word); + $intersectArray[] = 'SELECT si.id_product FROM '._DB_PREFIX_.'search_word sw LEFT JOIN '._DB_PREFIX_.'search_index si ON sw.id_word = si.id_word WHERE sw.id_lang = '.(int)$id_lang.' AND sw.id_shop = '.$context->shop->getID(true).' - AND sw.word LIKE + AND sw.word LIKE '.($word[0] == '-' ? ' \''.pSQL(Tools::substr($word, 1, PS_SEARCH_MAX_WORD_LENGTH)).'%\'' : '\''.pSQL(Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH)).'%\'' @@ -219,7 +220,7 @@ class SearchCore WHERE id_customer = '.(int)$id_customer.' )'); $result = $db->ExecuteS($sql, false); - + $eligibleProducts = array(); while ($row = $db->nextRow($result)) $eligibleProducts[] = $row['id_product']; @@ -235,7 +236,7 @@ class SearchCore return ($ajax ? array() : array('total' => 0, 'result' => array())); } array_unique($eligibleProducts); - + $productPool = ''; foreach ($eligibleProducts AS $id_product) if ($id_product) @@ -255,7 +256,7 @@ class SearchCore ORDER BY position DESC LIMIT 10'; return $db->ExecuteS($sql); } - + $sql = 'SELECT p.*, pl.`description_short`, pl.`available_now`, pl.`available_later`, pl.`link_rewrite`, pl.`name`, tax.`rate`, i.`id_image`, il.`legend`, m.`name` manufacturer_name '.$score.', DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 new FROM '._DB_PREFIX_.'product p @@ -284,12 +285,12 @@ class SearchCore LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.') WHERE p.`id_product` '.$productPool; $total = $db->getValue($sql); - + if (!$result) $resultProperties = false; else $resultProperties = Product::getProductsProperties((int)$id_lang, $result); - + return array('total' => $total,'result' => $resultProperties); } @@ -340,7 +341,7 @@ class SearchCore { $db = Db::getInstance(); $dropIndex = false; - + if ($id_product) $full = false; @@ -365,12 +366,12 @@ class SearchCore $ids[] = (int)$product['id_product']; if (sizeof($ids)) $db->Execute('DELETE FROM '._DB_PREFIX_.'search_index WHERE id_product IN ('.implode(',', $ids).')'); - - + + if (count($products) > 2000) $dropIndex = true; } - + if ($dropIndex) { $dropIndex = false; @@ -412,8 +413,8 @@ class SearchCore $countProducts = 0; $queryArray3 = array(); $productsArray = array(); - - // Every indexed words are cached into a PHP array + + // Every indexed words are cached into a PHP array $wordIdsByWord = array(); $wordIds = Db::getInstance()->ExecuteS(' SELECT id_word, word, id_lang, id_shop @@ -425,8 +426,8 @@ class SearchCore $wordIdsByWord[$wordId['id_shop']][$wordId['id_lang']] = array(); $wordIdsByWord[$wordId['id_shop']][$wordId['id_lang']]['_'.$wordId['word']] = (int)$wordId['id_word']; } - - // Now each non-indexed product is processed one by one, langage by langage + + // Now each non-indexed product is processed one by one, langage by langage while ($product = $db->nextRow($products)) { $product['tags'] = Search::getTags($db, (int)$product['id_product'], (int)$product['id_lang']); @@ -443,6 +444,9 @@ class SearchCore if (!empty($word)) { $word = Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH); + // Remove accents + $word = Tools::replaceAccentedChars($word); + if (!isset($pArray[$word])) $pArray[$word] = 0; $pArray[$word] += $weightArray[$key]; @@ -462,16 +466,20 @@ class SearchCore foreach ($pArray AS $word => $weight) if ($weight AND !isset($wordIdsByWord['_'.$word])) { - $queryArray[] = '('.(int)$product['id_lang'].', '.(int)$product['id_shop'].', \''.pSQL($word).'\')'; + $queryArray[$word] = '('.(int)$product['id_lang'].', '.(int)$product['id_shop'].', \''.pSQL($word).'\')'; $queryArray2[] = '\''.pSQL($word).'\''; $wordIdsByWord[$product['id_shop']][$product['id_lang']]['_'.$word] = 0; } - $existingWords = $db->ExecuteS('SELECT word FROM '._DB_PREFIX_.'search_word WHERE word IN ('.implode(',', $queryArray2).') GROUP BY word'); + $existingWords = $db->ExecuteS(' + SELECT word FROM '._DB_PREFIX_.'search_word + WHERE word IN ('.implode(',', $queryArray2).') + AND id_lang = '.(int)$product['id_lang'].' GROUP BY word'); + if($existingWords) foreach($existingWords as $data) - unset($queryArray[$data['word']]); - + unset($queryArray[Tools::replaceAccentedChars($data['word'])]); + if (count($queryArray)) { // The words are inserted... @@ -479,7 +487,6 @@ class SearchCore INSERT IGNORE INTO '._DB_PREFIX_.'search_word (id_lang, id_shop, word) VALUES '.implode(',',$queryArray)); } - if (count($queryArray2)) { // ...then their IDs are retrieved and added to the cache @@ -490,8 +497,9 @@ class SearchCore AND sw.id_lang = '.(int)$product['id_lang'].' AND sw.id_shop = '.(int)$product['id_shop'].' LIMIT '.count($queryArray2)); + // replace accents from the retrieved words so that words without accents or with differents accents can still be linked foreach ($addedWords AS $wordId) - $wordIdsByWord[$product['id_shop']][$product['id_lang']]['_'.$wordId['word']] = (int)$wordId['id_word']; + $wordIdsByWord[$product['id_shop']][$product['id_lang']]['_'.Tools::replaceAccentedChars($wordId['word'])] = (int)$wordId['id_word']; } } @@ -508,7 +516,7 @@ class SearchCore if (++$countWords % 200 == 0) Search::saveIndex($queryArray3); } - + if (!in_array($product['id_product'], $productsArray)) $productsArray[] = (int)$product['id_product']; @@ -516,11 +524,11 @@ class SearchCore if (++$countProducts % 50 == 0) Search::setProductsAsIndexed($productsArray); } - + // One last save is done at the end in order to save what's left Search::saveIndex($queryArray3); Search::setProductsAsIndexed($productsArray); - + // If it has been deleted, the index is created again once the indexation is done if (!$dropIndex) { @@ -532,7 +540,7 @@ class SearchCore } if ($dropIndex) $db->Execute('ALTER TABLE `'._DB_PREFIX_.'search_index` ADD PRIMARY KEY (`id_word`, `id_product`)'); - + Configuration::updateValue('PS_NEED_REBUILD_INDEX', 0); return true; } @@ -543,7 +551,7 @@ class SearchCore Db::getInstance()->Execute('UPDATE '._DB_PREFIX_.'product SET indexed = 1 WHERE id_product IN ('.implode(',', $products).') LIMIT '.(int)count($products)); $productsArray = array(); } - + // $queryArray3 is automatically emptied in order to be reused immediatly protected static function saveIndex(&$queryArray3) { @@ -562,7 +570,7 @@ class SearchCore $id_customer = (int)$context->customer->id; else $id_customer = 0; - + if (!is_numeric($pageNumber) OR !is_numeric($pageSize) OR !Validate::isBool($count) OR !Validate::isValidSearch($tag) OR $orderBy AND !$orderWay OR ($orderBy AND !Validate::isOrderBy($orderBy)) OR ($orderWay AND !Validate::isOrderBy($orderWay))) return false; diff --git a/classes/Tools.php b/classes/Tools.php index f5152f814..dbf481665 100644 --- a/classes/Tools.php +++ b/classes/Tools.php @@ -941,6 +941,29 @@ class ToolsCore $str = mb_strtolower($str, 'utf-8'); $str = trim($str); + $str = self::replaceAccentedChars($str); + + // Remove all non-whitelist chars. + $str = preg_replace('/[^a-zA-Z0-9\s\'\:\/\[\]-]/','', $str); + $str = preg_replace('/[\s\'\:\/\[\]-]+/',' ', $str); + $str = preg_replace('/[ ]/','-', $str); + $str = preg_replace('/[\/]/','-', $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. + $str = strtolower($str); + + return $str; + } + + /** + * Replace all accented chars by their equivalent non accented chars. + * + * @param string $str + * @return string + */ + public static function replaceAccentedChars($str) + { $str = preg_replace('/[\x{0105}\x{0104}\x{00E0}\x{00E1}\x{00E2}\x{00E3}\x{00E4}\x{00E5}]/u','a', $str); $str = preg_replace('/[\x{00E7}\x{010D}\x{0107}\x{0106}]/u','c', $str); $str = preg_replace('/[\x{010F}]/u','d', $str); @@ -958,17 +981,6 @@ class ToolsCore $str = preg_replace('/[\x{017C}\x{017A}\x{017B}\x{0179}\x{017E}]/u','z', $str); $str = preg_replace('/[\x{00E6}]/u','ae', $str); $str = preg_replace('/[\x{0153}]/u','oe', $str); - - // Remove all non-whitelist chars. - $str = preg_replace('/[^a-zA-Z0-9\s\'\:\/\[\]-]/','', $str); - $str = preg_replace('/[\s\'\:\/\[\]-]+/',' ', $str); - $str = preg_replace('/[ ]/','-', $str); - $str = preg_replace('/[\/]/','-', $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. - $str = strtolower($str); - return $str; } diff --git a/install-dev/controller.js b/install-dev/controller.js index 1e03a2da2..69dab95a9 100644 --- a/install-dev/controller.js +++ b/install-dev/controller.js @@ -279,7 +279,7 @@ function verifyAndSetRequire(firsttime) for (i = 0; i < testListRequired.length; i++){ result = testListRequired[i].getAttribute("result"); $($("div#sheet_require"+isUpdate+" > ul#required"+isUpdate+" .required")[i]) - .removeClass( (result == "fail") ? "okBlock" : "errorBlock" ) + .removeClass( (result == "fail") ? "ok" : "fail" ) .addClass(result); if (result == "fail") configIsOk = false; } @@ -290,7 +290,7 @@ function verifyAndSetRequire(firsttime) for (i = 0; i < testListOptional.length; i++){ result = testListOptional[i].getAttribute("result"); $($("div#sheet_require"+isUpdate+" > ul#optional"+isUpdate+" li.optional")[i]) - .removeClass( (result == "fail") ? "okBlock" : "errorBlock" ) + .removeClass( (result == "fail") ? "ok" : "fail" ) .addClass(result); if (result == "fail") optionalIsOk = false; } diff --git a/install-dev/sql/db_settings_extends.sql b/install-dev/sql/db_settings_extends.sql index 7dec0a25f..d97ee4ab6 100644 --- a/install-dev/sql/db_settings_extends.sql +++ b/install-dev/sql/db_settings_extends.sql @@ -417,7 +417,7 @@ INSERT INTO `PREFIX_image_lang` (`id_image`, `id_lang`, `legend`) VALUES INSERT INTO `PREFIX_tag` (`id_tag`, `id_lang`, `name`) VALUES (5, 1, 'apple'),(6, 2, 'ipod'),(7, 2, 'nano'),(8, 2, 'apple'),(18, 2, 'shuffle'), (19, 2, 'macbook'),(20, 2, 'macbookair'),(21, 2, 'air'),(22, 1, 'superdrive'),(27, 2, 'marche'),(26, 2, 'casque'),(25, 2, 'écouteurs'), -(24, 2, 'ipod touch tacticle'),(23, 1, 'Ipod touch'),(28, 1, 'ipod'),(29, 1, 'nano'),(30, 3, 'ipod'),(31, 3, 'nano'),(32, 3, 'apple'),(33, 1, 'shuffle'), +(24, 2, 'ipod touch tactile'),(23, 1, 'Ipod touch'),(28, 1, 'ipod'),(29, 1, 'nano'),(30, 3, 'ipod'),(31, 3, 'nano'),(32, 3, 'apple'),(33, 1, 'shuffle'), (34, 3, 'shuffle'),(35, 2, 'superdrive'),(36, 3, 'superdrive'),(37, 3, 'Ipod touch'); INSERT INTO `PREFIX_product_tag` (`id_product`, `id_tag`) VALUES (1, 5),(1, 6),(1, 7),(1, 8),(1, 28),(1, 29),(1, 30),(1, 31),(1, 32),(2, 6),(2, 18),(2, 28), @@ -770,7 +770,7 @@ INSERT INTO `PREFIX_search_word` (`id_word`, `id_lang`, `word`) VALUES (1, 1, 'i (925, 2, 'internet'),(926, 2, 'poche'),(927, 2, 'navigateur'),(928, 2, 'safari,'),(929, 2, 'consulter'),(930, 2, 'sites'),(931, 2, 'leur'),(932, 2, 'mise'), (933, 2, 'page'),(934, 2, 'effectuer'),(935, 2, 'zoom'),(936, 2, 'arrière'),(937, 2, 'simple'),(938, 2, 'pression'),(939, 2, 'l''écran'),(940, 2, 'contenu'), (941, 2, 'coffret'),(942, 2, 'écouteurs'),(943, 2, 'câble'),(944, 2, 'dock'),(945, 2, 'chiffon'),(946, 2, 'nettoyage'),(947, 2, 'support'),(948, 2, 'guide'), -(949, 2, 'démarrage'),(950, 2, 'tacticle'),(951, 2, '32go'),(952, 2, 'jack'),(953, 2, '120g'),(954, 2, '70mm'),(955, 2, '110mm'),(956, 3, 'touch'), +(949, 2, 'démarrage'),(950, 2, 'tactile'),(951, 2, '32go'),(952, 2, 'jack'),(953, 2, '120g'),(954, 2, '70mm'),(955, 2, '110mm'),(956, 3, 'touch'), (957, 3, 'interfaz'),(958, 3, 'revolucionaria'),(959, 3, 'color'),(960, 3, 'pulgadas'),(961, 3, '(80211b'),(962, 3, 'espesor'),(963, 3, 'safari,'), (964, 3, 'youtube,'),(965, 3, 'music'),(966, 3, 'store,'),(967, 3, 'correo,'),(968, 3, 'mapas,'),(969, 3, 'bolsa,'),(970, 3, 'tiempo,'),(971, 3, 'notas'), (972, 3, 'cinco'),(973, 3, 'mano'),(974, 3, 'consulta'),(975, 3, 'correo'),(976, 3, 'formato'),(977, 3, 'html'),(978, 3, 'enriquecido,'),(979, 3, 'fotos'), diff --git a/modules/blocklayered/blocklayered.js b/modules/blocklayered/blocklayered.js index 5725b7d8d..5a9d9f4d4 100644 --- a/modules/blocklayered/blocklayered.js +++ b/modules/blocklayered/blocklayered.js @@ -41,14 +41,12 @@ $(document).ready(function() $('').attr('type', 'hidden').attr('name', $(this).attr('name')).val($(this).attr('rel')).appendTo('#layered_form'); else $('\'input[name='+$(this).attr('name')+']:hidden\'').remove(); - window.location = '#'+$(this).next().children(1).attr('href').replace(/https?:\/\/.*\/\d+-[^\/]+/, ''); reloadContent(); }); // Click on checkbox $('#layered_form input[type=checkbox]').live('click', function() { - window.location = '#'+$(this).next().children(1).attr('href').replace(/https?:\/\/.*\/\d+-[^\/]+/, ''); reloadContent(); }); @@ -57,7 +55,6 @@ $(document).ready(function() click: function() { if($(this).parent().parent().find('input').attr('disabled') == '') { - window.location = '#'+this.href.replace(/https?:\/\/.*\/\d+-[^\/]+/, ''); $(this).parent().parent().find('input').click(); reloadContent(); } @@ -90,34 +87,12 @@ function initSliders() function initLayered() { initSliders(); - if (window.location.href.split('#').length == 2) + if (window.location.href.split('#').length == 2 && window.location.href.split('#')[1] != '') { var params = window.location.href.split('#')[1]; - reloadContent('&selected_filters='+params, true); + reloadContent('&selected_filters='+params); } - else - { - var params = window.location.href; - params = friendlyUrl(params, 'long'); - params = params.split('#'); - params.shift(); - $(params).each(function(it, val) - { - allowReload = true; - if (val.split('=')[0] == 'price' || val.split('=')[0] == 'weight') - { - $("#layered_"+val.split('=')[0]+"_slider").slider('values', 0, val.split('=')[1].split('_')[0]); - $("#layered_"+val.split('=')[0]+"_slider").slider('values', 1, val.split('=')[1].split('_')[1]); - $("#layered_"+val.split('=')[0]+"_slider").slider('option', 'slide')(0,{values:[val.split('=')[1].split('_')[0], val.split('=')[1].split('_')[1]]}); } - else - { - $('#'+val.split('=')[0]).click(); - } - }); - reloadContent(); -} -} function updatelink(link) { @@ -234,14 +209,8 @@ function openCloseFilter() }); } -function reloadContent(params_plus, force) +function reloadContent(params_plus) { - if (typeof(allowReload) == 'undefined' && typeof(force) != 'undefined' && force != true) - { - allowReload = true; - return; - } - for(i = 0; i < ajaxQueries.length; i++) ajaxQueries[i].abort(); ajaxQueries = new Array(); @@ -317,6 +286,9 @@ function reloadContent(params_plus, force) reloadProductComparison(); } initSliders(); + + if(typeof(current_friendly_url != 'undefined')) + window.location = current_friendly_url; } }); ajaxQueries.push(ajaxQuery); diff --git a/modules/blocklayered/blocklayered.php b/modules/blocklayered/blocklayered.php index f81b4e384..7830ef171 100644 --- a/modules/blocklayered/blocklayered.php +++ b/modules/blocklayered/blocklayered.php @@ -1387,7 +1387,7 @@ class BlockLayered extends Module /* If the current category isn't defined of if it's homepage, we have nothing to display */ $id_parent = (int)Tools::getValue('id_category', Tools::getValue('id_category_layered', 1)); if ($id_parent == 1) - return; + return false; $queryFilters = ' AND p.active = 1'; @@ -1888,7 +1888,7 @@ class BlockLayered extends Module { if (is_array($value) AND array_key_exists('checked', $value )) { - $paramGroupSelected .= '-'.Tools::link_rewrite($value['name']); + $paramGroupSelected .= '-'.str_replace('-', '_', Tools::link_rewrite($value['name'])); $paramGroupSelectedArray [Tools::link_rewrite($typeFilter['name'])][] = Tools::link_rewrite($value['name']); if (!isset($titleValues[$typeFilter['name']])) @@ -1900,7 +1900,7 @@ class BlockLayered extends Module } if(!empty($paramGroupSelected)) { - $paramSelected .= '/'.Tools::link_rewrite($typeFilter['name']).$paramGroupSelected; + $paramSelected .= '/'.str_replace('-', '_', Tools::link_rewrite($typeFilter['name'])).$paramGroupSelected; $optionCheckedArray[Tools::link_rewrite($typeFilter['name'])] = $paramGroupSelected; } } @@ -1912,21 +1912,32 @@ class BlockLayered extends Module { foreach ($typeFilter['values'] as $key => $values) { + $nofollow = false; $optionCheckedCloneArray = $optionCheckedArray; //if not filters checked, add parameter if(!in_array(Tools::link_rewrite($values['name']), $paramGroupSelectedArray[Tools::link_rewrite($typeFilter['name'])])) { //update parameter filter checked before - if(array_key_exists(Tools::link_rewrite($typeFilter['name']), $optionCheckedArray)) + if(array_key_exists(Tools::link_rewrite($typeFilter['name']), $optionCheckedArray)) { $optionCheckedCloneArray[Tools::link_rewrite($typeFilter['name'])] = $optionCheckedCloneArray[Tools::link_rewrite($typeFilter['name'])].'-'.str_replace('-', '_', Tools::link_rewrite($values['name'])); + $nofollow = true; + } else $optionCheckedCloneArray[Tools::link_rewrite($typeFilter['name'])] = '-'.str_replace('-', '_', Tools::link_rewrite($values['name'])); } + else + { + // Remove selected parameters + $optionCheckedCloneArray[Tools::link_rewrite($typeFilter['name'])] = str_replace('-'.str_replace('-', '_', Tools::link_rewrite($values['name'])), '', $optionCheckedCloneArray[Tools::link_rewrite($typeFilter['name'])]); + if(empty($optionCheckedCloneArray[Tools::link_rewrite($typeFilter['name'])])) + unset($optionCheckedCloneArray[Tools::link_rewrite($typeFilter['name'])]); + } $parameters = ''; foreach ($optionCheckedCloneArray as $keyGroup => $valueGroup) $parameters .= '/'.str_replace('-', '_',$keyGroup).$valueGroup; //write link $typeFilter['values'][$key]['link'] = $linkBase.$parameters; + $typeFilter['values'][$key]['rel'] = ($nofollow)?'nofollow':''; } } } @@ -1944,7 +1955,7 @@ class BlockLayered extends Module $cache = array('layered_show_qties' => (int)Configuration::get('PS_LAYERED_SHOW_QTIES'), 'id_category_layered' => (int)$id_parent, 'selected_filters' => $selectedFilters, 'n_filters' => (int)$nFilters, 'nbr_filterBlocks' => sizeof($filterBlocks), 'filters' => $filterBlocks, - 'title_values' => $titleValues); + 'title_values' => $titleValues, 'current_friendly_url' => htmlentities($paramSelected), 'nofollow' => $nofollow); return $cache; } @@ -1952,9 +1963,14 @@ class BlockLayered extends Module public function generateFiltersBlock($selectedFilters) { global $smarty; + if($filterBlock = $this->getFilterBlock($selectedFilters)) + { $smarty->assign($this->getFilterBlock($selectedFilters)); return $this->display(__FILE__, 'blocklayered.tpl'); } + else + return false; + } /* * This function must be improved diff --git a/modules/blocklayered/blocklayered.tpl b/modules/blocklayered/blocklayered.tpl index d9714df52..c4464f854 100644 --- a/modules/blocklayered/blocklayered.tpl +++ b/modules/blocklayered/blocklayered.tpl @@ -26,6 +26,9 @@ {if $nbr_filterBlocks != 0} +

{l s='Catalog' mod='blocklayered'}

@@ -83,7 +86,12 @@ {else} {/if} - + + {/if} {/foreach} {else} diff --git a/themes/prestashop/lang/fr.php b/themes/prestashop/lang/fr.php index 05ba75194..86cbb689a 100644 --- a/themes/prestashop/lang/fr.php +++ b/themes/prestashop/lang/fr.php @@ -284,7 +284,7 @@ $_LANG['order-carrier_674bb1e64d73fb88b873caf79ba06128'] = '(lire)'; $_LANG['order-carrier_e085dcd05d73bdd5afe338e5b6e42a18'] = 'Choisissez votre mode de livraison'; $_LANG['order-carrier_c8c4080207cd4f02548c8cb6285bd16b'] = 'Aucun transporteur nécessaire pour cette commande'; $_LANG['order-carrier_0fce1189b263c211a8239fb0e9df004d'] = 'J\'accepte de recevoir ma commande dans un emballage recyclé'; -$_LANG['order-carrier_8f90815af11493295587f91f571c2f95'] = 'Il n\'y a pas de transporteurs disponibles qui délivre à cette adresse.'; +$_LANG['order-carrier_8f90815af11493295587f91f571c2f95'] = 'Il n\'y a pas de transporteur disponible qui délivre à cette adresse.'; $_LANG['order-carrier_914419aa32f04011357d3b604a86d7eb'] = 'Transporteur'; $_LANG['order-carrier_a82be0f551b8708bc08eb33cd9ded0cf'] = 'Informations'; $_LANG['order-carrier_3601146c4e948c32b6424d2c0a7f0118'] = 'Prix';