MediaWiki 1.40.4
PageConfigFactory.php
Go to the documentation of this file.
1<?php
21
33use Wikimedia\Bcp47Code\Bcp47Code;
34use Wikimedia\Parsoid\Config\Api\PageConfig as ApiPageConfig;
36
43class PageConfigFactory extends \Wikimedia\Parsoid\Config\PageConfigFactory {
44
46 private $revisionStore;
47
49 private $slotRoleRegistry;
50
52 private $languageFactory;
53
59 public function __construct(
60 RevisionStore $revisionStore,
61 SlotRoleRegistry $slotRoleRegistry,
62 LanguageFactory $languageFactory
63 ) {
64 $this->revisionStore = $revisionStore;
65 $this->slotRoleRegistry = $slotRoleRegistry;
66 $this->languageFactory = $languageFactory;
67 }
68
86 public function create(
87 PageIdentity $pageId,
88 ?UserIdentity $user = null,
89 $revision = null,
90 ?string $unused = null, /* Added to mollify CI with cross-repo uses */
91 ?Bcp47Code $pageLanguageOverride = null,
92 ?array $parsoidSettings = null
93 ): \Wikimedia\Parsoid\Config\PageConfig {
94 $title = Title::castFromPageIdentity( $pageId );
95 '@phan-var Title $title';
96
97 if ( !empty( $parsoidSettings['debugApi'] ) ) {
98 if ( $revision === null ) {
99 throw new \InvalidArgumentException(
100 "Revision not provided. Cannot lookup revision via debug API." );
101 }
102
103 $content = $revision->getContent( SlotRecord::MAIN );
104 if ( $content instanceof WikitextContent ) {
105 $wtContent = $content->getText();
106 return ApiPageConfig::fromSettings( $parsoidSettings, [
107 "title" => $title->getPrefixedText(),
108 "pageContent" => $wtContent,
109 "pageLanguage" => $pageLanguageOverride, # ?Bcp47Code
110 "revid" => $revision->getId(),
111 "loadData" => true,
112 ] );
113 } else {
114 throw new \UnexpectedValueException(
115 "Non-wikitext content models not supported by debug API" );
116 }
117 }
118
119 if ( $revision === null ) {
120 // Fetch the 'latest' revision for the given title.
121 // Note: This initial fetch of the page context revision is
122 // *not* using Parser::fetchCurrentRevisionRecordOfTitle()
123 // (which usually invokes Parser::statelessFetchRevisionRecord
124 // and from there RevisionStore::getKnownCurrentRevision)
125 // because we don't have a Parser object to give to that callback.
126 // We could create one if needed for greater compatibility.
127 $revisionRecord = $this->revisionStore->getKnownCurrentRevision(
128 $title
129 ) ?: null;
130 // Note that $revisionRecord could still be null here if no
131 // page with that $title yet exists.
132 } elseif ( !is_int( $revision ) ) {
133 $revisionRecord = $revision;
134 } else {
135 if ( $revision === 0 ) {
136 // The client may explicitly provide 0 as the revision ID to indicate that
137 // the content doesn't belong to any saved revision, and provide wikitext
138 // in some way. Calling code should handle this case and provide a (fake)
139 // RevisionRecord based on the data in the request. If we get here, the
140 // code processing the request didn't handle this case properly.
141 throw new \UnexpectedValueException(
142 "Got revision ID 0 indicating unsaved content. " .
143 "Unsaved content must be provided as a RevisionRecord object."
144 );
145 }
146
147 // Fetch the correct revision record by the supplied id.
148 // This accesses the replica DB and may (or may not) fail over to
149 // the primary DB if the revision isn't found.
150 $revisionRecord = $this->revisionStore->getRevisionById( $revision );
151 if ( $revisionRecord === null ) {
152 // This revision really ought to exist. Check the primary DB.
153 // This *could* cause two requests to the primary DB if there
154 // were pending writes, but this codepath should be very rare.
155 // [T259855]
156 $revisionRecord = $this->revisionStore->getRevisionById(
157 $revision, RevisionStore::READ_LATEST
158 );
159 $success = ( $revisionRecord !== null ) ? 'success' : 'failure';
160 LoggerFactory::getInstance( 'Parsoid' )->error(
161 "Retried revision fetch after failure: {$success}", [
162 'id' => $revision,
163 'title' => $title->getPrefixedText(),
164 ]
165 );
166 }
167 if ( $revisionRecord === null ) {
168 throw new RevisionAccessException( "Can't find revision {$revision}" );
169 }
170 }
171
172 // If we have a revision record, check that we are allowed to see it.
173 // Mirrors the check from RevisionRecord::getContent
174 if (
175 $revisionRecord !== null &&
176 !$revisionRecord->audienceCan(
177 RevisionRecord::DELETED_TEXT, RevisionRecord::FOR_PUBLIC
178 )
179 ) {
180 throw new RevisionAccessException( 'Not an available content version.' );
181 }
182
183 $parserOptions =
184 $user
186 : ParserOptions::newFromAnon();
187
188 // Turn off some options since Parsoid/JS currently doesn't
189 // do anything with this. As we proceed with closer integration,
190 // we can figure out if there is any value to these limit reports.
191 $parserOptions->setOption( 'enableLimitReport', false );
192
193 $slotRoleHandler = $this->slotRoleRegistry->getRoleHandler( SlotRecord::MAIN );
194 if ( $pageLanguageOverride ) {
195 $pageLanguage = $this->languageFactory->getLanguage( $pageLanguageOverride );
196 } else {
197 $pageLanguage = $title->getPageLanguage();
198 }
199 return new PageConfig(
200 $parserOptions,
201 $slotRoleHandler,
202 $title,
203 $revisionRecord,
204 $pageLanguage,
205 $pageLanguage->getDir()
206 );
207 }
208
209}
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
PSR-3 logger instance factory.
Helper class used by MediaWiki to create Parsoid PageConfig objects.
__construct(RevisionStore $revisionStore, SlotRoleRegistry $slotRoleRegistry, LanguageFactory $languageFactory)
create(PageIdentity $pageId, ?UserIdentity $user=null, $revision=null, ?string $unused=null, ?Bcp47Code $pageLanguageOverride=null, ?array $parsoidSettings=null)
Create a new PageConfig.
Page-level configuration interface for Parsoid.
Exception representing a failure to look up a revision.
Page revision base class.
Service for looking up page revisions.
Value object representing a content slot associated with a page revision.
A registry service for SlotRoleHandlers, used to define which slot roles are available on which page.
Represents a title within MediaWiki.
Definition Title.php:82
Set options of the Parser.
setOption( $name, $value)
Set an option, generically.
static newFromUser( $user)
Get a ParserOptions object from a given user.
Content object for wiki text pages.
Interface for configuration instances.
Definition Config.php:30
Interface for objects (potentially) representing an editable wiki page.
Interface for objects representing user identity.
Copyright (C) 2011-2022 Wikimedia Foundation and others.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU Ge...
$content
Definition router.php:76