Merge branch '3.0'
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / acp / form / UserGroupOptionForm.class.php
CommitLineData
c9fba0a2
AE
1<?php
2namespace wcf\acp\form;
7a23a706 3use wcf\data\user\group\option\category\UserGroupOptionCategory;
c9fba0a2
AE
4use wcf\data\user\group\option\category\UserGroupOptionCategoryList;
5use wcf\data\user\group\option\UserGroupOption;
f1c1fc65 6use wcf\data\user\group\option\UserGroupOptionAction;
c9fba0a2
AE
7use wcf\data\user\group\UserGroup;
8use wcf\data\DatabaseObject;
264c6eea 9use wcf\form\AbstractForm;
c9fba0a2
AE
10use wcf\system\database\util\PreparedStatementConditionBuilder;
11use wcf\system\exception\IllegalLinkException;
12use wcf\system\exception\PermissionDeniedException;
13use wcf\system\exception\SystemException;
14use wcf\system\exception\UserInputException;
ace09b19 15use wcf\system\option\user\group\IUserGroupGroupOptionType;
eec1d83c 16use wcf\system\option\user\group\IUserGroupOptionType;
c9fba0a2
AE
17use wcf\system\WCF;
18
19/**
20 * Shows the user group option form to edit a single option.
21 *
22 * @author Alexander Ebert
c839bd49 23 * @copyright 2001-2018 WoltLab GmbH
c9fba0a2 24 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
e71525e4 25 * @package WoltLabSuite\Core\Acp\Form
c9fba0a2 26 */
264c6eea 27class UserGroupOptionForm extends AbstractForm {
c9fba0a2 28 /**
0fcfe5f6 29 * @inheritDoc
c9fba0a2
AE
30 */
31 public $activeMenuItem = 'wcf.acp.menu.link.group';
32
c9fba0a2
AE
33 /**
34 * list of parsed form elements per group
7a23a706 35 * @var string[]
c9fba0a2 36 */
058cbd6a 37 public $formElements = [];
c9fba0a2
AE
38
39 /**
40 * list of accessible groups
7a23a706 41 * @var UserGroup[]
c9fba0a2 42 */
058cbd6a 43 public $groups = [];
c9fba0a2 44
c9fba0a2 45 /**
0fcfe5f6 46 * @inheritDoc
c9fba0a2 47 */
058cbd6a 48 public $neededPermissions = ['admin.user.canEditGroup'];
c9fba0a2
AE
49
50 /**
51 * user group option type object
eec1d83c 52 * @var IUserGroupOptionType
c9fba0a2 53 */
eec1d83c 54 public $optionType;
c9fba0a2 55
5f46c4bc
AE
56 /**
57 * list of parent categories
7a23a706 58 * @var UserGroupOptionCategory[]
5f46c4bc 59 */
058cbd6a 60 public $parentCategories = [];
5f46c4bc 61
c9fba0a2
AE
62 /**
63 * list of values per user group
64 * @var array
65 */
058cbd6a 66 public $values = [];
c9fba0a2
AE
67
68 /**
69 * user group option object
4e25add7 70 * @var UserGroupOption
c9fba0a2 71 */
eec1d83c 72 public $userGroupOption;
c9fba0a2
AE
73
74 /**
75 * user group option id
76 * @var integer
77 */
78 public $userGroupOptionID = 0;
79
80 /**
0fcfe5f6 81 * @inheritDoc
c9fba0a2
AE
82 */
83 public function readParameters() {
84 parent::readParameters();
85
86 if (isset($_REQUEST['id'])) $this->userGroupOptionID = intval($_REQUEST['id']);
87 $this->userGroupOption = new UserGroupOption($this->userGroupOptionID);
88 if (!$this->userGroupOption) {
89 throw new IllegalLinkException();
90 }
91
92 // verify options and permissions for current option
c1b907f3 93 if ($this->userGroupOption->validateOptions() && $this->userGroupOption->validatePermissions()) {
c9fba0a2
AE
94 // read all categories
95 $categoryList = new UserGroupOptionCategoryList();
c9fba0a2
AE
96 $categoryList->readObjects();
97
058cbd6a 98 $categories = [];
c9fba0a2
AE
99 foreach ($categoryList as $category) {
100 $categories[$category->categoryName] = $category;
101 }
102
103 // verify categories
104 $category = $categories[$this->userGroupOption->categoryName];
105 while ($category != null) {
c1b907f3 106 if (!$category->validateOptions() || !$category->validatePermissions()) {
c9fba0a2
AE
107 throw new PermissionDeniedException();
108 }
109
5f46c4bc 110 array_unshift($this->parentCategories, $category);
c9fba0a2
AE
111 $category = ($category->parentCategoryName != '') ? $categories[$category->parentCategoryName] : null;
112 }
113 }
114 else {
115 throw new PermissionDeniedException();
116 }
117
417d067f
AE
118 // read accessible groups
119 $this->groups = UserGroup::getAccessibleGroups();
ae6b590f
MS
120 if ($this->userGroupOption->usersOnly) {
121 $guestGroup = UserGroup::getGroupByType(UserGroup::GUESTS);
122 if (isset($this->groups[$guestGroup->groupID])) {
123 unset($this->groups[$guestGroup->groupID]);
124 }
125 }
c9fba0a2
AE
126 if (empty($this->groups)) {
127 throw new PermissionDeniedException();
128 }
129
130 // get option type
131 $className = 'wcf\system\option\user\group\\'.ucfirst($this->userGroupOption->optionType).'UserGroupOptionType';
132 if (!class_exists($className)) {
133 throw new SystemException("Unable to find option type for '".$this->userGroupOption->optionType."'");
134 }
135 $this->optionType = new $className();
136 }
137
417d067f 138 /**
0fcfe5f6 139 * @inheritDoc
417d067f
AE
140 */
141 public function readFormParameters() {
142 parent::readFormParameters();
143
144 if (isset($_POST['values']) && is_array($_POST['values'])) $this->values = $_POST['values'];
145 }
146
c9fba0a2 147 /**
0fcfe5f6 148 * @inheritDoc
c9fba0a2
AE
149 */
150 public function validate() {
151 parent::validate();
152
0435e692
AE
153 $isAdmin = false;
154 foreach (WCF::getUser()->getGroupIDs() as $groupID) {
155 if (UserGroup::getGroupByID($groupID)->isAdminGroup()) {
156 $isAdmin = true;
157 break;
158 }
159 }
160
417d067f 161 // validate option values
2d4a1faf 162 foreach ($this->values as $groupID => &$optionValue) {
139fee8b 163 if (!isset($this->groups[$groupID])) {
417d067f 164 throw new PermissionDeniedException();
c9fba0a2
AE
165 }
166
2d4a1faf
MS
167 $optionValue = $this->optionType->getData($this->userGroupOption, $optionValue);
168
c9fba0a2
AE
169 try {
170 $this->optionType->validate($this->userGroupOption, $optionValue);
171 }
172 catch (UserInputException $e) {
4ba507d4 173 $this->errorType[$groupID] = $e->getType();
c9fba0a2 174 }
1c05b7e6 175
0435e692 176 if (!$isAdmin && $this->optionType->compare($optionValue, WCF::getSession()->getPermission($this->userGroupOption->optionName)) == 1) {
1c05b7e6
AE
177 $this->errorType[$groupID] = 'exceedsOwnPermission';
178 }
c9fba0a2
AE
179 }
180
417d067f
AE
181 // add missing values for option type 'boolean'
182 if ($this->userGroupOption->optionType == 'boolean') {
183 foreach ($this->groups as $groupID => $group) {
184 if (!isset($this->values[$groupID])) {
185 $this->values[$groupID] = 0;
186 }
187 }
188 }
6d39bd60
AE
189 else if ($this->userGroupOption->optionType == 'BBCodeSelect') {
190 foreach ($this->groups as $groupID => $group) {
191 if (!isset($this->values[$groupID])) {
192 $this->values[$groupID] = '';
193 }
194 }
195 }
417d067f 196
c9fba0a2
AE
197 if (!empty($this->errorType)) {
198 throw new UserInputException('optionValues', $this->errorType);
199 }
200 }
201
202 /**
0fcfe5f6 203 * @inheritDoc
c9fba0a2
AE
204 */
205 public function readData() {
206 parent::readData();
207
208 if (empty($_POST)) {
417d067f 209 // read values of accessible user groups
c9fba0a2 210 $conditions = new PreparedStatementConditionBuilder();
058cbd6a
MS
211 $conditions->add("groupID IN (?)", [array_keys($this->groups)]);
212 $conditions->add("optionID = ?", [$this->userGroupOption->optionID]);
c9fba0a2
AE
213
214 $sql = "SELECT groupID, optionValue
215 FROM wcf".WCF_N."_user_group_option_value
216 ".$conditions;
217 $statement = WCF::getDB()->prepareStatement($sql);
218 $statement->execute($conditions->getParameters());
0557bb04 219 $this->values = $statement->fetchMap('groupID', 'optionValue');
c9fba0a2
AE
220 }
221
c9fba0a2
AE
222 // create form elements for each group
223 foreach ($this->groups as $group) {
63b9817b 224 $optionValue = isset($this->values[$group->groupID]) ? $this->values[$group->groupID] : '';
ace09b19
AE
225 if ($this->optionType instanceof IUserGroupGroupOptionType) {
226 $this->optionType->setUserGroup($group);
227 }
228
c9fba0a2
AE
229 $this->formElements[$group->groupID] = $this->optionType->getFormElement($this->userGroupOption, $optionValue);
230 }
231 }
232
233 /**
0fcfe5f6 234 * @inheritDoc
c9fba0a2
AE
235 */
236 public function save() {
237 parent::save();
238
058cbd6a 239 $this->objectAction = new UserGroupOptionAction([$this->userGroupOption], 'updateValues', ['values' => $this->values]);
c9fba0a2
AE
240 $this->objectAction->executeAction();
241
242 // fire saved event
243 $this->saved();
244
245 WCF::getTPL()->assign('success', true);
246 }
247
248 /**
0fcfe5f6 249 * @inheritDoc
c9fba0a2
AE
250 */
251 public function assignVariables() {
252 parent::assignVariables();
253
3f891203 254 $everyoneGroupID = $guestGroupID = $userGroupID = 0;
eec1d83c 255 foreach ($this->groups as $group) {
3f891203
AE
256 if ($group->groupType == UserGroup::EVERYONE) {
257 $everyoneGroupID = $group->groupID;
258 }
259 else if ($group->groupType == UserGroup::GUESTS) {
eec1d83c 260 $guestGroupID = $group->groupID;
3f891203
AE
261 }
262 else if ($group->groupType == UserGroup::USERS) {
263 $userGroupID = $group->groupID;
eec1d83c
AE
264 }
265 }
266
058cbd6a 267 WCF::getTPL()->assign([
c9fba0a2 268 'formElements' => $this->formElements,
c9fba0a2 269 'groups' => $this->groups,
5f46c4bc 270 'parentCategories' => $this->parentCategories,
c9fba0a2 271 'userGroupOption' => $this->userGroupOption,
eec1d83c 272 'values' => $this->values,
3f891203
AE
273 'everyoneGroupID' => $everyoneGroupID,
274 'guestGroupID' => $guestGroupID,
275 'userGroupID' => $userGroupID
058cbd6a 276 ]);
c9fba0a2
AE
277 }
278
c9fba0a2
AE
279 /**
280 * Validates object options and permissions.
6e048dca 281 *
4e25add7 282 * @param DatabaseObject $object
c9fba0a2 283 * @return boolean
c1b907f3 284 *
e71525e4 285 * @deprecated 3.0
c9fba0a2
AE
286 */
287 protected function verifyPermissions(DatabaseObject $object) {
288 // check the options of this item
289 $hasEnabledOption = true;
290 if ($object->options) {
291 $hasEnabledOption = false;
292 $options = explode(',', strtoupper($object->options));
293 foreach ($options as $option) {
294 if (defined($option) && constant($option)) {
295 $hasEnabledOption = true;
296 break;
297 }
298 }
299 }
300 if (!$hasEnabledOption) return false;
9f959ced 301
c9fba0a2
AE
302 // check the permission of this item for the active user
303 $hasPermission = true;
304 if ($object->permissions) {
305 $hasPermission = false;
306 $permissions = explode(',', $object->permissions);
307 foreach ($permissions as $permission) {
308 if (WCF::getSession()->getPermission($permission)) {
309 $hasPermission = true;
310 break;
311 }
312 }
313 }
314 if (!$hasPermission) return false;
9f959ced 315
c9fba0a2
AE
316 return true;
317 }
318}