Битрикс: склонение наименований товаров

Итак, вводные данные.
У нас имеется каталог, в котором размещены несколько тысяч товаров. В целях SEO-оптимизации на страницах товаров должен быть размещен текст, содержащий наименование товара в различных падежах. Задача состоит в том, чтобы автоматизировать склонение наименований. Далее я буду рассматривать решение задачи на примере Битрикс, но оно достаточно универсально и может быть использовано в любой CMS с минимальной адаптацией.

Склонение наименований

Механизмов склонения слов может быть масса. Отмечу, что лучше всего использовать онлайн-сервисы и не городить «собственных решений», так как результаты работы последних могут иметь целый ряд ошибок. Я буду использовать «Морфер», а конкретно — его веб-сервис. Для начала нам понадобиться небольшая функция, которая сильно упростит наши дальнейшие действия. Выглядит она следующим образом:

function get_request($url, $params = NULL) {
    $ch = curl_init();
    if ($params !== NULL && !empty($params)){
        $url .= '?';
        foreach($params as $key => $value) {
            $url .= $key . '=' . curl_escape($ch, $value) . '&';
        }
        $url = rtrim($url, '&');
    }
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json'));
    $result = curl_exec($ch);
    if ($result === false) { $result = curl_error($ch); }
    $json = json_decode($result);
    curl_close($ch);
    return $json;
}

Обращение к сервису и получение результатов:

$base_url = 'https://ws3.morpher.ru';
$russian_declension = get_request("{$base_url}/russian/declension", ['s' => 'Пицца с сыром']);
$array = (array)$russian_declension;
$seoname = htmlspecialchars_decode($array['В']);

Массив в переменной $array в данном случае будет следующим:

Array
(
    [Р] => Пиццы с сыром
    [Д] => Пицце с сыром
    [В] => Пиццу с сыром
    [Т] => Пиццей с сыром
    [П] => Пицце с сыром
    [множественное] => stdClass Object
        (
            [И] => Пиццы с сыром
            [Р] => Пицц с сыром
            [Д] => Пиццам с сыром
            [В] => Пиццы с сыром
            [Т] => Пиццами с сыром
            [П] => Пиццах с сыром
        )
)

В данном примере меня интересовал винительный падеж, что можно заметить по переменной $seoname, с которой я и буду работать далее. Обратите внимание, что запрос возвращает нам склонения не только единственного, но и множественного числа, правда в виде stdClass Object. Получить его значения можно так: $seoname_many = $array['множественное']->Р;

Сохранение полученных данных и ограничения

Итак, интересующие нас значения получены. Остается записать их. Дальнейший код относится сугубо к Битрикс. Добавим в инфоблок каталога новое свойство.

Заполним его следующим образом:

CIBlockElement::SetPropertyValuesEx($ELEMENT_ID, false, array($PROPERTY_CODE => $PROPERTY_VALUE));

$ELEMENT_ID — уникальный идентификатор товара.
$PROPERTY_CODE — код заполняемого свойства (в моем случае — это SEO_NAME).
$PROPERTY_VALUE — переменная, в которой содержится значение, которое нужно записать (в моем случае — это $seo_name).

И на этом можно было и закончить, но нет. Дело в том, что сервис накладывает значительные ограничения. Заявлено, что суточный лимит на запросы с одного IP-адреса не может превышать 100 обращений. При этом стоит отметить, что на самом деле он больше, по крайней мере я замечал, что счетчик то останавливается, то вовсе сбрасывается.

Получить получить остаток на день можно следующим образом:

$requests_left = get_request("{$base_url}/get_queries_left_for_today");
echo "Остаток запросов на день: {$requests_left}";

Что касается ограничений как таковых — это небольшая проблема, если у вас есть несколько дней.
Функцию-обертку лучше добавить в соответствующие файлы вашей CMS, а вот само обращение к сервису и запись результатов — разместить в шаблоне страницы товара, при этом добавив проверку заполнено ли это свойство или нет. Логика в том, что открывая страницу товара для которой еще не было заполнено SEO-наименование, посетитель сайта инициирует выполнение нашего кода и SEO-наименование заполняется. Если посетитель сайта открывает страницу, где данное свойство уже заполнено — код игнорируется.

Мониторинг процесса наполнения (сколько заполнено и сколько осталось заполнить) можно организовать либо штатными средствами вашей CMS, если она это позволяет. Либо сделать небольшой отчет, который будет проверять заполняемость необходимых полей.

UPDATE 3.05.2020.

Буквально через несколько дней после данной публикации мне снова пришлось столкнуться с похожей задачей. К сожалению, после пары запросов к «Морферу» сервис начал выдавать ошибку: превышен лимит на количество запросов в сутки, перейдите на следующий тарифный план. Пришлось искать альтернативу, на помощь пришел сервис Morphos. Сразу оговорюсь, что длительное время я его не тестировал, но пару десятков запросов через него прогнал и результатами доволен. Особенно, учитывая тот факт, что сервис совершенно бесплатный и не имеет никаких ограничений.

Основные возможности Morphos:

  • склонение имён людей (Фамилия, Имя, Отчество)
  • склонение географических названий (Страны/Города)
  • склонение в единственном и множественном числах существительных
  • генерация имен числительных из чисел (количественные и порядковые)
  • генерация текстом денежных сумм и временных интервалов

Через API функционал несколько скромнее и позволяет склонять только имена и географические названия. При этом стоит сказать, что данный сервис не универсален, то есть склонение фразы «Пицца с сыром» не будет работать в нем корректно.

Пример запроса к Morphos:

$name = "Иванов Иван";
$json = file_get_contents("http://morphos.io/api/inflect-name?name=".$name."&_format=json");
$out = json_decode($json);
//соберем элементы массива в строку
$names = implode(", ", $out->cases);

Массив $json выглядит следующим образом:

{
    "name": "Иванов иван",
    "cases": [
        "Иванов Иван",
        "Иванова Ивана",
        "Иванову Ивану",
        "Иванова Ивана",
        "Ивановым Иваном",
        "Иванове Иване"
    ],
    "gender": "m"
}

 

Опубликовано: 25 апреля 2020 года, в рубрике «Битрикс».

2
Оставить комментарий

5000
  Подписаться  
сначала новые сначала старые
Уведомление о
MadLord

Привет, Денис! Лайк за статейку. Скажи а через прокси нельзя обойти ограничения по лимитам? И можешь ли помочь доделать один замечательный сайтик?

Поблагодарить автора статьи
Зачем это нужно