Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 63
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
TranslusionPagesModifier
0.00% covered (danger)
0.00%
0 / 63
0.00% covered (danger)
0.00%
0 / 6
380
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 modifyPage
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
30
 getIncludedPagePagesTitles
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
 getIndexTitleForPages
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 getQualityStatsForPages
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 buildQualityStatsBar
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace ProofreadPage\Parser;
4
5use IContextSource;
6use MediaWiki\Html\Html;
7use MediaWiki\Output\OutputPage;
8use MediaWiki\Parser\ParserOutput;
9use MediaWiki\Title\Title;
10use ProofreadPage\Index\IndexQualityStatsLookup;
11use ProofreadPage\Index\PagesQualityStats;
12use ProofreadPage\Page\IndexForPageLookup;
13use ProofreadPage\Page\PageQualityLevelLookup;
14
15/**
16 * @license GPL-2.0-or-later
17 *
18 * Modifies the UI of pages that transcludes Page: pages
19 */
20class TranslusionPagesModifier {
21
22    /** @var PageQualityLevelLookup */
23    private $pageQualityLevelLookup;
24
25    /** @var IndexQualityStatsLookup */
26    private $indexQualityStatsLookup;
27
28    /** @var IndexForPageLookup */
29    private $indexForPageLookup;
30
31    /** @var int */
32    private $pageNamespaceId;
33
34    /**
35     * @param PageQualityLevelLookup $pageQualityLevelLookup
36     * @param IndexQualityStatsLookup $indexQualityStatsLookup
37     * @param IndexForPageLookup $indexForPageLookup
38     * @param int $pageNamespaceId
39     */
40    public function __construct(
41        PageQualityLevelLookup $pageQualityLevelLookup,
42        IndexQualityStatsLookup $indexQualityStatsLookup,
43        IndexForPageLookup $indexForPageLookup,
44        int $pageNamespaceId
45    ) {
46        $this->pageQualityLevelLookup = $pageQualityLevelLookup;
47        $this->indexQualityStatsLookup = $indexQualityStatsLookup;
48        $this->indexForPageLookup = $indexForPageLookup;
49        $this->pageNamespaceId = $pageNamespaceId;
50    }
51
52    /**
53     * Add the source index and its statistics to the output page (if appropriate)
54     *
55     * @param ParserOutput $parserOutput
56     * @param OutputPage $outputPage
57     */
58    public function modifyPage( ParserOutput $parserOutput, OutputPage $outputPage ) {
59        $transcludedPages = $this->getIncludedPagePagesTitles( $parserOutput );
60        $indexTitle = $this->getIndexTitleForPages( $transcludedPages );
61
62        if ( $parserOutput->getExtensionData( 'proofreadpage_is_toc' ) && $indexTitle !== null ) {
63            $qualityStats = $this->indexQualityStatsLookup->getStatsForIndexTitle( $indexTitle );
64        } else {
65            $qualityStats = $this->getQualityStatsForPages( $transcludedPages );
66        }
67
68        if ( $indexTitle !== null ) {
69            $outputPage->addJsConfigVars( 'prpSourceIndexPage', $indexTitle->getPrefixedText() );
70            $outputPage->setProperty( 'prpSourceIndexPage', $indexTitle->getPrefixedText() );
71        }
72
73        if ( $qualityStats->getNumberOfPages() !== 0 ) {
74            $outputPage->setSubtitle(
75                $outputPage->getSubtitle() .
76                $this->buildQualityStatsBar( $qualityStats, $outputPage )
77            );
78        }
79
80        $outputPage->addModuleStyles( [ 'ext.proofreadpage.base', 'ext.proofreadpage.article' ] );
81    }
82
83    /**
84     * @param ParserOutput $parserOutput
85     * @return Title[]
86     */
87    private function getIncludedPagePagesTitles( ParserOutput $parserOutput ): array {
88        $templates = $parserOutput->getTemplates();
89
90        if ( $templates === null || !array_key_exists( $this->pageNamespaceId, $templates ) ) {
91            return [];
92        }
93
94        $titles = [];
95        foreach ( $templates[ $this->pageNamespaceId ] as $dbKey => $pageId ) {
96            $titles[] = Title::makeTitle( $this->pageNamespaceId, $dbKey );
97        }
98        return $titles;
99    }
100
101    /**
102     * @param array $pages
103     * @return Title|null
104     */
105    private function getIndexTitleForPages( array $pages ): ?Title {
106        foreach ( $pages as $page ) {
107            $indexTitle = $this->indexForPageLookup->getIndexForPageTitle( $page );
108            if ( $indexTitle !== null ) {
109                return $indexTitle;
110            }
111        }
112        return null;
113    }
114
115    /**
116     * @param Title[] $pages
117     * @return PagesQualityStats
118     */
119    private function getQualityStatsForPages( array $pages ): PagesQualityStats {
120        $this->pageQualityLevelLookup->prefetchQualityLevelForTitles( $pages );
121
122        $numberOfPagesByLevel = [];
123        foreach ( $pages as $pageTitle ) {
124            $pageQualityLevel = $this->pageQualityLevelLookup->getQualityLevelForPageTitle( $pageTitle );
125            if ( array_key_exists( $pageQualityLevel, $numberOfPagesByLevel ) ) {
126                $numberOfPagesByLevel[$pageQualityLevel]++;
127            } else {
128                $numberOfPagesByLevel[$pageQualityLevel] = 1;
129            }
130        }
131
132        return new PagesQualityStats( count( $pages ), $numberOfPagesByLevel );
133    }
134
135    /**
136     * @param PagesQualityStats $qualityStats
137     * @param IContextSource $contextSource
138     * @return string
139     */
140    private function buildQualityStatsBar(
141        PagesQualityStats $qualityStats,
142        IContextSource $contextSource
143    ): string {
144        $totalPages = $qualityStats->getNumberOfPages();
145        $percentages = [];
146        for ( $i = 4; $i >= 0; $i-- ) {
147            $pagesAtLevel = $qualityStats->getNumberOfPagesForQualityLevel( $i );
148            $percentages[$i] = $pagesAtLevel * 100 / $totalPages;
149        }
150        $percentages['e'] = 100 - array_sum( $percentages );
151
152        $output = '';
153        foreach ( $percentages as $key => $value ) {
154            // The following classes are used here: quality0, quality1, quality2, quality3, quality4, qualitye
155            $output .= Html::element( 'td', [
156                'class' => "quality$key",
157                'style' => "width: $value%;"
158            ] );
159        }
160
161        return Html::rawElement(
162            'table',
163            [
164                'class' => 'pr_quality',
165                'title' => $contextSource->msg(
166                    'proofreadpage-indexquality-alt',
167                    $qualityStats->getNumberOfPagesForQualityLevel( 4 ),
168                    $qualityStats->getNumberOfPagesForQualityLevel( 3 ),
169                    $qualityStats->getNumberOfPagesForQualityLevel( 1 )
170                )
171            ],
172            Html::rawElement( 'tr', [], $output )
173        );
174    }
175}