/**
  * Filter the query for list.
  *
  * @param \SelectQuery $query
  *   The query object.
  *
  * @throws BadRequestException
  *
  * @see \RestfulEntityBase::getQueryForList
  */
 protected function queryForListFilter(\SelectQuery $query)
 {
     foreach ($this->parseRequestForListFilter() as $filter) {
         /* @var ResourceFieldDbColumnInterface $filter_field */
         if (!($filter_field = $this->fieldDefinitions->get($filter['public_field']))) {
             continue;
         }
         $column_name = $filter_field->getColumnForQuery();
         if (in_array(strtoupper($filter['operator'][0]), array('IN', 'NOT IN', 'BETWEEN'))) {
             $query->condition($column_name, $filter['value'], $filter['operator'][0]);
             continue;
         }
         $condition = db_condition($filter['conjunction']);
         for ($index = 0; $index < count($filter['value']); $index++) {
             $condition->condition($column_name, $filter['value'][$index], $filter['operator'][$index]);
         }
         $query->condition($condition);
     }
 }
 /**
  * Creates a database query condition for a given search filter.
  *
  * Used as a helper method in createDbQuery().
  *
  * @param \Drupal\search_api\Query\FilterInterface $filter
  *   The filter for which a condition should be created.
  * @param array $fields
  *   Internal information about the index's fields.
  * @param \Drupal\Core\Database\Query\SelectInterface $db_query
  *   The database query to which the condition will be added.
  * @param \Drupal\search_api\IndexInterface $index
  *   The index we're searching on.
  *
  * @return \Drupal\Core\Database\Query\ConditionInterface|null
  *   The condition to set on the query, or NULL if none is necessary.
  *
  * @throws \Drupal\search_api\SearchApiException
  *   Thrown if an unknown field was used in the filter.
  */
 protected function createFilterCondition(FilterInterface $filter, array $fields, SelectInterface $db_query, IndexInterface $index)
 {
     $cond = db_condition($filter->getConjunction());
     $empty = TRUE;
     // Store whether a JOIN already occurred for a field, so we don't JOIN
     // repeatedly for OR filters.
     $first_join = array();
     // Store the table aliases for the fields in this condition group.
     $tables = array();
     foreach ($filter->getFilters() as $f) {
         if (is_object($f)) {
             $c = $this->createFilterCondition($f, $fields, $db_query, $index);
             if ($c) {
                 $empty = FALSE;
                 $cond->condition($c);
             }
         } else {
             $empty = FALSE;
             // We don't index the datasource explicitly, so this needs a bit of
             // magic.
             // @todo Index the datasource explicitly so this doesn't need magic.
             if ($f[0] === 'search_api_datasource') {
                 $alias = $this->getTableAlias(array('table' => $this->configuration['index_tables'][$index->id()]), $db_query);
                 // @todo Stop recognizing "!=" as an operator.
                 $operator = $f[2] == '<>' || $f[2] == '!=' ? 'NOT LIKE' : 'LIKE';
                 $prefix = Utility::createCombinedId($f[1], '');
                 $cond->condition($alias . '.item_id', db_like($prefix) . '%', $operator);
                 continue;
             }
             if (!isset($fields[$f[0]])) {
                 throw new SearchApiException(SafeMarkup::format('Unknown field in filter clause: @field.', array('@field' => $f[0])));
             }
             $field = $fields[$f[0]];
             // Fields have their own table, so we have to check for NULL values in
             // a special way (i.e., check for missing entries in that table).
             // @todo This can probably always use the denormalized table.
             if ($f[1] === NULL) {
                 $query = $this->database->select($field['table'], 't')->fields('t', array('item_id'));
                 $cond->condition('t.item_id', $query, $f[2] == '<>' || $f[2] == '!=' ? 'IN' : 'NOT IN');
                 continue;
             }
             if (Utility::isTextType($field['type'])) {
                 $keys = $this->prepareKeys($f[1]);
                 $query = $this->createKeysQuery($keys, array($f[0] => $field), $fields, $index);
                 // We don't need the score, so we remove it. The score might either be
                 // an expression or a field.
                 $query_expressions =& $query->getExpressions();
                 if ($query_expressions) {
                     $query_expressions = array();
                 } else {
                     $query_fields =& $query->getFields();
                     unset($query_fields['score']);
                     unset($query_fields);
                 }
                 unset($query_expressions);
                 $cond->condition('t.item_id', $query, $f[2] == '<>' || $f[2] == '!=' ? 'NOT IN' : 'IN');
             } else {
                 $new_join = $filter->getConjunction() == 'AND' || empty($first_join[$f[0]]);
                 if ($new_join || empty($tables[$f[0]])) {
                     $tables[$f[0]] = $this->getTableAlias($field, $db_query, $new_join);
                     $first_join[$f[0]] = TRUE;
                 }
                 $column = $tables[$f[0]] . '.' . 'value';
                 if ($f[1] !== NULL) {
                     $cond->condition($column, $f[1], $f[2]);
                 } else {
                     $method = $f[2] == '=' ? 'isNull' : 'isNotNull';
                     $cond->{$method}($column);
                 }
             }
         }
     }
     return $empty ? NULL : $cond;
 }
/**
 * Build the SQL WHERE clause OR condition from the various condition arrays
 * Alias of `db_conditionOR()`
 *
 * @param array $cond [,$cond2,$cond3,...] The condition array(s), for example
 *
 *     array(
 *       'fieldName1'    => $value1,
 *       'fieldName2 >=' => $value2,
 *       'fieldName3     => NULL
 *     )
 *
 * ### Operators allowed in condition array
 *     >, >=, <, <=, !=, between, nbetween, like, like%%, like%~, like~%, nlike, nlike%%, nlike%~, nlike~%
 *
 * @return string The built condition WHERE clause
 */
function db_or($cond = array())
{
    $conditions = func_get_args();
    $builtCond = array();
    foreach ($conditions as $c) {
        $builtCond[] = db_condition($c, 'OR');
    }
    return implode(' OR ', $builtCond);
}
 /**
  * Filter the query for list.
  *
  * @param \SelectQuery $query
  *   The query object.
  *
  * @throws \RestfulBadRequestException
  *
  * @see \RestfulEntityBase::getQueryForList
  */
 protected function queryForListFilter(\SelectQuery $query) {
   $public_fields = $this->getPublicFields();
   foreach ($this->parseRequestForListFilter() as $filter) {
     if (in_array(strtoupper($filter['operator'][0]), array('IN', 'BETWEEN'))) {
       $column_name = $this->getPropertyColumnForQuery($public_fields[$filter['public_field']]);
       $query->condition($column_name, $filter['value'], $filter['operator'][0]);
       continue;
     }
     $condition = db_condition($filter['conjunction']);
     for ($index = 0; $index < count($filter['value']); $index++) {
       $column_name = $this->getPropertyColumnForQuery($public_fields[$filter['public_field']]);
       $condition->condition($column_name, $filter['value'][$index], $filter['operator'][$index]);
     }
     $query->condition($condition);
   }
 }
 /**
  * Generate a slug of human-readable keywords
  *
  * @param string        $string     Text to slug
  * @param string        $table      Table name to check in. If it is empty, no check in the table
  * @param string|array  $condition  Condition to append table check-in, e.g,
  *   `fieldName != value` or `array('fieldName !=' => value)`
  *
  * @return string The generated slug
  */
 function _slug($string, $table = '', $condition = null)
 {
     $specChars = array('`', '~', '!', '@', '#', '$', '%', '\\^', '&', '*', '(', ')', '=', '+', '{', '}', '[', ']', ':', ';', "'", '"', '<', '>', '\\', '|', '?', '/', ',');
     $table = ltrim($table, db_prefix());
     $slug = strtolower(trim($string));
     $slug = trim($slug, '-');
     # clear special characters
     $slug = preg_replace('/(&amp;|&quot;|&#039;|&lt;|&gt;)/i', '', $slug);
     $slug = str_replace($specChars, '-', $slug);
     $slug = str_replace(array(' ', '.'), '-', $slug);
     if (is_array($condition)) {
         $condition = db_condition($condition);
     }
     while (1 && $table) {
         $sql = 'SELECT slug FROM ' . $table . ' WHERE slug = ":alias"';
         if ($condition) {
             $sql .= ' AND ' . $condition;
         }
         if ($result = db_query($sql, array(':alias' => $slug))) {
             if (db_numRows($result) == 0) {
                 break;
             }
             $segments = explode('-', $slug);
             if (sizeof($segments) > 1 && is_numeric($segments[sizeof($segments) - 1])) {
                 $index = array_pop($segments);
                 $index++;
             } else {
                 $index = 1;
             }
             $segments[] = $index;
             $slug = implode('-', $segments);
         }
     }
     $slug = preg_replace('/[\\-]+/', '-', $slug);
     return trim($slug, '-');
 }