Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 55
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
AbuseFilterChangesList
0.00% covered (danger)
0.00%
0 / 55
0.00% covered (danger)
0.00%
0 / 7
420
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 insertExtra
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
56
 recentChangesLine
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
20
 insertUserRelatedLinks
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
 insertComment
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
 insertLogEntry
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 insertRollback
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Extension\AbuseFilter;
4
5use HtmlArmor;
6use IContextSource;
7use LogFormatter;
8use MediaWiki\Linker\Linker;
9use MediaWiki\MediaWikiServices;
10use MediaWiki\Revision\RevisionRecord;
11use MediaWiki\SpecialPage\SpecialPage;
12use OldChangesList;
13use RecentChange;
14
15class AbuseFilterChangesList extends OldChangesList {
16
17    /**
18     * @var string
19     */
20    private $testFilter;
21
22    /**
23     * @param IContextSource $context
24     * @param string $testFilter
25     */
26    public function __construct( IContextSource $context, $testFilter ) {
27        parent::__construct( $context );
28        $this->testFilter = $testFilter;
29    }
30
31    /**
32     * @param string &$s
33     * @param RecentChange &$rc
34     * @param string[] &$classes
35     */
36    public function insertExtra( &$s, &$rc, &$classes ) {
37        if ( (int)$rc->getAttribute( 'rc_deleted' ) !== 0 ) {
38            $s .= ' ' . $this->msg( 'abusefilter-log-hidden-implicit' )->parse();
39            if ( !$this->userCan( $rc, RevisionRecord::SUPPRESSED_ALL ) ) {
40                // Remember to keep this in sync with the CheckMatch API
41                return;
42            }
43        }
44
45        $examineParams = [];
46        if ( $this->testFilter && strlen( $this->testFilter ) < 2000 ) {
47            // Since this is GETed, don't send it if it's too long to prevent broken URLs 2000 is taken from
48            // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-
49            // in-different-browsers/417184#417184
50            $examineParams['testfilter'] = $this->testFilter;
51        }
52
53        $title = SpecialPage::getTitleFor( 'AbuseFilter', 'examine/' . $rc->getAttribute( 'rc_id' ) );
54        $examineLink = $this->linkRenderer->makeLink(
55            $title,
56            new HtmlArmor( $this->msg( 'abusefilter-changeslist-examine' )->parse() ),
57            [],
58            $examineParams
59        );
60
61        $s .= ' ' . $this->msg( 'parentheses' )->rawParams( $examineLink )->escaped();
62
63        // Add CSS classes for match and not match
64        if ( isset( $rc->filterResult ) ) {
65            $class = $rc->filterResult ?
66                'mw-abusefilter-changeslist-match' :
67                'mw-abusefilter-changeslist-nomatch';
68
69            $classes[] = $class;
70        }
71    }
72
73    /**
74     * Overridden as a hacky workaround for T273387. Yuck!
75     * @inheritDoc
76     */
77    public function recentChangesLine( &$rc, $watched = false, $linenumber = null ) {
78        $par = parent::recentChangesLine( $rc, $watched, $linenumber );
79        if ( $par === false || $par === '' ) {
80            return $par;
81        }
82        $ret = preg_replace( '/<\/li>$/', '', $par );
83        if ( $rc->getAttribute( 'rc_source' ) === 'flow' ) {
84            $classes = [];
85            $this->insertExtra( $ret, $rc, $classes );
86        }
87        return $ret . '</li>';
88    }
89
90    /**
91     * Insert links to user page, user talk page and eventually a blocking link.
92     *   Like the parent, but don't hide details if user can see them.
93     *
94     * @param string &$s HTML to update
95     * @param RecentChange &$rc
96     */
97    public function insertUserRelatedLinks( &$s, &$rc ) {
98        $links = $this->getLanguage()->getDirMark() . Linker::userLink( $rc->getAttribute( 'rc_user' ),
99                $rc->getAttribute( 'rc_user_text' ) ) .
100                Linker::userToolLinks( $rc->getAttribute( 'rc_user' ), $rc->getAttribute( 'rc_user_text' ) );
101
102        if ( $this->isDeleted( $rc, RevisionRecord::DELETED_USER ) ) {
103            if ( $this->userCan( $rc, RevisionRecord::DELETED_USER ) ) {
104                $s .= ' <span class="history-deleted">' . $links . '</span>';
105            } else {
106                $s .= ' <span class="history-deleted">' .
107                    $this->msg( 'rev-deleted-user' )->escaped() . '</span>';
108            }
109        } else {
110            $s .= $links;
111        }
112    }
113
114    /**
115     * Insert a formatted comment. Like the parent, but don't hide details if user can see them.
116     * @param RecentChange $rc
117     * @return string
118     */
119    public function insertComment( $rc ) {
120        if ( $this->isDeleted( $rc, RevisionRecord::DELETED_COMMENT ) ) {
121            if ( $this->userCan( $rc, RevisionRecord::DELETED_COMMENT ) ) {
122                return ' <span class="history-deleted">' .
123                    MediaWikiServices::getInstance()->getCommentFormatter()
124                        ->formatBlock( $rc->getAttribute( 'rc_comment' ), $rc->getTitle() ) . '</span>';
125            } else {
126                return ' <span class="history-deleted">' .
127                    $this->msg( 'rev-deleted-comment' )->escaped() . '</span>';
128            }
129        } else {
130            return MediaWikiServices::getInstance()->getCommentFormatter()
131                ->formatBlock( $rc->getAttribute( 'rc_comment' ), $rc->getTitle() );
132        }
133    }
134
135    /**
136     * Insert a formatted action. The same as parent, but with a different audience in LogFormatter
137     *
138     * @param RecentChange $rc
139     * @return string
140     */
141    public function insertLogEntry( $rc ) {
142        $formatter = LogFormatter::newFromRow( $rc->getAttributes() );
143        $formatter->setContext( $this->getContext() );
144        $formatter->setAudience( LogFormatter::FOR_THIS_USER );
145        $formatter->setShowUserToolLinks( true );
146        $mark = $this->getLanguage()->getDirMark();
147        return $formatter->getActionText() . " $mark" . $formatter->getComment();
148    }
149
150    /**
151     * @param string &$s
152     * @param RecentChange &$rc
153     */
154    public function insertRollback( &$s, &$rc ) {
155        // Kill rollback links.
156    }
157}