Как запросить переведенный контент при использовании поведения перевода?

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

Прямо сейчас, единственный способ - набрать название на английском, чтобы cakePHP, например, получило имя на французском. Я не могу найти его по-французски.

Например: когда я ищу "Hello", я нахожу статью "Bonjour", но когда я ищу "Bonjour", я не могу найти ни одной статьи.

Так как мне искать на другом языке? Похоже, что Cakephp сначала ищет язык по умолчанию, чтобы потом получить традукции.

В моем контроллере:

$this->Ingredients->locale('fr_CA');
$data = $this->Ingredients->find('all')
->select([
    'Ingredients.id',
    'Ingredients.name'
])
->where(["Ingredients.name LIKE '%".$this->request->query['k']."%'"])
->order('Ingredients.recipe_count');

1 ответ

Решение

SQL-инъекции!

Прежде всего, у вас есть уязвимость, связанная с внедрением SQL, так как вы вставляете пользовательские данные в фрагмент SQL вместо использования key => value формат, который приведет к правильным запросам со связанными значениями!

Обязательно прочтите Кулинарную книгу> Доступ к базе данных и ORM >;; Построитель запросов> Расширенные условия для получения дополнительной информации о том, как правильно создавать расширенные условия!

Поиск переведенного контента

При поиске по переведенному контенту, поведение "Перевести" добавляет hasOne ассоциация для каждого переводимого поля, и по умолчанию схема именования TableAlias_field_translation так например Ingredients_name_translation,

Ассоциация содержится автоматически, поэтому вы можете искать на ее content поле, которое, возможно, будет содержать переведенный контент.

Начиная с CakePHP 3.4.0, соответственно 3.4.4, вы можете использовать translationField() метод, предоставленный поведением translate, он будет возвращать правильно псевдоним поля в зависимости от локали:

->where([
    $this->Ingredients->translationField('name') . ' LIKE' =>
        '%' . $this->request->query('k') . '%'
])

Обратите внимание, что до 3.4.4, translationField() не будет рассматривать случай, когда набор локалей соответствует локали по умолчанию! В этой ситуации вы хотите запросить исходные таблицы name столбец, но до 3.4.4 метод всегда будет возвращать content столбец связанной таблицы перевода.

См. Также Поваренная книга> Доступ к базе данных и ORM > Поведения> Перевести> Запрос переведенных полей

В версиях, предшествующих CakePHP 3.4, вам придется самостоятельно создавать имя столбца, например:

->where([
    'Ingredients_name_translation.content LIKE' => '%' . $this->request->query['k'] . '%'
])

В упомянутом выше случае, когда набор локаций соответствует языку по умолчанию, поведение Translate не будет содержать ассоциаций таблиц перевода, поэтому вам нужно будет принять соответствующие меры, чтобы убедиться, что в условиях используется правильное поле на основе на используемом языке, т.е. использовать Ingredients.name в случае использования языка по умолчанию!

Другие вопросы по тегам