123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434 |
- <?php
- class ElggBatch
- implements \Iterator {
-
- private $results = array();
-
- private $getter = null;
-
- private $chunkSize = 25;
-
- private $callback = null;
-
- private $offset = 0;
-
- private $limit = 0;
-
- private $retrievedResults = 0;
-
- private $resultIndex = 0;
-
- private $chunkIndex = 0;
-
- private $processedResults = 0;
-
- private $validGetter = null;
-
- public $callbackResult = null;
-
- private $incrementOffset = true;
-
- private $incompleteEntities = array();
-
- private $totalIncompletes = 0;
-
- public function __construct($getter, $options, $callback = null, $chunk_size = 25,
- $inc_offset = true) {
-
- $this->getter = $getter;
- $this->options = $options;
- $this->callback = $callback;
- $this->chunkSize = $chunk_size;
- $this->setIncrementOffset($inc_offset);
- if ($this->chunkSize <= 0) {
- $this->chunkSize = 25;
- }
-
- $this->offset = elgg_extract('offset', $options, 0);
- $this->limit = elgg_extract('limit', $options, elgg_get_config('default_limit'));
-
-
- if ($callback && is_callable($callback)) {
- $batch = new \ElggBatch($getter, $options, null, $chunk_size, $inc_offset);
- $all_results = null;
- foreach ($batch as $result) {
- $result = call_user_func($callback, $result, $getter, $options);
- if (!isset($all_results)) {
- if ($result === true || $result === false || $result === null) {
- $all_results = $result;
- } else {
- $all_results = array();
- }
- }
- if (($result === true || $result === false || $result === null) && !is_array($all_results)) {
- $all_results = $result && $all_results;
- } else {
- $all_results[] = $result;
- }
- }
- $this->callbackResult = $all_results;
- }
- }
-
- public function reportIncompleteEntity(\stdClass $row) {
- $this->incompleteEntities[] = $row;
- }
-
- private function getNextResultsChunk() {
-
- $this->results = array();
- if (!isset($this->validGetter)) {
- $this->validGetter = is_callable($this->getter);
- }
- if (!$this->validGetter) {
- return false;
- }
- $limit = $this->chunkSize;
-
- if ($this->limit != 0) {
- if ($this->retrievedResults >= $this->limit) {
- return false;
- }
-
-
- if ($this->limit < $this->chunkSize) {
- $limit = $this->limit;
- } elseif ($this->retrievedResults + $this->chunkSize > $this->limit) {
-
- $limit = $this->limit - $this->retrievedResults;
- }
- }
- if ($this->incrementOffset) {
- $offset = $this->offset + $this->retrievedResults;
- } else {
- $offset = $this->offset + $this->totalIncompletes;
- }
- $current_options = array(
- 'limit' => $limit,
- 'offset' => $offset,
- '__ElggBatch' => $this,
- );
- $options = array_merge($this->options, $current_options);
- $this->incompleteEntities = array();
- $this->results = call_user_func($this->getter, $options);
-
- _elgg_services()->db->disableQueryCache();
- $num_results = count($this->results);
- $num_incomplete = count($this->incompleteEntities);
- $this->totalIncompletes += $num_incomplete;
- if ($this->incompleteEntities) {
-
- array_splice($this->results, 0, 0, array_pad(array(), $num_incomplete, null));
-
- reset($this->results);
- for ($i = 0; $i < $num_incomplete; $i++) {
- next($this->results);
- }
- }
- if ($this->results) {
- $this->chunkIndex++;
-
- $this->resultIndex = $num_incomplete;
- $this->retrievedResults += ($num_results + $num_incomplete);
- if ($num_results == 0) {
-
-
- return $this->getNextResultsChunk();
- }
- _elgg_services()->db->enableQueryCache();
- return true;
- } else {
- _elgg_services()->db->enableQueryCache();
- return false;
- }
- }
-
- public function setIncrementOffset($increment = true) {
- $this->incrementOffset = (bool) $increment;
- }
-
-
- public function rewind() {
- $this->resultIndex = 0;
- $this->retrievedResults = 0;
- $this->processedResults = 0;
-
- if ($this->chunkIndex == 0 || $this->limit > $this->chunkSize) {
- $this->chunkIndex = 0;
- $this->getNextResultsChunk();
- }
- }
-
- public function current() {
- return current($this->results);
- }
-
- public function key() {
- return $this->processedResults;
- }
-
- public function next() {
-
- if (($this->processedResults + 1) >= $this->limit && $this->limit > 0) {
- $this->results = array();
- return false;
- }
-
- if (($this->resultIndex + 1) >= $this->chunkSize) {
- if (!$this->getNextResultsChunk()) {
- $this->results = array();
- return false;
- }
- $result = current($this->results);
- } else {
-
-
- $this->resultIndex++;
- $result = next($this->results);
- }
- $this->processedResults++;
- return $result;
- }
-
- public function valid() {
- if (!is_array($this->results)) {
- return false;
- }
- $key = key($this->results);
- return ($key !== null && $key !== false);
- }
- }
|