function DatabaseCondition::compile

Implements QueryConditionInterface::compile().

Throws

InvalidQueryConditionOperatorException

Overrides QueryConditionInterface::compile

File

includes/database/query.inc, line 1825

Class

DatabaseCondition
Generic class for a series of conditions in a query.

Code

public function compile(DatabaseConnection $connection, QueryPlaceholderInterface $queryPlaceholder) {
    // Re-compile if this condition changed or if we are compiled against a
    // different query placeholder object.
    if ($this->changed || isset($this->queryPlaceholderIdentifier) && $this->queryPlaceholderIdentifier != $queryPlaceholder->uniqueIdentifier()) {
        $this->queryPlaceholderIdentifier = $queryPlaceholder->uniqueIdentifier();
        $condition_fragments = array();
        $arguments = array();
        $conditions = $this->conditions;
        $conjunction = $conditions['#conjunction'];
        unset($conditions['#conjunction']);
        foreach ($conditions as $condition) {
            if (empty($condition['operator'])) {
                // This condition is a literal string, so let it through as is.
                $condition_fragments[] = ' (' . $condition['field'] . ') ';
                $arguments += $condition['value'];
            }
            else {
                // It's a structured condition, so parse it out accordingly.
                // Note that $condition['field'] will only be an object for a dependent
                // DatabaseCondition object, not for a dependent subquery.
                if ($condition['field'] instanceof QueryConditionInterface) {
                    // Compile the sub-condition recursively and add it to the list.
                    $condition['field']->compile($connection, $queryPlaceholder);
                    $condition_fragments[] = '(' . (string) $condition['field'] . ')';
                    $arguments += $condition['field']->arguments();
                }
                else {
                    // If the operator contains an invalid character, throw an
                    // exception to protect against SQL injection attempts.
                    if (stripos($condition['operator'], 'UNION') !== FALSE || strpbrk($condition['operator'], '[-\'"();') !== FALSE) {
                        throw new InvalidQueryConditionOperatorException('Invalid characters in query operator: ' . $condition['operator']);
                    }
                    // For simplicity, we treat all operators as the same data structure.
                    // In the typical degenerate case, this won't get changed.
                    $operator_defaults = array(
                        'prefix' => '',
                        'postfix' => '',
                        'delimiter' => '',
                        'operator' => $condition['operator'],
                        'use_value' => TRUE,
                    );
                    $operator = $connection->mapConditionOperator($condition['operator']);
                    if (!isset($operator)) {
                        $operator = $this->mapConditionOperator($condition['operator']);
                    }
                    $operator += $operator_defaults;
                    $placeholders = array();
                    if ($condition['value'] instanceof SelectQueryInterface) {
                        $condition['value']->compile($connection, $queryPlaceholder);
                        $placeholders[] = (string) $condition['value'];
                        $arguments += $condition['value']->arguments();
                        // Subqueries are the actual value of the operator, we don't
                        // need to add another below.
                        $operator['use_value'] = FALSE;
                    }
                    elseif (!$operator['delimiter']) {
                        $condition['value'] = array(
                            $condition['value'],
                        );
                    }
                    if ($operator['use_value']) {
                        foreach ($condition['value'] as $value) {
                            $placeholder = ':db_condition_placeholder_' . $queryPlaceholder->nextPlaceholder();
                            $arguments[$placeholder] = $value;
                            $placeholders[] = $placeholder;
                        }
                    }
                    $condition_fragments[] = ' (' . $connection->escapeField($condition['field']) . ' ' . $operator['operator'] . ' ' . $operator['prefix'] . implode($operator['delimiter'], $placeholders) . $operator['postfix'] . ') ';
                }
            }
        }
        $this->changed = FALSE;
        $this->stringVersion = implode($conjunction, $condition_fragments);
        $this->arguments = $arguments;
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.