[TASK] EM: Add possibility to bypass system dependency checks 45/29845/18
authorNicole Cordes <typo3@cordes.co>
Sat, 3 May 2014 14:05:10 +0000 (16:05 +0200)
committerXavier Perseguers <xavier@typo3.org>
Wed, 11 Jun 2014 14:49:24 +0000 (16:49 +0200)
This patch adds a new action to show all unresolved dependencies and
adds the possibility to bypass all system and version checks. Required
extensions are still tried to be fetched from TER.

Resolves: #54512
Releases: 6.2
Change-Id: I11cca622875d013ab6fd385d2c659477e803f6a2
Reviewed-on: https://review.typo3.org/29845
Reviewed-by: Markus Klein
Reviewed-by: Zbigniew Jacko
Tested-by: Zbigniew Jacko
Reviewed-by: Xavier Perseguers
Tested-by: Xavier Perseguers
29 files changed:
typo3/sysext/extensionmanager/Classes/Controller/ActionController.php
typo3/sysext/extensionmanager/Classes/Controller/DownloadController.php
typo3/sysext/extensionmanager/Classes/Controller/ListController.php
typo3/sysext/extensionmanager/Classes/Controller/UploadExtensionFileController.php
typo3/sysext/extensionmanager/Classes/Exception/MissingExtensionDependencyException.php [new file with mode: 0644]
typo3/sysext/extensionmanager/Classes/Exception/MissingVersionDependencyException.php [new file with mode: 0644]
typo3/sysext/extensionmanager/Classes/Exception/UnresolvedDependencyException.php [new file with mode: 0644]
typo3/sysext/extensionmanager/Classes/Exception/UnresolvedPhpDependencyException.php [new file with mode: 0644]
typo3/sysext/extensionmanager/Classes/Exception/UnresolvedTypo3DependencyException.php [new file with mode: 0644]
typo3/sysext/extensionmanager/Classes/Service/ExtensionManagementService.php
typo3/sysext/extensionmanager/Classes/Utility/DependencyUtility.php
typo3/sysext/extensionmanager/Classes/Utility/InstallUtility.php
typo3/sysext/extensionmanager/Resources/Private/Language/locallang.xlf
typo3/sysext/extensionmanager/Resources/Private/Partials/List/UnresolvedDependencies.html [new file with mode: 0644]
typo3/sysext/extensionmanager/Resources/Private/Partials/List/UnresolvedDependencies.json [new file with mode: 0644]
typo3/sysext/extensionmanager/Resources/Private/Partials/List/UnresolvedDependenciesMessage.html [new file with mode: 0644]
typo3/sysext/extensionmanager/Resources/Private/Templates/Action/RemoveExtension.json [deleted file]
typo3/sysext/extensionmanager/Resources/Private/Templates/Download/InstallFromTer.json
typo3/sysext/extensionmanager/Resources/Private/Templates/List/UnresolvedDependencies.html [new file with mode: 0644]
typo3/sysext/extensionmanager/Resources/Private/Templates/UploadExtensionFile/Extract.json [deleted file]
typo3/sysext/extensionmanager/Resources/Private/Templates/UploadExtensionFile/Form.html
typo3/sysext/extensionmanager/Resources/Public/JavaScript/main.js
typo3/sysext/extensionmanager/Resources/Public/JavaScript/ter.js
typo3/sysext/extensionmanager/Resources/Public/JavaScript/upload.js
typo3/sysext/extensionmanager/Tests/Unit/Controller/UploadExtensionFileControllerTest.php
typo3/sysext/extensionmanager/Tests/Unit/Domain/Model/DownloadQueueTest.php
typo3/sysext/extensionmanager/Tests/Unit/Service/ExtensionManagementServiceTest.php
typo3/sysext/extensionmanager/Tests/Unit/Utility/DependencyUtilityTest.php
typo3/sysext/extensionmanager/ext_tables.php

index d01c363..3fcdc15 100644 (file)
@@ -71,15 +71,15 @@ class ActionController extends AbstractController {
                                $this->installUtility->uninstall($extensionKey);
                        } else {
                                // install
-                               $this->managementService->resolveDependenciesAndInstall(
-                                       $this->extensionModelUtility->mapExtensionArrayToModel(
-                                               $this->installUtility->enrichExtensionWithDetails($extensionKey)
-                                       )
+                               $extension = $this->extensionModelUtility->mapExtensionArrayToModel(
+                                       $this->installUtility->enrichExtensionWithDetails($extensionKey)
                                );
+                               if ($this->managementService->installExtension($extension) === FALSE) {
+                                       $this->redirect('unresolvedDependencies', 'List', NULL, array('extensionKey' => $extensionKey));
+                               }
                        }
                } catch (\TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException $e) {
-                       $message = nl2br(htmlspecialchars($e->getMessage()));
-                       $this->addFlashMessage($message, '', \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR);
+                       $this->addFlashMessage(htmlspecialchars($e->getMessage()), '', \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR);
                } catch (\TYPO3\Flow\Package\Exception\PackageStatesFileNotWritableException $e) {
                        $this->addFlashMessage(htmlspecialchars($e->getMessage()), '', \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR);
                }
@@ -87,20 +87,39 @@ class ActionController extends AbstractController {
        }
 
        /**
+        * Install an extension and omit dependency checking
+        *
+        * @param string $extensionKey
+        * @return void
+        */
+       public function installExtensionWithoutSystemDependencyCheckAction($extensionKey) {
+               $this->managementService->setSkipSystemDependencyCheck(TRUE);
+               $this->forward('toggleExtensionInstallationState', NULL, NULL, array('extensionKey' => $extensionKey));
+       }
+
+       /**
         * Remove an extension (if it is still installed, uninstall it first)
         *
         * @param string $extension
+        * @return string
         */
        protected function removeExtensionAction($extension) {
-               $success = TRUE;
-               $message = '';
                try {
                        $this->installUtility->removeExtension($extension);
+                       $this->addFlashMessage(
+                               \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate(
+                                       'extensionList.remove.message',
+                                       'extensionmanager',
+                                       array(
+                                               'extension' => $extension,
+                                       )
+                               )
+                       );
                } catch (\TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException $e) {
-                       $message = $e->getMessage();
-                       $success = FALSE;
+                       $this->addFlashMessage(htmlspecialchars($e->getMessage()), '', \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR);
                }
-               $this->view->assign('success', $success)->assign('message', $message)->assign('extension', $extension);
+
+               return '';
        }
 
        /**
index 7575be0..66153a0 100644 (file)
@@ -115,11 +115,22 @@ class DownloadController extends AbstractController {
         * @param string $downloadPath
         */
        public function installFromTerAction(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension, $downloadPath) {
-               list($result, $errorMessage) = $this->installFromTer($extension, $downloadPath);
+               list($result, $errorMessages) = $this->installFromTer($extension, $downloadPath);
                $this->view
                        ->assign('result', $result)
                        ->assign('extension', $extension)
-                       ->assign('errorMessage', $errorMessage);
+                       ->assign('unresolvedDependencies', $errorMessages);
+       }
+
+       /**
+        * Check extension dependencies with special dependencies
+        *
+        * @param \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension
+        * @throws \Exception
+        */
+       public function installExtensionWithoutSystemDependencyCheckAction(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension) {
+               $this->managementService->setSkipSystemDependencyCheck(TRUE);
+               $this->forward('installFromTer', NULL, NULL, array('extension' => $extension, 'downloadPath' => 'Local'));
        }
 
        /**
@@ -214,13 +225,21 @@ class DownloadController extends AbstractController {
         */
        protected function installFromTer(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension, $downloadPath = 'Local') {
                $result = FALSE;
-               $errorMessage = '';
+               $errorMessages = array();
                try {
                        $this->downloadUtility->setDownloadPath($downloadPath);
-                       $result = $this->managementService->resolveDependenciesAndInstall($extension);
+                       if (($result = $this->managementService->installExtension($extension)) === FALSE) {
+                               $errorMessages = $this->managementService->getDependencyErrors();
+                       }
                } catch (\TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException $e) {
-                       $errorMessage = $e->getMessage();
+                       $errorMessages = array(
+                               $extension->getExtensionKey() => array(
+                                       'code' => $e->getCode(),
+                                       'message' => $e->getMessage(),
+                               ),
+                       );
                }
-               return array($result, $errorMessage);
+
+               return array($result, $errorMessages);
        }
 }
index 44151d4..2bcd27f 100644 (file)
@@ -52,6 +52,12 @@ class ListController extends AbstractController {
        protected $pageRenderer;
 
        /**
+        * @var \TYPO3\CMS\Extensionmanager\Utility\DependencyUtility
+        * @inject
+        */
+       protected $dependencyUtility;
+
+       /**
         * Add the needed JavaScript files for all actions
         */
        public function initializeAction() {
@@ -71,6 +77,32 @@ class ListController extends AbstractController {
        }
 
        /**
+        * Shows a list of unresolved dependency errors with the possibility to bypass the dependency check
+        *
+        * @param string $extensionKey
+        * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
+        * @return void
+        */
+       public function unresolvedDependenciesAction($extensionKey) {
+               $availableExtensions = $this->listUtility->getAvailableExtensions();
+               if (isset($availableExtensions[$extensionKey])) {
+                       $extensionArray = $this->listUtility->enrichExtensionsWithEmConfAndTerInformation(
+                               array(
+                                       $extensionKey => $availableExtensions[$extensionKey]
+                               )
+                       );
+                       /** @var \TYPO3\CMS\Extensionmanager\Utility\ExtensionModelUtility $extensionModelUtility */
+                       $extensionModelUtility = $this->objectManager->get('TYPO3\\CMS\\Extensionmanager\\Utility\\ExtensionModelUtility');
+                       $extension = $extensionModelUtility->mapExtensionArrayToModel($extensionArray[$extensionKey]);
+               } else {
+                       throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException('Extension ' . $extensionKey . ' is not available', 1402421007);
+               }
+               $this->dependencyUtility->checkDependencies($extension);
+               $this->view->assign('extension', $extension);
+               $this->view->assign('unresolvedDependencies', $this->dependencyUtility->getDependencyErrors());
+       }
+
+       /**
         * Shows extensions from TER
         * Either all extensions or depending on a search param
         *
index 3eac91e..e63bb96 100644 (file)
@@ -27,6 +27,7 @@ namespace TYPO3\CMS\Extensionmanager\Controller;
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
+use TYPO3\CMS\Core\Messaging\FlashMessage;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException;
 
@@ -72,7 +73,6 @@ class UploadExtensionFileController extends AbstractController {
         * @return void
         */
        public function formAction() {
-
        }
 
        /**
@@ -83,10 +83,10 @@ class UploadExtensionFileController extends AbstractController {
         * @return void
         */
        public function extractAction($overwrite = FALSE) {
+               $file = $_FILES['tx_extensionmanager_tools_extensionmanagerextensionmanager'];
+               $fileExtension = pathinfo($file['name']['extensionFile'], PATHINFO_EXTENSION);
+               $fileName = pathinfo($file['name']['extensionFile'], PATHINFO_BASENAME);
                try {
-                       $file = $_FILES['tx_extensionmanager_tools_extensionmanagerextensionmanager'];
-                       $fileExtension = pathinfo($file['name']['extensionFile'], PATHINFO_EXTENSION);
-                       $fileName = pathinfo($file['name']['extensionFile'], PATHINFO_BASENAME);
                        if (empty($file['name']['extensionFile'])) {
                                throw new ExtensionManagerException('No file given.', 1342858852);
                        }
@@ -101,16 +101,30 @@ class UploadExtensionFileController extends AbstractController {
                                        1342864339
                                );
                        }
+
+                       // Import extension
                        if ($fileExtension === 't3x') {
                                $extensionData = $this->getExtensionFromT3xFile($tempFile, $overwrite);
                        } else {
                                $extensionData = $this->getExtensionFromZipFile($tempFile, $fileName, $overwrite);
                        }
-                       $this->view->assign('extensionKey', $extensionData['extKey']);
+                       $this->installUtility->install($extensionData['extKey']);
+                       $this->removeBackupFolder();
+                       $this->addFlashMessage(
+                               htmlspecialchars($this->translate('extensionList.uploadFlashMessage.message', array($extensionData['extKey']))),
+                               htmlspecialchars($this->translate('extensionList.uploadFlashMessage.title')),
+                               FlashMessage::OK
+                       );
+                       $this->addFlashMessage(
+                               htmlspecialchars($this->translate('extensionList.installedFlashMessage.message', array($extensionData['extKey']))),
+                               '',
+                               FlashMessage::OK
+                       );
                } catch (\Exception $exception) {
                        $this->removeExtensionAndRestoreFromBackup($fileName);
-                       $this->view->assign('error', $exception->getMessage());
+                       $this->addFlashMessage(htmlspecialchars($exception->getMessage()), '', FlashMessage::ERROR);
                }
+               $this->redirect('index', 'List', NULL, array(self::TRIGGER_RefreshModuleMenu => TRUE));
        }
 
        /**
@@ -139,8 +153,7 @@ class UploadExtensionFileController extends AbstractController {
                }
                $this->removeFromOriginalPath = TRUE;
                $this->fileHandlingUtility->unpackExtensionFromExtensionDataArray($extensionData);
-               $this->installUtility->install($extensionData['extKey']);
-               $this->removeBackupFolder();
+
                return $extensionData;
        }
 
@@ -157,7 +170,7 @@ class UploadExtensionFileController extends AbstractController {
         * @throws ExtensionManagerException
         */
        protected function getExtensionFromZipFile($file, $fileName, $overwrite = FALSE) {
-                       // Remove version and extension from filename to determine the extension key
+               // Remove version and extension from filename to determine the extension key
                $extensionKey = $this->getExtensionKeyFromFileName($fileName);
                $isExtensionAvailable = $this->installUtility->isAvailable($extensionKey);
                if (!$overwrite && $isExtensionAvailable) {
@@ -168,8 +181,6 @@ class UploadExtensionFileController extends AbstractController {
                }
                $this->removeFromOriginalPath = TRUE;
                $this->fileHandlingUtility->unzipExtensionFromFile($file, $extensionKey);
-               $this->installUtility->install($extensionKey);
-               $this->removeBackupFolder();
 
                return array('extKey' => $extensionKey);
        }
diff --git a/typo3/sysext/extensionmanager/Classes/Exception/MissingExtensionDependencyException.php b/typo3/sysext/extensionmanager/Classes/Exception/MissingExtensionDependencyException.php
new file mode 100644 (file)
index 0000000..9ea4c56
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+namespace TYPO3\CMS\Extensionmanager\Exception;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2014 Nicole Cordes <typo3@cordes.co>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * An exception when some dependency is unresolved
+ *
+ * @author Nicole Cordes <typo3@cordes.co>
+ */
+class MissingExtensionDependencyException extends UnresolvedDependencyException {
+
+}
diff --git a/typo3/sysext/extensionmanager/Classes/Exception/MissingVersionDependencyException.php b/typo3/sysext/extensionmanager/Classes/Exception/MissingVersionDependencyException.php
new file mode 100644 (file)
index 0000000..8bdc09a
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+namespace TYPO3\CMS\Extensionmanager\Exception;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2014 Nicole Cordes <typo3@cordes.co>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * An exception when some dependency is unresolved
+ *
+ * @author Nicole Cordes <typo3@cordes.co>
+ */
+class MissingVersionDependencyException extends UnresolvedDependencyException {
+
+}
diff --git a/typo3/sysext/extensionmanager/Classes/Exception/UnresolvedDependencyException.php b/typo3/sysext/extensionmanager/Classes/Exception/UnresolvedDependencyException.php
new file mode 100644 (file)
index 0000000..a5c58c1
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+namespace TYPO3\CMS\Extensionmanager\Exception;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2014 Nicole Cordes <typo3@cordes.co>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * An exception when some dependency is unresolved
+ *
+ * @author Nicole Cordes <typo3@cordes.co>
+ */
+class UnresolvedDependencyException extends ExtensionManagerException {
+
+}
diff --git a/typo3/sysext/extensionmanager/Classes/Exception/UnresolvedPhpDependencyException.php b/typo3/sysext/extensionmanager/Classes/Exception/UnresolvedPhpDependencyException.php
new file mode 100644 (file)
index 0000000..a9d6748
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+namespace TYPO3\CMS\Extensionmanager\Exception;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2014 Nicole Cordes <typo3@cordes.co>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * An exception when some dependency is unresolved
+ *
+ * @author Nicole Cordes <typo3@cordes.co>
+ */
+class UnresolvedPhpDependencyException extends UnresolvedDependencyException {
+
+}
diff --git a/typo3/sysext/extensionmanager/Classes/Exception/UnresolvedTypo3DependencyException.php b/typo3/sysext/extensionmanager/Classes/Exception/UnresolvedTypo3DependencyException.php
new file mode 100644 (file)
index 0000000..7066043
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+namespace TYPO3\CMS\Extensionmanager\Exception;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2014 Nicole Cordes <typo3@cordes.co>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * An exception when some dependency is unresolved
+ *
+ * @author Nicole Cordes <typo3@cordes.co>
+ */
+class UnresolvedTypo3DependencyException extends UnresolvedDependencyException {
+
+}
index 32d5d3f..0944b88 100644 (file)
@@ -72,13 +72,18 @@ class ExtensionManagementService implements \TYPO3\CMS\Core\SingletonInterface {
        protected $downloadUtility;
 
        /**
+        * @var bool
+        */
+       protected $skipSystemDependencyCheck = FALSE;
+
+       /**
         * @param string $extensionKey
         * @return void
         */
        public function markExtensionForInstallation($extensionKey) {
                // We have to check for dependencies of the extension first, before marking it for installation
                // because this extension might have dependencies, which need to be installed first
-               $this->dependencyUtility->buildExtensionDependenciesTree(
+               $this->dependencyUtility->checkDependencies(
                        $this->extensionModelUtility->mapExtensionArrayToModel(
                                $this->installUtility->enrichExtensionWithDetails($extensionKey)
                        )
@@ -106,7 +111,7 @@ class ExtensionManagementService implements \TYPO3\CMS\Core\SingletonInterface {
        public function markExtensionForDownload(Extension $extension) {
                // We have to check for dependencies of the extension first, before marking it for download
                // because this extension might have dependencies, which need to be downloaded and installed first
-               $this->dependencyUtility->buildExtensionDependenciesTree($extension);
+               $this->dependencyUtility->checkDependencies($extension);
                $this->downloadQueue->addExtensionToQueue($extension);
        }
 
@@ -117,22 +122,31 @@ class ExtensionManagementService implements \TYPO3\CMS\Core\SingletonInterface {
        public function markExtensionForUpdate(Extension $extension) {
                // We have to check for dependencies of the extension first, before marking it for download
                // because this extension might have dependencies, which need to be downloaded and installed first
-               $this->dependencyUtility->buildExtensionDependenciesTree($extension);
+               $this->dependencyUtility->checkDependencies($extension);
                $this->downloadQueue->addExtensionToQueue($extension, 'update');
        }
 
        /**
-        * Resolve an extensions dependencies (download, copy and install dependent
-        * extensions) and install the extension
+        * Enables or disables the dependency check for system environment (PHP, TYPO3) before extension installation
+        *
+        * @param bool $skipSystemDependencyCheck
+        */
+       public function setSkipSystemDependencyCheck($skipSystemDependencyCheck) {
+               $this->skipSystemDependencyCheck = $skipSystemDependencyCheck;
+       }
+
+       /**
+        * Install the extension
         *
         * @param Extension $extension
-        * @return array
+        * @return bool|array Returns FALSE if dependencies cannot be resolved, otherwise array with installation information
         */
-       public function resolveDependenciesAndInstall(Extension $extension) {
-               $this->downloadMainExtension($extension);
-               $extensionKey = $extension->getExtensionKey();
-               $this->setInExtensionRepository($extensionKey);
-               $this->dependencyUtility->buildExtensionDependenciesTree($extension);
+       public function installExtension(Extension $extension) {
+               $this->downloadExtension($extension);
+
+               if (!$this->checkDependencies($extension)) {
+                       return FALSE;
+               }
 
                $updatedDependencies = array();
                $installedDependencies = array();
@@ -151,7 +165,7 @@ class ExtensionManagementService implements \TYPO3\CMS\Core\SingletonInterface {
                        $updatedDependencies = $this->uninstallDependenciesToBeUpdated($queue['update']);
                }
                // add extension at the end of the download queue
-               $this->downloadQueue->addExtensionToInstallQueue($extensionKey);
+               $this->downloadQueue->addExtensionToInstallQueue($extension->getExtensionKey());
                $installQueue = $this->downloadQueue->getExtensionInstallStorage();
                if (count($installQueue) > 0) {
                        $installedDependencies = $this->installDependencies($installQueue);
@@ -160,6 +174,38 @@ class ExtensionManagementService implements \TYPO3\CMS\Core\SingletonInterface {
        }
 
        /**
+        * Returns the unresolved dependency errors
+        *
+        * @return array
+        */
+       public function getDependencyErrors() {
+               return $this->dependencyUtility->getDependencyErrors();
+       }
+
+       /**
+        * Download an extension
+        *
+        * @param Extension $extension
+        */
+       protected function downloadExtension(Extension $extension) {
+               $this->downloadMainExtension($extension);
+               $this->setInExtensionRepository($extension->getExtensionKey());
+       }
+
+       /**
+        * Check dependencies for an extension and its required extensions
+        *
+        * @param Extension $extension
+        * @return bool Returns TRUE if all dependencies can be resolved, otherwise FALSE
+        */
+       protected function checkDependencies(Extension $extension) {
+               $this->dependencyUtility->setSkipSystemDependencyCheck($this->skipSystemDependencyCheck);
+               $this->dependencyUtility->checkDependencies($extension);
+
+               return !$this->dependencyUtility->hasDependencyErrors();
+       }
+
+       /**
         * Sets the path to the repository in an extension
         * (Initialisation/Extensions) depending on the extension
         * that is currently installed
@@ -253,7 +299,8 @@ class ExtensionManagementService implements \TYPO3\CMS\Core\SingletonInterface {
         * @return array
         */
        public function getAndResolveDependencies(Extension $extension) {
-               $this->dependencyUtility->buildExtensionDependenciesTree($extension);
+               $this->dependencyUtility->setSkipSystemDependencyCheck($this->skipSystemDependencyCheck);
+               $this->dependencyUtility->checkDependencies($extension);
                $installQueue = $this->downloadQueue->getExtensionInstallStorage();
                if (is_array($installQueue) && count($installQueue) > 0) {
                        $installQueue = array('install' => $installQueue);
index 31c6e0d..13b55f6 100644 (file)
@@ -26,8 +26,11 @@ namespace TYPO3\CMS\Extensionmanager\Utility;
  *
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
+use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
+use TYPO3\CMS\Core\Utility\VersionNumberUtility;
 use TYPO3\CMS\Extensionmanager\Domain\Model\Dependency;
-use TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException;
+use TYPO3\CMS\Extensionmanager\Domain\Model\Extension;
+use TYPO3\CMS\Extensionmanager\Exception;
 
 /**
  * Utility for dealing with dependencies
@@ -77,7 +80,18 @@ class DependencyUtility implements \TYPO3\CMS\Core\SingletonInterface {
        protected $localExtensionStorage = '';
 
        /**
+        * @var array
+        */
+       protected $dependencyErrors = array();
+
+       /**
+        * @var bool
+        */
+       protected $skipSystemDependencyCheck = FALSE;
+
+       /**
         * @param string $localExtensionStorage
+        * @return void
         */
        public function setLocalExtensionStorage($localExtensionStorage) {
                $this->localExtensionStorage = $localExtensionStorage;
@@ -94,56 +108,97 @@ class DependencyUtility implements \TYPO3\CMS\Core\SingletonInterface {
        }
 
        /**
-        * @param \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension
-        * @throws ExtensionManagerException
+        * @param bool $skipSpecialDependencyCheck
+        * @return void
         */
-       public function buildExtensionDependenciesTree(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension) {
-               $dependencies = $extension->getDependencies();
-               $this->checkDependencies($dependencies);
+       public function setSkipSystemDependencyCheck($skipSpecialDependencyCheck) {
+               $this->skipSystemDependencyCheck = $skipSpecialDependencyCheck;
        }
 
        /**
         * Checks dependencies for special cases (currently typo3 and php)
         *
-        * @param \SplObjectStorage $dependencies
-        * @throws ExtensionManagerException
-        * @return boolean
+        * @param Extension $extension
+        * @return void
         */
-       protected function checkDependencies(\SplObjectStorage $dependencies) {
-               $dependenciesToResolve = FALSE;
+       public function checkDependencies(Extension $extension) {
+               $dependencies = $extension->getDependencies();
                foreach ($dependencies as $dependency) {
                        /** @var Dependency $dependency */
                        $identifier = strtolower($dependency->getIdentifier());
-                       if (in_array($identifier, Dependency::$specialDependencies)) {
-                               $methodname = 'check' . ucfirst($identifier) . 'Dependency';
-                               $this->{$methodname}($dependency);
-                       } else {
-                               if ($dependency->getType() === 'depends') {
-                                       $dependenciesToResolve = !(bool) $this->checkExtensionDependency($dependency);
+                       try {
+                               if (in_array($identifier, Dependency::$specialDependencies)) {
+                                       if (!$this->skipSystemDependencyCheck) {
+                                               $methodName = 'check' . ucfirst($identifier) . 'Dependency';
+                                               $this->{$methodName}($dependency);
+                                       }
+                               } else {
+                                       if ($dependency->getType() === 'depends') {
+                                               $this->checkExtensionDependency($dependency);
+                                       }
                                }
+                       } catch (Exception\UnresolvedDependencyException $e) {
+                               if (in_array($identifier, Dependency::$specialDependencies)) {
+                                       $extensionKey = $extension->getExtensionKey();
+                               } else {
+                                       $extensionKey = $identifier;
+                               }
+                               if (!isset($this->dependencyErrors[$extensionKey])) {
+                                       $this->dependencyErrors[$extensionKey] = array();
+                               }
+                               $this->dependencyErrors[$extensionKey][] = array(
+                                       'code' => $e->getCode(),
+                                       'message' => $e->getMessage()
+                               );
                        }
                }
-               return $dependenciesToResolve;
+       }
+
+       /**
+        * Returns TRUE if a dependency error was found
+        *
+        * @return bool
+        */
+       public function hasDependencyErrors() {
+               return !empty($this->dependencyErrors);
+       }
+
+       /**
+        * Return the dependency errors
+        *
+        * @return array
+        */
+       public function getDependencyErrors() {
+               return $this->dependencyErrors;
        }
 
        /**
         * Returns true if current TYPO3 version fulfills extension requirements
         *
         * @param Dependency $dependency
+        * @throws Exception\UnresolvedTypo3DependencyException
         * @return boolean
-        * @throws ExtensionManagerException
         */
        protected function checkTypo3Dependency(Dependency $dependency) {
                $lowerCaseIdentifier = strtolower($dependency->getIdentifier());
                if ($lowerCaseIdentifier === 'typo3') {
-                       if (!($dependency->getLowestVersion() === '') && version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getNumericTypo3Version(), $dependency->getLowestVersion()) === -1) {
-                               throw new ExtensionManagerException('Your TYPO3 version is lower than necessary. You need at least TYPO3 version ' . $dependency->getLowestVersion());
+                       if (!($dependency->getLowestVersion() === '') && version_compare(VersionNumberUtility::getNumericTypo3Version(), $dependency->getLowestVersion()) === -1) {
+                               throw new Exception\UnresolvedTypo3DependencyException(
+                                       'Your TYPO3 version is lower than necessary. You need at least TYPO3 version ' . $dependency->getLowestVersion(),
+                                       1399144499
+                               );
                        }
-                       if (!($dependency->getHighestVersion() === '') && version_compare($dependency->getHighestVersion(), \TYPO3\CMS\Core\Utility\VersionNumberUtility::getNumericTypo3Version()) === -1) {
-                               throw new ExtensionManagerException('Your TYPO3 version is higher than allowed. You can use TYPO3 versions ' . $dependency->getLowestVersion() . ' - ' . $dependency->getHighestVersion());
+                       if (!($dependency->getHighestVersion() === '') && version_compare($dependency->getHighestVersion(), VersionNumberUtility::getNumericTypo3Version()) === -1) {
+                               throw new Exception\UnresolvedTypo3DependencyException(
+                                       'Your TYPO3 version is higher than allowed. You can use TYPO3 versions ' . $dependency->getLowestVersion() . ' - ' . $dependency->getHighestVersion(),
+                                       1399144521
+                               );
                        }
                } else {
-                       throw new ExtensionManagerException('checkTypo3Dependency can only check TYPO3 dependencies. Found dependency with identifier "' . $dependency->getIdentifier() . '"');
+                       throw new Exception\UnresolvedTypo3DependencyException(
+                               'checkTypo3Dependency can only check TYPO3 dependencies. Found dependency with identifier "' . $dependency->getIdentifier() . '"',
+                               1399144551
+                       );
                }
                return TRUE;
        }
@@ -152,26 +207,26 @@ class DependencyUtility implements \TYPO3\CMS\Core\SingletonInterface {
         * Returns true if current php version fulfills extension requirements
         *
         * @param Dependency $dependency
+        * @throws Exception\UnresolvedPhpDependencyException
         * @return boolean
-        * @throws ExtensionManagerException
         */
        protected function checkPhpDependency(Dependency $dependency) {
                $lowerCaseIdentifier = strtolower($dependency->getIdentifier());
                if ($lowerCaseIdentifier === 'php') {
                        if (!($dependency->getLowestVersion() === '') && version_compare(PHP_VERSION, $dependency->getLowestVersion()) === -1) {
-                               throw new ExtensionManagerException(
+                               throw new Exception\UnresolvedPhpDependencyException(
                                        'Your PHP version is lower than necessary. You need at least PHP version ' . $dependency->getLowestVersion(),
                                         1377977857
                                );
                        }
                        if (!($dependency->getHighestVersion() === '') && version_compare($dependency->getHighestVersion(), PHP_VERSION) === -1) {
-                               throw new ExtensionManagerException(
+                               throw new Exception\UnresolvedPhpDependencyException(
                                        'Your PHP version is higher than allowed. You can use PHP versions ' . $dependency->getLowestVersion() . ' - ' . $dependency->getHighestVersion(),
                                        1377977856
                                );
                        }
                } else {
-                       throw new ExtensionManagerException(
+                       throw new Exception\UnresolvedPhpDependencyException(
                                'checkPhpDependency can only check PHP dependencies. Found dependency with identifier "' . $dependency->getIdentifier() . '"',
                                1377977858
                        );
@@ -188,7 +243,7 @@ class DependencyUtility implements \TYPO3\CMS\Core\SingletonInterface {
         *
         * @todo handle exceptions / markForUpload
         * @param Dependency $dependency
-        * @throws ExtensionManagerException
+        * @throws Exception\MissingVersionDependencyException
         * @return boolean
         */
        protected function checkExtensionDependency(Dependency $dependency) {
@@ -201,8 +256,11 @@ class DependencyUtility implements \TYPO3\CMS\Core\SingletonInterface {
                        } else {
                                try {
                                        $this->getExtensionFromRepository($extensionKey, $dependency);
-                               } catch (ExtensionManagerException $e) {
-                                       throw new ExtensionManagerException('The extension ' . $dependency->getIdentifier() . ' is needed in version ' . $dependency->getLowestVersion() . ' - ' . $dependency->getHighestVersion() . ', but could not be fetched from TER', 1396302624);
+                               } catch (Exception\UnresolvedDependencyException $e) {
+                                       throw new Exception\MissingVersionDependencyException(
+                                               'The extension ' . $dependency->getIdentifier() . ' is needed in version ' . $dependency->getLowestVersion() . ' - ' . $dependency->getHighestVersion() . ', but could not be fetched from TER',
+                                               1396302624
+                                       );
                                }
                        }
                } else {
@@ -259,21 +317,41 @@ class DependencyUtility implements \TYPO3\CMS\Core\SingletonInterface {
         * @todo unit tests
         * @param string $extensionKey
         * @param Dependency $dependency
-        * @throws ExtensionManagerException
+        * @throws Exception\UnresolvedDependencyException
         * @return void
         */
        protected function getExtensionFromTer($extensionKey, Dependency $dependency) {
-               if (!$this->isExtensionDownloadableFromTer($extensionKey)) {
-                       throw new ExtensionManagerException('The extension ' . $extensionKey . ' is not available from TER.');
+               $isExtensionDownloadableFromTer = $this->isExtensionDownloadableFromTer($extensionKey);
+               if (!$isExtensionDownloadableFromTer) {
+                       if (!$this->skipSystemDependencyCheck) {
+                               throw new Exception\MissingExtensionDependencyException(
+                                       'The extension ' . $extensionKey . ' is not available from TER.',
+                                       1399161266
+                               );
+                       }
+                       return;
                }
 
-               if (!$this->isDownloadableVersionCompatible($dependency)) {
-                       throw new ExtensionManagerException('No compatible version found for extension ' . $extensionKey);
+               $isDownloadableVersionCompatible = $this->isDownloadableVersionCompatible($dependency);
+               if (!$isDownloadableVersionCompatible) {
+                       if (!$this->skipSystemDependencyCheck) {
+                               throw new Exception\MissingVersionDependencyException(
+                                       'No compatible version found for extension ' . $extensionKey,
+                                       1399161284
+                               );
+                       }
+                       return;
                }
 
                $latestCompatibleExtensionByIntegerVersionDependency = $this->getLatestCompatibleExtensionByIntegerVersionDependency($dependency);
-               if (!$latestCompatibleExtensionByIntegerVersionDependency instanceof \TYPO3\CMS\Extensionmanager\Domain\Model\Extension) {
-                       throw new ExtensionManagerException('Could not resolve dependency for "' . $dependency->getIdentifier() . '"');
+               if (!$latestCompatibleExtensionByIntegerVersionDependency instanceof Extension) {
+                       if (!$this->skipSystemDependencyCheck) {
+                               throw new Exception\MissingExtensionDependencyException(
+                                       'Could not resolve dependency for "' . $dependency->getIdentifier() . '"',
+                                       1399161302
+                               );
+                       }
+                       return;
                }
 
                if ($this->isDependentExtensionLoaded($extensionKey)) {
@@ -288,7 +366,7 @@ class DependencyUtility implements \TYPO3\CMS\Core\SingletonInterface {
         * @return boolean
         */
        protected function isDependentExtensionLoaded($extensionKey) {
-               return \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded($extensionKey);
+               return ExtensionManagementUtility::isLoaded($extensionKey);
        }
 
        /**
@@ -296,7 +374,7 @@ class DependencyUtility implements \TYPO3\CMS\Core\SingletonInterface {
         * @return boolean
         */
        protected function isLoadedVersionCompatible(Dependency $dependency) {
-               $extensionVersion = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getExtensionVersion($dependency->getIdentifier());
+               $extensionVersion = ExtensionManagementUtility::getExtensionVersion($dependency->getIdentifier());
                return $this->isVersionCompatible($extensionVersion, $dependency);
        }
 
@@ -368,7 +446,7 @@ class DependencyUtility implements \TYPO3\CMS\Core\SingletonInterface {
         * fulfills the given dependency from TER
         *
         * @param Dependency $dependency
-        * @return \TYPO3\CMS\Extensionmanager\Domain\Model\Extension
+        * @return Extension
         */
        protected function getLatestCompatibleExtensionByIntegerVersionDependency(Dependency $dependency) {
                $versions = $this->getLowestAndHighestIntegerVersions($dependency);
@@ -388,9 +466,9 @@ class DependencyUtility implements \TYPO3\CMS\Core\SingletonInterface {
         */
        protected function getLowestAndHighestIntegerVersions(Dependency $dependency) {
                $lowestVersion = $dependency->getLowestVersion();
-               $lowestVersionInteger = $lowestVersion ? \TYPO3\CMS\Core\Utility\VersionNumberUtility::convertVersionNumberToInteger($lowestVersion) : 0;
+               $lowestVersionInteger = $lowestVersion ? VersionNumberUtility::convertVersionNumberToInteger($lowestVersion) : 0;
                $highestVersion = $dependency->getHighestVersion();
-               $highestVersionInteger = $highestVersion ? \TYPO3\CMS\Core\Utility\VersionNumberUtility::convertVersionNumberToInteger($highestVersion) : 0;
+               $highestVersionInteger = $highestVersion ? VersionNumberUtility::convertVersionNumberToInteger($highestVersion) : 0;
                return array(
                        'lowestIntegerVersion' => $lowestVersionInteger,
                        'highestIntegerVersion' => $highestVersionInteger
index 9a95c7a..2704165 100644 (file)
@@ -421,10 +421,9 @@ class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface {
                if ($highestTerVersionExtension instanceof \TYPO3\CMS\Extensionmanager\Domain\Model\Extension) {
                        $highestVersion = $highestTerVersionExtension->getIntegerVersion();
                        if ($highestVersion > $version) {
-                               try {
-                                       $this->dependencyUtility->buildExtensionDependenciesTree($highestTerVersionExtension);
+                               $this->dependencyUtility->checkDependencies($highestTerVersionExtension);
+                               if (!$this->dependencyUtility->hasDependencyErrors()) {
                                        $isUpdateAvailable = TRUE;
-                               } catch (\TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException $e) {
                                }
                        }
                }
index e0b816c..67e85cc 100644 (file)
@@ -9,6 +9,9 @@
                        <trans-unit id="manageExtensions" xml:space="preserve">
                                <source>Manage Extensions</source>
                        </trans-unit>
+                       <trans-unit id="installExtension">
+                               <source>Install Extension</source>
+                       </trans-unit>
                        <trans-unit id="getExtensions" xml:space="preserve">
                                <source>Get Extensions</source>
                        </trans-unit>
                        <trans-unit id="extensionList.removalConfirmation.question" xml:space="preserve">
                                <source>Are you sure you want to remove the extension?</source>
                        </trans-unit>
-                       <trans-unit id="downloadExtension.dependencies.headline" xml:space="preserve">
+                       <trans-unit id="dependencyCheck.unresolvedDependencies.title">
+                               <source>Please read this carefully</source>
+                       </trans-unit>
+                       <trans-unit id="dependencyCheck.unresolvedDependencies.message">
+                               <source><![CDATA[
+                                       If you continue installing the extension, all dependency checks will be turned off.
+                                       <ul>
+                                               <li>Required extensions are tried to be fetched from TER (if they do not yet exist in the system)</li>
+                                               <li>Version dependency checks are skipped</li>
+                                       </ul>
+                                       <strong>
+                                               Be aware that an installation without dependency checks may turn your installation unusable.<br />
+                                               In such a case manual intervention is required.
+                                       </strong>
+                               ]]></source>
+                       </trans-unit>
+                       <trans-unit id="dependencyCheck.unresolvedDependencies.question">
+                               <source>Are you sure you want to proceed?</source>
+                       </trans-unit>
+                       <trans-unit id="dependencyCheck.unresolvedDependencies.proceed">
+                               <source>I know what I'm doing, install the extension!</source>
+                       </trans-unit>
+                       <trans-unit id="dependencyCheck.headline">
+                               <source>The following errors were found while trying to install "%s"</source>
+                       </trans-unit>
+                       <trans-unit id="dependencyCheck.requiredExtension">
+                               <source>Required extension "%s":</source>
+                       </trans-unit>
+                       <trans-unit id="downloadExtension.dependencies.headline">
                                <source>The following dependencies have to be resolved before installation:
 
 
                        <trans-unit id="extensionList.uploadFlashMessage.title" xml:space="preserve">
                                <source>Extension Upload</source>
                        </trans-unit>
-                       <trans-unit id="extensionList.uploadFlashMessage.message" xml:space="preserve">
-                               <source>{0} uploaded!</source>
+                       <trans-unit id="extensionList.uploadFlashMessage.message">
+                               <source>%s was uploaded!</source>
+                       </trans-unit>
+                       <trans-unit id="extensionList.installedFlashMessage.message">
+                               <source>%s was installed!</source>
                        </trans-unit>
                        <trans-unit id="extensionList.updateFromTerFlashMessage.title" xml:space="preserve">
                                <source>Update Extension List</source>
                        <trans-unit id="extensionList.showAllVersions.readOnline" xml:space="preserve">
                                <source>Read online</source>
                        </trans-unit>
+                       <trans-unit id="extensionList.remove.message">
+                               <source>Extension "%s" was removed successfully!</source>
+                       </trans-unit>
                        <trans-unit id="extensionList.distribution.key" xml:space="preserve">
                                <source>Key:</source>
                        </trans-unit>
diff --git a/typo3/sysext/extensionmanager/Resources/Private/Partials/List/UnresolvedDependencies.html b/typo3/sysext/extensionmanager/Resources/Private/Partials/List/UnresolvedDependencies.html
new file mode 100644 (file)
index 0000000..58edb4f
--- /dev/null
@@ -0,0 +1,22 @@
+<f:translate key="dependencyCheck.headline" arguments="{extensionKey: extension.extensionKey}" />:
+<ul>
+       <f:for each="{unresolvedDependencies}" key="key" as="messages">
+               <f:if condition="{key} == {extension.extensionKey}">
+                       <f:for each="{messages}" as="message">
+                               <li>{message.message}</li>
+                       </f:for>
+               </f:if>
+       </f:for>
+       <f:for each="{unresolvedDependencies}" key="key" as="messages">
+               <f:if condition="{key} != {extension.extensionKey}">
+                       <li>
+                               <strong><f:translate key="dependencyCheck.requiredExtension" arguments="{key: key}" /></strong>
+                               <ul>
+                                       <f:for each="{messages}" as="message">
+                                               <li>{message.message}</li>
+                                       </f:for>
+                               </ul>
+                       </li>
+               </f:if>
+       </f:for>
+</ul>
\ No newline at end of file
diff --git a/typo3/sysext/extensionmanager/Resources/Private/Partials/List/UnresolvedDependencies.json b/typo3/sysext/extensionmanager/Resources/Private/Partials/List/UnresolvedDependencies.json
new file mode 100644 (file)
index 0000000..010d8f1
--- /dev/null
@@ -0,0 +1,6 @@
+<f:render partial="List/UnresolvedDependencies.html" arguments="{_all}" />
+
+<h3><span class="t3-icon t3-icon-actions t3-icon-dialog-error">&nbsp;</span> <f:translate key="dependencyCheck.unresolvedDependencies.title" /></h3>
+<f:render partial="List/UnresolvedDependenciesMessage.html" />
+<br /><br />
+<strong><f:translate key="dependencyCheck.unresolvedDependencies.question" /></strong>
\ No newline at end of file
diff --git a/typo3/sysext/extensionmanager/Resources/Private/Partials/List/UnresolvedDependenciesMessage.html b/typo3/sysext/extensionmanager/Resources/Private/Partials/List/UnresolvedDependenciesMessage.html
new file mode 100644 (file)
index 0000000..e8f8bd5
--- /dev/null
@@ -0,0 +1 @@
+<f:translate key="dependencyCheck.unresolvedDependencies.message" />
\ No newline at end of file
diff --git a/typo3/sysext/extensionmanager/Resources/Private/Templates/Action/RemoveExtension.json b/typo3/sysext/extensionmanager/Resources/Private/Templates/Action/RemoveExtension.json
deleted file mode 100644 (file)
index 2fd7114..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-{namespace em=TYPO3\CMS\Extensionmanager\ViewHelpers}
-<em:format.jsonEncode additionalAttributes="{success:success, message:message, extension:extension}" />
\ No newline at end of file
index c8a2ada..79e5ee4 100644 (file)
@@ -1,2 +1,9 @@
 {namespace em=TYPO3\CMS\Extensionmanager\ViewHelpers}
-<em:format.jsonEncode additionalAttributes="{result:result, extension:extension.extensionKey, errorMessage: errorMessage}" />
\ No newline at end of file
+<em:format.jsonEncode additionalAttributes="{
+       result: result,
+       extension: extension.extensionKey,
+       errorCount: '{f:count(subject: unresolvedDependencies)}',
+       errorTitle: '{f:translate(key: \'downloadExtension.dependencies.errorTitle\')}',
+       errorMessage: '{f:render(partial: \'List/UnresolvedDependencies\', arguments: \'{_all}\')}',
+       skipDependencyUri: '{f:uri.action(action: \'installExtensionWithoutSystemDependencyCheck\', format: \'json\', arguments: \'{extension: extension}\')}'
+}" />
\ No newline at end of file
diff --git a/typo3/sysext/extensionmanager/Resources/Private/Templates/List/UnresolvedDependencies.html b/typo3/sysext/extensionmanager/Resources/Private/Templates/List/UnresolvedDependencies.html
new file mode 100644 (file)
index 0000000..5c3be28
--- /dev/null
@@ -0,0 +1,29 @@
+{namespace em=TYPO3\CMS\Extensionmanager\ViewHelpers}
+
+<f:layout name="main" />
+
+<f:section name="docheader-buttons">
+</f:section>
+
+<f:section name="module-headline">
+       <h1><f:translate key="installExtension">Install extension</f:translate></h1>
+</f:section>
+
+<f:section name="Content">
+       <f:flashMessages renderMode="div" />
+       <f:render partial="List/UnresolvedDependencies" arguments="{_all}" />
+       <br />
+       <div class="typo3-message message-error">
+               <div class="header-container">
+                       <div class="message-header"><f:translate key="dependencyCheck.unresolvedDependencies.title" /></div>
+               </div>
+               <div class="message-body"><f:render partial="List/UnresolvedDependenciesMessage" /></div>
+       </div>
+       <br />
+       <f:link.action action="index" class="t3-button">
+               Go back
+       </f:link.action>
+       <f:link.action action="installExtensionWithoutSystemDependencyCheck" controller="Action" arguments="{extensionKey: extension.extensionKey}" class="t3-button">
+               <span class="t3-icon t3-icon-actions t3-icon-dialog-error">&nbsp;</span> <f:translate key="dependencyCheck.unresolvedDependencies.proceed" />
+       </f:link.action>
+</f:section>
\ No newline at end of file
diff --git a/typo3/sysext/extensionmanager/Resources/Private/Templates/UploadExtensionFile/Extract.json b/typo3/sysext/extensionmanager/Resources/Private/Templates/UploadExtensionFile/Extract.json
deleted file mode 100644 (file)
index 3e011c8..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-{namespace em=TYPO3\CMS\Extensionmanager\ViewHelpers}
-<em:format.jsonEncode additionalAttributes="{success:'true', extension:extensionKey, error:error}" />
\ No newline at end of file
index 74aecb7..653878e 100644 (file)
@@ -1,4 +1,4 @@
-<f:form enctype="multipart/form-data" id="extensionUploadForm" method="post" controller="UploadExtensionFile" action="extract" format="json" additionalAttributes="{target:'typo3-extensionmanager-upload-target'}">
+<f:form enctype="multipart/form-data" id="extensionUploadForm" method="post" controller="UploadExtensionFile" action="extract">
        <div class="control-group">
                <label for="extensionFile">
                        <f:translate key="uploadTemplate.extensionLabel" />
@@ -20,6 +20,4 @@
                        <f:form.submit value="{f:translate(key:'uploadTemplate.uploadButton')}" id="extensionUpload" />
                </div>
        </div>
-
-       <iframe id="typo3-extensionmanager-upload-target" name="typo3-extensionmanager-upload-target" style="display: none;"></iframe>
 </f:form>
index c1a4a1b..8e69a6d 100644 (file)
                                                        $('.typo3-extension-manager').mask();
                                                        $.ajax({
                                                                url: dialog.url,
-                                                               dataType: 'json',
-                                                               success: removeExtension
+                                                               success: function() {
+                                                                       location.reload();
+                                                               },
+                                                               error: function() {
+                                                                       $('.typo3-extension-manager').unmask();
+                                                               }
                                                        });
                                                }
                                        }
                        }
                });
        }
-
-       function removeExtension(data) {
-               $('.typo3-extension-manager').unmask();
-               if (data.success) {
-                       datatable.fnDeleteRow(datatable.fnGetPosition(document.getElementById(data.extension)));
-               } else {
-                       TYPO3.Flashmessage.display(TYPO3.Severity.error, TYPO3.l10n.localize('extensionList.removalConfirmation.title'), data.message, 15);
-               }
-       }
 }(jQuery));
index 23806ab..7ee3901 100644 (file)
@@ -93,7 +93,7 @@
                } else {
                        if(data.hasErrors) {
                                $('.typo3-extension-manager').unmask();
-                               TYPO3.Flashmessage.display(TYPO3.Severity.error, data.title, data.message, 10);
+                               TYPO3.Flashmessage.display(TYPO3.Severity.error, data.title, data.message, 15);
                        } else {
                                var button = 'yes';
                                var dialog = [];
                                dataType: 'json',
                                success: function (data) {
                                        $('.typo3-extension-manager').unmask();
-                                       if (data.errorMessage.length) {
-                                               TYPO3.Flashmessage.display(TYPO3.Severity.error, TYPO3.l10n.localize('extensionList.dependenciesResolveDownloadError.title'), data.errorMessage, 5);
+                                       if (data.errorCount > 0) {
+                                               TYPO3.Dialog.QuestionDialog({
+                                                       title: data.errorTitle,
+                                                       msg: data.errorMessage,
+                                                       url: data.skipDependencyUri,
+                                                       fn: function (button, dummy, dialog) {
+                                                               if (button == 'yes') {
+                                                                       $('.typo3-extension-manager').mask();
+                                                                       getResolveDependenciesAndInstallResult('yes', dummy, dialog);
+                                                               }
+                                                       }
+                                               });
                                        } else {
                                                var successMessage = TYPO3.l10n.localize('extensionList.dependenciesResolveDownloadSuccess.message').replace(/\{0\}/g, data.extension) + ' <br />';
                                                successMessage += '<br /><h3>' + TYPO3.l10n.localize('extensionList.dependenciesResolveDownloadSuccess.header') + ':</h3>';
index 0380e91..b37ddab 100644 (file)
                                dataType: 'html',
                                success: function (data) {
                                        $('.uploadForm').html(data);
-                                       handleUploadForm();
                                }
                        });
                });
-
-               function handleUploadForm() {
-                       // Handle form submit response
-                       $('#typo3-extensionmanager-upload-target').on('load', function(event) {
-                               var html = $.trim($(this).contents().find('body').html());
-                               if (html[0] === '{') {
-                                       var data = $.parseJSON(html);
-                                       if (data.error) {
-                                               TYPO3.Flashmessage.display(TYPO3.Severity.error, 'Extension Upload failed', data.error, 5);
-                                       } else if (data.success) {
-                                               TYPO3.Flashmessage.display(TYPO3.Severity.information, TYPO3.l10n.localize('extensionList.uploadFlashMessage.title'), TYPO3.l10n.localize('extensionList.uploadFlashMessage.message').replace(/\{0\}/g, data.extension), 15);
-                                               location.reload();
-                                       }
-                               }
-                       });
-               }
        });
 }(jQuery));
index 8f7f55e..8695e19 100644 (file)
@@ -75,7 +75,10 @@ class UploadExtensionFileControllerTest extends \TYPO3\CMS\Core\Tests\UnitTestCa
        public function getExtensionFromZipFileExtractsExtensionKey($filename, $expectedKey) {
                $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Controller\\UploadExtensionFileController', array('dummy'));
                $installUtilityMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\InstallUtility', array(), array(), '', FALSE);
-               $installUtilityMock->expects($this->once())->method('install');
+               $installUtilityMock->expects($this->once())
+                       ->method('isAvailable')
+                       ->with($expectedKey)
+                       ->will($this->returnValue(FALSE));
                $fixture->_set('installUtility', $installUtilityMock);
                $fileHandlingUtilityMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\FileHandlingUtility');
                $fileHandlingUtilityMock->expects($this->once())->method('unzipExtensionFromFile');
index 07da196..8abf51e 100644 (file)
@@ -31,16 +31,34 @@ namespace TYPO3\CMS\Extensionmanager\Tests\Unit\Domain\Model;
 class DownloadQueueTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
 
        /**
+        * @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface|\TYPO3\CMS\Extensionmanager\Domain\Model\DownloadQueue
+        */
+       protected $downloadQueueMock;
+
+       /**
+        * @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Domain\Model\Extension
+        */
+       protected $extensionMock;
+
+       /**
+        * @return void
+        */
+       public function setUp() {
+               $this->downloadQueueMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\DownloadQueue', array('dummy'));
+               $this->extensionMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension', array('dummy'));
+               $this->extensionMock->setExtensionKey('foobar');
+               $this->extensionMock->setVersion('1.0.0');
+
+       }
+
+       /**
         * @test
         * @return void
         */
        public function addExtensionToQueueAddsExtensionToDownloadStorageArray() {
-               $extensionModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension', array('dummy'));
-               $extensionModelMock->_set('extensionKey', 'foobar');
-               $extensionModelMock->_set('version', '1.0.0');
-               $downloadQueueMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\DownloadQueue', array('dummy'));
-               $downloadQueueMock->addExtensionToQueue($extensionModelMock);
-               $extensionStorage = $downloadQueueMock->_get('extensionStorage');
+               $this->downloadQueueMock->addExtensionToQueue($this->extensionMock);
+               $extensionStorage = $this->downloadQueueMock->_get('extensionStorage');
+
                $this->assertArrayHasKey('foobar', $extensionStorage['download']);
        }
 
@@ -49,12 +67,9 @@ class DownloadQueueTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function addExtensionToQueueAddsExtensionToUpdateStorageArray() {
-               $extensionModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension', array('dummy'));
-               $extensionModelMock->_set('extensionKey', 'foobar');
-               $extensionModelMock->_set('version', '1.0.0');
-               $downloadQueueMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\DownloadQueue', array('dummy'));
-               $downloadQueueMock->addExtensionToQueue($extensionModelMock, 'update');
-               $extensionStorage = $downloadQueueMock->_get('extensionStorage');
+               $this->downloadQueueMock->addExtensionToQueue($this->extensionMock, 'update');
+               $extensionStorage = $this->downloadQueueMock->_get('extensionStorage');
+
                $this->assertArrayHasKey('foobar', $extensionStorage['update']);
        }
 
@@ -63,14 +78,8 @@ class DownloadQueueTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function addExtensionToQueueThrowsExceptionIfUnknownStackIsGiven() {
-               /** @var $extensionModelMock \TYPO3\CMS\Extensionmanager\Domain\Model\Extension */
-               $extensionModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension', array('dummy'));
-               $extensionModelMock->_set('extensionKey', 'foobar');
-               $extensionModelMock->_set('version', '1.0.0');
-               /** @var $downloadQueueMock \TYPO3\CMS\Extensionmanager\Domain\Model\DownloadQueue */
-               $downloadQueueMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\DownloadQueue', array('dummy'));
                $this->setExpectedException('TYPO3\\CMS\\Extensionmanager\\Exception\\ExtensionManagerException', $this->any(), 1342432103);
-               $downloadQueueMock->addExtensionToQueue($extensionModelMock, 'unknownStack');
+               $this->downloadQueueMock->addExtensionToQueue($this->extensionMock, 'unknownStack');
        }
 
        /**
@@ -78,16 +87,14 @@ class DownloadQueueTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function addExtensionToQueueThrowsExceptionIfExtensionWithSameKeyAndDifferentValuesAlreadyExists() {
-               $extensionModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension', array('dummy'));
-               $extensionModelMock->_set('extensionKey', 'foobar');
-               $extensionModelMock->_set('version', '1.0.0');
-               $extensionModelMock2 = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension', array('dummy'));
-               $extensionModelMock2->_set('extensionKey', 'foobar');
-               $extensionModelMock2->_set('version', '1.0.3');
-               $downloadQueueMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\DownloadQueue', array('dummy'));
-               $downloadQueueMock->_set('extensionStorage', array('foobar' => $extensionModelMock2));
+               /** @var \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extensionMock2 */
+               $extensionMock2 = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension', array('dummy'));
+               $extensionMock2->setExtensionKey('foobar');
+               $extensionMock2->setVersion('1.0.3');
+               $this->downloadQueueMock->_set('extensionStorage', array('foobar' => $extensionMock2));
+
                $this->setExpectedException('TYPO3\\CMS\\Extensionmanager\\Exception\\ExtensionManagerException', $this->any(), 1342432101);
-               $downloadQueueMock->addExtensionToQueue($extensionModelMock);
+               $this->downloadQueueMock->addExtensionToQueue($this->extensionMock);
        }
 
        /**
@@ -95,23 +102,22 @@ class DownloadQueueTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function removeExtensionFromQueueRemovesExtension() {
-               $extensionModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension', array('dummy'));
-               $extensionModelMock->_set('extensionKey', 'foobar');
-               $extensionModelMock->_set('version', '1.0.0');
-               $extensionModelMock2 = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension', array('dummy'));
-               $extensionModelMock2->_set('extensionKey', 'foobarbaz');
-               $extensionModelMock2->_set('version', '1.0.3');
-               $downloadQueueMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\DownloadQueue', array('dummy'));
-               $downloadQueueMock->_set('extensionStorage', array(
+               $extensionMock2 = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension', array('dummy'));
+               $extensionMock2->_set('extensionKey', 'foobarbaz');
+               $extensionMock2->_set('version', '1.0.3');
+               $this->downloadQueueMock->_set('extensionStorage', array(
                        'download' => array(
-                               'foobar' => $extensionModelMock,
-                               'foobarbaz' => $extensionModelMock2
+                               'foobar' => $this->extensionMock,
+                               'foobarbaz' => $extensionMock2
                        )
                ));
-               $extensionStorageBefore = $downloadQueueMock->_get('extensionStorage');
+               $extensionStorageBefore = $this->downloadQueueMock->_get('extensionStorage');
+
                $this->assertTrue(array_key_exists('foobar', $extensionStorageBefore['download']));
-               $downloadQueueMock->removeExtensionFromQueue($extensionModelMock);
-               $extensionStorageAfter = $downloadQueueMock->_get('extensionStorage');
+
+               $this->downloadQueueMock->removeExtensionFromQueue($this->extensionMock);
+               $extensionStorageAfter = $this->downloadQueueMock->_get('extensionStorage');
+
                $this->assertFalse(array_key_exists('foobar', $extensionStorageAfter['download']));
        }
 
index 881f941..33eff47 100644 (file)
@@ -43,8 +43,8 @@ class ExtensionManagementServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
                $extensionModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension');
                $extensionModelMock->_set('extensionKey', 'foobar');
                $extensionModelMock->_set('version', '1.0.0');
-               $dependencyUtilityMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('buildExtensionDependenciesTree'));
-               $dependencyUtilityMock->expects($this->atLeastOnce())->method('buildExtensionDependenciesTree');
+               $dependencyUtilityMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('checkDependencies'));
+               $dependencyUtilityMock->expects($this->atLeastOnce())->method('checkDependencies');
                $managementMock->_set('dependencyUtility', $dependencyUtilityMock);
                $downloadQueueMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\DownloadQueue', array('getExtensionQueue', 'addExtensionToInstallQueue'));
                $downloadQueueMock->expects($this->atLeastOnce())->method('getExtensionQueue')->will($this->returnValue(array(
@@ -54,7 +54,7 @@ class ExtensionManagementServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
                )));
                $managementMock->_set('downloadQueue', $downloadQueueMock);
                $managementMock->expects($this->once())->method('downloadDependencies')->with(array('foo' => $extensionModelMock))->will($this->returnValue(array()));
-               $managementMock->_call('resolveDependenciesAndInstall', $extensionModelMock);
+               $managementMock->_call('installExtension', $extensionModelMock);
        }
 
        /**
@@ -70,8 +70,8 @@ class ExtensionManagementServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
                $extensionModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension');
                $extensionModelMock->_set('extensionKey', 'foobar');
                $extensionModelMock->_set('version', '1.0.0');
-               $dependencyUtilityMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('buildExtensionDependenciesTree'));
-               $dependencyUtilityMock->expects($this->atLeastOnce())->method('buildExtensionDependenciesTree');
+               $dependencyUtilityMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('checkDependencies'));
+               $dependencyUtilityMock->expects($this->atLeastOnce())->method('checkDependencies');
                $managementMock->_set('dependencyUtility', $dependencyUtilityMock);
                $downloadQueueMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\DownloadQueue', array('getExtensionQueue', 'addExtensionToInstallQueue'));
                $downloadQueueMock->expects($this->atLeastOnce())->method('getExtensionQueue')->will($this->returnValue(array(
@@ -82,7 +82,7 @@ class ExtensionManagementServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
                $managementMock->_set('downloadQueue', $downloadQueueMock);
                $managementMock->expects($this->once())->method('downloadDependencies')->with(array('foo' => $extensionModelMock))->will($this->returnValue(array()));
                $managementMock->expects($this->once())->method('uninstallDependenciesToBeUpdated')->with(array('foo' => $extensionModelMock))->will($this->returnValue(array()));
-               $managementMock->_call('resolveDependenciesAndInstall', $extensionModelMock);
+               $managementMock->_call('installExtension', $extensionModelMock);
        }
 
        /**
@@ -99,7 +99,7 @@ class ExtensionManagementServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
                $extensionModelMock->_set('version', '1.0.0');
 
                $dependencyUtilityMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility');
-               $dependencyUtilityMock->expects($this->atLeastOnce())->method('buildExtensionDependenciesTree');
+               $dependencyUtilityMock->expects($this->atLeastOnce())->method('checkDependencies');
                $installUtilityMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\InstallUtility');
                $installUtilityMock->expects($this->any())->method('enrichExtensionWithDetails')->will($this->returnValue(array()));
                $extensionModelUtilityMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\ExtensionModelUtility');
@@ -128,15 +128,16 @@ class ExtensionManagementServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
                        'dummy'
                ));
 
-               $extensionModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension', array('getExtensionKey'));
-               $extensionModelMock->_set('extensionKey', 'foobar');
-               $extensionModelMock->_set('version', '1.0.0');
+               /** @var \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extensionModelMock */
+               $extensionModelMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension', array('getExtensionKey'));
+               $extensionModelMock->setExtensionKey('foobar');
+               $extensionModelMock->setVersion('1.0.0');
                $downloadQueue = array(
                        $extensionModelMock
                );
 
                $dependencyUtilityMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility');
-               $dependencyUtilityMock->expects($this->atLeastOnce())->method('buildExtensionDependenciesTree');
+               $dependencyUtilityMock->expects($this->atLeastOnce())->method('checkDependencies');
                $installUtilityMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\InstallUtility');
                $installUtilityMock->expects($this->any())->method('enrichExtensionWithDetails')->will($this->returnValue(array()));
                $extensionModelUtilityMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\ExtensionModelUtility');
@@ -170,7 +171,7 @@ class ExtensionManagementServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
                );
 
                $dependencyUtilityMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility');
-               $dependencyUtilityMock->expects($this->atLeastOnce())->method('buildExtensionDependenciesTree');
+               $dependencyUtilityMock->expects($this->atLeastOnce())->method('checkDependencies');
                $installUtilityMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\InstallUtility');
                $installUtilityMock->expects($this->any())->method('enrichExtensionWithDetails')->will($this->returnValue(array()));
                $extensionModelUtilityMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\ExtensionModelUtility');
index 5a69374..6dcc3e5 100644 (file)
@@ -33,24 +33,28 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        /**
         * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
         */
-       protected $mockObjectManager;
+       protected $objectManagerMock;
 
+       /**
+        * @return void
+        */
        public function setUp() {
-               $this->mockObjectManager = $this->getMock('TYPO3\\CMS\\Extbase\\Object\\ObjectManagerInterface');
+               $this->objectManagerMock = $this->getMock('TYPO3\\CMS\\Extbase\\Object\\ObjectManagerInterface');
        }
 
-
        /**
         * @test
         * @return void
         */
        public function checkTypo3DependencyThrowsExceptionIfVersionNumberIsTooLow() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('15.0.0'));
-               $dependencyModelMock->_set('identifier', 'typo3');
+               /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Domain\Model\Dependency $dependencyMock */
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('15.0.0'));
+               $dependencyMock->setIdentifier('typo3');
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
+
                $this->setExpectedException('TYPO3\\CMS\\Extensionmanager\\Exception\\ExtensionManagerException', 'Your TYPO3 version is lower than necessary. You need at least TYPO3 version 15.0.0');
-               $dependencyUtility->_call('checkTypo3Dependency', $dependencyModelMock);
+               $dependencyUtility->_call('checkTypo3Dependency', $dependencyMock);
        }
 
        /**
@@ -58,13 +62,15 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function checkTypo3DependencyThrowsExceptionIfVersionNumberIsTooHigh() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue('3.0.0'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
-               $dependencyModelMock->_set('identifier', 'typo3');
+               /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Domain\Model\Dependency $dependencyMock */
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue('3.0.0'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
+               $dependencyMock->setIdentifier('typo3');
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
+
                $this->setExpectedException('TYPO3\\CMS\\Extensionmanager\\Exception\\ExtensionManagerException', 'Your TYPO3 version is higher than allowed. You can use TYPO3 versions 1.0.0 - 3.0.0');
-               $dependencyUtility->_call('checkTypo3Dependency', $dependencyModelMock);
+               $dependencyUtility->_call('checkTypo3Dependency', $dependencyMock);
        }
 
        /**
@@ -72,11 +78,13 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function checkTypo3DependencyThrowsExceptionIfIdentifierIsNotTypo3() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
-               $dependencyModelMock->_set('identifier', '123');
+               /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Domain\Model\Dependency $dependencyMock */
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
+               $dependencyMock->setIdentifier('123');
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
+
                $this->setExpectedException('TYPO3\\CMS\\Extensionmanager\\Exception\\ExtensionManagerException', 'checkTypo3Dependency can only check TYPO3 dependencies. Found dependency with identifier "123"');
-               $dependencyUtility->_call('checkTypo3Dependency', $dependencyModelMock);
+               $dependencyUtility->_call('checkTypo3Dependency', $dependencyMock);
        }
 
        /**
@@ -84,12 +92,14 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function checkTypo3DependencyReturnsTrueIfVersionNumberIsInRange() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue('15.0.0'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
-               $dependencyModelMock->_set('identifier', 'typo3');
+               /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Domain\Model\Dependency $dependencyMock */
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue('15.0.0'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
+               $dependencyMock->setIdentifier('typo3');
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
-               $this->assertTrue($dependencyUtility->_call('checkTypo3Dependency', $dependencyModelMock));
+
+               $this->assertTrue($dependencyUtility->_call('checkTypo3Dependency', $dependencyMock));
        }
 
        /**
@@ -97,12 +107,14 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function checkTypo3DependencyCanHandleEmptyVersionHighestVersion() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue(''));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
-               $dependencyModelMock->_set('identifier', 'typo3');
+               /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Domain\Model\Dependency $dependencyMock */
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue(''));
+               $dependencyMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
+               $dependencyMock->setIdentifier('typo3');
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
-               $this->assertTrue($dependencyUtility->_call('checkTypo3Dependency', $dependencyModelMock));
+
+               $this->assertTrue($dependencyUtility->_call('checkTypo3Dependency', $dependencyMock));
        }
 
        /**
@@ -110,12 +122,14 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function checkTypo3DependencyCanHandleEmptyVersionLowestVersion() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue('15.0.0'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue(''));
-               $dependencyModelMock->_set('identifier', 'typo3');
+               /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Domain\Model\Dependency $dependencyMock */
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue('15.0.0'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue(''));
+               $dependencyMock->setIdentifier('typo3');
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
-               $this->assertTrue($dependencyUtility->_call('checkTypo3Dependency', $dependencyModelMock));
+
+               $this->assertTrue($dependencyUtility->_call('checkTypo3Dependency', $dependencyMock));
        }
 
        /**
@@ -123,12 +137,14 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function checkPhpDependencyThrowsExceptionIfVersionNumberIsTooLow() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('15.0.0'));
-               $dependencyModelMock->_set('identifier', 'php');
+               /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Domain\Model\Dependency $dependencyMock */
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('15.0.0'));
+               $dependencyMock->setIdentifier('php');
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
+
                $this->setExpectedException('TYPO3\\CMS\\Extensionmanager\\Exception\\ExtensionManagerException', 'Your PHP version is lower than necessary. You need at least PHP version 15.0.0');
-               $dependencyUtility->_call('checkPhpDependency', $dependencyModelMock);
+               $dependencyUtility->_call('checkPhpDependency', $dependencyMock);
        }
 
        /**
@@ -136,13 +152,15 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function checkPhpDependencyThrowsExceptionIfVersionNumberIsTooHigh() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue('3.0.0'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
-               $dependencyModelMock->_set('identifier', 'PHP');
+               /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Domain\Model\Dependency $dependencyMock */
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue('3.0.0'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
+               $dependencyMock->setIdentifier('php');
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
+
                $this->setExpectedException('TYPO3\\CMS\\Extensionmanager\\Exception\\ExtensionManagerException', 'Your PHP version is higher than allowed. You can use PHP versions 1.0.0 - 3.0.0');
-               $dependencyUtility->_call('checkPhpDependency', $dependencyModelMock);
+               $dependencyUtility->_call('checkPhpDependency', $dependencyMock);
        }
 
        /**
@@ -150,11 +168,13 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function checkPhpDependencyThrowsExceptionIfIdentifierIsNotTypo3() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
-               $dependencyModelMock->_set('identifier', '123');
+               /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Domain\Model\Dependency $dependencyMock */
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
+               $dependencyMock->setIdentifier('123');
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
+
                $this->setExpectedException('TYPO3\\CMS\\Extensionmanager\\Exception\\ExtensionManagerException', 'checkPhpDependency can only check PHP dependencies. Found dependency with identifier "123"');
-               $dependencyUtility->_call('checkPhpDependency', $dependencyModelMock);
+               $dependencyUtility->_call('checkPhpDependency', $dependencyMock);
        }
 
        /**
@@ -162,12 +182,14 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function checkPhpDependencyReturnsTrueIfVersionNumberIsInRange() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue('15.0.0'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
-               $dependencyModelMock->_set('identifier', 'PHP');
+               /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Domain\Model\Dependency $dependencyMock */
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue('15.0.0'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
+               $dependencyMock->setIdentifier('php');
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
-               $this->assertTrue($dependencyUtility->_call('checkPhpDependency', $dependencyModelMock));
+
+               $this->assertTrue($dependencyUtility->_call('checkPhpDependency', $dependencyMock));
        }
 
        /**
@@ -175,12 +197,14 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function checkPhpDependencyCanHandleEmptyVersionHighestVersion() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue(''));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
-               $dependencyModelMock->_set('identifier', 'PHP');
+               /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Domain\Model\Dependency $dependencyMock */
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue(''));
+               $dependencyMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
+               $dependencyMock->setIdentifier('php');
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
-               $this->assertTrue($dependencyUtility->_call('checkPhpDependency', $dependencyModelMock));
+
+               $this->assertTrue($dependencyUtility->_call('checkPhpDependency', $dependencyMock));
        }
 
        /**
@@ -188,12 +212,14 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function checkPhpDependencyCanHandleEmptyVersionLowestVersion() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue('15.0.0'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue(''));
-               $dependencyModelMock->_set('identifier', 'PHP');
+               /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Domain\Model\Dependency $dependencyMock */
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue('15.0.0'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue(''));
+               $dependencyMock->setIdentifier('php');
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
-               $this->assertTrue($dependencyUtility->_call('checkPhpDependency', $dependencyModelMock));
+
+               $this->assertTrue($dependencyUtility->_call('checkPhpDependency', $dependencyMock));
        }
 
        /**
@@ -201,13 +227,18 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function checkDependenciesCallsMethodToCheckPhpDependencies() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
-               $dependencyModelMock->_set('identifier', 'php');
+               /** @var \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extensionMock */
+               $extensionMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension', array('dummy'));
+               /** @var \TYPO3\CMS\Extensionmanager\Domain\Model\Dependency $dependencyMock */
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
+               $dependencyMock->setIdentifier('php');
                $dependencyStorage = new \SplObjectStorage();
-               $dependencyStorage->attach($dependencyModelMock);
-               $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('checkPhpDependency', 'checkTypo3Dependency'));
+               $dependencyStorage->attach($dependencyMock);
+               $extensionMock->setDependencies($dependencyStorage);
+               /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Utility\DependencyUtility $dependencyUtility */
+               $dependencyUtility = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('checkPhpDependency', 'checkTypo3Dependency'));
                $dependencyUtility->expects($this->atLeastOnce())->method('checkPhpDependency');
-               $dependencyUtility->_call('checkDependencies', $dependencyStorage);
+               $dependencyUtility->checkDependencies($extensionMock);
        }
 
        /**
@@ -215,13 +246,19 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function checkDependenciesCallsMethodToCheckTypo3Dependencies() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
-               $dependencyModelMock->_set('identifier', 'TyPo3');
+               /** @var \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extensionMock */
+               $extensionMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension', array('dummy'));
+               /** @var \TYPO3\CMS\Extensionmanager\Domain\Model\Dependency $dependencyMock */
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
+               $dependencyMock->setIdentifier('typo3');
                $dependencyStorage = new \SplObjectStorage();
-               $dependencyStorage->attach($dependencyModelMock);
-               $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('checkPhpDependency', 'checkTypo3Dependency'));
+               $dependencyStorage->attach($dependencyMock);
+               $extensionMock->setDependencies($dependencyStorage);
+               /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Utility\DependencyUtility $dependencyUtility */
+               $dependencyUtility = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('checkPhpDependency', 'checkTypo3Dependency'));
+
                $dependencyUtility->expects($this->atLeastOnce())->method('checkTypo3Dependency');
-               $dependencyUtility->_call('checkDependencies', $dependencyStorage);
+               $dependencyUtility->checkDependencies($extensionMock);
        }
 
        /**
@@ -229,12 +266,14 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function isVersionCompatibleReturnsTrueForCompatibleVersion() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue('15.0.0'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
+               /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Domain\Model\Dependency $dependencyMock */
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue('15.0.0'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
                $version = '3.3.3';
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
-               $this->assertTrue($dependencyUtility->_call('isVersionCompatible', $version, $dependencyModelMock));
+
+               $this->assertTrue($dependencyUtility->_call('isVersionCompatible', $version, $dependencyMock));
        }
 
        /**
@@ -242,12 +281,14 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function isVersionCompatibleReturnsFalseForIncompatibleVersion() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue('1.0.1'));
-               $dependencyModelMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
+               /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Domain\Model\Dependency $dependencyMock */
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getHighestVersion')->will($this->returnValue('1.0.1'));
+               $dependencyMock->expects($this->atLeastOnce())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
                $version = '3.3.3';
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
-               $this->assertFalse($dependencyUtility->_call('isVersionCompatible', $version, $dependencyModelMock));
+
+               $this->assertFalse($dependencyUtility->_call('isVersionCompatible', $version, $dependencyMock));
        }
 
        /**
@@ -260,10 +301,11 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                        'foo' => array(),
                        'bar' => array()
                );
-               $listUtilityMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\ListUtility', array('getAvailableExtensions'));
+               $listUtilityMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\ListUtility', array('getAvailableExtensions'));
                $listUtilityMock->expects($this->atLeastOnce())->method('getAvailableExtensions')->will($this->returnValue($availableExtensions));
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
                $dependencyUtility->_set('listUtility', $listUtilityMock);
+
                $this->assertTrue($dependencyUtility->_call('isDependentExtensionAvailable', 'dummy'));
        }
 
@@ -277,10 +319,11 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                        'foo' => array(),
                        'bar' => array()
                );
-               $listUtilityMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\ListUtility', array('getAvailableExtensions'));
+               $listUtilityMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\ListUtility', array('getAvailableExtensions'));
                $listUtilityMock->expects($this->atLeastOnce())->method('getAvailableExtensions')->will($this->returnValue($availableExtensions));
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
                $dependencyUtility->_set('listUtility', $listUtilityMock);
+
                $this->assertFalse($dependencyUtility->_call('isDependentExtensionAvailable', '42'));
        }
 
@@ -289,14 +332,14 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function isAvailableVersionCompatibleCallsIsVersionCompatibleWithExtensionVersion() {
-               $emConfUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\EmConfUtility', array('includeEmConf'));
+               $emConfUtility = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\EmConfUtility', array('includeEmConf'));
                $emConfUtility->expects($this->once())->method('includeEmConf')->will($this->returnValue(array(
                        'key' => 'dummy',
                        'version' => '1.0.0'
                )));
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('setAvailableExtensions', 'isVersionCompatible'));
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getIdentifier'));
-               $dependencyModelMock->expects($this->once())->method('getIdentifier')->will($this->returnValue('dummy'));
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getIdentifier'));
+               $dependencyMock->expects($this->once())->method('getIdentifier')->will($this->returnValue('dummy'));
                $dependencyUtility->_set('emConfUtility', $emConfUtility);
                $dependencyUtility->_set('availableExtensions', array(
                        'dummy' => array(
@@ -305,7 +348,7 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                ));
                $dependencyUtility->expects($this->once())->method('setAvailableExtensions');
                $dependencyUtility->expects($this->once())->method('isVersionCompatible')->with('1.0.0', $this->anything());
-               $dependencyUtility->_call('isAvailableVersionCompatible', $dependencyModelMock);
+               $dependencyUtility->_call('isAvailableVersionCompatible', $dependencyMock);
        }
 
        /**
@@ -313,11 +356,12 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function isExtensionDownloadableFromTerReturnsTrueIfOneVersionExists() {
-               $extensionRepositoryMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Repository\\ExtensionRepository', array('countByExtensionKey'), array($this->mockObjectManager));
+               $extensionRepositoryMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Repository\\ExtensionRepository', array('countByExtensionKey'), array($this->objectManagerMock));
                $extensionRepositoryMock->expects($this->once())->method('countByExtensionKey')->with('test123')->will($this->returnValue(1));
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
                $dependencyUtility->_set('extensionRepository', $extensionRepositoryMock);
                $count = $dependencyUtility->_call('isExtensionDownloadableFromTer', 'test123');
+
                $this->assertTrue($count);
        }
 
@@ -326,11 +370,12 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function isExtensionDownloadableFromTerReturnsFalseIfNoVersionExists() {
-               $extensionRepositoryMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Repository\\ExtensionRepository', array('countByExtensionKey'), array($this->mockObjectManager));
+               $extensionRepositoryMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Repository\\ExtensionRepository', array('countByExtensionKey'), array($this->objectManagerMock));
                $extensionRepositoryMock->expects($this->once())->method('countByExtensionKey')->with('test123')->will($this->returnValue(0));
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
                $dependencyUtility->_set('extensionRepository', $extensionRepositoryMock);
                $count = $dependencyUtility->_call('isExtensionDownloadableFromTer', 'test123');
+
                $this->assertFalse($count);
        }
 
@@ -339,15 +384,16 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function isDownloadableVersionCompatibleReturnsTrueIfCompatibleVersionExists() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getIdentifier', 'getHighestVersion', 'getLowestVersion'));
-               $dependencyModelMock->expects($this->once())->method('getIdentifier')->will($this->returnValue('dummy'));
-               $dependencyModelMock->expects($this->once())->method('getHighestVersion')->will($this->returnValue('10.0.0'));
-               $dependencyModelMock->expects($this->once())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
-               $extensionRepositoryMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Repository\\ExtensionRepository', array('countByVersionRangeAndExtensionKey'), array($this->mockObjectManager));
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getIdentifier', 'getHighestVersion', 'getLowestVersion'));
+               $dependencyMock->expects($this->once())->method('getIdentifier')->will($this->returnValue('dummy'));
+               $dependencyMock->expects($this->once())->method('getHighestVersion')->will($this->returnValue('10.0.0'));
+               $dependencyMock->expects($this->once())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
+               $extensionRepositoryMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Repository\\ExtensionRepository', array('countByVersionRangeAndExtensionKey'), array($this->objectManagerMock));
                $extensionRepositoryMock->expects($this->once())->method('countByVersionRangeAndExtensionKey')->with('dummy', 1000000, 10000000)->will($this->returnValue(2));
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
                $dependencyUtility->_set('extensionRepository', $extensionRepositoryMock);
-               $count = $dependencyUtility->_call('isDownloadableVersionCompatible', $dependencyModelMock);
+               $count = $dependencyUtility->_call('isDownloadableVersionCompatible', $dependencyMock);
+
                $this->assertTrue($count);
        }
 
@@ -356,9 +402,9 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function isDownloadableVersionCompatibleReturnsFalseIfIncompatibleVersionExists() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getIdentifier'));
-               $dependencyModelMock->expects($this->once())->method('getIdentifier')->will($this->returnValue('dummy'));
-               $extensionRepositoryMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Repository\\ExtensionRepository', array('countByVersionRangeAndExtensionKey'), array($this->mockObjectManager));
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getIdentifier'));
+               $dependencyMock->expects($this->once())->method('getIdentifier')->will($this->returnValue('dummy'));
+               $extensionRepositoryMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Repository\\ExtensionRepository', array('countByVersionRangeAndExtensionKey'), array($this->objectManagerMock));
                $extensionRepositoryMock->expects($this->once())->method('countByVersionRangeAndExtensionKey')->with('dummy', 1000000, 2000000)->will($this->returnValue(0));
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('getLowestAndHighestIntegerVersions'));
                $dependencyUtility->_set('extensionRepository', $extensionRepositoryMock);
@@ -366,7 +412,8 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                        'lowestIntegerVersion' => 1000000,
                        'highestIntegerVersion' => 2000000
                )));
-               $count = $dependencyUtility->_call('isDownloadableVersionCompatible', $dependencyModelMock);
+               $count = $dependencyUtility->_call('isDownloadableVersionCompatible', $dependencyMock);
+
                $this->assertFalse($count);
        }
 
@@ -375,15 +422,18 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @return void
         */
        public function getLowestAndHighestIntegerVersionsReturnsArrayWithVersions() {
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
-               $dependencyModelMock->expects($this->once())->method('getHighestVersion')->will($this->returnValue('2.0.0'));
-               $dependencyModelMock->expects($this->once())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
-               $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
-               $versions = $dependencyUtility->_call('getLowestAndHighestIntegerVersions', $dependencyModelMock);
-               $this->assertEquals(array(
+               $expectedVersions = array(
                        'lowestIntegerVersion' => 1000000,
                        'highestIntegerVersion' => 2000000
-               ), $versions);
+               );
+
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getHighestVersion', 'getLowestVersion'));
+               $dependencyMock->expects($this->once())->method('getHighestVersion')->will($this->returnValue('2.0.0'));
+               $dependencyMock->expects($this->once())->method('getLowestVersion')->will($this->returnValue('1.0.0'));
+               $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('dummy'));
+               $versions = $dependencyUtility->_call('getLowestAndHighestIntegerVersions', $dependencyMock);
+
+               $this->assertSame($expectedVersions, $versions);
        }
 
        /**
@@ -402,19 +452,20 @@ class DependencyUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                $myStorage = new $className();
                $myStorage->extensions[] = $extension1;
                $myStorage->extensions[] = $extension2;
-               $dependencyModelMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getIdentifier'));
-               $dependencyModelMock->expects($this->once())->method('getIdentifier')->will($this->returnValue('foobar'));
+               $dependencyMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Dependency', array('getIdentifier'));
+               $dependencyMock->expects($this->once())->method('getIdentifier')->will($this->returnValue('foobar'));
                $dependencyUtility = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility', array('getLowestAndHighestIntegerVersions'));
                $dependencyUtility->expects($this->once())->method('getLowestAndHighestIntegerVersions')->will($this->returnValue(array(
                        'lowestIntegerVersion' => 1000000,
                        'highestIntegerVersion' => 2000000
                )));
-               $extensionRepositoryMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Repository\\ExtensionRepository', array('findByVersionRangeAndExtensionKeyOrderedByVersion'), array($this->mockObjectManager));
+               $extensionRepositoryMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Repository\\ExtensionRepository', array('findByVersionRangeAndExtensionKeyOrderedByVersion'), array($this->objectManagerMock));
                $extensionRepositoryMock->expects($this->once())->method('findByVersionRangeAndExtensionKeyOrderedByVersion')->with('foobar', 1000000, 2000000)->will($this->returnValue($myStorage));
                $dependencyUtility->_set('extensionRepository', $extensionRepositoryMock);
-               $extension = $dependencyUtility->_call('getLatestCompatibleExtensionByIntegerVersionDependency', $dependencyModelMock);
-               $this->assertTrue($extension instanceof \TYPO3\CMS\Extensionmanager\Domain\Model\Extension);
-               $this->assertEquals('foo', $extension->getExtensionKey());
+               $extension = $dependencyUtility->_call('getLatestCompatibleExtensionByIntegerVersionDependency', $dependencyMock);
+
+               $this->assertInstanceOf('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension', $extension);
+               $this->assertSame('foo', $extension->getExtensionKey());
        }
 
 }
index 9b4e810..4ac67f1 100644 (file)
@@ -8,10 +8,10 @@ if (TYPO3_MODE === 'BE') {
                'TYPO3.CMS.' . $_EXTKEY,
                'tools',
                'extensionmanager', '', array(
-                       'List' => 'index,ter,showAllVersions,distributions',
-                       'Action' => 'toggleExtensionInstallationState,removeExtension,downloadExtensionZip,downloadExtensionData',
+                       'List' => 'index,unresolvedDependencies,ter,showAllVersions,distributions',
+                       'Action' => 'toggleExtensionInstallationState,installExtensionWithoutSystemDependencyCheck,removeExtension,downloadExtensionZip,downloadExtensionData',
                        'Configuration' => 'showConfigurationForm,save',
-                       'Download' => 'checkDependencies,installFromTer,installDistribution,updateExtension,updateCommentForUpdatableVersions',
+                       'Download' => 'checkDependencies,installFromTer,installExtensionWithoutSystemDependencyCheck,installDistribution,updateExtension,updateCommentForUpdatableVersions',
                        'UpdateScript' => 'show',
                        'UpdateFromTer' => 'updateExtensionListFromTer',
                        'UploadExtensionFile' => 'form,extract',