ignore disabled permissions in cache builder
authorMarcel Werk <burntime@woltlab.com>
Wed, 28 Aug 2019 16:00:29 +0000 (18:00 +0200)
committerMarcel Werk <burntime@woltlab.com>
Wed, 28 Aug 2019 16:00:29 +0000 (18:00 +0200)
Closes #3061

wcfsetup/install/files/lib/system/cache/builder/UserGroupPermissionCacheBuilder.class.php
wcfsetup/install/files/lib/system/option/AbstractOptionType.class.php
wcfsetup/install/files/lib/system/option/BooleanOptionType.class.php
wcfsetup/install/files/lib/system/option/IOptionType.class.php
wcfsetup/install/files/lib/system/option/RadioButtonOptionType.class.php

index d61aa563ca2d8264f4a03991947bbdc8b746c560..e8b582adfb1c796bd3fa207716e4b4fd0dde918d 100644 (file)
@@ -53,7 +53,8 @@ class UserGroupPermissionCacheBuilder extends AbstractCacheBuilder {
                $conditions = new PreparedStatementConditionBuilder();
                $conditions->add("option_value.groupID IN (?)", [$parameters]);
                
-               $sql = "SELECT          option_table.optionName, option_table.optionType, option_value.optionValue
+               $optionData = [];
+               $sql = "SELECT          option_table.optionName, option_table.optionType, option_value.optionValue, option_value.groupID, option_table.enableOptions
                        FROM            wcf".WCF_N."_user_group_option_value option_value
                        LEFT JOIN       wcf".WCF_N."_user_group_option option_table
                        ON              (option_table.optionID = option_value.optionID)
@@ -61,11 +62,33 @@ class UserGroupPermissionCacheBuilder extends AbstractCacheBuilder {
                $statement = WCF::getDB()->prepareStatement($sql);
                $statement->execute($conditions->getParameters());
                while ($row = $statement->fetchArray()) {
-                       if (!isset($data[$row['optionName']])) {
-                               $data[$row['optionName']] = ['type' => $row['optionType'], 'values' => []];
+                       $optionData[$row['groupID']][$row['optionName']] = $row;
+               }
+               
+               foreach ($optionData as $groupID => $options) {
+                       $optionBlacklist = [];
+                       
+                       foreach ($options as $option) {
+                               if ($option['enableOptions']) {
+                                       $typeObj = $this->getTypeObject($option['optionType']);
+                                       $disabledOptions = $typeObj->getDisabledOptionNames($option['optionValue'], $option['enableOptions']);
+                                       if (!empty($disabledOptions)) {
+                                               $optionBlacklist = array_merge($optionBlacklist, $disabledOptions);
+                                       }
+                               }
                        }
                        
-                       $data[$row['optionName']]['values'][] = $row['optionValue'];
+                       $options = array_filter($options, function($optionName) use (&$optionBlacklist) {
+                               return !in_array($optionName, $optionBlacklist);
+                       }, ARRAY_FILTER_USE_KEY);
+                       
+                       foreach ($options as $option) {
+                               if (!isset($data[$option['optionName']])) {
+                                       $data[$option['optionName']] = ['type' => $option['optionType'], 'values' => []];
+                               }
+                               
+                               $data[$option['optionName']]['values'][] = $option['optionValue'];
+                       }
                }
                
                $includesOwnerGroup = false;
index 9a8762004ba019bb86f16dad4b962c80a6b7d841..d0f3ffbfa50fbb0602da59a67a2f1b2e992c0d93 100644 (file)
@@ -56,4 +56,11 @@ abstract class AbstractOptionType implements IOptionType {
        public function hideLabelInSearch() {
                return false;
        }
+       
+       /**
+        * @inheritDoc
+        */
+       public function getDisabledOptionNames($value, $enableOptions) {
+               return [];
+       }
 }
index 651598580f5dc04f6b8810df8efa6281d65ec39b..0836bd7c85520802c0ac7df509be1b0ac899fe98 100644 (file)
@@ -5,6 +5,7 @@ use wcf\data\user\User;
 use wcf\data\user\UserList;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\WCF;
+use wcf\util\ArrayUtil;
 
 /**
  * Option type implementation for boolean values.
@@ -102,4 +103,23 @@ class BooleanOptionType extends AbstractOptionType implements ISearchableConditi
                
                return $value1 ? 1 : -1;
        }
+       
+       /**
+        * @inheritDoc
+        */
+       public function getDisabledOptionNames($value, $enableOptions) {
+               $options = ArrayUtil::trim(explode(',', $enableOptions));
+               $result = [];
+               
+               foreach ($options as $item) {
+                       if ($item{0} == '!') {
+                               if ($value) $result[] = $item;
+                       }
+                       else {
+                               if (!$value) $result[] = $item;
+                       }
+               }
+               
+               return $result;
+       }
 }
index 6b32fa1c77e55953530dbb7cc19b7afb54d8338e..6c9c105e74ad253d279e1bdb459e0fcdf5a56eb3 100644 (file)
@@ -48,7 +48,7 @@ interface IOptionType {
        public function getCSSClassName();
        
        /**
-        * Returns true if options supports internationalization .
+        * Returns true if options supports internationalization.
         * 
         * @return      boolean
         */
@@ -74,4 +74,14 @@ interface IOptionType {
         * @return      boolean
         */
        public function hideLabelInSearch();
+       
+       /**
+        * Determines disabled options by given option value.
+        * 
+        * @param       mixed           $value
+        * @param       string          $enableOptions
+        * @return      string[]
+        * @since       5.2
+        */
+       public function getDisabledOptionNames($value, $enableOptions);
 }
index 5e60c1b05c29656afb19dca399da27f985edfbb7..9acc7c532ca1f8d1393b231b80c45d3db635c61c 100644 (file)
@@ -6,6 +6,7 @@ use wcf\data\user\UserList;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\exception\UserInputException;
 use wcf\system\WCF;
+use wcf\util\ArrayUtil;
 use wcf\util\StringUtil;
 
 /**
@@ -128,4 +129,44 @@ class RadioButtonOptionType extends AbstractOptionType implements ISearchableCon
        public function getCSSClassName() {
                return 'checkboxList';
        }
+       
+       /**
+        * @inheritDoc
+        */
+       public function getDisabledOptionNames($value, $enableOptions) {
+               $valueToOptions = explode("\n", StringUtil::trim(StringUtil::unifyNewlines($enableOptions)));
+               
+               $i = 0;
+               foreach ($valueToOptions as $valueToOption) {
+                       if (mb_strpos($valueToOption, ':') !== false) {
+                               $optionData = explode(':', $valueToOption);
+                               $key = array_shift($optionData);
+                               $enableOptionValues = implode(':', $optionData);
+                       }
+                       else {
+                               $key = $i;
+                               $enableOptionValues = $valueToOption;
+                       }
+                       
+                       if ($key == $value) {
+                               $options = ArrayUtil::trim(explode(',', $enableOptionValues));
+                               $result = [];
+                               
+                               foreach ($options as $item) {
+                                       if ($item{0} == '!') {
+                                               $result[] = $item;
+                                       }
+                                       else {
+                                               $result[] = $item;
+                                       }
+                               }
+                               
+                               return $result;
+                       }
+                       
+                       $i++;
+               }
+               
+               return [];
+       }
 }