Exclude redirects from Special:Fewestrevisions
[lhc/web/wiklou.git] / includes / specials / SpecialMute.php
1 <?php
2 /*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 * @ingroup SpecialPage
20 */
21 use MediaWiki\Preferences\MultiUsernameFilter;
22
23 /**
24 * A special page that allows users to modify their notification
25 * preferences
26 *
27 * @ingroup SpecialPage
28 */
29 class SpecialMute extends FormSpecialPage {
30
31 /** @var User */
32 private $target;
33
34 /** @var int */
35 private $targetCentralId;
36
37 /** @var bool */
38 private $enableUserEmailBlacklist;
39
40 /** @var bool */
41 private $enableUserEmail;
42
43 /** @var CentralIdLookup */
44 private $centralIdLookup;
45
46 public function __construct() {
47 // TODO: inject all these dependencies once T222388 is resolved
48 $config = RequestContext::getMain()->getConfig();
49 $this->enableUserEmailBlacklist = $config->get( 'EnableUserEmailBlacklist' );
50 $this->enableUserEmail = $config->get( 'EnableUserEmail' );
51
52 $this->centralIdLookup = CentralIdLookup::factory();
53
54 parent::__construct( 'Mute', '', false );
55 }
56
57 /**
58 * Entry point for special pages
59 *
60 * @param string $par
61 */
62 public function execute( $par ) {
63 $this->requireLogin( 'specialmute-login-required' );
64 $this->loadTarget( $par );
65
66 parent::execute( $par );
67
68 $out = $this->getOutput();
69 $out->addModules( 'mediawiki.special.pageLanguage' );
70 }
71
72 /**
73 * @inheritDoc
74 */
75 public function requiresUnblock() {
76 return false;
77 }
78
79 /**
80 * @inheritDoc
81 */
82 protected function getDisplayFormat() {
83 return 'ooui';
84 }
85
86 /**
87 * @inheritDoc
88 */
89 public function onSuccess() {
90 $out = $this->getOutput();
91 $out->addWikiMsg( 'specialmute-success' );
92 }
93
94 /**
95 * @param array $data
96 * @param HTMLForm|null $form
97 * @return bool
98 */
99 public function onSubmit( array $data, HTMLForm $form = null ) {
100 if ( !empty( $data['MuteEmail'] ) ) {
101 $this->muteEmailsFromTarget();
102 } else {
103 $this->unmuteEmailsFromTarget();
104 }
105
106 return true;
107 }
108
109 /**
110 * @inheritDoc
111 */
112 public function getDescription() {
113 return $this->msg( 'specialmute' )->text();
114 }
115
116 /**
117 * Un-mute emails from target
118 */
119 private function unmuteEmailsFromTarget() {
120 $blacklist = $this->getBlacklist();
121
122 $key = array_search( $this->targetCentralId, $blacklist );
123 if ( $key !== false ) {
124 unset( $blacklist[$key] );
125 $blacklist = implode( "\n", $blacklist );
126
127 $user = $this->getUser();
128 $user->setOption( 'email-blacklist', $blacklist );
129 $user->saveSettings();
130 }
131 }
132
133 /**
134 * Mute emails from target
135 */
136 private function muteEmailsFromTarget() {
137 // avoid duplicates just in case
138 if ( !$this->isTargetBlacklisted() ) {
139 $blacklist = $this->getBlacklist();
140
141 $blacklist[] = $this->targetCentralId;
142 $blacklist = implode( "\n", $blacklist );
143
144 $user = $this->getUser();
145 $user->setOption( 'email-blacklist', $blacklist );
146 $user->saveSettings();
147 }
148 }
149
150 /**
151 * @inheritDoc
152 */
153 protected function alterForm( HTMLForm $form ) {
154 $form->setId( 'mw-specialmute-form' );
155 $form->setHeaderText( $this->msg( 'specialmute-header', $this->target )->parse() );
156 $form->setSubmitTextMsg( 'specialmute-submit' );
157 $form->setSubmitID( 'save' );
158 }
159
160 /**
161 * @inheritDoc
162 */
163 protected function getFormFields() {
164 if ( !$this->enableUserEmailBlacklist || !$this->enableUserEmail ) {
165 throw new ErrorPageError( 'specialmute', 'specialmute-error-email-blacklist-disabled' );
166 }
167
168 if ( !$this->getUser()->getEmailAuthenticationTimestamp() ) {
169 throw new ErrorPageError( 'specialmute', 'specialmute-error-email-preferences' );
170 }
171
172 $fields['MuteEmail'] = [
173 'type' => 'check',
174 'label-message' => 'specialmute-label-mute-email',
175 'default' => $this->isTargetBlacklisted(),
176 ];
177
178 return $fields;
179 }
180
181 /**
182 * @param string $username
183 */
184 private function loadTarget( $username ) {
185 $target = User::newFromName( $username );
186 if ( !$target || !$target->getId() ) {
187 throw new ErrorPageError( 'specialmute', 'specialmute-error-invalid-user' );
188 } else {
189 $this->target = $target;
190 $this->targetCentralId = $this->centralIdLookup->centralIdFromLocalUser( $target );
191 }
192 }
193
194 /**
195 * @return bool
196 */
197 private function isTargetBlacklisted() {
198 $blacklist = $this->getBlacklist();
199 return in_array( $this->targetCentralId, $blacklist );
200 }
201
202 /**
203 * @return array
204 */
205 private function getBlacklist() {
206 $blacklist = $this->getUser()->getOption( 'email-blacklist' );
207 if ( !$blacklist ) {
208 return [];
209 }
210
211 return MultiUsernameFilter::splitIds( $blacklist );
212 }
213 }