Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
68.33% covered (warning)
68.33%
41 / 60
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
MachineReadableRCFeedFormatter
68.33% covered (warning)
68.33%
41 / 60
0.00% covered (danger)
0.00%
0 / 1
24.13
0.00% covered (danger)
0.00%
0 / 1
 formatArray
n/a
0 / 0
n/a
0 / 0
0
 getLine
68.33% covered (warning)
68.33%
41 / 60
0.00% covered (danger)
0.00%
0 / 1
24.13
1<?php
2
3/**
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 * http://www.gnu.org/copyleft/gpl.html
18 *
19 * @file
20 */
21
22use MediaWiki\MainConfigNames;
23use MediaWiki\MediaWikiServices;
24use MediaWiki\WikiMap\WikiMap;
25
26/**
27 * Abstract class so there can be multiple formatters outputting the same data
28 *
29 * @since 1.23
30 */
31abstract class MachineReadableRCFeedFormatter implements RCFeedFormatter {
32
33    /**
34     * Take the packet and return the formatted string
35     * @param array $packet
36     * @return string
37     */
38    abstract protected function formatArray( array $packet );
39
40    /**
41     * Generates a notification that can be easily interpreted by a machine.
42     * @see RCFeedFormatter::getLine
43     * @param array $feed
44     * @param RecentChange $rc
45     * @param string|null $actionComment
46     * @return string|null
47     */
48    public function getLine( array $feed, RecentChange $rc, $actionComment ) {
49        $mainConfig = MediaWikiServices::getInstance()->getMainConfig();
50        $canonicalServer = $mainConfig->get( MainConfigNames::CanonicalServer );
51        $serverName = $mainConfig->get( MainConfigNames::ServerName );
52        $scriptPath = $mainConfig->get( MainConfigNames::ScriptPath );
53        $packet = [
54            // Usually, RC ID is exposed only for patrolling purposes,
55            // but there is no real reason not to expose it in other cases,
56            // and I can see how this may be potentially useful for clients.
57            'id' => $rc->getAttribute( 'rc_id' ),
58            'type' => RecentChange::parseFromRCType( $rc->getAttribute( 'rc_type' ) ),
59            'namespace' => $rc->getTitle()->getNamespace(),
60            'title' => $rc->getTitle()->getPrefixedText(),
61            'title_url' => $rc->getTitle()->getCanonicalURL(),
62            'comment' => $rc->getAttribute( 'rc_comment' ),
63            'timestamp' => (int)wfTimestamp( TS_UNIX, $rc->getAttribute( 'rc_timestamp' ) ),
64            'user' => $rc->getAttribute( 'rc_user_text' ),
65            'bot' => (bool)$rc->getAttribute( 'rc_bot' ),
66            'notify_url' => $rc->getNotifyUrl(),
67        ];
68
69        if ( isset( $feed['channel'] ) ) {
70            $packet['channel'] = $feed['channel'];
71        }
72
73        $type = $rc->getAttribute( 'rc_type' );
74        if ( $type == RC_EDIT || $type == RC_NEW ) {
75            $useRCPatrol = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::UseRCPatrol );
76            $useNPPatrol = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::UseNPPatrol );
77            $packet['minor'] = (bool)$rc->getAttribute( 'rc_minor' );
78            if ( $useRCPatrol || ( $type == RC_NEW && $useNPPatrol ) ) {
79                $packet['patrolled'] = (bool)$rc->getAttribute( 'rc_patrolled' );
80            }
81        }
82
83        switch ( $type ) {
84            case RC_EDIT:
85                $packet['length'] = [
86                    'old' => $rc->getAttribute( 'rc_old_len' ),
87                    'new' => $rc->getAttribute( 'rc_new_len' )
88                ];
89                $packet['revision'] = [
90                    'old' => $rc->getAttribute( 'rc_last_oldid' ),
91                    'new' => $rc->getAttribute( 'rc_this_oldid' )
92                ];
93                break;
94
95            case RC_NEW:
96                $packet['length'] = [ 'old' => null, 'new' => $rc->getAttribute( 'rc_new_len' ) ];
97                $packet['revision'] = [ 'old' => null, 'new' => $rc->getAttribute( 'rc_this_oldid' ) ];
98                break;
99
100            case RC_LOG:
101                $packet['log_id'] = $rc->getAttribute( 'rc_logid' );
102                $packet['log_type'] = $rc->getAttribute( 'rc_log_type' );
103                $packet['log_action'] = $rc->getAttribute( 'rc_log_action' );
104                if ( $rc->getAttribute( 'rc_params' ) ) {
105                    $params = $rc->parseParams();
106                    if (
107                        // If it's an actual serialised false...
108                        $rc->getAttribute( 'rc_params' ) == serialize( false ) ||
109                        // Or if we did not get false back when trying to unserialise
110                        $params !== false
111                    ) {
112                        // From ApiQueryLogEvents::addLogParams
113                        $logParams = [];
114                        // Keys like "4::paramname" can't be used for output so we change them to "paramname"
115                        foreach ( $params as $key => $value ) {
116                            if ( strpos( $key, ':' ) === false ) {
117                                $logParams[$key] = $value;
118                                continue;
119                            }
120                            $logParam = explode( ':', $key, 3 );
121                            $logParams[$logParam[2]] = $value;
122                        }
123                        $packet['log_params'] = $logParams;
124                    } else {
125                        $packet['log_params'] = explode( "\n", $rc->getAttribute( 'rc_params' ) );
126                    }
127                }
128                $packet['log_action_comment'] = $actionComment;
129                break;
130        }
131
132        $packet['server_url'] = $canonicalServer;
133        $packet['server_name'] = $serverName;
134
135        $packet['server_script_path'] = $scriptPath ?: '/';
136        $packet['wiki'] = WikiMap::getCurrentWikiId();
137
138        return $this->formatArray( $packet );
139    }
140}