Предположим, вам необходимо выбрать все опубликованные ноды и автор которых - суперадмин. В SQL запрос должен выглядеть так:

SELECT n.*
FROM node n
WHERE (n.status = 1 AND n.uid = 1)

Сформировать такой запрос не составит труда.

<?php
$query = db_select('node', 'n')
    ->fields('n')
    ->condition('n.status', NODE_PUBLISHED)
    ->condition('n.uid', 1);

Вдруг, внезапно вам захотелось изменить союз с AND на OR.

SELECT *
FROM node n
WHERE (n.status = 1 OR n.uid = 1)

Создать такой запрос изначально было бы не сложно. Пример:

<?php
$conditions = db_or()
    ->condition('n.status', NODE_PUBLISHED)
    ->condition('n.uid', 1);

$query = db_select('node', 'n')
    ->fields('n')
    ->condition($conditions);

Но изменить союз сложнее, если у вас уже есть готовый объект запроса. Вся проблема заключается в том, что Друпал не даёт доступ к свойству where класса SelectQuery.

Мы можем получить доступ к ключу conditions, который находится в свойстве where. От этого и будем отталкиваться.

Изменение союза

Проще всего изменить союз в массиве (дальше будем использовать переменную $query полученную в результате выполнения примера кода из блока "Создание запроса"):

<?php
$conditions = &$query->conditions();
$conditions['#conjunction'] = 'OR';

Но это стремный метод и плох он, в первую очередь, тем, что появляются вопросы:

  • А что будет если завтра Drupal решит использовать выдуманные собой названия союзов, вместо стандартных SQL-ных? Например, WHETHER вместо OR.
  • А что если изменится название ключа в котором хранится союз? Вместо #conjunction будет, например, #combination.

Вопросы, конечно, надуманные, но у меня они вызывают ощущение неправильного подхода.

Еще один способ изменения союза, на мой взгляд, более правильный. Почему этот способ лучше, я опишу в следующей статье, а сейчас пример:

<?php
// Создаём класс набора условий с союзом OR. (будем называть его класс "OR").
$or = db_or();
// Содаём ссылку на массив условий в классе с союзом OR.
$conditions = &$or->conditions();
// Копируем массив условий из запроса (будем называть условия в запросе класс "AND").
$conditions = $query->conditions();

// Для того, чтобы другие программисты понимали,
// что переменная была создана только для того,
// чтобы скопировать условия из класса "AND" в класс "OR".
unset($conditions);

// Удаление всех существующих условий в классе "AND".
$conditions = &$query->conditions();
foreach (element_children($conditions) as $idx) {
  unset($conditions[$idx]);
}

// Добавляем условия скопированные в класс "OR".
$query->condition($or);

Другие посты