Added validation of box position
authorAlexander Ebert <ebert@woltlab.com>
Fri, 8 Jul 2016 16:32:21 +0000 (18:32 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Fri, 8 Jul 2016 16:32:21 +0000 (18:32 +0200)
21 files changed:
wcfsetup/install/files/acp/templates/boxAdd.tpl
wcfsetup/install/files/js/WoltLab/WCF/Acp/Ui/Box/Handler.js
wcfsetup/install/files/lib/acp/form/BoxAddForm.class.php
wcfsetup/install/files/lib/acp/form/BoxEditForm.class.php
wcfsetup/install/files/lib/system/box/AbstractBoxController.class.php
wcfsetup/install/files/lib/system/box/ArticleCategoriesBoxController.class.php
wcfsetup/install/files/lib/system/box/ArticleListBoxController.class.php
wcfsetup/install/files/lib/system/box/FollowingsOnlineBoxController.class.php
wcfsetup/install/files/lib/system/box/IBoxController.class.php
wcfsetup/install/files/lib/system/box/PageCommentListBoxController.class.php
wcfsetup/install/files/lib/system/box/PaidSubscriptionsBoxController.class.php
wcfsetup/install/files/lib/system/box/RecentActivityListBoxController.class.php
wcfsetup/install/files/lib/system/box/RegisterButtonBoxController.class.php
wcfsetup/install/files/lib/system/box/SignedInAsBoxController.class.php
wcfsetup/install/files/lib/system/box/StaffOnlineListBoxController.class.php
wcfsetup/install/files/lib/system/box/StatisticsBoxController.class.php
wcfsetup/install/files/lib/system/box/TagCloudBoxController.class.php
wcfsetup/install/files/lib/system/box/TodaysBirthdaysBoxController.class.php
wcfsetup/install/files/lib/system/box/UserOnlineListBoxController.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 7a361d34dbff951c04d41db40d73133491c096ff..ceb6e473cc3e6fb19f2904ff7dcb92cf2adccc4d 100644 (file)
@@ -92,7 +92,7 @@
                                        <dd>
                                                <select name="boxControllerID" id="boxControllerID">
                                                        {foreach from=$availableBoxControllers item=availableBoxController}
-                                                               <option value="{@$availableBoxController->objectTypeID}"{if $boxController && $availableBoxController->objectTypeID == $boxController->objectTypeID} selected{/if}>{lang}wcf.acp.box.boxController.{@$availableBoxController->objectType}{/lang}</option>
+                                                               <option value="{@$availableBoxController->objectTypeID}"{if $boxController && $availableBoxController->objectTypeID == $boxController->objectTypeID} selected{/if} data-supported-positions='[{implode from=$availableBoxPositions[$availableBoxController->objectTypeID] item=$__position}"{$__position}"{/implode}]'>{lang}wcf.acp.box.boxController.{@$availableBoxController->objectType}{/lang}</option>
                                                        {/foreach}
                                                </select>
                                                
index c9382bdbc82f93489a3ec03b42b62c4ecf7e5803..21e7ab98af632eea8239cf1d6e7c13ead46c43f2 100644 (file)
@@ -10,6 +10,7 @@ define(['Dictionary', 'WoltLab/Wcf/Ui/Page/Search/Handler'], function(Dictionary
        "use strict";
        
        var _activePageId = 0;
+       var _boxController;
        var _cache;
        var _containerExternalLink;
        var _containerPageID;
@@ -17,6 +18,7 @@ define(['Dictionary', 'WoltLab/Wcf/Ui/Page/Search/Handler'], function(Dictionary
        var _handlers;
        var _pageId;
        var _pageObjectId;
+       var _position;
        
        /**
         * @exports     WoltLab/WCF/Acp/Ui/Box/Handler
@@ -30,6 +32,8 @@ define(['Dictionary', 'WoltLab/Wcf/Ui/Page/Search/Handler'], function(Dictionary
                init: function(handlers) {
                        _handlers = handlers;
                        
+                       _boxController = elById('boxControllerID');
+                       
                        _containerPageID = elById('linkPageIDContainer');
                        _containerExternalLink = elById('externalURLContainer');
                        _containerPageObjectId = elById('linkPageObjectIDContainer');
@@ -61,6 +65,14 @@ define(['Dictionary', 'WoltLab/Wcf/Ui/Page/Search/Handler'], function(Dictionary
                                        this._toggleLinkType(input.value);
                                }
                        }).bind(this));
+                       
+                       if (_boxController !== null) {
+                               _position = elById('position');
+                               _boxController.addEventListener('change', this._setAvailableBoxPositions.bind(this));
+                               
+                               // update positions on init
+                               this._setAvailableBoxPositions();
+                       }
                },
                
                /**
@@ -127,6 +139,22 @@ define(['Dictionary', 'WoltLab/Wcf/Ui/Page/Search/Handler'], function(Dictionary
                                _pageObjectId.value = objectId;
                                _cache.set(_activePageId, objectId);
                        });
+               },
+               
+               /**
+                * Updates the available box positions per box controller.
+                * 
+                * @protected
+                */
+               _setAvailableBoxPositions: function() {
+                       var supportedPositions = elData(_boxController.options[_boxController.selectedIndex], 'supported-positions');
+                       
+                       var option;
+                       for (var i = 0, length = _position.childElementCount; i < length; i++) {
+                               option = _position.children[i];
+                               
+                               option.disabled = (supportedPositions.indexOf(option.value) === -1);
+                       }
                }
        };
 });
index 0705b0ae29d900fa2de18ee01eb9575388f8fc5f..b388b7180f094e2aa30eadb775188b4bcdf54f7d 100644 (file)
@@ -18,6 +18,7 @@ use wcf\system\exception\UserInputException;
 use wcf\system\html\input\HtmlInputProcessor;
 use wcf\system\language\LanguageFactory;
 use wcf\system\page\handler\ILookupPageHandler;
+use wcf\system\page\handler\IMenuPageHandler;
 use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\ArrayUtil;
@@ -160,7 +161,7 @@ class BoxAddForm extends AbstractForm {
        
        /**
         * list of page handlers by page id
-        * @var \wcf\system\page\handler\IMenuPageHandler[]
+        * @var IMenuPageHandler[]
         */
        public $pageHandlers = [];
        
@@ -181,6 +182,11 @@ class BoxAddForm extends AbstractForm {
         */
        public $htmlInputProcessors = [];
        
+       /**
+        * @var ObjectType[]
+        */
+       public $availableBoxControllers = [];
+       
        /**
         * @inheritDoc
         */
@@ -200,6 +206,8 @@ class BoxAddForm extends AbstractForm {
                                }
                        }
                }
+               
+               $this->availableBoxControllers = ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.boxController');
        }
        
        /**
@@ -495,7 +503,7 @@ class BoxAddForm extends AbstractForm {
                        'availableLanguages' => LanguageFactory::getInstance()->getLanguages(),
                        'availableBoxTypes' => Box::$availableBoxTypes,
                        'availablePositions' => Box::$availablePositions,
-                       'availableBoxControllers' => ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.boxController'),
+                       'availableBoxControllers' => $this->availableBoxControllers,
                        'boxController' => $this->boxController,
                        'pageNodeList' => $this->pageNodeList,
                        'pageHandlers' => $this->pageHandlers,
index 6bd2acbddfe1a92299c898b9d6c636698a18b988..e95643eba7a9e4dd48f185e671c6cd630815f759 100644 (file)
@@ -5,8 +5,10 @@ use wcf\data\box\BoxAction;
 use wcf\data\object\type\ObjectTypeCache;
 use wcf\form\AbstractForm;
 use wcf\system\acl\simple\SimpleAclHandler;
+use wcf\system\box\IBoxController;
 use wcf\system\box\IConditionBoxController;
 use wcf\system\exception\IllegalLinkException;
+use wcf\system\exception\UserInputException;
 use wcf\system\language\LanguageFactory;
 use wcf\system\WCF;
 
@@ -25,6 +27,12 @@ class BoxEditForm extends BoxAddForm {
         */
        public $activeMenuItem = 'wcf.acp.menu.link.cms.box.list';
        
+       /**
+        * list of available positions per box handler
+        * @var array
+        */
+       public $availableBoxPositions = [];
+       
        /**
         * box id
         * @var integer
@@ -35,7 +43,7 @@ class BoxEditForm extends BoxAddForm {
         * box object
         * @var Box
         */
-       public $box = null;
+       public $box;
        
        /**
         * @inheritDoc
@@ -53,6 +61,19 @@ class BoxEditForm extends BoxAddForm {
                        throw new IllegalLinkException();
                }
                if ($this->box->isMultilingual) $this->isMultilingual = 1;
+               
+               $this->readBoxPositions();
+       }
+       
+       /**
+        * Loads available box positions per box controller.
+        */
+       protected function readBoxPositions() {
+               foreach ($this->availableBoxControllers as $boxController) {
+                       /** @var IBoxController $controller */
+                       $controller = $boxController->getProcessor();
+                       $this->availableBoxPositions[$boxController->objectTypeID] = $controller::getSupportedPositions();
+               }
        }
        
        /**
@@ -71,6 +92,26 @@ class BoxEditForm extends BoxAddForm {
                }
        }
        
+       /**
+        * @inheritDoc
+        */
+       public function validate() {
+               parent::validate();
+               
+               $this->validateBoxPosition();
+       }
+       
+       /**
+        * Validates the selected box position.
+        */
+       protected function validateBoxPosition() {
+               if ($this->boxType == 'system') {
+                       if (!in_array($this->position, $this->availableBoxPositions[$this->boxController->objectTypeID])) {
+                               throw new UserInputException('position', 'invalid');
+                       }
+               }
+       }
+       
        /**
         * @inheritDoc
         */
@@ -190,6 +231,7 @@ class BoxEditForm extends BoxAddForm {
                
                WCF::getTPL()->assign([
                        'action' => 'edit',
+                       'availableBoxPositions' => $this->availableBoxPositions,
                        'boxID' => $this->boxID,
                        'box' => $this->box
                ]);
index 2829e5ff1fdfc9068cb5073b4aafff019a124be8..8b8a9671efefc472a7b2e00e510424abed18cb72 100644 (file)
@@ -29,7 +29,7 @@ abstract class AbstractBoxController implements IBoxController {
         * supported box positions
         * @var string[]
         */
-       protected $supportedPositions = [];
+       protected static $supportedPositions = [];
        
        /**
         * Creates a new instance of AbstractBoxController.
@@ -107,9 +107,9 @@ abstract class AbstractBoxController implements IBoxController {
        /**
         * @inheritDoc
         */
-       public function getSupportedPositions() {
-               if (!empty($this->supportedPositions)) {
-                       return $this->supportedPositions;
+       public static function getSupportedPositions() {
+               if (!empty(static::$supportedPositions)) {
+                       return static::$supportedPositions;
                }
                
                return Box::$availablePositions;
index 12dfda5ac7f9ed3b09d9dda6a5d0c5ad96d46fb8..24abad0ed234cbe360db8759d221fa3d56a9809c 100644 (file)
@@ -19,7 +19,7 @@ class ArticleCategoriesBoxController extends AbstractBoxController {
        /**
         * @inheritDoc
         */
-       protected $supportedPositions = ['footerBoxes', 'sidebarLeft', 'sidebarRight', 'contentTop', 'contentBottom', 'footer'];
+       protected static $supportedPositions = ['footerBoxes', 'sidebarLeft', 'sidebarRight', 'contentTop', 'contentBottom', 'footer'];
        
        /**
         * @inheritDoc
index 3dd0d4efedcba18235806e9ba3531a118c126ce4..3edfb91c95ec68f979da861437f1409cd9c3318f 100644 (file)
@@ -16,7 +16,7 @@ class ArticleListBoxController extends AbstractDatabaseObjectListBoxController {
        /**
         * @inheritDoc
         */
-       protected $supportedPositions = ['sidebarLeft', 'sidebarRight', 'contentTop', 'contentBottom', 'top', 'bottom', 'footerBoxes'];
+       protected static $supportedPositions = ['sidebarLeft', 'sidebarRight', 'contentTop', 'contentBottom', 'top', 'bottom', 'footerBoxes'];
        
        /**
         * @inheritDoc
index d23cd629862b5ee354e6bb2b7c57552bbdf1af40..7b3e77a284337b5000da88f62eb8108283e8d7cd 100644 (file)
@@ -21,7 +21,7 @@ class FollowingsOnlineBoxController extends AbstractDatabaseObjectListBoxControl
        /**
         * @inheritDoc
         */
-       protected $supportedPositions = ['sidebarLeft', 'sidebarRight'];
+       protected static $supportedPositions = ['sidebarLeft', 'sidebarRight'];
        
        /**
         * @inheritDoc
index 77739c31b75daf658beb52743c8bad69bdeffe44..fc06a71f1d8886e8787200e5c28c23180adedaeb 100644 (file)
@@ -73,5 +73,5 @@ interface IBoxController {
         * 
         * @return      string[]
         */
-       public function getSupportedPositions();
+       public static function getSupportedPositions();
 }
index b6b4eadc9a7e6999c5f59285a8d4060778ca6635..f97f0823c27d9a4759fdb42b2b106d31760994e5 100644 (file)
@@ -16,7 +16,7 @@ class PageCommentListBoxController extends AbstractDatabaseObjectListBoxControll
        /**
         * @inheritDoc
         */
-       protected $supportedPositions = ['contentTop', 'contentBottom'];
+       protected static $supportedPositions = ['contentTop', 'contentBottom'];
        
        /**
         * @inheritDoc
index 9bc0c38bb332560f1fa6f650c23630225d2d4ab5..7f41eddd60a2abc17bb3057537c8953089e9e3d7 100644 (file)
@@ -18,7 +18,7 @@ class PaidSubscriptionsBoxController extends AbstractBoxController {
        /**
         * @inheritDoc
         */
-       protected $supportedPositions = ['contentTop', 'contentBottom', 'sidebarLeft', 'sidebarRight'];
+       protected static $supportedPositions = ['contentTop', 'contentBottom', 'sidebarLeft', 'sidebarRight'];
        
        /**
         * @inheritDoc
index fa2e80bf65016531ada9a4d06c2d1c20bcebe6b7..f3f3a62a2f38aa3ff93540290448e88211c81988 100644 (file)
@@ -47,7 +47,7 @@ class RecentActivityListBoxController extends AbstractDatabaseObjectListBoxContr
        /**
         * @inheritDoc
         */
-       protected $supportedPositions = ['contentTop', 'contentBottom', 'sidebarLeft', 'sidebarRight'];
+       protected static $supportedPositions = ['contentTop', 'contentBottom', 'sidebarLeft', 'sidebarRight'];
        
        /**
         * @inheritDoc
index a08bf9d266e17b0ef98dc747c96e7015f05b7f42..140dadf146a60d7ee7bffe8c56451545fafbc4b0 100644 (file)
@@ -15,7 +15,7 @@ class RegisterButtonBoxController extends AbstractBoxController {
        /**
         * @inheritDoc
         */
-       protected $supportedPositions = ['sidebarLeft', 'sidebarRight'];
+       protected static $supportedPositions = ['sidebarLeft', 'sidebarRight'];
        
        /**
         * @inheritDoc
index cbbc240c4b5b72d7b63a3e29d56966490bb5ec47..8c58868372f463e69bef2b3e0950ba6545862ca4 100644 (file)
@@ -15,7 +15,7 @@ class SignedInAsBoxController extends AbstractBoxController {
        /**
         * @inheritDoc
         */
-       protected $supportedPositions = ['sidebarLeft', 'sidebarRight'];
+       protected static $supportedPositions = ['sidebarLeft', 'sidebarRight'];
        
        /**
         * @inheritDoc
index cdbcc94dc4e43559ee1d4d7c28e994db8b8dab29..023bcc94af494094f3bdccacf81a80688a4ed8d1 100644 (file)
@@ -16,7 +16,7 @@ class StaffOnlineListBoxController extends AbstractDatabaseObjectListBoxControll
        /**
         * @inheritDoc
         */
-       protected $supportedPositions = ['sidebarLeft', 'sidebarRight'];
+       protected static $supportedPositions = ['sidebarLeft', 'sidebarRight'];
        
        /**
         * @inheritDoc
index 13352da45b7a417b6b110bfcc3c034d0a24580f4..0ef13cb6cf2d6ce3329c363f70c64144b7ff55ec 100644 (file)
@@ -16,7 +16,7 @@ class StatisticsBoxController extends AbstractBoxController {
        /**
         * @inheritDoc
         */
-       protected $supportedPositions = ['sidebarLeft', 'sidebarRight'];
+       protected static $supportedPositions = ['sidebarLeft', 'sidebarRight'];
        
        /**
         * @inheritDoc
index f7bb218f1fad430767353c033254420a0a1b042e..7f4f207889ec77446b63009e2097564a04919bd5 100644 (file)
@@ -17,7 +17,7 @@ class TagCloudBoxController extends AbstractBoxController {
        /**
         * @inheritDoc
         */
-       protected $supportedPositions = ['footerBoxes', 'sidebarLeft', 'sidebarRight'];
+       protected static $supportedPositions = ['footerBoxes', 'sidebarLeft', 'sidebarRight'];
        
        /**
         * taggable object type
index 3e13c57df6f0a9b70cf3f66c7a3df60257304223..f053286fa90c1a48cf3daa3695d5f1ae0ab89313 100644 (file)
@@ -20,7 +20,7 @@ class TodaysBirthdaysBoxController extends AbstractBoxController {
        /**
         * @inheritDoc
         */
-       protected $supportedPositions = ['sidebarLeft', 'sidebarRight'];
+       protected static $supportedPositions = ['sidebarLeft', 'sidebarRight'];
        
        /**
         * template name
index 40dfe3e35bb745bcab2dac2daafa71a3dbf0b61a..d5093c86d418edd7cd767df61ae497cf40009118 100644 (file)
@@ -17,7 +17,7 @@ class UserOnlineListBoxController extends AbstractDatabaseObjectListBoxControlle
        /**
         * @inheritDoc
         */
-       protected $supportedPositions = ['footerBoxes', 'sidebarLeft', 'sidebarRight'];
+       protected static $supportedPositions = ['footerBoxes', 'sidebarLeft', 'sidebarRight'];
        
        /**
         * enables the display of the user online record
index 17c2e827c43829b8ddfd54fece323ac3647d3dfa..59e9223f95bd2d080c73098199fae32081360a1e 100644 (file)
                <item name="wcf.acp.box.list"><![CDATA[Boxen]]></item>
                <item name="wcf.acp.box.name.error.notUnique"><![CDATA[Dieser Name wird bereits von einer anderen Box verwendet.]]></item>
                <item name="wcf.acp.box.position"><![CDATA[Position]]></item>
+               <item name="wcf.acp.box.position.error.invalid"><![CDATA[Die ausgewählte Position ist ungültig.]]></item>
                <item name="wcf.acp.box.showHeader"><![CDATA[Box-Titel anzeigen]]></item>
                <item name="wcf.acp.box.type"><![CDATA[Box-Typ]]></item>
                <item name="wcf.acp.box.type.html"><![CDATA[HTML]]></item>
index 9065a67cfa2c5f3b99ea73aa959f65be64a4cb2b..2d3e0e270dc1a99ac6cef04fee9a9a8cdb47ab8f 100644 (file)
@@ -160,6 +160,7 @@ Examples for medium ID detection:
                <item name="wcf.acp.box.list"><![CDATA[Boxes]]></item>
                <item name="wcf.acp.box.name.error.notUnique"><![CDATA[Name is already in use.]]></item>
                <item name="wcf.acp.box.position"><![CDATA[Position]]></item>
+               <item name="wcf.acp.box.position.error.invalid"><![CDATA[The selected position is invalid.]]></item>
                <item name="wcf.acp.box.showHeader"><![CDATA[Show box title]]></item>
                <item name="wcf.acp.box.type"><![CDATA[Page Type]]></item>
                <item name="wcf.acp.box.type.html"><![CDATA[HTML]]></item>