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