Option values are only saved, if they're better than the default value, previously only non-equal values were saved.
}
};
+/**
+ * Single-option handling for user group options.
+ *
+ * @param boolean canEditEveryone
+ */
+WCF.ACP.Options.Group = Class.extend({
+ /**
+ * true, if user can edit the 'Everyone' group
+ * @var boolean
+ */
+ _canEditEveryone: false,
+
+ /**
+ * Initializes the WCF.ACP.Options.Group class.
+ *
+ * @param boolean canEditEveryone
+ */
+ init: function(canEditEveryone) {
+ // disable 'Everyone' input
+ this._canEditEveryone = (canEditEveryone === true) ? true : false;
+ var $defaultValue = $('#defaultValueContainer').find('input, textarea').removeAttr('id').removeAttr('name');
+ if (!this._canEditEveryone) {
+ $defaultValue.attr('disabled', 'disabled');
+ }
+
+ // remove id and name-attribute from input elements
+ $('#otherValueContainer').find('input, textarea').removeAttr('id').removeAttr('name');
+
+ // bind event listener
+ $('#submitButton').click($.proxy(this._click, this));
+ },
+
+ /**
+ * Handles clicks on the submit button.
+ */
+ _click: function() {
+ var $values = { };
+
+ // collect default value
+ if (this._canEditEveryone) {
+ var $container = $('#defaultValueContainer > dl');
+ $values[$container.data('groupID')] = $container.find('textarea, input').val();
+ }
+
+ // collect values from other groups
+ $('#otherValueContainer > dl').each(function(index, container) {
+ var $container = $(container);
+
+ $values[$container.data('groupID')] = $container.find('textarea, input').val();
+ });
+
+ var $form = $('#defaultValueContainer').parent('form');
+ var $formSubmit = $form.children('.formSubmit');
+ for (var $groupID in $values) {
+ $('<input type="hidden" name="values[' + $groupID + ']" value="' + $values[$groupID] + '" />').appendTo($formSubmit);
+ }
+
+ // disable submit button
+ $('#submitButton').attr('disable', 'disable');
+
+ $form.submit();
+ }
+});
+
/**
* Worker support for ACP.
*
--- /dev/null
+{include file='header'}
+
+<script type="text/javascript">
+ //<![CDATA[
+ $(function() {
+ new WCF.ACP.Options.Group({@$userGroupOption->optionID}, {if $canEditEveryone}true{else}false{/if});
+ });
+ //]]>
+</script>
+
+<header class="boxHeadline">
+ <hgroup>
+ <h1>{lang}wcf.acp.group.option.editingOption{/lang} {lang}wcf.acp.group.option.{$userGroupOption->optionName}{/lang}</h1>
+ </hgroup>
+</header>
+
+<div class="contentNavigation"></div>
+
+<p class="info marginTop">{lang}wcf.acp.group.option.hint{/lang}</p>
+
+<form method="post" action="{link controller='UserGroupOption'}{/link}" class="marginTop">
+ <fieldset id="defaultValueContainer">
+ <legend>{lang}wcf.acp.group.option.defaultValue{/lang}</legend>
+
+ <dl data-group-id="{@$groupEveryone->groupID}">
+ <dt>{lang}{$groupEveryone->groupName}{/lang}</dt>
+ <dd>{@$defaultFormElement}</dd>
+ </dl>
+ </fieldset>
+
+ <fieldset id="otherValueContainer">
+ <legend>{lang}wcf.acp.group.option.other{/lang}</legend>
+
+ {foreach from=$groups item=group}
+ <dl data-group-id="{@$group->groupID}">
+ <dt>{lang}{$group->groupName}{/lang}</dt>
+ <dd>{@$formElements[$group->groupID]}</dd>
+ </dl>
+ {/foreach}
+ </fieldset>
+
+ <div class="formSubmit">
+ <input type="button" value="{lang}wcf.global.button.submit{/lang}" id="submitButton" />
+ <input type="hidden" name="id" value="{@$userGroupOption->optionID}" />
+ </div>
+</form>
+
+<div class="contentNavigation"></div>
+
+{include file='footer'}
$saveOptions = array();
foreach ($this->optionHandler->getCategoryOptions() as $option) {
$option = $option['object'];
- if ($optionValues[$option->optionID] != $defaultGroup->getGroupOption($option->optionName)) {
- $saveOptions[$option->optionID] = $optionValues[$option->optionID];
+ $defaultValue = $defaultGroup->getGroupOption($option->optionName);
+ $typeObject = $this->optionHandler->getTypeObject($option->optionType);
+
+ $newValue = $typeObject->merge($defaultValue, $optionValues[$option->optionID]);
+ if ($newValue !== null) {
+ $saveOptions[$option->optionID] = $newValue;
}
}
$defaultGroup = UserGroup::getGroupByType(UserGroup::EVERYONE);
foreach ($this->optionHandler->getCategoryOptions() as $option) {
$option = $option['object'];
- if ($optionValues[$option->optionID] != $defaultGroup->getGroupOption($option->optionName)) {
- $saveOptions[$option->optionID] = $optionValues[$option->optionID];
+ $defaultValue = $defaultGroup->getGroupOption($option->optionName);
+ $typeObject = $this->optionHandler->getTypeObject($option->optionType);
+
+ $newValue = $typeObject->merge($defaultValue, $optionValues[$option->optionID]);
+ if ($newValue !== null) {
+ $saveOptions[$option->optionID] = $newValue;
}
}
}
--- /dev/null
+<?php
+namespace wcf\acp\form;
+use wcf\data\user\group\option\UserGroupOptionAction;
+
+use wcf\data\user\group\option\category\UserGroupOptionCategoryList;
+use wcf\data\user\group\option\UserGroupOption;
+use wcf\data\user\group\UserGroup;
+use wcf\data\DatabaseObject;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
+use wcf\system\exception\IllegalLinkException;
+use wcf\system\exception\PermissionDeniedException;
+use wcf\system\exception\SystemException;
+use wcf\system\exception\UserInputException;
+use wcf\system\package\PackageDependencyHandler;
+use wcf\system\WCF;
+
+/**
+ * Shows the user group option form to edit a single option.
+ *
+ * @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 acp.form
+ * @category Community Framework
+ */
+class UserGroupOptionForm extends ACPForm {
+ /**
+ * @see wcf\acp\form\ACPForm::$activeMenuItem
+ */
+ public $activeMenuItem = 'wcf.acp.menu.link.group';
+
+ /**
+ * true, if user can edit the 'everyone' group
+ * @var boolean
+ */
+ public $canEditEveryone = false;
+
+ /**
+ * form element for default value
+ * @var string
+ */
+ public $defaultFormElement = '';
+
+ /**
+ * default value for every group
+ * @var mixed
+ */
+ public $defaultValue = null;
+
+ /**
+ * list of parsed form elements per group
+ * @var array<string>
+ */
+ public $formElements = array();
+
+ /**
+ * list of accessible groups
+ * @var array<wcf\data\user\group\UserGroup>
+ */
+ public $groups = array();
+
+ /**
+ * 'Everyone' user group object
+ * @var wcf\data\user\group\UserGroup
+ */
+ public $groupEveryone = null;
+
+ /**
+ * @see wcf\page\AbstractPage::$neededPermissions
+ */
+ public $neededPermissions = array('admin.user.canEditGroup');
+
+ /**
+ * user group option type object
+ * @var wcf\system\option\user\group\IUserGroupOptionType
+ */
+ public $optionType = null;
+
+ /**
+ * list of values per user group
+ * @var array
+ */
+ public $values = array();
+
+ /**
+ * user group option object
+ * @var wcf\data\user\group\option\UserGroupOption
+ */
+ public $userGroupOption = null;
+
+ /**
+ * user group option id
+ * @var integer
+ */
+ public $userGroupOptionID = 0;
+
+ /**
+ * @see wcf\page\IPage::readParameters()
+ */
+ public function readParameters() {
+ parent::readParameters();
+
+ if (isset($_REQUEST['id'])) $this->userGroupOptionID = intval($_REQUEST['id']);
+ $this->userGroupOption = new UserGroupOption($this->userGroupOptionID);
+ if (!$this->userGroupOption) {
+ throw new IllegalLinkException();
+ }
+
+ // verify options and permissions for current option
+ $dependencies = PackageDependencyHandler::getInstance()->getDependencies();
+ if ($this->verifyPermissions($this->userGroupOption) && in_array($this->userGroupOption->packageID, $dependencies)) {
+ // read all categories
+ $categoryList = new UserGroupOptionCategoryList();
+ $categoryList->getConditionBuilder()->add("packageID IN (?)", array($dependencies));
+ $categoryList->sqlLimit = 0;
+ $categoryList->readObjects();
+
+ $categories = array();
+ foreach ($categoryList as $category) {
+ $categories[$category->categoryName] = $category;
+ }
+
+ // verify categories
+ $category = $categories[$this->userGroupOption->categoryName];
+ while ($category != null) {
+ if (!$this->verifyPermissions($category)) {
+ throw new PermissionDeniedException();
+ }
+
+ $category = ($category->parentCategoryName != '') ? $categories[$category->parentCategoryName] : null;
+ }
+ }
+ else {
+ throw new PermissionDeniedException();
+ }
+
+ // validate accessible groups
+ $this->readAccessibleGroups();
+ if (empty($this->groups)) {
+ throw new PermissionDeniedException();
+ }
+
+ // get option type
+ $className = 'wcf\system\option\user\group\\'.ucfirst($this->userGroupOption->optionType).'UserGroupOptionType';
+ if (!class_exists($className)) {
+ throw new SystemException("Unable to find option type for '".$this->userGroupOption->optionType."'");
+ }
+ $this->optionType = new $className();
+ }
+
+ /**
+ * @see wcf\form\IForm::validate()
+ */
+ public function validate() {
+ parent::validate();
+
+ if (isset($_POST['values']) && is_array($_POST['values'])) $this->values = $_POST['values'];
+ if (empty($this->values)) {
+ throw new IllegalLinkException();
+ }
+
+ if (!$this->canEditEveryone) {
+ $sql = "SELECT optionValue
+ FROM wcf".WCF_N."_user_group_option_value
+ WHERE optionID = ?
+ AND groupID = ?";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute(array(
+ $this->userGroupOption->optionID,
+ $this->groupEveryone->groupID
+ ));
+ $row = $statement->fetchArray();
+ $defaultValue = $row['optionValue'];
+ }
+ else {
+ if (!isset($this->values[$this->groupEveryone->groupID])) {
+ throw new IllegalLinkException();
+ }
+
+ $defaultValue = $this->values[$this->groupEveryone->groupID];
+ }
+
+ foreach ($this->values as $groupID => $optionValue) {
+ if (!isset($this->groups[$groupID]) || (!$this->canEditEveryone && $groupID == $this->groupEveryone->groupID)) {
+ throw new PermissionDeniedException();
+ }
+
+ try {
+ $this->optionType->validate($this->userGroupOption, $optionValue);
+ }
+ catch (UserInputException $e) {
+ $this->errorType[$e->getField()] = $e->getType();
+ }
+
+ // check if not editing default value
+ if ($groupID != $this->groupEveryone->groupID) {
+ $newValue = $this->optionType->merge($defaultValue, $optionValue);
+ if ($newValue === null) {
+ unset($this->values[$groupID]);
+ }
+ else {
+ $this->values[$groupID] = $newValue;
+ }
+ }
+ }
+
+ if (!empty($this->errorType)) {
+ throw new UserInputException('optionValues', $this->errorType);
+ }
+ }
+
+ /**
+ * @see wcf\page\IPage::readData()
+ */
+ public function readData() {
+ parent::readData();
+
+ if (empty($_POST)) {
+ // read values for accessible user groups
+ $groupIDs = array_merge(array_keys($this->groups), array($this->groupEveryone->groupID));
+
+ $conditions = new PreparedStatementConditionBuilder();
+ $conditions->add("groupID IN (?)", array($groupIDs));
+ $conditions->add("optionID = ?", array($this->userGroupOption->optionID));
+
+ $sql = "SELECT groupID, optionValue
+ FROM wcf".WCF_N."_user_group_option_value
+ ".$conditions;
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute($conditions->getParameters());
+ while ($row = $statement->fetchArray()) {
+ // exclude default value from $values
+ if ($row['groupID'] == $this->groupEveryone->groupID) {
+ $this->defaultValue = $row['optionValue'];
+ continue;
+ }
+
+ $this->values[$row['groupID']] = $row['optionValue'];
+ }
+ }
+
+ // create form element for default group
+ $this->defaultFormElement = $this->optionType->getFormElement($this->userGroupOption, $this->defaultValue);
+
+ // create form elements for each group
+ foreach ($this->groups as $group) {
+ $optionValue = (isset($this->values[$group->groupID])) ? $this->values[$group->groupID] : $this->defaultValue;
+ $this->formElements[$group->groupID] = $this->optionType->getFormElement($this->userGroupOption, $optionValue);
+ }
+ }
+
+ /**
+ * @see wcf\form\IForm::save()
+ */
+ public function save() {
+ parent::save();
+
+ $this->objectAction = new UserGroupOptionAction(array($this->userGroupOption), 'updateValues', array('values' => $this->values));
+ $this->objectAction->executeAction();
+
+ // fire saved event
+ $this->saved();
+
+ WCF::getTPL()->assign('success', true);
+ }
+
+ /**
+ * @see wcf\page\IPage::assignVariables()
+ */
+ public function assignVariables() {
+ parent::assignVariables();
+
+ WCF::getTPL()->assign(array(
+ 'canEditEveryone' => $this->canEditEveryone,
+ 'defaultFormElement' => $this->defaultFormElement,
+ 'defaultValue' => $this->defaultValue,
+ 'formElements' => $this->formElements,
+ 'groupEveryone' => $this->groupEveryone,
+ 'groups' => $this->groups,
+ 'userGroupOption' => $this->userGroupOption,
+ 'values' => $this->values
+ ));
+ }
+
+ /**
+ * Reads accessible user groups.
+ */
+ protected function readAccessibleGroups() {
+ $this->groups = UserGroup::getAccessibleGroups();
+ $this->canEditEveryone = false;
+ foreach ($this->groups as $groupID => $group) {
+ if ($group->groupType == UserGroup::EVERYONE) {
+ $this->canEditEveryone = true;
+
+ // remove 'Everyone' from groups
+ $this->groupEveryone = $group;
+ unset($this->groups[$groupID]);
+ }
+ }
+
+ // add 'Everyone' group
+ if (!$this->canEditEveryone) {
+ $this->groupEveryone = UserGroup::getGroupByType(UserGroup::EVERYONE);
+ }
+ }
+
+ /**
+ * Validates object options and permissions.
+ *
+ * @param wcf\data\DatabaseObject $object
+ * @return boolean
+ */
+ protected function verifyPermissions(DatabaseObject $object) {
+ // check the options of this item
+ $hasEnabledOption = true;
+ if ($object->options) {
+ $hasEnabledOption = false;
+ $options = explode(',', strtoupper($object->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 ($object->permissions) {
+ $hasPermission = false;
+ $permissions = explode(',', $object->permissions);
+ foreach ($permissions as $permission) {
+ if (WCF::getSession()->getPermission($permission)) {
+ $hasPermission = true;
+ break;
+ }
+ }
+ }
+ if (!$hasPermission) return false;
+
+ return true;
+ }
+}
<?php
namespace wcf\data\user\group\option;
use wcf\data\AbstractDatabaseObjectAction;
+use wcf\system\WCF;
/**
* Executes user group option-related actions.
* @see wcf\data\AbstractDatabaseObjectAction::$className
*/
protected $className = 'wcf\data\user\group\option\UserGroupOptionEditor';
+
+ /**
+ * Updates option values for given option id.
+ */
+ public function updateValue() {
+ $option = current($this->objects);
+
+ // remove old values
+ $sql = "DELETE FROM wcf".WCF_N."_user_group_option_value
+ WHERE optionID = ?";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute(array(
+ $option->optionID
+ ));
+
+ if (!empty($this->parameters['values'])) {
+ $sql = "INSERT INTO wcf".WCF_N."_user_group_option_value
+ (optionID, groupID, optionValue)
+ VALUES (?, ?, ?)";
+ $statement = WCF::getDB()->prepareStatement($sql);
+
+ WCF::getDB()->beginTransaction();
+ foreach ($this->parameters['values'] as $groupID => $optionValue) {
+ $statement->execute(array(
+ $option->optionID,
+ $groupID,
+ $optionValue
+ ));
+ }
+ WCF::getDB()->commitTransaction();
+ }
+ }
}
* The merge of option values returns true, if at least one value is true. Otherwise false.
*
* @author Marcel Werk
- * @copyright 2001-2011 WoltLab GmbH
+ * @copyright 2001-2012 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package com.woltlab.wcf
* @subpackage system.option.user.group
/**
* @see wcf\system\option\user\group\IUserGroupOptionType::merge()
*/
- public function merge(array $values) {
- foreach ($values as $value) {
- if ($value) return true;
+ public function merge($defaultValue, $groupValue) {
+ // don't save if values are equal or $defaultValue is better
+ if ($defaultValue == $groupValue || $defaultValue && !$groupValue) {
+ return null;
}
-
- return false;
+
+ return $groupValue;
}
}
* The merge of option values returns the highest value.
*
* @author Tim Düsterhus
- * @copyright 2011 Tim Düsterhus
+ * @copyright 2001-2012 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package com.woltlab.wcf
* @subpackage system.option.user.group
/**
* @see wcf\system\option\user.group\IUserGroupOptionType::merge()
*/
- public function merge(array $values) {
- return max($values);
+ public function merge($defaultValue, $groupValue) {
+ if ($groupValue > $defaultValue) {
+ return $groupValue;
+ }
+
+ return null;
}
}
*/
interface IUserGroupOptionType extends IOptionType {
/**
- * Merges the different values of an option to a single value.
+ * Returns the value which results by merging or null if nothing should be saved.
*
- * @param array $values
+ * @param mixed $defaultValue
+ * @param mixed $groupValue
* @return mixed
*/
- public function merge(array $values);
+ public function merge($defaultValue, $groupValue);
}
* it returns the highest value.
*
* @author Marcel Werk
- * @copyright 2001-2011 WoltLab GmbH
+ * @copyright 2001-2012 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package com.woltlab.wcf
* @subpackage system.option.user.group
/**
* @see wcf\system\option\user\group\IUserGroupOptionType::merge()
*/
- public function merge(array $values) {
- if (in_array(-1, $values)) return -1;
- return parent::merge($values);
+ public function merge($defaultValue, $groupValue) {
+ if ($defaultValue == -1) {
+ return null;
+ }
+ else if ($groupValue == -1) {
+ return $groupValue;
+ }
+ else {
+ return parent::merge($defaultValue, $groupValue);
+ }
}
}
* The merge of option values returns -1 if all values are -1 otherwise the lowest value.
*
* @author Marcel Werk
- * @copyright 2001-2011 WoltLab GmbH
+ * @copyright 2001-2012 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package com.woltlab.wcf
* @subpackage system.option.user.group
/**
* @see wcf\system\option\user\group\IUserGroupOptionType::merge()
*/
- public function merge(array $values) {
- foreach ($values as $key => $value) {
- if ($value == -1) unset($values[$key]);
+ public function merge($defaultValue, $groupValue) {
+ if (($defaultValue == -1 && $groupValue == -1) || ($defaultValue == $groupValue)) {
+ return null;
}
- if (count($values) == 0) return -1;
- return min($values);
+ return min($defaultValue, $groupValue);
}
}
* The merge of option values returns the highest value.
*
* @author Marcel Werk
- * @copyright 2001-2011 WoltLab GmbH
+ * @copyright 2001-2012 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package com.woltlab.wcf
* @subpackage system.option.user.group
/**
* @see wcf\system\option\user.group\IUserGroupOptionType::merge()
*/
- public function merge(array $values) {
- return max($values);
+ public function merge($defaultValue, $groupValue) {
+ if ($groupValue > $defaultValue) {
+ return $groupValue;
+ }
+
+ return null;
}
}
* The merge of option values returns the lowest value.
*
* @author Marcel Werk
- * @copyright 2001-2011 WoltLab GmbH
+ * @copyright 2001-2012 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package com.woltlab.wcf
* @subpackage system.option.user.group
/**
* @see wcf\system\option\user\group\IUserGroupOptionType::merge()
*/
- public function merge(array $values) {
- return min($values);
+ public function merge($defaultValue, $groupValue) {
+ if ($defaultValue < $groupValue) {
+ return null;
+ }
+
+ return $groupValue;
}
}
<?php
namespace wcf\system\option\user\group;
use wcf\system\option\TextOptionType;
+use wcf\util\StringUtil;
/**
* TextUserGroupOptionType is an implementation of IUserGroupOptionType for text values.
/**
* @see wcf\system\option\user\group\IUserGroupOptionType::merge()
*/
- public function merge(array $values) {
- $result = '';
+ public function merge($defaultValue, $groupValue) {
+ $defaultValue = explode("\n", StringUtil::unifyNewlines($defaultValue));
+ $groupValue = explode("\n", StringUtil::unifyNewlines($groupValue));
- foreach ($values as $value) {
- if (!empty($result)) $result .= "\n";
- $result .= $value;
+ $result = array_diff($groupValue, $defaultValue);
+ if (empty($result)) {
+ return null;
}
-
- return $result;
+
+ return implode("\n", $result);
}
}
<?php
namespace wcf\system\option\user\group;
use wcf\system\option\TextareaOptionType;
+use wcf\util\StringUtil;
/**
* TextareaUserGroupOptionType is an implementation of IUserGroupOptionType for
/**
* @see wcf\system\option\user\group\IUserGroupOptionType::merge()
*/
- public function merge(array $values) {
- $result = '';
-
- foreach ($values as $value) {
- if (!empty($result)) $result .= "\n";
- $result .= $value;
+ public function merge($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 $result;
+
+ return implode("\n", $result);
}
}
/**
* @see wcf\system\option\user\group\IUserGroupOptionType::merge()
*/
- public function merge(array $values) {
- $result = array();
- foreach ($values as $value) {
- $value = explode(',', $value);
- $result = array_merge($result, $value);
+ public function merge($defaultValue, $groupValue) {
+ $defaultValue = explode(',', $defaultValue);
+ $groupValue = explode(',', $groupValue);
+
+ $result = array_diff($groupValue, $defaultValue);
+ if (empty($result)) {
+ return null;
}
- $result = array_unique($result);
-
return implode(',', $result);
}
}