Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 71 |
|
0.00% |
0 / 2 |
CRAP | |
0.00% |
0 / 1 |
MassMessageRequestParser | |
0.00% |
0 / 71 |
|
0.00% |
0 / 2 |
600 | |
0.00% |
0 / 1 |
parseRequest | |
0.00% |
0 / 53 |
|
0.00% |
0 / 1 |
182 | |||
getSpamlist | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
132 |
1 | <?php |
2 | declare( strict_types = 1 ); |
3 | |
4 | namespace MediaWiki\MassMessage\RequestProcessing; |
5 | |
6 | use MediaWiki\MassMessage\Services; |
7 | use MediaWiki\MassMessage\UrlHelper; |
8 | use MediaWiki\MediaWikiServices; |
9 | use MediaWiki\Revision\SlotRecord; |
10 | use MediaWiki\Status\Status; |
11 | use MediaWiki\Title\Title; |
12 | use MediaWiki\User\UserIdentity; |
13 | use MediaWiki\WikiMap\WikiMap; |
14 | use function wfMessage; |
15 | |
16 | /** |
17 | * Parses request submitted by user for sending a mass message |
18 | * @author Abijeet Patro |
19 | * @since 2021.12 |
20 | * @license GPL-2.0-or-later |
21 | */ |
22 | class MassMessageRequestParser { |
23 | /** |
24 | * @param array $data |
25 | * @param UserIdentity $user |
26 | * @return Status |
27 | */ |
28 | public function parseRequest( array $data, UserIdentity $user ): Status { |
29 | // Trim all the things! |
30 | foreach ( $data as $k => $v ) { |
31 | if ( is_string( $v ) ) { |
32 | $data[$k] = trim( $v ); |
33 | } |
34 | } |
35 | |
36 | $status = new Status(); |
37 | $currentWikiId = WikiMap::getCurrentWikiId(); |
38 | |
39 | $data['page-message'] ??= ''; |
40 | $data['page-message-section'] ??= ''; |
41 | $data['page-subject-section'] ??= ''; |
42 | $data['message'] ??= ''; |
43 | $data['subject'] ??= ''; |
44 | |
45 | if ( $data['subject'] === '' && $data['page-subject-section'] === '' ) { |
46 | $status->fatal( 'massmessage-empty-subject' ); |
47 | } |
48 | |
49 | $spamlist = self::getSpamlist( $data['spamlist'] ); |
50 | if ( $spamlist instanceof Title ) { |
51 | // Prep the HTML comment message |
52 | if ( $spamlist->inNamespace( NS_CATEGORY ) ) { |
53 | $url = $spamlist->getFullURL(); |
54 | } else { |
55 | $url = $spamlist->getFullURL( |
56 | [ 'oldid' => $spamlist->getLatestRevID() ], |
57 | false, |
58 | PROTO_CANONICAL |
59 | ); |
60 | } |
61 | |
62 | $data['comment'] = [ $user->getName(), $currentWikiId, $url ]; |
63 | } else { |
64 | // $spamlist contains a message key for an error message |
65 | $status->fatal( $spamlist ); |
66 | // Set dummy values in order to continue validation |
67 | $spamlist = Title::newMainPage(); |
68 | $data['comment'] = []; |
69 | } |
70 | |
71 | $footer = wfMessage( 'massmessage-message-footer' )->inContentLanguage()->plain(); |
72 | if ( trim( $footer ) ) { |
73 | // Only add the footer if it is not just whitespace |
74 | $data['message'] .= "\n" . $footer; |
75 | } |
76 | |
77 | $request = new MassMessageRequest( |
78 | $spamlist, |
79 | $data['subject'], |
80 | $data['page-message'], |
81 | $data['page-message-section'], |
82 | $data['page-subject-section'], |
83 | $data['message'], |
84 | $data['comment'] |
85 | ); |
86 | |
87 | $pageMessageBuilderResult = null; |
88 | if ( $request->hasPageMessage() ) { |
89 | $pageMessageBuilder = Services::getInstance()->getPageMessageBuilder(); |
90 | $pageMessageBuilderResult = $pageMessageBuilder->getContent( |
91 | $request->getPageMessage(), |
92 | $request->getPageMessageSection(), |
93 | $request->getPageSubjectSection(), |
94 | $currentWikiId |
95 | ); |
96 | |
97 | if ( !$pageMessageBuilderResult->isOK() ) { |
98 | $status->merge( $pageMessageBuilderResult->getStatus() ); |
99 | } |
100 | } |
101 | |
102 | if ( !$request->hasMessage() && !$pageMessageBuilderResult ) { |
103 | $status->fatal( 'massmessage-empty-message' ); |
104 | } |
105 | |
106 | if ( $status->isOK() ) { |
107 | $status->setResult( true, $request ); |
108 | } |
109 | |
110 | return $status; |
111 | } |
112 | |
113 | /** |
114 | * Parse and normalize the spamlist |
115 | * @param string $title |
116 | * @return Title|string string will be a error message key |
117 | */ |
118 | private static function getSpamlist( string $title ) { |
119 | $spamlist = Title::newFromText( $title ); |
120 | |
121 | // Simply return the title if it is a category |
122 | if ( $spamlist !== null && $spamlist->inNamespace( NS_CATEGORY ) ) { |
123 | return $spamlist; |
124 | } |
125 | |
126 | if ( $spamlist === null || !$spamlist->exists() ) { |
127 | return 'massmessage-spamlist-doesnotexist'; |
128 | } |
129 | |
130 | // Page exists, follow a redirect if possible |
131 | $target = UrlHelper::followRedirect( $spamlist ); |
132 | if ( $target === null || !$target->exists() ) { |
133 | // Interwiki redirect or non-existent page. |
134 | return 'massmessage-spamlist-invalid'; |
135 | } |
136 | $spamlist = $target; |
137 | |
138 | $contentModel = $spamlist->getContentModel(); |
139 | |
140 | if ( ( $contentModel !== 'MassMessageListContent' && $contentModel !== CONTENT_MODEL_WIKITEXT ) |
141 | || ( $contentModel === 'MassMessageListContent' && !MediaWikiServices::getInstance() |
142 | ->getRevisionLookup() |
143 | ->getRevisionByTitle( $spamlist ) |
144 | ->getContent( SlotRecord::MAIN ) |
145 | ->isValid() |
146 | ) |
147 | ) { |
148 | return 'massmessage-spamlist-invalid'; |
149 | } |
150 | |
151 | return $spamlist; |
152 | } |
153 | } |