Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
58.25% |
60 / 103 |
|
20.00% |
3 / 15 |
CRAP | |
0.00% |
0 / 1 |
SpecialClaimMentee | |
58.25% |
60 / 103 |
|
20.00% |
3 / 15 |
90.19 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
getGroupName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
doesWrites | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getDescription | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
preHtml | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
isListed | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
userCanExecute | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
displayRestrictionError | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
6 | |||
getFormFields | |
100.00% |
25 / 25 |
|
100.00% |
1 / 1 |
3 | |||
getDisplayFormat | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
onSubmit | |
91.30% |
21 / 23 |
|
0.00% |
0 / 1 |
7.03 | |||
onSuccess | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
1 | |||
setMentees | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
validateMentees | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
20 |
1 | <?php |
2 | |
3 | namespace GrowthExperiments\Specials; |
4 | |
5 | use GrowthExperiments\Mentorship\ChangeMentorFactory; |
6 | use GrowthExperiments\Mentorship\Provider\MentorProvider; |
7 | use MediaWiki\Config\Config; |
8 | use MediaWiki\Html\Html; |
9 | use MediaWiki\Linker\Linker; |
10 | use MediaWiki\Logger\LoggerFactory; |
11 | use MediaWiki\Message\Message; |
12 | use MediaWiki\SpecialPage\FormSpecialPage; |
13 | use MediaWiki\Status\Status; |
14 | use MediaWiki\User\User; |
15 | use MediaWiki\User\UserIdentity; |
16 | use PermissionsError; |
17 | |
18 | class SpecialClaimMentee extends FormSpecialPage { |
19 | |
20 | /** @var User[] */ |
21 | private array $mentees; |
22 | |
23 | private ?User $newMentor; |
24 | private MentorProvider $mentorProvider; |
25 | private ChangeMentorFactory $changeMentorFactory; |
26 | private Config $wikiConfig; |
27 | |
28 | /** |
29 | * @param MentorProvider $mentorProvider |
30 | * @param ChangeMentorFactory $changeMentorFactory |
31 | * @param Config $wikiConfig |
32 | */ |
33 | public function __construct( |
34 | MentorProvider $mentorProvider, |
35 | ChangeMentorFactory $changeMentorFactory, |
36 | Config $wikiConfig |
37 | ) { |
38 | parent::__construct( 'ClaimMentee' ); |
39 | |
40 | $this->mentorProvider = $mentorProvider; |
41 | $this->changeMentorFactory = $changeMentorFactory; |
42 | $this->wikiConfig = $wikiConfig; |
43 | } |
44 | |
45 | /** @inheritDoc */ |
46 | protected function getGroupName() { |
47 | return 'growth-tools'; |
48 | } |
49 | |
50 | public function doesWrites() { |
51 | return true; |
52 | } |
53 | |
54 | /** |
55 | * @inheritDoc |
56 | */ |
57 | public function getDescription() { |
58 | return $this->msg( 'growthexperiments-homepage-claimmentee-title' ); |
59 | } |
60 | |
61 | protected function preHtml() { |
62 | return Html::element( |
63 | 'p', |
64 | [], |
65 | $this->msg( 'growthexperiments-homepage-claimmentee-pretext' )->params( |
66 | $this->getUser()->getName() |
67 | )->text() |
68 | ); |
69 | } |
70 | |
71 | /** |
72 | * @inheritDoc |
73 | */ |
74 | public function execute( $par ) { |
75 | $this->requireNamedUser(); |
76 | $this->addHelpLink( 'Help:Growth/Tools/How to claim a mentee' ); |
77 | parent::execute( $par ); |
78 | } |
79 | |
80 | /** |
81 | * @inheritDoc |
82 | */ |
83 | public function isListed() { |
84 | return $this->userCanExecute( $this->getUser() ); |
85 | } |
86 | |
87 | /** |
88 | * @inheritDoc |
89 | */ |
90 | public function userCanExecute( User $user ) { |
91 | return $this->mentorProvider->isMentor( $user ); |
92 | } |
93 | |
94 | /** |
95 | * @inheritDoc |
96 | */ |
97 | public function displayRestrictionError() { |
98 | $signupTitle = $this->mentorProvider->getSignupTitle(); |
99 | |
100 | if ( $signupTitle === null ) { |
101 | throw new PermissionsError( |
102 | null, |
103 | [ 'growthexperiments-homepage-mentors-list-missing-or-misconfigured-generic' ] |
104 | ); |
105 | } |
106 | |
107 | throw new PermissionsError( |
108 | null, |
109 | [ [ 'growthexperiments-homepage-claimmentee-must-be-mentor', |
110 | $this->getUser()->getName(), |
111 | $signupTitle->getPrefixedText() ] ] |
112 | ); |
113 | } |
114 | |
115 | /** |
116 | * Get an HTMLForm descriptor array |
117 | * @return array |
118 | */ |
119 | protected function getFormFields() { |
120 | $req = $this->getRequest(); |
121 | $fields = [ |
122 | 'mentees' => [ |
123 | 'label-message' => 'growthexperiments-homepage-claimmentee-mentee', |
124 | 'type' => 'usersmultiselect', |
125 | 'exists' => true, |
126 | 'required' => true, |
127 | 'excludetemp' => true, |
128 | ], |
129 | 'reason' => [ |
130 | 'label-message' => 'growthexperiments-homepage-claimmentee-reason', |
131 | 'type' => 'text', |
132 | ], |
133 | 'stage' => [ 'type' => 'hidden', 'default' => 2 ] |
134 | ]; |
135 | $stage = $req->getInt( 'wpstage', 1 ); |
136 | $this->setMentees( $req->getVal( 'wpmentees', '' ) ); |
137 | if ( $stage >= 2 && $this->validateMentees() ) { |
138 | $fields['stage']['default'] = 3; |
139 | $fields['confirm'] = [ |
140 | 'label-message' => 'growthexperiments-claimmentee-confirm', |
141 | 'type' => 'check', |
142 | 'default' => false, |
143 | ]; |
144 | } |
145 | return $fields; |
146 | } |
147 | |
148 | /** |
149 | * @return string |
150 | */ |
151 | protected function getDisplayFormat() { |
152 | return 'ooui'; |
153 | } |
154 | |
155 | /** |
156 | * @inheritDoc |
157 | */ |
158 | public function onSubmit( array $data ) { |
159 | $this->setMentees( $data['mentees'] ); |
160 | |
161 | // Should be caught by exits => true, but just to be sure |
162 | if ( !$this->validateMentees() ) { |
163 | return Status::newFatal( 'growthexperiments-homepage-claimmentee-invalid-username' ); |
164 | } |
165 | |
166 | $this->newMentor = $this->getUser(); |
167 | |
168 | $status = Status::newGood(); |
169 | $logger = LoggerFactory::getInstance( 'GrowthExperiments' ); |
170 | foreach ( $this->mentees as $mentee ) { |
171 | $changementor = $this->changeMentorFactory->newChangeMentor( |
172 | $mentee, |
173 | $this->newMentor |
174 | ); |
175 | |
176 | if ( |
177 | $data['confirm'] !== true |
178 | && $data['stage'] !== 3 |
179 | && $changementor->wasMentorChanged() |
180 | ) { |
181 | return Status::newFatal( |
182 | 'growthexperiments-homepage-claimmentee-alreadychanged', |
183 | $mentee, |
184 | $this->newMentor |
185 | ); |
186 | } |
187 | |
188 | $status->merge( $changementor->execute( $this->newMentor, $data['reason'] ) ); |
189 | if ( !$status->isOK() ) { |
190 | // Do not process next users if at least one failed |
191 | return $status; |
192 | } |
193 | } |
194 | |
195 | return $status; |
196 | } |
197 | |
198 | public function onSuccess() { |
199 | $mentees = array_map( static function ( UserIdentity $user ) { |
200 | return Linker::userLink( $user->getId(), $user->getName() ); |
201 | }, $this->mentees ); |
202 | |
203 | $language = $this->getLanguage(); |
204 | |
205 | $this->getOutput()->addWikiMsg( |
206 | 'growthexperiments-homepage-claimmentee-success', |
207 | Message::rawParam( $language->listToText( $mentees ) ), |
208 | $language->formatNum( count( $mentees ) ), |
209 | $this->getUser()->getName(), |
210 | $this->newMentor->getName(), |
211 | Message::rawParam( $this->getLinkRenderer()->makeLink( |
212 | $this->newMentor->getUserPage(), $this->newMentor->getName() ) ) |
213 | ); |
214 | } |
215 | |
216 | private function setMentees( string $namesRaw = '' ) { |
217 | $names = explode( "\n", $namesRaw ); |
218 | $this->mentees = []; |
219 | |
220 | foreach ( $names as $name ) { |
221 | $user = User::newFromName( $name ); |
222 | if ( $user !== false ) { |
223 | $this->mentees[] = $user; |
224 | } |
225 | } |
226 | } |
227 | |
228 | private function validateMentees() { |
229 | foreach ( $this->mentees as $mentee ) { |
230 | if ( !( $mentee instanceof User && $mentee->isNamed() ) ) { |
231 | return false; |
232 | } |
233 | } |
234 | return true; |
235 | } |
236 | } |