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