Options were handled within the Form-derived classes itself, causing non-accessible code if calling from outside (e.g. using an AJAX-request).
<?php
namespace wcf\acp\form;
-use wcf\data\option\category\OptionCategory;
-use wcf\data\option\Option;
use wcf\form\AbstractForm;
-use wcf\system\cache\CacheHandler;
-use wcf\system\exception\SystemException;
use wcf\system\exception\UserInputException;
-use wcf\system\language\I18nHandler;
-use wcf\util\ClassUtil;
-use wcf\util\StringUtil;
+use wcf\system\option\OptionHandler;
/**
* This class provides default implementations for a list of options.
* @see wcf\form\AbstractForm::$errorType
*/
public $errorType = array();
-
+
/**
* cache name
* @var string
*/
- public $cacheName = 'option-';
+ public $cacheName = 'option';
/**
* cache class name
* @var string
*/
public $cacheClass = 'wcf\system\cache\builder\OptionCacheBuilder';
-
- /**
- * list of all option categories
- * @var array<wcf\data\option\category\OptionCategory>
- */
- public $cachedCategories = array();
-
- /**
- * list of all options
- * @var array<wcf\data\option\Option>
- */
- public $cachedOptions = array();
-
- /**
- * category structure
- * @var array
- */
- public $cachedCategoryStructure = array();
-
- /**
- * option structure
- * @var array
- */
- public $cachedOptionToCategories = array();
-
- /**
- * raw option values
- * @var array<mixed>
- */
- public $rawValues = array();
-
- /**
- * option values
- * @var array<mixed>
- */
- public $optionValues = array();
/**
* Name of the active option category.
public $categoryName = '';
/**
- * Options of the active category.
- * @var array<Option>
+ * language item pattern
+ * @var string
*/
- public $options = array();
+ protected $languageItemPattern = '';
/**
- * Type object cache.
- * @var array
+ * option handler object
+ * @var wcf\system\option\IOptionHandler
*/
- public $typeObjects = array();
+ public $optionHandler = null;
/**
- * language item pattern
+ * option handler class name
* @var string
*/
- protected $languageItemPattern = '';
-
+ public $optionHandlerClassName = 'wcf\system\option\OptionHandler';
+
/**
- * @see wcf\form\IForm::readFormParameters()
+ * @see wcf\page\Page::readParameters()
*/
- public function readFormParameters() {
- parent::readFormParameters();
-
- if (isset($_POST['values']) && is_array($_POST['values'])) $this->rawValues = $_POST['values'];
+ public function readParameters() {
+ parent::readParameters();
- foreach ($this->options as $option) {
- if ($option->supportI18n) {
- I18nHandler::getInstance()->register($option->optionName);
- I18nHandler::getInstance()->setOptions($option->optionName, $option->packageID, $option->optionValue, $this->languageItemPattern);
- }
- }
- I18nHandler::getInstance()->readValues();
+ $this->optionHandler = new $this->optionHandlerClassName($this->cacheName, $this->cacheClass, $this->languageItemPattern, $this->categoryName);
}
-
+
/**
- * Returns an object of the requested option type.
- *
- * @param string $type
- * @return wcf\system\option\IOptionType
+ * @see wcf\form\IForm::readFormParameters()
*/
- protected function getTypeObject($type) {
- if (!isset($this->typeObjects[$type])) {
- $className = 'wcf\system\option\\'.StringUtil::firstCharToUpperCase($type).'OptionType';
-
- // validate class
- if (!class_exists($className)) {
- throw new SystemException("unable to find class '".$className."'");
- }
- if (!ClassUtil::isInstanceOf($className, 'wcf\system\option\IOptionType')) {
- throw new SystemException("'".$className."' should implement wcf\system\option\IOptionType");
- }
- // create instance
- $this->typeObjects[$type] = new $className();
- }
+ public function readFormParameters() {
+ parent::readFormParameters();
- return $this->typeObjects[$type];
+ $this->optionHandler->readUserInput($_POST);
}
/**
public function validate() {
parent::validate();
- foreach ($this->options as $option) {
- try {
- $this->validateOption($option);
- }
- catch (UserInputException $e) {
- $this->errorType[$e->getField()] = $e->getType();
- }
- }
+ $this->errorType = $this->optionHandler->validate();
if (count($this->errorType) > 0) {
throw new UserInputException('options', $this->errorType);
}
}
- /**
- * Validates an option.
- *
- * @param Option $option
- */
- protected function validateOption(Option $option) {
- // get type object
- $typeObj = $this->getTypeObject($option->optionType);
-
- // get new value
- $newValue = isset($this->rawValues[$option->optionName]) ? $this->rawValues[$option->optionName] : null;
-
- // get save value
- $this->optionValues[$option->optionName] = $typeObj->getData($option, $newValue);
-
- // validate with pattern
- if ($option->validationPattern) {
- if (!preg_match('~'.$option->validationPattern.'~', $this->optionValues[$option->optionName])) {
- throw new UserInputException($option->optionName, 'validationFailed');
- }
- }
-
- // validate by type object
- $typeObj->validate($option, $newValue);
- }
-
- /**
- * Gets all options and option categories from cache.
- */
- protected function readCache() {
- // init cache
- $cacheName = $this->cacheName.PACKAGE_ID;
- CacheHandler::getInstance()->addResource($cacheName, WCF_DIR.'cache/cache.'.$cacheName.'.php', $this->cacheClass);
-
- // get cache contents
- $this->cachedCategories = CacheHandler::getInstance()->get($cacheName, 'categories');
- $this->cachedOptions = CacheHandler::getInstance()->get($cacheName, 'options');
- $this->cachedCategoryStructure = CacheHandler::getInstance()->get($cacheName, 'categoryStructure');
- $this->cachedOptionToCategories = CacheHandler::getInstance()->get($cacheName, 'optionToCategories');
-
- // get active options
- $this->loadActiveOptions($this->categoryName);
- }
-
- /**
- * Creates a list of all active options.
- *
- * @param string $parentCategoryName
- */
- protected function loadActiveOptions($parentCategoryName) {
- if (!isset($this->cachedCategories[$parentCategoryName]) || static::checkCategory($this->cachedCategories[$parentCategoryName])) {
- if (isset($this->cachedOptionToCategories[$parentCategoryName])) {
- foreach ($this->cachedOptionToCategories[$parentCategoryName] as $optionName) {
- if (static::checkOption($this->cachedOptions[$optionName])) {
- $this->options[$optionName] = $this->cachedOptions[$optionName];
- }
- }
- }
- if (isset($this->cachedCategoryStructure[$parentCategoryName])) {
- foreach ($this->cachedCategoryStructure[$parentCategoryName] as $categoryName) {
- $this->loadActiveOptions($categoryName);
- }
- }
- }
- }
-
- /**
- * Checks the required permissions and options of a category.
- *
- * @param OptionCategory $category
- * @return boolean
- */
- protected static function checkCategory(OptionCategory $category) {
- if ($category->permissions) {
- $hasPermission = false;
- $permissions = explode(',', $category->permissions);
- foreach ($permissions as $permission) {
- if (WCF::getSession()->getPermission($permission)) {
- $hasPermission = true;
- break;
- }
- }
-
- if (!$hasPermission) return false;
-
- }
- if ($category->options) {
- $hasEnabledOption = false;
- $options = explode(',', strtoupper($category->options));
- foreach ($options as $option) {
- if (defined($option) && constant($option)) {
- $hasEnabledOption = true;
- break;
- }
- }
-
- if (!$hasEnabledOption) return false;
- }
-
- return true;
- }
-
- /**
- * @see wcf\system\option\IOptionType::getFormElement()
- */
- protected function getFormElement($type, Option $option) {
- return $this->getTypeObject($type)->getFormElement($option, (isset($this->optionValues[$option->optionName]) ? $this->optionValues[$option->optionName] : null));
- }
-
- /**
- * Checks the required permissions and options of an option.
- *
- * @param Option $option
- * @return boolean
- */
- protected static function checkOption(Option $option) {
- if ($option->permissions) {
- $hasPermission = false;
- $permissions = explode(',', $option->permissions);
- foreach ($permissions as $permission) {
- if (WCF::getSession()->getPermission($permission)) {
- $hasPermission = true;
- break;
- }
- }
-
- if (!$hasPermission) return false;
-
- }
- if ($option->options) {
- $hasEnabledOption = false;
- $options = explode(',', strtoupper($option->options));
- foreach ($options as $option) {
- if (defined($option) && constant($option)) {
- $hasEnabledOption = true;
- break;
- }
- }
-
- if (!$hasEnabledOption) return false;
- }
-
- return true;
- }
-
- /**
- * Returns the tree of options.
- *
- * @param string $parentCategoryName
- * @param integer $level
- * @return array
- */
- protected function getOptionTree($parentCategoryName = '', $level = 0) {
- $tree = array();
-
- if (isset($this->cachedCategoryStructure[$parentCategoryName])) {
- // get super categories
- foreach ($this->cachedCategoryStructure[$parentCategoryName] as $superCategoryName) {
- $superCategoryObject = $this->cachedCategories[$superCategoryName];
- $superCategory = array(
- 'object' => $superCategoryObject,
- 'categories' => array(),
- 'options' => array()
- );
-
- if (static::checkCategory($superCategoryObject)) {
- if ($level <= 1) {
- $superCategory['categories'] = $this->getOptionTree($superCategoryName, $level + 1);
- }
- if ($level > 1 || count($superCategory['categories']) == 0) {
- $superCategory['options'] = $this->getCategoryOptions($superCategoryName);
- }
- else {
- $superCategory['options'] = $this->getCategoryOptions($superCategoryName, false);
- }
-
- if (count($superCategory['categories']) > 0 || count($superCategory['options']) > 0) {
- $tree[] = $superCategory;
- }
- }
- }
- }
-
- return $tree;
- }
-
- /**
- * Returns a list with the options of a specific option category.
- *
- * @param string $categoryName
- * @param boolean $inherit
- * @return array
- */
- protected function getCategoryOptions($categoryName = '', $inherit = true) {
- $children = array();
-
- // get sub categories
- if ($inherit && isset($this->cachedCategoryStructure[$categoryName])) {
- foreach ($this->cachedCategoryStructure[$categoryName] as $subCategoryName) {
- $children = array_merge($children, $this->getCategoryOptions($subCategoryName));
- }
- }
-
- // get options
- if (isset($this->cachedOptionToCategories[$categoryName])) {
- $i = 0;
- $last = count($this->cachedOptionToCategories[$categoryName]) - 1;
- foreach ($this->cachedOptionToCategories[$categoryName] as $optionName) {
- if (!isset($this->options[$optionName]) || !$this->checkOption($this->options[$optionName])) continue;
-
- // get option object
- $option = $this->options[$optionName];
-
- // get form element html
- $html = $this->getFormElement($option->optionType, $option);
-
- // add option to list
- $children[] = array(
- 'object' => $option,
- 'html' => $html,
- 'cssClassName' => $this->getTypeObject($option->optionType)->getCSSClassName()
- );
-
- $i++;
- }
- }
-
- return $children;
- }
-
public function readData() {
parent::readData();
if (!count($_POST)) {
- foreach ($this->options as $option) {
- if ($option->supportI18n) {
- I18nHandler::getInstance()->register($option->optionName);
- I18nHandler::getInstance()->setOptions($option->optionName, $option->packageID, $option->optionValue, $this->languageItemPattern);
- }
- }
+ $this->optionHandler->readData();
}
}
}
/**
* @see wcf\acp\form\AbstractOptionListForm::$languageItemPattern
*/
- protected $languageItemPattern = 'wcf.option.option\d+';
+ protected $languageItemPattern = 'wcf.acp.option.option\d+';
/**
* @see wcf\page\IPage::readParameters()
*/
public function readParameters() {
- parent::readParameters();
-
if (isset($_REQUEST['id'])) $this->categoryID = intval($_REQUEST['id']);
$this->category = new OptionCategory($this->categoryID);
if (!isset($this->category->categoryID)) {
throw new IllegalLinkException();
}
$this->categoryName = $this->category->categoryName;
+
+ parent::readParameters();
}
/**
parent::save();
// save options
- $saveOptions = array();
- foreach ($this->options as $option) {
- // handle i18n support
- if ($option->supportI18n) {
- if (I18nHandler::getInstance()->isPlainValue($option->optionName)) {
- I18nHandler::getInstance()->remove('wcf.option.option' . $option->optionID, $option->packageID);
- $saveOptions[$option->optionID] = I18nHandler::getInstance()->getValue($option->optionName);
- }
- else {
- I18nHandler::getInstance()->save($option->optionName, 'wcf.option.option' . $option->optionID, 'wcf.option', $option->packageID);
- $saveOptions[$option->optionID] = 'wcf.option.option' . $option->optionID;
- }
- }
- else {
- $saveOptions[$option->optionID] = $this->optionValues[$option->optionName];
- }
- }
+ $saveOptions = $this->optionHandler->save('wcf.acp.option', 'wcf.acp.option.option');
$optionAction = new OptionAction(array(), 'updateAll', array('data' => $saveOptions));
$optionAction->executeAction();
$this->saved();
public function readData() {
parent::readData();
- if (!count($_POST)) {
- // get option values
- foreach ($this->options as $option) {
- $this->optionValues[$option->optionName] = $option->optionValue;
- }
- }
-
// load option tree
- $this->optionTree = $this->getOptionTree($this->category->categoryName);
+ $this->optionTree = $this->optionHandler->getOptionTree($this->category->categoryName);
if (!count($_POST)) {
$this->activeTabMenuItem = $this->optionTree[0]['object']->categoryName;
WCFACP::checkMasterPassword();
}
- // get options and categories from cache
- $this->readCache();
-
// show form
parent::show();
}
return $result;
}
+
+ /**
+ * Returns true, if option is visible
+ *
+ * @return boolean
+ */
+ public function isVisible() {
+ return !$this->hidden;
+ }
}
--- /dev/null
+<?php
+namespace wcf\system\option;
+
+/**
+ * Default interface for option handlers.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2011 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.option
+ * @category Community Framework
+ */
+interface IOptionHandler {
+ /**
+ * Creates a new option handler instance.
+ *
+ * @param string $cacheName
+ * @param string $cacheClass
+ * @param string $languageItemPattern
+ * @param string $categoryName
+ */
+ public function __construct($cacheName, $cacheClass, $languageItemPattern = '', $categoryName = '');
+
+ /**
+ * Reads user input from given source array.
+ *
+ * @param array $source
+ */
+ public function readUserInput(array &$source);
+
+ /**
+ * Validates user input, returns an array with all occured errors.
+ *
+ * @return array
+ */
+ public function validate();
+
+ /**
+ * Returns the tree of options.
+ *
+ * @param string $parentCategoryName
+ * @param integer $level
+ * @return array
+ */
+ public function getOptionTree($parentCategoryName = '', $level = 0);
+
+ /**
+ * Returns a list with the options of a specific option category.
+ *
+ * @param string $categoryName
+ * @param boolean $inherit
+ * @return array
+ */
+ public function getCategoryOptions($categoryName = '', $inherit = true);
+
+ /**
+ * Initializes i18n support.
+ */
+ public function readData();
+
+ /**
+ * Saves i18n variables and returns the updated option values.
+ *
+ * @param string $categoryName
+ * @param string $optionPrefix
+ * @return array
+ */
+ public function save($categoryName, $optionPrefix);
+}
--- /dev/null
+<?php
+namespace wcf\system\option;
+use wcf\data\option\category\OptionCategory;
+use wcf\data\option\Option;
+use wcf\system\cache\CacheHandler;
+use wcf\system\exception\UserInputException;
+use wcf\system\language\I18nHandler;
+use wcf\util\ClassUtil;
+use wcf\util\StringUtil;
+
+/**
+ * Default implementation for option lists.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2011 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.option
+ * @category Community Framework
+ */
+class OptionHandler implements IOptionHandler {
+ /**
+ * cache name
+ * @var string
+ */
+ public $cacheName = '';
+
+ /**
+ * cache class name
+ * @var string
+ */
+ public $cacheClass = '';
+
+ /**
+ * list of all option categories
+ * @var array<wcf\data\option\category\OptionCategory>
+ */
+ public $cachedCategories = null;
+
+ /**
+ * list of all options
+ * @var array<wcf\data\option\Option>
+ */
+ public $cachedOptions = null;
+
+ /**
+ * category structure
+ * @var array
+ */
+ public $cachedCategoryStructure = null;
+
+ /**
+ * option structure
+ * @var array
+ */
+ protected $cachedOptionToCategories = null;
+
+ /**
+ * Name of the active option category.
+ * @var string
+ */
+ public $categoryName = '';
+
+ /**
+ * Options of the active category.
+ * @var array<Option>
+ */
+ public $options = array();
+
+ /**
+ * Type object cache.
+ * @var array<wcf\system\option\ITypeObject>
+ */
+ public $typeObjects = array();
+
+ /**
+ * language item pattern
+ * @var string
+ */
+ public $languageItemPattern = '';
+
+ /**
+ * option values
+ * @var array<mixed>
+ */
+ public $optionValues = array();
+
+ /**
+ * raw option values
+ * @var array<mixed>
+ */
+ public $rawValues = array();
+
+ /**
+ * @see wcf\system\option\IOptionHandler::__construct()
+ */
+ public function __construct($cacheName, $cacheClass, $languageItemPattern = '', $categoryName = '') {
+ $this->cacheName = $cacheName;
+ $this->cacheClass = $cacheClass;
+ $this->categoryName = $categoryName;
+ $this->languageItemPattern = $languageItemPattern;
+
+ // load cache on init
+ $this->readCache();
+ }
+
+ /**
+ * @see wcf\system\option\IOptionHandler::readUserInput()
+ */
+ public function readUserInput(array &$source) {
+ if (isset($source['values']) && is_array($source['values'])) $this->rawValues = $source['values'];
+
+ foreach ($this->options as $option) {
+ if ($option->supportI18n) {
+ I18nHandler::getInstance()->register($option->optionName);
+ I18nHandler::getInstance()->setOptions($option->optionName, $option->packageID, $option->optionValue, $this->languageItemPattern);
+ }
+ }
+ I18nHandler::getInstance()->readValues();
+ }
+
+ /**
+ * @see wcf\system\option\IOptionHandler::validate()
+ */
+ public function validate() {
+ $errors = array();
+
+ foreach ($this->options as $option) {
+ try {
+ $this->validateOption($option);
+ }
+ catch (UserInputException $e) {
+ $errors[$e->getField()] = $e->getType();
+ }
+ }
+
+ return $errors;
+ }
+
+ /**
+ * @see wcf\system\option\IOptionHandler::getOptionTree()
+ */
+ public function getOptionTree($parentCategoryName = '', $level = 0) {
+ $tree = array();
+
+ if (isset($this->cachedCategoryStructure[$parentCategoryName])) {
+ // get super categories
+ foreach ($this->cachedCategoryStructure[$parentCategoryName] as $superCategoryName) {
+ $superCategoryObject = $this->cachedCategories[$superCategoryName];
+ $superCategory = array(
+ 'object' => $superCategoryObject,
+ 'categories' => array(),
+ 'options' => array()
+ );
+
+ if (static::checkCategory($superCategoryObject)) {
+ if ($level <= 1) {
+ $superCategory['categories'] = $this->getOptionTree($superCategoryName, $level + 1);
+ }
+ if ($level > 1 || count($superCategory['categories']) == 0) {
+ $superCategory['options'] = $this->getCategoryOptions($superCategoryName);
+ }
+ else {
+ $superCategory['options'] = $this->getCategoryOptions($superCategoryName, false);
+ }
+
+ if (count($superCategory['categories']) > 0 || count($superCategory['options']) > 0) {
+ $tree[] = $superCategory;
+ }
+ }
+ }
+ }
+
+ return $tree;
+ }
+
+ /**
+ * @see wcf\system\option\IOptionHandler::getCategoryOptions()
+ */
+ public function getCategoryOptions($categoryName = '', $inherit = true) {
+ $children = array();
+
+ // get sub categories
+ if ($inherit && isset($this->cachedCategoryStructure[$categoryName])) {
+ foreach ($this->cachedCategoryStructure[$categoryName] as $subCategoryName) {
+ $children = array_merge($children, $this->getCategoryOptions($subCategoryName));
+ }
+ }
+
+ // get options
+ if (isset($this->cachedOptionToCategories[$categoryName])) {
+ $i = 0;
+ $last = count($this->cachedOptionToCategories[$categoryName]) - 1;
+ foreach ($this->cachedOptionToCategories[$categoryName] as $optionName) {
+ if (!isset($this->options[$optionName]) || !$this->checkOption($this->options[$optionName])) continue;
+
+ // get option object
+ $option = $this->options[$optionName];
+
+ // get form element html
+ $html = $this->getFormElement($option->optionType, $option);
+
+ // add option to list
+ $children[] = array(
+ 'object' => $option,
+ 'html' => $html,
+ 'cssClassName' => $this->getTypeObject($option->optionType)->getCSSClassName()
+ );
+
+ $i++;
+ }
+ }
+
+ return $children;
+ }
+
+ /**
+ * @see wcf\system\option\IOptionHandler::readData()
+ */
+ public function readData() {
+ foreach ($this->options as $option) {
+ if ($option->supportI18n) {
+ I18nHandler::getInstance()->register($option->optionName);
+ I18nHandler::getInstance()->setOptions($option->optionName, $option->packageID, $option->optionValue, $this->languageItemPattern);
+ }
+
+ $this->optionValues[$option->optionName] = $option->optionValue;
+ }
+ }
+
+ /**
+ * @see wcf\system\option\IOptionHandler::save()
+ */
+ public function save($categoryName, $optionPrefix) {
+ $saveOptions = array();
+
+ foreach ($this->options as $option) {
+ // handle i18n support
+ if ($option->supportI18n) {
+ if (I18nHandler::getInstance()->isPlainValue($option->optionName)) {
+ I18nHandler::getInstance()->remove($optionPrefix . $option->optionID, $option->packageID);
+ $saveOptions[$option->optionID] = I18nHandler::getInstance()->getValue($option->optionName);
+ }
+ else {
+ I18nHandler::getInstance()->save($option->optionName, $optionPrefix . $option->optionID, $categoryName, $option->packageID);
+ $saveOptions[$option->optionID] = $optionPrefix . $option->optionID;
+ }
+ }
+ else {
+ $saveOptions[$option->optionID] = $this->optionValues[$option->optionName];
+ }
+ }
+
+ return $saveOptions;
+ }
+
+ /**
+ * Validates an option.
+ *
+ * @param wcf\data\option\Option $option
+ */
+ protected function validateOption(Option $option) {
+ // get type object
+ $typeObj = $this->getTypeObject($option->optionType);
+
+ // get new value
+ $newValue = isset($this->rawValues[$option->optionName]) ? $this->rawValues[$option->optionName] : null;
+
+ // get save value
+ $this->optionValues[$option->optionName] = $typeObj->getData($option, $newValue);
+
+ // validate with pattern
+ if ($option->validationPattern) {
+ if (!preg_match('~'.$option->validationPattern.'~', $this->optionValues[$option->optionName])) {
+ throw new UserInputException($option->optionName, 'validationFailed');
+ }
+ }
+
+ // validate by type object
+ $typeObj->validate($option, $newValue);
+ }
+
+ /**
+ * @see wcf\system\option\IOptionType::getFormElement()
+ */
+ protected function getFormElement($type, Option $option) {
+ return $this->getTypeObject($type)->getFormElement($option, (isset($this->optionValues[$option->optionName]) ? $this->optionValues[$option->optionName] : null));
+ }
+
+ /**
+ * Returns an object of the requested option type.
+ *
+ * @param string $type
+ * @return wcf\system\option\IOptionType
+ */
+ protected function getTypeObject($type) {
+ if (!isset($this->typeObjects[$type])) {
+ $className = 'wcf\system\option\\'.ucfirst($type).'OptionType';
+
+ // validate class
+ if (!class_exists($className)) {
+ throw new SystemException("unable to find class '".$className."'");
+ }
+ if (!ClassUtil::isInstanceOf($className, 'wcf\system\option\IOptionType')) {
+ throw new SystemException("'".$className."' should implement wcf\system\option\IOptionType");
+ }
+
+ // create instance
+ $this->typeObjects[$type] = new $className();
+ }
+
+ return $this->typeObjects[$type];
+ }
+
+ /**
+ * Gets all options and option categories from cache.
+ */
+ protected function readCache() {
+ $cacheName = $this->cacheName . '-' . PACKAGE_ID;
+ CacheHandler::getInstance()->addResource($cacheName, WCF_DIR.'cache/cache.'.$cacheName.'.php', $this->cacheClass);
+
+ // get cache contents
+ $this->cachedCategories = CacheHandler::getInstance()->get($cacheName, 'categories');
+ $this->cachedOptions = CacheHandler::getInstance()->get($cacheName, 'options');
+ $this->cachedCategoryStructure = CacheHandler::getInstance()->get($cacheName, 'categoryStructure');
+ $this->cachedOptionToCategories = CacheHandler::getInstance()->get($cacheName, 'optionToCategories');
+
+ // get active options
+ $this->loadActiveOptions($this->categoryName);
+ }
+
+ /**
+ * Creates a list of all active options.
+ *
+ * @param string $parentCategoryName
+ */
+ protected function loadActiveOptions($parentCategoryName) {
+ if (!isset($this->cachedCategories[$parentCategoryName]) || $this->checkCategory($this->cachedCategories[$parentCategoryName])) {
+ if (isset($this->cachedOptionToCategories[$parentCategoryName])) {
+ foreach ($this->cachedOptionToCategories[$parentCategoryName] as $optionName) {
+ if ($this->checkOption($this->cachedOptions[$optionName])) {
+ $this->options[$optionName] = $this->cachedOptions[$optionName];
+ }
+ }
+ }
+
+ if (isset($this->cachedCategoryStructure[$parentCategoryName])) {
+ foreach ($this->cachedCategoryStructure[$parentCategoryName] as $categoryName) {
+ $this->loadActiveOptions($categoryName);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks the required permissions and options of a category.
+ *
+ * @param wcf\data\option\category\OptionCategory $category
+ * @return boolean
+ */
+ protected function checkCategory(OptionCategory $category) {
+ if ($category->permissions) {
+ $hasPermission = false;
+ $permissions = explode(',', $category->permissions);
+ foreach ($permissions as $permission) {
+ if (WCF::getSession()->getPermission($permission)) {
+ $hasPermission = true;
+ break;
+ }
+ }
+
+ if (!$hasPermission) return false;
+
+ }
+
+ if ($category->options) {
+ $hasEnabledOption = false;
+ $options = explode(',', strtoupper($category->options));
+ foreach ($options as $option) {
+ if (defined($option) && constant($option)) {
+ $hasEnabledOption = true;
+ break;
+ }
+ }
+
+ if (!$hasEnabledOption) return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Checks the required permissions and options of an option.
+ *
+ * @param wcf\data\option\Option $option
+ * @return boolean
+ */
+ protected function checkOption(Option $option) {
+ if ($option->permissions) {
+ $hasPermission = false;
+ $permissions = explode(',', $option->permissions);
+ foreach ($permissions as $permission) {
+ if (WCF::getSession()->getPermission($permission)) {
+ $hasPermission = true;
+ break;
+ }
+ }
+
+ if (!$hasPermission) return false;
+
+ }
+
+ if ($option->options) {
+ $hasEnabledOption = false;
+ $options = explode(',', strtoupper($option->options));
+ foreach ($options as $option) {
+ if (defined($option) && constant($option)) {
+ $hasEnabledOption = true;
+ break;
+ }
+ }
+
+ if (!$hasEnabledOption) return false;
+ }
+
+ if (!$option->isVisible()) {
+ return false;
+ }
+
+ return true;
+ }
+}