Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 109 |
|
0.00% |
0 / 13 |
CRAP | |
0.00% |
0 / 1 |
NewUserMessage | |
0.00% |
0 / 109 |
|
0.00% |
0 / 13 |
1640 | |
0.00% |
0 / 1 |
fetchEditor | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
fetchSignature | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
12 | |||
fetchTemplateIfExists | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
20 | |||
fetchSubject | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
fetchText | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
20 | |||
fetchFlags | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
12 | |||
substString | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
12 | |||
createNewUserMessage | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
42 | |||
onLocalUserCreated | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
30 | |||
onUserGetReservedNames | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
leaveUserMessage | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
12 | |||
formatUserMessage | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
getMsg | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | /** Extension:NewUserMessage |
4 | * |
5 | * @file |
6 | * @ingroup Extensions |
7 | * |
8 | * @author [http://www.organicdesign.co.nz/nad User:Nad] |
9 | * @license GPL-2.0-or-later |
10 | * @copyright 2007-10-15 [http://www.organicdesign.co.nz/nad User:Nad] |
11 | * @copyright 2009 Siebrand Mazeland |
12 | */ |
13 | |
14 | namespace MediaWiki\Extension\NewUserMessage; |
15 | |
16 | use ContentHandler; |
17 | use MediaWiki\Auth\Hook\LocalUserCreatedHook; |
18 | use MediaWiki\Deferred\DeferredUpdates; |
19 | use MediaWiki\MediaWikiServices; |
20 | use MediaWiki\Revision\RevisionRecord; |
21 | use MediaWiki\Title\Title; |
22 | use MediaWiki\User\Hook\UserGetReservedNamesHook; |
23 | use MediaWiki\User\User; |
24 | use Message; |
25 | use ParserOptions; |
26 | use WikiPage; |
27 | |
28 | class NewUserMessage implements |
29 | LocalUserCreatedHook, |
30 | UserGetReservedNamesHook |
31 | { |
32 | /** |
33 | * Produce the editor for new user messages. |
34 | * @return User|bool |
35 | */ |
36 | private static function fetchEditor() { |
37 | // Create a user object for the editing user and add it to the |
38 | // database if it is not there already |
39 | $editor = User::newFromName( self::getMsg( 'newusermessage-editor' )->text() ); |
40 | |
41 | if ( !$editor ) { |
42 | return false; // Invalid username |
43 | } |
44 | |
45 | if ( !$editor->isRegistered() ) { |
46 | $editor->addToDatabase(); |
47 | } |
48 | |
49 | return $editor; |
50 | } |
51 | |
52 | /** |
53 | * Produce a (possibly random) signature. |
54 | * @return string |
55 | */ |
56 | private static function fetchSignature() { |
57 | $signatures = self::getMsg( 'newusermessage-signatures' )->text(); |
58 | $signature = ''; |
59 | |
60 | if ( !self::getMsg( 'newusermessage-signatures' )->isDisabled() ) { |
61 | $pattern = '/^\* ?(.*?)$/m'; |
62 | $signatureList = []; |
63 | preg_match_all( $pattern, $signatures, $signatureList, PREG_SET_ORDER ); |
64 | if ( count( $signatureList ) > 0 ) { |
65 | $rand = rand( 0, count( $signatureList ) - 1 ); |
66 | $signature = $signatureList[$rand][1]; |
67 | } |
68 | } |
69 | |
70 | return $signature; |
71 | } |
72 | |
73 | /** |
74 | * Return the template name if it exists, or '' otherwise. |
75 | * @param string $template string with page name of user message template |
76 | * @return string |
77 | */ |
78 | private static function fetchTemplateIfExists( $template ) { |
79 | $text = Title::newFromText( $template ); |
80 | |
81 | if ( !$text ) { |
82 | wfDebug( __METHOD__ . ": '$template' is not a valid title.\n" ); |
83 | return ''; |
84 | } elseif ( $text->getNamespace() !== NS_TEMPLATE ) { |
85 | wfDebug( __METHOD__ . ": '$template' is not a valid Template.\n" ); |
86 | return ''; |
87 | } elseif ( !$text->exists() ) { |
88 | return ''; |
89 | } |
90 | |
91 | return $text->getText(); |
92 | } |
93 | |
94 | /** |
95 | * Produce a subject for the message. |
96 | * @return string |
97 | */ |
98 | private static function fetchSubject() { |
99 | return self::fetchTemplateIfExists( |
100 | self::getMsg( 'newusermessage-template-subject' )->text() |
101 | ); |
102 | } |
103 | |
104 | /** |
105 | * Produce the template that contains the text of the message. |
106 | * @return string |
107 | */ |
108 | private static function fetchText() { |
109 | $template = self::getMsg( 'newusermessage-template-body' )->text(); |
110 | |
111 | $title = Title::newFromText( $template ); |
112 | if ( $title && $title->exists() && $title->getLength() ) { |
113 | return $template; |
114 | } |
115 | |
116 | // Fall back if necessary to the old template |
117 | return self::getMsg( 'newusermessage-template' )->text(); |
118 | } |
119 | |
120 | /** |
121 | * Produce the flags to set on WikiPage::doUserEditContent |
122 | * @return int |
123 | */ |
124 | private static function fetchFlags() { |
125 | global $wgNewUserMinorEdit, $wgNewUserSuppressRC; |
126 | |
127 | $flags = EDIT_NEW; |
128 | if ( $wgNewUserMinorEdit ) { |
129 | $flags |= EDIT_MINOR; |
130 | } |
131 | if ( $wgNewUserSuppressRC ) { |
132 | $flags |= EDIT_SUPPRESS_RC; |
133 | } |
134 | |
135 | return $flags; |
136 | } |
137 | |
138 | /** |
139 | * Take care of substition on the string in a uniform manner |
140 | * @param string $str |
141 | * @param User $user |
142 | * @param User $editor |
143 | * @param Title $talk |
144 | * @param string|null $preparse If provided, then preparse the string using a Parser |
145 | * @return string |
146 | */ |
147 | private static function substString( $str, $user, $editor, $talk, $preparse = null ) { |
148 | $realName = $user->getRealName(); |
149 | $name = $user->getName(); |
150 | |
151 | // Add (any) content to [[MediaWiki:Newusermessage-substitute]] to substitute the |
152 | // welcome template. |
153 | $substDisabled = self::getMsg( 'newusermessage-substitute' )->isDisabled(); |
154 | |
155 | if ( $substDisabled ) { |
156 | $str = '{{' . "$str|realName=$realName|name=$name}}"; |
157 | } else { |
158 | $str = '{{subst:' . "$str|realName=$realName|name=$name}}"; |
159 | } |
160 | |
161 | if ( $preparse ) { |
162 | $str = MediaWikiServices::getInstance()->getParser()->preSaveTransform( |
163 | $str, |
164 | $talk, |
165 | $editor, |
166 | new ParserOptions( $user ) |
167 | ); |
168 | } |
169 | |
170 | return $str; |
171 | } |
172 | |
173 | /** |
174 | * Add the message if the users talk page does not already exist |
175 | * @param User $user User object |
176 | * @return bool |
177 | */ |
178 | public static function createNewUserMessage( $user ) { |
179 | $talk = $user->getTalkPage(); |
180 | |
181 | // Only leave message if user doesn't have a talk page yet |
182 | if ( !$talk->exists() ) { |
183 | $wikiPage = MediaWikiServices::getInstance()->getWikiPageFactory()->newFromTitle( $talk ); |
184 | $subject = self::fetchSubject(); |
185 | $text = self::fetchText(); |
186 | $signature = self::fetchSignature(); |
187 | $editSummary = self::getMsg( 'newuseredit-summary' )->text(); |
188 | $editor = self::fetchEditor(); |
189 | $flags = self::fetchFlags(); |
190 | |
191 | # Do not add a message if the username is invalid or if the account that adds it, |
192 | # is blocked |
193 | if ( !$editor || $editor->getBlock() ) { |
194 | return true; |
195 | } |
196 | |
197 | if ( $subject ) { |
198 | $subject = self::substString( $subject, $user, $editor, $talk, "preparse" ); |
199 | } |
200 | if ( $text ) { |
201 | $text = self::substString( $text, $user, $editor, $talk ); |
202 | } |
203 | |
204 | self::leaveUserMessage( $user, $wikiPage, $subject, $text, |
205 | $signature, $editSummary, $editor, $flags ); |
206 | } |
207 | return true; |
208 | } |
209 | |
210 | /** |
211 | * Hook function to create new user pages when an account is created or autocreated |
212 | * @param User $user object of the user |
213 | * @param bool $autocreated |
214 | */ |
215 | public function onLocalUserCreated( $user, $autocreated ) { |
216 | global $wgNewUserMessageOnAutoCreate; |
217 | |
218 | if ( $user->isTemp() ) { |
219 | return; // not a new registered user |
220 | } |
221 | |
222 | if ( !$autocreated ) { |
223 | DeferredUpdates::addCallableUpdate( |
224 | static function () use ( $user ) { |
225 | if ( $user->isBot() ) { |
226 | return; // not a human |
227 | } |
228 | |
229 | NewUserMessage::createNewUserMessage( $user ); |
230 | }, |
231 | DeferredUpdates::PRESEND |
232 | ); |
233 | } elseif ( $wgNewUserMessageOnAutoCreate ) { |
234 | MediaWikiServices::getInstance()->getJobQueueGroup()->lazyPush( |
235 | new NewUserMessageJob( [ 'userId' => $user->getId() ] ) ); |
236 | } |
237 | } |
238 | |
239 | /** |
240 | * Hook function to provide a reserved name |
241 | * @param array &$names |
242 | */ |
243 | public function onUserGetReservedNames( &$names ) { |
244 | $names[] = 'msg:newusermessage-editor'; |
245 | } |
246 | |
247 | /** |
248 | * Leave a user a message |
249 | * @param User $user User to message |
250 | * @param WikiPage $wikiPage user talk page |
251 | * @param string $subject string with the subject of the message |
252 | * @param string $text string with the message to leave |
253 | * @param string $signature string to leave in the signature |
254 | * @param string $summary string with the summary for this change, defaults to |
255 | * "Leave system message." |
256 | * @param User $editor User leaving the message, defaults to |
257 | * "{{MediaWiki:usermessage-editor}}" |
258 | * @param int $flags default edit flags |
259 | * |
260 | * @return bool true if it was successful |
261 | */ |
262 | public static function leaveUserMessage( $user, $wikiPage, $subject, $text, $signature, |
263 | $summary, $editor, $flags |
264 | ) { |
265 | $text = self::formatUserMessage( $subject, $text, $signature ); |
266 | $flags = $wikiPage->checkFlags( $flags ); |
267 | |
268 | if ( $flags & EDIT_UPDATE ) { |
269 | $content = $wikiPage->getContent( RevisionRecord::RAW ); |
270 | if ( $content !== null ) { |
271 | $text = $content->getNativeData() . "\n" . $text; |
272 | } |
273 | } |
274 | |
275 | $status = $wikiPage->doUserEditContent( |
276 | ContentHandler::makeContent( $text, $wikiPage->getTitle() ), |
277 | $editor, |
278 | $summary, |
279 | $flags |
280 | ); |
281 | return $status->isGood(); |
282 | } |
283 | |
284 | /** |
285 | * Format the user message using a hook, a template, or, failing these, a static format. |
286 | * @param string $subject the subject of the message |
287 | * @param string $text the content of the message |
288 | * @param string $signature the signature, if provided. |
289 | * @return string in wiki text with complete user message |
290 | */ |
291 | protected static function formatUserMessage( $subject, $text, $signature ) { |
292 | $contents = ""; |
293 | $signature = $signature === '' ? "~~~~" : "{$signature} ~~~~~"; |
294 | |
295 | if ( $subject ) { |
296 | $contents .= "== $subject ==\n\n"; |
297 | } |
298 | $contents .= "$text\n\n-- $signature\n"; |
299 | |
300 | return $contents; |
301 | } |
302 | |
303 | /** |
304 | * @param string $name |
305 | * @return Message |
306 | */ |
307 | protected static function getMsg( $name ) { |
308 | return wfMessage( $name )->inContentLanguage(); |
309 | } |
310 | } |