Last active
September 29, 2015 15:23
-
-
Save damiankloip/68ee7fd2412125d17e90 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @file | |
* Contains \Drupal\Core\Entity\EntityIterator. | |
*/ | |
namespace Drupal\Core\Entity; | |
/** | |
* Provides an Iterator class for dealing with large amounts of entities | |
* but not loading them all into memory. | |
*/ | |
class EntityIterator implements \Iterator, \Countable { | |
/** | |
* The entity storage controller to load entities. | |
* | |
* @var \Drupal\Core\Entity\EntityStorageInterface | |
*/ | |
protected $entityStorage; | |
/** | |
* An array of entity IDs to iterate over. | |
* | |
* @var array | |
*/ | |
protected $entityIds; | |
/** | |
* An array of queued entityIDs, IDs are removed until rewind() is called. | |
* | |
* @var array | |
*/ | |
protected $entityIdQueue; | |
/** | |
* The Amount of cached entities to store before clearing the static cache. | |
* | |
* @var int | |
*/ | |
protected $cacheLimit; | |
/** | |
* The current array position in $entityIds. | |
* | |
* @var int | |
*/ | |
protected $current; | |
/** | |
* Currently loaded entities. | |
* | |
* @var array | |
*/ | |
protected $loadedEntities = []; | |
/** | |
* A falg indicating when all queued IDs have been claimed. | |
* | |
* @var bool | |
*/ | |
protected $allClaimed = FALSE; | |
/** | |
* Constructs an entity iterator object. | |
* | |
* @param \Drupal\Core\Entity\EntityStorageInterface $entity_controller | |
* @param array $ids | |
* @param int $cache_limit | |
*/ | |
public function __construct(EntityStorageInterface $entity_storage_controller, array $ids, $cache_limit = 50) { | |
$this->entityStorage = $entity_storage_controller; | |
// Make sure we don't use a keyed array. | |
$this->entityIds = array_values($ids); | |
$this->cacheLimit = (int) $cache_limit; | |
$this->rewind(); | |
} | |
/** | |
* Implements \Countable::count(). | |
*/ | |
public function count() { | |
return count($this->entityIds); | |
} | |
/** | |
* Implements \Iterator::current() | |
*/ | |
public function current() { | |
return $this->getEntity(); | |
} | |
/** | |
* Implements \Iterator::key() | |
*/ | |
public function key() { | |
return $this->getEntityId(); | |
} | |
/** | |
* Implements \Iterator::next() | |
*/ | |
public function next() { | |
return $this->current++; | |
} | |
/** | |
* Implements \Iterator::rewind() | |
*/ | |
public function rewind() { | |
$this->entityStorage->resetCache(); | |
$this->entityIdQueue = $this->entityIds; | |
$this->loadedEntities = []; | |
$this->current = key($this->entityIds); | |
} | |
/** | |
* Implements \Iterator::valid() | |
*/ | |
public function valid() { | |
return $this->getEntityId(); | |
} | |
/** | |
* Returns the entity ID from the value of the current $entityIds array position. | |
* | |
* @return bool | |
*/ | |
protected function getEntityId() { | |
if (isset($this->entityIds[$this->current])) { | |
return $this->entityIds[$this->current]; | |
} | |
return NULL; | |
} | |
/** | |
* Returns a loaded entity. | |
* | |
* @return \Drupal\Core\Entity\EntityInterface. | |
*/ | |
protected function getEntity() { | |
$id = $this->getEntityId(); | |
if (isset($this->loadedEntities[$id])) { | |
// Remove the loaded entity before returning. | |
$entity = $this->loadedEntities[$id]; | |
unset($this->loadedEntities[$id]); | |
return $entity; | |
} | |
if (empty($this->loadedEntities) && !$this->allClaimed) { | |
$this->loadEntities(); | |
if (isset($this->loadedEntities[$id])) { | |
// Remove the loaded entity before returning. | |
$entity = $this->loadedEntities[$id]; | |
unset($this->loadedEntities[$id]); | |
return $entity; | |
} | |
} | |
return NULL; | |
} | |
/** | |
* Loads a set of entities. | |
* | |
* This depends on the cacheLimit property. | |
*/ | |
protected function loadEntities() { | |
// Reset any previously loaded entities. | |
$this->entityStorage->resetCache(); | |
// Take the cacheLimit amount of IDs from the beginning of the array and | |
// load them. This will keep reducing the queued Ids until they are gone. It | |
// doesn't make sense to use SqlQueue or anything, as we want multiple at | |
// once. | |
$ids = array_splice($this->entityIdQueue, 0, $this->cacheLimit); | |
// If all queued IDs have been taken, set a flag. | |
if (empty($this->entityIdQueue)) { | |
$this->allClaimed = TRUE; | |
} | |
$this->loadedEntities = $this->entityStorage->loadMultiple($ids); | |
return count($this->loadedEntities); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment