‪TYPO3CMS  9.5
ExtensionManagementService.php
Go to the documentation of this file.
1 <?php
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 
21 
26 {
30  protected ‪$downloadQueue;
31 
35  protected ‪$dependencyUtility;
36 
40  protected ‪$installUtility;
41 
46 
50  protected ‪$downloadUtility;
51 
55  protected ‪$automaticInstallationEnabled = true;
56 
60  protected ‪$skipDependencyCheck = false;
61 
65  public function ‪injectDownloadQueue(\‪TYPO3\CMS\Extensionmanager\Domain\Model\DownloadQueue ‪$downloadQueue)
66  {
67  $this->downloadQueue = ‪$downloadQueue;
68  }
69 
73  public function ‪injectDependencyUtility(\‪TYPO3\CMS\Extensionmanager\Utility\DependencyUtility ‪$dependencyUtility)
74  {
75  $this->dependencyUtility = ‪$dependencyUtility;
76  }
77 
81  public function ‪injectInstallUtility(\‪TYPO3\CMS\Extensionmanager\Utility\InstallUtility ‪$installUtility)
82  {
83  $this->installUtility = ‪$installUtility;
84  }
85 
89  public function ‪injectExtensionModelUtility(\‪TYPO3\CMS\Extensionmanager\Utility\ExtensionModelUtility ‪$extensionModelUtility)
90  {
91  $this->extensionModelUtility = ‪$extensionModelUtility;
92  }
93 
97  public function ‪injectDownloadUtility(\‪TYPO3\CMS\Extensionmanager\Utility\DownloadUtility ‪$downloadUtility)
98  {
99  $this->downloadUtility = ‪$downloadUtility;
100  }
101 
105  public function ‪markExtensionForInstallation($extensionKey)
106  {
107  // We have to check for dependencies of the extension first, before marking it for installation
108  // because this extension might have dependencies, which need to be installed first
109  $this->installUtility->reloadAvailableExtensions();
110  $extension = $this->‪getExtension($extensionKey);
111  $this->dependencyUtility->checkDependencies($extension);
112  $this->downloadQueue->addExtensionToInstallQueue($extension);
113  }
114 
121  public function ‪markExtensionForCopy($extensionKey, $sourceFolder)
122  {
123  $this->downloadQueue->addExtensionToCopyQueue($extensionKey, $sourceFolder);
124  }
125 
131  public function ‪markExtensionForDownload(‪Extension $extension)
132  {
133  // We have to check for dependencies of the extension first, before marking it for download
134  // because this extension might have dependencies, which need to be downloaded and installed first
135  $this->dependencyUtility->checkDependencies($extension);
136  if (!$this->dependencyUtility->hasDependencyErrors()) {
137  $this->downloadQueue->addExtensionToQueue($extension);
138  }
139  }
140 
144  public function ‪markExtensionForUpdate(Extension $extension)
145  {
146  // We have to check for dependencies of the extension first, before marking it for download
147  // because this extension might have dependencies, which need to be downloaded and installed first
148  $this->dependencyUtility->checkDependencies($extension);
149  $this->downloadQueue->addExtensionToQueue($extension, 'update');
150  }
151 
158  {
159  $this->skipDependencyCheck = ‪$skipDependencyCheck;
160  }
161 
166  {
167  $this->automaticInstallationEnabled = (bool)‪$automaticInstallationEnabled;
168  }
169 
176  public function ‪installExtension(‪Extension $extension)
177  {
178  $this->‪downloadExtension($extension);
179  if (!$this->‪checkDependencies($extension)) {
180  return false;
181  }
182 
183  $downloadedDependencies = [];
184  $updatedDependencies = [];
185  $installQueue = [];
186 
187  // First resolve all dependencies and the sub-dependencies until all queues are empty as new extensions might be
188  // added each time
189  // Extensions have to be installed in reverse order. Extensions which were added at last are dependencies of
190  // earlier ones and need to be available before
191  while (!$this->downloadQueue->isCopyQueueEmpty()
192  || !$this->downloadQueue->isQueueEmpty('download')
193  || !$this->downloadQueue->isQueueEmpty('update')
194  ) {
195  // First copy all available extension
196  // This might change other queues again
197  $copyQueue = $this->downloadQueue->resetExtensionCopyStorage();
198  if (!empty($copyQueue)) {
199  $this->‪copyDependencies($copyQueue);
200  }
201  $installQueue = array_merge($this->downloadQueue->resetExtensionInstallStorage(), $installQueue);
202  // Get download and update information
203  $queue = $this->downloadQueue->resetExtensionQueue();
204  if (!empty($queue['download'])) {
205  $downloadedDependencies = array_merge($downloadedDependencies, $this->‪downloadDependencies($queue['download']));
206  }
207  $installQueue = array_merge($this->downloadQueue->resetExtensionInstallStorage(), $installQueue);
208  if ($this->automaticInstallationEnabled) {
209  if (!empty($queue['update'])) {
210  $this->‪downloadDependencies($queue['update']);
211  $updatedDependencies = array_merge($updatedDependencies, $this->‪uninstallDependenciesToBeUpdated($queue['update']));
212  }
213  $installQueue = array_merge($this->downloadQueue->resetExtensionInstallStorage(), $installQueue);
214  }
215  }
216 
217  // If there were any dependency errors we have to abort here
218  if ($this->dependencyUtility->hasDependencyErrors()) {
219  return false;
220  }
221 
222  // Attach extension to install queue
223  $this->downloadQueue->addExtensionToInstallQueue($extension);
224  $installQueue += $this->downloadQueue->resetExtensionInstallStorage();
225  $installedDependencies = [];
226  if ($this->automaticInstallationEnabled) {
227  $installedDependencies = $this->‪installDependencies($installQueue);
228  }
229 
230  return array_merge($downloadedDependencies, $updatedDependencies, $installedDependencies);
231  }
232 
238  public function ‪getDependencyErrors()
239  {
240  return $this->dependencyUtility->getDependencyErrors();
241  }
242 
248  public function ‪getExtension($extensionKey)
249  {
250  return $this->extensionModelUtility->mapExtensionArrayToModel(
251  $this->installUtility->enrichExtensionWithDetails($extensionKey)
252  );
253  }
254 
261  public function ‪isAvailable($extensionKey)
262  {
263  return $this->installUtility->isAvailable($extensionKey);
264  }
265 
273  public function ‪reloadPackageInformation($extensionKey)
274  {
275  $this->installUtility->reloadPackageInformation($extensionKey);
276  }
277 
283  protected function ‪downloadExtension(‪Extension $extension)
284  {
285  $this->‪downloadMainExtension($extension);
286  $this->‪setInExtensionRepository($extension->‪getExtensionKey());
287  }
288 
295  protected function ‪checkDependencies(‪Extension $extension)
296  {
297  $this->dependencyUtility->setSkipDependencyCheck($this->skipDependencyCheck);
298  $this->dependencyUtility->checkDependencies($extension);
299 
300  return !$this->dependencyUtility->hasDependencyErrors();
301  }
302 
310  protected function ‪setInExtensionRepository($extensionKey)
311  {
313  $path = $paths[$this->downloadUtility->getDownloadPath()];
314  $localExtensionStorage = $path . $extensionKey . '/Initialisation/Extensions/';
315  $this->dependencyUtility->setLocalExtensionStorage($localExtensionStorage);
316  }
317 
323  protected function ‪copyDependencies(array $copyQueue)
324  {
325  $installPaths = ‪Extension::returnAllowedInstallPaths();
326  foreach ($copyQueue as $extensionKey => $sourceFolder) {
327  $destination = $installPaths['Local'] . $extensionKey;
328  GeneralUtility::mkdir($destination);
329  GeneralUtility::copyDirectory($sourceFolder . $extensionKey, $destination);
330  $this->‪markExtensionForInstallation($extensionKey);
331  $this->downloadQueue->removeExtensionFromCopyQueue($extensionKey);
332  }
333  }
334 
342  protected function ‪uninstallDependenciesToBeUpdated(array $updateQueue)
343  {
344  $resolvedDependencies = [];
345  foreach ($updateQueue as $extensionToUpdate) {
346  $this->installUtility->uninstall($extensionToUpdate->getExtensionKey());
347  $resolvedDependencies['updated'][$extensionToUpdate->getExtensionKey()] = $extensionToUpdate;
348  }
349  return $resolvedDependencies;
350  }
351 
358  protected function ‪installDependencies(array $installQueue)
359  {
360  if (empty($installQueue)) {
361  return [];
362  }
363  $this->‪emitWillInstallExtensionsSignal($installQueue);
364  $resolvedDependencies = [];
365  $this->installUtility->install(...array_keys($installQueue));
366  foreach ($installQueue as $extensionKey => $_) {
367  $this->‪emitHasInstalledExtensionSignal($extensionKey);
368  if (!isset($resolvedDependencies['installed']) || !is_array($resolvedDependencies['installed'])) {
369  $resolvedDependencies['installed'] = [];
370  }
371  $resolvedDependencies['installed'][$extensionKey] = $extensionKey;
372  }
373  return $resolvedDependencies;
374  }
375 
383  protected function ‪downloadDependencies(array ‪$downloadQueue)
384  {
385  $resolvedDependencies = [];
386  foreach (‪$downloadQueue as $extensionToDownload) {
387  $this->downloadUtility->download($extensionToDownload);
388  $this->downloadQueue->removeExtensionFromQueue($extensionToDownload);
389  $resolvedDependencies['downloaded'][$extensionToDownload->getExtensionKey()] = $extensionToDownload;
390  $this->‪markExtensionForInstallation($extensionToDownload->getExtensionKey());
391  }
392  return $resolvedDependencies;
393  }
394 
401  public function ‪getAndResolveDependencies(‪Extension $extension)
402  {
403  $this->dependencyUtility->setSkipDependencyCheck($this->skipDependencyCheck);
404  $this->dependencyUtility->checkDependencies($extension);
405  $installQueue = $this->downloadQueue->getExtensionInstallStorage();
406  if (is_array($installQueue) && !empty($installQueue)) {
407  $installQueue = ['install' => $installQueue];
408  }
409  return array_merge($this->downloadQueue->getExtensionQueue(), $installQueue);
410  }
411 
419  public function ‪downloadMainExtension(‪Extension $extension)
420  {
421  // The extension object has a uid if the extension is not present in the system
422  // or an update of a present extension is triggered.
423  if ($extension->‪getUid()) {
424  $this->downloadUtility->download($extension);
425  }
426  }
427 
431  protected function ‪emitWillInstallExtensionsSignal(array $installQueue)
432  {
433  $this->‪getSignalSlotDispatcher()->‪dispatch(__CLASS__, 'willInstallExtensions', [$installQueue]);
434  }
435 
440  protected function ‪emitHasInstalledExtensionSignal($extensionKey)
441  {
442  $this->‪getSignalSlotDispatcher()->‪dispatch(__CLASS__, 'hasInstalledExtensions', [$extensionKey]);
443  }
444 
450  protected function ‪getSignalSlotDispatcher()
451  {
452  if (!isset($this->signalSlotDispatcher)) {
453  $this->signalSlotDispatcher = GeneralUtility::makeInstance(ObjectManager::class)
454  ->get(Dispatcher::class);
455  }
457  }
458 }
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\injectDownloadQueue
‪injectDownloadQueue(\TYPO3\CMS\Extensionmanager\Domain\Model\DownloadQueue $downloadQueue)
Definition: ExtensionManagementService.php:58
‪TYPO3\CMS\Extensionmanager\Domain\Model\Extension\returnAllowedInstallPaths
‪static array returnAllowedInstallPaths()
Definition: Extension.php:449
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\copyDependencies
‪copyDependencies(array $copyQueue)
Definition: ExtensionManagementService.php:316
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\emitWillInstallExtensionsSignal
‪emitWillInstallExtensionsSignal(array $installQueue)
Definition: ExtensionManagementService.php:424
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\checkDependencies
‪bool checkDependencies(Extension $extension)
Definition: ExtensionManagementService.php:288
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\injectDependencyUtility
‪injectDependencyUtility(\TYPO3\CMS\Extensionmanager\Utility\DependencyUtility $dependencyUtility)
Definition: ExtensionManagementService.php:66
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\injectExtensionModelUtility
‪injectExtensionModelUtility(\TYPO3\CMS\Extensionmanager\Utility\ExtensionModelUtility $extensionModelUtility)
Definition: ExtensionManagementService.php:82
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\injectInstallUtility
‪injectInstallUtility(\TYPO3\CMS\Extensionmanager\Utility\InstallUtility $installUtility)
Definition: ExtensionManagementService.php:74
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\setSkipDependencyCheck
‪setSkipDependencyCheck($skipDependencyCheck)
Definition: ExtensionManagementService.php:150
‪TYPO3\CMS\Extensionmanager\Domain\Model\Extension
Definition: Extension.php:24
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\uninstallDependenciesToBeUpdated
‪array uninstallDependenciesToBeUpdated(array $updateQueue)
Definition: ExtensionManagementService.php:335
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\markExtensionForDownload
‪markExtensionForDownload(Extension $extension)
Definition: ExtensionManagementService.php:124
‪TYPO3
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\$downloadQueue
‪TYPO3 CMS Extensionmanager Domain Model DownloadQueue $downloadQueue
Definition: ExtensionManagementService.php:29
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\$dependencyUtility
‪TYPO3 CMS Extensionmanager Utility DependencyUtility $dependencyUtility
Definition: ExtensionManagementService.php:33
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\$skipDependencyCheck
‪bool $skipDependencyCheck
Definition: ExtensionManagementService.php:53
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\markExtensionForUpdate
‪markExtensionForUpdate(Extension $extension)
Definition: ExtensionManagementService.php:137
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\setAutomaticInstallationEnabled
‪setAutomaticInstallationEnabled($automaticInstallationEnabled)
Definition: ExtensionManagementService.php:158
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\getSignalSlotDispatcher
‪Dispatcher getSignalSlotDispatcher()
Definition: ExtensionManagementService.php:443
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\setInExtensionRepository
‪setInExtensionRepository($extensionKey)
Definition: ExtensionManagementService.php:303
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\markExtensionForInstallation
‪markExtensionForInstallation($extensionKey)
Definition: ExtensionManagementService.php:98
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\downloadDependencies
‪array downloadDependencies(array $downloadQueue)
Definition: ExtensionManagementService.php:376
‪TYPO3\CMS\Extensionmanager\Service
Definition: ExtensionManagementService.php:2
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\$downloadUtility
‪TYPO3 CMS Extensionmanager Utility DownloadUtility $downloadUtility
Definition: ExtensionManagementService.php:45
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\injectDownloadUtility
‪injectDownloadUtility(\TYPO3\CMS\Extensionmanager\Utility\DownloadUtility $downloadUtility)
Definition: ExtensionManagementService.php:90
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\installExtension
‪bool array installExtension(Extension $extension)
Definition: ExtensionManagementService.php:169
‪TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject\getUid
‪int getUid()
Definition: AbstractDomainObject.php:62
‪TYPO3\CMS\Extensionmanager\Domain\Model\Extension\getExtensionKey
‪string getExtensionKey()
Definition: Extension.php:261
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\reloadPackageInformation
‪reloadPackageInformation($extensionKey)
Definition: ExtensionManagementService.php:266
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\installDependencies
‪array installDependencies(array $installQueue)
Definition: ExtensionManagementService.php:351
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher\dispatch
‪mixed dispatch($signalClassName, $signalName, array $signalArguments=[])
Definition: Dispatcher.php:115
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\$extensionModelUtility
‪TYPO3 CMS Extensionmanager Utility ExtensionModelUtility $extensionModelUtility
Definition: ExtensionManagementService.php:41
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\$automaticInstallationEnabled
‪bool $automaticInstallationEnabled
Definition: ExtensionManagementService.php:49
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\isAvailable
‪bool isAvailable($extensionKey)
Definition: ExtensionManagementService.php:254
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\markExtensionForCopy
‪markExtensionForCopy($extensionKey, $sourceFolder)
Definition: ExtensionManagementService.php:114
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\$installUtility
‪TYPO3 CMS Extensionmanager Utility InstallUtility $installUtility
Definition: ExtensionManagementService.php:37
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\getAndResolveDependencies
‪array getAndResolveDependencies(Extension $extension)
Definition: ExtensionManagementService.php:394
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService
Definition: ExtensionManagementService.php:26
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:22
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\getDependencyErrors
‪array getDependencyErrors()
Definition: ExtensionManagementService.php:231
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\downloadExtension
‪downloadExtension(Extension $extension)
Definition: ExtensionManagementService.php:276
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\getExtension
‪Extension getExtension($extensionKey)
Definition: ExtensionManagementService.php:241
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Extensionmanager\Domain\Model\Extension\returnInstallPaths
‪static array returnInstallPaths()
Definition: Extension.php:433
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\emitHasInstalledExtensionSignal
‪emitHasInstalledExtensionSignal($extensionKey)
Definition: ExtensionManagementService.php:433
‪TYPO3\CMS\Extbase\Object\ObjectManager
Definition: ObjectManager.php:25
‪$signalSlotDispatcher
‪$signalSlotDispatcher
Definition: ext_localconf.php:6
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService\downloadMainExtension
‪downloadMainExtension(Extension $extension)
Definition: ExtensionManagementService.php:412
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher
Definition: Dispatcher.php:28