Repository: Make it possible to initialize column properties lazily

refs #8826
This commit is contained in:
Johannes Meyer 2015-05-07 08:28:32 +02:00
parent ba4330de43
commit 99be358714
2 changed files with 77 additions and 34 deletions

View File

@ -230,8 +230,6 @@ class LdapUserBackend extends Repository implements UserBackendInterface
*/ */
public function select(array $columns = null) public function select(array $columns = null)
{ {
$this->initializeQueryColumns();
$query = parent::select($columns); $query = parent::select($columns);
$query->getQuery()->setBase($this->baseDn); $query->getQuery()->setBase($this->baseDn);
if ($this->filter) { if ($this->filter) {
@ -244,26 +242,28 @@ class LdapUserBackend extends Repository implements UserBackendInterface
/** /**
* Initialize this repository's query columns * Initialize this repository's query columns
* *
* @return array
*
* @throws ProgrammingError In case either $this->userNameAttribute or $this->userClass has not been set yet * @throws ProgrammingError In case either $this->userNameAttribute or $this->userClass has not been set yet
*/ */
protected function initializeQueryColumns() protected function initializeQueryColumns()
{ {
if ($this->queryColumns === null) { if ($this->userClass === null) {
if ($this->userClass === null) { throw new ProgrammingError('It is required to set the objectClass where to look for users first');
throw new ProgrammingError('It is required to set the objectClass where to look for users first'); }
} if ($this->userNameAttribute === null) {
if ($this->userNameAttribute === null) { throw new ProgrammingError('It is required to set a attribute name where to find a user\'s name first');
throw new ProgrammingError('It is required to set a attribute name where to find a user\'s name first'); }
}
$this->queryColumns[$this->userClass] = array( return array(
$this->userClass => array(
'user' => $this->userNameAttribute, 'user' => $this->userNameAttribute,
'user_name' => $this->userNameAttribute, 'user_name' => $this->userNameAttribute,
'is_active' => 'unknown', // msExchUserAccountControl == 2/512/514? <- AD LDAP 'is_active' => 'unknown', // msExchUserAccountControl == 2/512/514? <- AD LDAP
'created_at' => 'whenCreated', // That's AD LDAP, 'created_at' => 'whenCreated', // That's AD LDAP,
'last_modified' => 'whenChanged' // what's OpenLDAP? 'last_modified' => 'whenChanged' // what's OpenLDAP?
); )
} );
} }
/** /**

View File

@ -121,14 +121,6 @@ abstract class Repository implements Selectable
$this->aliasColumnMap = array(); $this->aliasColumnMap = array();
$this->init(); $this->init();
if ($this->filterColumns === null) {
$this->filterColumns = $this->getFilterColumns();
}
if ($this->sortRules === null) {
$this->sortRules = $this->getSortRules();
}
} }
/** /**
@ -187,7 +179,7 @@ abstract class Repository implements Selectable
public function getBaseTable() public function getBaseTable()
{ {
if ($this->baseTable === null) { if ($this->baseTable === null) {
$queryColumns = $this->queryColumns; // Copy because of reset() $queryColumns = $this->getQueryColumns();
reset($queryColumns); reset($queryColumns);
$this->baseTable = key($queryColumns); $this->baseTable = key($queryColumns);
if (is_int($this->baseTable) || !is_array($queryColumns[$this->baseTable])) { if (is_int($this->baseTable) || !is_array($queryColumns[$this->baseTable])) {
@ -198,31 +190,81 @@ abstract class Repository implements Selectable
return $this->baseTable; return $this->baseTable;
} }
/**
* Return the query columns being provided
*
* Calls $this->initializeQueryColumns() in case $this->queryColumns is null.
*
* @return array
*/
public function getQueryColumns()
{
if ($this->queryColumns === null) {
$this->queryColumns = $this->initializeQueryColumns();
}
return $this->queryColumns;
}
/**
* Overwrite this in your repository implementation in case you need to initialize the query columns lazily
*
* @return array
*/
protected function initializeQueryColumns()
{
return array();
}
/** /**
* 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->initializeFilterColumns() in case $this->filterColumns is null.
*
* @return array * @return array
*/ */
public function getFilterColumns() public function getFilterColumns()
{ {
if ($this->filterColumns !== null) { if ($this->filterColumns === null) {
return $this->filterColumns; $this->filterColumns = $this->initializeFilterColumns();
} }
return $this->filterColumns;
}
/**
* Overwrite this in your repository implementation in case you need to initialize the filter columns lazily
*
* @return array
*/
protected function initializeFilterColumns()
{
return array(); return array();
} }
/** /**
* Return the default sort rules to be applied on a query * Return the default sort rules to be applied on a query
* *
* Calls $this->initializeSortRules() in case $this->sortRules is null.
*
* @return array * @return array
*/ */
public function getSortRules() public function getSortRules()
{ {
if ($this->sortRules !== null) { if ($this->sortRules === null) {
return $this->sortRules; $this->sortRules = $this->initializeSortRules();
} }
return $this->sortRules;
}
/**
* Overwrite this in your repository implementation in case you need to initialize the sort rules lazily
*
* @return array
*/
protected function initializeSortRules()
{
return array(); return array();
} }
@ -232,15 +274,9 @@ abstract class Repository implements Selectable
* @param array $columns The desired columns, if null all columns will be queried * @param array $columns The desired columns, if null all columns will be queried
* *
* @return RepositoryQuery * @return RepositoryQuery
*
* @throws ProgrammingError In case $this->queryColumns has not been initialized yet
*/ */
public function select(array $columns = null) public function select(array $columns = null)
{ {
if (empty($this->queryColumns)) {
throw new ProgrammingError('Repositories are required to initialize $this->queryColumns first');
}
$this->initializeAliasMaps(); $this->initializeAliasMaps();
$query = new RepositoryQuery($this); $query = new RepositoryQuery($this);
@ -250,6 +286,8 @@ abstract class Repository implements Selectable
/** /**
* Initialize $this->aliasTableMap and $this->aliasColumnMap * Initialize $this->aliasTableMap and $this->aliasColumnMap
*
* @throws ProgrammingError In case $this->queryColumns does not provide any column information
*/ */
protected function initializeAliasMaps() protected function initializeAliasMaps()
{ {
@ -257,7 +295,12 @@ abstract class Repository implements Selectable
return; return;
} }
foreach ($this->queryColumns as $table => $columns) { $queryColumns = $this->getQueryColumns();
if (empty($queryColumns)) {
throw new ProgrammingError('Repositories are required to initialize $this->queryColumns first');
}
foreach ($queryColumns as $table => $columns) {
foreach ($columns as $alias => $column) { foreach ($columns as $alias => $column) {
if (! is_string($alias)) { if (! is_string($alias)) {
$this->aliasTableMap[$column] = $table; $this->aliasTableMap[$column] = $table;
@ -297,7 +340,7 @@ abstract class Repository implements Selectable
*/ */
public function hasQueryColumn($name) public function hasQueryColumn($name)
{ {
return array_key_exists($name, $this->aliasColumnMap) && !in_array($name, $this->filterColumns); return array_key_exists($name, $this->aliasColumnMap) && !in_array($name, $this->getFilterColumns());
} }
/** /**
@ -311,7 +354,7 @@ abstract class Repository implements Selectable
*/ */
public function requireQueryColumn($name) public function requireQueryColumn($name)
{ {
if (in_array($name, $this->filterColumns)) { if (in_array($name, $this->getFilterColumns())) {
throw new QueryException(t('Filter column "%s" cannot be queried'), $name); throw new QueryException(t('Filter column "%s" cannot be queried'), $name);
} }
if (! array_key_exists($name, $this->aliasColumnMap)) { if (! array_key_exists($name, $this->aliasColumnMap)) {