Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
92.00% |
69 / 75 |
|
66.67% |
2 / 3 |
CRAP | |
0.00% |
0 / 1 |
AutoModeratorFetchRevScoreJob | |
92.00% |
69 / 75 |
|
66.67% |
2 / 3 |
14.10 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
run | |
91.18% |
62 / 68 |
|
0.00% |
0 / 1 |
10.07 | |||
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 |
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 AutoModerator\RevisionCheck; |
21 | use AutoModerator\Util; |
22 | use Job; |
23 | use MediaWiki\Logger\LoggerFactory; |
24 | use MediaWiki\MediaWikiServices; |
25 | use MediaWiki\Revision\RevisionRecord; |
26 | use MediaWiki\Revision\SlotRecord; |
27 | use MediaWiki\Title\Title; |
28 | use RuntimeException; |
29 | |
30 | class AutoModeratorFetchRevScoreJob extends Job { |
31 | |
32 | use AutoModeratorConfigLoaderStaticTrait; |
33 | |
34 | /** |
35 | * @var int |
36 | */ |
37 | private $wikiPageId; |
38 | |
39 | /** |
40 | * @var int |
41 | */ |
42 | private $revId; |
43 | |
44 | /** |
45 | * @var int|false |
46 | */ |
47 | private $originalRevId; |
48 | |
49 | /** |
50 | * @var string[] |
51 | */ |
52 | private $tags; |
53 | |
54 | /** |
55 | * @var bool |
56 | */ |
57 | private bool $isRetryable = true; |
58 | |
59 | /** |
60 | * @var string |
61 | */ |
62 | private string $undoSummary; |
63 | |
64 | /** |
65 | * @param Title $title |
66 | * @param array $params |
67 | * - 'wikiPageId': (int) |
68 | * - 'revId': (int) |
69 | * - 'originalRevId': (int|false) |
70 | * - 'userId': (int) |
71 | * - 'userName': (string) |
72 | * - 'tags': (string[]) |
73 | * - 'undoSummary': (string) |
74 | */ |
75 | public function __construct( Title $title, array $params ) { |
76 | parent::__construct( 'AutoModeratorFetchRevScoreJob', $title, $params ); |
77 | $this->wikiPageId = $params[ 'wikiPageId' ]; |
78 | $this->revId = $params[ 'revId' ]; |
79 | $this->originalRevId = $params[ 'originalRevId' ]; |
80 | $this->tags = $params[ 'tags' ]; |
81 | $this->undoSummary = $params[ 'undoSummary' ]; |
82 | } |
83 | |
84 | public function run(): bool { |
85 | $services = MediaWikiServices::getInstance(); |
86 | $wikiPageFactory = $services->getWikiPageFactory(); |
87 | $revisionStore = $services->getRevisionStore(); |
88 | $contentHandlerFactory = $services->getContentHandlerFactory(); |
89 | $userGroupManager = $services->getUserGroupManager(); |
90 | $restrictionStore = $services->getRestrictionStore(); |
91 | $config = $services->getMainConfig(); |
92 | $wikiConfig = $this->getAutoModeratorWikiConfig(); |
93 | $userFactory = $services->getUserFactory(); |
94 | $user = $userFactory->newFromAnyId( |
95 | $this->params['userId'], |
96 | $this->params['userName'] |
97 | ); |
98 | |
99 | $autoModeratorUser = Util::getAutoModeratorUser( $config, $userGroupManager ); |
100 | $wikiId = Util::getWikiID( $config ); |
101 | $logger = LoggerFactory::getInstance( 'AutoModerator' ); |
102 | $rev = $revisionStore->getRevisionById( $this->revId ); |
103 | if ( $rev === null ) { |
104 | $message = 'rev rev_id not found'; |
105 | $error = strtr( $message, [ |
106 | 'rev_id' => (string)$this->revId |
107 | ] ); |
108 | $this->setLastError( $error ); |
109 | $this->setAllowRetries( true ); |
110 | return false; |
111 | } |
112 | $contentHandler = $contentHandlerFactory->getContentHandler( $rev->getSlot( |
113 | SlotRecord::MAIN, |
114 | RevisionRecord::RAW |
115 | )->getModel() ); |
116 | |
117 | $liftWingClient = Util::initializeLiftWingClient( $config ); |
118 | $reverted = []; |
119 | try { |
120 | $response = $liftWingClient->get( $this->revId ); |
121 | $this->setAllowRetries( $response[ 'allowRetries' ] ?? true ); |
122 | if ( isset( $response['errorMessage'] ) ) { |
123 | $this->setLastError( $response['errorMessage'] ); |
124 | return false; |
125 | } |
126 | $revisionCheck = new RevisionCheck( |
127 | $this->wikiPageId, |
128 | $wikiPageFactory, |
129 | $this->revId, |
130 | $this->originalRevId, |
131 | $user, |
132 | $this->tags, |
133 | $autoModeratorUser, |
134 | $revisionStore, |
135 | $config, |
136 | $wikiConfig, |
137 | $contentHandler, |
138 | $logger, |
139 | $userGroupManager, |
140 | $restrictionStore, |
141 | $wikiId, |
142 | $this->undoSummary, |
143 | true |
144 | ); |
145 | $reverted = $revisionCheck->maybeRevert( $response ); |
146 | } catch ( RuntimeException $exception ) { |
147 | $this->setLastError( $exception->getMessage() ); |
148 | return false; |
149 | } |
150 | // Revision reverted |
151 | if ( array_key_exists( '1', $reverted ) && $reverted['1'] === 'success' ) { |
152 | return true; |
153 | } |
154 | // Revert attempted but failed |
155 | if ( array_key_exists( '0', $reverted ) && $reverted['0'] === 'failure' ) { |
156 | $this->setLastError( 'Revision ' . $this->revId . ' requires a manual revert.' ); |
157 | $this->setAllowRetries( false ); |
158 | return false; |
159 | } |
160 | // Revision passed check; noop. |
161 | if ( array_key_exists( '0', $reverted ) && $reverted['0'] === 'Not reverted' ) { |
162 | return true; |
163 | } |
164 | return false; |
165 | } |
166 | |
167 | private function setAllowRetries( bool $isRetryable ) { |
168 | $this->isRetryable = $isRetryable; |
169 | } |
170 | |
171 | /** |
172 | * @inheritDoc |
173 | * @codeCoverageIgnore |
174 | */ |
175 | public function allowRetries(): bool { |
176 | return $this->isRetryable; |
177 | } |
178 | |
179 | /** |
180 | * @inheritDoc |
181 | * @codeCoverageIgnore |
182 | */ |
183 | public function ignoreDuplicates(): bool { |
184 | return true; |
185 | } |
186 | } |