TYPO3 CMS  TYPO3_8-7
Helper.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 {
55  protected $repository = null;
56 
61 
66 
71 
77  public function __construct()
78  {
80  $this->objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
82  $repositoryRepository = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Domain\Repository\RepositoryRepository::class);
83  $this->extensionRepository = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository::class);
84  $this->configurationUtility = $this->objectManager->get(ConfigurationUtility::class);
86  $repository = $repositoryRepository->findByUid(1);
87  if (is_object($repository)) {
88  $this->setRepository($repository);
89  }
90  }
91 
101  public function setRepository(\TYPO3\CMS\Extensionmanager\Domain\Model\Repository $repository)
102  {
103  $this->repository = $repository;
104  }
105 
115  public function fetchExtListFile()
116  {
117  $this->fetchFile($this->getRemoteExtListFile(), $this->getLocalExtListFile());
118  }
119 
129  public function fetchMirrorListFile()
130  {
131  $this->fetchFile($this->getRemoteMirrorListFile(), $this->getLocalMirrorListFile());
132  }
133 
143  protected function fetchFile($remoteResource, $localResource)
144  {
145  if ($this->configurationUtility->getCurrentConfiguration('extensionmanager')['offlineMode']['value']) {
146  throw new ExtensionManagerException('Extension Manager is in offline mode. No TER connection available.', 1437078780);
147  }
148  if (is_string($remoteResource) && is_string($localResource) && !empty($remoteResource) && !empty($localResource)) {
149  $fileContent = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($remoteResource);
150  if ($fileContent !== false) {
151  if (\TYPO3\CMS\Core\Utility\GeneralUtility::writeFileToTypo3tempDir($localResource, $fileContent) !== null) {
152  throw new ExtensionManagerException(sprintf('Could not write to file %s.', $localResource), 1342635378);
153  }
154  } else {
155  throw new ExtensionManagerException(sprintf('Could not access remote resource %s.', $remoteResource), 1342635425);
156  }
157  }
158  }
159 
167  public function getLocalExtListFile()
168  {
169  return PATH_site . 'typo3temp/var/ExtensionManager/' . (int)$this->repository->getUid() . '.extensions.xml.gz';
170  }
171 
179  public function getRemoteExtListFile()
180  {
181  $mirror = $this->getMirrors(true)->getMirror();
182  $filePath = 'https://' . $mirror['host'] . $mirror['path'] . 'extensions.xml.gz';
183  return $filePath;
184  }
185 
193  public function getRemoteExtHashFile()
194  {
195  $mirror = $this->getMirrors(true)->getMirror();
196  $filePath = 'https://' . $mirror['host'] . $mirror['path'] . 'extensions.md5';
197  return $filePath;
198  }
199 
207  public function getLocalMirrorListFile()
208  {
209  return PATH_site . 'typo3temp/var/ExtensionManager/' . (int)$this->repository->getUid() . '.mirrors.xml.gz';
210  }
211 
219  public function getRemoteMirrorListFile()
220  {
221  $filePath = $this->repository->getMirrorListUrl();
222  return $filePath;
223  }
224 
237  public function getMirrors($forcedUpdateFromRemote = true)
238  {
239  if ($this->repository === null) {
240  throw new ExtensionManagerException('No extension repository was found.', 1523971295);
241  }
242  $assignedMirror = $this->repository->getMirrors();
243  if ($forcedUpdateFromRemote || is_null($assignedMirror) || !is_object($assignedMirror)) {
244  if ($forcedUpdateFromRemote || !is_file($this->getLocalMirrorListFile())) {
245  $this->fetchMirrorListFile();
246  }
248  $objMirrorListImporter = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extensionmanager\Utility\Importer\MirrorListUtility::class);
249  $this->repository->addMirrors($objMirrorListImporter->getMirrors($this->getLocalMirrorListFile()));
250  }
251  return $this->repository->getMirrors();
252  }
253 
263  public function isExtListUpdateNecessary()
264  {
265  if ($this->repository === null) {
266  throw new ExtensionManagerException('No extension repository was found.', 1500060252);
267  }
268  $updateNecessity = 0;
269  if ($this->extensionRepository->countByRepository($this->repository->getUid()) <= 0) {
270  $updateNecessity |= self::PROBLEM_NO_VERSIONS_IN_DATABASE;
271  }
272  if (!is_file($this->getLocalExtListFile())) {
273  $updateNecessity |= self::PROBLEM_EXTENSION_FILE_NOT_EXISTING;
274  } else {
275  $remotemd5 = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($this->getRemoteExtHashFile());
276  if ($remotemd5 !== false) {
277  $localmd5 = md5_file($this->getLocalExtListFile());
278  if ($remotemd5 !== $localmd5) {
279  $updateNecessity |= self::PROBLEM_EXTENSION_HASH_CHANGED;
280  }
281  } else {
282  throw new ExtensionManagerException('Could not retrieve extension hash file from remote server.', 1342635016);
283  }
284  }
285  return $updateNecessity;
286  }
287 
296  public function updateExtList()
297  {
298  $updated = false;
299  $updateNecessity = $this->isExtListUpdateNecessary();
300  if ($updateNecessity !== 0) {
301  // retrieval of file necessary
302  $tmpBitmask = self::PROBLEM_EXTENSION_FILE_NOT_EXISTING | self::PROBLEM_EXTENSION_HASH_CHANGED;
303  if (($tmpBitmask & $updateNecessity) > 0) {
304  $this->fetchExtListFile();
305  $updateNecessity &= ~$tmpBitmask;
306  }
307  // database table cleanup
308  if ($updateNecessity & self::PROBLEM_NO_VERSIONS_IN_DATABASE) {
309  $updateNecessity &= ~self::PROBLEM_NO_VERSIONS_IN_DATABASE;
310  } else {
311  // Use straight query as extbase "remove" is too slow here
312  // This truncates the whole table. It would be more correct to remove only rows of a specific
313  // repository, but multiple repository handling is not implemented, and truncate is quicker.
314  GeneralUtility::makeInstance(ConnectionPool::class)
315  ->getConnectionForTable('tx_extensionmanager_domain_model_extension')
316  ->truncate('tx_extensionmanager_domain_model_extension');
317  }
318  // no further problems - start of import process
319  if ($updateNecessity === 0) {
320  $uid = $this->repository->getUid();
321  /* @var $objExtListImporter \TYPO3\CMS\Extensionmanager\Utility\Importer\ExtensionListUtility */
322  $objExtListImporter = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Utility\Importer\ExtensionListUtility::class);
323  $objExtListImporter->import($this->getLocalExtListFile(), $uid);
324  $updated = true;
325  }
326  }
327  return $updated;
328  }
329 }
fetchFile($remoteResource, $localResource)
Definition: Helper.php:143
static writeFileToTypo3tempDir($filepath, $content)
static makeInstance($className,... $constructorArguments)
setRepository(\TYPO3\CMS\Extensionmanager\Domain\Model\Repository $repository)
Definition: Helper.php:101