Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
MultiDimensionProvider.php
Go to the documentation of this file.
1 <?php
6 declare(strict_types=1);
7 
9 
13 class MultiDimensionProvider implements \IteratorAggregate
14 {
18  private $dimensionsIterators = [];
19 
23  private $dimensionsDataProviders = [];
24 
28  private $dimensionsProvidersCount = 0;
29 
33  public function __construct(array $dimensionProviders = [])
34  {
35  foreach ($dimensionProviders as $dimensionDataProvider) {
36  $this->addDimensionDataProvider($dimensionDataProvider);
37  }
38  }
39 
46  public function getIterator(): \Traversable
47  {
48  // just return empty array if we have no dimension providers to iterate over
49  if ($this->dimensionsProvidersCount === 0) {
50  yield [];
51  return;
52  }
53 
54  // this recreates iterators for dimension so we can iterate over them
55  $this->rewind();
56 
57  // if at leas one dimension provider has no dimensions to return we can't multiple dimension at all
58  if (!$this->hasCurrentDimension()) {
59  throw new \LogicException('Can`t multiple dimensions because some of them are empty.');
60  }
61 
62  // return dimensions until all iterators become invalid
63  while ($this->hasCurrentDimension()) {
64  yield $this->getCurrentDimension();
65  $this->setNextDimension();
66  }
67  }
68 
74  private function getCurrentDimension(): array
75  {
76  $dimensions = [];
77 
78  foreach ($this->dimensionsIterators as $dimensionIterator) {
80  $dimension = $dimensionIterator->current();
81  $dimensions[$dimension->getName()] = $dimension;
82  }
83 
84  return $dimensions;
85  }
86 
93  private function setNextDimension()
94  {
95  $this->dimensionsIterators[$this->dimensionsProvidersCount - 1]->next();
96 
97  for ($i = ($this->dimensionsProvidersCount - 1); $i > 0; $i--) {
98  if (!$this->dimensionsIterators[$i]->valid()) {
99  $this->dimensionsIterators[$i] = $this->dimensionsDataProviders[$i]->getIterator();
100  $this->dimensionsIterators[$i-1]->next();
101  }
102  }
103  }
104 
110  private function rewind()
111  {
112  $this->dimensionsIterators = [];
113 
114  foreach ($this->dimensionsDataProviders as $dimensionDataProvider) {
115  $this->dimensionsIterators[] = $dimensionDataProvider->getIterator();
116  }
117  }
118 
129  private function hasCurrentDimension(): bool
130  {
131  $valid = true;
132 
133  foreach ($this->dimensionsIterators as $dimensionsIterator) {
134  // if at least one data provider is invalid at this stage - all generator is invalid
135  if (!$dimensionsIterator->valid()) {
136  return false;
137  }
138  }
139 
140  // generator is valid only when all data providers are valid
141  return $valid;
142  }
143 
151  private function addDimensionDataProvider(DimensionProviderInterface $dimensionDataProvider)
152  {
153  $this->dimensionsDataProviders[] = $dimensionDataProvider;
154  $this->dimensionsProvidersCount++;
155  }
156 }
$i
Definition: gallery.phtml:31