Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
77.50% |
62 / 80 |
|
50.00% |
2 / 4 |
CRAP | |
0.00% |
0 / 1 |
AutoModeratorSendRevertTalkPageMsgJob | |
77.50% |
62 / 80 |
|
50.00% |
2 / 4 |
14.93 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
1 | |||
run | |
80.77% |
42 / 52 |
|
0.00% |
0 / 1 |
7.35 | |||
setAllowRetries | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
allowRetries | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
ignoreDuplicates | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
createTalkPageMessageContent | |
50.00% |
8 / 16 |
|
0.00% |
0 / 1 |
2.50 |
1 | <?php |
2 | /** |
3 | * This program is free software: you can redistribute it and/or modify |
4 | * it under the terms of the GNU General Public License as published by |
5 | * the Free Software Foundation, either version 3 of the License, or |
6 | * (at your option) any later version. |
7 | * |
8 | * This program is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | * GNU General Public License for more details. |
12 | * |
13 | * You should have received a copy of the GNU General Public License |
14 | * along with this program. If not, see <http:www.gnu.org/licenses/>. |
15 | */ |
16 | |
17 | namespace AutoModerator\Services; |
18 | |
19 | use AutoModerator\Config\AutoModeratorConfigLoaderStaticTrait; |
20 | use Content; |
21 | use Job; |
22 | use MediaWiki\CommentStore\CommentStoreComment; |
23 | use MediaWiki\Logger\LoggerFactory; |
24 | use MediaWiki\MediaWikiServices; |
25 | use MediaWiki\Revision\SlotRecord; |
26 | use MediaWiki\Title\Title; |
27 | use RuntimeException; |
28 | |
29 | class AutoModeratorSendRevertTalkPageMsgJob extends Job { |
30 | |
31 | use AutoModeratorConfigLoaderStaticTrait; |
32 | |
33 | /** |
34 | * @var bool |
35 | */ |
36 | private bool $isRetryable = true; |
37 | |
38 | /** |
39 | * @var int |
40 | */ |
41 | private $wikiPageId; |
42 | |
43 | /** |
44 | * @var int |
45 | */ |
46 | private $revId; |
47 | |
48 | /** |
49 | * @var int |
50 | */ |
51 | private int $parentRevId; |
52 | |
53 | /** |
54 | * @var ?string |
55 | */ |
56 | private ?string $pageTitle; |
57 | |
58 | /** |
59 | * @var int |
60 | */ |
61 | private int $autoModeratorUserId; |
62 | |
63 | /** |
64 | * @var string |
65 | */ |
66 | private string $autoModeratorUserName; |
67 | |
68 | /** |
69 | * @var string |
70 | */ |
71 | private string $talkPageMessageHeader; |
72 | |
73 | /** |
74 | * @var string |
75 | */ |
76 | private string $talkPageMessageEditSummary; |
77 | |
78 | /** |
79 | * @var string |
80 | */ |
81 | private string $falsePositiveReportPage; |
82 | |
83 | /** |
84 | * @var string |
85 | */ |
86 | private string $wikiId; |
87 | |
88 | /** |
89 | * @var string |
90 | */ |
91 | private string $NOT_WIKI_TEXT_ERROR_MESSAGE = 'Failed to send AutoModerator revert talk page message |
92 | due to content model not being wikitext the current content model is: '; |
93 | |
94 | /** |
95 | * @var string |
96 | */ |
97 | private string $NO_USER_TALK_PAGE_ERROR_MESSAGE = "Failed to retrieve user talk page title |
98 | for sending AutoModerator revert talk page message."; |
99 | |
100 | /** |
101 | * @var string |
102 | */ |
103 | private string $NO_PARENT_REVISION_FOUND = "Failed to retrieve reverted revision from revision store."; |
104 | |
105 | /** |
106 | * @var string |
107 | */ |
108 | private string $NO_CONTENT_TALK_PAGE_ERROR_MESSAGE = "Failed to create AutoModerator revert message |
109 | content for talk page."; |
110 | |
111 | /** |
112 | * @var string |
113 | */ |
114 | private string $CREATE_TALK_PAGE_ERROR_MESSAGE = "Failed to create message for sending AutoModerator revert |
115 | talk page message."; |
116 | |
117 | /** |
118 | * @param Title $title |
119 | * @param array $params |
120 | * - 'wikiPageId': (int) |
121 | * - 'revId': (int) |
122 | * - 'parentRevId': (int) |
123 | * - 'autoModeratorUserId': (int) |
124 | * - 'autoModeratorUserName': (string) |
125 | * - 'talkPageMessageHeader': (string) |
126 | * - 'talkPageMessageEditSummary': (string) |
127 | * - 'falsePositiveReportPage': (string) |
128 | * - 'wikiId': (string) |
129 | */ |
130 | public function __construct( Title $title, array $params ) { |
131 | parent::__construct( 'AutoModeratorSendRevertTalkPageMsgJob', $title, $params ); |
132 | $this->pageTitle = $title; |
133 | $this->wikiPageId = $params['wikiPageId']; |
134 | $this->revId = $params['revId']; |
135 | $this->parentRevId = $params['parentRevId']; |
136 | $this->autoModeratorUserId = $params['autoModeratorUserId']; |
137 | $this->autoModeratorUserName = $params['autoModeratorUserName']; |
138 | $this->talkPageMessageHeader = $params['talkPageMessageHeader']; |
139 | $this->talkPageMessageEditSummary = $params['talkPageMessageEditSummary']; |
140 | $this->falsePositiveReportPage = $params['falsePositiveReportPage'] ?? ""; |
141 | $this->wikiId = $params['wikiId']; |
142 | } |
143 | |
144 | public function run(): bool { |
145 | $logger = LoggerFactory::getInstance( 'AutoModerator' ); |
146 | try { |
147 | $services = MediaWikiServices::getInstance(); |
148 | $userFactory = $services->getUserFactory(); |
149 | $revisionStore = $services->getRevisionStore(); |
150 | $parentRevision = $revisionStore->getRevisionById( $this->parentRevId ); |
151 | if ( !$parentRevision ) { |
152 | $this->setLastError( $this->NO_PARENT_REVISION_FOUND ); |
153 | $this->setAllowRetries( false ); |
154 | return false; |
155 | } |
156 | $userTalkPageTitle = $services->getTitleFactory()->makeTitleSafe( |
157 | NS_USER_TALK, |
158 | $parentRevision->getUser()->getName() |
159 | ); |
160 | if ( !$userTalkPageTitle ) { |
161 | $this->setLastError( $this->NO_USER_TALK_PAGE_ERROR_MESSAGE ); |
162 | $this->setAllowRetries( false ); |
163 | return false; |
164 | } |
165 | $autoModeratorUser = $userFactory->newFromAnyId( |
166 | $this->params['autoModeratorUserId'], |
167 | $this->params['autoModeratorUserName'] |
168 | ); |
169 | $userTalkPage = $services->getWikiPageFactory()->newFromTitle( $userTalkPageTitle ); |
170 | $currentContentModel = $userTalkPage->getContentModel(); |
171 | if ( $currentContentModel !== CONTENT_MODEL_WIKITEXT ) { |
172 | $logger->error( $this->NOT_WIKI_TEXT_ERROR_MESSAGE . $currentContentModel ); |
173 | $this->setLastError( $this->NOT_WIKI_TEXT_ERROR_MESSAGE . $currentContentModel ); |
174 | $this->setAllowRetries( false ); |
175 | return false; |
176 | } |
177 | $updatedContent = $this->createTalkPageMessageContent( |
178 | $userTalkPage->getContent(), |
179 | $this->talkPageMessageHeader, |
180 | wfMessage( 'automoderator-wiki-revert-message' )->params( |
181 | $this->autoModeratorUserName, |
182 | $this->revId, |
183 | $this->pageTitle, |
184 | $this->falsePositiveReportPage )->plain(), |
185 | $userTalkPageTitle, |
186 | $currentContentModel ); |
187 | if ( !$updatedContent ) { |
188 | $logger->error( $this->NO_CONTENT_TALK_PAGE_ERROR_MESSAGE ); |
189 | $this->setLastError( $this->NO_CONTENT_TALK_PAGE_ERROR_MESSAGE ); |
190 | return false; |
191 | } |
192 | $userTalkPage |
193 | ->newPageUpdater( $autoModeratorUser ) |
194 | ->setContent( SlotRecord::MAIN, $updatedContent ) |
195 | ->saveRevision( CommentStoreComment::newUnsavedComment( $this->talkPageMessageEditSummary ), |
196 | $userTalkPage->exists() ? EDIT_UPDATE : EDIT_NEW ); |
197 | } catch ( RuntimeException $e ) { |
198 | $this->setLastError( $this->CREATE_TALK_PAGE_ERROR_MESSAGE ); |
199 | $logger->error( $this->CREATE_TALK_PAGE_ERROR_MESSAGE ); |
200 | return false; |
201 | } |
202 | return true; |
203 | } |
204 | |
205 | private function setAllowRetries( bool $isRetryable ) { |
206 | $this->isRetryable = $isRetryable; |
207 | } |
208 | |
209 | /** |
210 | * @inheritDoc |
211 | * @codeCoverageIgnore |
212 | */ |
213 | public function allowRetries(): bool { |
214 | return $this->isRetryable; |
215 | } |
216 | |
217 | /** |
218 | * @inheritDoc |
219 | * @codeCoverageIgnore |
220 | */ |
221 | public function ignoreDuplicates(): bool { |
222 | return true; |
223 | } |
224 | |
225 | /** |
226 | * @param ?Content $currentContent |
227 | * @param string $headerRawMessage |
228 | * @param string $messageContent |
229 | * @param Title $userTalkPageTitle |
230 | * @return Content|null |
231 | */ |
232 | private function createTalkPageMessageContent( ?Content $currentContent, |
233 | string $headerRawMessage, |
234 | string $messageContent, |
235 | Title $userTalkPageTitle, |
236 | string $contentModel ): ?Content { |
237 | if ( $currentContent ) { |
238 | $newLine = "\n"; |
239 | return $currentContent->getContentHandler()->makeContent( |
240 | $currentContent->getWikitextForTransclusion() . $newLine . $headerRawMessage . $newLine . |
241 | $messageContent, |
242 | $userTalkPageTitle, |
243 | $contentModel |
244 | ); |
245 | } else { |
246 | $contentHandler = MediaWikiServices::getInstance() |
247 | ->getContentHandlerFactory() |
248 | ->getContentHandler( $contentModel ); |
249 | return $contentHandler->makeContent( |
250 | $headerRawMessage . $messageContent, |
251 | $userTalkPageTitle, |
252 | $contentModel |
253 | ); |
254 | } |
255 | } |
256 | } |