Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 95
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
ZObjectEditAction
0.00% covered (danger)
0.00%
0 / 95
0.00% covered (danger)
0.00%
0 / 7
210
0.00% covered (danger)
0.00%
0 / 1
 getName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTargetZObjectWithLabels
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTargetZObject
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getPageTitleMsg
0.00% covered (danger)
0.00%
0 / 59
0.00% covered (danger)
0.00%
0 / 1
42
 show
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
12
 getRestriction
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 doesWrites
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * WikiLambda edit action for ZObjects
4 *
5 * @file
6 * @ingroup Extensions
7 * @copyright 2020– Abstract Wikipedia team; see AUTHORS.txt
8 * @license MIT
9 */
10
11namespace MediaWiki\Extension\WikiLambda;
12
13use Action;
14use MediaWiki\Html\Html;
15use MediaWiki\MediaWikiServices;
16
17class ZObjectEditAction extends Action {
18    use ZObjectEditingPageTrait;
19
20    /**
21     * @inheritDoc
22     */
23    public function getName() {
24        return 'edit';
25    }
26
27    /**
28     * Get the type and language labels of the target zObject
29     * @return array
30     */
31    public function getTargetZObjectWithLabels() {
32        return $this->getTargetZObject()->getTypeStringAndLanguage( $this->getLanguage() );
33    }
34
35    /**
36     * Get the target zObject
37     * @return ZObjectContent|bool Found ZObject
38     */
39    public function getTargetZObject() {
40        $zObjectStore = WikiLambdaServices::getZObjectStore();
41        return $zObjectStore->fetchZObjectByTitle( $this->getTitle() );
42    }
43
44    /**
45     * Get page title message
46     * @return string
47     */
48    protected function getPageTitleMsg() {
49        // If the page doesn't exist (e.g. it's been deleted), return nothing.
50        if ( !$this->getTargetZObject() ) {
51            return '';
52        }
53
54        // the language object of the user's preferred language
55        $zObjectLabelsWithLang = $this->getTargetZObjectWithLabels();
56
57        [ 'title' => $labelText ] = $this->getTargetZObject()->getLabels()
58            ->buildStringForLanguage( $this->getLanguage() )
59            ->fallbackWithEnglish()
60            ->placeholderForTitle()
61            ->getStringAndLanguageCode();
62
63        $untitledStyle = $labelText === wfMessage( 'wikilambda-editor-default-name' )->text() ?
64            'ext-wikilambda-editpage-header--title-untitled' : null;
65
66        $label = Html::element(
67            'span',
68            [
69                'class' => [
70                    'ext-wikilambda-editpage-header-title',
71                    'ext-wikilambda-editpage-header-title--function-name',
72                    $untitledStyle
73                ]
74            ],
75            $labelText
76        );
77
78        $zObjectId = $this->getTargetZObject()->getZid();
79        $id = Html::element(
80            'span',
81            [
82                'class' => 'ext-wikilambda-editpage-header-zid'
83            ],
84            $zObjectId
85        );
86
87        /* BCP47 Codes can occur in two places:
88            (1) in front of the entire header - this happens if
89                (a) ONLY the TYPE is in a non-user language OR
90                (b) if both the TYPE and the NAME are in the SAME non-user language
91            (2) in front of the name - this happens if the NAME is in a non-user language
92        */
93
94        // used to go from LANG_CODE -> LANG_NAME
95        // TODO (T362246): Dependency-inject
96        $services = MediaWikiServices::getInstance();
97
98        // the BCP47 code of the language currently being rendered for the zObject Type
99        $typeLangCode = $zObjectLabelsWithLang[ 'languageCode' ] ?: '';
100        $typeLangName = $services->getLanguageNameUtils()->getLanguageName( $typeLangCode );
101
102        // the BCP47 code of the language currently being rendered for the zObject Type
103        $userLangCode = $this->getLanguage()->getCode();
104
105        $nameLangCode = $this->getTargetZObject()
106            ->getLabels()
107            ->buildStringForLanguage( $this->getLanguage() )
108            ->fallbackWithEnglish()
109            ->getLanguageProvided() ?? $userLangCode;
110        $nameLangTitle = $services->getLanguageNameUtils()->getLanguageName( $nameLangCode );
111
112        $BCP47CodeClassName = 'ext-wikilambda-editpage-header--bcp47-code';
113
114        $BCP47CodeObjectName = '';
115        if ( $nameLangCode !== $userLangCode ) {
116            $BCP47CodeObjectName = ZObjectUtils::wrapBCP47CodeInFakeCodexChip(
117                $nameLangCode, $nameLangTitle, $BCP47CodeClassName
118            );
119        }
120
121        // show a language label if the text is not the user's preferred language
122        $BCP47CodeObjectType = '';
123        if ( $typeLangCode !== $userLangCode ) {
124            $BCP47CodeObjectType = ZObjectUtils::wrapBCP47CodeInFakeCodexChip(
125                $nameLangCode, $typeLangName, $BCP47CodeClassName
126            );
127        }
128
129        $prefix = Html::element(
130            'span', [ 'class' => 'ext-wikilambda-editpage-header-title' ],
131            $this->msg( 'wikilambda-edit' )->text()
132        );
133
134        return Html::rawElement(
135            'span',
136            [ 'class' => 'ext-wikilambda-editpage-header' ],
137            " " . $prefix . " " . $BCP47CodeObjectType . " " . $zObjectLabelsWithLang[ 'title' ]
138            . $this->msg( 'colon-separator' )->text() . $BCP47CodeObjectName . $label . ' ' . $id );
139    }
140
141    public function show() {
142        $output = $this->getOutput();
143        $output->addModules( [ 'ext.wikilambda.edit' ] );
144
145        // (T347528) The action's Title object, not the Message getPageTitle() for the HTML page heading
146        $zId = $this->getTitle()->getBaseText();
147
148        $output->addModuleStyles( [ 'ext.wikilambda.editpage.styles' ] );
149
150        // (T328679) If the page doesn't exist yet, route the user to the ZObject creation system
151        // rather than running the code below that assumes the ZObject exists.
152        if ( !$this->getTitle()->exists() ) {
153            $this->generateZObjectPayload( $output, $this->getContext(), [
154                'createNewPage' => true,
155                'zId' => $zId,
156            ] );
157            return;
158        }
159
160        // (T290217) Show page title
161        // NOTE setPageTitle sets both the HTML <title> header and the <h1> tag
162        $output->setPageTitle( $this->getPageTitleMsg() );
163
164        $zObjectLabelsWithLang = $this->getTargetZObjectWithLabels();
165
166        if ( $zObjectLabelsWithLang[ 'title' ] === 'Function' ) {
167            $linkLabel = Html::element(
168                'a',
169                [
170                    'class' => 'ext-wikilambda-editpage-header-description--link',
171                    'href' => $this->msg( 'wikilambda-users-help-link' )->text()
172                ],
173                $this->msg( 'wikilambda-special-edit-function-definition-special-permission-link-label' )->text()
174            );
175
176            $output->addHtml( Html::rawElement(
177                'div', [ 'class' => 'ext-wikilambda-editpage-header-description' ],
178                $this->msg( 'wikilambda-special-edit-function-definition-description' )->rawParams( $linkLabel )
179                ->escaped()
180            ) );
181        }
182
183        $this->generateZObjectPayload( $output, $this->getContext(), [
184            'createNewPage' => false,
185            'zId' => $zId,
186        ] );
187    }
188
189    /**
190     * @inheritDoc
191     */
192    public function getRestriction() {
193        // This is a very basic check; proper type-specific checking depends on the attemped
194        // edit/creation content, which isn't available yet
195        return 'wikilambda-create';
196    }
197
198    public function doesWrites() {
199        return true;
200    }
201}