TYPO3  7.6
CoreInstaller.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Composer\Installer;
3 
4 /***************************************************************
5  * Copyright notice
6  *
7  * (c) 2014 Christian Opitz <christian.opitz at netresearch.de>
8  * All rights reserved
9  *
10  * This script is part of the TYPO3 project. The TYPO3 project is
11  * free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * The GNU General Public License can be found at
17  * http://www.gnu.org/copyleft/gpl.html.
18  *
19  * This script is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * This copyright notice MUST APPEAR in all copies of the script!
25  ***************************************************************/
26 
29 
36 class CoreInstaller implements \Composer\Installer\InstallerInterface {
37 
38  const TYPO3_DIR = 'typo3';
39  const TYPO3_INDEX_PHP = 'index.php';
40 
41  protected $symlinks = array();
42 
46  protected $composer;
47 
51  protected $downloadManager;
52 
56  protected $filesystem;
57 
62 
66  protected $pluginConfig;
67 
72  public function __construct(\Composer\Composer $composer, Filesystem $filesystem, CoreInstaller\GetTypo3OrgService $getTypo3OrgService) {
73  $this->composer = $composer;
74  $this->downloadManager = $composer->getDownloadManager();
75  $this->filesystem = $filesystem;
76  $this->getTypo3OrgService = $getTypo3OrgService;
77  $this->initializeConfiguration();
78  $this->initializeSymlinks();
79  }
80 
84  protected function initializeConfiguration() {
85  $this->pluginConfig = Config::load($this->composer);
86  }
87 
91  protected function initializeSymlinks() {
92  $webDir = $this->filesystem->normalizePath($this->pluginConfig->get('web-dir'));
93  $this->filesystem->ensureDirectoryExists($webDir);
94  $backendDir = $this->filesystem->normalizePath($this->pluginConfig->get('backend-dir'));
95  $sourcesDir = $this->determineInstallPath();
96  $this->symlinks = array(
97  $sourcesDir . DIRECTORY_SEPARATOR . self::TYPO3_INDEX_PHP
98  => $webDir . DIRECTORY_SEPARATOR . self::TYPO3_INDEX_PHP,
99  $sourcesDir . DIRECTORY_SEPARATOR . self::TYPO3_DIR
100  => $backendDir
101  );
102  }
103 
110  public function supports($packageType) {
111  return $packageType === 'typo3-cms-core';
112  }
113 
122  public function isInstalled(\Composer\Repository\InstalledRepositoryInterface $repo, \Composer\Package\PackageInterface $package) {
123  return $repo->hasPackage($package)
124  && is_readable($this->getInstallPath($package))
125  && $this->filesystem->allFilesExist($this->symlinks);
126  }
127 
134  public function install(\Composer\Repository\InstalledRepositoryInterface $repo, \Composer\Package\PackageInterface $package) {
135  $this->getTypo3OrgService->addDistToPackage($package);
136 
137  if ($this->filesystem->someFilesExist($this->symlinks)) {
138  $this->filesystem->removeSymlinks($this->symlinks);
139  }
140 
141  $this->installCode($package);
142 
143  $this->filesystem->establishSymlinks($this->symlinks, FALSE);
144 
145  if (!$repo->hasPackage($package)) {
146  $repo->addPackage(clone $package);
147  }
148  }
149 
157  public function update(\Composer\Repository\InstalledRepositoryInterface $repo, \Composer\Package\PackageInterface $initial, \Composer\Package\PackageInterface $target) {
158  $this->getTypo3OrgService->addDistToPackage($initial);
159  $this->getTypo3OrgService->addDistToPackage($target);
160 
161  if ($this->filesystem->someFilesExist($this->symlinks)) {
162  $this->filesystem->removeSymlinks($this->symlinks);
163  }
164 
165  $this->updateCode($initial, $target);
166 
167  $this->filesystem->establishSymlinks($this->symlinks, FALSE);
168 
169  $repo->removePackage($initial);
170  if (!$repo->hasPackage($target)) {
171  $repo->addPackage(clone $target);
172  }
173  }
174 
181  public function uninstall(\Composer\Repository\InstalledRepositoryInterface $repo, \Composer\Package\PackageInterface $package) {
182  if (!$repo->hasPackage($package)) {
183  throw new \InvalidArgumentException('Package is not installed: '.$package);
184  }
185 
186  if ($this->filesystem->someFilesExist($this->symlinks)) {
187  $this->filesystem->removeSymlinks($this->symlinks);
188  }
189 
190  $this->removeCode($package);
191  $repo->removePackage($package);
192  }
193 
200  public function getInstallPath(\Composer\Package\PackageInterface $package) {
201  return $this->determineInstallPath();
202  }
203 
207  protected function determineInstallPath() {
208  return $this->pluginConfig->get('cms-package-dir');
209  }
210 
214  protected function installCode(\Composer\Package\PackageInterface $package) {
215  $downloadPath = $this->getInstallPath($package);
216  $this->downloadManager->download($package, $downloadPath);
217  }
218 
223  protected function updateCode(\Composer\Package\PackageInterface $initial, \Composer\Package\PackageInterface $target) {
224  // Currently the install path for all versions is the same.
225  // In the future the install path for two core versions may differ.
226  $initialDownloadPath = $this->getInstallPath($initial);
227  $targetDownloadPath = $this->getInstallPath($target);
228  if ($targetDownloadPath !== $initialDownloadPath) {
229  // if the target and initial dirs intersect, we force a remove + install
230  // to avoid the rename wiping the target dir as part of the initial dir cleanup
231  if (substr($initialDownloadPath, 0, strlen($targetDownloadPath)) === $targetDownloadPath
232  || substr($targetDownloadPath, 0, strlen($initialDownloadPath)) === $initialDownloadPath
233  ) {
234  $this->removeCode($initial);
235  $this->installCode($target);
236 
237  return;
238  }
239 
240  $this->filesystem->rename($initialDownloadPath, $targetDownloadPath);
241  }
242  $this->downloadManager->update($initial, $target, $targetDownloadPath);
243  }
244 
248  protected function removeCode(\Composer\Package\PackageInterface $package) {
249  $downloadPath = $this->getInstallPath($package);
250  $this->downloadManager->remove($package, $downloadPath);
251  }
252 }
253 
254 ?>