Fix various issues when saving gui-edited PIP entries
authorMatthias Schmidt <gravatronics@live.com>
Fri, 16 Nov 2018 18:06:32 +0000 (19:06 +0100)
committerMatthias Schmidt <gravatronics@live.com>
Fri, 16 Nov 2018 18:06:32 +0000 (19:06 +0100)
See #2545

27 files changed:
wcfsetup/install/files/lib/system/box/AbstractDatabaseObjectListBoxController.class.php
wcfsetup/install/files/lib/system/devtools/pip/TXmlGuiPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/ACLOptionPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/ACPMenuPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/ACPSearchProviderPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/AbstractMenuPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/AbstractOptionPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/AbstractXMLPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/BBCodePackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/BoxPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/ClipboardActionPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/CronjobPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/EventListenerPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/LanguagePackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/MediaProviderPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/MenuItemPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/ObjectTypeDefinitionPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/OptionPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/PagePackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/SmileyPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/TemplateListenerPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/UserGroupOptionPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/UserMenuPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/UserNotificationEventPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/UserOptionPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/UserProfileMenuPackageInstallationPlugin.class.php
wcfsetup/install/lang/en.xml

index 4748d59660a6ea40c1ae18ca7d85d71aadb6f032..dbc18b0723365d3f0777b78798e299e989b55af0 100644 (file)
@@ -159,7 +159,10 @@ abstract class AbstractDatabaseObjectListBoxController extends AbstractBoxContro
                                        ->objectProperty('sortField')
                                        ->label('wcf.acp.box.controller.sortField')
                                        ->description('wcf.acp.box.controller.sortField.description')
-                                       ->options(array_combine($this->validSortFields, $this->validSortFields))
+                                       ->options(array_merge(
+                                               ['' => 'wcf.global.noSelection'],
+                                               array_combine($this->validSortFields, $this->validSortFields)
+                                       ))
                                        ->addDependency(
                                                ValueFormFieldDependency::create('boxType')
                                                        ->field($objectTypeField)
@@ -168,6 +171,11 @@ abstract class AbstractDatabaseObjectListBoxController extends AbstractBoxContro
                                
                                SortOrderFormField::create($prefix . 'sortOrder')
                                        ->objectProperty('sortOrder')
+                                       ->options([
+                                               '' => 'wcf.global.noSelection',
+                                               'ASC' => 'wcf.global.sortOrder.ascending',
+                                               'DESC' => 'wcf.global.sortOrder.descending',
+                                       ])
                                        ->addDependency(
                                                ValueFormFieldDependency::create('boxType')
                                                        ->field($objectTypeField)
index ae709f4903b2ddf7ecc6ae244adca3a71332fd71..574c5d23603a9c8e2eb81aa3516c9a290ed7005e 100644 (file)
@@ -7,6 +7,7 @@ use wcf\system\form\builder\field\IFormField;
 use wcf\system\form\builder\IFormDocument;
 use wcf\system\form\builder\IFormNode;
 use wcf\system\package\PackageInstallationDispatcher;
+use wcf\system\package\plugin\AbstractXMLPackageInstallationPlugin;
 use wcf\system\WCF;
 use wcf\util\DOMUtil;
 use wcf\util\StringUtil;
@@ -24,6 +25,7 @@ use wcf\util\XML;
  * @since      3.2
  * 
  * @property   PackageInstallationDispatcher|DevtoolsPackageInstallationDispatcher     $installation
+ * @mixin      AbstractXMLPackageInstallationPlugin
  */
 trait TXmlGuiPackageInstallationPlugin {
        /**
@@ -69,7 +71,7 @@ trait TXmlGuiPackageInstallationPlugin {
        /**
         * Adds optional child elements to the given elements based on the given
         * child data and form.
-        *
+        * 
         * @param       \DOMElement     $element                element to which the child elements are added
         * @param       array           $children
         * @param       IFormDocument   $form                   form containing the children's data
@@ -79,22 +81,22 @@ trait TXmlGuiPackageInstallationPlugin {
                
                $document = $element->ownerDocument;
                
-               foreach ($children as $index => $key) {
-                       if (is_string($index)) {
-                               $childName = $index;
-                               if (!is_array($key)) {
+               foreach ($children as $key => $value) {
+                       if (is_string($key)) {
+                               $childName = $key;
+                               if (!is_array($value)) {
                                        $isOptional = true;
                                        $cdata = false;
-                                       $defaultValue = $key;
+                                       $defaultValue = $value;
                                }
                                else {
-                                       $isOptional = array_key_exists('defaultValue', $key);
-                                       $cdata = $key['cdata'] ?? false;
-                                       $defaultValue = $key['defaultValue'] ?? null;
+                                       $isOptional = array_key_exists('defaultValue', $value);
+                                       $cdata = $value['cdata'] ?? false;
+                                       $defaultValue = $value['defaultValue'] ?? null;
                                }
                        }
                        else {
-                               $childName = $key;
+                               $childName = $value;
                                $isOptional = false;
                                $cdata = false;
                                $defaultValue = null;
index 38bdfd8612f95a5128204db4486026359ee186dd..f800730b4982264a30274004b8b691ce22e864fe 100644 (file)
@@ -2,6 +2,8 @@
 namespace wcf\system\package\plugin;
 use wcf\data\acl\option\ACLOptionEditor;
 use wcf\data\acl\option\ACLOptionList;
+use wcf\data\acl\option\category\ACLOptionCategory;
+use wcf\data\acl\option\category\ACLOptionCategoryEditor;
 use wcf\data\acl\option\category\ACLOptionCategoryList;
 use wcf\data\object\type\ObjectTypeCache;
 use wcf\system\devtools\pip\IDevtoolsPipEntryList;
@@ -147,32 +149,65 @@ class ACLOptionPackageInstallationPlugin extends AbstractOptionPackageInstallati
         * @inheritDoc
         */
        protected function saveCategory($category) {
-               $objectTypeID = $this->getObjectTypeID($category['objecttype'] ?? $category['objectType']);
+               if (isset($category['objectTypeID'])) {
+                       $objectTypeID = $category['objectTypeID'];
+               }
+               else {
+                       $objectTypeID = $this->getObjectTypeID($category['objecttype']);
+               }
                
-               // search existing category
-               $sql = "SELECT  categoryID
-                       FROM    wcf".WCF_N."_".$this->tableName."_category
-                       WHERE   categoryName = ?
-                               AND objectTypeID = ?
-                               AND packageID = ?";
-               $statement = WCF::getDB()->prepareStatement($sql);
-               $statement->execute([
-                       $category['categoryName'],
-                       $objectTypeID,
-                       $this->installation->getPackageID()
-               ]);
-               $row = $statement->fetchArray();
-               if (!$row) {
-                       // insert new category
-                       $sql = "INSERT INTO     wcf".WCF_N."_".$this->tableName."_category
-                                               (packageID, objectTypeID, categoryName)
-                               VALUES          (?, ?, ?)";
+               if ($this->editedEntry === null) {
+                       // search existing category
+                       $sql = "SELECT  categoryID
+                               FROM    wcf".WCF_N."_".$this->tableName."_category
+                               WHERE   categoryName = ?
+                                       AND objectTypeID = ?
+                                       AND packageID = ?";
                        $statement = WCF::getDB()->prepareStatement($sql);
                        $statement->execute([
-                               $this->installation->getPackageID(),
+                               $category['categoryName'],
                                $objectTypeID,
-                               $category['categoryName']
+                               $this->installation->getPackageID()
                        ]);
+                       $row = $statement->fetchArray();
+                       if (!$row) {
+                               // insert new category
+                               $sql = "INSERT INTO     wcf".WCF_N."_".$this->tableName."_category
+                                                       (packageID, objectTypeID, categoryName)
+                                       VALUES          (?, ?, ?)";
+                               $statement = WCF::getDB()->prepareStatement($sql);
+                               $statement->execute([
+                                       $this->installation->getPackageID(),
+                                       $objectTypeID,
+                                       $category['categoryName']
+                               ]);
+                       }
+               }
+               else {
+                       $editedData = $this->getElementData($this->editedEntry, true);
+                       
+                       $sql = "SELECT  categoryID
+                               FROM    wcf".WCF_N."_".$this->tableName."_category
+                               WHERE   categoryName = ?
+                                       AND objectTypeID = ?
+                                       AND packageID = ?";
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute([
+                               $editedData['categoryName'],
+                               $editedData['objectTypeID'],
+                               $this->installation->getPackageID()
+                       ]);
+                       $categoryID = $statement->fetchSingleColumn();
+                       
+                       if ($categoryID === false) {
+                               throw new \UnexpectedValueException("Cannot find edited acl option category in database.");
+                       }
+                       else {
+                               (new ACLOptionCategoryEditor(new ACLOptionCategory($categoryID)))->update([
+                                       'categoryName' => $category['categoryName'],
+                                       'objectTypeID' => $objectTypeID
+                               ]);
+                       }
                }
        }
        
@@ -218,41 +253,7 @@ class ACLOptionPackageInstallationPlugin extends AbstractOptionPackageInstallati
                                'objectTypeID' => $objectTypeID
                        ];
                        
-                       // check for option existence
-                       $sql = "SELECT  optionID
-                               FROM    wcf".WCF_N."_".$this->tableName."
-                               WHERE   optionName = ?
-                                       AND objectTypeID = ?
-                                       AND packageID = ?";
-                       $statement = WCF::getDB()->prepareStatement($sql);
-                       $statement->execute([
-                               $data['optionName'],
-                               $data['objectTypeID'],
-                               $this->installation->getPackageID()
-                       ]);
-                       $row = $statement->fetchArray();
-                       if (!$row) {
-                               $sql = "INSERT INTO     wcf".WCF_N."_".$this->tableName."
-                                                       (packageID, objectTypeID, optionName, categoryName)
-                                       VALUES          (?, ?, ?, ?)";
-                               $statement = WCF::getDB()->prepareStatement($sql);
-                               $statement->execute([
-                                       $this->installation->getPackageID(),
-                                       $data['objectTypeID'],
-                                       $data['optionName'],
-                                       $data['categoryName']
-                               ]);
-                       }
-                       else {
-                               $sql = "UPDATE  wcf".WCF_N."_".$this->tableName."
-                                       SET     categoryName = ?
-                                       WHERE   optionID = ?";
-                               $statement = WCF::getDB()->prepareStatement($sql);
-                               $statement->execute([
-                                       $data['categoryName'],
-                                       $row['optionID']
-                               ]);
-                       }
+                       $this->saveOption($data, $data['categoryName']);
                }
        }
        
@@ -260,7 +261,41 @@ class ACLOptionPackageInstallationPlugin extends AbstractOptionPackageInstallati
         * @inheritDoc
         */
        protected function saveOption($option, $categoryName, $existingOptionID = 0) {
-               // does nothing
+               // check for option existence
+               $sql = "SELECT  optionID
+                       FROM    wcf".WCF_N."_".$this->tableName."
+                       WHERE   optionName = ?
+                               AND objectTypeID = ?
+                               AND packageID = ?";
+               $statement = WCF::getDB()->prepareStatement($sql);
+               $statement->execute([
+                       $option['optionName'],
+                       $option['objectTypeID'],
+                       $this->installation->getPackageID()
+               ]);
+               $row = $statement->fetchArray();
+               if (!$row) {
+                       $sql = "INSERT INTO     wcf".WCF_N."_".$this->tableName."
+                                               (packageID, objectTypeID, optionName, categoryName)
+                               VALUES          (?, ?, ?, ?)";
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute([
+                               $this->installation->getPackageID(),
+                               $option['objectTypeID'],
+                               $option['optionName'],
+                               $categoryName
+                       ]);
+               }
+               else {
+                       $sql = "UPDATE  wcf".WCF_N."_".$this->tableName."
+                               SET     categoryName = ?
+                               WHERE   optionID = ?";
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute([
+                               $categoryName,
+                               $row['optionID']
+                       ]);
+               }
        }
        
        /**
@@ -476,20 +511,38 @@ class ACLOptionPackageInstallationPlugin extends AbstractOptionPackageInstallati
         */
        protected function doGetElementData(\DOMElement $element, $saveData) {
                $data = [
-                       'name' => $element->getAttribute('name'),
                        'packageID' => $this->installation->getPackage()->packageID,
                        'objectType' => $element->getElementsByTagName('objecttype')->item(0)->nodeValue
                ];
                
-               if ($this->entryType === 'options') {
-                       $categoryName = $element->getElementsByTagName('categoryname')->item(0);
-                       if ($categoryName !== null) {
-                               $data['categoryname'] = $categoryName->nodeValue;
-                       }
+               switch ($this->entryType) {
+                       case 'categories':
+                               $data['categoryName'] = $element->getAttribute('name');
+                               
+                               break;
+                               
+                       case 'options':
+                               $data['optionName'] = $element->getAttribute('name');
+                               
+                               $categoryName = $element->getElementsByTagName('categoryname')->item(0);
+                               if ($categoryName !== null) {
+                                       $data['categoryname'] = $categoryName->nodeValue;
+                               }
+                               else if ($saveData) {
+                                       $data['categoryname'] = '';
+                               }
+                               
+                               break;
                }
-               else if ($saveData) {
-                       $data['categoryName'] = $data['name'];
-                       unset($data['name']);
+               
+               if (!$saveData) {
+                       $data['name'] = $element->getAttribute('name');
+               }
+               else {
+                       $objectType = $data['objectType'];
+                       unset($data['objectType']);
+                       
+                       $data['objectTypeID'] = $this->getObjectTypeID($objectType);
                }
                
                return $data;
index 5827a3474aff99f8a92ca857a6f3f19a0a80a2e7..50fa14f0267fc4936af6f38d02b528ce7ab9ae31 100644 (file)
@@ -135,6 +135,9 @@ class ACPMenuPackageInstallationPlugin extends AbstractMenuPackageInstallationPl
                if ($icon !== null) {
                        $data['icon'] = $icon->nodeValue;
                }
+               else {
+                       $data['icon'] = '';
+               }
                
                return $data;
        }
index 61a2d461d07d4547de4f86abee98c71fae1651c4..cb769c02eaaf88e5d3f35627ce3bbdadb018fa9c 100644 (file)
@@ -124,6 +124,9 @@ class ACPSearchProviderPackageInstallationPlugin extends AbstractXMLPackageInsta
                if ($showOrder) {
                        $data['showOrder'] = $showOrder->nodeValue;
                }
+               else if ($saveData) {
+                       $data['showOrder'] = $this->getShowOrder(null);
+               }
                
                return $data;
        }
index e5081668a525b4b18398a3b5461d61330116cbe5..620d91143ba5ca32b5a042d4d2c8a70729ed3934 100644 (file)
@@ -327,31 +327,54 @@ abstract class AbstractMenuPackageInstallationPlugin extends AbstractXMLPackageI
                if ($parentMenuItem !== null) {
                        $data['parentMenuItem'] = $parentMenuItem->nodeValue;
                }
+               else if ($saveData) {
+                       $data['parentMenuItem'] = '';
+               }
                
                $controller = $element->getElementsByTagName('controller')->item(0);
                if ($controller !== null) {
                        $data['menuItemController'] = $controller->nodeValue;
                }
+               else if ($saveData) {
+                       $data['menuItemController'] = '';
+               }
                
                $link = $element->getElementsByTagName('link')->item(0);
                if ($link !== null) {
                        $data['menuItemLink'] = $link->nodeValue;
                }
+               else if ($saveData) {
+                       $data['menuItemLink'] = '';
+               }
                
                $options = $element->getElementsByTagName('options')->item(0);
                if ($options !== null) {
                        $data['options'] = $options->nodeValue;
                }
+               else if ($saveData) {
+                       $data['options'] = '';
+               }
                
                $permissions = $element->getElementsByTagName('permissions')->item(0);
                if ($permissions !== null) {
                        $data['permissions'] = $permissions->nodeValue;
                }
+               else if ($saveData) {
+                       $data['permissions'] = '';
+               }
                
                $showOrder = $element->getElementsByTagName('showorder')->item(0);
                if ($showOrder !== null) {
                        $data['showOrder'] = $showOrder->nodeValue;
                }
+               if ($saveData && $this->editedEntry === null) {
+                       // only set explicit showOrder when adding new menu item
+                       $data['showOrder'] = $this->getShowOrder(
+                               $data['showOrder'] ?? null,
+                               $data['parentMenuItem'],
+                               'parentMenuItem'
+                       );
+               }
                
                return $data;
        }
index d2d57af41cece9958b7887c1b39a2d57f00c0c8c..e644947b336f78b7551c9568956465e1ae782184 100644 (file)
@@ -696,9 +696,7 @@ abstract class AbstractOptionPackageInstallationPlugin extends AbstractXMLPackag
         * @since       3.2
         */
        protected function doGetElementData(\DOMElement $element, $saveData) {
-               $data = [
-                       'packageID' => $this->installation->getPackage()->packageID
-               ];
+               $data = [];
                
                switch ($this->entryType) {
                        case 'categories':
@@ -708,82 +706,139 @@ abstract class AbstractOptionPackageInstallationPlugin extends AbstractXMLPackag
                                if ($parent !== null) {
                                        $data['parentCategoryName'] = $parent->nodeValue;
                                }
+                               else if ($saveData) {
+                                       $data['parentCategoryName'] = '';
+                               }
                                
                                foreach (['options', 'permissions'] as $optionalPropertyName) {
                                        $optionalProperty = $element->getElementsByTagName($optionalPropertyName)->item(0);
                                        if ($optionalProperty !== null) {
                                                $data[$optionalPropertyName] = StringUtil::normalizeCsv($optionalProperty->nodeValue);
                                        }
+                                       else if ($saveData) {
+                                               $data[$optionalPropertyName] = '';
+                                       }
                                }
                                
                                $showOrder = $element->getElementsByTagName('showorder')->item(0);
                                if ($showOrder !== null) {
                                        $data['showOrder'] = $showOrder->nodeValue;
                                }
+                               if ($saveData && $this->editedEntry === null) {
+                                       // only set explicit showOrder when adding new categories
+                                       $data['showOrder'] = $this->getShowOrder(
+                                               $data['showOrder'] ?? null,
+                                               $data['parentCategoryName'],
+                                               'parentCategoryName',
+                                               '_category'
+                                       );
+                               }
                                
                                break;
                        
                        case 'options':
-                               $data['optionName'] = $element->getAttribute('name');
-                               $data['categoryName'] = $element->getElementsByTagName('categoryname')->item(0)->nodeValue;
-                               $data['optionType'] = $element->getElementsByTagName('optiontype')->item(0)->nodeValue;
-                               
-                               foreach (['defaultValue', 'enableOptions', 'validationPattern', 'showOrder'] as $optionalPropertyName) {
-                                       $optionalProperty = $element->getElementsByTagName(strtolower($optionalPropertyName))->item(0);
-                                       if ($optionalProperty !== null) {
-                                               $data[$optionalPropertyName] = $optionalProperty->nodeValue;
+                               if (!$saveData) {
+                                       $data['optionName'] = $element->getAttribute('name');
+                                       $data['categoryName'] = $element->getElementsByTagName('categoryname')->item(0)->nodeValue;
+                                       $data['optionType'] = $element->getElementsByTagName('optiontype')->item(0)->nodeValue;
+                                       
+                                       foreach (['defaultValue', 'enableOptions', 'validationPattern'] as $optionalPropertyName) {
+                                               $optionalProperty = $element->getElementsByTagName(strtolower($optionalPropertyName))->item(0);
+                                               if ($optionalProperty !== null) {
+                                                       $data[$optionalPropertyName] = $optionalProperty->nodeValue;
+                                               }
                                        }
-                               }
-                               
-                               foreach (['options', 'permissions'] as $optionalPropertyName) {
-                                       $optionalProperty = $element->getElementsByTagName($optionalPropertyName)->item(0);
-                                       if ($optionalProperty !== null) {
-                                               $data[$optionalPropertyName] = StringUtil::normalizeCsv($optionalProperty->nodeValue);
+                                       
+                                       $showOrder = $element->getElementsByTagName('showorder')->item(0);
+                                       if ($showOrder !== null) {
+                                               $data['showOrder'] = $showOrder->nodeValue;
                                        }
-                               }
-                               
-                               // object-type specific elements
-                               $optionals = [
-                                       'minvalue',
-                                       'maxvalue',
-                                       'suffix',
-                                       'minlength',
-                                       'maxlength',
-                                       'issortable',
-                                       'allowemptyvalue',
-                                       'disableAutocomplete'
-                               ];
-                               
-                               foreach ($optionals as $optionalPropertyName) {
-                                       $optionalProperty = $element->getElementsByTagName($optionalPropertyName)->item(0);
-                                       if ($optionalProperty !== null) {
-                                               $data[$optionalPropertyName] = $optionalProperty->nodeValue;
+                                       
+                                       foreach (['options', 'permissions'] as $optionalPropertyName) {
+                                               $optionalProperty = $element->getElementsByTagName($optionalPropertyName)->item(0);
+                                               if ($optionalProperty !== null) {
+                                                       $data[$optionalPropertyName] = StringUtil::normalizeCsv($optionalProperty->nodeValue);
+                                               }
                                        }
-                               }
-                               
-                               if ($saveData) {
-                                       $lowercaseData = [
-                                               'categoryname' => $data['categoryName'],
-                                               'packageID' => $this->installation->getPackage()->packageID,
-                                               'name' => $data['optionName']
-                                       ];
                                        
-                                       $lowercaseFields = [
-                                               'optionName',
-                                               'optionType',
-                                               'defaultValue',
-                                               'enableOptions',
-                                               'validationPattern',
-                                               'showOrder'
+                                       // object-type specific elements
+                                       $optionals = [
+                                               'minvalue',
+                                               'maxvalue',
+                                               'suffix',
+                                               'minlength',
+                                               'maxlength',
+                                               'issortable',
+                                               'allowemptyvalue',
+                                               'disableAutocomplete'
                                        ];
                                        
-                                       foreach ($lowercaseFields as $name) {
-                                               if (isset($data[$name])) {
-                                                       $lowercaseData[strtolower($name)] = $data[$name];
+                                       foreach ($optionals as $optionalPropertyName) {
+                                               $optionalProperty = $element->getElementsByTagName($optionalPropertyName)->item(0);
+                                               if ($optionalProperty !== null) {
+                                                       $data[$optionalPropertyName] = $optionalProperty->nodeValue;
+                                               }
+                                       }
+                               }
+                               else {
+                                       $data['name'] = $element->getAttribute('name');
+                                       $data['categoryname'] = $element->getElementsByTagName('categoryname')->item(0)->nodeValue;
+                                       $data['optiontype'] = $element->getElementsByTagName('optiontype')->item(0)->nodeValue;
+                                       
+                                       foreach (['defaultvalue', 'enableoptions', 'validationpattern'] as $optionalPropertyName) {
+                                               $optionalProperty = $element->getElementsByTagName($optionalPropertyName)->item(0);
+                                               if ($optionalProperty !== null) {
+                                                       $data[$optionalPropertyName] = $optionalProperty->nodeValue;
+                                               }
+                                               else if ($optionalPropertyName === 'defaultvalue') {
+                                                       $data[$optionalPropertyName] = null;
+                                               }
+                                               else {
+                                                       $data[$optionalPropertyName] = '';
+                                               }
+                                       }
+                                       
+                                       $showOrder = $element->getElementsByTagName('showorder')->item(0);
+                                       if ($showOrder !== null) {
+                                               $data['showorder'] = $showOrder->nodeValue;
+                                       }
+                                       if ($this->editedEntry === null) {
+                                               // only set explicit showOrder when adding new categories
+                                               $data['showorder'] = $this->getShowOrder(
+                                                       $data['showorder'] ?? null,
+                                                       $data['categoryName'],
+                                                       'categoryName'
+                                               );
+                                       }
+                                       
+                                       foreach (['options', 'permissions'] as $optionalPropertyName) {
+                                               $optionalProperty = $element->getElementsByTagName($optionalPropertyName)->item(0);
+                                               if ($optionalProperty !== null) {
+                                                       $data[$optionalPropertyName] = StringUtil::normalizeCsv($optionalProperty->nodeValue);
+                                               }
+                                               else {
+                                                       $daota[$optionalPropertyName] = '';
                                                }
                                        }
                                        
-                                       return $lowercaseData;
+                                       // object-type specific elements
+                                       $optionals = [
+                                               'minvalue',
+                                               'maxvalue',
+                                               'suffix',
+                                               'minlength',
+                                               'maxlength',
+                                               'issortable',
+                                               'allowemptyvalue',
+                                               'disableAutocomplete'
+                                       ];
+                                       
+                                       foreach ($optionals as $optionalPropertyName) {
+                                               $optionalProperty = $element->getElementsByTagName($optionalPropertyName)->item(0);
+                                               if ($optionalProperty !== null) {
+                                                       $data[$optionalPropertyName] = $optionalProperty->nodeValue;
+                                               }
+                                       }
                                }
                                
                                break;
index 63672c352f9de7b69733b84fa9f398bfa38941ca..1c76e61fe278fc30096e76bbd698be8dbd59471b 100644 (file)
@@ -374,7 +374,7 @@ abstract class AbstractXMLPackageInstallationPlugin extends AbstractPackageInsta
        /**
         * Returns the show order value.
         * 
-        * @param       integer         $showOrder
+        * @param       null|integer    $showOrder
         * @param       string          $parentName
         * @param       string          $columnName
         * @param       string          $tableNameExtension
index 50fd25ba1369d44d287977f180e6a1c0d81bf55c..139d3e61b6c254e606dd2b2f6f341e9514cf0605 100644 (file)
@@ -255,30 +255,49 @@ class BBCodePackageInstallationPlugin extends AbstractXMLPackageInstallationPlug
                        if ($child !== null) {
                                $data[$arrayKey] = $child->nodeValue;
                        }
+                       else if ($saveData) {
+                               if (substr($arrayKey, 0, 2) === 'is') {
+                                       $data[$arrayKey] = 0;
+                               }
+                               else {
+                                       $data[$arrayKey] = '';
+                               }
+                       }
                }
                
                if (!empty($data['wysiwygicon']) && !empty($data['buttonLabel'])) {
                        $data['showButton'] = 1;
                }
+               else if ($saveData) {
+                       $data['showButton'] = 0;
+               }
                
                // attributes
                $attributes = $element->getElementsByTagName('attributes')->item(0);
                if ($attributes !== null) {
                        $optionalAttributeElements = [
-                               'attributeHtml' => 'html',
+                               $saveData ? 'html' : 'attributeHtml' => 'html',
                                'required' => 'required',
-                               'useText' => 'usetext',
-                               'validationPattern' => 'validationpattern',
+                               'usetext' => $saveData ? 'usetext' : 'useText',
+                               'validationpattern' => $saveData ? 'validationpattern' : 'validationPattern'
                        ];
                        
                        /** @var \DOMElement $attribute */
                        foreach ($attributes->childNodes as $attribute) {
-                               $attributeData = ['name' => $attribute->nodeValue];
+                               $attributeData = [];
                                
-                               foreach ($optionalAttributeElements as $arrayKey => $elementName) {
+                               foreach ($optionalAttributeElements as $elementName => $arrayIndex) {
                                        $child = $attribute->getElementsByTagName($elementName)->item(0);
                                        if ($child !== null) {
-                                               $attributeData[$arrayKey] = $child->nodeValue;
+                                               $attributeData[$arrayIndex] = $child->nodeValue;
+                                       }
+                                       else if ($saveData) {
+                                               if ($elementName === 'required' || $elementName === 'usetext') {
+                                                       $attributeData[$arrayIndex] = 0;
+                                               }
+                                               else {
+                                                       $attributeData[$arrayIndex] = '';
+                                               }
                                        }
                                }
                                
@@ -530,13 +549,15 @@ class BBCodePackageInstallationPlugin extends AbstractXMLPackageInstallationPlug
                                $attribute = $document->createElement('attribute');
                                $attribute->setAttribute('name', (string) $attributeNumber);
                                
-                               if (!empty($attributeData['attributeHtml'])) {
+                               if (!empty($attributeData['html'])) {
                                        $html = $document->createElement('html');
-                                       $html->appendChild($document->createCDATASection($attributeData['attributeHtml']));
+                                       $html->appendChild($document->createCDATASection($attributeData['html']));
                                        $attribute->appendChild($html);
                                }
                                if (!empty($attributeData['validationPattern'])) {
-                                       $attribute->appendChild($document->createElement('validationpattern', $attributeData['validationPattern']));
+                                       $validationpattern = $document->createElement('validationpattern');
+                                       $validationpattern->appendChild($document->createCDATASection($attributeData['validationPattern']));
+                                       $attribute->appendChild($validationpattern);
                                }
                                if (!empty($attributeData['required'])) {
                                        $attribute->appendChild($document->createElement('required', $attributeData['required']));
index cf0a074343e2027abeb3c960e686087fb31c3519..36ad15c2b91aa238dbce0351f404c726ab280ccc 100644 (file)
@@ -640,11 +640,17 @@ class BoxPackageInstallationPlugin extends AbstractXMLPackageInstallationPlugin
                                if ($contentContent !== null) {
                                        $data['content'][$languageID] = $contentContent->nodeValue;
                                }
+                               else if ($saveData) {
+                                       $data['content'][$languageID] = '';
+                               }
                                
                                $title = $content->getElementsByTagName('title')->item(0);
                                if ($title !== null) {
                                        $data['title'][$languageID] = $title->nodeValue;
                                }
+                               else if ($saveData) {
+                                       $data['title'][$languageID] = '';
+                               }
                        }
                }
                
@@ -653,6 +659,14 @@ class BoxPackageInstallationPlugin extends AbstractXMLPackageInstallationPlugin
                        if ($optionalElement !== null) {
                                $data[$optionalElementName] = $optionalElement->nodeValue;
                        }
+                       else if ($saveData) {
+                               if ($optionalElementName === 'showHeader' || $optionalElementName === 'visibleEverywhere') {
+                                       $data[$optionalElementName] = 0;
+                               }
+                               else {
+                                       $data[$optionalElementName] = '';
+                               }
+                       }
                }
                
                $visibilityExceptions = $element->getElementsByTagName('visibilityExceptions')->item(0);
index 044fd843ae17b0a13a6357358f7aa8e0d6e0b388..ef28aa975e7f624fbcf20add696240646e50df77 100644 (file)
@@ -4,6 +4,7 @@ use wcf\data\clipboard\action\ClipboardAction;
 use wcf\data\clipboard\action\ClipboardActionEditor;
 use wcf\data\clipboard\action\ClipboardActionList;
 use wcf\system\clipboard\action\IClipboardAction;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\devtools\pip\IDevtoolsPipEntryList;
 use wcf\system\devtools\pip\IGuiPackageInstallationPlugin;
 use wcf\system\devtools\pip\TXmlGuiPackageInstallationPlugin;
@@ -138,11 +139,15 @@ class ClipboardActionPackageInstallationPlugin extends AbstractXMLPackageInstall
         * @inheritDoc
         */
        protected function postImport() {
+               $conditionBuilder = new PreparedStatementConditionBuilder();
+               $conditionBuilder->add('packageID = ?', [$this->installation->getPackageID()]);
+               $conditionBuilder->add('actionID IN (?)', [array_keys($this->pages)]);
+               
                // clear pages
                $sql = "DELETE FROM     wcf".WCF_N."_clipboard_page
-                       WHERE           packageID = ?";
+                       " . $conditionBuilder;
                $statement = WCF::getDB()->prepareStatement($sql);
-               $statement->execute([$this->installation->getPackageID()]);
+               $statement->execute($conditionBuilder->getParameters());
                
                if (!empty($this->pages)) {
                        // insert pages
@@ -256,6 +261,14 @@ class ClipboardActionPackageInstallationPlugin extends AbstractXMLPackageInstall
                if ($showOrder !== null) {
                        $data['showOrder'] = $showOrder->nodeValue;
                }
+               if ($saveData && $this->editedEntry === null) {
+                       // only set explicit showOrder when adding new clipboard actions
+                       $data['showOrder'] = $this->getShowOrder(
+                               $data['showOrder'] ?? null,
+                               $data['actionClassName'],
+                               'actionClassName'
+                       );
+               }
                
                /** @var \DOMElement $page */
                foreach ($element->getElementsByTagName('pages')->item(0)->childNodes as $page) {
index c4d0cf8ad2a2e8b6ea7a9d4bdbbfe91099862b5c..4425dd778f96b232670b0d800055bfd2885392d3 100644 (file)
@@ -298,14 +298,46 @@ class CronjobPackageInstallationPlugin extends AbstractXMLPackageInstallationPlu
                        }
                }
                
+               $canBeEdited = $element->getElementsByTagName('canbeedited')->item(0);
+               if ($canBeEdited !== null) {
+                       $data['canBeEdited'] = $canBeEdited->nodeValue;
+               }
+               else if ($saveData) {
+                       $data['canBeEdited'] = 1;
+               }
+               
                $canBeEdited = $element->getElementsByTagName('canbeedited')->item(0);
                if ($canBeEdited !== null) {
                        $data['canBeDisabled'] = $canBeEdited->nodeValue;
                }
+               else if ($saveData) {
+                       $data['canBeDisabled'] = 1;
+               }
                
                $isDisabled = $element->getElementsByTagName('isdisabled')->item(0);
                if ($isDisabled !== null) {
-                       $data['canBeDisabled'] = $isDisabled->nodeValue;
+                       $data['isDisabled'] = $isDisabled->nodeValue;
+               }
+               else if ($saveData) {
+                       $data['isDisabled'] = 0;
+               }
+               
+               $isDisabled = $element->getElementsByTagName('options')->item(0);
+               if ($isDisabled !== null) {
+                       $data['options'] = $isDisabled->nodeValue;
+               }
+               else if ($saveData) {
+                       $data['options'] = '';
+               }
+               
+               if ($saveData) {
+                       $descriptions = $data['description'];
+                       unset($data['description']);
+                       
+                       $data['description'] = [];
+                       foreach ($descriptions as $languageID => $description) {
+                               $data['description'][LanguageFactory::getInstance()->getLanguage($languageID)->languageCode] = $description;
+                       }
                }
                
                return $data;
index 7882d8a928fb2d9b2388c937e35b6b40077bf2a7..3b78f113399c8d08f4f78cf1643c2864e2e3a8e2 100644 (file)
@@ -294,11 +294,35 @@ class EventListenerPackageInstallationPlugin extends AbstractXMLPackageInstallat
                        'packageID' => $this->installation->getPackage()->packageID
                ];
                
-               foreach (['environment', 'inherit', 'nice', 'options', 'permissions'] as $optionalElementProperty) {
+               foreach (['environment', 'inherit', 'options', 'permissions'] as $optionalElementProperty) {
                        $optionalElement = $element->getElementsByTagName($optionalElementProperty)->item(0);
                        if ($optionalElement !== null) {
                                $data[$optionalElementProperty] = $optionalElement->nodeValue;
                        }
+                       else if ($saveData) {
+                               switch ($optionalElementProperty) {
+                                       case 'environment':
+                                               $data[$optionalElementProperty] = 'user';
+                                               break;
+                                               
+                                       case 'inherit':
+                                               $data[$optionalElementProperty] = 0;
+                                               break;
+                                       
+                                       case 'options':
+                                       case 'permissions':
+                                               $data[$optionalElementProperty] = '';
+                                               break;
+                               }
+                       }
+               }
+               
+               $niceValue = $element->getElementsByTagName('nice')->item(0);
+               if ($niceValue !== null) {
+                       $data['niceValue'] = $niceValue->nodeValue;
+               }
+               else if ($saveData) {
+                       $data['niceValue'] = 0;
                }
                
                return $data;
index c7ccfe8562839c99c31c1d3822477a6656ed3a33..baecb7e17912db1735a75eaf1d01f1d5dd56fc5d 100644 (file)
@@ -291,7 +291,7 @@ class LanguagePackageInstallationPlugin extends AbstractXMLPackageInstallationPl
         * @inheritDoc
         */
        protected function findExistingItem(array $data) {
-               wcfDebug($data);
+               // does nothing
        }
        
        /**
@@ -529,12 +529,13 @@ class LanguagePackageInstallationPlugin extends AbstractXMLPackageInstallationPl
                                }
                        }
                        else {
-                               $data['languageCategory'] = $languageCategory;
+                               $data['languageCategoryID'] = LanguageFactory::getInstance()->getCategory($languageCategory)->languageCategoryID;
                        }
                }
                
                if (!$saveData) {
                        $data[$element->ownerDocument->documentElement->getAttribute('languagecode')] = $element->nodeValue;
+                       $data['languageCategoryIDMode'] = 'selection';
                }
                
                return $data;
index 4aae173f4dee4606399fd377314876711b3cf1d8..6e42a48e9bab098b5cfc00598fe08f28567284f1 100644 (file)
@@ -8,6 +8,7 @@ use wcf\system\devtools\pip\IGuiPackageInstallationPlugin;
 use wcf\system\devtools\pip\TXmlGuiPackageInstallationPlugin;
 use wcf\system\form\builder\container\FormContainer;
 use wcf\system\form\builder\field\ClassNameFormField;
+use wcf\system\form\builder\field\data\CustomFormFieldDataProcessor;
 use wcf\system\form\builder\field\MultilineTextFormField;
 use wcf\system\form\builder\field\TextFormField;
 use wcf\system\form\builder\field\TitleFormField;
@@ -187,6 +188,13 @@ class MediaProviderPackageInstallationPlugin extends AbstractXMLPackageInstallat
                                        }
                                }))
                ]);
+               
+               $form->getDataHandler()->add(new CustomFormFieldDataProcessor('unifyNewlines', function(IFormDocument $document, array $parameters) {
+                       $parameters['data']['regex'] = StringUtil::unifyNewlines(StringUtil::escapeCDATA($parameters['data']['regex']));
+                       $parameters['data']['html'] = StringUtil::unifyNewlines(StringUtil::escapeCDATA($parameters['data']['html']));
+                       
+                       return $parameters;
+               }));
        }
        
        /**
@@ -206,7 +214,6 @@ class MediaProviderPackageInstallationPlugin extends AbstractXMLPackageInstallat
                        $data['html'] = $html->nodeValue;
                }
                else if ($saveData) {
-                       // when saving data, `html` has to be present
                        $data['html'] = '';
                }
                
@@ -214,6 +221,9 @@ class MediaProviderPackageInstallationPlugin extends AbstractXMLPackageInstallat
                if ($className !== null) {
                        $data['className'] = $className->nodeValue;
                }
+               else if ($saveData) {
+                       $data['className'] = '';
+               }
                
                return $data;
        }
index 8b8f3c378e72c21ad69bb5433be0fbfaf31f079a..9ca8878dacecd077b48eb052de4ff5a16be986df 100644 (file)
@@ -14,7 +14,6 @@ use wcf\system\devtools\pip\TXmlGuiPackageInstallationPlugin;
 use wcf\system\exception\SystemException;
 use wcf\system\form\builder\container\FormContainer;
 use wcf\system\form\builder\field\dependency\ValueFormFieldDependency;
-use wcf\system\form\builder\field\IntegerFormField;
 use wcf\system\form\builder\field\RadioButtonFormField;
 use wcf\system\form\builder\field\SingleSelectionFormField;
 use wcf\system\form\builder\field\TextFormField;
@@ -358,15 +357,7 @@ class MenuItemPackageInstallationPlugin extends AbstractXMLPackageInstallationPl
                                ->label('wcf.acp.pip.menuItem.externalURL')
                                ->description('wcf.acp.pip.menuItem.externalURL.description')
                                ->required()
-                               ->i18n(),
-                       
-                       IntegerFormField::create('showOrder')
-                               ->objectProperty('showorder')
-                               ->label('wcf.acp.pip.menuItem.showOrder')
-                               ->description('wcf.acp.pip.menuItem.showOrder.description')
-                               ->objectProperty('showorder')
-                               ->minimum(1)
-                               ->nullable()
+                               ->i18n()
                ]);
                
                /** @var SingleSelectionFormField $menuField */
@@ -449,14 +440,17 @@ class MenuItemPackageInstallationPlugin extends AbstractXMLPackageInstallationPl
                        $data['title'][LanguageFactory::getInstance()->getLanguageByCode($title->getAttribute('language'))->languageID] = $title->nodeValue;
                }
                
-               foreach (['externalURL', 'menu', 'page', 'parent', 'showOrder'] as $optionalElementName) {
+               foreach (['externalURL', 'menu', 'page', 'parent'] as $optionalElementName) {
                        $optionalElement = $element->getElementsByTagName($optionalElementName)->item(0);
                        if ($optionalElement !== null) {
                                $data[$optionalElementName] = $optionalElement->nodeValue;
                        }
+                       else if ($saveData) {
+                               $data[$optionalElementName] = '';
+                       }
                }
                
-               if (isset($data['parent'])) {
+               if (!empty($data['parent'])) {
                        $menuItemList = new MenuItemList();
                        $menuItemList->getConditionBuilder()->add('identifier = ?', [$data['parent']]);
                        $menuItemList->getConditionBuilder()->add('packageID IN (?)', [
@@ -470,15 +464,27 @@ class MenuItemPackageInstallationPlugin extends AbstractXMLPackageInstallationPl
                        if (count($menuItemList) === 1) {
                                if ($saveData) {
                                        $data['menuID'] = $menuItemList->current()->menuID;
+                                       $data['parentItemID'] = $menuItemList->current()->itemID;
+                                       
+                                       unset($data['parent']);
                                }
                                else {
                                        $data['menu'] = (new Menu($menuItemList->current()->menuID))->identifier;
                                }
                        }
                }
-               else if (isset($data['menu']) && $saveData) {
-                       $data['menuID'] = $this->getMenuID($data['menu']);
-                       unset($data['menu']);
+               else if ($saveData) {
+                       if (isset($data['menu'])) {
+                               $data['menuID'] = $this->getMenuID($data['menu']);
+                               unset($data['menu']);
+                       }
+                       
+                       $data['parentItemID'] = null;
+               }
+               
+               if ($saveData && $this->editedEntry === null) {
+                       // only set explicit showOrder when adding new menu item
+                       $data['showOrder'] = $this->getItemOrder($data['menuID'], $data['parentItemID']);
                }
                
                if ($saveData) {
index f9eab984463c502ceb86c51520fea24adc7ed2f4..3962b6b046b18f43b90e9b71ae1bfadca4a8232f 100644 (file)
@@ -155,6 +155,9 @@ class ObjectTypeDefinitionPackageInstallationPlugin extends AbstractXMLPackageIn
                if ($interfaceName) {
                        $data['interfaceName'] = $interfaceName->nodeValue;
                }
+               else if ($saveData) {
+                       $data['interfaceName'] = '';
+               }
                
                return $data;
        }
index a6b05c6a06c9b8667fe52cb3586cf0e30091a338..878fb9f98bfae99984274d1993ac53bb110026b0 100644 (file)
@@ -252,7 +252,15 @@ class OptionPackageInstallationPlugin extends AbstractOptionPackageInstallationP
                                foreach (['selectOptions', 'hidden', 'supportI18n', 'requireI18n'] as $optionalPropertyName) {
                                        $optionalProperty = $element->getElementsByTagName(strtolower($optionalPropertyName))->item(0);
                                        if ($optionalProperty !== null) {
-                                               $data[$optionalPropertyName] = $optionalProperty->nodeValue;
+                                               $data[$saveData ? strtolower($optionalPropertyName) : $optionalPropertyName] = $optionalProperty->nodeValue;
+                                       }
+                                       else if ($saveData) {
+                                               if ($optionalPropertyName === 'selectOptions') {
+                                                       $data['selectoptions'] = '';
+                                               }
+                                               else {
+                                                       $data[strtolower($optionalPropertyName)] = 0;
+                                               }
                                        }
                                }
                                
index f21bd44d387ace2c89e7f34270032167187e3f2a..c423f9cb10dd5397ecc4c7d1f971ccc77f17757c 100644 (file)
@@ -525,7 +525,7 @@ class PagePackageInstallationPlugin extends AbstractXMLPackageInstallationPlugin
                                        }
                                        
                                        return $nestedOptions;
-                               }, true)
+                               }, atrue)
                                ->addValidator(new FormFieldValidator('selfParent', function(SingleSelectionFormField $formField) {
                                        /** @var TextFormField $identifier */
                                        $identifier = $formField->getDocument()->getNodeById('identifier');
@@ -660,23 +660,42 @@ class PagePackageInstallationPlugin extends AbstractXMLPackageInstallationPlugin
                        'excludeFromLandingPage', 'availableDuringOfflineMode', 'requireObjectID'
                ];
                
+               $zeroDefaultOptions = [
+                       'hasFixedParent',
+                       'allowSpidersToIndex',
+                       'excludeFromLandingPage',
+                       'availableDuringOfflineMode',
+                       'requireObjectID'
+               ];
+               
                foreach ($optionalElements as $optionalElementName) {
                        $optionalElement = $element->getElementsByTagName($optionalElementName)->item(0);
                        if ($optionalElement !== null) {
                                $data[$optionalElementName] = $optionalElement->nodeValue;
                        }
+                       else if ($saveData) {
+                               if (in_array($optionalElementName, $zeroDefaultOptions)) {
+                                       $data[$optionalElementName] = 0;
+                               }
+                               else {
+                                       $data[$optionalElementName] = '';
+                               }
+                       }
                }
                
-               $readData = function($languageID, \DOMElement $content) use (&$data) {
+               $readData = function($languageID, \DOMElement $content) use (&$data, $saveData) {
                        foreach (['title', 'content', 'customURL', 'metaDescription', 'metaKeywords'] as $contentElementName) {
                                $contentElement = $content->getElementsByTagName($contentElementName)->item(0);
+                               if (!isset($data[$contentElementName])) {
+                                       $data[$contentElementName] = [];
+                               }
+                               
                                if ($contentElement) {
-                                       if (!isset($data[$contentElementName])) {
-                                               $data[$contentElementName] = [];
-                                       }
-                                       
                                        $data[$contentElementName][$languageID] = $contentElement->nodeValue;
                                }
+                               else if ($saveData) {
+                                       $data[$contentElementName][$languageID] = '';
+                               }
                        }
                };
                
index 1b24a882fa4b05c789119a844ace65d722311a60..9685b20248ff303d76d0e6760902727d149cf323 100644 (file)
@@ -168,9 +168,11 @@ class SmileyPackageInstallationPlugin extends AbstractXMLPackageInstallationPlug
                                                return;
                                        }
                                        
+                                       $aliases = $this->editedEntry ? $this->editedEntry->getElementsByTagName('aliases')->item(0) : null;
                                        if (
                                                $formField->getDocument()->getFormMode() === IFormDocument::FORM_MODE_CREATE ||
-                                               $this->editedEntry->getElementsByTagName('aliases')->item(0)->nodeValue !== $formField->getSaveValue()
+                                               $aliases === null ||
+                                               $aliases->nodeValue !== $formField->getSaveValue()
                                        ) {
                                                $notUniqueCodes = [];
                                                foreach ($formField->getValue() as $alias) {
@@ -243,10 +245,16 @@ class SmileyPackageInstallationPlugin extends AbstractXMLPackageInstallationPlug
                        if ($child !== null) {
                                $data[$arrayKey] = $child->nodeValue;
                        }
-               }
-               
-               if ($saveData && !isset($data['aliases'])) {
-                       $data['aliases'] = '';
+                       else {
+                               if ($arrayKey === 'showOrder') {
+                                       if ($this->editedEntry === null) {
+                                               $data[$arrayKey] = $this->getShowOrder(null);
+                                       }
+                               }
+                               else {
+                                       $data[$arrayKey] = '';
+                               }
+                       }
                }
                
                return $data;
index 6d6c9d91220ac247300c1d425072a69b8f3b3ca8..0f883d6a6ae27b7291d8cb521c4544d4521d5b2a 100644 (file)
@@ -13,6 +13,9 @@ use wcf\system\devtools\pip\TXmlGuiPackageInstallationPlugin;
 use wcf\system\form\builder\container\FormContainer;
 use wcf\system\form\builder\field\data\CustomFormFieldDataProcessor;
 use wcf\system\form\builder\field\dependency\ValueFormFieldDependency;
+use wcf\system\form\builder\field\IntegerFormField;
+use wcf\system\form\builder\field\OptionFormField;
+use wcf\system\form\builder\field\UserGroupOptionFormField;
 use wcf\system\form\builder\field\validation\FormFieldValidationError;
 use wcf\system\form\builder\field\validation\FormFieldValidator;
 use wcf\system\form\builder\field\MultilineTextFormField;
@@ -274,7 +277,7 @@ class TemplateListenerPackageInstallationPlugin extends AbstractXMLPackageInstal
                                        $nameField = $formField->getDocument()->getNodeById('name');
                                        
                                        /** @var SingleSelectionFormField $templateNameFormField */
-                                       $templateNameFormField = $formField->getDocument()->getNodeById('templateName');
+                                       $templateNameFormField = $formField->getDocument()->getNodeById('frontendTemplateName');
                                        
                                        /** @var SingleSelectionFormField $acpTemplateNameFormField */
                                        $acpTemplateNameFormField = $formField->getDocument()->getNodeById('acpTemplateName');
@@ -334,7 +337,29 @@ class TemplateListenerPackageInstallationPlugin extends AbstractXMLPackageInstal
                                ->objectProperty('templatecode')
                                ->label('wcf.acp.pip.templateListener.templateCode')
                                ->description('wcf.acp.pip.templateListener.templateCode.description')
-                               ->required()
+                               ->required(),
+                       
+                       IntegerFormField::create('niceValue')
+                               ->objectProperty('nice')
+                               ->label('wcf.acp.pip.templateListener.niceValue')
+                               ->description('wcf.acp.pip.templateListener.niceValue.description')
+                               ->nullable()
+                               ->minimum(-128)
+                               ->maximum(127),
+                       
+                       OptionFormField::create()
+                               ->description('wcf.acp.pip.templateListener.options.description')
+                               ->packageIDs(array_merge(
+                                       [$this->installation->getPackage()->packageID],
+                                       array_keys($this->installation->getPackage()->getAllRequiredPackages())
+                               )),
+                       
+                       UserGroupOptionFormField::create()
+                               ->description('wcf.acp.pip.templateListener.permissions.description')
+                               ->packageIDs(array_merge(
+                                       [$this->installation->getPackage()->packageID],
+                                       array_keys($this->installation->getPackage()->getAllRequiredPackages())
+                               ))
                ]);
                
                /** @var SingleSelectionFormField $environment */
@@ -364,7 +389,7 @@ class TemplateListenerPackageInstallationPlugin extends AbstractXMLPackageInstal
         * @since       3.2
         */
        protected function doGetElementData(\DOMElement $element, $saveData) {
-               return [
+               $data = [
                        'environment' => $element->getElementsByTagName('environment')->item(0)->nodeValue,
                        'eventName' => $element->getElementsByTagName('eventname')->item(0)->nodeValue,
                        'name' => $element->getAttribute('name'),
@@ -372,6 +397,26 @@ class TemplateListenerPackageInstallationPlugin extends AbstractXMLPackageInstal
                        'templateCode' => $element->getElementsByTagName('templatecode')->item(0)->nodeValue,
                        'templateName' => $element->getElementsByTagName('templatename')->item(0)->nodeValue
                ];
+               
+               $nice = $element->getElementsByTagName('nice')->item(0);
+               if ($nice !== null) {
+                       $data['niceValue'] = $nice->nodeValue;
+               }
+               else if ($saveData) {
+                       $data['niceValue'] = 0;
+               }
+               
+               foreach (['options', 'permissions'] as $elementName) {
+                       $optionalElement = $element->getElementsByTagName($elementName)->item(0);
+                       if ($optionalElement !== null) {
+                               $data[$elementName] = $optionalElement->nodeValue;
+                       }
+                       else if ($saveData) {
+                               $data[$elementName] = '';
+                       }
+               }
+               
+               return $data;
        }
        
        /**
@@ -406,7 +451,7 @@ class TemplateListenerPackageInstallationPlugin extends AbstractXMLPackageInstal
                                        
                                case 'user':
                                        /** @var SingleSelectionFormField $templateName */
-                                       $templateName = $document->getNodeById('templateName');
+                                       $templateName = $document->getNodeById('frontendTemplateName');
                                        
                                        /** @var SingleSelectionFormField $eventName */
                                        $eventName = $document->getNodeById($data['templateName'] . '_eventName');
@@ -456,7 +501,10 @@ class TemplateListenerPackageInstallationPlugin extends AbstractXMLPackageInstal
                                'eventname',
                                'templatecode' => [
                                        'cdata' => true
-                               ]
+                               ],
+                               'nice' => 0,
+                               'options' => '',
+                               'permissions' => ''
                        ],
                        $form
                );
index be76c8884036335708981f4b9013315ff37b7167..630e8a6a8d47aff119019b935b403fae1ea5a0ea 100644 (file)
@@ -288,6 +288,11 @@ class UserGroupOptionPackageInstallationPlugin extends AbstractOptionPackageInst
                                                        $data[$optionalPropertyName] = $optionalProperty->nodeValue;
                                                }
                                        }
+                                       else if ($saveData && $optionalPropertyName === 'usersOnly') {
+                                               // all of the other fields will be put in `additionalData`
+                                               // or not saved thus empty values are not necessary 
+                                               $data['usersonly'] = 0;
+                                       }
                                }
                                
                                break;
index 2f424afd4973b6e602c4200733e5b4918a9cadb7..4273cfe9a2e10a98182f755b697b04e65a044342 100644 (file)
@@ -107,7 +107,7 @@ class UserMenuPackageInstallationPlugin extends AbstractMenuPackageInstallationP
                // thus the parent menu item must be at least on the second level
                // for the menu item to support links
                $menuItemsSupportingLinks = array_keys(array_filter($menuItemLevels, function($menuItemLevel) {
-                       return $menuItemLevel >= 2;
+                       return $menuItemLevel >= 1;
                }));
                
                foreach (['menuItemController', 'menuItemLink'] as $nodeId) {
@@ -132,11 +132,17 @@ class UserMenuPackageInstallationPlugin extends AbstractMenuPackageInstallationP
                if ($className !== null) {
                        $data['className'] = $className->nodeValue;
                }
+               else if ($saveData) {
+                       $data['className'] = '';
+               }
                
                $icon = $element->getElementsByTagName('iconclassname')->item(0);
                if ($icon !== null) {
                        $data['iconClassName'] = $icon->nodeValue;
                }
+               else if ($saveData) {
+                       $data['iconClassName'] = '';
+               }
                
                return $data;
        }
index 78ba3657be4a2b0acf68909ac055faeb93efb221..c4ebc7a2449ade9e5e797c5ecd446d4acde8a27a 100644 (file)
@@ -306,21 +306,33 @@ class UserNotificationEventPackageInstallationPlugin extends AbstractXMLPackageI
                if ($options) {
                        $data['options'] = StringUtil::normalizeCsv($options->nodeValue);
                }
+               else if ($saveData) {
+                       $data['options'] = '';
+               }
                
                $permissions = $element->getElementsByTagName('permissions')->item(0);
                if ($permissions) {
                        $data['permissions'] = StringUtil::normalizeCsv($permissions->nodeValue);
                }
+               else if ($saveData) {
+                       $data['permissions'] = '';
+               }
                
                // the presence of a `preset` element is treated as `<preset>1</preset>
                if ($element->getElementsByTagName('preset')->length === 1) {
                        $data['preset'] = 1;
                }
+               else if ($saveData) {
+                       $data['preset'] = 0;
+               }
                
                $presetMailNotificationType = $element->getElementsByTagName('presetmailnotificationtype')->item(0);
                if ($presetMailNotificationType && in_array($presetMailNotificationType->nodeValue, ['instant', 'daily'])) {
                        $data['presetMailNotificationType'] = $presetMailNotificationType->nodeValue;
                }
+               else if ($saveData) {
+                       $data['presetMailNotificationType'] = 'none';
+               }
                
                return $data;
        }
index 91fc08cfa1dd5a7a71c0cb92041d5f0d80f04c60..05544a331b9676badbf468855d4c185bf3dfaeef 100644 (file)
@@ -238,6 +238,7 @@ class UserOptionPackageInstallationPlugin extends AbstractOptionPackageInstallat
                                        ->label('wcf.acp.pip.userOption.options.editable')
                                        ->description('wcf.acp.pip.userOption.options.editable.description')
                                        ->options([
+                                               0 => 'wcf.acp.user.option.editable.0',
                                                1 => 'wcf.acp.user.option.editable.1',
                                                2 => 'wcf.acp.user.option.editable.2',
                                                3 => 'wcf.acp.user.option.editable.3',
@@ -361,6 +362,11 @@ class UserOptionPackageInstallationPlugin extends AbstractOptionPackageInstallat
                                                        $data[$optionalPropertyName] = $optionalProperty->nodeValue;
                                                }
                                        }
+                                       else if ($saveData && $optionalPropertyName === 'selectOptions') {
+                                               // all of the other fields will be put in `additionalData`,
+                                               // thus empty values are not necessary 
+                                               $data['selectoptions'] = '';
+                                       }
                                }
                                
                                $messageObjectType = $element->getElementsByTagName('messageObjectType')->item(0);
@@ -423,9 +429,9 @@ class UserOptionPackageInstallationPlugin extends AbstractOptionPackageInstallat
                                                'outputclass' => '',
                                                'required' => 0,
                                                'askduringregistration' => 0,
-                                               'editable' => '0',
-                                               'visible' => '0',
                                                'searchable' => 0,
+                                               'visible' => '0',
+                                               'editable' => '0',
                                                'isdisabled' => 0,
                                                'messageObjectType' => '',
                                                'contentpattern' => ''
index 8368ac96ba2fe635ad36c9eb35a41de8de6ef874..d34635a0b8e4146055233cd5b28f9cbdcf234b71 100644 (file)
@@ -188,16 +188,26 @@ class UserProfileMenuPackageInstallationPlugin extends AbstractXMLPackageInstall
                if ($options) {
                        $data['options'] = StringUtil::normalizeCsv($options->nodeValue);
                }
+               else if ($saveData) {
+                       $data['options'] = '';
+               }
                
                $permissions = $element->getElementsByTagName('permissions')->item(0);
                if ($permissions) {
                        $data['permissions'] = StringUtil::normalizeCsv($permissions->nodeValue);
                }
+               else if ($saveData) {
+                       $data['permissions'] = '';
+               }
                
                $showOrder = $element->getElementsByTagName('showorder')->item(0);
                if ($showOrder) {
                        $data['showOrder'] = intval($showOrder->nodeValue);
                }
+               if ($saveData && $this->editedEntry === null) {
+                       // only set explicit showOrder when adding new menu item
+                       $data['showOrder'] = $this->getShowOrder($data['showOrder'] ?? null);
+               }
                
                return $data;
        }
index 1ecb9d4faa130f950c73d0992ad598c6ce702ff2..ef1698fa2b09b8cf413d68411e566aa22b5bd99d 100644 (file)
@@ -2183,7 +2183,7 @@ If you have <strong>already bought the licenses for the listed apps</strong>, th
                <item name="wcf.acp.pip.smiley.aliases.description"><![CDATA[Secondary codes that are converted into this smiley.]]></item>
                <item name="wcf.acp.pip.smiley.aliases.error.notUnique"><![CDATA[The following aliases are already used by another smiley: {implode from=$notUniqueCodes item=notUniqueCode}<code>{$notUniqueCode}</code>{/implode}.]]></item>
                <item name="wcf.acp.pip.smiley.showOrder"><![CDATA[Display Order]]></item>
-               <item name="wcf.acp.pip.smiley.showOrder.description"><![CDATA[The entered value determines in which order the smiley are shown.]]></item>
+               <item name="wcf.acp.pip.smiley.showOrder.description"><![CDATA[The entered value determines in which order the smilies are shown.]]></item>
                <item name="wcf.acp.pip.smiley.smileyPath"><![CDATA[Smiley Path]]></item>
                <item name="wcf.acp.pip.smiley.smileyPath.description"><![CDATA[The entered path has to be relative to <code>{'WCF_DIR'|constant}</code>.]]></item>
                <item name="wcf.acp.pip.smiley.smileyPath.error.fileDoesNotExist"><![CDATA[The entered file does not exist.]]></item>