Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
85.23% covered (warning)
85.23%
75 / 88
72.73% covered (warning)
72.73%
8 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
StructuredMentorProvider
85.23% covered (warning)
85.23%
75 / 88
72.73% covered (warning)
72.73%
8 / 11
22.42
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 getSignupTitle
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getMentorDataForUser
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 newMentorFromUserIdentity
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 newFromMentorDataAndUserIdentity
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
20
 getDefaultMentorIntroText
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 getMentors
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 getMentorsSafe
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAutoAssignedMentors
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
2
 getWeightedAutoAssignedMentors
94.44% covered (success)
94.44%
17 / 18
0.00% covered (danger)
0.00%
0 / 1
4.00
 getManuallyAssignedMentors
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace GrowthExperiments\Mentorship\Provider;
4
5use GrowthExperiments\Config\WikiPageConfigLoader;
6use GrowthExperiments\MentorDashboard\MentorTools\IMentorWeights;
7use GrowthExperiments\Mentorship\Mentor;
8use MediaWiki\SpecialPage\SpecialPage;
9use MediaWiki\Title\Title;
10use MediaWiki\User\UserIdentity;
11use MediaWiki\User\UserIdentityLookup;
12use MediaWiki\User\UserIdentityValue;
13use MediaWiki\User\UserNameUtils;
14use MessageLocalizer;
15
16class 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}