From: Marcel Werk Date: Tue, 3 May 2016 09:35:26 +0000 (+0200) Subject: Added box links X-Git-Tag: 3.0.0_Beta_1~1768 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=5636588a6d4aa06b6a5a88e7933cbd7fd9841b02;p=GitHub%2FWoltLab%2FWCF.git Added box links --- diff --git a/wcfsetup/install/files/acp/templates/boxAdd.tpl b/wcfsetup/install/files/acp/templates/boxAdd.tpl index 57ef98a87c..5f190776f2 100644 --- a/wcfsetup/install/files/acp/templates/boxAdd.tpl +++ b/wcfsetup/install/files/acp/templates/boxAdd.tpl @@ -12,6 +12,23 @@ } }); }); + + require(['Dictionary', 'Language', 'WoltLab/WCF/Acp/Ui/Box/Handler'], function(Dictionary, Language, AcpUiBoxHandler) { + Language.addObject({ + 'wcf.page.pageObjectID.search.noResults': '{lang}wcf.page.pageObjectID.search.noResults{/lang}', + 'wcf.page.pageObjectID.search.results': '{lang}wcf.page.pageObjectID.search.results{/lang}', + 'wcf.page.pageObjectID.search.results.description': '{lang}wcf.page.pageObjectID.search.results.description{/lang}', + 'wcf.page.pageObjectID.search.terms': '{lang}wcf.page.pageObjectID.search.terms{/lang}', + 'wcf.page.pageObjectID.search.terms.description': '{lang}wcf.page.pageObjectID.search.terms.description{/lang}' + }); + + var handlers = new Dictionary(); + {foreach from=$pageHandlers key=handlerPageID item=requireObjectID} + handlers.set({@$handlerPageID}, {if $requireObjectID}true{else}false{/if}); + {/foreach} + + AcpUiBoxHandler.init(handlers); + }); {/if} @@ -166,6 +183,78 @@ {event name='dataFields'} +
+

{lang}wcf.acp.box.link{/lang}

+ +
+
+
+ + + +
+
+ + + + + + + + {event name='linkFields'} +
+ {if !$isMultilingual}

content

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 new file mode 100644 index 0000000000..456e7a49a7 --- /dev/null +++ b/wcfsetup/install/files/js/WoltLab/WCF/Acp/Ui/Box/Handler.js @@ -0,0 +1,132 @@ +/** + * Provides the interface logic to add and edit boxes. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @module WoltLab/WCF/Acp/Ui/Box/Handler + */ +define(['Dictionary', 'WoltLab/Wcf/Ui/Page/Search/Handler'], function(Dictionary, UiPageSearchHandler) { + "use strict"; + + var _activePageId = 0; + var _cache; + var _containerExternalLink; + var _containerPageID; + var _containerPageObjectId = null; + var _handlers; + var _pageId; + var _pageObjectId; + + /** + * @exports WoltLab/WCF/Acp/Ui/Box/Handler + */ + return { + /** + * Initializes the interface logic. + * + * @param {Dictionary} handlers list of handlers by page id supporting page object ids + */ + init: function(handlers) { + _handlers = handlers; + + _containerPageID = elById('linkPageIDContainer'); + _containerExternalLink = elById('externalURLContainer'); + _containerPageObjectId = elById('linkPageObjectIDContainer'); + + if (_handlers.size) { + _pageId = elById('linkPageID'); + _pageId.addEventListener('change', this._togglePageId.bind(this)); + + _pageObjectId = elById('linkPageObjectID'); + + _cache = new Dictionary(); + _activePageId = ~~_pageId.value; + if (_activePageId && _handlers.has(_activePageId)) { + _cache.set(_activePageId, ~~_pageObjectId.value); + } + + elById('searchLinkPageObjectID').addEventListener(WCF_CLICK_EVENT, this._openSearch.bind(this)); + + // toggle page object id container on init + if (_handlers.has(~~_pageId.value)) { + elShow(_containerPageObjectId); + } + } + + elBySelAll('input[name="linkType"]', null, (function(input) { + input.addEventListener('change', this._toggleLinkType.bind(this, input.value)); + + if (input.checked) { + this._toggleLinkType(input.value); + } + }).bind(this)); + }, + + /** + * Toggles between the interface for internal and external links. + * + * @param {string} value selected option value + * @protected + */ + _toggleLinkType: function(value) { + if (value == 'none') { + elHide(_containerPageID); + elHide(_containerPageObjectId); + elHide(_containerExternalLink); + } + if (value == 'internal') { + elShow(_containerPageID); + elHide(_containerExternalLink); + this._togglePageId(); + } + if (value == 'external') { + elHide(_containerPageID); + elHide(_containerPageObjectId); + elShow(_containerExternalLink); + } + }, + + /** + * Handles the changed page selection. + * + * @protected + */ + _togglePageId: function() { + if (_handlers.has(_activePageId)) { + _cache.set(_activePageId, ~~_pageObjectId.value); + } + + _activePageId = ~~_pageId.value; + + // page w/o pageObjectID support, discard value + if (!_handlers.has(_activePageId)) { + _pageObjectId.value = ''; + + elHide(_containerPageObjectId); + + return; + } + + var newValue = ~~_cache.get(_activePageId); + _pageObjectId.value = (newValue) ? newValue : ''; + + elShow(_containerPageObjectId); + }, + + /** + * Opens the handler lookup dialog. + * + * @param {Event} event event object + * @protected + */ + _openSearch: function(event) { + event.preventDefault(); + + UiPageSearchHandler.open(_activePageId, _pageId.options[_pageId.selectedIndex].textContent, function(objectId) { + _pageObjectId.value = objectId; + _cache.set(_activePageId, objectId); + }); + } + }; +}); diff --git a/wcfsetup/install/files/lib/acp/form/BoxAddForm.class.php b/wcfsetup/install/files/lib/acp/form/BoxAddForm.class.php index a309a6b53b..596d15725a 100644 --- a/wcfsetup/install/files/lib/acp/form/BoxAddForm.class.php +++ b/wcfsetup/install/files/lib/acp/form/BoxAddForm.class.php @@ -5,11 +5,13 @@ use wcf\data\box\BoxAction; use wcf\data\box\BoxEditor; use wcf\data\media\Media; use wcf\data\media\ViewableMediaList; +use wcf\data\page\Page; use wcf\data\page\PageNodeTree; use wcf\form\AbstractForm; use wcf\system\database\util\PreparedStatementConditionBuilder; use wcf\system\exception\UserInputException; use wcf\system\language\LanguageFactory; +use wcf\system\page\handler\ILookupPageHandler; use wcf\system\WCF; use wcf\util\ArrayUtil; use wcf\util\StringUtil; @@ -120,6 +122,42 @@ class BoxAddForm extends AbstractForm { */ public $pageIDs = []; + /** + * link type + * @var string + */ + public $linkType = 'none'; + + /** + * link page id + * @var int + */ + public $linkPageID = 0; + + /** + * link page object id + * @var int + */ + public $linkPageObjectID = 0; + + /** + * link external URL + * @var string + */ + public $externalURL = ''; + + /** + * list of page handlers by page id + * @var \wcf\system\page\handler\IMenuPageHandler[] + */ + public $pageHandlers = []; + + /** + * nested list of page nodes + * @var \RecursiveIteratorIterator + */ + public $pageNodeList; + /** * @inheritDoc */ @@ -127,6 +165,18 @@ class BoxAddForm extends AbstractForm { parent::readParameters(); if (!empty($_REQUEST['isMultilingual'])) $this->isMultilingual = 1; + + $this->pageNodeList = (new PageNodeTree())->getNodeList(); + + // fetch page handlers + foreach ($this->pageNodeList as $pageNode) { + $handler = $pageNode->getPage()->getHandler(); + if ($handler !== null) { + if ($handler instanceof ILookupPageHandler) { + $this->pageHandlers[$pageNode->getPage()->pageID] = $pageNode->getPage()->requireObjectID; + } + } + } } /** @@ -146,6 +196,11 @@ class BoxAddForm extends AbstractForm { if (isset($_POST['controller'])) $this->controller = StringUtil::trim($_POST['controller']); if (isset($_POST['pageIDs']) && is_array($_POST['pageIDs'])) $this->pageIDs = ArrayUtil::toIntegerArray($_POST['pageIDs']); + if (isset($_POST['linkType'])) $this->linkType = $_POST['linkType']; + if (!empty($_POST['linkPageID'])) $this->linkPageID = intval($_POST['linkPageID']); + if (!empty($_POST['linkPageObjectID'])) $this->linkPageObjectID = intval($_POST['linkPageObjectID']); + if (isset($_POST['externalURL'])) $this->externalURL = StringUtil::trim($_POST['externalURL']); + if (isset($_POST['title']) && is_array($_POST['title'])) $this->title = ArrayUtil::trim($_POST['title']); if (isset($_POST['content']) && is_array($_POST['content'])) $this->content = ArrayUtil::trim($_POST['content']); @@ -202,6 +257,43 @@ class BoxAddForm extends AbstractForm { // @todo check controller } + // validate link + if ($this->linkType == 'internal') { + $this->externalURL = ''; + + if (!$this->linkPageID) { + throw new UserInputException('linkPageID'); + } + $page = new Page($this->linkPageID); + if (!$page->pageID) { + throw new UserInputException('linkPageID', 'invalid'); + } + + // validate page object id + if (isset($this->pageHandlers[$page->pageID])) { + if ($this->pageHandlers[$page->pageID] && !$this->linkPageObjectID) { + throw new UserInputException('linkPageObjectID'); + } + + /** @var ILookupPageHandler $handler */ + $handler = $page->getHandler(); + if ($this->linkPageObjectID && !$handler->isValid($this->linkPageObjectID)) { + throw new UserInputException('linkPageObjectID', 'invalid'); + } + } + } + else if ($this->linkType == 'external') { + $this->linkPageID = $this->linkPageObjectID = null; + + if (empty($this->externalURL)) { + throw new UserInputException('externalURL'); + } + } + else { + $this->linkPageID = $this->linkPageObjectID = null; + $this->externalURL = ''; + } + // validate page ids if (!empty($this->pageIDs)) { $conditionBuilder = new PreparedStatementConditionBuilder(); @@ -274,6 +366,9 @@ class BoxAddForm extends AbstractForm { 'cssClassName' => $this->cssClassName, 'showHeader' => $this->showHeader, 'controller' => $this->controller, + 'linkPageID' => $this->linkPageID, + 'linkPageObjectID' => ($this->linkPageObjectID ?: 0), + 'externalURL' => $this->externalURL, 'identifier' => '' ]), 'content' => $content, 'pageIDs' => $this->pageIDs ]); $returnValues = $this->objectAction->executeAction(); @@ -319,10 +414,15 @@ class BoxAddForm extends AbstractForm { 'imageID' => $this->imageID, 'images' => $this->images, 'pageIDs' => $this->pageIDs, + 'linkType' => $this->linkType, + 'linkPageID' => $this->linkPageID, + 'linkPageObjectID' => $this->linkPageObjectID, + 'externalURL' => $this->externalURL, 'availableLanguages' => LanguageFactory::getInstance()->getLanguages(), 'availableBoxTypes' => Box::$availableBoxTypes, 'availablePositions' => Box::$availablePositions, - 'pageNodeList' => (new PageNodeTree())->getNodeList() + '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 817e1adaca..2634407ed3 100644 --- a/wcfsetup/install/files/lib/acp/form/BoxEditForm.class.php +++ b/wcfsetup/install/files/lib/acp/form/BoxEditForm.class.php @@ -132,6 +132,11 @@ class BoxEditForm extends BoxAddForm { if ($this->box->visibleEverywhere) $this->visibleEverywhere = 1; else $this->visibleEverywhere = 0; $this->pageIDs = $this->box->getPageIDs(); + $this->linkPageID = $this->box->linkPageID; + $this->linkPageObjectID = $this->box->linkPageObjectID; + $this->externalURL = $this->box->externalURL; + if ($this->linkPageID) $this->linkType = 'internal'; + if ($this->externalURL) $this->linkType = 'external'; foreach ($this->box->getBoxContent() as $languageID => $content) { $this->title[$languageID] = $content['title']; diff --git a/wcfsetup/install/files/lib/data/box/Box.class.php b/wcfsetup/install/files/lib/data/box/Box.class.php index b361ed0e53..05a72bd062 100644 --- a/wcfsetup/install/files/lib/data/box/Box.class.php +++ b/wcfsetup/install/files/lib/data/box/Box.class.php @@ -4,6 +4,11 @@ use wcf\data\media\ViewableMedia; use wcf\data\menu\Menu; use wcf\data\menu\MenuCache; use wcf\data\DatabaseObject; +use wcf\data\page\Page; +use wcf\data\page\PageCache; +use wcf\system\exception\SystemException; +use wcf\system\page\handler\ILookupPageHandler; +use wcf\system\page\handler\IMenuPageHandler; use wcf\system\WCF; use wcf\util\StringUtil; @@ -32,6 +37,9 @@ use wcf\util\StringUtil; * @property-read integer $packageID * @property-read string $controller * @property-read integer|null $menuID + * @property-read integer $linkPageID + * @property-read integer $linkPageObjectID + * @property-read string $externalURL */ class Box extends DatabaseObject { /** @@ -92,6 +100,17 @@ class Box extends DatabaseObject { */ protected $__controller; + /** + * @var IMenuPageHandler + */ + protected $linkPageHandler; + + /** + * page object + * @var Page + */ + protected $linkPage; + /** * Returns true if the active user can delete this box. * @@ -308,14 +327,68 @@ class Box extends DatabaseObject { return (isset($boxContent[0]) && $boxContent[0]['imageID']); } + /** + * Returns the URL of this box. + * + * @return string + */ public function getLink() { - // @todo - return ''; + if ($this->linkPageObjectID) { + $handler = $this->getLinkPageHandler(); + if ($handler && $handler instanceof ILookupPageHandler) { + return $handler->getLink($this->linkPageObjectID); + } + } + + if ($this->linkPageID) { + return $this->getLinkPage()->getLink(); + } + else { + return $this->externalURL; + } } + /** + * Returns true if this box has a link. + * + * @return boolean + */ public function hasLink() { - // @todo - return false; + return ($this->linkPageID || !empty($this->externalURL)); + } + + /** + * Returns the IMenuPageHandler of the linked page. + * + * @return IMenuPageHandler|null + * @throws SystemException + */ + protected function getLinkPageHandler() { + $page = $this->getLinkPage(); + if ($page !== null && $page->handler) { + if ($this->linkPageHandler === null) { + $className = $page->handler; + $this->linkPageHandler = new $className; + if (!($this->linkPageHandler instanceof IMenuPageHandler)) { + throw new SystemException("Expected a valid handler implementing '" . IMenuPageHandler::class . "'."); + } + } + } + + return $this->linkPageHandler; + } + + /** + * Returns the page that is linked by this box. + * + * @return Page|null + */ + public function getLinkPage() { + if ($this->linkPage === null && $this->linkPageID) { + $this->linkPage = PageCache::getInstance()->getPage($this->linkPageID); + } + + return $this->linkPage; } /** diff --git a/wcfsetup/setup/db/install.sql b/wcfsetup/setup/db/install.sql index a7a4950c0c..4d976be425 100644 --- a/wcfsetup/setup/db/install.sql +++ b/wcfsetup/setup/db/install.sql @@ -238,7 +238,10 @@ CREATE TABLE wcf1_box ( originIsSystem TINYINT(1) NOT NULL DEFAULT 0, packageID INT(10) NOT NULL, controller VARCHAR(255) NOT NULL DEFAULT '', - menuID INT(10) NULL + menuID INT(10), + linkPageID INT(10), + linkPageObjectID INT(10) NOT NULL DEFAULT 0, + externalURL VARCHAR(255) NOT NULL DEFAULT '' ); DROP TABLE IF EXISTS wcf1_box_content; @@ -1639,6 +1642,7 @@ ALTER TABLE wcf1_bbcode_attribute ADD FOREIGN KEY (bbcodeID) REFERENCES wcf1_bbc ALTER TABLE wcf1_box ADD FOREIGN KEY (packageID) REFERENCES wcf1_package (packageID) ON DELETE CASCADE; ALTER TABLE wcf1_box ADD FOREIGN KEY (menuID) REFERENCES wcf1_menu (menuID) ON DELETE CASCADE; +ALTER TABLE wcf1_box ADD FOREIGN KEY (linkPageID) REFERENCES wcf1_page (pageID) ON DELETE SET NULL; ALTER TABLE wcf1_box_content ADD FOREIGN KEY (boxID) REFERENCES wcf1_box (boxID) ON DELETE CASCADE; ALTER TABLE wcf1_box_content ADD FOREIGN KEY (languageID) REFERENCES wcf1_language (languageID) ON DELETE CASCADE;