Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
29.55% covered (danger)
29.55%
13 / 44
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
ArticleCompileSnippet
29.55% covered (danger)
29.55%
13 / 44
33.33% covered (danger)
33.33%
1 / 3
131.31
0.00% covered (danger)
0.00%
0 / 1
 compile
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
42
 generateArticleSnippet
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
20
 hasReferenceTag
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
8
1<?php
2
3namespace MediaWiki\Extension\PageTriage\ArticleCompile;
4
5use MediaWiki\Content\TextContent;
6use MediaWiki\Language\Language;
7use MediaWiki\Language\MessageParser;
8use MediaWiki\MediaWikiServices;
9use MediaWiki\Parser\Sanitizer;
10use MediaWiki\Title\Title;
11
12/**
13 * Article snippet
14 */
15class ArticleCompileSnippet extends ArticleCompile {
16
17    /** @inheritDoc */
18    public function compile() {
19        $services = MediaWikiServices::getInstance();
20        $lang = $services->getContentLanguage();
21        $msgParser = $services->getMessageParser();
22        foreach ( $this->mPageId as $pageId ) {
23            $content = $this->getContentByPageId( $pageId );
24            if ( $content ) {
25                $text = ( $content instanceof TextContent ) ? $content->getText() : null;
26                if ( $text !== null ) {
27                    $this->metadata[$pageId]['snippet'] = self::generateArticleSnippet(
28                        $text, $pageId, $lang, $msgParser
29                    );
30                    // Reference tag (and other tags) have text strings as the value.
31                    $this->metadata[$pageId]['reference'] = $this->hasReferenceTag( $text ) ? '1' : '0';
32                }
33            }
34        }
35        return true;
36    }
37
38    /**
39     * Generate article snippet for listview from article text
40     * @param string $text page text
41     * @param int $pageId Id of the page
42     * @param Language $lang
43     * @param MessageParser $msgParser
44     * @return string
45     */
46    public static function generateArticleSnippet( string $text, int $pageId, Language $lang,
47        MessageParser $msgParser ) {
48        $text = strip_tags( $text );
49        $attempt = 0;
50        $title = Title::newFromID( $pageId );
51
52        // 10 attempts at most, the logic here is to find the first }} and
53        // find the matching {{ for that }}
54        while ( $attempt < 10 ) {
55            $closeCurPos = strpos( $text, '}}' );
56
57            if ( $closeCurPos === false ) {
58                break;
59            }
60            $tempStr = substr( $text, 0, $closeCurPos + 2 );
61
62            $openCurPos = strrpos( $tempStr, '{{' );
63            if ( $openCurPos === false ) {
64                $text = substr_replace( $text, '', $closeCurPos, 2 );
65            } else {
66                $text = substr_replace( $text, '', $openCurPos, $closeCurPos - $openCurPos + 2 );
67            }
68            $attempt++;
69        }
70
71        $text = trim( Sanitizer::stripAllTags(
72            $msgParser->parse( $text, $title, true, false, $lang )->getContentHolderText()
73        ) );
74        // strip out non-useful data for snippet
75        $text = str_replace( [ '{', '}', '[edit]' ], '', $text );
76
77        return $lang->truncateForDatabase( $text, 255 );
78    }
79
80    /**
81     * Check if a page has a reference. This checks <ref> and </ref>
82     * tags along with the presence of the sfn or harvb templates
83     *
84     * @param string $wikitext Article content in wikitext format.
85     * @return bool
86     */
87    private function hasReferenceTag( string $wikitext ): bool {
88        $closeTag = stripos( $wikitext, '</ref>' );
89
90        if ( $closeTag !== false ) {
91            $openTag = stripos( $wikitext, '<ref ' );
92            if ( $openTag !== false && $openTag < $closeTag ) {
93                return true;
94            }
95            $openTag = stripos( $wikitext, '<ref>' );
96            if ( $openTag !== false && $openTag < $closeTag ) {
97                return true;
98            }
99        }
100
101        $refStyleArray = [ '{{sfn', '{{harvnb' ];
102        foreach ( $refStyleArray as $refStyle ) {
103            if ( stripos( $wikitext, $refStyle ) !== false ) {
104                return true;
105            }
106        }
107
108        return false;
109    }
110
111}