Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
88.46% |
46 / 52 |
|
50.00% |
2 / 4 |
CRAP | |
0.00% |
0 / 1 |
RecentChangeSaveHookHandler | |
88.46% |
46 / 52 |
|
50.00% |
2 / 4 |
21.68 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
handle | |
84.62% |
11 / 13 |
|
0.00% |
0 / 1 |
8.23 | |||
checkModel | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
8 | |||
triggerJob | |
84.00% |
21 / 25 |
|
0.00% |
0 / 1 |
4.07 |
1 | <?php |
2 | /** |
3 | * Copyright (C) 2016 Brad Jorsch <bjorsch@wikimedia.org> |
4 | * |
5 | * This program is free software: you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation, either version 3 of the License, or |
8 | * (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License |
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | */ |
18 | |
19 | namespace ORES\Hooks; |
20 | |
21 | use Exception; |
22 | use MediaWiki\MediaWikiServices; |
23 | use MediaWiki\Request\WebRequest; |
24 | use ORES\Services\FetchScoreJob; |
25 | use Psr\Log\LoggerInterface; |
26 | use RecentChange; |
27 | |
28 | class RecentChangeSaveHookHandler { |
29 | |
30 | /** |
31 | * @var LoggerInterface |
32 | */ |
33 | private $logger; |
34 | |
35 | /** |
36 | * @var WebRequest |
37 | */ |
38 | private $request; |
39 | |
40 | /** |
41 | * @param LoggerInterface $logger |
42 | * @param WebRequest $request |
43 | */ |
44 | public function __construct( LoggerInterface $logger, WebRequest $request ) { |
45 | $this->logger = $logger; |
46 | $this->request = $request; |
47 | } |
48 | |
49 | /** |
50 | * @param RecentChange $rc |
51 | * @param array[] $modelsConfig |
52 | * @param bool $excludeBots |
53 | * @param bool[] $enabledNamespaces |
54 | */ |
55 | public function handle( |
56 | RecentChange $rc, |
57 | array $modelsConfig, |
58 | $excludeBots, |
59 | array $enabledNamespaces |
60 | ) { |
61 | if ( $rc->getAttribute( 'rc_bot' ) && $excludeBots ) { |
62 | return; |
63 | } |
64 | |
65 | // Check if we actually want score for this namespace |
66 | $ns = $rc->getAttribute( 'rc_namespace' ); |
67 | if ( $enabledNamespaces && |
68 | !( isset( $enabledNamespaces[$ns] ) && $enabledNamespaces[$ns] ) |
69 | ) { |
70 | return; |
71 | } |
72 | |
73 | $models = []; |
74 | foreach ( $modelsConfig as $model => $modelConfig ) { |
75 | $add = $this->checkModel( $rc, $modelConfig ); |
76 | if ( $add ) { |
77 | $models[] = $model; |
78 | } |
79 | } |
80 | |
81 | ( new HookRunner( MediaWikiServices::getInstance()->getHookContainer() ) )->onORESCheckModels( $rc, $models ); |
82 | |
83 | $this->triggerJob( $rc, $models ); |
84 | } |
85 | |
86 | private function checkModel( RecentChange $rc, array $config ): bool { |
87 | if ( $config['enabled'] !== true ) { |
88 | return false; |
89 | } |
90 | |
91 | $acceptedTypes = $config['types'] ?? [ RC_EDIT, RC_NEW ]; |
92 | if ( !in_array( $rc->getAttribute( 'rc_type' ), $acceptedTypes ) ) { |
93 | return false; |
94 | } |
95 | |
96 | $ns = $rc->getAttribute( 'rc_namespace' ); |
97 | if ( isset( $config['namespaces'] ) && !in_array( $ns, $config['namespaces'] ) ) { |
98 | return false; |
99 | } |
100 | |
101 | if ( isset( $config['excludeBots'] ) && $config['excludeBots'] !== false && |
102 | $rc->getAttribute( 'rc_bot' ) |
103 | ) { |
104 | return false; |
105 | } |
106 | |
107 | return true; |
108 | } |
109 | |
110 | private function triggerJob( RecentChange $rc, array $models ) { |
111 | if ( $models === [] ) { |
112 | return; |
113 | } |
114 | |
115 | $revid = $rc->getAttribute( 'rc_this_oldid' ); |
116 | $this->logger->debug( 'Processing edit {revid}', [ |
117 | 'revid' => $revid, |
118 | ] ); |
119 | $ua = $this->request->getHeader( 'User-Agent' ); |
120 | $ua = $ua !== false ? $this->request->normalizeUnicode( $ua ) : false; |
121 | $job = new FetchScoreJob( $rc->getTitle(), [ |
122 | 'revid' => $revid, |
123 | 'originalRequest' => [ |
124 | 'ip' => $this->request->getIP(), |
125 | 'userAgent' => $ua, |
126 | ], |
127 | 'models' => $models, |
128 | 'precache' => true, |
129 | ] ); |
130 | try { |
131 | MediaWikiServices::getInstance()->getJobQueueGroup()->push( $job ); |
132 | $this->logger->debug( 'Job pushed for {revid}', [ |
133 | 'revid' => $revid, |
134 | ] ); |
135 | } catch ( Exception $e ) { |
136 | $this->logger->error( 'Job push failed for {revid}', [ |
137 | 'revid' => $revid, |
138 | ] ); |
139 | } |
140 | } |
141 | |
142 | } |