Skip to content

Instantly share code, notes, and snippets.

@damiankloip
Created July 21, 2016 07:41
Show Gist options
  • Save damiankloip/cd80165084dfc3c65e08d836965571ab to your computer and use it in GitHub Desktop.
Save damiankloip/cd80165084dfc3c65e08d836965571ab to your computer and use it in GitHub Desktop.
<?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 ChunkedIterator implements \IteratorAggregate, \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;
/**
* The size of each chunk of loaded entities.
*
* This will also be the amount of cached entities stored before clearing the
* static cache.
*
* @var int
*/
protected $chunkSize;
/**
* @var \Closure
*/
protected $closure;
/**
* Constructs an entity iterator object.
*
* @param \Drupal\Core\Entity\EntityStorageInterface $entity_controller
* @param array $ids
* @param int $chunk_size
*/
public function __construct(EntityStorageInterface $entity_storage_controller, array $ids, $chunk_size = 50) {
// Create a clone of the storage controller so the static cache of the
// actual storage controller remains intact.
$this->entityStorage = clone $entity_storage_controller;
// Make sure we don't use a keyed array.
$this->entityIds = array_values($ids);
$this->chunkSize = (int) $chunk_size;
}
/**
* Implements \Countable::count().
*/
public function count() {
return count($this->entityIds);
}
/**
* Implements \IteratorAggregate::GetIterator()
*/
public function getIterator() {
foreach (array_chunk($this->entityIds, $this->chunkSize) as $ids_chunk) {
foreach ($this->loadEntities($ids_chunk) as $id => $entity) {
yield $id => $entity;
}
}
}
/**
* Loads a set of entities.
*
* This depends on the cacheLimit property.
*/
protected function loadEntities(array $ids) {
// Reset any previously loaded entities then load the current set of IDs.
$this->resetCache();
return $this->entityStorage->loadMultiple($ids);
}
/**
* Resets the entity storage static cache.
*/
protected function resetCache() {
$closure = $this->getClosure();
$closure();
}
/**
* Gets the closure bound to the entity storage.
*
* @return \Closure
*/
protected function getClosure() {
if (!isset($this->closure)) {
$this->closure = function () {
$this->entities = [];
};
$this->closure->bindTo($this->entityStorage);
}
return $this->closure;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment