Repository: Introduce query column blacklists

We can no longer use $filterColumns to blacklist query columns so
there is now another set of column names required to achieve this.

refs #9029
This commit is contained in:
Johannes Meyer 2015-08-13 14:06:27 +02:00
parent e4f331bff9
commit 4b6849eea7
5 changed files with 59 additions and 14 deletions

View File

@ -61,7 +61,7 @@ class DbUserBackend extends DbRepository implements UserBackendInterface, Inspec
* *
* @var array * @var array
*/ */
protected $filterColumns = array('user'); protected $blacklistedQueryColumns = array('user');
/** /**
* The default sort rules to be applied on a query * The default sort rules to be applied on a query

View File

@ -50,7 +50,7 @@ class LdapUserBackend extends LdapRepository implements UserBackendInterface, In
* *
* @var array * @var array
*/ */
protected $filterColumns = array('user'); protected $blacklistedQueryColumns = array('user');
/** /**
* The default sort rules to be applied on a query * The default sort rules to be applied on a query

View File

@ -71,7 +71,7 @@ class DbUserGroupBackend extends DbRepository implements UserGroupBackendInterfa
* *
* @var array * @var array
*/ */
protected $filterColumns = array('group', 'user'); protected $blacklistedQueryColumns = array('group', 'user');
/** /**
* The value conversion rules to apply on a query or statement * The value conversion rules to apply on a query or statement

View File

@ -32,7 +32,7 @@ class IniUserGroupBackend extends IniRepository implements UserGroupBackendInter
* *
* @var array * @var array
*/ */
protected $filterColumns = array('group'); protected $blacklistedQueryColumns = array('group');
/** /**
* The value conversion rules to apply on a query or statement * The value conversion rules to apply on a query or statement

View File

@ -64,17 +64,34 @@ abstract class Repository implements Selectable
* 'alias2' => 'column3' * 'alias2' => 'column3'
* ) * )
* ) * )
* <pre><code> * </code></pre>
* *
* @var array * @var array
*/ */
protected $queryColumns; protected $queryColumns;
/** /**
* The columns (or aliases) which are not permitted to be queried. (by design) * The columns (or aliases) which are not permitted to be queried
*
* Blacklisted query columns can still occur in a filter expression or sort rule.
* *
* @var array An array of strings * @var array An array of strings
*/ */
protected $blacklistedQueryColumns;
/**
* The filter columns being provided
*
* This might be intialized by concrete repository implementations, in the following format
* <pre><code>
* array(
* 'alias_or_column_name',
* 'label_to_show_in_the_filter_editor' => 'alias_or_column_name'
* )
* </code></pre>
*
* @var array
*/
protected $filterColumns; protected $filterColumns;
/** /**
@ -98,7 +115,7 @@ abstract class Repository implements Selectable
* // Ascendant sort by default * // Ascendant sort by default
* ) * )
* ) * )
* <pre><code> * </code></pre>
* Note that it's mandatory to supply the alias name in case there is one. * Note that it's mandatory to supply the alias name in case there is one.
* *
* @var array * @var array
@ -260,6 +277,33 @@ abstract class Repository implements Selectable
/** /**
* Return the columns (or aliases) which are not permitted to be queried * Return the columns (or aliases) which are not permitted to be queried
* *
* Calls $this->initializeBlacklistedQueryColumns() in case $this->blacklistedQueryColumns is null.
*
* @return array
*/
public function getBlacklistedQueryColumns()
{
if ($this->blacklistedQueryColumns === null) {
$this->blacklistedQueryColumns = $this->initializeBlacklistedQueryColumns();
}
return $this->blacklistedQueryColumns;
}
/**
* Overwrite this in your repository implementation in case you
* need to initialize the blacklisted query columns lazily
*
* @return array
*/
protected function initializeBlacklistedQueryColumns()
{
return array();
}
/**
* Return the filter columns being provided
*
* Calls $this->initializeFilterColumns() in case $this->filterColumns is null. * Calls $this->initializeFilterColumns() in case $this->filterColumns is null.
* *
* @return array * @return array
@ -781,10 +825,10 @@ abstract class Repository implements Selectable
throw new ProgrammingError('Table name "%s" not found', $table); throw new ProgrammingError('Table name "%s" not found', $table);
} }
$filterColumns = $this->getFilterColumns(); $blacklist = $this->getBlacklistedQueryColumns();
$columns = array(); $columns = array();
foreach ($queryColumns[$table] as $alias => $column) { foreach ($queryColumns[$table] as $alias => $column) {
if (! in_array(is_string($alias) ? $alias : $column, $filterColumns)) { if (! in_array(is_string($alias) ? $alias : $column, $blacklist)) {
$columns[$alias] = $column; $columns[$alias] = $column;
} }
} }
@ -874,7 +918,8 @@ abstract class Repository implements Selectable
return false; return false;
} }
return !in_array($alias, $this->getFilterColumns()) && $this->validateQueryColumnAssociation($table, $name); return !in_array($alias, $this->getBlacklistedQueryColumns())
&& $this->validateQueryColumnAssociation($table, $name);
} }
/** /**
@ -898,8 +943,8 @@ abstract class Repository implements Selectable
throw new QueryException(t('Query column "%s" not found'), $name); throw new QueryException(t('Query column "%s" not found'), $name);
} }
if (in_array($alias, $this->getFilterColumns())) { if (in_array($alias, $this->getBlacklistedQueryColumns())) {
throw new QueryException(t('Filter column "%s" cannot be queried'), $name); throw new QueryException(t('Column "%s" cannot be queried'), $name);
} }
if (! $this->validateQueryColumnAssociation($table, $alias)) { if (! $this->validateQueryColumnAssociation($table, $alias)) {
@ -985,8 +1030,8 @@ abstract class Repository implements Selectable
throw new StatementException('Statement column "%s" not found', $name); throw new StatementException('Statement column "%s" not found', $name);
} }
if (in_array($alias, $this->getFilterColumns())) { if (in_array($alias, $this->getBlacklistedQueryColumns())) {
throw new StatementException('Filter column "%s" cannot be referenced in a statement', $name); throw new StatementException('Column "%s" cannot be referenced in a statement', $name);
} }
if (! $this->validateQueryColumnAssociation($table, $alias)) { if (! $this->validateQueryColumnAssociation($table, $alias)) {