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