Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
43.69% |
45 / 103 |
|
0.00% |
0 / 5 |
CRAP | |
0.00% |
0 / 1 |
ApiManageMentorList | |
43.69% |
45 / 103 |
|
0.00% |
0 / 5 |
126.85 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
68.18% |
45 / 66 |
|
0.00% |
0 / 1 |
32.89 | |||
isWriteMode | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
needsToken | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getAllowedParams | |
0.00% |
0 / 31 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace GrowthExperiments\Api; |
4 | |
5 | use ApiBase; |
6 | use ApiMain; |
7 | use GrowthExperiments\MentorDashboard\MentorTools\IMentorWeights; |
8 | use GrowthExperiments\MentorDashboard\MentorTools\MentorStatusManager; |
9 | use GrowthExperiments\Mentorship\Provider\IMentorWriter; |
10 | use GrowthExperiments\Mentorship\Provider\MentorProvider; |
11 | use IDBAccessObject; |
12 | use LogicException; |
13 | use MediaWiki\ParamValidator\TypeDef\UserDef; |
14 | use Wikimedia\ParamValidator\ParamValidator; |
15 | |
16 | class ApiManageMentorList extends ApiBase { |
17 | |
18 | private MentorProvider $mentorProvider; |
19 | private IMentorWriter $mentorWriter; |
20 | private MentorStatusManager $mentorStatusManager; |
21 | |
22 | /** |
23 | * @param ApiMain $mainModule |
24 | * @param string $moduleName |
25 | * @param MentorProvider $mentorProvider |
26 | * @param IMentorWriter $mentorWriter |
27 | * @param MentorStatusManager $mentorStatusManager |
28 | */ |
29 | public function __construct( |
30 | ApiMain $mainModule, |
31 | $moduleName, |
32 | MentorProvider $mentorProvider, |
33 | IMentorWriter $mentorWriter, |
34 | MentorStatusManager $mentorStatusManager |
35 | ) { |
36 | parent::__construct( $mainModule, $moduleName ); |
37 | |
38 | $this->mentorProvider = $mentorProvider; |
39 | $this->mentorWriter = $mentorWriter; |
40 | $this->mentorStatusManager = $mentorStatusManager; |
41 | } |
42 | |
43 | /** |
44 | * @inheritDoc |
45 | */ |
46 | public function execute() { |
47 | $block = $this->getUser()->getBlock( IDBAccessObject::READ_LATEST ); |
48 | if ( $block && $block->isSitewide() ) { |
49 | $this->dieBlocked( $block ); |
50 | } |
51 | |
52 | // if the user is not a mentor, require enrollasmentor or managementors; the if is here to |
53 | // allow users to remove themselves, even after they lost the ability to enroll themselves. |
54 | if ( !$this->mentorProvider->isMentor( $this->getUser() ) ) { |
55 | $this->checkUserRightsAny( [ 'enrollasmentor', 'managementors' ] ); |
56 | } |
57 | |
58 | $params = $this->extractRequestParams(); |
59 | |
60 | if ( $params['username'] !== null ) { |
61 | $this->checkUserRightsAny( 'managementors' ); |
62 | // despite the name, $params['username'] is converted to an UserIdentity |
63 | // via UserDef::PARAM_RETURN_OBJECT in getAllowedParams(). |
64 | $mentorUser = $params['username']; |
65 | } else { |
66 | $mentorUser = $this->getUser(); |
67 | } |
68 | |
69 | $mentor = $this->mentorProvider->newMentorFromUserIdentity( $mentorUser ); |
70 | |
71 | if ( $params['message'] !== null ) { |
72 | $mentor->setIntroText( $params['message'] !== '' ? $params['message'] : null ); |
73 | } |
74 | if ( $params['weight'] !== null ) { |
75 | $mentor->setWeight( (int)$params['weight'] ); |
76 | } |
77 | |
78 | // ensure awaytimestamp is provided when isaway=true |
79 | if ( $params['isaway'] && $params['awaytimestamp'] === null ) { |
80 | $this->dieWithError( |
81 | 'growthexperiments-api-managementors-error-no-away-timestamp', |
82 | 'away-timestamp' |
83 | ); |
84 | } |
85 | |
86 | switch ( $params['geaction'] ) { |
87 | case 'add': |
88 | $statusValue = $this->mentorWriter->addMentor( |
89 | $mentor, |
90 | $this->getUser(), |
91 | $params['summary'] |
92 | ); |
93 | break; |
94 | case 'change': |
95 | $statusValue = $this->mentorWriter->changeMentor( |
96 | $mentor, |
97 | $this->getUser(), |
98 | $params['summary'] |
99 | ); |
100 | break; |
101 | case 'remove': |
102 | $statusValue = $this->mentorWriter->removeMentor( |
103 | $mentor, |
104 | $this->getUser(), |
105 | $params['summary'] |
106 | ); |
107 | break; |
108 | default: |
109 | // this should never happen, unless getAllowedParams is wrong |
110 | throw new LogicException( 'Invalid geaction passed validation' ); |
111 | } |
112 | |
113 | if ( !$statusValue->isOK() ) { |
114 | $this->dieStatus( $statusValue ); |
115 | } |
116 | |
117 | if ( $params['geaction'] !== 'remove' ) { |
118 | if ( $params['isaway'] ) { |
119 | $result = $this->mentorStatusManager->markMentorAsAwayTimestamp( |
120 | $mentorUser, |
121 | $params['awaytimestamp'] |
122 | ); |
123 | if ( !$result->isOK() ) { |
124 | $this->dieStatus( $result ); |
125 | } |
126 | } else { |
127 | $this->mentorStatusManager->markMentorAsActive( $mentorUser ); |
128 | } |
129 | } |
130 | |
131 | $rawBackTs = $this->mentorStatusManager->getMentorBackTimestamp( $mentorUser ); |
132 | $this->getResult()->addValue( null, $this->getModuleName(), [ |
133 | 'status' => 'ok', |
134 | 'mentor' => [ |
135 | 'message' => $mentor->hasCustomIntroText() ? $mentor->getIntroText() : null, |
136 | 'weight' => $mentor->getWeight(), |
137 | 'awayTimestamp' => $rawBackTs, |
138 | 'awayTimestampHuman' => $rawBackTs !== null ? $this->getContext() |
139 | ->getLanguage()->date( $rawBackTs, true ) : null, |
140 | |
141 | // NOTE: Legacy attribute, weight provides the same info. |
142 | 'automaticallyAssigned' => $mentor->getWeight() !== IMentorWeights::WEIGHT_NONE, |
143 | ] |
144 | ] ); |
145 | } |
146 | |
147 | /** |
148 | * @inheritDoc |
149 | */ |
150 | public function isWriteMode() { |
151 | return true; |
152 | } |
153 | |
154 | /** |
155 | * @inheritDoc |
156 | */ |
157 | public function needsToken() { |
158 | return 'csrf'; |
159 | } |
160 | |
161 | /** |
162 | * @inheritDoc |
163 | */ |
164 | protected function getAllowedParams() { |
165 | return [ |
166 | 'geaction' => [ |
167 | ParamValidator::PARAM_REQUIRED => true, |
168 | ParamValidator::PARAM_TYPE => [ |
169 | 'add', |
170 | 'change', |
171 | 'remove', |
172 | ] |
173 | ], |
174 | 'message' => [ |
175 | ParamValidator::PARAM_TYPE => 'string' |
176 | ], |
177 | 'weight' => [ |
178 | ParamValidator::PARAM_TYPE => array_map( 'strval', IMentorWeights::WEIGHTS ) |
179 | ], |
180 | 'isaway' => [ |
181 | ParamValidator::PARAM_TYPE => 'boolean', |
182 | ], |
183 | 'awaytimestamp' => [ |
184 | ParamValidator::PARAM_TYPE => 'timestamp', |
185 | ], |
186 | 'summary' => [ |
187 | ParamValidator::PARAM_TYPE => 'string', |
188 | ParamValidator::PARAM_DEFAULT => '', |
189 | ], |
190 | 'username' => [ |
191 | ParamValidator::PARAM_TYPE => 'user', |
192 | UserDef::PARAM_ALLOWED_USER_TYPES => [ 'name' ], |
193 | UserDef::PARAM_RETURN_OBJECT => true, |
194 | ], |
195 | ]; |
196 | } |
197 | } |