Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 68
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
PagelistTagParser
0.00% covered (danger)
0.00%
0 / 68
0.00% covered (danger)
0.00%
0 / 3
210
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
 render
0.00% covered (danger)
0.00%
0 / 58
0.00% covered (danger)
0.00%
0 / 1
156
 formatError
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace ProofreadPage\Parser;
4
5use HtmlArmor;
6use MediaWiki\Html\Html;
7use Parser;
8use ProofreadPage\Context;
9use ProofreadPage\FileNotFoundException;
10use ProofreadPage\Pagination\FilePagination;
11use ProofreadPage\Pagination\PageList;
12use ProofreadPage\Pagination\SimpleFilePagination;
13use ProofreadPage\ProofreadPage;
14
15/**
16 * @license GPL-2.0-or-later
17 *
18 * Parser for the <pagelist> tag
19 */
20class PagelistTagParser {
21
22    /**
23     * @var Parser
24     */
25    private $parser;
26
27    /**
28     * @var Context
29     */
30    private $context;
31
32    /**
33     * @param Parser $parser
34     * @param Context $context
35     */
36    public function __construct( Parser $parser, Context $context ) {
37        $this->parser = $parser;
38        $this->context = $context;
39    }
40
41    /**
42     * Render a <pagelist> tag
43     *
44     * @param array $args tags arguments
45     * @return string
46     */
47    public function render( array $args ) {
48        $title = $this->parser->getTitle();
49        if ( !$title->inNamespace( $this->context->getIndexNamespaceId() ) ) {
50            return $this->formatError( 'proofreadpage_pagelistnotallowed' );
51        }
52        $pageList = new PageList( $args );
53        try {
54            $image = $this->context->getFileProvider()->getFileForIndexTitle( $title );
55        } catch ( FileNotFoundException $e ) {
56            return $this->formatError( 'proofreadpage_nosuch_file' );
57        }
58
59        if ( $image->isMultipage() ) {
60            $pagination = new FilePagination(
61                $title,
62                $pageList,
63                $image->pageCount(),
64                $this->context->getPageNamespaceId()
65            );
66            $pagination->prefetchPageLinks();
67        } else {
68            $pagination = new SimpleFilePagination( $title, $pageList, $this->context->getPageNamespaceId() );
69        }
70        $count = $pagination->getNumberOfPages();
71
72        $from = $args['from'] ?? 1;
73        $to = $args['to'] ?? $count;
74        if ( !is_int( $from ) ) {
75            if ( !ctype_digit( $from ) ) {
76                return $this->formatError( 'proofreadpage_number_expected' );
77            }
78            $from = (int)$from;
79        }
80        if ( !is_int( $to ) ) {
81            if ( !ctype_digit( $to ) ) {
82                return $this->formatError( 'proofreadpage_number_expected' );
83            }
84            $to = (int)$to;
85        }
86        if ( !FilePagination::isValidInterval( $from, $to, $count ) ) {
87            return $this->formatError( 'proofreadpage_invalid_interval' );
88        }
89        $return = [];
90        for ( $i = $from; $i <= $to; $i++ ) {
91            $pageNumber = $pagination->getDisplayedPageNumber( $i );
92            $pageNumberExpression = $pageNumber->getFormattedPageNumber( $title->getPageLanguage() );
93            if ( !preg_match( '/^[\p{L}\p{N}\p{Mc}]+$/', $pageNumberExpression ) ) {
94                $pageNumberExpression = $this->parser->recursiveTagParse( $pageNumberExpression );
95            }
96
97            $pageTitle = $pagination->getPageTitle( $i );
98            if ( !$pageNumber->isEmpty() ) {
99                // Adds the page as a dependency in order to make sure that the Index: page is
100                // purged if the status of the Page: page changes
101                $this->parser->getOutput()->addTemplate(
102                    $pageTitle,
103                    $pageTitle->getArticleID(),
104                    $pageTitle->getLatestRevID()
105                );
106
107                $qualityClass = ProofreadPage::getQualityLevelClassesForTitle( $pageTitle, true );
108                $linkRenderer = $this->parser->getLinkRenderer();
109                $pageNumberExpression = $linkRenderer->makeLink(
110                    $pageTitle,
111                    new HtmlArmor( $pageNumberExpression ),
112                    [ 'class' => 'prp-index-pagelist-page ' . $qualityClass ]
113                );
114            }
115            $return[] = $pageNumberExpression;
116        }
117
118        $this->parser->getOutput()->addImage(
119            $image->getTitle()->getDBkey(), $image->getTimestamp(), $image->getSha1()
120        );
121
122        return Html::rawElement(
123            'div',
124            [ 'class' => 'prp-index-pagelist' ],
125            implode( ' ', $return )
126        );
127    }
128
129    /**
130     * @param string $errorMsg
131     * @return string
132     */
133    private function formatError( $errorMsg ) {
134        $error = Html::element( 'strong',
135                [ 'class' => 'error' ],
136                wfMessage( $errorMsg )->inContentLanguage()->text()
137            );
138        return Html::rawElement( 'span',
139            [ 'class' => 'prp-index-pagelist' ],
140            $error
141        );
142    }
143}