You are here

protected function StringDatabaseStorage::dbStringSelect in Localization update 7.2

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 StringStorageInterface::getStrings() and these additional ones:

  • 'translation', Whether to include translation fields too. Defaults to FALSE.

Return value

SelectQuery Query object with all the tables, fields and conditions.

File

includes/locale/StringDatabaseStorage.php, line 292
Definition of StringDatabaseStorage.

Class

StringDatabaseStorage
Defines the locale string class.

Code

protected function dbStringSelect(array $conditions, array $options = array()) {

  // Change field 'customized' into 'l10n_status'. This enables the Drupal 8
  // backported code to work with the Drupal 7 style database tables.
  if (isset($conditions['customized'])) {
    $conditions['l10n_status'] = $conditions['customized'];
    unset($conditions['customized']);
  }

  // Start building the query with source table and check whether we need to
  // join the target table too.
  $query = db_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", array(
        ':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
        ->addField('t', 'plid');
      $query
        ->addField('t', 'plural');
      $query
        ->addField('t', 'language');
      $query
        ->addField('t', 'translation');
      $query
        ->addField('t', 'l10n_status', 'customized');
    }
  }

  // If we have conditions for location's type or name, then we need the
  // location table, for which we add a subquery.
  if (isset($conditions['type']) || isset($conditions['name'])) {
    $subquery = db_select('locales_location', 'l', $this->options)
      ->fields('l', array(
      'sid',
    ));
    foreach (array(
      'type',
      'name',
    ) as $field) {
      if (isset($conditions[$field])) {
        $subquery
          ->condition('l.' . $field, $conditions[$field]);
        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(db_or()
        ->condition($field_alias, $value)
        ->isNull($field_alias));
    }
    else {
      $query
        ->condition($field_alias, $value);
    }
  }

  // Process other options, string filter, query limit, etc...
  if (!empty($options['filters'])) {
    if (count($options['filters']) > 1) {
      $filter = db_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, '%' . db_like($string) . '%', 'LIKE');
    }
  }
  if (!empty($options['pager limit'])) {
    $query = $query
      ->extend('PagerDefault')
      ->limit($options['pager limit']);
  }
  return $query;
}