Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 74
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
LegacyTranslationAids
0.00% covered (danger)
0.00%
0 / 74
0.00% covered (danger)
0.00%
0 / 6
132
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
 getDefinition
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 getBoxes
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
12
 getDefinitionBox
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
6
 getDocumentationBox
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
12
 ajaxEditLink
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\TranslatorInterface;
5
6use IContextSource;
7use MediaWiki\Extension\Translate\MessageLoading\MessageHandle;
8use MediaWiki\Extension\Translate\TranslatorInterface\Aid\MessageDefinitionAid;
9use MediaWiki\Extension\Translate\TranslatorInterface\Aid\TranslationAidDataProvider;
10use MediaWiki\Extension\Translate\Utilities\Utilities;
11use MediaWiki\Html\Html;
12use MediaWiki\Languages\LanguageFactory;
13use MediaWiki\Title\Title;
14use MessageGroup;
15
16/**
17 * Provides minimal translation aids which integrate with the edit page and on diffs for
18 * translatable messages.
19 * @author Niklas Laxström
20 * @license GPL-2.0-or-later
21 */
22class LegacyTranslationAids {
23    /** @var MessageHandle */
24    private $handle;
25    /** @var MessageGroup */
26    private $group;
27    /** @var IContextSource */
28    private $context;
29    /** @var LanguageFactory */
30    private $languageFactory;
31
32    public function __construct(
33        MessageHandle $handle,
34        IContextSource $context,
35        LanguageFactory $languageFactory
36    ) {
37        $this->handle = $handle;
38        $this->context = $context;
39        $this->group = $handle->getGroup();
40        $this->languageFactory = $languageFactory;
41    }
42
43    private function getDefinition(): ?string {
44        $obj = new MessageDefinitionAid(
45            $this->group,
46            $this->handle,
47            $this->context,
48            new TranslationAidDataProvider( $this->handle )
49        );
50
51        return $obj->getData()['value'];
52    }
53
54    /**
55     * Returns block element HTML snippet that contains the translation aids.
56     * Not all boxes are shown all the time depending on whether they have
57     * any information to show and on configuration variables.
58     * @return string Block level HTML snippet or empty string.
59     */
60    public function getBoxes(): string {
61        $boxes = [];
62
63        try {
64            $boxes[] = $this->getDocumentationBox();
65        } catch ( TranslationHelperException $e ) {
66            $boxes[] = "<!-- Documentation not available: {$e->getMessage()} -->";
67        }
68
69        try {
70            $boxes[] = $this->getDefinitionBox();
71        } catch ( TranslationHelperException $e ) {
72            $boxes[] = "<!-- Definition not available: {$e->getMessage()} -->";
73        }
74
75        $this->context->getOutput()->addModuleStyles( 'ext.translate.quickedit' );
76        return Html::rawElement(
77            'div',
78            [ 'class' => 'mw-sp-translate-edit-fields' ],
79            implode( "\n\n", $boxes )
80        );
81    }
82
83    private function getDefinitionBox(): string {
84        $definition = $this->getDefinition();
85        if ( (string)$definition === '' ) {
86            throw new TranslationHelperException( 'Message lacks definition' );
87        }
88
89        $linkTag = self::ajaxEditLink( $this->handle->getTitle(), $this->group->getLabel() );
90        $label =
91            wfMessage( 'translate-edit-definition' )->escaped() .
92            wfMessage( 'word-separator' )->escaped() .
93            wfMessage( 'parentheses' )->rawParams( $linkTag )->escaped();
94
95        $sl = $this->languageFactory->getLanguage( $this->group->getSourceLanguage() );
96
97        $msg = Html::rawElement( 'div',
98            [
99                'class' => 'mw-translate-edit-deftext',
100                'dir' => $sl->getDir(),
101                'lang' => $sl->getHtmlCode(),
102            ],
103            Utilities::convertWhiteSpaceToHTML( $definition )
104        );
105
106        $class = [ 'class' => 'mw-sp-translate-edit-definition' ];
107
108        return Utilities::fieldset( $label, $msg, $class );
109    }
110
111    private function getDocumentationBox(): string {
112        global $wgTranslateDocumentationLanguageCode;
113
114        if ( !$wgTranslateDocumentationLanguageCode ) {
115            throw new TranslationHelperException( 'Message documentation language code is not defined' );
116        }
117
118        $page = $this->handle->getKey();
119        $ns = $this->handle->getTitle()->getNamespace();
120
121        $title = $this->handle->getTitleForLanguage( $wgTranslateDocumentationLanguageCode );
122        $edit = $this->ajaxEditLink(
123            $title,
124            $this->context->msg( 'translate-edit-contribute' )->text()
125        );
126        $info = Utilities::getMessageContent( $page, $wgTranslateDocumentationLanguageCode, $ns );
127
128        $class = 'mw-sp-translate-edit-info';
129
130        // The information is most likely in English
131        $divAttribs = [ 'dir' => 'ltr', 'lang' => 'en', 'class' => 'mw-content-ltr mw-parser-output' ];
132
133        if ( (string)$info === '' ) {
134            $info = $this->context->msg( 'translate-edit-no-information' )->plain();
135            $class = 'mw-sp-translate-edit-noinfo';
136            $lang = $this->context->getLanguage();
137            // The message saying that there's no info, should be translated
138            $divAttribs = [ 'dir' => $lang->getDir(), 'lang' => $lang->getHtmlCode() ];
139        }
140        $class .= ' mw-sp-translate-message-documentation';
141
142        $contents = $this->context->getOutput()->parseInlineAsInterface( $info );
143
144        return Utilities::fieldset(
145            $this->context->msg( 'translate-edit-information' )->rawParams( $edit )->escaped(),
146            Html::rawElement( 'div', $divAttribs, $contents ), [ 'class' => $class ]
147        );
148    }
149
150    private function ajaxEditLink( Title $target, string $linkText ): string {
151        $handle = new MessageHandle( $target );
152        $uri = Utilities::getEditorUrl( $handle );
153        return Html::element(
154            'a',
155            [ 'href' => $uri ],
156            $linkText
157        );
158    }
159}