Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 67 |
|
0.00% |
0 / 12 |
CRAP | |
0.00% |
0 / 1 |
MassMessageHooks | |
0.00% |
0 / 67 |
|
0.00% |
0 / 12 |
1406 | |
0.00% |
0 / 1 |
onParserFirstCallInit | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
outputParserFunction | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
12 | |||
storeDataParserFunction | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
12 | |||
onUserGetReservedNames | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
onAPIQuerySiteInfoStatisticsInfo | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
onSkinTemplateNavigation__Universal | |
0.00% |
0 / 27 |
|
0.00% |
0 / 1 |
240 | |||
onBeforePageDisplay | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
30 | |||
onRejectParserCacheValue | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
onEmailConfirmed | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
onListDefinedTags | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
onChangeTagsListActive | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
addRegisterTags | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | // phpcs:disable MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName |
4 | |
5 | namespace MediaWiki\MassMessage; |
6 | |
7 | use MediaWiki\Api\Hook\APIQuerySiteInfoStatisticsInfoHook; |
8 | use MediaWiki\ChangeTags\Hook\ChangeTagsListActiveHook; |
9 | use MediaWiki\ChangeTags\Hook\ListDefinedTagsHook; |
10 | use MediaWiki\Hook\BeforePageDisplayHook; |
11 | use MediaWiki\Hook\ParserFirstCallInitHook; |
12 | use MediaWiki\Hook\RejectParserCacheValueHook; |
13 | use MediaWiki\Hook\SkinTemplateNavigation__UniversalHook; |
14 | use MediaWiki\MediaWikiServices; |
15 | use MediaWiki\Output\OutputPage; |
16 | use MediaWiki\Parser\ParserOutput; |
17 | use MediaWiki\SpecialPage\SpecialPage; |
18 | use MediaWiki\User\Hook\UserGetReservedNamesHook; |
19 | use MediaWiki\User\User; |
20 | use Parser; |
21 | use ParserOptions; |
22 | use Skin; |
23 | use WikiPage; |
24 | |
25 | /** |
26 | * Hooks! |
27 | */ |
28 | |
29 | class MassMessageHooks implements |
30 | ParserFirstCallInitHook, |
31 | APIQuerySiteInfoStatisticsInfoHook, |
32 | UserGetReservedNamesHook, |
33 | SkinTemplateNavigation__UniversalHook, |
34 | BeforePageDisplayHook, |
35 | ListDefinedTagsHook, |
36 | ChangeTagsListActiveHook, |
37 | RejectParserCacheValueHook |
38 | { |
39 | |
40 | /** |
41 | * Hook to load our parser function. |
42 | * |
43 | * @param Parser $parser |
44 | */ |
45 | public function onParserFirstCallInit( $parser ) { |
46 | $parser->setFunctionHook( 'target', [ __CLASS__, 'outputParserFunction' ] ); |
47 | } |
48 | |
49 | /** |
50 | * Main parser function for {{#target:User talk:Example|en.wikipedia.org}}. |
51 | * Prepares the human facing output. |
52 | * Hostname is optional for local delivery. |
53 | * |
54 | * @param Parser $parser |
55 | * @param string $page |
56 | * @param string $site |
57 | * @return array |
58 | */ |
59 | public static function outputParserFunction( Parser $parser, $page, $site = '' ) { |
60 | $config = MediaWikiServices::getInstance()->getMainConfig(); |
61 | |
62 | $parser->addTrackingCategory( 'massmessage-list-category' ); |
63 | |
64 | $data = MassMessage::processPFData( $page, $site ); |
65 | if ( isset( $data['error'] ) ) { |
66 | return $data; |
67 | } |
68 | |
69 | // Use a message so wikis can customize the output. |
70 | if ( $config->get( 'AllowGlobalMessaging' ) ) { |
71 | $msg = wfMessage( 'massmessage-target' ) |
72 | ->params( $data['site'], $config->get( 'Script' ), $data['title'] )->plain(); |
73 | } else { |
74 | $msg = wfMessage( 'massmessage-target-local' )->params( $data['title'] )->plain(); |
75 | } |
76 | |
77 | return [ $msg, 'noparse' => false ]; |
78 | } |
79 | |
80 | /** |
81 | * Reads the parser function and extracts the data from it. |
82 | * |
83 | * @param Parser $parser |
84 | * @param string $page |
85 | * @param string $site |
86 | * @return string |
87 | */ |
88 | public static function storeDataParserFunction( Parser $parser, $page, $site = '' ) { |
89 | $data = MassMessage::processPFData( $page, $site ); |
90 | if ( isset( $data['error'] ) ) { |
91 | // Output doesn't matter |
92 | return ''; |
93 | } |
94 | $output = $parser->getOutput(); |
95 | $current = $output->getExtensionData( 'massmessage-targets' ); |
96 | if ( !$current ) { |
97 | $output->setExtensionData( 'massmessage-targets', [ $data ] ); |
98 | } else { |
99 | $output->setExtensionData( 'massmessage-targets', |
100 | array_merge( $current, [ $data ] ) ); |
101 | } |
102 | return ''; |
103 | } |
104 | |
105 | /** |
106 | * Add our username to the list of reserved ones |
107 | * |
108 | * @param array &$reservedUsernames |
109 | */ |
110 | public function onUserGetReservedNames( &$reservedUsernames ) { |
111 | $reservedUsernames[] = MediaWikiServices::getInstance()->getMainConfig()->get( 'MassMessageAccountUsername' ); |
112 | } |
113 | |
114 | /** |
115 | * Add the number of queued messages to &meta=siteinfo&siprop=statistics. |
116 | * |
117 | * @param array &$result |
118 | */ |
119 | public function onAPIQuerySiteInfoStatisticsInfo( &$result ) { |
120 | $result['queued-massmessages'] = MassMessage::getQueuedCount(); |
121 | } |
122 | |
123 | /** |
124 | * Override the Edit tab for delivery lists. |
125 | * |
126 | * @param \SkinTemplate $sktemplate |
127 | * @param array &$links |
128 | */ |
129 | public function onSkinTemplateNavigation__Universal( $sktemplate, &$links ): void { |
130 | $title = $sktemplate->getTitle(); |
131 | if ( $title->hasContentModel( 'MassMessageListContent' ) |
132 | && array_key_exists( 'edit', $links['views'] ) |
133 | ) { |
134 | // Get the revision being viewed, if applicable |
135 | $request = $sktemplate->getRequest(); |
136 | $direction = $request->getVal( 'direction' ); |
137 | $diff = $request->getVal( 'diff' ); |
138 | // getInt is guaranteed to return an integer, 0 if invalid |
139 | $oldid = $request->getInt( 'oldid' ); |
140 | $revisionLookup = MediaWikiServices::getInstance()->getRevisionLookup(); |
141 | $oldRev = $revisionLookup->getRevisionById( $oldid ); |
142 | if ( $direction === 'next' && $oldRev ) { |
143 | $next = $revisionLookup->getNextRevision( $oldRev ); |
144 | $revId = $next ? $next->getId() : $oldid; |
145 | } elseif ( $direction === 'prev' && $oldRev ) { |
146 | $prev = $revisionLookup->getPreviousRevision( $oldRev ); |
147 | $revId = $prev ? $prev->getId() : $oldid; |
148 | } elseif ( $diff !== null ) { |
149 | if ( ctype_digit( $diff ) ) { |
150 | $revId = (int)$diff; |
151 | } elseif ( $diff === 'next' && $oldRev ) { |
152 | $next = $revisionLookup->getNextRevision( $oldRev ); |
153 | $revId = $next ? $next->getId() : $oldid; |
154 | } else { |
155 | // diff is 'prev' or gibberish |
156 | $revId = $oldid; |
157 | } |
158 | } else { |
159 | $revId = $oldid; |
160 | } |
161 | |
162 | $query = ( $revId > 0 ) ? 'oldid=' . $revId : ''; |
163 | $links['views']['edit']['href'] = SpecialPage::getTitleFor( |
164 | 'EditMassMessageList', $title |
165 | )->getFullUrl( $query ); |
166 | } |
167 | } |
168 | |
169 | /** |
170 | * Add scripts and styles. |
171 | * |
172 | * @param OutputPage $out |
173 | * @param Skin $skin |
174 | */ |
175 | public function onBeforePageDisplay( $out, $skin ): void { |
176 | $title = $out->getTitle(); |
177 | if ( $title->exists() && $title->hasContentModel( 'MassMessageListContent' ) ) { |
178 | $permManager = MediaWikiServices::getInstance()->getPermissionManager(); |
179 | if ( $out->getRevisionId() === $title->getLatestRevId() |
180 | && $permManager->quickUserCan( 'edit', $out->getUser(), $title ) |
181 | ) { |
182 | $out->addBodyClasses( 'mw-massmessage-editable' ); |
183 | } |
184 | } |
185 | } |
186 | |
187 | /** |
188 | * Hook: RejectParserCacheValue |
189 | * |
190 | * Reject old cache entries that don't contain our "ext.MassMessage.content" |
191 | * module. |
192 | * |
193 | * @param ParserOutput $parserOutput |
194 | * @param WikiPage $wikiPage |
195 | * @param ParserOptions $parserOptions |
196 | * @return bool |
197 | */ |
198 | public function onRejectParserCacheValue( $parserOutput, $wikiPage, |
199 | $parserOptions |
200 | ): bool { |
201 | if ( $wikiPage->getTitle()->hasContentModel( 'MassMessageListContent' ) && |
202 | !in_array( 'ext.MassMessage.content', $parserOutput->getModules() ) |
203 | ) { |
204 | return false; |
205 | } |
206 | |
207 | return true; |
208 | } |
209 | |
210 | /** |
211 | * Mark the messenger account's email as confirmed in job runs (T75061). |
212 | * |
213 | * @param User $user |
214 | * @param bool &$confirmed |
215 | * @return bool |
216 | */ |
217 | public static function onEmailConfirmed( User $user, &$confirmed ) { |
218 | if ( $user->getId() === MassMessage::getMessengerUser()->getId() ) { |
219 | $confirmed = true; |
220 | // Skip further checks |
221 | return false; |
222 | } |
223 | return true; |
224 | } |
225 | |
226 | /** |
227 | * Register the change tag for MassMessage delivery |
228 | * |
229 | * @param array &$tags |
230 | */ |
231 | public function onListDefinedTags( &$tags ) { |
232 | $this->addRegisterTags( $tags ); |
233 | } |
234 | |
235 | /** |
236 | * Register the change tag for MassMessage delivery |
237 | * |
238 | * @param array &$tags |
239 | */ |
240 | public function onChangeTagsListActive( &$tags ) { |
241 | $this->addRegisterTags( $tags ); |
242 | } |
243 | |
244 | /** |
245 | * @param array &$tags |
246 | */ |
247 | private function addRegisterTags( &$tags ) { |
248 | $tags[] = 'massmessage-delivery'; |
249 | } |
250 | } |