ok
Direktori : /home2/selectio/www/fms-worksuite/vendor/google/cloud-core/src/Iterator/ |
Current File : /home2/selectio/www/fms-worksuite/vendor/google/cloud-core/src/Iterator/PageIteratorTrait.php |
<?php /** * Copyright 2017 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace Google\Cloud\Core\Iterator; use Google\Cloud\Core\ArrayTrait; /** * This trait fulfills the * [\Iterator](http://php.net/manual/en/class.iterator.php) interface and * returns results as a page of items. */ trait PageIteratorTrait { use ArrayTrait; /** * @var array|null */ private $page; /** * @var callable */ private $resultMapper; /** * @var callable */ private $call; /** * @var array */ private $callOptions; /** * @var array */ private $config; /** * @var int */ private $position = 0; /** * @var int */ private $itemCount = 0; /** * @var array */ private $resultTokenPath; /** * @var array */ private $nextResultTokenPath; /** * @var array */ private $itemsPath; /** * @var string|null */ private $initialResultToken; /** * @param callable $resultMapper Maps a result. * @param callable $call The call to execute. * @param array $callOptions Options to use with the call. * @param array $config [optional] { * Configuration options. * * @type string $itemsKey The key for the items to iterate over from the * response. **Defaults to** `"items"`. * @type string $nextResultTokenKey The key for the next result token in * the response. **Defaults to** `"nextPageToken"`. * @type string $resultTokenKey The key for the results token set in the * request. **Defaults too** `"pageToken"`. * @type array $firstPage The first page of results. If set, this data * will be used for the first page of results instead of making * a network request. * @type callable $setNextResultTokenCondition If this condition passes * then it should be considered safe to set the token to get the * next set of results. * @type int $resultLimit Limit the number of results returned in total. * **Defaults to** `0` (return all results). * } */ public function __construct( callable $resultMapper, callable $call, array $callOptions, array $config = [] ) { $this->resultMapper = $resultMapper; $this->call = $call; $this->config = $config + [ 'itemsKey' => 'items', 'nextResultTokenKey' => 'nextPageToken', 'resultTokenKey' => 'pageToken', 'firstPage' => null, 'resultLimit' => 0, 'setNextResultTokenCondition' => function () { return true; } ]; $this->callOptions = $callOptions; $this->resultTokenPath = explode('.', $this->config['resultTokenKey']); $this->nextResultTokenPath = explode('.', $this->config['nextResultTokenKey']); $this->itemsPath = explode('.', $this->config['itemsKey']); $this->initialResultToken = $this->nextResultToken(); } /** * Fetch the token used to get the next set of results. * * @return string|null */ public function nextResultToken() { return $this->get($this->resultTokenPath, $this->callOptions); } /** * Rewind the iterator. * * @return null */ #[\ReturnTypeWillChange] public function rewind() { $this->itemCount = 0; $this->position = 0; if ($this->config['firstPage']) { list($this->page, $shouldContinue) = $this->mapResults($this->config['firstPage']); $nextResultToken = $this->determineNextResultToken($this->page, $shouldContinue); } else { $this->page = null; $nextResultToken = $this->initialResultToken; } if ($nextResultToken) { $this->set($this->resultTokenPath, $this->callOptions, $nextResultToken); } } /** * Get the current page. * * @return array|null */ #[\ReturnTypeWillChange] public function current() { if ($this->page === null) { $this->page = $this->executeCall(); } $page = $this->get($this->itemsPath, $this->page); if ($this->nextResultToken()) { return $page ?: []; } return $page; } /** * Get the key current page's key. * * @return int */ #[\ReturnTypeWillChange] public function key() { return $this->position; } /** * Advances to the next page. * * @return null */ #[\ReturnTypeWillChange] public function next() { $this->position++; $this->page = $this->nextResultToken() ? $this->executeCall() : null; } /** * Determines if the current position is valid. * * @return bool */ #[\ReturnTypeWillChange] public function valid() { if (!$this->page && $this->position) { return false; } return true; } /** * Executes the provided call to get a set of results. * * @return array */ private function executeCall() { $call = $this->call; list($results, $shouldContinue) = $this->mapResults( $call($this->callOptions) ); $this->set( $this->resultTokenPath, $this->callOptions, $this->determineNextResultToken($results, $shouldContinue) ); return $results; } /** * @param array $results * @return array */ private function mapResults(array $results) { $items = $this->get($this->itemsPath, $results); $resultMapper = $this->resultMapper; $shouldContinue = true; if ($items) { foreach ($items as $key => $item) { $items[$key] = $resultMapper($item); $this->itemCount++; if ($this->config['resultLimit'] && $this->config['resultLimit'] <= $this->itemCount) { $items = array_slice($items, 0, $key + 1); $shouldContinue = false; break; } } $this->set($this->itemsPath, $results, $items); } return [$results, $shouldContinue]; } /** * @param array $results * @param bool $shouldContinue * @return null */ private function determineNextResultToken(array $results, $shouldContinue = true) { return $shouldContinue && $this->config['setNextResultTokenCondition']($results) ? $this->get($this->nextResultTokenPath, $results) : null; } /** * @param array $path * @param array $array * @return mixed */ private function get(array $path, array $array) { $result = $array; foreach ($path as $key) { if (!isset($result[$key])) { return null; } $result = $result[$key]; } return $result; } /** * @param array $path * @param array $array * @param mixed $value * @return null */ private function set(array $path, array &$array, $value) { $temp = &$array; foreach ($path as $key) { $temp = &$temp[$key]; } $temp = $value; } }