예제 #1
0
 /**
  * Implements Drupal\Core\Database\Query\ConditionInterface::compile().
  */
 public function compile(Connection $connection, PlaceholderInterface $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 ConditionInterface) {
                     // 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 {
                     // 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);
                     // Remove potentially dangerous characters.
                     // If something passed in an invalid character stop early, so we
                     // don't rely on a broken SQL statement when we would just replace
                     // those characters.
                     if (stripos($condition['operator'], 'UNION') !== FALSE || strpbrk($condition['operator'], '[-\'"();') !== FALSE) {
                         $this->changed = TRUE;
                         $this->arguments = [];
                         // Provide a string which will result into an empty query result.
                         $this->stringVersion = '( AND 1 = 0 )';
                         // Conceptually throwing an exception caused by user input is bad
                         // as you result into a WSOD, which depending on your webserver
                         // configuration can result into the assumption that your site is
                         // broken.
                         // On top of that the database API relies on __toString() which
                         // does not allow to throw exceptions.
                         trigger_error('Invalid characters in query operator: ' . $condition['operator'], E_USER_ERROR);
                         return;
                     }
                     $operator = $connection->mapConditionOperator($condition['operator']);
                     if (!isset($operator)) {
                         $operator = $this->mapConditionOperator($condition['operator']);
                     }
                     $operator += $operator_defaults;
                     $placeholders = array();
                     if ($condition['value'] instanceof SelectInterface) {
                         $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'] && !is_array($condition['value'])) {
                         $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;
     }
 }
예제 #2
0
 /**
  * Implements Drupal\Core\Database\Query\ConditionInterface::compile().
  */
 public function compile(Connection $connection, PlaceholderInterface $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 ConditionInterface) {
                     // 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 {
                     // 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 SelectInterface) {
                         $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'] && !is_array($condition['value'])) {
                         $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;
     }
 }