Commit | Line | Data |
---|---|---|
320f4a6d | 1 | <?php |
a9229942 | 2 | |
320f4a6d | 3 | namespace wcf\data\user\ignore; |
a9229942 TD |
4 | |
5 | use wcf\data\AbstractDatabaseObjectAction; | |
013abaff AE |
6 | use wcf\data\user\follow\UserFollow; |
7 | use wcf\data\user\follow\UserFollowEditor; | |
a8c5936e | 8 | use wcf\system\cache\runtime\UserProfileRuntimeCache; |
320f4a6d MW |
9 | use wcf\system\exception\IllegalLinkException; |
10 | use wcf\system\exception\PermissionDeniedException; | |
11 | use wcf\system\exception\UserInputException; | |
10bc76ec TD |
12 | use wcf\system\form\builder\data\processor\CustomFormDataProcessor; |
13 | use wcf\system\form\builder\DialogFormDocument; | |
14 | use wcf\system\form\builder\field\RadioButtonFormField; | |
15 | use wcf\system\form\builder\field\validation\FormFieldValidationError; | |
16 | use wcf\system\form\builder\field\validation\FormFieldValidator; | |
17 | use wcf\system\form\builder\IFormDocument; | |
320f4a6d MW |
18 | use wcf\system\user\storage\UserStorageHandler; |
19 | use 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 |
32 | class 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 | } |