MediaWiki master
PreloadedContentBuilder.php
Go to the documentation of this file.
1<?php
2
3namespace MediaWiki\EditPage;
4
18use MessageCache;
20use Wikimedia\Assert\Assert;
21
31
32 use ParametersHelper;
33
34 private IContentHandlerFactory $contentHandlerFactory;
35 private WikiPageFactory $wikiPageFactory;
36 private RedirectLookup $redirectLookup;
37 private SpecialPageFactory $specialPageFactory;
38 private ContentTransformer $contentTransformer;
39 private HookRunner $hookRunner;
40
41 public function __construct(
42 IContentHandlerFactory $contentHandlerFactory,
43 WikiPageFactory $wikiPageFactory,
44 RedirectLookup $redirectLookup,
45 SpecialPageFactory $specialPageFactory,
46 ContentTransformer $contentTransformer,
47 HookContainer $hookContainer
48 ) {
49 // Services
50 $this->contentHandlerFactory = $contentHandlerFactory;
51 $this->wikiPageFactory = $wikiPageFactory;
52 $this->redirectLookup = $redirectLookup;
53 $this->specialPageFactory = $specialPageFactory;
54 $this->contentTransformer = $contentTransformer;
55 $this->hookRunner = new HookRunner( $hookContainer );
56 }
57
69 public function getPreloadedContent(
71 Authority $performer,
72 ?string $preload,
73 array $preloadParams,
74 ?string $section
75 ): Content {
76 Assert::parameterElementType( 'string', $preloadParams, '$preloadParams' );
77
78 $content = null;
79 if ( $section !== 'new' ) {
80 $content = $this->getDefaultContent( $page );
81 }
82 if ( $content === null ) {
83 if ( ( $preload === null || $preload === '' ) && $section === 'new' ) {
84 // Custom preload text for new sections
85 $preload = 'MediaWiki:addsection-preload';
86 }
87 $content = $this->getPreloadedContentFromParams( $page, $performer, $preload, $preloadParams );
88 }
89 $title = Title::newFromPageIdentity( $page );
90 if ( !$title->getArticleID() ) {
91 $contentModel = $title->getContentModel();
92 $contentHandler = $this->contentHandlerFactory->getContentHandler( $contentModel );
93 $contentFormat = $contentHandler->getDefaultFormat();
94 $text = $contentHandler->serializeContent( $content, $contentFormat );
95 $this->hookRunner->onEditFormPreloadText( $text, $title );
96 $content = $contentHandler->unserializeContent( $text, $contentFormat );
97 }
98 return $content;
99 }
100
111 public function getDefaultContent( ProperPageIdentity $page ): ?Content {
112 $title = Title::newFromPageIdentity( $page );
113 $contentModel = $title->getContentModel();
114 $contentHandler = $this->contentHandlerFactory->getContentHandler( $contentModel );
115 $contentFormat = $contentHandler->getDefaultFormat();
116 if ( $title->getNamespace() === NS_MEDIAWIKI ) {
117 // If this is a system message, get the default text.
118 $text = $title->getDefaultMessageText();
119 if ( $text !== false ) {
120 return $contentHandler->unserializeContent( $text, $contentFormat );
121 }
122 }
123 return null;
124 }
125
135 private function getPreloadedContentFromParams(
136 ProperPageIdentity $contextPage,
137 Authority $performer,
138 ?string $preload,
139 array $preloadParams
140 ): Content {
141 $contextTitle = Title::newFromPageIdentity( $contextPage );
142 $contentModel = $contextTitle->getContentModel();
143 $handler = $this->contentHandlerFactory->getContentHandler( $contentModel );
144
145 // T297725: Don't trick users into making edits to e.g. .js subpages
146 if ( !$handler->supportsPreloadContent() || $preload === null || $preload === '' ) {
147 return $handler->makeEmptyContent();
148 }
149
150 $title = Title::newFromText( $preload );
151
152 if ( $title && $title->getNamespace() == NS_MEDIAWIKI ) {
153 // When the preload source is in NS_MEDIAWIKI, get the content via wfMessage, to
154 // enable preloading from i18n messages. The message framework can work with normal
155 // pages in NS_MEDIAWIKI, so this does not restrict preloading only to i18n messages.
156 $msg = wfMessage( MessageCache::normalizeKey( $title->getText() ) );
157
158 if ( $msg->isDisabled() ) {
159 // Message is disabled and should not be used for preloading
160 return $handler->makeEmptyContent();
161 }
162
163 return $this->transform(
164 $handler->unserializeContent( $msg
165 ->page( $title )
166 ->params( $preloadParams )
167 ->inContentLanguage()
168 ->plain()
169 ),
170 $title
171 );
172 }
173
174 // (T299544) Use SpecialMyLanguage redirect so that nonexistent translated pages can
175 // fall back to the corresponding page in a suitable language
176 $title = $this->getTargetTitleIfSpecialMyLanguage( $title );
177
178 # Check for existence to avoid getting MediaWiki:Noarticletext
179 if ( !$this->isPageExistingAndViewable( $title, $performer ) ) {
180 // TODO: somehow show a warning to the user!
181 return $handler->makeEmptyContent();
182 }
183
184 $page = $this->wikiPageFactory->newFromTitle( $title );
185 if ( $page->isRedirect() ) {
186 $redirTarget = $this->redirectLookup->getRedirectTarget( $title );
187 $redirTarget = Title::castFromLinkTarget( $redirTarget );
188 # Same as before
189 if ( !$this->isPageExistingAndViewable( $redirTarget, $performer ) ) {
190 // TODO: somehow show a warning to the user!
191 return $handler->makeEmptyContent();
192 }
193 $page = $this->wikiPageFactory->newFromTitle( $redirTarget );
194 }
195
196 $content = $page->getContent( RevisionRecord::RAW );
197
198 if ( !$content ) {
199 // TODO: somehow show a warning to the user!
200 return $handler->makeEmptyContent();
201 }
202
203 if ( $content->getModel() !== $handler->getModelID() ) {
204 $converted = $content->convert( $handler->getModelID() );
205
206 if ( !$converted ) {
207 // TODO: somehow show a warning to the user!
208 wfDebug( "Attempt to preload incompatible content: " .
209 "can't convert " . $content->getModel() .
210 " to " . $handler->getModelID() );
211
212 return $handler->makeEmptyContent();
213 }
214
215 $content = $converted;
216 }
217 return $this->transform( $content, $title, $preloadParams );
218 }
219
220 private function transform(
221 Content $content,
222 PageReference $title,
223 array $preloadParams = []
224 ) {
225 return $this->contentTransformer->preloadTransform(
226 $content,
227 $title,
228 // The preload transformations don't depend on the user anyway
229 ParserOptions::newFromAnon(),
230 $preloadParams
231 );
232 }
233}
const NS_MEDIAWIKI
Definition Defines.php:73
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Provides the initial content of the edit box displayed in an edit form when creating a new page or a ...
__construct(IContentHandlerFactory $contentHandlerFactory, WikiPageFactory $wikiPageFactory, RedirectLookup $redirectLookup, SpecialPageFactory $specialPageFactory, ContentTransformer $contentTransformer, HookContainer $hookContainer)
getDefaultContent(ProperPageIdentity $page)
Get the content that is displayed when viewing a page that does not exist.
getPreloadedContent(ProperPageIdentity $page, Authority $performer, ?string $preload, array $preloadParams, ?string $section)
Get the initial content of the edit box displayed in an edit form when creating a new page or a new s...
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Service for creating WikiPage objects.
Page revision base class.
Factory for handling the special page list and generating SpecialPage objects.
Represents a title within MediaWiki.
Definition Title.php:78
getContentModel( $flags=0)
Get the page's content model id, see the CONTENT_MODEL_XXX constants.
Definition Title.php:1065
Cache messages that are defined by MediaWiki-namespace pages or by hooks.
Set options of the Parser.
Base interface for representing page content.
Definition Content.php:39
Interface for objects (potentially) representing a page that can be viewable and linked to on a wiki.
Interface for a page that is (or could be, or used to be) an editable wiki page.
Service for resolving a wiki page redirect.
This interface represents the authority associated with the current execution context,...
Definition Authority.php:37