Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
80.77% covered (warning)
80.77%
42 / 52
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
CategoriesSnippet
80.77% covered (warning)
80.77%
42 / 52
33.33% covered (danger)
33.33%
1 / 3
11.86
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 getHtml
76.47% covered (warning)
76.47%
26 / 34
0.00% covered (danger)
0.00%
0 / 1
5.33
 buildCategoryLinks
84.62% covered (warning)
84.62%
11 / 13
0.00% covered (danger)
0.00%
0 / 1
5.09
1<?php
2
3namespace FileImporter\Html;
4
5use MediaWiki\Html\Html;
6use MediaWiki\Language\ILanguageConverter;
7use MediaWiki\Language\MessageLocalizer;
8use MediaWiki\Linker\LinkRenderer;
9use MediaWiki\MediaWikiServices;
10use MediaWiki\SpecialPage\SpecialPage;
11use MediaWiki\Title\Title;
12use OOUI\IconWidget;
13
14/**
15 * @license GPL-2.0-or-later
16 */
17class CategoriesSnippet {
18
19    private ILanguageConverter $languageConverter;
20    private LinkRenderer $linkRenderer;
21
22    /**
23     * @param MessageLocalizer $context
24     * @param string[] $visibleCategories
25     * @param string[] $hiddenCategories
26     */
27    public function __construct(
28        private readonly MessageLocalizer $context,
29        private readonly array $visibleCategories,
30        private readonly array $hiddenCategories,
31    ) {
32        $services = MediaWikiServices::getInstance();
33        $this->languageConverter = $services
34            ->getLanguageConverterFactory()
35            ->getLanguageConverter( $services->getContentLanguage() );
36        $this->linkRenderer = $services->getLinkRenderer();
37    }
38
39    /**
40     * Render categories in a format similar to OutputPage
41     *
42     * @return string HTML rendering of categories box
43     */
44    public function getHtml(): string {
45        $output = '';
46
47        // TODO: Gracefully handle an empty list of categories, pending decisions about the desired
48        // behavior.
49        if ( $this->visibleCategories === [] && $this->hiddenCategories === [] ) {
50            return Html::rawElement(
51                'div',
52                [],
53                new IconWidget( [ 'icon' => 'info' ] )
54                    . ' '
55                    . $this->context->msg( 'fileimporter-category-encouragement' )->parse()
56            );
57        }
58
59        $categoryLinks = $this->buildCategoryLinks( $this->visibleCategories );
60        $hiddenCategoryLinks = $this->buildCategoryLinks( $this->hiddenCategories );
61
62        if ( $categoryLinks ) {
63            $output .= Html::rawElement(
64                'div',
65                [ 'class' => 'mw-normal-catlinks' ],
66                $this->linkRenderer->makeLink(
67                    SpecialPage::getSafeTitleFor( 'Categories' ),
68                    $this->context->msg( 'pagecategories' )->numParams( count( $categoryLinks ) )
69                        ->text()
70                ) .
71                $this->context->msg( 'colon-separator' )->escaped() .
72                Html::rawElement( 'ul', [], implode( '', $categoryLinks ) )
73            );
74        }
75
76        if ( $hiddenCategoryLinks ) {
77            $output .= Html::rawElement(
78                'div',
79                [ 'class' => 'mw-hidden-catlinks' ],
80                $this->context->msg( 'hidden-categories' )
81                    ->numParams( count( $hiddenCategoryLinks ) )->escaped() .
82                $this->context->msg( 'colon-separator' )->escaped() .
83                Html::rawElement( 'ul', [], implode( '', $hiddenCategoryLinks ) )
84            );
85        }
86
87        $output = Html::rawElement( 'div', [ 'class' => 'catlinks' ], $output );
88
89        return $output;
90    }
91
92    /**
93     * @param string[] $categories List of raw category names
94     * @return string[] List of HTML `li` tags each containing a local link to a category.
95     */
96    private function buildCategoryLinks( array $categories ) {
97        $categoryLinks = [];
98
99        foreach ( $categories as $category ) {
100            $originalCategory = $category;
101
102            $title = Title::makeTitleSafe( NS_CATEGORY, $category );
103            if ( !$title ) {
104                continue;
105            }
106
107            $this->languageConverter->findVariantLink( $category, $title, true );
108            if ( $category !== $originalCategory && array_key_exists( $category, $categories ) ) {
109                continue;
110            }
111
112            $text = $title->getText();
113            $categoryLinks[] = Html::rawElement( 'li', [], $this->linkRenderer->makeLink( $title,
114                $text ) );
115        }
116
117        return $categoryLinks;
118    }
119
120}