function StringDatabaseStorage::dbStringSelect
Same name in other branches
- 8.9.x core/modules/locale/src/StringDatabaseStorage.php \Drupal\locale\StringDatabaseStorage::dbStringSelect()
- 10 core/modules/locale/src/StringDatabaseStorage.php \Drupal\locale\StringDatabaseStorage::dbStringSelect()
- 11.x core/modules/locale/src/StringDatabaseStorage.php \Drupal\locale\StringDatabaseStorage::dbStringSelect()
Builds a SELECT query with multiple conditions and fields.
The query uses both 'locales_source' and 'locales_target' tables. Note that by default, as we are selecting both translated and untranslated strings target field's conditions will be modified to match NULL rows too.
Parameters
array $conditions: An associative array with field => value conditions that may include NULL values. If a language condition is included it will be used for joining the 'locales_target' table.
array $options: An associative array of additional options. It may contain any of the options used by Drupal\locale\StringStorageInterface::getStrings() and these additional ones:
- 'translation', Whether to include translation fields too. Defaults to FALSE.
Return value
\Drupal\Core\Database\Query\Select Query object with all the tables, fields and conditions.
File
-
core/
modules/ locale/ src/ StringDatabaseStorage.php, line 353
Class
- StringDatabaseStorage
- Defines a class to store localized strings in the database.
Namespace
Drupal\localeCode
protected function dbStringSelect(array $conditions, array $options = []) {
// Start building the query with source table and check whether we need to
// join the target table too.
$query = $this->connection
->select('locales_source', 's', $this->options)
->fields('s');
// Figure out how to join and translate some options into conditions.
if (isset($conditions['translated'])) {
// This is a meta-condition we need to translate into simple ones.
if ($conditions['translated']) {
// Select only translated strings.
$join = 'innerJoin';
}
else {
// Select only untranslated strings.
$join = 'leftJoin';
$conditions['translation'] = NULL;
}
unset($conditions['translated']);
}
else {
$join = !empty($options['translation']) ? 'leftJoin' : FALSE;
}
if ($join) {
if (isset($conditions['language'])) {
// If we've got a language condition, we use it for the join.
$query->{$join}('locales_target', 't', "t.lid = s.lid AND t.language = :langcode", [
':langcode' => $conditions['language'],
]);
unset($conditions['language']);
}
else {
// Since we don't have a language, join with locale id only.
$query->{$join}('locales_target', 't', "t.lid = s.lid");
}
if (!empty($options['translation'])) {
// We cannot just add all fields because 'lid' may get null values.
$query->fields('t', [
'language',
'translation',
'customized',
]);
}
}
// If we have conditions for location's type or name, then we need the
// location table, for which we add a subquery. We cast any scalar value to
// array so we can consistently use IN conditions.
if (isset($conditions['type']) || isset($conditions['name'])) {
$subquery = $this->connection
->select('locales_location', 'l', $this->options)
->fields('l', [
'sid',
]);
foreach ([
'type',
'name',
] as $field) {
if (isset($conditions[$field])) {
$subquery->condition('l.' . $field, (array) $conditions[$field], 'IN');
unset($conditions[$field]);
}
}
$query->condition('s.lid', $subquery, 'IN');
}
// Add conditions for both tables.
foreach ($conditions as $field => $value) {
$table_alias = $this->dbFieldTable($field);
$field_alias = $table_alias . '.' . $field;
if (is_null($value)) {
$query->isNull($field_alias);
}
elseif ($table_alias == 't' && $join === 'leftJoin') {
// Conditions for target fields when doing an outer join only make
// sense if we add also OR field IS NULL.
$query->condition($this->connection
->condition('OR')
->condition($field_alias, (array) $value, 'IN')
->isNull($field_alias));
}
else {
$query->condition($field_alias, (array) $value, 'IN');
}
}
// Process other options, string filter, query limit, etc.
if (!empty($options['filters'])) {
if (count($options['filters']) > 1) {
$filter = $this->connection
->condition('OR');
$query->condition($filter);
}
else {
// If we have a single filter, just add it to the query.
$filter = $query;
}
foreach ($options['filters'] as $field => $string) {
$filter->condition($this->dbFieldTable($field) . '.' . $field, '%' . $this->connection
->escapeLike($string) . '%', 'LIKE');
}
}
if (!empty($options['pager limit'])) {
$query = $query->extend(PagerSelectExtender::class)
->limit($options['pager limit']);
}
return $query;
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.