Обработка специальных символов в ссылках

Опубликовано Опубликовано в рубрике prestashop, Русская документация PrestaShop 1.6, Учебник разработчика PrestaShop 1.6

Обработка специальных символов в ссылках

Не все магазины используют простой текстовый контент ASCII. Любой магазин, который использует названия продуктов со специальными символами, может организовать необходимую поддержку этих специальных символов в ссылках.

По сути, даже «базовые» языки теперь объединяют заимствованные слова с других языков: любой англоговорящий знает разницу между «resume» and «résumé».

Вы всегда должны стремиться поддерживать специальные символы.

PrestaShop не обрабатывает многие специальные символы с языков, использующих не латинский алфавит. Но поскольку PrestaShop построен вокруг UTF-8 (кодировка Unicode), вы можете легко организовать их поддержку.

Чтобы поддерживать специальные символы вашего языка в ссылках вы должны переопределить некоторые методы.

На этой странице вы увидите, как обрабатывать камбоджийский язык (кхмерский).

Представленный метод использует библиотеку PCRE (http://www.pcre.org/pcre.txt), которая включена в PHP. Это библиотека регулярных выражений, которые могут иметь много применений, среди которых поддержка специальных символов. Она может помочь вам поддерживать многие языки или «скрипты».
В текущем списке есть сценарии: Arabic, Armenian, Avestan, Balinese, Bamum, Batak, Bengali, Bopomofo, Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Chakma, Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, Devanagari, Egyptian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana, Imperial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscriptional_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah_Li, Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, Lydian, Malayalam, Mandaic, Meetei_Mayek, Meroitic_Cursive, Meroitic_Hieroglyphs, Miao, Mongolian, Myanmar, New_Tai_Lue, Nko, Ogham, Old_Italic, Old_Persian, Old_South_Arabian, Old_Turkic, Ol_Chiki, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Samaritan, Saurashtra, Sharada, Shavian, Sinhala, Sora_Sompeng, Sundanese, Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tai_Tham, Tai_Viet, Takri, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai, Yi.

Большинство этих языков обрабатываются с помощью \pL PCRE шорткодов. Рекомендуется протестировать вашу установку PrestaShop, чтобы узнать, не работает ли ваш язык по умолчанию. Если нет, вы можете протестировать список, указанный выше.

Чтобы обрабатывать камбоджийские символы, вам нужно добавить фрагмент кода PCRE, чтобы эти символы соответствовали регулярным выражениям в PrestaShop.

Этот фрагмент кода PCRE довольно прост: \p{Khmer}

Первый класс, который мы должны переопределить, находится в классе Validate . Мы работаем с методом isLinkRewrite() . Этот метод будет проверять, что строка является валидным URL (без ввода кода).

public static function isLinkRewrite($link)
{
    if (Configuration::get('PS_ALLOW_ACCENTED_CHARS_URL'))
        return preg_match('/^[_a-zA-Z0-9\-\pL\p{Khmer}]+$/u', $link);
    return preg_match('/^[_a-zA-Z0-9\-]+$/', $link);
}

Затем вам необходимо переопределить класс Tools , а более точно str2url() метод, который позволяет вам очистить строку и превратить ее в валидный и безопасный URL.

public static function str2url($str)
{
    if (function_exists('mb_strtolower'))
        $str = mb_strtolower($str, 'utf-8');
 
    if (!function_exists('mb_strtolower') || !Configuration::get('PS_ALLOW_ACCENTED_CHARS_URL'))
        $str = Tools::replaceAccentedChars($str);
 
    // Remove all non-whitelist chars.
    if (Configuration::get('PS_ALLOW_ACCENTED_CHARS_URL'))
        $str = preg_replace('/[^a-zA-Z0-9\s\'\:\/\[\]-\pL\p{Kmer}]/u''', $str);   
    else
        $str = preg_replace('/[^a-zA-Z0-9\s\'\:\/\[\]-]/','', $str);
    
    $str = preg_replace('/[\s\'\:\/\[\]-]+/'' ', $str);
    $str = str_replace(array(' ''/'), '-', $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 (!function_exists('mb_strtolower'))
        $str = strtolower($str);
 
    return $str;
}

И, наконец, вам нужно будет обновить маршруты по умолчанию из Dispatcher  класса. Это делается путем добавления следующего кода в конце Dispatcher класса, после «$this->loadRoutes();» строки:

public function __construct()
{
    // ...
    // previous code does not change
    // ...
    $this->loadRoutes();
    foreach ($this->default_routes as &$routes)
        foreach ($routes['keywords'] as &$keywords)
            $keywords['regexp'] = str_replace('\\pL''\\pL\\p{Khmer}', $keywords['regexp']);
    parent::__construct();
}

Теперь вы переопределили основные методы, и ваша инсталляция PrestaShop сможет обрабатывать камбоджийские символы в вашем URL-адресе.

Если вы хотите обрабатывать другой язык, вам просто нужно добавить новое условие к вашему регулярному выражению.

Предположим, что вместо кхмеров мы хотим поддержать язык телугу, который в основном используется в юго-центральной Индии.

Все, что нам нужно сделать, это изменить приведенный выше код и заменить каждый экземпляр \p{Khmer} with \p{Telugu}:

Например, первым переопределением будет:

public static function isLinkRewrite($link)
{
    if (Configuration::get('PS_ALLOW_ACCENTED_CHARS_URL'))
        return preg_match('/^[_a-zA-Z0-9\-\pL\p{Telugu}]+$/u', $link);
    return preg_match('/^[_a-zA-Z0-9\-]+$/', $link);
}

Предположим, что помимо кхмеров мы хотим поддержать глаголический, славянский алфавит с IX века.

В этом случае нам просто нужно повторить код PCRE с «Glagolotic», а не «Khmer».

Например, первым переопределением будет:

public static function isLinkRewrite($link)
{
    if (Configuration::get('PS_ALLOW_ACCENTED_CHARS_URL'))
        return preg_match('/^[_a-zA-Z0-9\-\pL\p{Khmer}\p{Glagolitic}]+$/u', $link);
    return preg_match('/^[_a-zA-Z0-9\-]+$/', $link);
}

Как вы можете видеть, у нас есть оба \p{Khmer} и \p{Glagolitic} в регулярном выражении, один за другим. Вы можете добавить столько языков, сколько необходимо.