Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
PatchRegistry.php
Go to the documentation of this file.
1 <?php
8 
12 class PatchRegistry implements \IteratorAggregate
13 {
18  private $dependents = [];
19 
23  private $patches = [];
24 
28  private $patchFactory;
29 
35  private $appliedPatches = [];
36 
40  private $patchHistory;
41 
45  private $iterator = null;
46 
50  private $reverseIterator = null;
51 
55  private $cyclomaticStack = [];
56 
62  public function __construct(PatchFactory $patchFactory, PatchHistory $patchHistory)
63  {
64  $this->patchFactory = $patchFactory;
65  $this->patchHistory = $patchHistory;
66  }
67 
73  private function registerDependents(string $patchName)
74  {
75  $dependencies = $patchName::getDependencies();
76 
77  foreach ($dependencies as $dependency) {
78  $this->dependents[$dependency][] = $patchName;
79  }
80  }
81 
88  public function registerPatch(string $patchName)
89  {
90  if ($this->patchHistory->isApplied($patchName)) {
91  $this->appliedPatches[$patchName] = $patchName;
92  $this->registerDependents($patchName);
93  return false;
94  }
95 
96  if (isset($this->patches[$patchName])) {
97  return $this->patches[$patchName];
98  }
99 
100  $this->patches[$patchName] = $patchName;
101  return $patchName;
102  }
103 
110  private function getDependentPatches(string $patch)
111  {
112  $patches = [];
113  $patchName = $patch;
114 
118  if (isset($this->dependents[$patchName])) {
119  foreach ($this->dependents[$patchName] as $dependent) {
120  if (isset($this->appliedPatches[$dependent])) {
121  $dependent = $this->appliedPatches[$dependent];
122  $patches = array_replace($patches, $this->getDependentPatches($dependent));
123  $patches[$dependent] = $dependent;
124  unset($this->appliedPatches[$dependent]);
125  }
126  }
127  }
128 
129  return $patches;
130  }
131 
136  private function getDependencies(string $patch)
137  {
138  $depInstances = [];
139  $deps = call_user_func([$patch, 'getDependencies']);
140  $this->cyclomaticStack[$patch] = true;
141 
142  foreach ($deps as $dep) {
143  if (isset($this->cyclomaticStack[$dep])) {
144  throw new \LogicException("Cyclomatic dependency during patch installation");
145  }
146 
147  $depInstance = $this->registerPatch($dep);
152  if (!$depInstance) {
153  continue;
154  }
155 
156  $depInstances = array_replace($depInstances, $this->getDependencies($this->patches[$dep]));
157  $depInstances[$depInstance] = $depInstance;
158  }
159 
160  unset($this->cyclomaticStack[$patch]);
161  return $depInstances;
162  }
163 
172  public function getReverseIterator()
173  {
174  if ($this->reverseIterator === null) {
175  $reversePatches = [];
176 
177  while (!empty($this->appliedPatches)) {
178  $patch = array_pop($this->appliedPatches);
179  $reversePatches = array_replace($reversePatches, $this->getDependentPatches($patch));
180  $reversePatches[$patch] = $patch;
181  }
182 
183  $this->reverseIterator = new \ArrayIterator($reversePatches);
184  }
185 
186  return $this->reverseIterator;
187  }
188 
196  public function getIterator()
197  {
198  if ($this->iterator === null) {
199  $installPatches = [];
200  $patchInstances = $this->patches;
201 
202  while (!empty($patchInstances)) {
203  $firstPatch = array_shift($patchInstances);
204  $deps = $this->getDependencies($firstPatch);
205 
209  foreach ($deps as $dep) {
210  unset($patchInstances[$dep]);
211  }
212 
213  $installPatches = array_replace($installPatches, $deps);
214  $installPatches[$firstPatch] = $firstPatch;
215  }
216 
217  $this->iterator = new \ArrayIterator($installPatches);
218  }
219 
220  return $this->iterator;
221  }
222 }
__construct(PatchFactory $patchFactory, PatchHistory $patchHistory)