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