Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 93
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
EditPagePage
0.00% covered (danger)
0.00%
0 / 93
0.00% covered (danger)
0.00%
0 / 6
240
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 showContentForm
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 1
20
 addEditInSequenceModule
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 showEditArea
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 getCheckboxesWidget
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 1
42
 importContentFormData
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace ProofreadPage\Page;
4
5use Article;
6use MediaWiki\EditPage\EditPage;
7use MediaWiki\Html\Html;
8use MediaWiki\MediaWikiServices;
9use MediaWiki\Permissions\PermissionManager;
10use MediaWiki\User\Options\UserOptionsLookup;
11use OOUI\FieldLayout;
12use OOUI\HtmlSnippet;
13use ProofreadPage\Context;
14use ProofreadPage\EditInSequence;
15use ProofreadPage\OOUI\PageQualityInputWidget;
16use Wikimedia\Rdbms\ReadOnlyMode;
17
18/**
19 * @license GPL-2.0-or-later
20 */
21class EditPagePage extends EditPage {
22
23    /**
24     * @var PageContentBuilder
25     */
26    private $pageContentBuilder;
27
28    /**
29     * @var PageDisplayHandler
30     */
31    private $pageDisplayHandler;
32
33    /**
34     * @var PermissionManager
35     */
36    private $permissionManager;
37
38    /**
39     * @var UserOptionsLookup
40     */
41    private $userOptionsLookup;
42
43    /**
44     * @var ReadOnlyMode
45     */
46    private $readOnlyMode;
47
48    /**
49     * @param Article $article
50     * @param Context $context
51     */
52    public function __construct( Article $article, Context $context ) {
53        parent::__construct( $article );
54
55        $this->pageContentBuilder = new PageContentBuilder( $this->context, $context );
56        $this->pageDisplayHandler = new PageDisplayHandler( $context );
57        $this->permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
58        $this->userOptionsLookup = MediaWikiServices::getInstance()->getUserOptionsLookup();
59        $this->readOnlyMode = MediaWikiServices::getInstance()->getReadOnlyMode();
60    }
61
62    /**
63     * @inheritDoc
64     */
65    protected function showContentForm() {
66        $out = $this->context->getOutput();
67
68        // custom CSS for preview
69        $css = $this->pageDisplayHandler->getCustomCss( $this->getTitle() );
70        if ( $css !== '' ) {
71            $out->addInlineStyle( $css );
72        }
73
74        $inputAttributes = [];
75        if ( $this->readOnlyMode->isReadOnly() ) {
76            $inputAttributes['readonly'] = '';
77        }
78
79        /** @var PageContent $content */
80        $content = $this->toEditContent( $this->textbox1 );
81        '@phan-var PageContent $content';
82
83        $out->addHTML( $this->pageDisplayHandler->buildPageContainerBegin() );
84        $this->showEditArea(
85            'wpHeaderTextbox',
86            'prp-page-edit-header',
87            'proofreadpage_header',
88            $content->getHeader()->serialize(),
89            $inputAttributes + [ 'rows' => '2', 'tabindex' => '1' ]
90        );
91        $this->showEditArea(
92            'wpTextbox1',
93            'prp-page-edit-body',
94            'proofreadpage_body',
95            $content->getBody()->serialize(),
96            $inputAttributes + [ 'tabindex' => '1' ]
97        );
98        $this->showEditArea(
99            'wpFooterTextbox',
100            'prp-page-edit-footer',
101            'proofreadpage_footer',
102            $content->getFooter()->serialize(),
103            $inputAttributes + [ 'rows' => '2', 'tabindex' => '1' ]
104        );
105        // the 3 textarea tabindex are set to 1 because summary tabindex is 1 too
106        $out->addHTML( $this->pageDisplayHandler->buildPageContainerEnd( $this->getTitle() ) );
107
108        $out->addModules( 'ext.proofreadpage.page.edit' );
109        if ( $this->userOptionsLookup->getOption( $this->context->getUser(), 'usebetatoolbar' ) ) {
110            $out->addModules( 'ext.wikiEditor' );
111        }
112        $out->addModuleStyles( [ 'ext.proofreadpage.page.edit.styles' ] );
113
114        $jsVars = $this->pageDisplayHandler->getPageJsConfigVars( $this->getTitle(), $content );
115        $out->addJsConfigVars( $jsVars );
116
117        $this->addEditInSequenceModule();
118    }
119
120    public function addEditInSequenceModule() {
121        if ( EditInSequence::shouldLoadEditInSequence( $this->context ) ) {
122            $this->context->getOutput()->addModules( 'ext.proofreadpage.page.editinsequence' );
123        }
124    }
125
126    /**
127     * Outputs an edit area to edition
128     *
129     * @param string $textareaName the name of the textarea node (used also as id)
130     * @param string $areaClass the class of the div container
131     * @param string $labelMsg the label of the area
132     * @param string $content the text to edit
133     * @param string[] $textareaAttributes attributes to add to textarea node
134     */
135    protected function showEditArea(
136        $textareaName, $areaClass, $labelMsg, $content, array $textareaAttributes
137    ) {
138        $out = $this->context->getOutput();
139        $label = Html::element(
140            'label',
141            [ 'for' => $textareaName, 'class' => 'prp-page-edit-area-label' ],
142            $this->context->msg( $labelMsg )->text()
143        );
144        $out->addHTML( Html::openElement( 'div', [ 'class' => "prp-edit-area $areaClass" ] ) . $label );
145        $this->showTextbox( $content, $textareaName, $textareaAttributes );
146        $out->addHTML( Html::closeElement( 'div' ) );
147    }
148
149    /**
150     * Sets the checkboxes for the proofreading status of the page.
151     *
152     * @inheritDoc
153     */
154    public function getCheckboxesWidget( &$tabindex, $checked ) {
155        $checkboxes = parent::getCheckboxesWidget( $tabindex, $checked );
156        if ( $this->isConflict ) {
157            // EditPage::showEditForm() does not call showContentForm() in case of a conflict
158            // because "conflicts can't be resolved […] using the custom edit ui." Don't show the
159            // rest of the custom UI (the quality radio buttons) as well.
160            return $checkboxes;
161        }
162
163        // @phan-suppress-next-line PhanUndeclaredMethod
164        $oldLevel = $this->getCurrentContent()->getLevel();
165        $hasRight = $this->permissionManager->userHasRight( $this->context->getUser(), 'pagequality' );
166        $levels = [];
167        for ( $level = 0; $level <= 4; $level++ ) {
168            $newLevel = new PageLevel( $level, $this->context->getUser() );
169            $changeAllowed = $oldLevel->isChangeAllowed( $newLevel, $this->permissionManager );
170
171            // Only show valid transitions for the user, unless the user is logged out
172            // then show them all, but they'll be disabled.
173            if ( !$changeAllowed && $hasRight ) {
174                continue;
175            }
176            $levels[] = $level;
177        }
178
179        $pageQualityInputWidget = new PageQualityInputWidget( [
180            'tabIndex' => ++$tabindex,
181            'disabled' => !$hasRight,
182            'levels' => $levels,
183            // @phan-suppress-next-line PhanUndeclaredMethod
184            'value' => $this->toEditContent( $this->textbox1 )->getLevel()->getLevel(),
185        ] );
186
187        $labelMsg = $pageQualityInputWidget->isDisabled()
188            ? 'proofreadpage_page_status_logged_out'
189            : 'proofreadpage_page_status';
190        $fieldLayout = new FieldLayout( $pageQualityInputWidget, [
191            'label' => new HtmlSnippet( $this->context->msg( $labelMsg )->parse() ),
192            // This ID and the .prp-quality-widget class are deprecated, but still used in various user scripts etc.
193            'id' => 'wpQuality-container',
194            'classes' => [ 'prp-page-edit-QualityInputWidget-field', 'prp-quality-widget' ],
195        ] );
196
197        $checkboxes['wpr-pageStatus'] = $fieldLayout;
198        return $checkboxes;
199    }
200
201    /**
202     * @inheritDoc
203     */
204    protected function importContentFormData( &$request ) {
205        /** @var PageContent $content */
206        $content = $this->getCurrentContent();
207        // @phan-suppress-next-line PhanUndeclaredMethod
208        $oldLevel = $content->getLevel();
209
210        return $this->pageContentBuilder->buildContentFromInput(
211            $request->getText( 'wpHeaderTextbox' ),
212            $request->getText( 'wpTextbox1' ),
213            $request->getText( 'wpFooterTextbox' ),
214            $request->getInt( 'wpQuality', $oldLevel->getLevel() ),
215            $oldLevel
216        )->serialize();
217    }
218}