Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
94.12% covered (success)
94.12%
48 / 51
71.43% covered (warning)
71.43%
5 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiSetMentor
94.12% covered (success)
94.12%
48 / 51
71.43% covered (warning)
71.43%
5 / 7
13.03
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 execute
91.67% covered (success)
91.67%
22 / 24
0.00% covered (danger)
0.00%
0 / 1
6.02
 assertUserExists
50.00% covered (danger)
50.00%
1 / 2
0.00% covered (danger)
0.00%
0 / 1
2.50
 mustBePosted
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 needsToken
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isWriteMode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAllowedParams
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace GrowthExperiments\Api;
4
5use ApiBase;
6use ApiMain;
7use ApiUsageException;
8use GrowthExperiments\Mentorship\ChangeMentorFactory;
9use GrowthExperiments\Mentorship\Mentor;
10use GrowthExperiments\Mentorship\MentorManager;
11use IDBAccessObject;
12use MediaWiki\ParamValidator\TypeDef\UserDef;
13use MediaWiki\User\UserIdentity;
14use MediaWiki\User\UserIdentityUtils;
15use Wikimedia\ParamValidator\ParamValidator;
16
17class ApiSetMentor extends ApiBase {
18    /** @var MentorManager */
19    private $mentorManager;
20
21    /** @var ChangeMentorFactory */
22    private $changeMentorFactory;
23
24    /** @var UserIdentityUtils */
25    private $userIdentityUtils;
26
27    /**
28     * @param ApiMain $mainModule
29     * @param string $moduleName
30     * @param MentorManager $mentorManager
31     * @param ChangeMentorFactory $changeMentorFactory
32     * @param UserIdentityUtils $userIdentityUtils
33     */
34    public function __construct(
35        ApiMain $mainModule,
36        $moduleName,
37        MentorManager $mentorManager,
38        ChangeMentorFactory $changeMentorFactory,
39        UserIdentityUtils $userIdentityUtils
40    ) {
41        parent::__construct( $mainModule, $moduleName );
42
43        $this->mentorManager = $mentorManager;
44        $this->changeMentorFactory = $changeMentorFactory;
45        $this->userIdentityUtils = $userIdentityUtils;
46    }
47
48    /**
49     * @inheritDoc
50     */
51    public function execute() {
52        $block = $this->getUser()->getBlock( IDBAccessObject::READ_LATEST );
53        if ( $block && $block->isSitewide() ) {
54            $this->dieBlocked( $block );
55        }
56
57        $params = $this->extractRequestParams();
58        /** @var UserIdentity $mentee */
59        $mentee = $params['mentee'];
60        /** @var UserIdentity $mentor */
61        $mentor = $params['mentor'];
62
63        if ( !in_array( $this->getUser()->getId(), [ $mentee->getId(), $mentor->getId() ] ) ) {
64            // If you're neither the mentee nor the (new) mentor,
65            // you must have setmentor rights.
66            $this->checkUserRightsAny( 'setmentor' );
67        }
68
69        $this->assertUserExists( $mentee );
70        $this->assertUserExists( $mentor );
71
72        $oldMentorObj = $this->mentorManager->getMentorForUserIfExists( $mentee );
73
74        $changeMentor = $this->changeMentorFactory->newChangeMentor(
75            $mentee,
76            $this->getUser()
77        );
78        $status = $changeMentor->execute( $mentor, $params['reason'] );
79        if ( !$status->isOK() ) {
80            $this->dieStatus( $status );
81        }
82
83        $this->getResult()->addValue( null, $this->getModuleName(), [
84            'status' => 'ok',
85            'mentee' => $mentee,
86            'newMentor' => $mentor,
87            'oldMentor' => $oldMentorObj instanceof Mentor ? $oldMentorObj->getUserIdentity() : false,
88        ] );
89    }
90
91    /**
92     * Throw an exception if the user is anonymous or temporary.
93     * @param UserIdentity $user
94     * @throws ApiUsageException
95     */
96    private function assertUserExists( UserIdentity $user ) {
97        if ( !$this->userIdentityUtils->isNamed( $user ) ) {
98            $this->dieWithError( [ 'nosuchusershort', $user->getName() ] );
99        }
100    }
101
102    /** @inheritDoc */
103    public function mustBePosted() {
104        return true;
105    }
106
107    /**
108     * @inheritDoc
109     */
110    public function needsToken() {
111        return 'csrf';
112    }
113
114    /** @inheritDoc */
115    public function isWriteMode() {
116        return true;
117    }
118
119    /**
120     * @inheritDoc
121     */
122    public function getAllowedParams() {
123        return [
124            'mentee' => [
125                ParamValidator::PARAM_REQUIRED => true,
126                ParamValidator::PARAM_TYPE => 'user',
127                UserDef::PARAM_ALLOWED_USER_TYPES => [ 'name' ],
128                UserDef::PARAM_RETURN_OBJECT => true,
129            ],
130            'mentor' => [
131                ParamValidator::PARAM_REQUIRED => true,
132                ParamValidator::PARAM_TYPE => 'user',
133                UserDef::PARAM_ALLOWED_USER_TYPES => [ 'name' ],
134                UserDef::PARAM_RETURN_OBJECT => true,
135            ],
136            'reason' => [
137                ParamValidator::PARAM_TYPE => 'string',
138                ParamValidator::PARAM_DEFAULT => '',
139            ],
140        ];
141    }
142}