From c21b2424810fc1ec487f9df0d66d84744562d5db Mon Sep 17 00:00:00 2001
From: Alexander Ebert <ebert@woltlab.com>
Date: Fri, 8 Jul 2016 18:32:21 +0200
Subject: [PATCH] Added validation of box position

---
 .../install/files/acp/templates/boxAdd.tpl    |  2 +-
 .../js/WoltLab/WCF/Acp/Ui/Box/Handler.js      | 28 ++++++++++++
 .../files/lib/acp/form/BoxAddForm.class.php   | 12 ++++-
 .../files/lib/acp/form/BoxEditForm.class.php  | 44 ++++++++++++++++++-
 .../box/AbstractBoxController.class.php       |  8 ++--
 .../ArticleCategoriesBoxController.class.php  |  2 +-
 .../box/ArticleListBoxController.class.php    |  2 +-
 .../FollowingsOnlineBoxController.class.php   |  2 +-
 .../lib/system/box/IBoxController.class.php   |  2 +-
 .../PageCommentListBoxController.class.php    |  2 +-
 .../PaidSubscriptionsBoxController.class.php  |  2 +-
 .../RecentActivityListBoxController.class.php |  2 +-
 .../box/RegisterButtonBoxController.class.php |  2 +-
 .../box/SignedInAsBoxController.class.php     |  2 +-
 .../StaffOnlineListBoxController.class.php    |  2 +-
 .../box/StatisticsBoxController.class.php     |  2 +-
 .../box/TagCloudBoxController.class.php       |  2 +-
 .../TodaysBirthdaysBoxController.class.php    |  2 +-
 .../box/UserOnlineListBoxController.class.php |  2 +-
 wcfsetup/install/lang/de.xml                  |  1 +
 wcfsetup/install/lang/en.xml                  |  1 +
 21 files changed, 102 insertions(+), 22 deletions(-)

diff --git a/wcfsetup/install/files/acp/templates/boxAdd.tpl b/wcfsetup/install/files/acp/templates/boxAdd.tpl
index 7a361d34db..ceb6e473cc 100644
--- a/wcfsetup/install/files/acp/templates/boxAdd.tpl
+++ b/wcfsetup/install/files/acp/templates/boxAdd.tpl
@@ -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>
 						
diff --git a/wcfsetup/install/files/js/WoltLab/WCF/Acp/Ui/Box/Handler.js b/wcfsetup/install/files/js/WoltLab/WCF/Acp/Ui/Box/Handler.js
index c9382bdbc8..21e7ab98af 100644
--- a/wcfsetup/install/files/js/WoltLab/WCF/Acp/Ui/Box/Handler.js
+++ b/wcfsetup/install/files/js/WoltLab/WCF/Acp/Ui/Box/Handler.js
@@ -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);
+			}
 		}
 	};
 });
diff --git a/wcfsetup/install/files/lib/acp/form/BoxAddForm.class.php b/wcfsetup/install/files/lib/acp/form/BoxAddForm.class.php
index 0705b0ae29..b388b7180f 100644
--- a/wcfsetup/install/files/lib/acp/form/BoxAddForm.class.php
+++ b/wcfsetup/install/files/lib/acp/form/BoxAddForm.class.php
@@ -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,
diff --git a/wcfsetup/install/files/lib/acp/form/BoxEditForm.class.php b/wcfsetup/install/files/lib/acp/form/BoxEditForm.class.php
index 6bd2acbddf..e95643eba7 100644
--- a/wcfsetup/install/files/lib/acp/form/BoxEditForm.class.php
+++ b/wcfsetup/install/files/lib/acp/form/BoxEditForm.class.php
@@ -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
 		]);
diff --git a/wcfsetup/install/files/lib/system/box/AbstractBoxController.class.php b/wcfsetup/install/files/lib/system/box/AbstractBoxController.class.php
index 2829e5ff1f..8b8a9671ef 100644
--- a/wcfsetup/install/files/lib/system/box/AbstractBoxController.class.php
+++ b/wcfsetup/install/files/lib/system/box/AbstractBoxController.class.php
@@ -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;
diff --git a/wcfsetup/install/files/lib/system/box/ArticleCategoriesBoxController.class.php b/wcfsetup/install/files/lib/system/box/ArticleCategoriesBoxController.class.php
index 12dfda5ac7..24abad0ed2 100644
--- a/wcfsetup/install/files/lib/system/box/ArticleCategoriesBoxController.class.php
+++ b/wcfsetup/install/files/lib/system/box/ArticleCategoriesBoxController.class.php
@@ -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
diff --git a/wcfsetup/install/files/lib/system/box/ArticleListBoxController.class.php b/wcfsetup/install/files/lib/system/box/ArticleListBoxController.class.php
index 3dd0d4efed..3edfb91c95 100644
--- a/wcfsetup/install/files/lib/system/box/ArticleListBoxController.class.php
+++ b/wcfsetup/install/files/lib/system/box/ArticleListBoxController.class.php
@@ -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
diff --git a/wcfsetup/install/files/lib/system/box/FollowingsOnlineBoxController.class.php b/wcfsetup/install/files/lib/system/box/FollowingsOnlineBoxController.class.php
index d23cd62986..7b3e77a284 100644
--- a/wcfsetup/install/files/lib/system/box/FollowingsOnlineBoxController.class.php
+++ b/wcfsetup/install/files/lib/system/box/FollowingsOnlineBoxController.class.php
@@ -21,7 +21,7 @@ class FollowingsOnlineBoxController extends AbstractDatabaseObjectListBoxControl
 	/**
 	 * @inheritDoc
 	 */
-	protected $supportedPositions = ['sidebarLeft', 'sidebarRight'];
+	protected static $supportedPositions = ['sidebarLeft', 'sidebarRight'];
 	
 	/**
 	 * @inheritDoc
diff --git a/wcfsetup/install/files/lib/system/box/IBoxController.class.php b/wcfsetup/install/files/lib/system/box/IBoxController.class.php
index 77739c31b7..fc06a71f1d 100644
--- a/wcfsetup/install/files/lib/system/box/IBoxController.class.php
+++ b/wcfsetup/install/files/lib/system/box/IBoxController.class.php
@@ -73,5 +73,5 @@ interface IBoxController {
 	 * 
 	 * @return	string[]
 	 */
-	public function getSupportedPositions();
+	public static function getSupportedPositions();
 }
diff --git a/wcfsetup/install/files/lib/system/box/PageCommentListBoxController.class.php b/wcfsetup/install/files/lib/system/box/PageCommentListBoxController.class.php
index b6b4eadc9a..f97f0823c2 100644
--- a/wcfsetup/install/files/lib/system/box/PageCommentListBoxController.class.php
+++ b/wcfsetup/install/files/lib/system/box/PageCommentListBoxController.class.php
@@ -16,7 +16,7 @@ class PageCommentListBoxController extends AbstractDatabaseObjectListBoxControll
 	/**
 	 * @inheritDoc
 	 */
-	protected $supportedPositions = ['contentTop', 'contentBottom'];
+	protected static $supportedPositions = ['contentTop', 'contentBottom'];
 	
 	/**
 	 * @inheritDoc
diff --git a/wcfsetup/install/files/lib/system/box/PaidSubscriptionsBoxController.class.php b/wcfsetup/install/files/lib/system/box/PaidSubscriptionsBoxController.class.php
index 9bc0c38bb3..7f41eddd60 100644
--- a/wcfsetup/install/files/lib/system/box/PaidSubscriptionsBoxController.class.php
+++ b/wcfsetup/install/files/lib/system/box/PaidSubscriptionsBoxController.class.php
@@ -18,7 +18,7 @@ class PaidSubscriptionsBoxController extends AbstractBoxController {
 	/**
 	 * @inheritDoc
 	 */
-	protected $supportedPositions = ['contentTop', 'contentBottom', 'sidebarLeft', 'sidebarRight'];
+	protected static $supportedPositions = ['contentTop', 'contentBottom', 'sidebarLeft', 'sidebarRight'];
 	
 	/**
 	 * @inheritDoc
diff --git a/wcfsetup/install/files/lib/system/box/RecentActivityListBoxController.class.php b/wcfsetup/install/files/lib/system/box/RecentActivityListBoxController.class.php
index fa2e80bf65..f3f3a62a2f 100644
--- a/wcfsetup/install/files/lib/system/box/RecentActivityListBoxController.class.php
+++ b/wcfsetup/install/files/lib/system/box/RecentActivityListBoxController.class.php
@@ -47,7 +47,7 @@ class RecentActivityListBoxController extends AbstractDatabaseObjectListBoxContr
 	/**
 	 * @inheritDoc
 	 */
-	protected $supportedPositions = ['contentTop', 'contentBottom', 'sidebarLeft', 'sidebarRight'];
+	protected static $supportedPositions = ['contentTop', 'contentBottom', 'sidebarLeft', 'sidebarRight'];
 	
 	/**
 	 * @inheritDoc
diff --git a/wcfsetup/install/files/lib/system/box/RegisterButtonBoxController.class.php b/wcfsetup/install/files/lib/system/box/RegisterButtonBoxController.class.php
index a08bf9d266..140dadf146 100644
--- a/wcfsetup/install/files/lib/system/box/RegisterButtonBoxController.class.php
+++ b/wcfsetup/install/files/lib/system/box/RegisterButtonBoxController.class.php
@@ -15,7 +15,7 @@ class RegisterButtonBoxController extends AbstractBoxController {
 	/**
 	 * @inheritDoc
 	 */
-	protected $supportedPositions = ['sidebarLeft', 'sidebarRight'];
+	protected static $supportedPositions = ['sidebarLeft', 'sidebarRight'];
 	
 	/**
 	 * @inheritDoc
diff --git a/wcfsetup/install/files/lib/system/box/SignedInAsBoxController.class.php b/wcfsetup/install/files/lib/system/box/SignedInAsBoxController.class.php
index cbbc240c4b..8c58868372 100644
--- a/wcfsetup/install/files/lib/system/box/SignedInAsBoxController.class.php
+++ b/wcfsetup/install/files/lib/system/box/SignedInAsBoxController.class.php
@@ -15,7 +15,7 @@ class SignedInAsBoxController extends AbstractBoxController {
 	/**
 	 * @inheritDoc
 	 */
-	protected $supportedPositions = ['sidebarLeft', 'sidebarRight'];
+	protected static $supportedPositions = ['sidebarLeft', 'sidebarRight'];
 	
 	/**
 	 * @inheritDoc
diff --git a/wcfsetup/install/files/lib/system/box/StaffOnlineListBoxController.class.php b/wcfsetup/install/files/lib/system/box/StaffOnlineListBoxController.class.php
index cdbcc94dc4..023bcc94af 100644
--- a/wcfsetup/install/files/lib/system/box/StaffOnlineListBoxController.class.php
+++ b/wcfsetup/install/files/lib/system/box/StaffOnlineListBoxController.class.php
@@ -16,7 +16,7 @@ class StaffOnlineListBoxController extends AbstractDatabaseObjectListBoxControll
 	/**
 	 * @inheritDoc
 	 */
-	protected $supportedPositions = ['sidebarLeft', 'sidebarRight'];
+	protected static $supportedPositions = ['sidebarLeft', 'sidebarRight'];
 	
 	/**
 	 * @inheritDoc
diff --git a/wcfsetup/install/files/lib/system/box/StatisticsBoxController.class.php b/wcfsetup/install/files/lib/system/box/StatisticsBoxController.class.php
index 13352da45b..0ef13cb6cf 100644
--- a/wcfsetup/install/files/lib/system/box/StatisticsBoxController.class.php
+++ b/wcfsetup/install/files/lib/system/box/StatisticsBoxController.class.php
@@ -16,7 +16,7 @@ class StatisticsBoxController extends AbstractBoxController {
 	/**
 	 * @inheritDoc
 	 */
-	protected $supportedPositions = ['sidebarLeft', 'sidebarRight'];
+	protected static $supportedPositions = ['sidebarLeft', 'sidebarRight'];
 	
 	/**
 	 * @inheritDoc
diff --git a/wcfsetup/install/files/lib/system/box/TagCloudBoxController.class.php b/wcfsetup/install/files/lib/system/box/TagCloudBoxController.class.php
index f7bb218f1f..7f4f207889 100644
--- a/wcfsetup/install/files/lib/system/box/TagCloudBoxController.class.php
+++ b/wcfsetup/install/files/lib/system/box/TagCloudBoxController.class.php
@@ -17,7 +17,7 @@ class TagCloudBoxController extends AbstractBoxController {
 	/**
 	 * @inheritDoc
 	 */
-	protected $supportedPositions = ['footerBoxes', 'sidebarLeft', 'sidebarRight'];
+	protected static $supportedPositions = ['footerBoxes', 'sidebarLeft', 'sidebarRight'];
 	
 	/**
 	 * taggable object type
diff --git a/wcfsetup/install/files/lib/system/box/TodaysBirthdaysBoxController.class.php b/wcfsetup/install/files/lib/system/box/TodaysBirthdaysBoxController.class.php
index 3e13c57df6..f053286fa9 100644
--- a/wcfsetup/install/files/lib/system/box/TodaysBirthdaysBoxController.class.php
+++ b/wcfsetup/install/files/lib/system/box/TodaysBirthdaysBoxController.class.php
@@ -20,7 +20,7 @@ class TodaysBirthdaysBoxController extends AbstractBoxController {
 	/**
 	 * @inheritDoc
 	 */
-	protected $supportedPositions = ['sidebarLeft', 'sidebarRight'];
+	protected static $supportedPositions = ['sidebarLeft', 'sidebarRight'];
 	
 	/**
 	 * template name
diff --git a/wcfsetup/install/files/lib/system/box/UserOnlineListBoxController.class.php b/wcfsetup/install/files/lib/system/box/UserOnlineListBoxController.class.php
index 40dfe3e35b..d5093c86d4 100644
--- a/wcfsetup/install/files/lib/system/box/UserOnlineListBoxController.class.php
+++ b/wcfsetup/install/files/lib/system/box/UserOnlineListBoxController.class.php
@@ -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
diff --git a/wcfsetup/install/lang/de.xml b/wcfsetup/install/lang/de.xml
index 17c2e827c4..59e9223f95 100644
--- a/wcfsetup/install/lang/de.xml
+++ b/wcfsetup/install/lang/de.xml
@@ -161,6 +161,7 @@
 		<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>
diff --git a/wcfsetup/install/lang/en.xml b/wcfsetup/install/lang/en.xml
index 9065a67cfa..2d3e0e270d 100644
--- a/wcfsetup/install/lang/en.xml
+++ b/wcfsetup/install/lang/en.xml
@@ -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>
-- 
2.20.1