<classname><![CDATA[wcf\system\search\acp\OptionACPSearchResultProvider]]></classname>
<showorder>2</showorder>
</acpsearchprovider>
+ <acpsearchprovider name="userGroupOption">
+ <classname><![CDATA[wcf\system\search\acp\UserGroupOptionACPSearchResultProvider]]></classname>
+ <showorder>3</showorder>
+ </acpsearchprovider>
</import>
</data>
--- /dev/null
+<?php
+namespace wcf\system\search\acp;
+use wcf\data\DatabaseObject;
+use wcf\system\WCF;
+
+/**
+ * Abstract class to validate options and permissions for a given object.
+ *
+ * @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 system.search.acp
+ * @category Community Framework
+ */
+abstract class AbstractACPSearchResultProvider {
+ /**
+ * Validates object options and permissions.
+ *
+ * @param wcf\data\DatabaseObject $object
+ * @param string $optionsColumnName
+ * @param string $permissionsColumnName
+ * @return boolean
+ */
+ protected function validate(DatabaseObject $object, $optionsColumnName = 'options', $permissionsColumnName = 'permissions') {
+ // check the options of this item
+ $hasEnabledOption = true;
+ if ($object->$optionsColumnName) {
+ $hasEnabledOption = false;
+ $options = explode(',', strtoupper($object->$optionsColumnName));
+ foreach ($options as $option) {
+ if (defined($option) && constant($option)) {
+ $hasEnabledOption = true;
+ break;
+ }
+ }
+ }
+ if (!$hasEnabledOption) return false;
+
+ // check the permission of this item for the active user
+ $hasPermission = true;
+ if ($object->$permissionsColumnName) {
+ $hasPermission = false;
+ $permissions = explode(',', $object->$permissionsColumnName);
+ foreach ($permissions as $permission) {
+ if (WCF::getSession()->getPermission($permission)) {
+ $hasPermission = true;
+ break;
+ }
+ }
+ }
+ if (!$hasPermission) return false;
+
+ return true;
+ }
+}
--- /dev/null
+<?php
+namespace wcf\system\search\acp;
+use wcf\system\exception\SystemException;
+use wcf\util\ClassUtil;
+
+/**
+ * Abstract class to handle nested categories.
+ *
+ * @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 system.search.acp
+ * @category Community Framework
+ */
+abstract class AbstractCategorizedACPSearchResultProvider extends AbstractACPSearchResultProvider {
+ /**
+ * list of categories
+ * @var array<wcf\data\DatabaseObject>
+ */
+ protected $categories = array();
+
+ /**
+ * class name for category list
+ * @var string
+ */
+ protected $listClassName = '';
+
+ /**
+ * list of top category names (level 1 and 2)
+ * @var array<string>
+ */
+ protected $topCategories = array();
+
+ /**
+ * Creates a new categorized ACP search result provider.
+ */
+ public function __construct() {
+ $this->loadCategories();
+ }
+
+ /**
+ * Returns a level 1 or 2 category id for given category name.
+ *
+ * @param string $categoryName
+ * @return integer
+ */
+ protected function getCategoryID($categoryName) {
+ $category = $this->getTopCategory($categoryName);
+
+ return $category->categoryID;
+ }
+
+ /**
+ * Returns a level 1 or 2 category name for given category name.
+ *
+ * @param string $categoryName
+ * @return string
+ */
+ protected function getCategoryName($categoryName) {
+ $category = $this->getTopCategory($categoryName);
+
+ return $category->categoryName;
+ }
+
+ /**
+ * Returns a level 1 or 2 category for given category name.
+ *
+ * @param string $categoryName
+ * @return wcf\data\DatabaseObject
+ */
+ protected function getTopCategory($categoryName) {
+ if (!$this->isValid($categoryName)) {
+ throw new SystemException("Category name '".$categoryName."' is unknown");
+ }
+
+ // this is a top category
+ if (in_array($categoryName, $this->topCategories)) {
+ return $this->categories[$categoryName];
+ }
+
+ // check parent category
+ return $this->getTopCategory($this->categories[$categoryName]->parentCategoryName);
+ }
+
+ /**
+ * Loads categories.
+ */
+ protected function loadCategories() {
+ // validate list class name
+ if (empty($this->listClassName) || !ClassUtil::isInstanceOf($this->listClassName, 'wcf\data\DatabaseObjectList')) {
+ throw new SystemException("Given class '".$this->listClassName."' is empty or invalid");
+ }
+
+ // read categories
+ $categoryList = new $this->listClassName();
+ $categoryList->sqlLimit = 0;
+ $categoryList->readObjects();
+
+ foreach ($categoryList as $category) {
+ // validate options and permissions
+ if (!$this->validate($category)) {
+ continue;
+ }
+
+ // save level 1 categories
+ if ($category->parentCategoryName == '') {
+ $this->topCategories[] = $category->categoryName;
+ }
+
+ $this->categories[$category->categoryName] = $category;
+ }
+
+ // create level 2 categories
+ $topCategories = array();
+ foreach ($this->categories as $category) {
+ if ($category->parentCategoryName && in_array($category->parentCategoryName, $this->topCategories)) {
+ $topCategories[] = $category->categoryName;
+ }
+ }
+
+ $this->topCategories = array_merge($this->topCategories, $topCategories);
+ }
+
+ /**
+ * Returns true, if given category is valid and accessible.
+ *
+ * @param string $categoryName
+ * @return boolean
+ */
+ protected function isValid($categoryName) {
+ return isset($this->categories[$categoryName]);
+ }
+}
<?php
namespace wcf\system\search\acp;
+use wcf\data\acp\menu\item\ACPMenuItem;
use wcf\system\database\util\PreparedStatementConditionBuilder;
use wcf\system\package\PackageDependencyHandler;
use wcf\system\request\LinkHandler;
* @subpackage system.search.acp
* @category Community Framework
*/
-class MenuItemACPSearchResultProvider implements IACPSearchResultProvider {
+class MenuItemACPSearchResultProvider extends AbstractACPSearchResultProvider implements IACPSearchResultProvider {
/**
* @see wcf\system\search\acp\IACPSearchResultProvider::search()
*/
break;
}
- if ($this->checkMenuItem($row)) {
- $results[] = new ACPSearchResult($languageItems[$row['menuItem']], $row['menuItemLink'] . SID_ARG_1ST);
- $count++;
+ $menuItem = new ACPMenuItem(null, $row);
+ if (!$this->validate($menuItem)) {
+ continue;
}
+
+ $results[] = new ACPSearchResult($languageItems[$row['menuItem']], $row['menuItemLink'] . SID_ARG_1ST);
+ $count++;
}
return $results;
}
-
- /**
- * Validates options and permissions for a given menu item.
- *
- * @param array $row
- * @return boolean
- */
- protected function checkMenuItem(array $row) {
- // check the options of this item
- $hasEnabledOption = true;
- if (!empty($row['options'])) {
- $hasEnabledOption = false;
- $options = explode(',', strtoupper($row['options']));
- foreach ($options as $option) {
- if (defined($option) && constant($option)) {
- $hasEnabledOption = true;
- break;
- }
- }
- }
- if (!$hasEnabledOption) return false;
-
- // check the permission of this item for the active user
- $hasPermission = true;
- if (!empty($row['permissions'])) {
- $hasPermission = false;
- $permissions = explode(',', $row['permissions']);
- foreach ($permissions as $permission) {
- if (WCF::getSession()->getPermission($permission)) {
- $hasPermission = true;
- break;
- }
- }
- }
- if (!$hasPermission) return false;
-
- return true;
- }
}
<?php
namespace wcf\system\search\acp;
+use wcf\data\option\Option;
use wcf\data\option\category\OptionCategoryList;
use wcf\system\database\util\PreparedStatementConditionBuilder;
use wcf\system\exception\SystemException;
* @subpackage system.search.acp
* @category Community Framework
*/
-class OptionACPSearchResultProvider implements IACPSearchResultProvider {
+class OptionACPSearchResultProvider extends AbstractCategorizedACPSearchResultProvider implements IACPSearchResultProvider {
/**
- * list of option categories
- * @var array<wcf\data\option\category\OptionCategory>
+ * @see wcf\system\search\acp\AbstractCategorizedACPSearchResultProvider::$listClassName
*/
- protected $optionCategories = array();
-
- /**
- * list of level 1 or 2 categories
- * @var array<wcf\data\option\category\OptionCategory>
- */
- protected $topCategories = array();
+ protected $listClassName = 'wcf\data\option\category\OptionCategoryList';
/**
* @see wcf\system\search\acp\IACPSearchResultProvider::search()
$conditions = new PreparedStatementConditionBuilder();
$conditions->add("optionName IN (?)", array($optionNames));
- $sql = "SELECT optionName, categoryName
+ $sql = "SELECT optionName, categoryName, options, permissions
FROM wcf".WCF_N."_option
".$conditions;
$statement = WCF::getDB()->prepareStatement($sql);
$statement->execute($conditions->getParameters());
while ($row = $statement->fetchArray()) {
- $link = LinkHandler::getInstance()->getLink('Option', array('id' => $this->getCategoryID($row['categoryName'])), 'optionName='.$row['optionName'].'#'.$this->getCategoryName($row['categoryName']));
- $results[] = new ACPSearchResult($languageItems[$row['optionName']], $link);
- }
-
- return $results;
- }
-
- /**
- * Returns the primary category id for given category name.
- *
- * @param string $categoryName
- * @return integer
- */
- protected function getCategoryID($categoryName) {
- // get option categories
- $this->loadCategories();
-
- if (!isset($this->optionCategories[$categoryName])) {
- throw new SystemException("Option category '".$categoryName."' is invalid");
- }
-
- // use the category id of parent category
- if ($this->optionCategories[$categoryName]->parentCategoryName != '') {
- return $this->getCategoryID($this->optionCategories[$categoryName]->parentCategoryName);
- }
-
- return $this->optionCategories[$categoryName]->categoryID;
- }
-
- /**
- * Returns a level 1 or 2 category name.
- *
- * @param string $categoryName
- * @return string
- */
- protected function getCategoryName($categoryName) {
- // get option categories
- $this->loadCategories();
-
- // load level 1
- if (empty($this->topCategories)) {
- foreach ($this->optionCategories as $category) {
- if ($category->parentCategoryName == '') {
- $this->topCategories[$category->categoryName] = $category;
- }
+ // category is not accessible
+ if (!$this->isValid($row['categoryName'])) {
+ continue;
}
- // load level 2
- $secondLevelCategories = array();
- foreach ($this->optionCategories as $category) {
- if ($category->parentCategoryName != '' && isset($this->topCategories[$category->parentCategoryName])) {
- $secondLevelCategories[$category->categoryName] = $category;
- }
+ // option is not accessible
+ $option = new Option(null, $row);
+ if (!$this->validate($option)) {
+ continue;
}
- $this->topCategories = array_merge($this->topCategories, $secondLevelCategories);
- }
-
- if (!isset($this->optionCategories[$categoryName])) {
- throw new SystemException("Option category '".$categoryName."' is invalid");
- }
-
- if (isset($this->topCategories[$categoryName])) {
- return $categoryName;
+ $link = LinkHandler::getInstance()->getLink('Option', array('id' => $this->getCategoryID($row['categoryName'])), 'optionName='.$row['optionName'].'#'.$this->getCategoryName($row['categoryName']));
+ $results[] = new ACPSearchResult($languageItems[$row['optionName']], $link);
}
- return $this->getCategoryName($this->optionCategories[$categoryName]->parentCategoryName);
- }
-
- /**
- * Loads option categories.
- */
- protected function loadCategories() {
- if (empty($this->optionCategories)) {
- $categoryList = new OptionCategoryList();
- $categoryList->sqlLimit = 0;
- $categoryList->readObjects();
-
- foreach ($categoryList as $category) {
- $this->optionCategories[$category->categoryName] = $category;
- }
- }
+ return $results;
}
}
--- /dev/null
+<?php
+namespace wcf\system\search\acp;
+use wcf\data\user\group\option\UserGroupOption;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
+use wcf\system\package\PackageDependencyHandler;
+use wcf\system\request\LinkHandler;
+use wcf\system\WCF;
+
+/**
+ * ACP search provider for user group options.
+ *
+ * @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 system.search.acp
+ * @category Community Framework
+ */
+class UserGroupOptionACPSearchResultProvider extends AbstractCategorizedACPSearchResultProvider implements IACPSearchResultProvider {
+ /**
+ * @see wcf\system\search\acp\AbstractCategorizedACPSearchResultProvider::$listClassName
+ */
+ protected $listClassName = 'wcf\data\user\group\option\category\UserGroupOptionCategoryList';
+
+ /**
+ * @see wcf\system\search\acp\IACPSearchResultProvider::search()
+ */
+ public function search($query, $limit = 5) {
+ $results = array();
+
+ // search by language item
+ $conditions = new PreparedStatementConditionBuilder();
+ $conditions->add("languageID = ?", array(WCF::getLanguage()->languageID));
+ $conditions->add("languageItemValue LIKE ?", array($query.'%'));
+ $conditions->add("packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies()));
+
+ // filter by language item
+ $languageItemsConditions = '';
+ $languageItemsParameters = array();
+ foreach (ACPSearchHandler::getInstance()->getAbbreviations('.acp.group.option.%') as $abbreviation) {
+ if (!empty($languageItemsConditions)) $languageItemsConditions .= " OR ";
+ $languageItemsConditions .= "languageItem LIKE ?";
+ $languageItemsParameters[] = $abbreviation;
+ }
+ $conditions->add("(".$languageItemsConditions.")", $languageItemsParameters);
+
+ $sql = "SELECT languageItem, languageItemValue
+ FROM wcf".WCF_N."_language_item
+ ".$conditions."
+ ORDER BY languageItemValue ASC";
+ $statement = WCF::getDB()->prepareStatement($sql); // don't use a limit here
+ $statement->execute($conditions->getParameters());
+ $languageItems = array();
+ while ($row = $statement->fetchArray()) {
+ // ignore descriptions
+ if (substr($row['languageItem'], -12) == '.description') {
+ continue;
+ }
+
+ $itemName = preg_replace('~^([a-z]+)\.acp\.group\.option\.~', '', $row['languageItem']);
+ $languageItems[$itemName] = $row['languageItemValue'];
+ }
+
+ if (empty($languageItems)) {
+ return array();
+ }
+
+ $conditions = new PreparedStatementConditionBuilder();
+ $conditions->add("optionName IN (?)", array(array_keys($languageItems)));
+
+ $sql = "SELECT optionID, optionName, categoryName, permissions, options
+ FROM wcf".WCF_N."_user_group_option
+ ".$conditions;
+ $statement = WCF::getDB()->prepareStatement($sql); // don't use a limit here
+ $statement->execute($conditions->getParameters());
+
+ $count = 0;
+ while ($row = $statement->fetchArray()) {
+ if ($count == $limit) {
+ break;
+ }
+
+ // category is not accessible
+ if (!$this->isValid($row['categoryName'])) {
+ continue;
+ }
+
+ // option is not accessible
+ $userGroupOption = new UserGroupOption(null, $row);
+ if (!$this->validate($userGroupOption)) {
+ continue;
+ }
+
+ $link = LinkHandler::getInstance()->getLink('UserGroupOption', array('id' => $row['optionID']));
+ $results[] = new ACPSearchResult($languageItems[$row['optionName']], $link);
+ $count++;
+ }
+
+ return $results;
+ }
+}