Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
98.86% |
173 / 175 |
|
83.33% |
5 / 6 |
CRAP | |
0.00% |
0 / 1 |
ImportPreviewPage | |
98.86% |
173 / 175 |
|
83.33% |
5 / 6 |
13 | |
0.00% |
0 / 1 |
getHtml | |
98.33% |
118 / 120 |
|
0.00% |
0 / 1 |
3 | |||
buildShowChangesButtonHtml | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
1 | |||
buildEditSummaryHtml | |
100.00% |
25 / 25 |
|
100.00% |
1 / 1 |
5 | |||
buildImportIdentityFormSnippet | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
1 | |||
buildCategoriesSnippet | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
1 | |||
wasEdited | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace FileImporter\Html; |
4 | |
5 | use FileImporter\Data\ImportPlan; |
6 | use FileImporter\Services\CategoryExtractor; |
7 | use MediaWiki\EditPage\EditPage; |
8 | use MediaWiki\Html\Html; |
9 | use MediaWiki\Linker\Linker; |
10 | use MediaWiki\MediaWikiServices; |
11 | use MediaWiki\Registration\ExtensionRegistry; |
12 | use OOUI\ButtonInputWidget; |
13 | use OOUI\ButtonWidget; |
14 | use OOUI\TextInputWidget; |
15 | |
16 | /** |
17 | * Page displaying the preview of the import before it has happened. |
18 | * |
19 | * @license GPL-2.0-or-later |
20 | * @author Addshore |
21 | */ |
22 | class ImportPreviewPage extends SpecialPageHtmlFragment { |
23 | |
24 | public const ACTION_BUTTON = 'action'; |
25 | public const ACTION_EDIT_TITLE = 'edittitle'; |
26 | public const ACTION_EDIT_INFO = 'editinfo'; |
27 | public const ACTION_SUBMIT = 'submit'; |
28 | public const ACTION_VIEW_DIFF = 'viewdiff'; |
29 | |
30 | public function getHtml( ImportPlan $importPlan ): string { |
31 | // TODO: Inject |
32 | if ( ExtensionRegistry::getInstance()->isLoaded( 'CentralAuth' ) ) { |
33 | $config = $this->getContext()->getConfig(); |
34 | $sourceEditingEnabled = $config->get( 'FileImporterSourceWikiTemplating' ); |
35 | $sourceDeletionEnabled = $config->get( 'FileImporterSourceWikiDeletion' ); |
36 | } else { |
37 | $sourceEditingEnabled = false; |
38 | $sourceDeletionEnabled = false; |
39 | } |
40 | |
41 | $text = $importPlan->getFileInfoText(); |
42 | $title = $importPlan->getTitle(); |
43 | |
44 | $details = $importPlan->getDetails(); |
45 | $textRevisionsCount = count( $details->getTextRevisions()->toArray() ); |
46 | $fileRevisionsCount = count( $details->getFileRevisions()->toArray() ); |
47 | $categoriesSnippet = $this->buildCategoriesSnippet( $importPlan ); |
48 | |
49 | return Html::openElement( |
50 | 'form', |
51 | [ |
52 | 'action' => $this->getPageTitle()->getLocalURL(), |
53 | 'method' => 'POST', |
54 | ] |
55 | ) . |
56 | Html::hidden( 'wpUnicodeCheck', EditPage::UNICODE_CHECK ) . |
57 | ( new HelpBanner( $this ) )->getHtml() . |
58 | $this->msg( 'fileimporter-previewnote' )->parseAsBlock() . |
59 | Html::rawElement( |
60 | 'div', |
61 | [ 'class' => 'mw-importfile-header' ], |
62 | Html::element( |
63 | 'h2', |
64 | [], |
65 | $title->getText() |
66 | ) . |
67 | new ButtonInputWidget( |
68 | [ |
69 | 'classes' => [ 'mw-importfile-rightAlign' ], |
70 | 'label' => $this->msg( 'fileimporter-edittitle' )->plain(), |
71 | 'type' => 'submit', |
72 | 'name' => self::ACTION_BUTTON, |
73 | 'value' => self::ACTION_EDIT_TITLE |
74 | ] |
75 | ) |
76 | ) . |
77 | Linker::makeExternalImage( $details->getImageDisplayUrl(), $title->getPrefixedText() ) . |
78 | Html::rawElement( |
79 | 'div', |
80 | [ 'class' => 'mw-importfile-header' ], |
81 | Html::element( |
82 | 'h2', |
83 | [], |
84 | $this->msg( 'fileimporter-heading-fileinfo' )->plain() |
85 | ) . |
86 | new ButtonInputWidget( |
87 | [ |
88 | 'classes' => [ 'mw-importfile-rightAlign' ], |
89 | 'label' => $this->msg( 'fileimporter-editinfo' )->plain(), |
90 | 'type' => 'submit', |
91 | 'name' => self::ACTION_BUTTON, |
92 | 'value' => self::ACTION_EDIT_INFO |
93 | ] |
94 | ) |
95 | ) . |
96 | Html::rawElement( |
97 | 'div', |
98 | [ 'class' => 'mw-importfile-parsedContent' ], |
99 | ( new TextRevisionSnippet( $this ) )->getHtml( |
100 | $details->getTextRevisions()->getLatest(), |
101 | $text |
102 | ) |
103 | ) . |
104 | $categoriesSnippet . |
105 | Html::element( 'h2', [], $this->msg( 'fileimporter-heading-filehistory' )->plain() ) . |
106 | $this->msg( |
107 | 'fileimporter-filerevisions', |
108 | [ |
109 | $fileRevisionsCount, |
110 | $fileRevisionsCount, |
111 | ] |
112 | )->parseAsBlock() . |
113 | ( new SourceWikiCleanupSnippet( |
114 | $sourceEditingEnabled, |
115 | $sourceDeletionEnabled |
116 | ) )->getHtml( $importPlan, $this->getUser() ) . |
117 | Html::openElement( 'div', [ 'class' => 'mw-importfile-importOptions' ] ) . |
118 | $this->buildEditSummaryHtml( $importPlan ) . |
119 | $this->msg( |
120 | 'fileimporter-textrevisions', |
121 | [ |
122 | $textRevisionsCount, |
123 | $textRevisionsCount, |
124 | ] |
125 | )->parseAsBlock() . |
126 | Html::element( |
127 | 'input', |
128 | [ |
129 | 'type' => 'hidden', |
130 | 'name' => 'token', |
131 | 'value' => $this->getUser()->getEditToken() |
132 | ] |
133 | ) . |
134 | new ButtonInputWidget( |
135 | [ |
136 | 'classes' => [ 'mw-importfile-import-submit' ], |
137 | 'label' => $this->msg( 'fileimporter-import' )->plain(), |
138 | 'type' => 'submit', |
139 | 'flags' => [ 'primary', 'progressive' ], |
140 | 'name' => self::ACTION_BUTTON, |
141 | 'value' => self::ACTION_SUBMIT, |
142 | 'infusable' => true |
143 | ] |
144 | ) . |
145 | ( $this->wasEdited( $importPlan ) ? $this->buildShowChangesButtonHtml() : '' ) . |
146 | new ButtonWidget( |
147 | [ |
148 | 'classes' => [ 'mw-importfile-import-cancel' ], |
149 | 'label' => $this->msg( 'fileimporter-cancel' )->plain(), |
150 | 'href' => $importPlan->getRequest()->getUrl()->getUrl() |
151 | ] |
152 | ) . |
153 | Html::element( 'span', [], $this->msg( 'fileimporter-import-wait' )->plain() ) . |
154 | $this->buildImportIdentityFormSnippet( $importPlan ) . |
155 | // End of mw-importfile-importOptions |
156 | Html::closeElement( 'div' ) . |
157 | Html::closeElement( 'form' ); |
158 | } |
159 | |
160 | private function buildShowChangesButtonHtml() { |
161 | return new ButtonInputWidget( |
162 | [ |
163 | 'classes' => [ 'mw-importfile-import-diff' ], |
164 | 'label' => $this->msg( 'fileimporter-viewdiff' )->plain(), |
165 | 'name' => self::ACTION_BUTTON, |
166 | 'value' => self::ACTION_VIEW_DIFF, |
167 | 'type' => 'submit', |
168 | ] |
169 | ); |
170 | } |
171 | |
172 | /** |
173 | * @return string |
174 | */ |
175 | private function buildEditSummaryHtml( ImportPlan $importPlan ) { |
176 | $summary = $importPlan->getRequest()->getIntendedSummary(); |
177 | if ( $summary === null ) { |
178 | $replacements = $importPlan->getNumberOfTemplateReplacements(); |
179 | $summary = $replacements > 0 |
180 | ? $this->msg( |
181 | 'fileimporter-auto-replacements-summary', |
182 | $replacements |
183 | )->inContentLanguage()->text() |
184 | : null; |
185 | } |
186 | if ( $summary === null |
187 | && !$this->wasEdited( $importPlan ) |
188 | ) { |
189 | return ''; |
190 | } |
191 | |
192 | return Html::element( |
193 | 'p', |
194 | [], |
195 | $this->msg( 'fileimporter-editsummary' )->plain() |
196 | ) . |
197 | new TextInputWidget( |
198 | [ |
199 | 'name' => 'intendedRevisionSummary', |
200 | 'classes' => [ 'mw-importfile-import-summary' ], |
201 | 'value' => $summary, |
202 | 'infusable' => true |
203 | ] |
204 | ); |
205 | } |
206 | |
207 | /** |
208 | * @return string |
209 | */ |
210 | private function buildImportIdentityFormSnippet( ImportPlan $importPlan ) { |
211 | return ( new ImportIdentityFormSnippet( [ |
212 | 'clientUrl' => $importPlan->getRequest()->getUrl(), |
213 | 'intendedFileName' => $importPlan->getFileName(), |
214 | 'intendedWikitext' => $importPlan->getFileInfoText(), |
215 | 'actionStats' => json_encode( $importPlan->getActionStats() ), |
216 | 'validationWarnings' => json_encode( $importPlan->getValidationWarnings() ), |
217 | 'importDetailsHash' => $importPlan->getDetails()->getOriginalHash(), |
218 | ] ) )->getHtml(); |
219 | } |
220 | |
221 | /** |
222 | * @return string HTML snippet for a box showing the categories, or empty string if there are |
223 | * no categories. |
224 | */ |
225 | private function buildCategoriesSnippet( ImportPlan $importPlan ) { |
226 | /** @var CategoryExtractor $categoryExtractor */ |
227 | $categoryExtractor = MediaWikiServices::getInstance() |
228 | ->getService( 'FileImporterCategoryExtractor' ); |
229 | [ $visibleCategories, $hiddenCategories ] = $categoryExtractor->getCategoriesGrouped( |
230 | $importPlan->getFileInfoText(), |
231 | $importPlan->getTitle(), |
232 | $this->getUser() |
233 | ); |
234 | return ( new CategoriesSnippet( |
235 | $visibleCategories, |
236 | $hiddenCategories |
237 | ) )->getHtml(); |
238 | } |
239 | |
240 | /** |
241 | * @return bool |
242 | */ |
243 | private function wasEdited( ImportPlan $importPlan ) { |
244 | return $importPlan->wasFileInfoTextChanged() || |
245 | $importPlan->getNumberOfTemplateReplacements() > 0; |
246 | } |
247 | |
248 | } |