From: Alexander Ebert Date: Sat, 18 Aug 2012 12:07:19 +0000 (+0200) Subject: Enhanced ACP search, added user group option provider X-Git-Tag: 2.0.0_Beta_1~959^2~2 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=868867eacc6b9019372aeb29e29e2fdc0ea16f0a;p=GitHub%2FWoltLab%2FWCF.git Enhanced ACP search, added user group option provider --- diff --git a/com.woltlab.wcf/acpSearchProvider.xml b/com.woltlab.wcf/acpSearchProvider.xml index 7b86ff031f..ee01187506 100644 --- a/com.woltlab.wcf/acpSearchProvider.xml +++ b/com.woltlab.wcf/acpSearchProvider.xml @@ -9,5 +9,9 @@ 2 + + + 3 + diff --git a/wcfsetup/install/files/lib/system/search/acp/AbstractACPSearchResultProvider.class.php b/wcfsetup/install/files/lib/system/search/acp/AbstractACPSearchResultProvider.class.php new file mode 100644 index 0000000000..0165ab3ef9 --- /dev/null +++ b/wcfsetup/install/files/lib/system/search/acp/AbstractACPSearchResultProvider.class.php @@ -0,0 +1,56 @@ + + * @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; + } +} diff --git a/wcfsetup/install/files/lib/system/search/acp/AbstractCategorizedACPSearchResultProvider.class.php b/wcfsetup/install/files/lib/system/search/acp/AbstractCategorizedACPSearchResultProvider.class.php new file mode 100644 index 0000000000..4b099069eb --- /dev/null +++ b/wcfsetup/install/files/lib/system/search/acp/AbstractCategorizedACPSearchResultProvider.class.php @@ -0,0 +1,134 @@ + + * @package com.woltlab.wcf + * @subpackage system.search.acp + * @category Community Framework + */ +abstract class AbstractCategorizedACPSearchResultProvider extends AbstractACPSearchResultProvider { + /** + * list of categories + * @var array + */ + protected $categories = array(); + + /** + * class name for category list + * @var string + */ + protected $listClassName = ''; + + /** + * list of top category names (level 1 and 2) + * @var array + */ + 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]); + } +} diff --git a/wcfsetup/install/files/lib/system/search/acp/MenuItemACPSearchResultProvider.class.php b/wcfsetup/install/files/lib/system/search/acp/MenuItemACPSearchResultProvider.class.php index fc493d1318..c7af47b1ee 100644 --- a/wcfsetup/install/files/lib/system/search/acp/MenuItemACPSearchResultProvider.class.php +++ b/wcfsetup/install/files/lib/system/search/acp/MenuItemACPSearchResultProvider.class.php @@ -1,5 +1,6 @@ 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; - } } diff --git a/wcfsetup/install/files/lib/system/search/acp/OptionACPSearchResultProvider.class.php b/wcfsetup/install/files/lib/system/search/acp/OptionACPSearchResultProvider.class.php index fe4c39c738..d7ef7ed330 100644 --- a/wcfsetup/install/files/lib/system/search/acp/OptionACPSearchResultProvider.class.php +++ b/wcfsetup/install/files/lib/system/search/acp/OptionACPSearchResultProvider.class.php @@ -1,5 +1,6 @@ + * @see wcf\system\search\acp\AbstractCategorizedACPSearchResultProvider::$listClassName */ - protected $optionCategories = array(); - - /** - * list of level 1 or 2 categories - * @var array - */ - protected $topCategories = array(); + protected $listClassName = 'wcf\data\option\category\OptionCategoryList'; /** * @see wcf\system\search\acp\IACPSearchResultProvider::search() @@ -74,94 +68,28 @@ class OptionACPSearchResultProvider implements IACPSearchResultProvider { $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; } } diff --git a/wcfsetup/install/files/lib/system/search/acp/UserGroupOptionACPSearchResultProvider.class.php b/wcfsetup/install/files/lib/system/search/acp/UserGroupOptionACPSearchResultProvider.class.php new file mode 100644 index 0000000000..9fa9af9b6e --- /dev/null +++ b/wcfsetup/install/files/lib/system/search/acp/UserGroupOptionACPSearchResultProvider.class.php @@ -0,0 +1,101 @@ + + * @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; + } +}