Add support for uninstall scripts
authorMatthias Schmidt <gravatronics@live.com>
Sun, 24 Jan 2016 10:44:01 +0000 (11:44 +0100)
committerMatthias Schmidt <gravatronics@live.com>
Sun, 24 Jan 2016 10:44:01 +0000 (11:44 +0100)
CHANGELOG.md
wcfsetup/install/files/acp/uninstall/.htaccess [new file with mode: 0644]
wcfsetup/install/files/lib/system/package/PackageUninstallationDispatcher.class.php

index 2dbfa1e2024c67fd011495bfe4f272622e9f1f76..95d9383b77bebb780885bdf3ee0506d49cc6d8b4 100644 (file)
@@ -39,6 +39,7 @@
 * `permissions` and `options` support for event listener PIP.
 * `name` attribute for event listener PIP (`listenerName` for event listener objects).
 * `permissions` and `options` support for template listener PIP.
+* file `{WCF_DIR}/acp/uninstall/{packageName}.php` is automatically executed if package is uninstalled right before the first file PIP is executed
 
 #### Removed Code
 
diff --git a/wcfsetup/install/files/acp/uninstall/.htaccess b/wcfsetup/install/files/acp/uninstall/.htaccess
new file mode 100644 (file)
index 0000000..3418e55
--- /dev/null
@@ -0,0 +1 @@
+deny from all
\ No newline at end of file
index abd508403c79d0fec16c56b0e20711bd83b96dd7..f1a4c41a4c863b7b0ed8f115d64e20d1fdd442bc 100644 (file)
@@ -20,17 +20,24 @@ use wcf\system\WCF;
  * Handles the whole uninstallation process.
  * 
  * @author     Alexander Ebert
- * @copyright  2001-2015 WoltLab GmbH
+ * @copyright  2001-2016 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    com.woltlab.wcf
  * @subpackage system.package
  * @category   Community Framework
  */
 class PackageUninstallationDispatcher extends PackageInstallationDispatcher {
+       /**
+        * is true if the package's uninstall script has been executed or if no
+        * such script exists
+        * @var boolean
+        */
+       protected $didExecuteUninstallScript = false;
+       
        /**
         * Creates a new instance of PackageUninstallationDispatcher.
         * 
-        * @param       \wcf\data\package\installation\queue\PackageInstallationQueue   $queue
+        * @param       PackageInstallationQueue        $queue
         */
        public function __construct(PackageInstallationQueue $queue) {
                $this->queue = $queue;
@@ -58,6 +65,14 @@ class PackageUninstallationDispatcher extends PackageInstallationDispatcher {
                                break;
                                
                                case 'pip':
+                                       // the file pip is always executed last, thus, just before it,
+                                       // execute the uninstall script
+                                       if ($nodeData['pluginName'] == 'file' && !$this->didExecuteUninstallScript) {
+                                               $this->executeUninstallScript();
+                                               
+                                               $this->didExecuteUninstallScript = true;
+                                       }
+                                       
                                        $this->executePIP($nodeData);
                                break;
                        }
@@ -96,7 +111,7 @@ class PackageUninstallationDispatcher extends PackageInstallationDispatcher {
        }
        
        /**
-        * @see \wcf\system\package\PackageInstallationDispatcher::executePIP()
+        * @inheritDoc
         */
        protected function executePIP(array $nodeData) {
                $pip = new $nodeData['className']($this);
@@ -104,23 +119,36 @@ class PackageUninstallationDispatcher extends PackageInstallationDispatcher {
                $pip->uninstall();
        }
        
+       /**
+        * Executes the package's uninstall script (if existing).
+        * 
+        * @since       2.2
+        */
+       protected function executeUninstallScript() {
+               // check if uninstall script file for the uninstalled package exists
+               $uninstallScript = WCF_DIR.'acp/uninstall/'.$this->package->package.'.php';
+               if (file_exists($uninstallScript)) {
+                       include($uninstallScript);
+               }
+       }
+       
        /**
         * Uninstalls current package.
         * 
         * @param       array           $nodeData
         */
        protected function uninstallPackage(array $nodeData) {
-               PackageEditor::deleteAll(array($this->queue->packageID));
+               PackageEditor::deleteAll([$this->queue->packageID]);
                
                // remove localized package infos
                // todo: license/readme
                $sql = "DELETE FROM     wcf".WCF_N."_language_item
                        WHERE           languageItem IN (?, ?)";
                $statement = WCF::getDB()->prepareStatement($sql);
-               $statement->execute(array(
+               $statement->execute([
                        'wcf.acp.package.packageName.package'.$this->queue->packageID,
                        'wcf.acp.package.packageDescription.package'.$this->queue->packageID
-               ));
+               ]);
                
                // reset package cache
                PackageCacheBuilder::getInstance()->reset();
@@ -163,7 +191,7 @@ class PackageUninstallationDispatcher extends PackageInstallationDispatcher {
                        throw new IllegalLinkException();
                }
                
-               $dependentPackages = array();
+               $dependentPackages = [];
                $uninstallAvailable = true;
                if ($package->isRequired()) {
                        // get packages that requires this package
@@ -186,24 +214,24 @@ class PackageUninstallationDispatcher extends PackageInstallationDispatcher {
         * @param       Package         $package
         * @param       array           $packages
         */
-       public static function addQueueEntries(Package $package, $packages = array()) {
+       public static function addQueueEntries(Package $package, $packages = []) {
                // get new process no
                $processNo = PackageInstallationQueue::getNewProcessNo();
                
                // add dependent packages to queue
-               $statementParameters = array();
+               $statementParameters = [];
                foreach ($packages as $dependentPackage) {
-                       $statementParameters[] = array(
+                       $statementParameters[] = [
                                'packageName' => $dependentPackage['packageName'],
                                'packageID' => $dependentPackage['packageID']
-                       );
+                       ];
                }
                
                // add uninstalling package to queue
-               $statementParameters[] = array(
+               $statementParameters[] = [
                        'packageName' => $package->getName(),
                        'packageID' => $package->packageID
-               );
+               ];
                
                // insert queue entry (entries)
                $sql = "INSERT INTO     wcf".WCF_N."_package_installation_queue
@@ -211,13 +239,13 @@ class PackageUninstallationDispatcher extends PackageInstallationDispatcher {
                        VALUES          (?, ?, ?, ?, ?)";
                $statement = WCF::getDB()->prepareStatement($sql);
                foreach ($statementParameters as $parameter) {
-                       $statement->execute(array(
+                       $statement->execute([
                                $processNo,
                                WCF::getUser()->userID,
                                $parameter['packageName'],
                                $parameter['packageID'],
                                'uninstall'
-                       ));
+                       ]);
                }
                
                self::openQueue(0, $processNo);