Delete language items when uninstalling cronjobs, menus and menu items
authorMatthias Schmidt <gravatronics@live.com>
Sun, 14 Apr 2019 14:22:15 +0000 (16:22 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Sun, 14 Apr 2019 14:22:15 +0000 (16:22 +0200)
Close #2896

wcfsetup/install/files/lib/data/cronjob/CronjobEditor.class.php
wcfsetup/install/files/lib/data/menu/MenuEditor.class.php
wcfsetup/install/files/lib/data/menu/item/MenuItemEditor.class.php
wcfsetup/install/files/lib/system/package/plugin/CronjobPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/MenuItemPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/MenuPackageInstallationPlugin.class.php

index 506b8ca7a3fc90e2c02e64dcb3837e48cfd231b9..ba56df818e2318036352734b7801facc63cdc3a2 100644 (file)
@@ -144,6 +144,26 @@ class CronjobEditor extends DatabaseObjectEditor implements IEditableCachedObjec
                }
        }
        
+       /**
+        * @inheritDoc
+        */
+       public static function deleteAll(array $objectIDs = []) {
+               // delete language items
+               if (!empty($objectIDs)) {
+                       $sql = "DELETE FROM     wcf".WCF_N."_language_item
+                               WHERE           languageItem = ?";
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       
+                       WCF::getDB()->beginTransaction();
+                       foreach ($objectIDs as $cronjobID) {
+                               $statement->execute(['wcf.acp.cronjob.description.cronjob' . $cronjobID]);
+                       }
+                       WCF::getDB()->commitTransaction();
+               }
+               
+               return parent::deleteAll($objectIDs);
+       }
+       
        /**
         * @inheritDoc
         */
index dfa6481c4d379ec1e5a4cfcf132f001d609b216f..3d977908b2de8eb8e971cc1c5c457c3ed4794841 100644 (file)
@@ -79,6 +79,32 @@ class MenuEditor extends DatabaseObjectEditor implements IEditableCachedObject {
                return $menu;
        }
        
+       /**
+        * @inheritDoc
+        */
+       public static function deleteAll(array $objectIDs = []) {
+               if (!empty($objectIDs)) {
+                       // delete language items
+                       $menuList = new MenuList();
+                       $menuList->setObjectIDs($objectIDs);
+                       $menuList->readObjects();
+                       
+                       if (count($menuList)) {
+                               $sql = "DELETE FROM     wcf".WCF_N."_language_item
+                                       WHERE           languageItem = ?";
+                               $statement = WCF::getDB()->prepareStatement($sql);
+                               
+                               WCF::getDB()->beginTransaction();
+                               foreach ($menuList as $menu) {
+                                       $statement->execute(['wcf.menu.' . $menu->identifier]);
+                               }
+                               WCF::getDB()->commitTransaction();
+                       }
+               }
+               
+               return parent::deleteAll($objectIDs);
+       }
+       
        /**
         * @inheritDoc
         */
index 41026e20badffc95d1319d1f55a8f89d577bd932..00b231517310e7e6d2b6a25499e7e4fddb178259 100644 (file)
@@ -79,6 +79,32 @@ class MenuItemEditor extends DatabaseObjectEditor implements IEditableCachedObje
                return $menuItem;
        }
        
+       /**
+        * @inheritDoc
+        */
+       public static function deleteAll(array $objectIDs = []) {
+               if (!empty($objectIDs)) {
+                       // delete language items
+                       $menuItemList = new MenuItemList();
+                       $menuItemList->setObjectIDs($objectIDs);
+                       $menuItemList->readObjects();
+                       
+                       if (count($menuItemList)) {
+                               $sql = "DELETE FROM     wcf".WCF_N."_language_item
+                                       WHERE           languageItem = ?";
+                               $statement = WCF::getDB()->prepareStatement($sql);
+                               
+                               WCF::getDB()->beginTransaction();
+                               foreach ($menuItemList as $menuItem) {
+                                       $statement->execute(['wcf.menu.item.' . $menuItem->identifier]);
+                               }
+                               WCF::getDB()->commitTransaction();
+                       }
+               }
+               
+               return parent::deleteAll($objectIDs);
+       }
+       
        /**
         * @inheritDoc
         */
index 9df9e06784a71edc9701481661c91edd5f354d3c..c24ec7afeca53a14771d60578ed5834a21386a27 100644 (file)
@@ -2,7 +2,9 @@
 namespace wcf\system\package\plugin;
 use wcf\data\cronjob\Cronjob;
 use wcf\data\cronjob\CronjobEditor;
+use wcf\data\cronjob\CronjobList;
 use wcf\system\cronjob\ICronjob;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\devtools\pip\IDevtoolsPipEntryList;
 use wcf\system\devtools\pip\IGuiPackageInstallationPlugin;
 use wcf\system\devtools\pip\TXmlGuiPackageInstallationPlugin;
@@ -56,30 +58,41 @@ class CronjobPackageInstallationPlugin extends AbstractXMLPackageInstallationPlu
         * @inheritDoc
         */
        protected function handleDelete(array $items) {
-               $sql = "DELETE FROM     wcf".WCF_N."_".$this->tableName."
-                       WHERE           className = ?
-                                       AND packageID = ?";
-               $legacyStatement = WCF::getDB()->prepareStatement($sql);
-               
-               $sql = "DELETE FROM     wcf".WCF_N."_".$this->tableName."
-                       WHERE           cronjobName = ?
-                                       AND packageID = ?";
-               $statement = WCF::getDB()->prepareStatement($sql);
-               
+               // read cronjobs from database because deleting the language items requires the
+               // cronjob id
+               $cronjobs = $legacyCronjobs = [];
                foreach ($items as $item) {
                        if (!isset($item['attributes']['name'])) {
-                               $legacyStatement->execute([
-                                       $item['elements']['classname'],
-                                       $this->installation->getPackageID()
-                               ]);
+                               $legacyCronjobs[] = $item['elements']['classname'];
                        }
                        else {
-                               $statement->execute([
-                                       $item['attributes']['name'],
-                                       $this->installation->getPackageID()
-                               ]);
+                               $cronjobs[] = $item['attributes']['name'];
                        }
                }
+               
+               if (empty($cronjobs) && empty($legacyCronjobs)) {
+                       return;
+               }
+               
+               $cronjobList = new CronjobList();
+               $cronjobList->getConditionBuilder()->add(
+                       'packageID = ?',
+                       [$this->installation->getPackageID()]
+               );
+               
+               $conditionBuilder = new PreparedStatementConditionBuilder(false, 'OR');
+               if (!empty($cronjobs)) {
+                       $conditionBuilder->add('cronjobName IN (?)', [$cronjobs]);
+               }
+               if (!empty($legacyCronjobs)) {
+                       $conditionBuilder->add('className IN (?)', [$legacyCronjobs]);
+               }
+               $cronjobList->getConditionBuilder()->add($conditionBuilder, $conditionBuilder->getParameters());
+               $cronjobList->readObjectIDs();
+               
+               if (!empty($cronjobList->getObjectIDs())) {
+                       CronjobEditor::deleteAll($cronjobList->getObjectIDs());
+               }
        }
        
        /**
index ce48e9a2e31aca488978de28a333423218992040..19d7ad164617f0debf165742641c77db2dfadf95 100644 (file)
@@ -56,12 +56,20 @@ class MenuItemPackageInstallationPlugin extends AbstractXMLPackageInstallationPl
                                        AND packageID = ?";
                $statement = WCF::getDB()->prepareStatement($sql);
                
+               $sql = "DELETE FROM     wcf" . WCF_N . "_language_item
+                       WHERE           languageItem = ?";
+               $languageItemStatement = WCF::getDB()->prepareStatement($sql);
+               
                WCF::getDB()->beginTransaction();
                foreach ($items as $item) {
                        $statement->execute([
                                $item['attributes']['identifier'],
                                $this->installation->getPackageID()
                        ]);
+                       
+                       $languageItemStatement->execute([
+                               'wcf.menu.item.' . $item['attributes']['identifier']
+                       ]);
                }
                WCF::getDB()->commitTransaction();
        }
index d72b0e2d8f3cc1100a78f80deccccae27eada8bb..a5b095a1661d636dbc47b4b198390812e77c3dcc 100644 (file)
@@ -71,12 +71,20 @@ class MenuPackageInstallationPlugin extends AbstractXMLPackageInstallationPlugin
                                        AND packageID = ?";
                $statement = WCF::getDB()->prepareStatement($sql);
                
+               $sql = "DELETE FROM     wcf" . WCF_N . "_language_item
+                       WHERE           languageItem = ?";
+               $languageItemStatement = WCF::getDB()->prepareStatement($sql);
+               
                WCF::getDB()->beginTransaction();
                foreach ($items as $item) {
                        $statement->execute([
                                $item['attributes']['identifier'],
                                $this->installation->getPackageID()
                        ]);
+                       
+                       $languageItemStatement->execute([
+                               'wcf.menu.' . $item['attributes']['identifier']
+                       ]);
                }
                WCF::getDB()->commitTransaction();
        }