My website is in multiple languages so an article\'s title depends on the local. But there\'s a problem: How can I search for an article in another language?
Right now,
First things first, what you have there is a SQL injection vulnerability, as you are inserting user data into an SQL fragment instead of using the key => value
format, which would result in proper queries with bound values!
Please be sure to read Cookbook > Database Access & ORM > Query Builder > Advanced Conditions for more information on how to properly build advanced conditions!
Searching by translated content, well, the Translate behavior adds a hasOne
association for each translatable field, and by default the naming scheme is TableAlias_field_translation
, so for example Ingredients_name_translation
.
The association is being contained automatically, so you can search on its content
field, which will possibly hold the translated content.
As of CakePHP 3.4.0, respectively 3.4.4, you can use the translationField()
method provided by the translate behavior, it will return the properly aliased field depending on the locale:
->where([
$this->Ingredients->translationField('name') . ' LIKE' =>
'%' . $this->request->query('k') . '%'
])
Note that before 3.4.4, translationField()
would not consider the case where the locale set matches the default locale! In that situation you would want to query against the original tables name
column, but before 3.4.4 the method would always return the content
column of the associated translation table.
See also Cookbook > Database Access & ORM > Behaviors > Translate > Querying Translated Fields
In versions before CakePHP 3.4, you'll have to build the column name yourself, like:
->where([
'Ingredients_name_translation.content LIKE' => '%' . $this->request->query['k'] . '%'
])
In the case mentioned above, where the locate set matches the default language, the Translate behavior won't contain the translation table associations, so you'd have to take appropriate measures to ensure that the correct field is being used in the conditions, based on the language in use, ie use Ingredients.name
in case the default language is being used!