<showorder>3</showorder>
</acpmenuitem>
+ <!-- page menu -->
+ <acpmenuitem name="wcf.acp.menu.link.pageMenu">
+ <parent>wcf.acp.menu.link.display</parent>
+ </acpmenuitem>
+
+ <acpmenuitem name="wcf.acp.menu.link.pageMenu.list">
+ <link>index.php/PageMenuItemList/</link>
+ <parent>wcf.acp.menu.link.pageMenu</parent>
+ <permissions>admin.display.canManagePageMenu</permissions>
+ <showorder>1</showorder>
+ </acpmenuitem>
+
+ <acpmenuitem name="wcf.acp.menu.link.pageMenu.add">
+ <link>index.php/PageMenuItemAdd/</link>
+ <parent>wcf.acp.menu.link.pageMenu</parent>
+ <permissions>admin.display.canManagePageMenu</permissions>
+ <showorder>2</showorder>
+ </acpmenuitem>
+ <!-- /page menu -->
+
<acpmenuitem name="wcf.acp.menu.link.content">
<showorder>4</showorder>
</acpmenuitem>
<category name="admin.style">
<parent>admin.display</parent>
</category>
+ <category name="admin.display.pageMenu">
+ <parent>admin.display</parent>
+ </category>
<category name="admin.content">
<parent>admin</parent>
<admindefaultvalue>1</admindefaultvalue>
<showorder>4</showorder>
</option>
+ <option name="admin.display.canManagePageMenu">
+ <categoryname>admin.display.pageMenu</categoryname>
+ <optiontype>boolean</optiontype>
+ <defaultvalue>0</defaultvalue>
+ <admindefaultvalue>1</admindefaultvalue>
+ </option>
</options>
</import>
</data>
<nav id="mainMenu" class="mainMenu">
<ul>
{content}
- {foreach from=$__wcf->getACPMenu()->getMenuItems('') item=menuItem}
- <li data-menu-item="{$menuItem->menuItem}"><a>{lang}{@$menuItem->menuItem}{/lang}</a></li>
+ {foreach from=$__wcf->getACPMenu()->getMenuItems('') item=_menuItem}
+ <li data-menu-item="{$_menuItem->menuItem}"><a>{lang}{@$_menuItem->menuItem}{/lang}</a></li>
{/foreach}
{/content}
</ul>
{content}
{* work-around for unknown core-object during WCFSetup *}
{if PACKAGE_ID}
- {foreach from=$__wcf->getACPMenu()->getMenuItems('') item=parentMenuItem}
- <div id="{$parentMenuItem->menuItem}-container" style="display: none;" class="menuGroup collapsibleMenus" data-parent-menu-item="{$parentMenuItem->menuItem}">
- {foreach from=$__wcf->getACPMenu()->getMenuItems($parentMenuItem->menuItem) item=menuItem}
+ {foreach from=$__wcf->getACPMenu()->getMenuItems('') item=_parentMenuItem}
+ <div id="{$_parentMenuItem->menuItem}-container" style="display: none;" class="menuGroup collapsibleMenus" data-parent-menu-item="{$_parentMenuItem->menuItem}">
+ {foreach from=$__wcf->getACPMenu()->getMenuItems($_parentMenuItem->menuItem) item=_menuItem}
<fieldset>
- <legend class="menuHeader" data-menu-item="{$menuItem->menuItem}">{lang}{@$menuItem->menuItem}{/lang}</legend>
+ <legend class="menuHeader" data-menu-item="{$_menuItem->menuItem}">{lang}{@$_menuItem->menuItem}{/lang}</legend>
<nav class="menuGroupItems">
- <ul id="{$menuItem->menuItem}">
- {foreach from=$__wcf->getACPMenu()->getMenuItems($menuItem->menuItem) item=menuItemCategory}
+ <ul id="{$_menuItem->menuItem}">
+ {foreach from=$__wcf->getACPMenu()->getMenuItems($_menuItem->menuItem) item=menuItemCategory}
{if $__wcf->getACPMenu()->getMenuItems($menuItemCategory->menuItem)|count > 0}
{foreach from=$__wcf->getACPMenu()->getMenuItems($menuItemCategory->menuItem) item=subMenuItem}
<li id="{$subMenuItem->menuItem}" data-menu-item="{$subMenuItem->menuItem}"><a href="{$subMenuItem->getLink()}">{lang}{$subMenuItem->menuItem}{/lang}</a></li>
--- /dev/null
+{include file='header' pageTitle='wcf.acp.pageMenu.'|concat:$action}
+
+<script type="text/javascript">
+ //<![CDATA[
+ $(function() {
+ var $isDisabled = $('#isDisabled');
+ var $isLandingPageContainer = $('#isLandingPageContainer');
+ var $menuPosition = $('#menuPosition');
+ var $parentMenuItemContainer = $('#parentMenuItemContainer');
+
+ function handleMenuPosition() {
+ if ($menuPosition.val() === 'header') {
+ $parentMenuItemContainer.show();
+
+ if (!$isDisabled.is(':checked')) {
+ $isLandingPageContainer.show();
+ }
+ }
+ else {
+ $parentMenuItemContainer.hide();
+ $isLandingPageContainer.hide();
+ }
+ }
+
+ function handleIsDisabled() {
+ if ($isDisabled.is(':checked')) {
+ $isLandingPageContainer.hide();
+ }
+ else {
+ $isLandingPageContainer.show();
+ }
+ }
+
+ $isDisabled.change(handleIsDisabled);
+ $menuPosition.change(handleMenuPosition);
+
+ handleIsDisabled();
+ handleMenuPosition();
+ });
+ //]]>
+</script>
+
+<header class="boxHeadline">
+ <hgroup>
+ <h1>{lang}wcf.acp.pageMenu.{$action}{/lang}</h1>
+ </hgroup>
+</header>
+
+{if $errorField}
+ <p class="error">{lang}wcf.global.form.error{/lang}</p>
+{/if}
+
+{if $success|isset}
+ <p class="success">{lang}wcf.global.form.{$action}.success{/lang}</p>
+{/if}
+
+<div class="contentNavigation">
+ <nav>
+ <ul>
+ <li><a href="{link controller='PageMenuItemList'}{/link}" class="button"><img src="{@RELATIVE_WCF_DIR}icon/list.svg" alt="" /> <span>{lang}wcf.acp.pageMenu.list{/lang}</span></a></li>
+ </ul>
+ </nav>
+</div>
+
+<div class="container containerPadding marginTop">
+ <form method="post" action="{if $action == 'add'}{link controller='PageMenuItemAdd'}{/link}{else}{link controller='PageMenuItemEdit' id=$menuItem->menuItemID}{/link}{/if}">
+ <fieldset>
+ <legend>{lang}wcf.acp.pageMenu.data{/lang}</legend>
+
+ <dl{if $errorField == 'menuPosition'} class="formError"{/if}>
+ <dt><label for="menuPosition">{lang}wcf.acp.pageMenu.menuPosition{/lang}</label></dt>
+ <dd>
+ <select name="menuPosition" id="menuPosition">
+ <option value="header"{if $menuPosition == 'header'} selected="selected"{/if}>{lang}wcf.acp.pageMenu.menuPosition.header{/lang}</option>
+ <option value="footer"{if $menuPosition == 'footer'} selected="selected"{/if}>{lang}wcf.acp.pageMenu.menuPosition.footer{/lang}</option>
+ </select>
+ {if $errorField == 'menuPosition'}
+ <small class="innerError">
+ {if $errorType == 'empty'}
+ {lang}wcf.global.form.error.empty{/lang}
+ {else}
+ {lang}wcf.acp.pageMenu.menuPosition.error.{$errorType}{/lang}
+ {/if}
+ </small>
+ {/if}
+ </dd>
+ </dl>
+
+ <dl id="parentMenuItemContainer"{if $errorField == 'parentMenuItem'} class="formError"{/if}>
+ <dt><label for="parentMenuItem">{lang}wcf.acp.pageMenu.parentMenuItem{/lang}</label></dt>
+ <dd>
+ <select name="parentMenuItem" id="parentMenuItem">
+ <option value=""{if $parentMenuItem == ''} selected="selected"{/if}></option>
+ {foreach from=$availableParentMenuItems item=availableParentMenuItem}
+ <option value="{$availableParentMenuItem->menuItem}"{if $parentMenuItem == $availableParentMenuItem->menuItem} selected="selected"{/if}>{$availableParentMenuItem}</option>
+ {/foreach}
+ </select>
+ {if $errorField == 'parentMenuItem'}
+ <small class="innerError">
+ {if $errorType == 'empty'}
+ {lang}wcf.global.form.error.empty{/lang}
+ {else}
+ {lang}wcf.acp.pageMenu.parentMenuItem.error.{$errorType}{/lang}
+ {/if}
+ </small>
+ {/if}
+ </dd>
+ </dl>
+
+ <dl{if $errorField == 'pageMenuItem'} class="formError"{/if}>
+ <dt><label for="pageMenuItem">{lang}wcf.acp.pageMenu.pageMenuItem{/lang}</label></dt>
+ <dd>
+ <input type="text" name="pageMenuItem" id="pageMenuItem" value="{$pageMenuItem}" class="long" required="required" />
+ {if $errorField == 'pageMenuItem'}
+ <small class="innerError">
+ {if $errorType == 'empty'}
+ {lang}wcf.global.form.error.empty{/lang}
+ {else}
+ {lang}wcf.acp.pageMenu.pageMenuItem.error.{$errorType}{/lang}
+ {/if}
+ </small>
+ {/if}
+
+ {include file='multipleLanguageInputJavascript' elementIdentifier='pageMenuItem' forceSelection=true}
+ </dd>
+ </dl>
+
+ <dl{if $errorField == 'menuItemLink'} class="formError"{/if}>
+ <dt><label for="menuItemLink">{lang}wcf.acp.pageMenu.menuItemLink{/lang}</label></dt>
+ <dd>
+ <input type="text" name="menuItemLink" id="menuItemLink" value="{$menuItemLink}" class="long" required="required" />
+ {if $errorField == 'menuItemLink'}
+ <small class="innerError">
+ {if $errorType == 'empty'}
+ {lang}wcf.global.form.error.empty{/lang}
+ {else}
+ {lang}wcf.acp.pageMenu.menuItemLink.error.{$errorType}{/lang}
+ {/if}
+ </small>
+ {/if}
+
+ {include file='multipleLanguageInputJavascript' elementIdentifier='menuItemLink' forceSelection=false}
+ </dd>
+ </dl>
+
+ <dl>
+ <dd>
+ <label><input type="checkbox" name="newWindow" id="newWindow" value="1"{if $newWindow} checked="checked"{/if} /> <span>{lang}wcf.acp.pageMenu.newWindow{/lang}</span></label>
+ </dd>
+ </dl>
+ </fieldset>
+
+ <fieldset>
+ <legend>{lang}wcf.acp.pageMenu.advanced{/lang}</legend>
+
+ <dl>
+ <dt><label for="showOrder">{lang}wcf.acp.pageMenu.showOrder{/lang}</label></dt>
+ <dd>
+ <input type="number" name="showOrder" id="showOrder" value="{@$showOrder}" class="long" min="0" />
+ </dd>
+ </dl>
+
+ <dl>
+ <dd>
+ <label><input type="checkbox" name="isDisabled" id="isDisabled" value="1"{if $isDisabled} checked="checked"{/if} /> <span>{lang}wcf.acp.pageMenu.isDisabled{/lang}</span></label>
+ </dd>
+ </dl>
+
+ <dl id="isLandingPageContainer">
+ <dd>
+ <label><input type="checkbox" name="isLandingPage" id="isLandingPage" value="1"{if $isLandingPage} checked="checked"{/if} /> <span>{lang}wcf.acp.pageMenu.isLandingPage{/lang}</span></label>
+ <small>{lang}wcf.acp.pageMenu.isLandingPage.description{/lang}</small>
+ </dd>
+ </dl>
+ </fieldset>
+
+ <div class="formSubmit">
+ <input type="submit" value="{lang}wcf.global.button.submit{/lang}" />
+ </div>
+ </form>
+</div>
+
+<div class="contentNavigation">
+ <nav>
+ <ul>
+ <li><a href="{link controller='PageMenuItemList'}{/link}" class="button"><img src="{@RELATIVE_WCF_DIR}icon/list.svg" alt="" /> <span>{lang}wcf.acp.pageMenu.list{/lang}</span></a></li>
+ </ul>
+ </nav>
+</div>
+
+{include file='footer'}
--- /dev/null
+{include file='header' pageTitle='wcf.acp.pageMenu.list'}
+
+<header class="boxHeadline">
+ <hgroup>
+ <h1>{lang}wcf.acp.pageMenu.list{/lang}</h1>
+ </hgroup>
+</header>
+
+<script type="text/javascript">
+ //<![CDATA[
+ $(function() {
+ new WCF.Action.Delete('wcf\\data\\page\\menu\\item\\PageMenuItemAction', $('.sortableNode'));
+ new WCF.Action.Toggle('wcf\\data\\page\\menu\\item\\PageMenuItemAction', $('.sortableNode'));
+
+ {if $headerItems|count}new WCF.Sortable.List('pageMenuItemHeaderList', 'wcf\\data\\page\\menu\\item\\PageMenuItemAction', undefined, { protectRoot: true }, false, { menuPosition: 'header' });{/if}
+ {if $footerItems|count}new WCF.Sortable.List('pageMenuItemFooterList', 'wcf\\data\\page\\menu\\item\\PageMenuItemAction', undefined, { }, true, { menuPosition: 'footer' });{/if}
+ });
+ //]]>
+</script>
+
+<div class="contentNavigation">
+ <nav>
+ <ul>
+ <li><a href="{link controller='PageMenuItemAdd'}{/link}" title="{lang}wcf.acp.pageMenu.add{/lang}" class="button"><img src="{@$__wcf->getPath()}icon/add.svg" alt="" class="icon24" /> <span>{lang}wcf.acp.pageMenu.add{/lang}</span></a></li>
+
+ {event name='largeButtonsTop'}
+ </ul>
+ </nav>
+</div>
+
+{hascontent}
+ <fieldset>
+ <legend>{lang}wcf.acp.pageMenu.header{/lang}</legend>
+
+ <div id="pageMenuItemHeaderList" class="container containerPadding sortableListContainer">
+ <ol class="sortableList" data-object-id="0">
+ {content}
+ {foreach from=$headerItems item=menuItem}
+ <li class="sortableNode" data-object-id="{@$menuItem->menuItemID}">
+ <span class="sortableNodeLabel">
+ <a href="{link controller='PageMenuItemEdit' id=$menuItem->menuItemID}{/link}">{lang}{$menuItem->menuItem}{/lang}</a>
+ <span class="statusDisplay sortableButtonContainer">
+ <img src="{@$__wcf->getPath()}icon/{if $menuItem->isDisabled}disabled{else}enabled{/if}.svg" alt="" title="{lang}wcf.global.button.{if $menuItem->isDisabled}enable{else}disable{/if}{/lang}" class="icon16 jsToggleButton jsTooltip pointer" data-object-id="{@$menuItem->menuItemID}" data-disable-message="{lang}wcf.global.button.disable{/lang}" data-enable-message="{lang}wcf.global.button.enable{/lang}" />
+ <a href="{link controller='PageMenuItemEdit' id=$menuItem->menuItemID}{/link}" class="jsTooltip" title="{lang}wcf.global.button.edit{/lang}"><img src="{@$__wcf->getPath()}icon/edit.svg" alt="" class="icon16" /></a>
+ <img src="{@$__wcf->getPath()}icon/delete.svg" alt="" title="{lang}wcf.global.button.delete{/lang}" class="icon16 jsDeleteButton jsTooltip pointer" data-object-id="{@$menuItem->menuItemID}" data-confirm-message="{lang}wcf.acp.pageMenu.delete.sure{/lang}" />
+ </span>
+ </span>
+ {if $menuItem|count}
+ <ol class="sortableList" data-object-id="{@$menuItem->menuItemID}">
+ {foreach from=$menuItem item=childMenuItem}
+ <li class="sortableNode sortableNoNesting" data-object-id="{@$childMenuItem->menuItemID}">
+ <span class="sortableNodeLabel">
+ <a href="{link controller='PageMenuItemEdit' id=$childMenuItem->menuItemID}{/link}">{lang}{$childMenuItem->menuItem}{/lang}</a>
+ <span class="statusDisplay sortableButtonContainer">
+ <img src="{@$__wcf->getPath()}icon/{if $childMenuItem->isDisabled}disabled{else}enabled{/if}.svg" alt="" title="{lang}wcf.global.button.{if $childMenuItem->isDisabled}enable{else}disable{/if}{/lang}" class="icon16 jsToggleButton jsTooltip pointer" data-object-id="{@$childMenuItem->menuItemID}" data-disable-message="{lang}wcf.global.button.disable{/lang}" data-enable-message="{lang}wcf.global.button.enable{/lang}" />
+ <a href="{link controller='PageMenuItemEdit' id=$childMenuItem->menuItemID}{/link}" class="jsTooltip" title="{lang}wcf.global.button.edit{/lang}"><img src="{@$__wcf->getPath()}icon/edit.svg" alt="" class="icon16" /></a>
+ <img src="{@$__wcf->getPath()}icon/delete.svg" alt="" title="{lang}wcf.global.button.delete{/lang}" class="icon16 jsDeleteButton jsTooltip pointer" data-object-id="{@$childMenuItem->menuItemID}" data-confirm-message="{lang}wcf.acp.pageMenu.delete.sure{/lang}" />
+ </span>
+ </span>
+ </li>
+ {/foreach}
+ </ol>
+ {/if}
+ </li>
+ {/foreach}
+ {/content}
+ </ol>
+
+ <div class="formSubmit">
+ <button data-type="submit">{lang}wcf.global.button.save{/lang}</button>
+ </div>
+ </div>
+ </fieldset>
+{/hascontent}
+
+{hascontent}
+ <fieldset>
+ <legend>{lang}wcf.acp.pageMenu.footer{/lang}</legend>
+
+ <div id="pageMenuItemFooterList" class="container containerPadding sortableListContainer">
+ <ol class="sortableList simpleSortableList">
+ {content}
+ {foreach from=$footerItems item=menuItem}
+ <li class="sortableNode" data-object-id="{@$menuItem->menuItemID}">
+ <span class="sortableNodeLabel">
+ <a href="{link controller='PageMenuItemEdit' id=$menuItem->menuItemID}{/link}">{lang}{$menuItem->menuItem}{/lang}</a>
+ <span class="statusDisplay sortableButtonContainer">
+ <img src="{@$__wcf->getPath()}icon/{if $menuItem->isDisabled}disabled{else}enabled{/if}.svg" alt="" title="{lang}wcf.global.button.{if $menuItem->isDisabled}enable{else}disable{/if}{/lang}" class="icon16 jsToggleButton jsTooltip pointer" data-object-id="{@$menuItem->menuItemID}" data-disable-message="{lang}wcf.global.button.disable{/lang}" data-enable-message="{lang}wcf.global.button.enable{/lang}" />
+ <a href="{link controller='PageMenuItemEdit' id=$menuItem->menuItemID}{/link}" class="jsTooltip" title="{lang}wcf.global.button.edit{/lang}"><img src="{@$__wcf->getPath()}icon/edit.svg" alt="" class="icon16" /></a>
+ <img src="{@$__wcf->getPath()}icon/delete.svg" alt="" title="{lang}wcf.global.button.delete{/lang}" class="icon16 jsDeleteButton jsTooltip pointer" data-object-id="{@$menuItem->menuItemID}" data-confirm-message="{lang}wcf.acp.pageMenu.delete.sure{/lang}" />
+ </span>
+ </span>
+ </li>
+ {/foreach}
+ {/content}
+ </ol>
+
+ <div class="formSubmit">
+ <button data-type="submit">{lang}wcf.global.button.save{/lang}</button>
+ </div>
+ </div>
+ </fieldset>
+{/hascontent}
+
+<div class="contentNavigation">
+ <nav>
+ <ul>
+ <li><a href="{link controller='PageMenuItemAdd'}{/link}" title="{lang}wcf.acp.pageMenu.add{/lang}" class="button"><img src="{@$__wcf->getPath()}icon/add.svg" alt="" class="icon24" /> <span>{lang}wcf.acp.pageMenu.add{/lang}</span></a></li>
+
+ {event name='largeButtonsBottom'}
+ </ul>
+ </nav>
+</div>
+
+{include file='footer'}
--- /dev/null
+<?php
+namespace wcf\acp\form;
+use wcf\data\page\menu\item\PageMenuItemAction;
+use wcf\data\page\menu\item\PageMenuItemEditor;
+use wcf\data\page\menu\item\PageMenuItemList;
+use wcf\system\exception\UserInputException;
+use wcf\system\language\I18nHandler;
+use wcf\system\package\PackageDependencyHandler;
+use wcf\system\WCF;
+use wcf\util\StringUtil;
+
+/**
+ * Shows the page menu item add form.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2012 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage acp.form
+ * @category Community Framework
+ */
+class PageMenuItemAddForm extends ACPForm {
+ /**
+ * @see wcf\acp\form\ACPForm::$activeMenuItem
+ */
+ public $activeMenuItem = 'wcf.acp.menu.link.pageMenu.add';
+
+ /**
+ * list of available parent menu items
+ * @var wcf\data\page\menu\item\PageMenuItemList
+ */
+ public $availableParentMenuItems = null;
+
+ /**
+ * activation state
+ * @var boolean
+ */
+ public $isDisabled = false;
+
+ /**
+ * true, if menu item is landing page
+ * @var boolean
+ */
+ public $isLandingPage = false;
+
+ /**
+ * menu item link
+ * @var string
+ */
+ public $menuItemLink = '';
+
+ /**
+ * menu item position
+ * @var string
+ */
+ public $menuPosition = 'header';
+
+ /**
+ * @see wcf\page\AbstractPage::$neededPermissions
+ */
+ public $neededPermissions = array('admin.display.canManagePageMenu');
+
+ /**
+ * open link in new window
+ * @var boolean
+ */
+ public $newWindow = false;
+
+ /**
+ * page menu item name
+ * @var string
+ */
+ public $pageMenuItem = '';
+
+ /**
+ * parent menu item
+ * @var string
+ */
+ public $parentMenuItem = '';
+
+ /**
+ * show order
+ * @var integer
+ */
+ public $showOrder = 0;
+
+ /**
+ * @see wcf\page\IPage::readParameters()
+ */
+ public function readParameters() {
+ parent::readParameters();
+
+ I18nHandler::getInstance()->register('menuItemLink');
+ I18nHandler::getInstance()->register('pageMenuItem');
+
+ $this->readAvailableParentMenuItems();
+ }
+
+ /**
+ * Prepares list object to read available parent menu items.
+ */
+ protected function initAvailableParentMenuItems() {
+ $this->availableParentMenuItems = new PageMenuItemList();
+ $this->availableParentMenuItems->getConditionBuilder()->add("page_menu_item.packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies()));
+ $this->availableParentMenuItems->getConditionBuilder()->add("page_menu_item.parentMenuItem = ''");
+ $this->availableParentMenuItems->sqlOrderBy = "page_menu_item.showOrder ASC";
+ }
+
+ /**
+ * Reads a list of available parent menu items.
+ */
+ protected function readAvailableParentMenuItems() {
+ $this->initAvailableParentMenuItems();
+
+ $this->availableParentMenuItems->readObjects();
+ }
+
+ /**
+ * @see wcf\form\IForm::readFormParameters()
+ */
+ public function readFormParameters() {
+ parent::readFormParameters();
+
+ I18nHandler::getInstance()->readValues();
+ if (I18nHandler::getInstance()->isPlainValue('menuItemLink')) $this->menuItemLink = I18nHandler::getInstance()->getValue('menuItemLink');
+ if (I18nHandler::getInstance()->isPlainValue('pageMenuItem')) $this->pageMenuItem = I18nHandler::getInstance()->getValue('pageMenuItem');
+
+ if (isset($_POST['isDisabled'])) $this->isDisabled = true;
+ if (isset($_POST['isLandingPage'])) $this->isLandingPage = true;
+ if (isset($_POST['menuPosition'])) $this->menuPosition = StringUtil::trim($_POST['menuPosition']);
+ if (isset($_POST['newWindow'])) $this->newWindow = true;
+ if (isset($_POST['parentMenuItem'])) $this->parentMenuItem = StringUtil::trim($_POST['parentMenuItem']);
+ if (isset($_POST['showOrder'])) $this->showOrder = intval($_POST['showOrder']);
+ }
+
+ /**
+ * @see wcf\form\IForm::validate()
+ */
+ public function validate() {
+ parent::validate();
+
+ // validate menu position
+ if (empty($this->menuPosition)) {
+ throw new UserInputException('menuPosition');
+ }
+ else if ($this->menuPosition != 'header' && $this->menuPosition != 'footer') {
+ throw new UserInputException('menuPosition', 'notValid');
+ }
+
+ // validate menu item link
+ if (!I18nHandler::getInstance()->validateValue('menuItemLink')) {
+ throw new UserInputException('menuItemLink');
+ }
+
+ // validate page menu item name
+ if (!I18nHandler::getInstance()->validateValue('pageMenuItem', true)) {
+ throw new UserInputException('pageMenuItem');
+ }
+
+ // validate parent menu item
+ if ($this->menuPosition == 'footer') {
+ $this->parentMenuItem = '';
+ }
+ else if (!empty($this->parentMenuItem)) {
+ $valid = false;
+ foreach ($this->availableParentMenuItems as $menuItem) {
+ if ($menuItem->menuItem == $this->parentMenuItem) {
+ $valid = true;
+ break;
+ }
+ }
+
+ if (!$valid) {
+ throw new UserInputException('parentMenuItem', 'notValid');
+ }
+ }
+
+ // validate landing page
+ if ($this->isDisabled) {
+ $this->isLandingPage = false;
+ }
+ else if ($this->menuPosition == 'footer' || !empty($this->parentMenuItem)) {
+ $this->isLandingPage = false;
+ }
+ }
+
+ /**
+ * @see wcf\form\IForm::save()
+ */
+ public function save() {
+ parent::save();
+
+ $this->objectAction = new PageMenuItemAction(array(), 'create', array('data' => array(
+ 'isDisabled' => ($this->isDisabled) ? 1 : 0,
+ 'isLandingPage' => ($this->isLandingPage) ? 1 : 0,
+ 'menuItem' => $this->pageMenuItem,
+ 'menuItemLink' => $this->menuItemLink,
+ 'menuPosition' => $this->menuPosition,
+ 'newWindow' => ($this->newWindow) ? 1 : 0,
+ 'parentMenuItem' => $this->parentMenuItem,
+ 'showOrder' => $this->showOrder
+ )));
+ $this->objectAction->executeAction();
+
+ $returnValues = $this->objectAction->getReturnValues();
+ $menuItem = $returnValues['returnValues'];
+ $data = array();
+ if (!I18nHandler::getInstance()->isPlainValue('menuItemLink')) {
+ I18nHandler::getInstance()->save('menuItemLink', 'wcf.page.menuItemLink'.$menuItem->menuItemID, 'wcf.page');
+ $data['menuItemLink'] = 'wcf.page.menuItemLink'.$menuItem->menuItemID;
+ }
+
+ // save menu item
+ I18nHandler::getInstance()->save('pageMenuItem', 'wcf.page.menuItem'.$menuItem->menuItemID, 'wcf.page');
+ $data['menuItem'] = 'wcf.page.menuItem'.$menuItem->menuItemID;
+
+ // update i18n values
+ $menuItemEditor = new PageMenuItemEditor($menuItem);
+ $menuItemEditor->update($data);
+
+ // call saved event
+ $this->saved();
+
+ // show success
+ WCF::getTPL()->assign('success', true);
+
+ // reset variables
+ $this->isDisabled = $this->isLandingPage = $this->newWindow = false;
+ $this->menuPosition = 'header';
+ $this->menuItemLink = $this->pageMenuItem = $this->parentMenuItem = '';
+ $this->showOrder = 0;
+
+ // reload parent menu items
+ if ($menuItem->menuPosition == 'header' && $menuItem->parentMenuItem != '') {
+ $this->readAvailableParentMenuItems();
+ }
+ }
+
+ /**
+ * @see wcf\page\IPage::assignVariables()
+ */
+ public function assignVariables() {
+ parent::assignVariables();
+
+ I18nHandler::getInstance()->assignVariables();
+
+ WCF::getTPL()->assign(array(
+ 'action' => 'add',
+ 'availableParentMenuItems' => $this->availableParentMenuItems,
+ 'isDisabled' => $this->isDisabled,
+ 'isLandingPage' => $this->isLandingPage,
+ 'menuItemLink' => $this->menuItemLink,
+ 'menuPosition' => $this->menuPosition,
+ 'newWindow' => $this->newWindow,
+ 'pageMenuItem' => $this->pageMenuItem,
+ 'parentMenuItem' => $this->parentMenuItem,
+ 'showOrder' => $this->showOrder
+ ));
+ }
+}
--- /dev/null
+<?php
+namespace wcf\acp\form;
+use wcf\data\page\menu\item\PageMenuItem;
+use wcf\data\page\menu\item\PageMenuItemAction;
+use wcf\system\exception\IllegalLinkException;
+use wcf\system\language\I18nHandler;
+use wcf\system\WCF;
+
+/**
+ * Shows the page menu item edit form.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2012 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage acp.form
+ * @category Community Framework
+ */
+class PageMenuItemEditForm extends PageMenuItemAddForm {
+ /**
+ * @see wcf\acp\form\ACPForm::$activeMenuItem
+ */
+ public $activeMenuItem = 'wcf.acp.menu.link.pageMenu';
+
+ /**
+ * page menu item object
+ * @var wcf\data\page\menu\item\PageMenuItem
+ */
+ public $menuItem = null;
+
+ /**
+ * menu item id
+ * @var integer
+ */
+ public $menuItemID = 0;
+
+ /**
+ * @see wcf\page\IPage::readParameters()
+ */
+ public function readParameters() {
+ if (isset($_REQUEST['id'])) $this->menuItemID = intval($_REQUEST['id']);
+ $this->menuItem = new PageMenuItem($this->menuItemID);
+ if (!$this->menuItem->menuItemID) {
+ throw new IllegalLinkException();
+ }
+
+ parent::readParameters();
+ }
+
+ /**
+ * @see wcf\acp\form\PageMenuItemAddForm::initAvailableParentMenuItems()
+ */
+ protected function initAvailableParentMenuItems() {
+ parent::initAvailableParentMenuItems();
+
+ // remove current item as valid parent menu item
+ $this->availableParentMenuItems->getConditionBuilder()->add("page_menu_item.menuItem <> ?", array($this->menuItem->menuItem));
+ }
+
+ /**
+ * @see wcf\page\IPage::readData()
+ */
+ public function readData() {
+ parent::readData();
+
+ I18nHandler::getInstance()->setOptions('menuItemLink', PACKAGE_ID, $this->menuItem->menuItemLink, 'wcf.page.menuItemLink\d+');
+ I18nHandler::getInstance()->setOptions('pageMenuItem', PACKAGE_ID, $this->menuItem->menuItem, 'wcf.page.menuItem\d+');
+
+ if (empty($_POST)) {
+ $this->isDisabled = ($this->menuItem->isDisabled) ? true : false;
+ $this->isLandingPage = ($this->menuItem->isLandingPage) ? true : false;
+ $this->menuPosition = $this->menuItem->menuPosition;
+ $this->newWindow = ($this->menuItem->newWindow) ? true : false;
+ $this->pageMenuItem = $this->menuItem->menuItem;
+ $this->parentMenuItem = $this->menuItem->parentMenuItem;
+ $this->showOrder = $this->menuItem->showOrder;
+ }
+ }
+
+ /**
+ * @see wcf\form\IForm::save()
+ */
+ public function save() {
+ ACPForm::save();
+
+ // save menu item
+ I18nHandler::getInstance()->save('pageMenuItem', $this->menuItem->menuItem, 'wcf.page');
+
+ // save menu item link
+ $this->menuItemLink = 'wcf.page.menuItemLink'.$this->menuItem->menuItemID;
+ if (I18nHandler::getInstance()->isPlainValue('menuItemLink')) {
+ I18nHandler::getInstance()->remove($this->menuItemLink);
+ $this->menuItemLink= I18nHandler::getInstance()->getValue('menuItemLink');
+ }
+ else {
+ I18nHandler::getInstance()->save('menuItemLink', $this->menuItemLink, 'wcf.page');
+ }
+
+ // save menu item
+ $this->objectAction = new PageMenuItemAction(array($this->menuItem), 'update', array('data' => array(
+ 'isDisabled' => ($this->isDisabled) ? 1 : 0,
+ 'isLandingPage' => ($this->isLandingPage) ? 1 : 0,
+ 'menuItemLink' => $this->menuItemLink,
+ 'newWindow' => ($this->newWindow) ? 1 : 0,
+ 'parentMenuItem' => ($this->menuItem->menuPosition == 'header' ? $this->parentMenuItem : ''),
+ 'showOrder' => $this->showOrder
+ )));
+ $this->objectAction->executeAction();
+
+ $this->saved();
+
+ WCF::getTPL()->assign('success', true);
+ }
+
+ /**
+ * @see wcf\page\IPage::assignVariables()
+ */
+ public function assignVariables() {
+ parent::assignVariables();
+
+ I18nHandler::getInstance()->assignVariables(!empty($_POST));
+
+ WCF::getTPL()->assign(array(
+ 'action' => 'edit',
+ 'menuItem' => $this->menuItem,
+ 'menuItemID' => $this->menuItemID
+ ));
+ }
+}
--- /dev/null
+<?php
+namespace wcf\acp\page;
+use wcf\data\page\menu\item\PageMenuItemList;
+use wcf\data\page\menu\item\ViewablePageMenuItem;
+use wcf\page\AbstractPage;
+use wcf\system\menu\acp\ACPMenu;
+use wcf\system\package\PackageDependencyHandler;
+use wcf\system\WCF;
+
+/**
+ * Shows a list of page menu items.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2012 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage acp.page
+ * @category Community Framework
+ */
+class PageMenuItemListPage extends AbstractPage {
+ /**
+ * list of footer page menu items
+ * @var array<wcf\data\page\menu\item\PageMenuItem>
+ */
+ public $footerItems = array();
+
+ /**
+ * list of header page menu items
+ * @var array<wcf\data\page\menu\item\PageMenuItem>
+ */
+ public $headerItems = array();
+
+ /**
+ * @see wcf\page\AbstractPage::$neededPermissions
+ */
+ public $neededPermissions = array('admin.display.canManagePageMenu');
+
+ /**
+ * @see wcf\page\IPage::readData()
+ */
+ public function readData() {
+ parent::readData();
+
+ $menuItemList = new PageMenuItemList();
+ $menuItemList->getConditionBuilder()->add("page_menu_item.packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies()));
+ $menuItemList->sqlOrderBy = "page_menu_item.parentMenuItem ASC, page_menu_item.showOrder ASC";
+ $menuItemList->readObjects();
+
+ foreach ($menuItemList as $menuItem) {
+ if ($menuItem->menuPosition == 'footer') {
+ if ($menuItem->parentMenuItem) {
+ $this->footerItems[$menuItem->parentMenuItem]->addChild($menuItem);
+ }
+ else {
+ $this->footerItems[$menuItem->menuItem] = $menuItem;
+ }
+ }
+ else {
+ if ($menuItem->parentMenuItem) {
+ $this->headerItems[$menuItem->parentMenuItem]->addChild($menuItem);
+ }
+ else {
+ $this->headerItems[$menuItem->menuItem] = new ViewablePageMenuItem($menuItem);
+ }
+ }
+ }
+ }
+
+ /**
+ * @see wcf\page\IPage::assignVariables()
+ */
+ public function assignVariables() {
+ parent::assignVariables();
+
+ WCF::getTPL()->assign(array(
+ 'footerItems' => $this->footerItems,
+ 'headerItems' => $this->headerItems
+ ));
+ }
+
+ /**
+ * @see wcf\page\IPage::show()
+ */
+ public function show() {
+ // set active menu item.
+ ACPMenu::getInstance()->setActiveMenuItem('wcf.acp.menu.link.pageMenu.list');
+
+ parent::show();
+ }
+}
--- /dev/null
+<?php
+namespace wcf\data;
+
+/**
+ * Default interface for sortable database objects.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2012 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage data
+ * @category Community Framework
+ */
+interface ISortableAction {
+ /**
+ * Validates the 'updatePosition' action.
+ */
+ public function validateUpdatePosition();
+
+ /**
+ * Updates the position of given objects.
+ */
+ public function updatePosition();
+}
use wcf\system\menu\page\DefaultPageMenuItemProvider;
use wcf\system\menu\ITreeMenuItem;
use wcf\system\request\LinkHandler;
+use wcf\system\WCF;
/**
- * Represents an page menu item.
+ * Represents a page menu item.
*
* @author Alexander Ebert
* @copyright 2001-2012 WoltLab GmbH
$parameters['application'] = $abbreviation;
}
- return LinkHandler::getInstance()->getLink(null, $parameters, $this->menuItemLink);
+ return LinkHandler::getInstance()->getLink(null, $parameters, WCF::getLanguage()->get($this->menuItemLink));
+ }
+
+ /**
+ * Returns the menu item name.
+ *
+ * @return string
+ */
+ public function __toString() {
+ return WCF::getLanguage()->get($this->menuItem);
}
}
<?php
namespace wcf\data\page\menu\item;
use wcf\data\AbstractDatabaseObjectAction;
+use wcf\data\ISortableAction;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
+use wcf\system\exception\UserInputException;
+use wcf\system\WCF;
/**
* Executes page menu item-related actions.
* @subpackage data.page.menu.item
* @category Community Framework
*/
-class PageMenuItemAction extends AbstractDatabaseObjectAction {
+class PageMenuItemAction extends AbstractDatabaseObjectAction implements ISortableAction {
/**
* @see wcf\data\AbstractDatabaseObjectAction::$className
*/
protected $className = 'wcf\data\page\menu\item\PageMenuItemEditor';
+
+ /**
+ * list of menu items
+ * @var array<wcf\data\page\menu\item\PageMenuItem>
+ */
+ public $menuItems = array();
+
+ /**
+ * @see wcf\data\IDatabaseObjectAction::create()
+ */
+ public function create() {
+ if (!isset($this->parameters['data']['packageID'])) {
+ $this->parameters['data']['packageID'] = PACKAGE_ID;
+ }
+
+ $menuItem = parent::create();
+
+ if ($menuItem->isLandingPage) {
+ $menuItemEditor = new PageMenuItemEditor($menuItem);
+ $menuItemEditor->setAsLandingPage();
+ }
+
+ return $menuItem;
+ }
+
+ /**
+ * @see wcf\data\ISortableAction::validateUpdatePosition()
+ */
+ public function validateUpdatePosition() {
+ WCF::getSession()->checkPermissions(array('admin.display.canManagePageMenu'));
+
+ if (!isset($this->parameters['data']) || !isset($this->parameters['data']['structure']) || !is_array($this->parameters['data']['structure'])) {
+ throw new UserInputException('structure');
+ }
+
+ if (!isset($this->parameters['menuPosition']) || !in_array($this->parameters['menuPosition'], array('footer', 'header'))) {
+ throw new UserInputException('structure');
+ }
+
+ if ($this->parameters['menuPosition'] == 'footer') {
+ if (count($this->parameters['data']['structure']) > 1 || !isset($this->parameters['data']['structure'][0])) {
+ throw new UserInputException('structure');
+ }
+ }
+
+ $menuItemIDs = array();
+ foreach ($this->parameters['data']['structure'] as $menuItems) {
+ $menuItemIDs = array_merge($menuItemIDs, $menuItems);
+ }
+
+ $menuItemList = new PageMenuItemList();
+ $menuItemList->getConditionBuilder()->add("page_menu_item.menuItemID IN (?)", array($menuItemIDs));
+ $menuItemList->getConditionBuilder()->add("page_menu_item.menuPosition = ?", array($this->parameters['menuPosition']));
+ $menuItemList->sqlLimit = 0;
+ $menuItemList->readObjects();
+ $this->menuItems = $menuItemList->getObjects();
+
+ if (count($this->menuItems) != count($menuItemIDs)) {
+ throw new UserInputException('structure');
+ }
+
+ foreach ($this->parameters['data']['structure'] as $parentMenuItemID => $menuItems) {
+ if ($parentMenuItemID && !isset($this->menuItems[$parentMenuItemID])) {
+ throw new UserInputException('structure');
+ }
+ }
+ }
+
+ /**
+ * @see wcf\data\ISortableAction::updatePosition()
+ */
+ public function updatePosition() {
+ $sql = "UPDATE wcf".WCF_N."_page_menu_item
+ SET parentMenuItem = ?,
+ showOrder = ?
+ WHERE menuItemID = ?";
+ $statement = WCF::getDB()->prepareStatement($sql);
+
+ WCF::getDB()->beginTransaction();
+ foreach ($this->parameters['data']['structure'] as $parentMenuItemID => $menuItems) {
+ foreach ($menuItems as $showOrder => $menuItemID) {
+ $statement->execute(array(
+ ($parentMenuItemID ? $this->menuItems[$parentMenuItemID]->menuItem : ''),
+ $showOrder,
+ $menuItemID
+ ));
+ }
+ }
+ WCF::getDB()->commitTransaction();
+ }
}
use wcf\data\DatabaseObjectEditor;
use wcf\data\IEditableCachedObject;
use wcf\system\cache\CacheHandler;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
+use wcf\system\package\PackageDependencyHandler;
use wcf\system\WCF;
/**
* @see wcf\data\IEditableObject::delete()
*/
public function delete() {
+ $conditions = new PreparedStatementConditionBuilder();
+ $conditions->add("packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies()));
+ $conditions->add("showOrder >= ?", array($this->showOrder));
+ $conditions->add("menuPosition = ?", array($this->menuPosition));
+
// update show order
$sql = "UPDATE wcf".WCF_N."_page_menu_item
SET showOrder = showOrder - 1
- WHERE showOrder >= ?
- AND menuPosition = ?";
+ ".$conditions;
$statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute(array(
- $this->showOrder,
- $this->menuPosition
- ));
+ $statement->execute($conditions->getParameters());
parent::delete();
}
* @param integer $showOrder
*/
public static function setShowOrder($menuItemID, $menuPosition = 'header', $showOrder = 1) {
- // Update
+ $conditions = new PreparedStatementConditionBuilder();
+ $conditions->add("packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies()));
+ $conditions->add("menuItemID = ?", array($menuItemID));
+
+ // update show order
$sql = "UPDATE wcf".WCF_N."_page_menu_item
SET showOrder = ?,
menuPosition = ?
- WHERE menuItemID = ?";
+ ".$conditions;
$statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute(array(
+
+ $parameters = array_merge(array(
$showOrder,
- $menuPosition,
- $menuItemID
- ));
+ $menuPosition
+ ), $conditions->getParameters());
+ $statement->execute($parameters);
+ }
+
+ /**
+ * Sets current page menu item as landing page.
+ */
+ public function setAsLandingPage() {
+ $conditions = new PreparedStatementConditionBuilder();
+ $conditions->add("packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies()));
+
+ $sql = "UPDATE wcf".WCF_N."_page_menu_item
+ SET isLandingPage = 0
+ ".$conditions;
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute($conditions->getParameters());
+
+ $this->update(array('isLandingPage' => 1));
}
/**
protected function updateShowOrder($showOrder, $menuPosition) {
if ($menuPosition == $this->menuPosition) {
if ($this->showOrder != $showOrder) {
+ $conditions = new PreparedStatementConditionBuilder();
+ $conditions->add("packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies()));
+ $conditions->add("showOrder <= ?", array($showOrder));
+ $conditions->add("showOrder > ?", array($this->showOrder));
+ $conditions->add("menuPosition = ?", array($menuPosition));
+
if ($showOrder < $this->showOrder) {
$sql = "UPDATE wcf".WCF_N."_page_menu_item
SET showOrder = showOrder + 1
- WHERE showOrder >= ?
- AND showOrder < ?
- AND menuPosition = ?";
+ ".$conditions;
$statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute(array(
- $showOrder,
- $this->showOrder,
- $menuPosition
- ));
+ $statement->execute($conditions->getParameters());
}
else if ($showOrder > $this->showOrder) {
$sql = "UPDATE wcf".WCF_N."_page_menu_item
AND showOrder > ?
AND menuPosition = ?";
$statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute(array(
- $showOrder,
- $this->showOrder,
- $menuPosition
- ));
+ $statement->execute($conditions->getParameters());
}
}
}
else {
+ $conditions = new PreparedStatementConditionBuilder();
+ $conditions->add("packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies()));
+ $conditions->add("showOrder >= ?", array($this->showOrder));
+ $conditions->add("menuPosition = ?", array($this->menuPosition));
+
$sql = "UPDATE wcf".WCF_N."_page_menu_item
SET showOrder = showOrder - 1
- WHERE showOrder >= ?
- AND menuPosition = ?";
+ ".$conditions;
$statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute(array(
- $this->showOrder,
- $this->menuPosition
- ));
-
+ $statement->execute($conditions->getParameters());
+
+ $conditions = new PreparedStatementConditionBuilder();
+ $conditions->add("packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies()));
+ $conditions->add("showOrder >= ?", array($showOrder));
+ $conditions->add("menuPosition = ?", array($menuPosition));
+
$sql = "UPDATE wcf".WCF_N."_page_menu_item
SET showOrder = showOrder + 1
- WHERE showOrder >= ?
- AND menuPosition = ?";
+ ".$conditions;
$statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute(array(
- $showOrder,
- $menuPosition
- ));
+ $statement->execute($conditions->getParameters());
}
}
*/
protected static function getShowOrder($showOrder, $menuPosition) {
if ($showOrder == 0) {
+ $conditions = new PreparedStatementConditionBuilder();
+ $conditions->add("packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies()));
+ $conditions->add("menuPosition = ?", array($menuPosition));
+
// get next number in row
$sql = "SELECT MAX(showOrder) AS showOrder
FROM wcf".WCF_N."_page_menu_item
- WHERE menuPosition = ?";
+ ".$conditions;
$statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute(array($menuPosition));
+ $statement->execute($conditions->getParameters());
$row = $statement->fetchArray();
if (!empty($row)) $showOrder = intval($row['showOrder']) + 1;
else $showOrder = 1;
}
else {
+ $conditions = new PreparedStatementConditionBuilder();
+ $conditions->add("packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies()));
+ $conditions->add("showOrder >= ?", array($showOrder));
+ $conditions->add("menuPosition = ?", array($menuPosition));
+
$sql = "UPDATE wcf".WCF_N."_page_menu_item
SET showOrder = showOrder + 1
- WHERE showOrder >= ?
- AND menuPosition = ?";
+ ".$conditions;
$statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute(array(
- $showOrder,
- $menuPosition
- ));
+ $statement->execute($conditions->getParameters());
}
return $showOrder;
--- /dev/null
+<?php
+namespace wcf\data\page\menu\item;
+use wcf\data\DatabaseObjectDecorator;
+
+/**
+ * Provides a viewable page menu item with children support.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2012 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage data.page.menu.item
+ * @category Community Framework
+ */
+class ViewablePageMenuItem extends DatabaseObjectDecorator implements \Countable, \Iterator {
+ /**
+ * @see wcf\data\DatabaseObjectDecorator::$baseClass
+ */
+ protected static $baseClass = 'wcf\data\page\menu\item\PageMenuItem';
+
+ /**
+ * current iterator index
+ * @var integer
+ */
+ protected $index = 0;
+
+ /**
+ * list of page menu items
+ * @var array<wcf\data\page\menu\item\PageMenuItem>
+ */
+ protected $objects = array();
+
+ /**
+ * Adds a page menu item to collection.
+ *
+ * @param wcf\data\page\menu\item\PageMenuItem $menuItem
+ */
+ public function addChild(PageMenuItem $menuItem) {
+ if ($menuItem->parentMenuItem == $this->menuItem) {
+ $this->objects[] = $menuItem;
+ }
+ }
+
+ /**
+ * @see \Countable::count()
+ */
+ public function count() {
+ return count($this->objects);
+ }
+
+ /**
+ * @see \Iterator::current()
+ */
+ public function current() {
+ return $this->objects[$this->index];
+ }
+
+ /**
+ * @see \Iterator::key()
+ */
+ public function key() {
+ return $this->index;
+ }
+
+ /**
+ * @see \Iterator::next()
+ */
+ public function next() {
+ ++$this->index;
+ }
+
+ /**
+ * @see \Iterator::rewind()
+ */
+ public function rewind() {
+ $this->index = 0;
+ }
+
+ /**
+ * @see \Iterator::valid()
+ */
+ public function valid() {
+ return isset($this->objects[$this->index]);
+ }
+}
use wcf\system\database\util\PreparedStatementConditionBuilder;
use wcf\system\exception\SystemException;
use wcf\system\language\LanguageFactory;
+use wcf\system\package\PackageDependencyHandler;
+use wcf\system\Regex;
use wcf\system\SingletonFactory;
use wcf\system\WCF;
use wcf\util\StringUtil;
*/
protected $elementOptions = array();
+ /**
+ * language variable regex object
+ * @var wcf\system\Regex
+ */
+ protected $regex = null;
+
/**
* @see wcf\system\SingletonFactory::init()
*/
}
/**
- * Saves language variable for i18n. Given package id must match the associated
- * packages, using PACKAGE_ID is highly discouraged as this breaks the ability
- * to delete unused language items on package uninstallation using foreign keys.
+ * Saves language variable for i18n.
*
* @param string $elementID
* @param string $languageVariable
* @param string $languageCategory
* @param integer $packageID
*/
- public function save($elementID, $languageVariable, $languageCategory, $packageID) {
+ public function save($elementID, $languageVariable, $languageCategory, $packageID = PACKAGE_ID) {
// get language category id
$sql = "SELECT languageCategoryID
FROM wcf".WCF_N."_language_category
$conditions = new PreparedStatementConditionBuilder();
$conditions->add("languageID IN (?)", array($languageIDs));
$conditions->add("languageItem = ?", array($languageVariable));
- $conditions->add("packageID = ?", array($packageID));
+
+ if (isset($this->elementOptions[$elementID]) && !Regex::compile('^'.$this->elementOptions[$elementID]['pattern'].'$')->match($languageVariable) && $this->isLanguageVariable($languageVariable)) {
+ $conditions->add("packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies()));
+ }
+ else {
+ $conditions->add("packageID = ?", array($packageID));
+ }
$sql = "SELECT languageItemID, languageID
FROM wcf".WCF_N."_language_item
* @param string $languageVariable
* @param integer $packageID
*/
- public function remove($languageVariable, $packageID) {
+ public function remove($languageVariable, $packageID = PACKAGE_ID) {
$sql = "DELETE FROM wcf".WCF_N."_language_item
WHERE languageItem = ?
AND packageID = ?";
}
}
else {
- if (preg_match('~^'.$this->elementOptions[$elementID]['pattern'].'$~', $this->elementOptions[$elementID]['value'])) {
+ $isI18n = Regex::compile('^'.$this->elementOptions[$elementID]['pattern'].'$')->match($this->elementOptions[$elementID]['value']);
+ if (!$isI18n) {
+ // check if it's a regular language variable
+ $isI18n = Regex::compile('^([a-zA-Z0-9-_]+\.)+[a-zA-Z0-9-_]+$')->match($this->elementOptions[$elementID]['value']);
+ }
+
+ if ($isI18n) {
// use i18n values from language items
$sql = "SELECT languageID, languageItemValue
FROM wcf".WCF_N."_language_item
public function enableAssignValueVariables() {
$this->assignValueVariablesDisabled = false;
}
+
+ /**
+ * Returns true, if given string equals a language variable.
+ *
+ * @param string $string
+ * @return boolean
+ */
+ protected function isLanguageVariable($string) {
+ if ($this->regex === null) {
+ $this->regex = new Regex('^([a-zA-Z0-9-_]+\.)+[a-zA-Z0-9-_]+$');
+ }
+
+ return $this->regex->match($string);
+ }
}
isDisabled TINYINT(1) NOT NULL DEFAULT 0,
className VARCHAR(255) NOT NULL DEFAULT '',
isLandingPage TINYINT(1) NOT NULL DEFAULT 0,
+ newWindow TINYINT(1) NOT NULL DEFAULT 0,
UNIQUE KEY (packageID, menuItem)
);