[BUGFIX] Resolves extension dependencies recursively
[Packages/TYPO3.CMS.git] / typo3 / sysext / extensionmanager / Classes / Domain / Model / DownloadQueue.php
1 <?php
2 namespace TYPO3\CMS\Extensionmanager\Domain\Model;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException;
18
19 /**
20 * Download Queue - storage for extensions to be downloaded
21 */
22 class DownloadQueue implements \TYPO3\CMS\Core\SingletonInterface
23 {
24 /**
25 * Storage for extensions to be downloaded
26 *
27 * @var Extension[string][string]
28 */
29 protected $extensionStorage = [];
30
31 /**
32 * Storage for extensions to be installed
33 *
34 * @var array
35 */
36 protected $extensionInstallStorage = [];
37
38 /**
39 * Storage for extensions to be copied
40 *
41 * @var array
42 */
43 protected $extensionCopyStorage = [];
44
45 /**
46 * @var \TYPO3\CMS\Extensionmanager\Utility\ListUtility
47 */
48 protected $listUtility;
49
50 /**
51 * @param \TYPO3\CMS\Extensionmanager\Utility\ListUtility $listUtility
52 */
53 public function injectListUtility(\TYPO3\CMS\Extensionmanager\Utility\ListUtility $listUtility)
54 {
55 $this->listUtility = $listUtility;
56 }
57
58 /**
59 * Adds an extension to the download queue.
60 * If the extension was already requested in a different version
61 * an exception is thrown.
62 *
63 * @param \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension
64 * @param string $stack
65 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
66 * @return void
67 */
68 public function addExtensionToQueue(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension, $stack = 'download')
69 {
70 if (!is_string($stack) || !in_array($stack, ['download', 'update'])) {
71 throw new ExtensionManagerException('Stack has to be either "download" or "update"', 1342432103);
72 }
73 if (!isset($this->extensionStorage[$stack])) {
74 $this->extensionStorage[$stack] = [];
75 }
76 if (array_key_exists($extension->getExtensionKey(), $this->extensionStorage[$stack])) {
77 if ($this->extensionStorage[$stack][$extension->getExtensionKey()] !== $extension) {
78 throw new ExtensionManagerException(
79 $extension->getExtensionKey() . ' was requested to be downloaded in different versions (' . $extension->getVersion()
80 . ' and ' . $this->extensionStorage[$stack][$extension->getExtensionKey()]->getVersion() . ').',
81 1342432101
82 );
83 }
84 }
85 $this->extensionStorage[$stack][$extension->getExtensionKey()] = $extension;
86 }
87
88 /**
89 * @return array
90 */
91 public function getExtensionQueue()
92 {
93 return $this->extensionStorage;
94 }
95
96 /**
97 * Remove an extension from download queue
98 *
99 * @param \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension
100 * @param string $stack Stack to remove extension from (download, update or install)
101 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
102 * @return void
103 */
104 public function removeExtensionFromQueue(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension, $stack = 'download')
105 {
106 if (!is_string($stack) || !in_array($stack, ['download', 'update'])) {
107 throw new ExtensionManagerException('Stack has to be either "download" or "update"', 1342432104);
108 }
109 if (array_key_exists($stack, $this->extensionStorage) && is_array($this->extensionStorage[$stack])) {
110 if (array_key_exists($extension->getExtensionKey(), $this->extensionStorage[$stack])) {
111 unset($this->extensionStorage[$stack][$extension->getExtensionKey()]);
112 }
113 }
114 }
115
116 /**
117 * Adds an extension to the install queue for later installation
118 *
119 * @param Extension $extension
120 * @return void
121 */
122 public function addExtensionToInstallQueue($extension)
123 {
124 $this->extensionInstallStorage[$extension->getExtensionKey()] = $extension;
125 }
126
127 /**
128 * Removes an extension from the install queue
129 *
130 * @param string $extensionKey
131 * @return void
132 */
133 public function removeExtensionFromInstallQueue($extensionKey)
134 {
135 if (array_key_exists($extensionKey, $this->extensionInstallStorage)) {
136 unset($this->extensionInstallStorage[$extensionKey]);
137 }
138 }
139
140 /**
141 * Adds an extension to the copy queue for later copying
142 *
143 * @param string $extensionKey
144 * @param string $sourceFolder
145 * @return void
146 */
147 public function addExtensionToCopyQueue($extensionKey, $sourceFolder)
148 {
149 $this->extensionCopyStorage[$extensionKey] = $sourceFolder;
150 }
151
152 /**
153 * Remove an extension from extension copy storage
154 *
155 * @param $extensionKey
156 * @return void
157 */
158 public function removeExtensionFromCopyQueue($extensionKey)
159 {
160 if (array_key_exists($extensionKey, $this->extensionCopyStorage)) {
161 unset($this->extensionCopyStorage[$extensionKey]);
162 }
163 }
164
165 /**
166 * Gets the extension installation queue
167 *
168 * @return array
169 */
170 public function getExtensionInstallStorage()
171 {
172 return $this->extensionInstallStorage;
173 }
174
175 /**
176 * Gets the extension copy queue
177 *
178 * @return array
179 */
180 public function getExtensionCopyStorage()
181 {
182 return $this->extensionCopyStorage;
183 }
184
185 /**
186 * Return whether the queue contains extensions or not
187 *
188 * @param string $stack
189 * @return bool
190 */
191 public function isQueueEmpty($stack = 'download')
192 {
193 return empty($this->extensionStorage[$stack]);
194 }
195
196 /**
197 * Return whether the copy queue contains extensions or not
198 *
199 * @return bool
200 */
201 public function isCopyQueueEmpty()
202 {
203 return empty($this->extensionCopyStorage);
204 }
205
206 /**
207 * Return whether the install queue contains extensions or not
208 *
209 * @return bool
210 */
211 public function isInstallQueueEmpty()
212 {
213 return empty($this->extensionInstallStorage);
214 }
215
216 /**
217 * Resets the extension queue and returns old extensions
218 *
219 * @param string|null $stack if null, all stacks are reset
220 * @return array
221 */
222 public function resetExtensionQueue($stack = null)
223 {
224 $storage = [];
225 if ($stack === null) {
226 $storage = $this->extensionStorage;
227 $this->extensionStorage = [];
228 } elseif (isset($this->extensionStorage[$stack])) {
229 $storage = $this->extensionStorage[$stack];
230 $this->extensionStorage[$stack] = [];
231 }
232
233 return $storage;
234 }
235
236 /**
237 * Resets the copy queue and returns the old extensions
238 * @return array
239 */
240 public function resetExtensionCopyStorage()
241 {
242 $storage = $this->extensionCopyStorage;
243 $this->extensionCopyStorage = [];
244
245 return $storage;
246 }
247
248 /**
249 * Resets the install queue and returns the old extensions
250 * @return array
251 */
252 public function resetExtensionInstallStorage()
253 {
254 $storage = $this->extensionInstallStorage;
255 $this->extensionInstallStorage = [];
256
257 return $storage;
258 }
259 }