[Решено] Баг с icl_get_string_id + icl_register_string
Эта тема решена. Вот описание проблемы и ее решения.
Проблема: Клиент столкнулся с проблемой, где функция icl_get_string_id всегда возвращает 0 после первого вызова, что приводит к повторному добавлению перевода через API, если строка уже зарегистрирована. Решение: Мы рекомендуем использовать доступные хуки WPML для регистрации строк и переводов, чтобы избежать подобных проблем. Для регистрации строки следует использовать хук
Если данное решение окажется неактуальным или не подходит под ваш случай, мы настоятельно рекомендуем проверить связанные известные проблемы по ссылке https://wpml.org/known-issues/, убедиться в версии исправления и подтвердить, что у вас установлены последние версии тем и плагинов. Если проблема сохраняется, пожалуйста, откройте новый тикет в службе поддержки WPML.
Это форум технической поддержки WPML – плагина для многоязычной WordPress.
Доступно для чтения всем, но только клиенты, купившие WPML, могут оставлять сообщения. Сотрудники WPML отвечают на сообщения форума 6 дней в неделю, 22 часов в сутки.
Предыстория вопроса:
Я пытаюсь массово перевести названия стран. Для переводов решил использовать стратегию проверять с помощью icl_get_string_id есть ли уже зарегистрированная строчка для перевода, если есть, то добавляю программно перевод через icl_register_string. Проблема возникает в функции get_translated_string, где после первого вызова icl_get_string_id id кэшируется и всегда 0, если строчка не найдена. Если попытаться еще раз получить ид строчки, то всегда будет возвращаться 0, и я всегда буду пытаться по новой перевести строчку через API и по новой пытаться добавить перевод. Код функции: private function get_translated_string($text, $lang = 'ru') { $string_name = $text; $string_id = icl_get_string_id($text, $this->text_domain, $string_name); if (!$string_id) { $this->log_to_CLI(''); $this->log_to_CLI(sprintf('%s not found string', $string_id)); $string_id = icl_register_string($this->text_domain, $string_name, $text); $this->log_to_CLI(sprintf('%s Registered string: %s', $string_id, $text)); $translated_text = $this->translate_text($text, $lang); icl_add_string_translation($string_id, $lang, $translated_text, ICL_TM_COMPLETE); $this->log_to_CLI(sprintf('%s -> %s', $text, $translated_text)); return $translated_text; } return apply_filters('wpml_translate_single_string', $text, $this->text_domain, $string_name, $lang); } public function test() { $data = ['Vatican', 'Ukraine', 'Tanzania', 'USA', 'Vatican', 'Ukraine', 'Tanzania', 'USA']; foreach ($data as $str) { $translated = $this->get_translated_string($str, 'ru'); } WP_CLI::success('ok'); }
Симптомы:
После первого вызова функции icl_get_string_id id кэшируется и всегда 0, если строчка не найдена.
Вопросы:
Почему icl_get_string_id всегда возвращает 0 после первого вызова?
Как избежать повторного добавления перевода через API, если строка уже зарегистрирована?
Я не могу потвердить, если же это баг, так как Вы используете внутреннюю функцию WPML в своем пользовательском коде, она может не отрабатывать так, как ожидаете. Для таких целей Вам необходимо использовать доступные хуки WPML, которые Вы можете просмотреть здесь: https://wpml.org/documentation/support/wpml-coding-api/wpml-hooks-reference/
Если есть необходимость перевода контента в пользовательских таблицах базы данных, тогда да.
есть какие-то тогда легальные варианты регистрировать строчку и переводы для нее?
или получается можно зарегистрировать строчки как в гайде выше и потом через translation management автоматически перевести?
Да, все верно понимаете. Для регистрации строки Вам необходимо использовать хук wpml_register_string (https://wpml.org/wpml-hook/wpml_register_string/). На данный момент, нет возможности программной регистрации перевода. Но, есть возможность перевода автоматически или вручную.