Merge remote-tracking branch 'origin/6.0'
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / data / user / ignore / UserIgnoreAction.class.php
CommitLineData
320f4a6d 1<?php
a9229942 2
320f4a6d 3namespace wcf\data\user\ignore;
a9229942
TD
4
5use wcf\data\AbstractDatabaseObjectAction;
013abaff
AE
6use wcf\data\user\follow\UserFollow;
7use wcf\data\user\follow\UserFollowEditor;
a8c5936e 8use wcf\system\cache\runtime\UserProfileRuntimeCache;
320f4a6d
MW
9use wcf\system\exception\IllegalLinkException;
10use wcf\system\exception\PermissionDeniedException;
11use wcf\system\exception\UserInputException;
10bc76ec
TD
12use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
13use wcf\system\form\builder\DialogFormDocument;
14use wcf\system\form\builder\field\RadioButtonFormField;
15use wcf\system\form\builder\field\validation\FormFieldValidationError;
16use wcf\system\form\builder\field\validation\FormFieldValidator;
17use wcf\system\form\builder\IFormDocument;
320f4a6d
MW
18use wcf\system\user\storage\UserStorageHandler;
19use wcf\system\WCF;
20
21/**
22 * Executes ignored user-related actions.
a9229942
TD
23 *
24 * @author Alexander Ebert
25 * @copyright 2001-2019 WoltLab GmbH
26 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
a9229942
TD
27 *
28 * @method UserIgnore create()
29 * @method UserIgnoreEditor[] getObjects()
30 * @method UserIgnoreEditor getSingleObject()
320f4a6d 31 */
a9229942
TD
32class UserIgnoreAction extends AbstractDatabaseObjectAction
33{
10bc76ec
TD
34 protected $form;
35
a9229942
TD
36 /**
37 * Validates the 'ignore' action.
38 */
39 public function validateIgnore()
40 {
41 $this->readInteger('userID', false, 'data');
42
43 $userProfile = UserProfileRuntimeCache::getInstance()->getObject($this->parameters['data']['userID']);
44 if ($userProfile === null || $userProfile->userID == WCF::getUser()->userID) {
45 throw new IllegalLinkException();
46 }
47
48 // check permissions
49 if ($userProfile->getPermission('user.profile.cannotBeIgnored')) {
50 throw new PermissionDeniedException();
51 }
10bc76ec
TD
52
53 $this->readInteger('type', true, 'data');
54
55 if (
56 $this->parameters['data']['type']
57 && !\in_array($this->parameters['data']['type'], [
58 UserIgnore::TYPE_BLOCK_DIRECT_CONTACT,
59 UserIgnore::TYPE_HIDE_MESSAGES,
60 ])
61 ) {
62 throw new UserInputException('type', 'invalid');
63 }
a9229942
TD
64 }
65
66 /**
67 * Ignores a user.
68 *
69 * @return array
70 */
71 public function ignore()
72 {
10bc76ec
TD
73 $ignore = new UserIgnoreEditor(UserIgnore::getIgnore($this->parameters['data']['userID']));
74 $type = $this->parameters['data']['type'] ?? UserIgnore::TYPE_BLOCK_DIRECT_CONTACT;
75
76 if ($ignore->ignoreID) {
77 $ignore->update([
78 'type' => $type,
79 'time' => TIME_NOW,
80 ]);
81 } else {
82 $ignore = UserIgnoreEditor::createOrIgnore([
83 'ignoreUserID' => $this->parameters['data']['userID'],
84 'type' => $type,
85 'time' => TIME_NOW,
86 'userID' => WCF::getUser()->userID,
87 ]);
88 }
a9229942
TD
89
90 if ($ignore !== null) {
91 UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'ignoredUserIDs');
92 UserStorageHandler::getInstance()->reset([$this->parameters['data']['userID']], 'ignoredByUserIDs');
93
94 // check if target user is following the current user
95 $sql = "SELECT *
96 FROM wcf" . WCF_N . "_user_follow
97 WHERE userID = ?
98 AND followUserID = ?";
99 $statement = WCF::getDB()->prepareStatement($sql);
100 $statement->execute([
101 $this->parameters['data']['userID'],
102 WCF::getUser()->userID,
103 ]);
104
105 $follow = $statement->fetchObject(UserFollow::class);
106
107 // remove follower
108 if ($follow !== null) {
109 $followEditor = new UserFollowEditor($follow);
110 $followEditor->delete();
111
112 // reset storage
113 UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'followerUserIDs');
114 UserStorageHandler::getInstance()->reset([$this->parameters['data']['userID']], 'followingUserIDs');
115 }
116 }
117
118 return ['isIgnoredUser' => 1];
119 }
120
121 /**
122 * Validates the 'unignore' action.
123 */
124 public function validateUnignore()
125 {
126 $this->readInteger('userID', false, 'data');
127
128 $userProfile = UserProfileRuntimeCache::getInstance()->getObject($this->parameters['data']['userID']);
129 if ($userProfile === null) {
130 throw new IllegalLinkException();
131 }
132 }
133
134 /**
135 * Unignores a user.
136 *
137 * @return array
138 */
139 public function unignore()
140 {
141 $ignore = UserIgnore::getIgnore($this->parameters['data']['userID']);
142
143 if ($ignore->ignoreID) {
144 $ignoreEditor = new UserIgnoreEditor($ignore);
145 $ignoreEditor->delete();
146
147 UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'ignoredUserIDs');
2571bf19 148 UserStorageHandler::getInstance()->reset([$this->parameters['data']['userID']], 'ignoredByUserIDs');
a9229942
TD
149 }
150
151 return ['isIgnoredUser' => 0];
152 }
153
10bc76ec
TD
154 public function validateGetDialog()
155 {
156 $this->readInteger('userID');
157
158 $userProfile = UserProfileRuntimeCache::getInstance()->getObject($this->parameters['userID']);
159 if ($userProfile === null || $userProfile->userID == WCF::getUser()->userID) {
160 throw new IllegalLinkException();
161 }
162
163 $ignore = UserIgnore::getIgnore($this->parameters['userID']);
164
165 // Check if the user is not yet ignored and cannot be ignored.
166 if (!$ignore && $userProfile->getPermission('user.profile.cannotBeIgnored')) {
167 throw new PermissionDeniedException();
168 }
169 }
170
171 public function getDialog()
172 {
173 $form = $this->getForm();
174
175 return [
176 'dialog' => $form->getHtml(),
177 'formId' => $form->getId(),
178 ];
179 }
180
181 public function validateSubmitDialog()
182 {
183 $this->validateGetDialog();
184
185 $this->readString('formId');
186
187 $this->getForm()->requestData($this->parameters['data'] ?? []);
188 $this->getForm()->readValues();
3c547b52 189 $this->getForm()->validate();
10bc76ec
TD
190 }
191
192 public function submitDialog()
193 {
10bc76ec
TD
194 if ($this->getForm()->hasValidationErrors()) {
195 return [
196 'dialog' => $this->getForm()->getHtml(),
197 'formId' => $this->getForm()->getId(),
198 ];
199 }
200
201 $formData = $this->getForm()->getData();
202
203 if ($formData['data']['type'] === UserIgnore::TYPE_NO_IGNORE) {
204 return (new self([], 'unignore', [
205 'data' => [
206 'userID' => $this->parameters['userID'],
207 ],
208 ]))->executeAction()['returnValues'];
209 } else {
210 return (new self([], 'ignore', [
211 'data' => [
212 'userID' => $this->parameters['userID'],
213 'type' => $formData['data']['type'],
214 ],
215 ]))->executeAction()['returnValues'];
216 }
217 }
218
219 protected function getForm(): IFormDocument
220 {
221 if ($this->form === null) {
222 $id = 'userIgnore';
223 $this->form = DialogFormDocument::create($id)
224 ->ajax()
225 ->prefix($id);
226
227 $ignore = UserIgnore::getIgnore($this->parameters['userID']);
228
229 $this->form->appendChildren([
230 RadioButtonFormField::create('type')
231 ->label(WCF::getLanguage()->get('wcf.user.ignore.type'))
232 ->options([
233 UserIgnore::TYPE_NO_IGNORE => WCF::getLanguage()
234 ->get('wcf.user.ignore.type.noIgnore'),
235 UserIgnore::TYPE_BLOCK_DIRECT_CONTACT => WCF::getLanguage()
236 ->get('wcf.user.ignore.type.blockDirectContact'),
237 UserIgnore::TYPE_HIDE_MESSAGES => WCF::getLanguage()
238 ->get('wcf.user.ignore.type.hideMessages'),
239 ])
240 ->value($ignore->type ?: 0)
241 ->addValidator(new FormFieldValidator('type', function (RadioButtonFormField $formField) {
242 $userProfile = UserProfileRuntimeCache::getInstance()->getObject($this->parameters['userID']);
243 if ($userProfile->getPermission('user.profile.cannotBeIgnored')) {
244 if ($formField->getValue() != UserIgnore::TYPE_NO_IGNORE) {
245 $formField->addValidationError(
246 new FormFieldValidationError(
247 'cannotBeIgnored',
248 'wcf.user.ignore.error.cannotBeIgnored'
249 )
250 );
251 }
252 }
253 })),
254 ]);
255
256 $this->form->getDataHandler()->addProcessor(
257 new CustomFormDataProcessor(
258 'type',
259 static function (IFormDocument $document, array $parameters) {
260 $parameters['data']['type'] = \intval($parameters['data']['type']);
261
262 return $parameters;
263 }
264 )
265 );
266
267 $this->form->build();
268 }
269
270 return $this->form;
271 }
272
a9229942
TD
273 /**
274 * @inheritDoc
275 */
276 public function validateDelete()
277 {
278 // read objects
279 if (empty($this->objects)) {
280 $this->readObjects();
281
282 if (empty($this->objects)) {
283 throw new UserInputException('objectIDs');
284 }
285 }
286
287 // validate ownership
288 foreach ($this->getObjects() as $ignore) {
289 if ($ignore->userID != WCF::getUser()->userID) {
290 throw new PermissionDeniedException();
291 }
292 }
293 }
294
295 /**
296 * @inheritDoc
297 */
298 public function delete()
299 {
2571bf19
C
300 $userIDs = \array_map(function ($ignore) {
301 return $ignore->ignoreUserID;
302 }, $this->getObjects());
303
a9229942
TD
304 $returnValues = parent::delete();
305
306 // reset storage
307 UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'ignoredUserIDs');
2571bf19 308 UserStorageHandler::getInstance()->reset($userIDs, 'ignoredByUserIDs');
a9229942
TD
309
310 return $returnValues;
311 }
320f4a6d 312}