Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
85.23% |
75 / 88 |
|
72.73% |
8 / 11 |
CRAP | |
0.00% |
0 / 1 |
StructuredMentorProvider | |
85.23% |
75 / 88 |
|
72.73% |
8 / 11 |
22.42 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
getSignupTitle | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getMentorDataForUser | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
newMentorFromUserIdentity | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
newFromMentorDataAndUserIdentity | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
20 | |||
getDefaultMentorIntroText | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
2 | |||
getMentors | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
2 | |||
getMentorsSafe | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getAutoAssignedMentors | |
100.00% |
16 / 16 |
|
100.00% |
1 / 1 |
2 | |||
getWeightedAutoAssignedMentors | |
94.44% |
17 / 18 |
|
0.00% |
0 / 1 |
4.00 | |||
getManuallyAssignedMentors | |
100.00% |
16 / 16 |
|
100.00% |
1 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace GrowthExperiments\Mentorship\Provider; |
4 | |
5 | use GrowthExperiments\Config\WikiPageConfigLoader; |
6 | use GrowthExperiments\MentorDashboard\MentorTools\IMentorWeights; |
7 | use GrowthExperiments\Mentorship\Mentor; |
8 | use MediaWiki\SpecialPage\SpecialPage; |
9 | use MediaWiki\Title\Title; |
10 | use MediaWiki\User\UserIdentity; |
11 | use MediaWiki\User\UserIdentityLookup; |
12 | use MediaWiki\User\UserIdentityValue; |
13 | use MediaWiki\User\UserNameUtils; |
14 | use MessageLocalizer; |
15 | |
16 | class StructuredMentorProvider extends MentorProvider { |
17 | use GetMentorDataTrait; |
18 | |
19 | private UserIdentityLookup $userIdentityLookup; |
20 | private UserNameUtils $userNameUtils; |
21 | private MessageLocalizer $messageLocalizer; |
22 | |
23 | /** |
24 | * @param WikiPageConfigLoader $configLoader |
25 | * @param UserIdentityLookup $userIdentityLookup |
26 | * @param UserNameUtils $userNameUtils |
27 | * @param MessageLocalizer $messageLocalizer |
28 | * @param Title $mentorList |
29 | */ |
30 | public function __construct( |
31 | WikiPageConfigLoader $configLoader, |
32 | UserIdentityLookup $userIdentityLookup, |
33 | UserNameUtils $userNameUtils, |
34 | MessageLocalizer $messageLocalizer, |
35 | Title $mentorList |
36 | ) { |
37 | parent::__construct(); |
38 | |
39 | $this->configLoader = $configLoader; |
40 | $this->userIdentityLookup = $userIdentityLookup; |
41 | $this->userNameUtils = $userNameUtils; |
42 | $this->messageLocalizer = $messageLocalizer; |
43 | $this->mentorList = $mentorList; |
44 | } |
45 | |
46 | /** |
47 | * @inheritDoc |
48 | */ |
49 | public function getSignupTitle(): ?Title { |
50 | return SpecialPage::getTitleFor( 'EnrollAsMentor' ); |
51 | } |
52 | |
53 | /** |
54 | * @param UserIdentity $mentor |
55 | * @return array|null |
56 | */ |
57 | private function getMentorDataForUser( UserIdentity $mentor ): ?array { |
58 | return $this->getMentorData()[$mentor->getId()] ?? null; |
59 | } |
60 | |
61 | /** |
62 | * @inheritDoc |
63 | */ |
64 | public function newMentorFromUserIdentity( |
65 | UserIdentity $mentorUser, |
66 | ?UserIdentity $menteeUser = null |
67 | ): Mentor { |
68 | return $this->newFromMentorDataAndUserIdentity( |
69 | $this->getMentorDataForUser( $mentorUser ), |
70 | $mentorUser, |
71 | $menteeUser |
72 | ); |
73 | } |
74 | |
75 | /** |
76 | * @param array|null $mentorData |
77 | * @param UserIdentity $mentorUser |
78 | * @param UserIdentity|null $menteeUser |
79 | * @return Mentor |
80 | */ |
81 | private function newFromMentorDataAndUserIdentity( |
82 | ?array $mentorData, |
83 | UserIdentity $mentorUser, |
84 | ?UserIdentity $menteeUser = null |
85 | ): Mentor { |
86 | $weight = $mentorData['weight'] ?? IMentorWeights::WEIGHT_NORMAL; |
87 | if ( |
88 | $mentorData && |
89 | array_key_exists( 'automaticallyAssigned', $mentorData ) && |
90 | !$mentorData['automaticallyAssigned'] |
91 | ) { |
92 | // T347157: To aid with migration; remove once automaticallyAssigned is not set. |
93 | $weight = IMentorWeights::WEIGHT_NONE; |
94 | } |
95 | return new Mentor( |
96 | $mentorUser, |
97 | $mentorData['message'] ?? null, |
98 | $this->getDefaultMentorIntroText( $mentorUser, $menteeUser ), |
99 | $weight |
100 | ); |
101 | } |
102 | |
103 | /** |
104 | * @param UserIdentity $mentor |
105 | * @param ?UserIdentity $mentee |
106 | * @return string |
107 | */ |
108 | private function getDefaultMentorIntroText( |
109 | UserIdentity $mentor, |
110 | ?UserIdentity $mentee |
111 | ): string { |
112 | return $this->messageLocalizer |
113 | ->msg( 'growthexperiments-homepage-mentorship-intro' ) |
114 | ->inContentLanguage() |
115 | ->params( $mentor->getName() ) |
116 | ->params( $mentee ? $mentee->getName() : '' ) |
117 | ->text(); |
118 | } |
119 | |
120 | /** |
121 | * @inheritDoc |
122 | */ |
123 | public function getMentors(): array { |
124 | $mentorIds = array_keys( $this->getMentorData() ); |
125 | if ( $mentorIds === [] ) { |
126 | return []; |
127 | } |
128 | |
129 | return $this->userIdentityLookup->newSelectQueryBuilder() |
130 | ->whereUserIds( $mentorIds ) |
131 | ->registered() |
132 | ->fetchUserNames(); |
133 | } |
134 | |
135 | /** |
136 | * @inheritDoc |
137 | */ |
138 | public function getMentorsSafe(): array { |
139 | return $this->getMentors(); |
140 | } |
141 | |
142 | /** |
143 | * @inheritDoc |
144 | */ |
145 | public function getAutoAssignedMentors(): array { |
146 | $userIDs = array_keys( array_filter( |
147 | $this->getMentorData(), |
148 | function ( array $mentorData, int $userId ) { |
149 | return $this->newFromMentorDataAndUserIdentity( |
150 | $mentorData, |
151 | new UserIdentityValue( $userId, $mentorData['username'] ?? '' ) |
152 | )->getWeight() !== IMentorWeights::WEIGHT_NONE; |
153 | }, |
154 | ARRAY_FILTER_USE_BOTH |
155 | ) ); |
156 | |
157 | if ( $userIDs === [] ) { |
158 | return []; |
159 | } |
160 | |
161 | return $this->userIdentityLookup->newSelectQueryBuilder() |
162 | ->whereUserIds( $userIDs ) |
163 | ->registered() |
164 | ->fetchUserNames(); |
165 | } |
166 | |
167 | /** |
168 | * @inheritDoc |
169 | */ |
170 | public function getWeightedAutoAssignedMentors(): array { |
171 | $mentors = $this->getMentorData(); |
172 | |
173 | $usernames = []; |
174 | foreach ( $mentors as $userId => $mentorData ) { |
175 | $user = $this->userIdentityLookup->getUserIdentityByUserId( $userId ); |
176 | if ( !$user ) { |
177 | continue; |
178 | } |
179 | |
180 | $mentor = $this->newFromMentorDataAndUserIdentity( |
181 | $mentorData, |
182 | $user |
183 | ); |
184 | if ( $mentor->getWeight() === IMentorWeights::WEIGHT_NONE ) { |
185 | continue; |
186 | } |
187 | |
188 | $usernames = array_merge( $usernames, array_fill( |
189 | 0, |
190 | $mentorData['weight'], |
191 | $user->getName() |
192 | ) ); |
193 | } |
194 | return $usernames; |
195 | } |
196 | |
197 | /** |
198 | * @inheritDoc |
199 | */ |
200 | public function getManuallyAssignedMentors(): array { |
201 | $userIDs = array_keys( array_filter( |
202 | $this->getMentorData(), |
203 | function ( array $mentorData, int $userId ) { |
204 | return $this->newFromMentorDataAndUserIdentity( |
205 | $mentorData, |
206 | new UserIdentityValue( $userId, $mentorData['username'] ?? '' ) |
207 | )->getWeight() === IMentorWeights::WEIGHT_NONE; |
208 | }, |
209 | ARRAY_FILTER_USE_BOTH |
210 | ) ); |
211 | |
212 | if ( $userIDs === [] ) { |
213 | return []; |
214 | } |
215 | |
216 | return $this->userIdentityLookup->newSelectQueryBuilder() |
217 | ->whereUserIds( $userIDs ) |
218 | ->registered() |
219 | ->fetchUserNames(); |
220 | } |
221 | } |