Esempio n. 1
0
 /**
  * Add a sort rule for this query
  *
  * If called without a specific column, the repository's defaul sort rules will be applied.
  * This notifies the repository about each column being required as filter column.
  *
  * @param   string  $field          The name of the column by which to sort the query's result
  * @param   string  $direction      The direction to use when sorting (asc or desc, default is asc)
  * @param   bool    $ignoreDefault  Whether to ignore any default sort rules if $field is given
  *
  * @return  $this
  */
 public function order($field = null, $direction = null, $ignoreDefault = false)
 {
     $sortRules = $this->getSortRules();
     if ($field === null) {
         // Use first available sort rule as default
         if (empty($sortRules)) {
             // Return early in case of no sort defaults and no given $field
             return $this;
         }
         $sortColumns = reset($sortRules);
         if (!array_key_exists('columns', $sortColumns)) {
             $sortColumns['columns'] = array(key($sortRules));
         }
         if ($direction !== null || !array_key_exists('order', $sortColumns)) {
             $sortColumns['order'] = $direction ?: static::SORT_ASC;
         }
     } else {
         $alias = $this->repository->reassembleQueryColumnAlias($this->target, $field) ?: $field;
         if (!$ignoreDefault && array_key_exists($alias, $sortRules)) {
             $sortColumns = $sortRules[$alias];
             if (!array_key_exists('columns', $sortColumns)) {
                 $sortColumns['columns'] = array($alias);
             }
             if ($direction !== null || !array_key_exists('order', $sortColumns)) {
                 $sortColumns['order'] = $direction ?: static::SORT_ASC;
             }
         } else {
             $sortColumns = array('columns' => array($alias), 'order' => $direction);
         }
     }
     $baseDirection = strtoupper($sortColumns['order']) === static::SORT_DESC ? static::SORT_DESC : static::SORT_ASC;
     foreach ($sortColumns['columns'] as $column) {
         list($column, $specificDirection) = $this->splitOrder($column);
         if ($this->hasLimit() && $this->repository->providesValueConversion($this->target, $column)) {
             Logger::debug('Cannot order by column "%s" in repository "%s". The query is' . ' limited and applies value conversion rules on the column', $column, $this->repository->getName());
             continue;
         }
         try {
             $this->query->order($this->repository->requireFilterColumn($this->target, $column, $this), $specificDirection ?: $baseDirection);
         } catch (QueryException $_) {
             Logger::info('Cannot order by column "%s" in repository "%s"', $column, $this->repository->getName());
         }
     }
     return $this;
 }
Esempio n. 2
0
 /**
  * Validate that the given column is a valid filter target and return it or the actual name if it's an alias
  *
  * Attempts to join the given column from a different table if its association to the given table cannot be
  * verified. In case of a PostgreSQL connection and if a COLLATE SQL-instruction is part of the resolved column,
  * this applies LOWER() on the column and, if given, strtolower() on the filter's expression.
  *
  * @param   string              $table  The table where to look for the column or alias
  * @param   string              $name   The name or alias of the column to validate
  * @param   RepositoryQuery     $query  An optional query to pass as context,
  *                                      if not given the column is considered being used for a statement filter
  * @param   FilterExpression    $filter An optional filter to pass as context
  *
  * @return  string                      The given column's name
  *
  * @throws  QueryException              In case the given column is not a valid filter column
  * @throws  ProgrammingError            In case the given column is not found in $table and cannot be joined in
  */
 public function requireFilterColumn($table, $name, RepositoryQuery $query = null, FilterExpression $filter = null)
 {
     if ($name instanceof Zend_Db_Expr) {
         return $name;
     }
     $joined = false;
     if ($query === null) {
         $column = $this->requireStatementColumn($table, $name);
     } elseif ($this->validateQueryColumnAssociation($table, $name)) {
         $column = parent::requireFilterColumn($table, $name, $query, $filter);
     } else {
         $column = $this->joinColumn($name, $table, $query);
         if ($column === null) {
             if ($query !== null) {
                 // It may be an aliased Zend_Db_Expr
                 $desiredColumns = $query->getColumns();
                 if (isset($desiredColumns[$name]) && $desiredColumns[$name] instanceof Zend_Db_Expr) {
                     $column = $desiredColumns[$name];
                 }
             }
             if ($column === null) {
                 throw new ProgrammingError('Unable to find a valid table for column "%s" to join into "%s"', $name, $table);
             }
         } else {
             $joined = true;
         }
     }
     if (!empty($this->caseInsensitiveColumns)) {
         if ($joined) {
             $table = $this->findTableName($name);
         }
         if ($column === $name) {
             if ($query === null) {
                 $name = $this->reassembleStatementColumnAlias($table, $name);
             } else {
                 $name = $this->reassembleQueryColumnAlias($table, $name);
             }
         }
         if (isset($this->caseInsensitiveColumns[$table][$name])) {
             $column = 'LOWER(' . $column . ')';
             if ($filter !== null) {
                 $expression = $filter->getExpression();
                 if (is_array($expression)) {
                     $filter->setExpression(array_map('strtolower', $expression));
                 } else {
                     $filter->setExpression(strtolower($expression));
                 }
             }
         }
     }
     return $column;
 }
Esempio n. 3
0
 /**
  * Validate that the given column is a valid filter target and return it or the actual name if it's an alias
  *
  * Attempts to join the given column from a different table if its association to the given table cannot be
  * verified.
  *
  * @param   string              $table  The table where to look for the column or alias
  * @param   string              $name   The name or alias of the column to validate
  * @param   RepositoryQuery     $query  An optional query to pass as context,
  *                                      if not given the column is considered being used for a statement filter
  *
  * @return  string                      The given column's name
  *
  * @throws  QueryException              In case the given column is not a valid filter column
  */
 public function requireFilterColumn($table, $name, RepositoryQuery $query = null)
 {
     if ($query === null) {
         return $this->requireStatementColumn($table, $name);
     }
     if ($this->validateQueryColumnAssociation($table, $name)) {
         return parent::requireFilterColumn($table, $name, $query);
     }
     return $this->joinColumn($name, $table, $query);
 }
 /**
  * Validate that the given column is a valid filter target and return it or the actual name if it's an alias
  *
  * Attempts to join the given column from a different table if its association to the given table cannot be
  * verified. In case of a PostgreSQL connection and if a COLLATE SQL-instruction is part of the resolved column,
  * this applies LOWER() on the column and, if given, strtolower() on the filter's expression.
  *
  * @param   string              $table  The table where to look for the column or alias
  * @param   string              $name   The name or alias of the column to validate
  * @param   RepositoryQuery     $query  An optional query to pass as context,
  *                                      if not given the column is considered being used for a statement filter
  * @param   FilterExpression    $filter An optional filter to pass as context
  *
  * @return  string                      The given column's name
  *
  * @throws  QueryException              In case the given column is not a valid filter column
  */
 public function requireFilterColumn($table, $name, RepositoryQuery $query = null, FilterExpression $filter = null)
 {
     $joined = false;
     if ($query === null) {
         $column = $this->requireStatementColumn($table, $name);
     } elseif ($this->validateQueryColumnAssociation($table, $name)) {
         $column = parent::requireFilterColumn($table, $name, $query, $filter);
     } else {
         $column = $this->joinColumn($name, $table, $query);
         $joined = true;
     }
     if (!empty($this->caseInsensitiveColumns)) {
         if ($joined) {
             $table = $this->findTableName($name);
         }
         if ($column === $name) {
             if ($query === null) {
                 $name = $this->reassembleStatementColumnAlias($table, $name);
             } else {
                 $name = $this->reassembleQueryColumnAlias($table, $name);
             }
         }
         if (isset($this->caseInsensitiveColumns[$table][$name])) {
             $column = 'LOWER(' . $column . ')';
             if ($filter !== null) {
                 $expression = $filter->getExpression();
                 if (is_array($expression)) {
                     $filter->setExpression(array_map('strtolower', $expression));
                 } else {
                     $filter->setExpression(strtolower($expression));
                 }
             }
         }
     }
     return $column;
 }