This fix is relevant for user group option types that can have a list of values (e.g. list of usable attachments). In the database, only the difference between the default value and the user group's value is stored. This difference is calculated by `IUserGroupOptionType::diff()`. When the permissions for a certain type of user groups are calculated, the difference for all relevant user groups have to be merged, which is done by `IUserGroupOptionType::merge()`.
The code of the previous merge function is the same as the code of the new diff function. This worked fine when calculating the difference to store the values. But if the merge of two option values was calculated during the permission calculation for a certain type of user groups, again, the difference was calculated, not the merge. This had the effect, that if, for instance, the default value for the usable attachment types was "gif, jpg" and the value for the administrator group was "foo, jpg", administrators were only allowed to use "foo" attachments (which is the diff of the two) instead of "foo", "gif" and "jpg".
$defaultValue = $defaultGroup->getGroupOption($option->optionName);
$typeObject = $this->optionHandler->getTypeObject($option->optionType);
- $newValue = $typeObject->merge($defaultValue, $optionValues[$option->optionID]);
+ $newValue = $typeObject->diff($defaultValue, $optionValues[$option->optionID]);
if ($newValue !== null) {
$saveOptions[$option->optionID] = $newValue;
}
$defaultValue = $defaultGroup->getGroupOption($option->optionName);
$typeObject = $this->optionHandler->getTypeObject($option->optionType);
- $newValue = $typeObject->merge($defaultValue, $optionValues[$option->optionID]);
+ $newValue = $typeObject->diff($defaultValue, $optionValues[$option->optionID]);
if ($newValue !== null) {
$saveOptions[$option->optionID] = $newValue;
}
// check if not editing default value
if ($groupID != $this->groupEveryone->groupID) {
- $newValue = $this->optionType->merge($this->defaultValue, $optionValue);
+ $newValue = $this->optionType->diff($this->defaultValue, $optionValue);
if ($newValue === null) {
unset($this->values[$groupID]);
}
* User group option type implementation for boolean values.
*
* The merge of option values returns true, if at least one value is true.
- *
+ *
* @author Marcel Werk
* @copyright 2001-2012 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @category Community Framework
*/
class BooleanUserGroupOptionType extends BooleanOptionType implements IUserGroupOptionType {
+ /**
+ * @see wcf\system\option\user\group\IUserGroupOptionType::diff()
+ */
+ public function diff($defaultValue, $groupValue) {
+ return $this->merge($defaultValue, $groupValue);
+ }
+
/**
* @see wcf\system\option\user\group\IUserGroupOptionType::merge()
*/
* @category Community Framework
*/
class FileSizeUserGroupOptionType extends FileSizeOptionType implements IUserGroupOptionType {
+ /**
+ * @see wcf\system\option\user\group\IUserGroupOptionType::diff()
+ */
+ public function diff($defaultValue, $groupValue) {
+ return $this->merge($defaultValue, $groupValue);
+ }
+
/**
* @see wcf\system\option\user.group\IUserGroupOptionType::merge()
*/
* @category Community Framework
*/
interface IUserGroupOptionType extends IOptionType {
+ /**
+ * Returns the value which results by calculating the difference of the
+ * given values.
+ *
+ * @param mixed $defaultValue
+ * @param mixed $groupValue
+ * @return mixed
+ */
+ public function diff($defaultValue, $groupValue);
+
/**
* Returns the value which results by merging or null if nothing should be saved.
*
* @category Community Framework
*/
class InfiniteIntegerUserGroupOptionType extends IntegerUserGroupOptionType {
+ /**
+ * @see wcf\system\option\user\group\IUserGroupOptionType::diff()
+ */
+ public function diff($defaultValue, $groupValue) {
+ return $this->merge($defaultValue, $groupValue);
+ }
+
/**
* @see wcf\system\option\user\group\IUserGroupOptionType::merge()
*/
* @category Community Framework
*/
class InfiniteInverseIntegerUserGroupOptionType extends InverseIntegerUserGroupOptionType {
+ /**
+ * @see wcf\system\option\user\group\IUserGroupOptionType::diff()
+ */
+ public function diff($defaultValue, $groupValue) {
+ return $this->merge($defaultValue, $groupValue);
+ }
+
/**
* @see wcf\system\option\user\group\IUserGroupOptionType::merge()
*/
* @category Community Framework
*/
class IntegerUserGroupOptionType extends IntegerOptionType implements IUserGroupOptionType {
+ /**
+ * @see wcf\system\option\user\group\IUserGroupOptionType::diff()
+ */
+ public function diff($defaultValue, $groupValue) {
+ return $this->merge($defaultValue, $groupValue);
+ }
+
/**
* @see wcf\system\option\user.group\IUserGroupOptionType::merge()
*/
* @category Community Framework
*/
class InverseIntegerUserGroupOptionType extends IntegerOptionType implements IUserGroupOptionType {
+ /**
+ * @see wcf\system\option\user\group\IUserGroupOptionType::diff()
+ */
+ public function diff($defaultValue, $groupValue) {
+ return $this->merge($defaultValue, $groupValue);
+ }
+
/**
* @see wcf\system\option\user\group\IUserGroupOptionType::merge()
*/
* @package com.woltlab.wcf
* @subpackage system.option.user.group
* @category Community Framework
+ *
+ * @todo text options types can't have line breaks, why use them to split
+ * values? what to do?
*/
class TextUserGroupOptionType extends TextOptionType implements IUserGroupOptionType {
/**
- * @see wcf\system\option\user\group\IUserGroupOptionType::merge()
+ * @see wcf\system\option\user\group\IUserGroupOptionType::diff()
*/
- public function merge($defaultValue, $groupValue) {
+ public function diff($defaultValue, $groupValue) {
$defaultValue = explode("\n", StringUtil::unifyNewlines($defaultValue));
$groupValue = explode("\n", StringUtil::unifyNewlines($groupValue));
return implode("\n", $result);
}
+
+ /**
+ * @see wcf\system\option\user\group\IUserGroupOptionType::merge()
+ */
+ public function merge($defaultValue, $groupValue) {
+ $defaultValue = empty($defaultValue) ? array() : explode("\n", StringUtil::unifyNewlines($defaultValue));
+ $groupValue = empty($groupValue) ? array() : explode("\n", StringUtil::unifyNewlines($groupValue));
+
+ return implode("\n", array_unique(array_merge($defaultValue, $groupValue)));
+ }
}
*/
class TextareaUserGroupOptionType extends TextareaOptionType implements IUserGroupOptionType {
/**
- * @see wcf\system\option\user\group\IUserGroupOptionType::merge()
+ * @see wcf\system\option\user\group\IUserGroupOptionType::diff()
*/
- public function merge($defaultValue, $groupValue) {
+ public function diff($defaultValue, $groupValue) {
$defaultValue = explode("\n", StringUtil::unifyNewlines($defaultValue));
$groupValue = explode("\n", StringUtil::unifyNewlines($groupValue));
-
+
$result = array_diff($groupValue, $defaultValue);
if (empty($result)) {
return null;
}
-
+
return implode("\n", $result);
}
+
+ /**
+ * @see wcf\system\option\user\group\IUserGroupOptionType::merge()
+ */
+ public function merge($defaultValue, $groupValue) {
+ $defaultValue = empty($defaultValue) ? array() : explode("\n", StringUtil::unifyNewlines($defaultValue));
+ $groupValue = empty($groupValue) ? array() : explode("\n", StringUtil::unifyNewlines($groupValue));
+
+ return implode("\n", array_unique(array_merge($defaultValue, $groupValue)));
+ }
}
}
/**
- * @see wcf\system\option\user\group\IUserGroupOptionType::merge()
+ * @see wcf\system\option\user\group\IUserGroupOptionType::diff()
*/
- public function merge($defaultValue, $groupValue) {
+ public function diff($defaultValue, $groupValue) {
$defaultValue = explode(',', $defaultValue);
$groupValue = explode(',', $groupValue);
return implode(',', $result);
}
+
+ /**
+ * @see wcf\system\option\user\group\IUserGroupOptionType::merge()
+ */
+ public function merge($defaultValue, $groupValue) {
+ $defaultValue = empty($defaultValue) ? array() : explode(',', StringUtil::unifyNewlines($defaultValue));
+ $groupValue = empty($groupValue) ? array() : explode(',', StringUtil::unifyNewlines($groupValue));
+
+ return implode(',', array_unique(array_merge($defaultValue, $groupValue)));
+ }
}