A lazy-loading proxy for a result array from a fetching functionA batch can be counted or iterated over via foreach, where the batch will internally fetch results several rows at a time. This allows you to efficiently work on large result sets without loading all results in memory.
A batch can run operations for any function that supports an options array and supports the keys "offset", "limit", and "count". This is usually used with elgg_get_entities() and friends, elgg_get_annotations(), and elgg_get_metadata(). In fact, those functions will return results as batches by passing in "batch" as true.
Unlike a real array, direct access of results is not supported.
If you pass a valid PHP callback, all results will be run through that callback. You can still foreach() through the result set after. Valid PHP callbacks can be a string, an array, or a closure. http://php.net/manual/en/language.pseudo-types.php
The callback function must accept 3 arguments: an entity, the getter used, and the options used.
Results from the callback are stored in callbackResult. If the callback returns only booleans, callbackResults will be the combined result of all calls. If no entities are processed, callbackResults will be null.
If the callback returns anything else, callbackresult will be an indexed array of whatever the callback returns. If returning error handling information, you should include enough information to determine which result you're referring to.
Don't combine returning bools and returning something else.
Note that returning false will not stop the foreach.
<?php
private $results = array();
private $getter = null;
private $options = array();
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;
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;
if ($this->chunkSize <= 0) {
$this->chunkSize = 25;
}
if ($callback && is_callable($callback)) {
$batch = new \ElggBatch($getter, $options, null, $chunk_size, $inc_offset);
$all_results = null;
if (!isset($all_results)) {
} else {
$all_results = array();
}
}
$all_results =
$result && $all_results;
} else {
}
}
$this->callbackResult = $all_results;
}
}
$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);
$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++) {
}
}
if ($this->results) {
$this->chunkIndex++;
$this->resultIndex = $num_incomplete;
$this->retrievedResults += ($num_results + $num_incomplete);
if ($num_results == 0) {
return $this->getNextResultsChunk();
}
return true;
} else {
return false;
}
}
$this->incrementOffset = (bool) $increment;
}
$this->resultIndex = 0;
$this->retrievedResults = 0;
$this->processedResults = 0;
if ($this->chunkIndex == 0 || $this->limit > $this->chunkSize) {
$this->chunkIndex = 0;
$this->getNextResultsChunk();
}
}
}
return $this->processedResults;
}
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;
}
} else {
$this->resultIndex++;
}
$this->processedResults++;
}
public function valid() {
if (!is_array($this->results)) {
return false;
}
return (
$key !==
null &&
$key !==
false);
}
public function count() {
if (!is_callable($this->getter)) {
$inspector = new \Elgg\Debug\Inspector();
throw new RuntimeException("Getter is not callable: " . $inspector->describeCallable($this->getter));
}
$options = array_merge($this->options, ['count' => true]);
return call_user_func($this->getter, $options);
}
if (
$name ===
'options') {
return $this->options;
}
_elgg_services()->logger->warn(
"Read of non-existent property '$name'");
return null;
}
if (
$name ===
'options') {
}
}
}
if($guid==elgg_get_logged_in_user_guid()) $name
__construct($getter, $options, $callback=null, $chunk_size=25, $inc_offset=true)
Batches operations on any elgg_get_*() or compatible function that supports an options array.
rewind()
Implements Iterator.
__get($name)
Read a property.
setIncrementOffset($increment=true)
Increment the offset from the original options array? Setting to false is required for callbacks that...
reportIncompleteEntity(\stdClass $row)
Tell the process that an entity was incomplete during a fetch.
count()
Count the total results available at this moment.
__set($name, $value)
Write a property.
elgg_get_config($name, $site_guid=0)
Get an Elgg configuration value.
elgg_extract($key, $array, $default=null, $strict=true)
Checks for $array[$key] and returns its value if it exists, else returns $default.
elgg_deprecated_notice($msg, $dep_version, $backtrace_level=1)
Log a notice about deprecated use of a function, view, etc.
_elgg_services(\Elgg\Di\ServiceProvider $services=null)
Get the global service provider.
Specifies a countable iterator, usually of result rows from a DB.