Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 67 |
|
0.00% |
0 / 9 |
CRAP | |
0.00% |
0 / 1 |
ApiEchoMute | |
0.00% |
0 / 67 |
|
0.00% |
0 / 9 |
506 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 33 |
|
0.00% |
0 / 1 |
72 | |||
lookupIds | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
56 | |||
parsePref | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
serializePref | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getAllowedParams | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
2 | |||
needsToken | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
mustBePosted | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
isWriteMode | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\Notifications\Api; |
4 | |
5 | use ApiBase; |
6 | use ApiMain; |
7 | use MediaWiki\Cache\LinkBatchFactory; |
8 | use MediaWiki\Title\Title; |
9 | use MediaWiki\User\CentralId\CentralIdLookup; |
10 | use MediaWiki\User\Options\UserOptionsManager; |
11 | use Wikimedia\ParamValidator\ParamValidator; |
12 | |
13 | class ApiEchoMute extends ApiBase { |
14 | |
15 | /** @var CentralIdLookup */ |
16 | private $centralIdLookup; |
17 | |
18 | /** @var LinkBatchFactory */ |
19 | private $linkBatchFactory; |
20 | |
21 | /** @var UserOptionsManager */ |
22 | private $userOptionsManager; |
23 | |
24 | /** @var string[][] */ |
25 | private const MUTE_LISTS = [ |
26 | 'user' => [ |
27 | 'pref' => 'echo-notifications-blacklist', |
28 | 'type' => 'user', |
29 | ], |
30 | 'page-linked-title' => [ |
31 | 'pref' => 'echo-notifications-page-linked-title-muted-list', |
32 | 'type' => 'title' |
33 | ], |
34 | ]; |
35 | |
36 | /** |
37 | * @param ApiMain $main |
38 | * @param string $action |
39 | * @param CentralIdLookup $centralIdLookup |
40 | * @param LinkBatchFactory $linkBatchFactory |
41 | * @param UserOptionsManager $userOptionsManager |
42 | */ |
43 | public function __construct( |
44 | ApiMain $main, |
45 | $action, |
46 | CentralIdLookup $centralIdLookup, |
47 | LinkBatchFactory $linkBatchFactory, |
48 | UserOptionsManager $userOptionsManager |
49 | ) { |
50 | parent::__construct( $main, $action ); |
51 | |
52 | $this->centralIdLookup = $centralIdLookup; |
53 | $this->linkBatchFactory = $linkBatchFactory; |
54 | $this->userOptionsManager = $userOptionsManager; |
55 | } |
56 | |
57 | public function execute() { |
58 | $user = $this->getUser(); |
59 | if ( !$user || !$user->isRegistered() ) { |
60 | $this->dieWithError( |
61 | [ 'apierror-mustbeloggedin', $this->msg( 'action-editmyoptions' ) ], |
62 | 'notloggedin' |
63 | ); |
64 | } |
65 | |
66 | $this->checkUserRightsAny( 'editmyoptions' ); |
67 | |
68 | $params = $this->extractRequestParams(); |
69 | $mutelistInfo = self::MUTE_LISTS[ $params['type'] ]; |
70 | $prefValue = $this->userOptionsManager->getOption( $user, $mutelistInfo['pref'] ); |
71 | $ids = $this->parsePref( $prefValue ); |
72 | $targetsToMute = $params['mute'] ?? []; |
73 | $targetsToUnmute = $params['unmute'] ?? []; |
74 | |
75 | $changed = false; |
76 | $addIds = $this->lookupIds( $targetsToMute, $mutelistInfo['type'] ); |
77 | foreach ( $addIds as $id ) { |
78 | if ( !in_array( $id, $ids ) ) { |
79 | $ids[] = $id; |
80 | $changed = true; |
81 | } |
82 | } |
83 | $removeIds = $this->lookupIds( $targetsToUnmute, $mutelistInfo['type'] ); |
84 | foreach ( $removeIds as $id ) { |
85 | $index = array_search( $id, $ids ); |
86 | if ( $index !== false ) { |
87 | array_splice( $ids, $index, 1 ); |
88 | $changed = true; |
89 | } |
90 | } |
91 | |
92 | if ( $changed ) { |
93 | $this->userOptionsManager->setOption( |
94 | $user, |
95 | $mutelistInfo['pref'], |
96 | $this->serializePref( $ids ) |
97 | ); |
98 | $this->userOptionsManager->saveOptions( $user ); |
99 | } |
100 | |
101 | $this->getResult()->addValue( null, $this->getModuleName(), 'success' ); |
102 | } |
103 | |
104 | private function lookupIds( $names, $type ) { |
105 | if ( $type === 'title' ) { |
106 | $linkBatch = $this->linkBatchFactory->newLinkBatch(); |
107 | foreach ( $names as $name ) { |
108 | $linkBatch->addObj( Title::newFromText( $name ) ); |
109 | } |
110 | $linkBatch->execute(); |
111 | |
112 | $ids = []; |
113 | foreach ( $names as $name ) { |
114 | $title = Title::newFromText( $name ); |
115 | if ( $title instanceof Title && $title->getArticleID() > 0 ) { |
116 | $ids[] = $title->getArticleID(); |
117 | } |
118 | } |
119 | return $ids; |
120 | } elseif ( $type === 'user' ) { |
121 | return $this->centralIdLookup->centralIdsFromNames( $names, CentralIdLookup::AUDIENCE_PUBLIC ); |
122 | } |
123 | } |
124 | |
125 | private function parsePref( $prefValue ) { |
126 | return preg_split( '/\n/', $prefValue, -1, PREG_SPLIT_NO_EMPTY ); |
127 | } |
128 | |
129 | private function serializePref( $ids ) { |
130 | return implode( "\n", $ids ); |
131 | } |
132 | |
133 | public function getAllowedParams( $flags = 0 ) { |
134 | return [ |
135 | 'type' => [ |
136 | ParamValidator::PARAM_REQUIRED => true, |
137 | ParamValidator::PARAM_TYPE => array_keys( self::MUTE_LISTS ), |
138 | ], |
139 | 'mute' => [ |
140 | ParamValidator::PARAM_ISMULTI => true, |
141 | ], |
142 | 'unmute' => [ |
143 | ParamValidator::PARAM_ISMULTI => true, |
144 | ] |
145 | ]; |
146 | } |
147 | |
148 | public function needsToken() { |
149 | return 'csrf'; |
150 | } |
151 | |
152 | public function mustBePosted() { |
153 | return true; |
154 | } |
155 | |
156 | public function isWriteMode() { |
157 | return true; |
158 | } |
159 | |
160 | } |