From 045f075b2f3f0cbd380373ad7bcf1e3fb2f0f386 Mon Sep 17 00:00:00 2001 From: Matthias Schmidt Date: Wed, 18 Jul 2012 21:36:07 +0200 Subject: [PATCH] Removes ACL-related stuff --- .../template/categoryOptionList.tpl | 5 + .../template/categorySelectList.tpl | 3 - .../files/acp/templates/categoryAdd.tpl | 160 --------- .../files/acp/templates/categoryList.tpl | 119 ------- .../acp/templates/categoryOptionList.tpl | 5 + .../acp/templates/categorySelectList.tpl | 3 - .../form/AbstractCategoryAddForm.class.php | 323 ------------------ .../form/AbstractCategoryEditForm.class.php | 168 --------- .../page/AbstractCategoryListPage.class.php | 162 --------- .../lib/data/category/Category.class.php | 6 +- .../data/category/CategoryAction.class.php | 8 +- .../data/category/CategoryEditor.class.php | 44 +-- .../lib/data/category/CategoryNode.class.php | 10 +- .../data/category/CategoryNodeList.class.php | 15 +- .../builder/CategoryCacheBuilder.class.php | 26 +- .../category/AbstractCategoryType.class.php | 54 ++- .../system/category/CategoryHandler.class.php | 74 ++-- .../system/category/ICategoryType.class.php | 27 +- wcfsetup/setup/db/install.sql | 4 +- 19 files changed, 136 insertions(+), 1080 deletions(-) create mode 100644 com.woltlab.wcf/template/categoryOptionList.tpl delete mode 100644 com.woltlab.wcf/template/categorySelectList.tpl delete mode 100644 wcfsetup/install/files/acp/templates/categoryAdd.tpl delete mode 100644 wcfsetup/install/files/acp/templates/categoryList.tpl create mode 100644 wcfsetup/install/files/acp/templates/categoryOptionList.tpl delete mode 100644 wcfsetup/install/files/acp/templates/categorySelectList.tpl delete mode 100644 wcfsetup/install/files/lib/acp/form/AbstractCategoryAddForm.class.php delete mode 100644 wcfsetup/install/files/lib/acp/form/AbstractCategoryEditForm.class.php delete mode 100644 wcfsetup/install/files/lib/acp/page/AbstractCategoryListPage.class.php diff --git a/com.woltlab.wcf/template/categoryOptionList.tpl b/com.woltlab.wcf/template/categoryOptionList.tpl new file mode 100644 index 0000000000..0d78102102 --- /dev/null +++ b/com.woltlab.wcf/template/categoryOptionList.tpl @@ -0,0 +1,5 @@ +{foreach from=$categoryNodeList item=category} + {if !$maximumNestingLevel|isset || $maximumNestingLevel == -2 || $categoryNodeList->getDepth() <= $maximumNestingLevel} + + {/if} +{/foreach} \ No newline at end of file diff --git a/com.woltlab.wcf/template/categorySelectList.tpl b/com.woltlab.wcf/template/categorySelectList.tpl deleted file mode 100644 index db6f59a7d7..0000000000 --- a/com.woltlab.wcf/template/categorySelectList.tpl +++ /dev/null @@ -1,3 +0,0 @@ -{foreach from=$categoryNodeList item=category} - -{/foreach} \ No newline at end of file diff --git a/wcfsetup/install/files/acp/templates/categoryAdd.tpl b/wcfsetup/install/files/acp/templates/categoryAdd.tpl deleted file mode 100644 index 1c6a104259..0000000000 --- a/wcfsetup/install/files/acp/templates/categoryAdd.tpl +++ /dev/null @@ -1,160 +0,0 @@ -{include file='header'} - -{if $aclObjectTypeID} - {include file='aclPermissions'} -{/if} - - -{include file='multipleLanguageInputJavascript' elementIdentifier='title'} -{if $objectType->getProcessor()->supportsDescriptions()} - {include file='multipleLanguageInputJavascript' elementIdentifier='description'} -{/if} - -
-
-

{@$objectType->getProcessor()->getLanguageVariable($action)}

-
-
- -{if $errorField} -

{lang}wcf.global.form.error{/lang}

-{/if} - -{if $success|isset} -

{lang}wcf.global.form.{@$action}.success{/lang}

-{/if} - -{hascontent} -
- -
-{/hascontent} - -
-
-
- {lang}wcf.global.form.data{/lang} - - {if $categoryNodeList|count} - -
-
- - {if $errorField == 'parentCategoryID'} - - {assign var=__languageVariable value='parentCategoryID.error.'|concat:$errorType} - {@$objectType->getProcessor()->getLanguageVariable($__languageVariable)} - - {/if} - {hascontent}{content}{@$objectType->getProcessor()->getLanguageVariable('parentCategoryID.description', true)}{/content}{/hascontent} -
- - {/if} - - -
-
- - {if $errorField == 'title'} - - {if $errorType == 'empty'} - {lang}wcf.global.form.error.empty{/lang} - {else} - {assign var=__languageVariable value='title.error.'|concat:$errorType} - {@$objectType->getProcessor()->getLanguageVariable($__languageVariable)} - {/if} - - {/if} - {hascontent}{content}{@$objectType->getProcessor()->getLanguageVariable('title.description', true)}{/content}{/hascontent} -
- - - {if $objectType->getProcessor()->supportsDescriptions()} - -
-
- - {if $errorField == 'description'} - - {if $errorType == 'empty'} - {lang}wcf.global.form.error.empty{/lang} - {else} - {assign var=__languageVariable value='description.error.'|concat:$errorType} - {@$objectType->getProcessor()->getLanguageVariable($__languageVariable)} - {/if} - - {/if} - {hascontent}{content}{@$objectType->getProcessor()->getLanguageVariable('description.description', true)}{/content}{/hascontent} -
- - {/if} - - -
-
- - {hascontent}{content}{@$objectType->getProcessor()->getLanguageVariable('isDisabled.description', true)}{/content}{/hascontent} -
- - - -
-
- - {if $errorField == 'showOrder'} - - {assign var=__languageVariable value='showOrder.error.'|concat:$errorType} - {@$objectType->getProcessor()->getLanguageVariable($__languageVariable)} - - {/if} - {hascontent}{content}{@$objectType->getProcessor()->getLanguageVariable('showOrder.description', true)}{/content}{/hascontent} -
- - - {event name='dataFields'} -
- - {if $aclObjectTypeID} -
- {lang}wcf.acp.acl.permissions{/lang} - -
-
{lang}wcf.acp.acl.permissions{/lang}
-
-
- - {event name='permissionFields'} -
- {/if} - - {event name='fieldsets'} -
- -
- - -
-
- -{include file='footer'} \ No newline at end of file diff --git a/wcfsetup/install/files/acp/templates/categoryList.tpl b/wcfsetup/install/files/acp/templates/categoryList.tpl deleted file mode 100644 index 6bd63e2dfb..0000000000 --- a/wcfsetup/install/files/acp/templates/categoryList.tpl +++ /dev/null @@ -1,119 +0,0 @@ -{include file='header'} - -{if $categoryNodeList|count} - -{/if} - -
-
-

{@$objectType->getProcessor()->getLanguageVariable('list')}

-
-
- -{hascontent} -
- -
-{/hascontent} - -{if $categoryNodeList|count} -
-
    - {assign var=oldDepth value=0} - {foreach from=$categoryNodeList item=category} - {section name=i loop=$oldDepth-$categoryNodeList->getDepth()}
{/section} - -
  • - - - {if $objectType->getProcessor()->canEditCategory()} - - {else} - - {/if} - - {if $objectType->getProcessor()->canDeleteCategory()} - - {else} - - {/if} - - {if $objectType->getProcessor()->canEditCategory()} - - {else} - - {/if} - - {event name='buttons'} - - - - {$category->getTitle()} - - - -
      - {if !$categoryNodeList->current()->hasChildren()} -
  • - {/if} - {assign var=oldDepth value=$categoryNodeList->getDepth()} - {/foreach} - {section name=i loop=$oldDepth}{/section} - - - {if $objectType->getProcessor()->canEditCategory() && $categoryNodeList|count > 1} -
    - -
    - {/if} -
    - - {hascontent} -
    - -
    - {/hascontent} -{else} -

    {@$objectType->getProcessor()->getLanguageVariable('noneAvailable')}

    -{/if} - -{include file='footer'} \ No newline at end of file diff --git a/wcfsetup/install/files/acp/templates/categoryOptionList.tpl b/wcfsetup/install/files/acp/templates/categoryOptionList.tpl new file mode 100644 index 0000000000..2e47acffa8 --- /dev/null +++ b/wcfsetup/install/files/acp/templates/categoryOptionList.tpl @@ -0,0 +1,5 @@ +{foreach from=$categoryNodeList item=category} + {if !$maximumNestingLevel|isset || $maximumNestingLevel == -2 || $categoryNodeList->getDepth() <= $maximumNestingLevel} + + {/if} +{/foreach} \ No newline at end of file diff --git a/wcfsetup/install/files/acp/templates/categorySelectList.tpl b/wcfsetup/install/files/acp/templates/categorySelectList.tpl deleted file mode 100644 index db6f59a7d7..0000000000 --- a/wcfsetup/install/files/acp/templates/categorySelectList.tpl +++ /dev/null @@ -1,3 +0,0 @@ -{foreach from=$categoryNodeList item=category} - -{/foreach} \ No newline at end of file diff --git a/wcfsetup/install/files/lib/acp/form/AbstractCategoryAddForm.class.php b/wcfsetup/install/files/lib/acp/form/AbstractCategoryAddForm.class.php deleted file mode 100644 index a30ad81ef2..0000000000 --- a/wcfsetup/install/files/lib/acp/form/AbstractCategoryAddForm.class.php +++ /dev/null @@ -1,323 +0,0 @@ - - * @package com.woltlab.wcf - * @subpackage acp.form - * @category Community Framework - */ -abstract class AbstractCategoryAddForm extends ACPForm { - /** - * id of the category acl object type - * @var integer - */ - public $aclObjectTypeID = 0; - - /** - * name of the controller used to add new categories - * @var string - */ - public $addController = ''; - - /** - * additional category data - * @var array - */ - public $additionalData = array(); - - /** - * list with the category nodes - * @var wcf\data\category\CategoryNodeList - */ - public $categoryNodeList = null; - - /** - * description of the category - * @var string - */ - public $description = ''; - - /** - * indicates if the category is disabled - * @var integer - */ - public $isDisabled = 0; - - /** - * name of the controller used to edit categories - * @var string - */ - public $editController = ''; - - /** - * name of the controller used to list the categories - * @var string - */ - public $listController = ''; - - /** - * category object type object - * @var wcf\data\object\type\ObjectType - */ - public $objectType = null; - - /** - * name of the category object type - * @var string - */ - public $objectTypeName = ''; - - /** - * id of the package the created package belongs to - * @var integer - */ - public $packageID = 0; - - /** - * id of the parent category id - * @var integer - */ - public $parentCategoryID = 0; - - /** - * category show order - * @var integer - */ - public $showOrder = 0; - - /** - * @see wcf\page\AbstractPage::$templateName - */ - public $templateName = 'categoryAdd'; - - /** - * title of the category - * @var string - */ - public $title = ''; - - /** - * @see wcf\page\AbstractPage::__run() - */ - public function __run() { - $classNameParts = explode('\\', get_called_class()); - $className = array_pop($classNameParts); - - // autoset controllers - if (empty($this->addController)) { - $this->addController = StringUtil::replace(array('AddForm', 'EditForm'), 'Add', $className); - } - if (empty($this->editController)) { - $this->editController = StringUtil::replace(array('AddForm', 'EditForm'), 'Edit', $className); - } - if (empty($this->listController)) { - $this->listController = StringUtil::replace(array('AddForm', 'EditForm'), 'List', $className); - } - - parent::__run(); - } - - /** - * @see wcf\page\IPage::assignVariables() - */ - public function assignVariables() { - parent::assignVariables(); - - I18nHandler::getInstance()->assignVariables(); - - WCF::getTPL()->assign(array( - 'aclObjectTypeID' => $this->aclObjectTypeID, - 'action' => 'add', - 'addController' => $this->addController, - 'categoryNodeList' => $this->categoryNodeList, - 'description' => $this->description, - 'editController' => $this->editController, - 'isDisabled' => $this->isDisabled, - 'listController' => $this->listController, - 'objectType' => $this->objectType, - 'parentCategoryID' => $this->parentCategoryID, - 'showOrder' => $this->showOrder, - 'title' => $this->title - )); - } - - /** - * Reads the categories. - */ - protected function readCategories() { - $this->categoryNodeList = new CategoryNodeList($this->objectType->objectTypeID, 0, true); - } - - /** - * Checks if the active user has the needed permissions to add a new category. - */ - protected function checkCategoryPermissions() { - if (!$this->objectType->getProcessor()->canAddCategory()) { - throw new PermissionDeniedException(); - } - } - - /** - * @see wcf\page\IPage::readData() - */ - public function readData() { - $this->objectType = CategoryHandler::getInstance()->getObjectTypeByName($this->objectTypeName); - if ($this->objectType === null) { - throw new SystemException("Unknown category object type with name '".$this->objectTypeName."'"); - } - - // check permissions - $this->checkCategoryPermissions(); - - // get acl object type id - if ($this->objectType->getProcessor()->getACLObjectTypeName()) { - $this->aclObjectTypeID = ACLHandler::getInstance()->getObjectTypeID($this->objectType->getProcessor()->getACLObjectTypeName()); - } - - // autoset package id - if (!$this->packageID) { - $this->packageID = $this->objectType->packageID; - } - - if ($this->objectType->getProcessor()->supportsDescriptions()) { - I18nHandler::getInstance()->register('description'); - } - I18nHandler::getInstance()->register('title'); - - parent::readData(); - - $this->readCategories(); - } - - /** - * @see wcf\page\IForm::readFormParameters() - */ - public function readFormParameters() { - parent::readFormParameters(); - - I18nHandler::getInstance()->readValues(); - - if (isset($_POST['additionalData'])) { - $this->additionalData = ArrayUtil::trim($_POST['additionalData']); - } - if ($this->objectType->getProcessor()->supportsDescriptions() && isset($_POST['description'])) { - $this->description = StringUtil::trim($_POST['description']); - } - if (isset($_POST['isDisabled'])) { - $this->isDisabled = 1; - } - if (isset($_POST['parentCategoryID'])) { - $this->parentCategoryID = intval($_POST['parentCategoryID']); - } - if (isset($_POST['showOrder'])) { - $this->showOrder = intval($_POST['showOrder']); - } - if (isset($_POST['title'])) { - $this->title = StringUtil::trim($_POST['title']); - } - } - - /** - * @see wcf\page\IForm::save() - */ - public function save() { - parent::save(); - - $this->objectAction = new CategoryAction(array(), 'create', array( - 'data' => array( - 'additionalData' => serialize($this->additionalData), - 'description' => $this->description, - 'isDisabled' => $this->isDisabled, - 'objectTypeID' => $this->objectType->objectTypeID, - 'parentCategoryID' => $this->parentCategoryID, - 'showOrder' => $this->showOrder, - 'title' => $this->title - ) - )); - $this->objectAction->executeAction(); - $returnValues = $this->objectAction->getReturnValues(); - - if (($this->objectType->getProcessor()->supportsDescriptions() && !I18nHandler::getInstance()->isPlainValue('description')) || !I18nHandler::getInstance()->isPlainValue('title')) { - $categoryID = $returnValues['returnValues']->categoryID; - - $updateData = array(); - if ($this->objectType->getProcessor()->supportsDescriptions() && !I18nHandler::getInstance()->isPlainValue('description')) { - $updateData['description'] = $this->objectType->getProcessor()->getI18nLangVarPrefix().'.description.category'.$categoryID; - I18nHandler::getInstance()->save('description', $updateData['description'], $this->objectType->getProcessor()->getDescriptionLangVarCategory(), $this->packageID); - } - if (!I18nHandler::getInstance()->isPlainValue('title')) { - $updateData['title'] = $this->objectType->getProcessor()->getI18nLangVarPrefix().'.title.category'.$categoryID; - I18nHandler::getInstance()->save('title', $updateData['title'], $this->objectType->getProcessor()->getTitleLangVarCategory(), $this->packageID); - } - - // update description/title - $editor = new CategoryEditor($returnValues['returnValues']); - $editor->update($updateData); - } - - // save acl - if ($this->aclObjectTypeID) { - ACLHandler::getInstance()->save($returnValues['returnValues']->categoryID, $this->aclObjectTypeID); - } - - // reload cache - CategoryHandler::getInstance()->reloadCache(); - - // reset values - $this->parentCategoryID = 0; - $this->showOrder = 0; - - $this->saved(); - - // disable assignment of i18n values - I18nHandler::getInstance()->disableAssignValueVariables(); - - // show success message - WCF::getTPL()->assign('success', true); - } - - /** - * @see wcf\page\IForm::validate() - */ - public function validate() { - parent::validate(); - - $this->validateParentCategory(); - - if (!I18nHandler::getInstance()->validateValue('title')) { - throw new UserInputException('title'); - } - - if ($this->objectType->getProcessor()->supportsDescriptions() && !I18nHandler::getInstance()->validateValue('description')) { - throw new UserInputException('description'); - } - } - - /** - * Validates the parent category. - */ - protected function validateParentCategory() { - if ($this->parentCategoryID) { - if (CategoryHandler::getInstance()->getCategory($this->objectType->objectTypeID, $this->parentCategoryID) === null) { - throw new UserInputException('parentCategoryID', 'invalid'); - } - } - } -} diff --git a/wcfsetup/install/files/lib/acp/form/AbstractCategoryEditForm.class.php b/wcfsetup/install/files/lib/acp/form/AbstractCategoryEditForm.class.php deleted file mode 100644 index 9f89e4e099..0000000000 --- a/wcfsetup/install/files/lib/acp/form/AbstractCategoryEditForm.class.php +++ /dev/null @@ -1,168 +0,0 @@ - - * @package com.woltlab.wcf - * @subpackage acp.form - * @category Community Framework - */ -class AbstractCategoryEditForm extends AbstractCategoryAddForm { - /** - * edited category - * @var wcf\data\category\Category - */ - public $category = null; - - /** - * id of the edited category - * @var integer - */ - public $categoryID = 0; - - /** - * @see wcf\page\IPage::assignVariables() - */ - public function assignVariables() { - parent::assignVariables(); - - I18nHandler::getInstance()->assignVariables(!empty($_POST)); - - WCF::getTPL()->assign(array( - 'action' => 'edit', - 'category' => $this->category - )); - } - - /** - * @see wcf\acp\form\AbstractCategoryAddForm::checkCategoryPermissions() - */ - protected function checkCategoryPermissions() { - if (!$this->objectType->getProcessor()->canEditCategory()) { - throw new PermissionDeniedException(); - } - } - - /** - * @see wcf\acp\form\AbstractCategoryAddForm::readCategories() - */ - protected function readCategories() { - $this->categoryNodeList = new CategoryNodeList($this->objectType->objectTypeID, 0, true, array($this->category->objectTypeCategoryID)); - } - - /** - * @see wcf\page\IPage::readParameters() - */ - public function readParameters() { - parent::readParameters(); - - if (isset($_REQUEST['id'])) { - $this->categoryID = intval($_REQUEST['id']); - } - $this->category = new Category($this->categoryID); - if (!$this->category->categoryID) { - throw new IllegalLinkException(); - } - } - - /** - * @see wcf\page\IPage::readData() - */ - public function readData() { - parent::readData(); - - if (empty($_POST)) { - if ($this->objectType->getProcessor()->supportsDescriptions()) { - I18nHandler::getInstance()->setOptions('description', $this->packageID, $this->category->description, $this->objectType->getProcessor()->getI18nLangVarPrefix().'.description.category\d+'); - } - I18nHandler::getInstance()->setOptions('title', $this->packageID, $this->category->title, $this->objectType->getProcessor()->getI18nLangVarPrefix().'.title.category\d+'); - - $this->additionalData = $this->category->additionalData; - $this->isDisabled = $this->category->isDisabled; - $this->parentCategoryID = $this->category->parentCategoryID; - $this->showOrder = $this->category->showOrder; - } - } - - /** - * @see wcf\form\IForm::save() - */ - public function save() { - ACPForm::save(); - - // handle description - if ($this->objectType->getProcessor()->supportsDescriptions()) { - $this->description = $this->objectType->getProcessor()->getI18nLangVarPrefix().'.description.category'.$this->category->categoryID; - if (I18nHandler::getInstance()->isPlainValue('description')) { - I18nHandler::getInstance()->remove($this->description, $this->packageID); - $this->description = I18nHandler::getInstance()->getValue('description'); - } - else { - I18nHandler::getInstance()->save('description', $this->description, $this->objectType->getProcessor()->getDescriptionLangVarCategory(), $this->packageID); - } - } - - // handle title - $this->title = $this->objectType->getProcessor()->getI18nLangVarPrefix().'.title.category'.$this->category->categoryID; - if (I18nHandler::getInstance()->isPlainValue('title')) { - I18nHandler::getInstance()->remove($this->title, $this->packageID); - $this->title = I18nHandler::getInstance()->getValue('title'); - } - else { - I18nHandler::getInstance()->save('title', $this->title, $this->objectType->getProcessor()->getTitleLangVarCategory(), $this->packageID); - } - - // update category - $this->objectAction = new CategoryAction(array($this->category), 'update', array( - 'data' => array( - 'additionalData' => serialize($this->additionalData), - 'description' => $this->description, - 'isDisabled' => $this->isDisabled, - 'parentCategoryID' => $this->parentCategoryID, - 'showOrder' => $this->showOrder, - 'title' => $this->title - ) - )); - $this->objectAction->executeAction(); - - // update acl - if ($this->aclObjectTypeID) { - ACLHandler::getInstance()->save($this->category->categoryID, $this->aclObjectTypeID); - } - - // reload cache - CategoryHandler::getInstance()->reloadCache(); - - $this->saved(); - - // show success message - WCF::getTPL()->assign('success', true); - } - - /** - * @see wcf\acp\form\AbstractCategoryAddForm::validateParentCategory() - */ - protected function validateParentCategory() { - parent::validateParentCategory(); - - // check if new parent category is no child category of the category - $childCategories = CategoryHandler::getInstance()->getChildCategories($this->category); - if (isset($childCategories[$this->parentCategoryID])) { - throw new UserInputException('parentCategoryID', 'invalid'); - } - } -} diff --git a/wcfsetup/install/files/lib/acp/page/AbstractCategoryListPage.class.php b/wcfsetup/install/files/lib/acp/page/AbstractCategoryListPage.class.php deleted file mode 100644 index c1f11b1ee0..0000000000 --- a/wcfsetup/install/files/lib/acp/page/AbstractCategoryListPage.class.php +++ /dev/null @@ -1,162 +0,0 @@ - - * @package com.woltlab.wcf - * @subpackage acp.page - * @category Community Framework - */ -abstract class AbstractCategoryListPage extends AbstractPage { - /** - * active acp menu item - * @var string - */ - public $activeMenuItem = ''; - - /** - * name of the controller used to add new categories - * @var string - */ - public $addController = ''; - - /** - * category node list - * @var wcf\data\category\CategoryNodeList - */ - public $categoryNodeList = null; - - /** - * ids of collapsed categories - * @var array - */ - public $collapsedCategoryIDs = null; - - /** - * id of the collapsible category object type - * @var integer - */ - public $collapsibleObjectTypeID = 0; - - /** - * name of the controller used to edit categories - * @var string - */ - public $editController = ''; - - /** - * category object type object - * @var wcf\data\object\type\ObjectType - */ - public $objectType = null; - - /** - * name of the category object type - * @var string - */ - public $objectTypeName = ''; - - /** - * @see wcf\page\AbstractPage::$templateName - */ - public $templateName = 'categoryList'; - - /** - * @see wcf\page\AbstractPage::__run() - */ - public function __run() { - $classNameParts = explode('\\', get_called_class()); - $className = array_pop($classNameParts); - - // autoset controllers - if (empty($this->addController)) { - $this->addController = StringUtil::replace('ListPage', 'Add', $className); - } - if (empty($this->editController)) { - $this->editController = StringUtil::replace('ListPage', 'Edit', $className); - } - - parent::__run(); - } - - /** - * @see wcf\page\IPage::assignVariables() - */ - public function assignVariables() { - parent::assignVariables(); - - WCF::getTPL()->assign(array( - 'addController' => $this->addController, - 'categoryNodeList' => $this->categoryNodeList, - 'collapsedCategoryIDs' => $this->collapsedCategoryIDs, - 'collapsibleObjectTypeID' => $this->collapsibleObjectTypeID, - 'editController' => $this->editController, - 'objectType' => $this->objectType - )); - } - - /** - * Checks if the active user has the needed permissions to view this list. - */ - protected function checkCategoryPermissions() { - if (!$this->objectType->getProcessor()->canDeleteCategory() && !$this->objectType->getProcessor()->canEditCategory()) { - throw new PermissionDeniedException(); - } - } - - /** - * Reads the categories. - */ - protected function readCategories() { - $this->categoryNodeList = new CategoryNodeList($this->objectType->objectTypeID, 0, true); - } - - /** - * @see wcf\page\IPage::readData() - */ - public function readData() { - $this->objectType = CategoryHandler::getInstance()->getObjectTypeByName($this->objectTypeName); - if ($this->objectType === null) { - throw new SystemException("Unknown category object type with name '".$this->objectTypeName."'"); - } - - // check permissions - $this->checkCategoryPermissions(); - - $this->readCategories(); - - // get ids of collapsed category - $this->collapsibleObjectTypeID = UserCollapsibleContentHandler::getInstance()->getObjectTypeID($this->objectType->getProcessor()->getCollapsibleObjectTypeName()); - if ($this->collapsibleObjectTypeID !== null) { - $this->collapsedCategoryIDs = UserCollapsibleContentHandler::getInstance()->getCollapsedContent($this->collapsibleObjectTypeID); - $this->collapsedCategoryIDs = array_flip($this->collapsedCategoryIDs); - } - - parent::readData(); - } - - /** - * @see wcf\page\IPage::show() - */ - public function show() { - if ($this->activeMenuItem) { - ACPMenu::getInstance()->setActiveMenuItem($this->activeMenuItem); - } - - parent::show(); - } -} diff --git a/wcfsetup/install/files/lib/data/category/Category.class.php b/wcfsetup/install/files/lib/data/category/Category.class.php index 701d70c00d..25f1435843 100644 --- a/wcfsetup/install/files/lib/data/category/Category.class.php +++ b/wcfsetup/install/files/lib/data/category/Category.class.php @@ -77,7 +77,7 @@ class Category extends DatabaseObject implements IRouteController { * @see wcf\system\request\IRouteController::getID() */ public function getID() { - return $this->objectTypeCategoryID; + return $this->categoryID; } /** @@ -87,7 +87,7 @@ class Category extends DatabaseObject implements IRouteController { */ public function getParentCategory() { if ($this->parentCategoryID && $this->parentCategory === null) { - $this->parentCategory = CategoryHandler::getInstance()->getCategory($this->objectTypeID, $this->parentCategoryID); + $this->parentCategory = CategoryHandler::getInstance()->getCategory($this->parentCategoryID); } return $this->parentCategory; @@ -113,7 +113,7 @@ class Category extends DatabaseObject implements IRouteController { } /** - * @see wcf\system\request\IRouteController::getTitle() + * @see wcf\data\ITitledDatabaseObject::getTitle() */ public function getTitle() { return WCF::getLanguage()->get($this->title); diff --git a/wcfsetup/install/files/lib/data/category/CategoryAction.class.php b/wcfsetup/install/files/lib/data/category/CategoryAction.class.php index b771094739..d20bab41a7 100644 --- a/wcfsetup/install/files/lib/data/category/CategoryAction.class.php +++ b/wcfsetup/install/files/lib/data/category/CategoryAction.class.php @@ -79,7 +79,7 @@ class CategoryAction extends AbstractDatabaseObjectAction { foreach ($categoryIDs as $categoryID) { $this->objects[$categoryID]->update(array( - 'parentCategoryID' => $parentCategoryID ? $this->objects[$parentCategoryID]->objectTypeCategoryID : 0, + 'parentCategoryID' => $parentCategoryID ? $this->objects[$parentCategoryID]->categoryID : 0, 'showOrder' => $showOrders[$parentCategoryID]++ )); } @@ -138,7 +138,7 @@ class CategoryAction extends AbstractDatabaseObjectAction { } foreach ($this->objects as $categoryEditor) { - if (!$categoryEditor->getCategoryType()->canAddCategory()) { + if (!$categoryEditor->getCategoryType()->canDeleteCategory()) { throw new ValidateActionException('Insufficient permissions'); } } @@ -214,7 +214,7 @@ class CategoryAction extends AbstractDatabaseObjectAction { foreach ($this->parameters['data']['structure'] as $parentCategoryID => $categoryIDs) { if ($parentCategoryID) { // validate category - $category = CategoryHandler::getInstance()->getCategoryByID($parentCategoryID); + $category = CategoryHandler::getInstance()->getCategory($parentCategoryID); if ($category === null) { throw new ValidateActionException("Unknown category with id '".$parentCategoryID."'"); } @@ -229,7 +229,7 @@ class CategoryAction extends AbstractDatabaseObjectAction { foreach ($categoryIDs as $categoryID) { // validate category - $category = CategoryHandler::getInstance()->getCategoryByID($categoryID); + $category = CategoryHandler::getInstance()->getCategory($categoryID); if ($category === null) { throw new ValidateActionException("Unknown category with id '".$categoryID."'"); } diff --git a/wcfsetup/install/files/lib/data/category/CategoryEditor.class.php b/wcfsetup/install/files/lib/data/category/CategoryEditor.class.php index 5d2e04eb5b..44f7245ef2 100644 --- a/wcfsetup/install/files/lib/data/category/CategoryEditor.class.php +++ b/wcfsetup/install/files/lib/data/category/CategoryEditor.class.php @@ -1,11 +1,9 @@ parentCategoryID) { @@ -135,7 +133,6 @@ class CategoryEditor extends DatabaseObjectEditor implements IEditableCachedObje // handle show order $parameters['showOrder'] = static::getShowOrder($parameters['objectTypeID'], $parameters['parentCategoryID'], $parameters['showOrder']); - $parameters['objectTypeCategoryID'] = static::getNextCategoryID($parameters['objectTypeID']); // handle additionalData if (!isset($parameters['additionalData'])) { @@ -157,44 +154,13 @@ class CategoryEditor extends DatabaseObjectEditor implements IEditableCachedObje $statement = WCF::getDB()->prepareStatement($sql); foreach ($objectIDs as $categoryID) { - $category = CategoryHandler::getInstance()->getCategoryByID($categoryID); + $category = CategoryHandler::getInstance()->getCategory($categoryID); $statement->execute(array($category->parentCategoryID, $category->showOrder)); } return parent::deleteAll($objectIDs); } - /** - * Returns the next category id for the given object type id. - * - * @param integer $objectTypeID - * @return integer - */ - protected static function getNextCategoryID($objectTypeID) { - $objectType = CategoryHandler::getInstance()->getObjectType($objectTypeID); - if ($objectType === null) { - throw new SystemException("Invalid category object type id '".$objectTypeID."'"); - } - - $nextCategoryID = 1; - if ($objectType->nextCategoryID !== null) { - $nextCategoryID = $objectType->nextCategoryID; - } - - // update next category additional data - $objectTypeEditor = new ObjectTypeEditor($objectType); - $objectTypeEditor->update(array( - 'additionalData' => serialize(array_merge($objectType->additionalData, array( - 'nextCategoryID' => $nextCategoryID + 1 - ))) - )); - - // reset object type cache - CacheHandler::getInstance()->clear(WCF_DIR.'cache/', 'cache.objectType-*.php'); - - return $nextCategoryID; - } - /** * Returns the show order for a new category. * @@ -205,8 +171,8 @@ class CategoryEditor extends DatabaseObjectEditor implements IEditableCachedObje */ protected static function getShowOrder($objectTypeID, $parentCategoryID, $showOrder) { // correct invalid values - if ($showOrder <= 0) { - $showOrder = 1; + if ($showOrder === null) { + $showOrder = PHP_INT_MAX; } $sql = "SELECT MAX(showOrder) AS showOrder diff --git a/wcfsetup/install/files/lib/data/category/CategoryNode.class.php b/wcfsetup/install/files/lib/data/category/CategoryNode.class.php index 402204b021..eb81c8a985 100644 --- a/wcfsetup/install/files/lib/data/category/CategoryNode.class.php +++ b/wcfsetup/install/files/lib/data/category/CategoryNode.class.php @@ -31,7 +31,7 @@ class CategoryNode extends DatabaseObjectDecorator implements \RecursiveIterator * list of object type category ids of excluded categories * @var array */ - protected $excludedObjectTypeCategoryIDs = false; + protected $excludedCategoryIDs = false; /** * @see wcf\data\DatabaseObjectDecorator::$baseClass @@ -41,16 +41,16 @@ class CategoryNode extends DatabaseObjectDecorator implements \RecursiveIterator /** * @see wcf\data\DatabaseObjectDecorator::__construct() */ - public function __construct(DatabaseObject $object, $inludeDisabledCategories = false, array $excludedObjectTypeCategoryIDs = array()) { + public function __construct(DatabaseObject $object, $inludeDisabledCategories = false, array $excludedCategoryIDs = array()) { parent::__construct($object); $this->inludeDisabledCategories = $inludeDisabledCategories; - $this->excludedObjectTypeCategoryIDs = $excludedObjectTypeCategoryIDs; + $this->excludedCategoryIDs = $excludedCategoryIDs; $className = get_called_class(); foreach (CategoryHandler::getInstance()->getChildCategories($this->getDecoratedObject()) as $category) { if ($this->fulfillsConditions($category)) { - $this->childCategories[] = new $className($category, $inludeDisabledCategories, $excludedObjectTypeCategoryIDs); + $this->childCategories[] = new $className($category, $inludeDisabledCategories, $excludedCategoryIDs); } } } @@ -77,7 +77,7 @@ class CategoryNode extends DatabaseObjectDecorator implements \RecursiveIterator * @return boolean */ public function fulfillsConditions(Category $category) { - return !in_array($category->objectTypeCategoryID, $this->excludedObjectTypeCategoryIDs) && ($this->includeDisabledCategories || !$category->isDisabled); + return !in_array($category->categoryID, $this->excludedCategoryIDs) && ($this->includeDisabledCategories || !$category->isDisabled); } /** diff --git a/wcfsetup/install/files/lib/data/category/CategoryNodeList.class.php b/wcfsetup/install/files/lib/data/category/CategoryNodeList.class.php index 211a3a477a..33bed817e1 100644 --- a/wcfsetup/install/files/lib/data/category/CategoryNodeList.class.php +++ b/wcfsetup/install/files/lib/data/category/CategoryNodeList.class.php @@ -35,31 +35,30 @@ class CategoryNodeList extends \RecursiveIteratorIterator implements \Countable /** * Creates a new CategoryNodeList instance. * - * @param integer $objectTypeID + * @param string $objectType * @param integer $parentCategoryID * @param boolean $inludeDisabledCategories * @param array $excludedCategoryIDs */ - public function __construct($objectTypeID, $parentCategoryID = 0, $inludeDisabledCategories = false, array $excludedObjectTypeCategoryIDs = array()) { + public function __construct($objectType, $parentCategoryID = 0, $inludeDisabledCategories = false, array $excludedCategoryIDs = array()) { $this->parentCategoryID = $parentCategoryID; // get parent category if (!$this->parentCategoryID) { // empty node $parentCategory = new Category(null, array( - 'categoryID' => $this->parentCategoryID, - 'objectTypeID' => $objectTypeID, - 'objectTypeCategoryID' => $this->parentCategoryID + 'categoryID' => 0, + 'objectTypeID' => CategoryHandler::getInstance()->getObjectTypeByName($objectType)->objectTypeID )); } else { - $parentCategory = CategoryHandler::getInstance()->getCategory($objectTypeID, $this->parentCategoryID); + $parentCategory = CategoryHandler::getInstance()->getCategory($this->parentCategoryID); if ($parentCategory === null) { - throw new SystemException("There is no category with id '".$this->parentCategoryID."' and object type id '".$objectTypeID."'"); + throw new SystemException("There is no category with id '".$this->parentCategoryID."'"); } } - parent::__construct(new $this->nodeClassName($parentCategory, $inludeDisabledCategories, $excludedObjectTypeCategoryIDs), \RecursiveIteratorIterator::SELF_FIRST); + parent::__construct(new $this->nodeClassName($parentCategory, $inludeDisabledCategories, $excludedCategoryIDs), \RecursiveIteratorIterator::SELF_FIRST); } /** diff --git a/wcfsetup/install/files/lib/system/cache/builder/CategoryCacheBuilder.class.php b/wcfsetup/install/files/lib/system/cache/builder/CategoryCacheBuilder.class.php index ac694e34df..13e67e0bcc 100644 --- a/wcfsetup/install/files/lib/system/cache/builder/CategoryCacheBuilder.class.php +++ b/wcfsetup/install/files/lib/system/cache/builder/CategoryCacheBuilder.class.php @@ -1,6 +1,7 @@ sqlLimit = 0; + $list->sqlSelects = "object_type.objectType"; $list->sqlJoins = " LEFT JOIN wcf".WCF_N."_object_type object_type - ON (object_type.objectTypeID = category.objectTypeID) - LEFT JOIN wcf".WCF_N."_package_dependency package_dependency - ON (package_dependency.dependency = object_type.packageID)"; - $list->getConditionBuilder()->add("package_dependency.packageID = ?", array($packageID)); - $list->sqlOrderBy = "package_dependency.priority ASC, category.showOrder ASC"; + ON (object_type.objectTypeID = category.objectTypeID)"; + $list->getConditionBuilder()->add("object_type.packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies())); + $list->sqlOrderBy = "category.showOrder ASC"; $list->readObjects(); $data = array( - 'categories' => array(), - 'categoryIDs' => array() + 'categories' => $list->getObjects(), + 'objectTypeCategoryIDs' => array() ); foreach ($list as $category) { - if (!isset($data['categories'][$category->objectTypeID])) { - $data['categories'][$category->objectTypeID] = array(); + if (!isset($data['objectTypeCategoryIDs'][$category->objectType])) { + $data['objectTypeCategoryIDs'][$category->objectType] = array(); } - $data['categories'][$category->objectTypeID][$category->objectTypeCategoryID] = $category; - $data['categoryIDs'][$category->categoryID] = array( - 'objectTypeID' => $category->objectTypeID, - 'objectTypeCategoryID' => $category->objectTypeCategoryID - ); + $data['objectTypeCategoryIDs'][$category->objectType][] = $category->categoryID; } return $data; diff --git a/wcfsetup/install/files/lib/system/category/AbstractCategoryType.class.php b/wcfsetup/install/files/lib/system/category/AbstractCategoryType.class.php index 7c3ba1effb..c907575f9c 100644 --- a/wcfsetup/install/files/lib/system/category/AbstractCategoryType.class.php +++ b/wcfsetup/install/files/lib/system/category/AbstractCategoryType.class.php @@ -16,16 +16,16 @@ use wcf\system\WCF; */ abstract class AbstractCategoryType extends SingletonFactory implements ICategoryType { /** - * name of the acl object type - * @var string + * indicates if categories of this type may have no empty description + * @var boolean */ - protected $aclObjectTypeName = ''; + protected $forceDescription = true; /** - * name of the collapsible object type - * @var string + * indicates if categories of this type have descriptions + * @var boolean */ - protected $collapsibleObjectTypeName = ''; + protected $hasDescription = true; /** * language category which contains the language variables of i18n values @@ -46,10 +46,17 @@ abstract class AbstractCategoryType extends SingletonFactory implements ICategor protected $permissionPrefix = ''; /** - * indicates if the category type supports descriptions - * @var boolean + * maximum category nesting lebel + * @var integer + */ + protected $maximumNestingLevel = -1; + + /** + * name of the object types associated with categories of this type (the + * key is the definition name and value the object type name) + * @var array */ - protected $supportsDescriptions = true; + protected $objectTypes = array(); /** * @see wcf\system\category\ICategoryType::afterDeletion() @@ -86,17 +93,21 @@ abstract class AbstractCategoryType extends SingletonFactory implements ICategor } /** - * @see wcf\system\category\ICategoryType::getACLObjectTypeName() + * @see wcf\system\category\ICategoryType::forceDescription() */ - public function getACLObjectTypeName() { - return $this->aclObjectTypeName ?: null; + public function forceDescription() { + return $this->hasDescription() && $this->forceDescription; } /** - * @see wcf\system\category\ICategoryType::getCollapsibleObjectTypeName() + * @see wcf\system\category\ICategoryType::getObjectTypeName() */ - public function getCollapsibleObjectTypeName() { - return $this->aclObjectTypeName ?: null; + public function getObjectTypeName($definitionName) { + if (isset($this->objectTypes[$definitionName])) { + return $this->objectTypes[$definitionName]; + } + + return null; } /** @@ -127,6 +138,13 @@ abstract class AbstractCategoryType extends SingletonFactory implements ICategor return WCF::getLanguage()->get('wcf.category.'.$name, $optional); } + /** + * @see wcf\system\category\ICategoryType::getMaximumNestingLevel() + */ + public function getMaximumNestingLevel() { + return $this->maximumNestingLevel; + } + /** * @see wcf\system\category\ICategoryType::getTitleLangVarCategory() */ @@ -135,9 +153,9 @@ abstract class AbstractCategoryType extends SingletonFactory implements ICategor } /** - * @see wcf\system\category\ICategoryType::supportsDescriptions() + * @see wcf\system\category\ICategoryType::hasDescription() */ - public function supportsDescriptions() { - return $this->supportsDescriptions; + public function hasDescription() { + return $this->hasDescription; } } diff --git a/wcfsetup/install/files/lib/system/category/CategoryHandler.class.php b/wcfsetup/install/files/lib/system/category/CategoryHandler.class.php index be66a854df..aa1354a175 100644 --- a/wcfsetup/install/files/lib/system/category/CategoryHandler.class.php +++ b/wcfsetup/install/files/lib/system/category/CategoryHandler.class.php @@ -23,10 +23,10 @@ class CategoryHandler extends SingletonFactory { protected $categories = array(); /** - * maps each category id to its object type id and object type category id + * category ids grouped by the object type they belong to * @var array */ - protected $categoryIDs = array(); + protected $objectTypeCategoryIDs = array(); /** * mapes the names of the category object types to the object type ids @@ -41,33 +41,26 @@ class CategoryHandler extends SingletonFactory { protected $objectTypes = array(); /** - * Returns all category objects with the given object type id. + * Returns all category objects with the given object type. If no object + * type is given, all categories grouped by object type are returned. * - * @param integer $objectTypeID - * @return array + * @param string $objectType + * @return array */ - public function getCategories($objectTypeID) { - if (isset($this->categories[$objectTypeID])) { - return $this->categories[$objectTypeID]; + public function getCategories($objectType = null) { + $categories = array(); + if ($objectType === null) { + foreach ($this->objectTypes as $objectType) { + $categories[$objectType->objectType] = $this->getCategories($objectType->objectType); + } } - - return array(); - } - - /** - * Returns the category object with the given object type id and object - * type category id. - * - * @param integer $objectTypeID - * @param integer $objectTypeCategoryID - * @return wcf\data\category\Category - */ - public function getCategory($objectTypeID, $objectTypeCategoryID) { - if (isset($this->categories[$objectTypeID][$objectTypeCategoryID])) { - return $this->categories[$objectTypeID][$objectTypeCategoryID]; + else if (isset($this->objectTypeCategoryIDs[$objectType])) { + foreach ($this->objectTypeCategoryIDs[$objectType] as $categoryID) { + $categories[$categoryID] = $this->getCategory($categoryID); + } } - return null; + return $categories; } /** @@ -76,9 +69,9 @@ class CategoryHandler extends SingletonFactory { * @param integer $categoryID * @return wcf\data\category\Category */ - public function getCategoryByID($categoryID) { - if (isset($this->categoryIDs[$categoryID])) { - return $this->getCategory($this->categoryIDs[$categoryID]['objectTypeID'], $this->categoryIDs[$categoryID]['objectTypeCategoryID']); + public function getCategory($categoryID) { + if (isset($this->categories[$categoryID])) { + return $this->categories[$categoryID]; } return null; @@ -93,11 +86,9 @@ class CategoryHandler extends SingletonFactory { public function getChildCategories(Category $category) { $categories = array(); - if (isset($this->categories[$category->objectTypeID])) { - foreach ($this->categories[$category->objectTypeID] as $__category) { - if ($__category->parentCategoryID == $category->objectTypeCategoryID) { - $categories[$__category->objectTypeCategoryID] = $__category; - } + foreach ($this->categories as $__category) { + if ($__category->parentCategoryID == $category->categoryID && ($category->categoryID || $category->objectTypeID == $__category->objectTypeID)) { + $categories[$__category->categoryID] = $__category; } } @@ -121,17 +112,26 @@ class CategoryHandler extends SingletonFactory { /** * Gets the object type with the given name. * - * @param string $objectTypeName + * @param string $objectType * @return wcf\data\object\type\ObjectType */ - public function getObjectTypeByName($objectTypeName) { - if (isset($this->objectTypes[$objectTypeName])) { - return $this->objectTypes[$objectTypeName]; + public function getObjectTypeByName($objectType) { + if (isset($this->objectTypes[$objectType])) { + return $this->objectTypes[$objectType]; } return null; } + /** + * Returns all category object types. + * + * @return array + */ + public function getObjectTypes() { + return $this->objectTypes; + } + /** * @see wcf\system\SingletonFactory::init() */ @@ -148,7 +148,7 @@ class CategoryHandler extends SingletonFactory { 'wcf\system\cache\builder\CategoryCacheBuilder' ); $this->categories = CacheHandler::getInstance()->get($cacheName, 'categories'); - $this->categoryIDs = CacheHandler::getInstance()->get($cacheName, 'categoryIDs'); + $this->objectTypeCategoryIDs = CacheHandler::getInstance()->get($cacheName, 'objectTypeCategoryIDs'); } /** diff --git a/wcfsetup/install/files/lib/system/category/ICategoryType.class.php b/wcfsetup/install/files/lib/system/category/ICategoryType.class.php index 5c3436e045..b3524d78ec 100644 --- a/wcfsetup/install/files/lib/system/category/ICategoryType.class.php +++ b/wcfsetup/install/files/lib/system/category/ICategoryType.class.php @@ -42,20 +42,21 @@ interface ICategoryType { public function canEditCategory(); /** - * Returns the name of the acl object type for categories of this type. - * Returns null if categories of this type don't support acl. + * Returns true if a category of this type may have no empty description. * - * @return string + * @return boolean */ - public function getACLObjectTypeName(); + public function forceDescription(); /** - * Returns the name of the collapsible object type for categories of this - * type. Returns null if categories of this type don't support collapsing. + * Returns the name of the object type of the definition with the given + * name for categories of this type. If categories of this type are no + * object of the relevant type, null is returned. * + * @param string $definitionName * @return string */ - public function getCollapsibleObjectTypeName(); + public function getObjectTypeName($definitionName); /** * Returns the language variable category for the description language @@ -87,6 +88,14 @@ interface ICategoryType { */ public function getLanguageVariable($name, $optional = false); + /** + * Returns the maximum category nesting level for this type. "-1" means + * that there is no maximum. + * + * @return integer + */ + public function getMaximumNestingLevel(); + /** * Returns the language variable category for the title language variables * of categories of this type. @@ -96,9 +105,9 @@ interface ICategoryType { public function getTitleLangVarCategory(); /** - * Returns true if categories of this type support descriptions. + * Returns true if categories of this type have descriptions. * * @return boolean */ - public function supportsDescriptions(); + public function hasDescription(); } diff --git a/wcfsetup/setup/db/install.sql b/wcfsetup/setup/db/install.sql index 689b6ffa0e..c6efbd941e 100644 --- a/wcfsetup/setup/db/install.sql +++ b/wcfsetup/setup/db/install.sql @@ -86,15 +86,13 @@ DROP TABLE IF EXISTS wcf1_category; CREATE TABLE wcf1_category ( categoryID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY, objectTypeID INT(10) NOT NULL, - objectTypeCategoryID INT(10) NOT NULL, parentCategoryID INT(10) NOT NULL, title VARCHAR(255) NOT NULL, description TEXT, showOrder INT(10) NOT NULL, time INT(10) NOT NULL, isDisabled TINYINT(1) NOT NULL DEFAULT 0, - additionalData TEXT, - UNIQUE KEY (objectTypeID, objectTypeCategoryID) + additionalData TEXT ); DROP TABLE IF EXISTS wcf1_cleanup_listener; -- 2.20.1