MediaWiki  master
PageConfigFactory.php
Go to the documentation of this file.
1 <?php
21 
30 use ParserOptions;
31 use Title;
32 use Wikimedia\Parsoid\Config\Api\PageConfig as ApiPageConfig;
33 use WikitextContent;
34 
40 class PageConfigFactory extends \Wikimedia\Parsoid\Config\PageConfigFactory {
41 
43  private $revisionStore;
44 
46  private $slotRoleRegistry;
47 
52  public function __construct(
53  RevisionStore $revisionStore,
54  SlotRoleRegistry $slotRoleRegistry
55  ) {
56  $this->revisionStore = $revisionStore;
57  $this->slotRoleRegistry = $slotRoleRegistry;
58  }
59 
77  public function create(
78  PageIdentity $pageId,
79  ?UserIdentity $user = null,
80  $revision = null,
81  ?string $unused = null, /* Added to mollify CI with cross-repo uses */
82  ?string $pagelanguageOverride = null,
83  ?array $parsoidSettings = null
84  ): \Wikimedia\Parsoid\Config\PageConfig {
85  $title = Title::castFromPageIdentity( $pageId );
86  '@phan-var Title $title';
87 
88  if ( !empty( $parsoidSettings['debugApi'] ) ) {
89  if ( $revision === null ) {
90  throw new \InvalidArgumentException(
91  "Revision not provided. Cannot lookup revision via debug API." );
92  }
93 
94  $content = $revision->getContent( SlotRecord::MAIN );
95  if ( $content instanceof WikitextContent ) {
96  $wtContent = $content->getText();
97  return ApiPageConfig::fromSettings( $parsoidSettings, [
98  "title" => $title->getPrefixedText(),
99  "pageContent" => $wtContent,
100  "pageLanguage" => $pagelanguageOverride,
101  "revid" => $revision->getId(),
102  "loadData" => true,
103  ] );
104  } else {
105  throw new \UnexpectedValueException(
106  "Non-wikitext content models not supported by debug API" );
107  }
108  }
109 
110  if ( $revision === null ) {
111  // Fetch the 'latest' revision for the given title.
112  // Note: This initial fetch of the page context revision is
113  // *not* using Parser::fetchCurrentRevisionRecordOfTitle()
114  // (which usually invokes Parser::statelessFetchRevisionRecord
115  // and from there RevisionStore::getKnownCurrentRevision)
116  // because we don't have a Parser object to give to that callback.
117  // We could create one if needed for greater compatibility.
118  $revisionRecord = $this->revisionStore->getKnownCurrentRevision(
119  $title
120  ) ?: null;
121  // Note that $revisionRecord could still be null here if no
122  // page with that $title yet exists.
123  } elseif ( !is_int( $revision ) ) {
124  $revisionRecord = $revision;
125  } else {
126  // Fetch the correct revision record by the supplied id.
127  // This accesses the replica DB and may (or may not) fail over to
128  // the primary DB if the revision isn't found.
129  $revisionRecord = $this->revisionStore->getRevisionById( $revision );
130  if ( $revisionRecord === null ) {
131  // This revision really ought to exist. Check the primary DB.
132  // This *could* cause two requests to the primary DB if there
133  // were pending writes, but this codepath should be very rare.
134  // [T259855]
135  $revisionRecord = $this->revisionStore->getRevisionById(
136  $revision, RevisionStore::READ_LATEST
137  );
138  $success = ( $revisionRecord !== null ) ? 'success' : 'failure';
139  LoggerFactory::getInstance( 'Parsoid' )->error(
140  "Retried revision fetch after failure: {$success}", [
141  'id' => $revision,
142  'title' => $title->getPrefixedText(),
143  ]
144  );
145  }
146  if ( $revisionRecord === null ) {
147  throw new RevisionAccessException( "Can't find revision {$revision}" );
148  }
149  }
150 
151  // If we have a revision record, check that we are allowed to see it.
152  // Mirrors the check from RevisionRecord::getContent
153  if (
154  $revisionRecord !== null &&
155  !$revisionRecord->audienceCan(
157  )
158  ) {
159  throw new RevisionAccessException( 'Not an available content version.' );
160  }
161 
162  $parserOptions =
163  $user
164  ? ParserOptions::newFromUser( $user )
165  : ParserOptions::newFromAnon();
166 
167  // Turn off some options since Parsoid/JS currently doesn't
168  // do anything with this. As we proceed with closer integration,
169  // we can figure out if there is any value to these limit reports.
170  $parserOptions->setOption( 'enableLimitReport', false );
171 
172  $slotRoleHandler = $this->slotRoleRegistry->getRoleHandler( SlotRecord::MAIN );
173  return new PageConfig(
174  $parserOptions,
175  $slotRoleHandler,
176  $title,
177  $revisionRecord,
178  $pagelanguageOverride
179  );
180  }
181 
182 }
$success
PSR-3 logger instance factory.
static getInstance( $channel)
Get a named logger instance from the currently configured logger factory.
Helper class used by MediaWiki to create Parsoid PageConfig objects.
__construct(RevisionStore $revisionStore, SlotRoleRegistry $slotRoleRegistry)
create(PageIdentity $pageId, ?UserIdentity $user=null, $revision=null, ?string $unused=null, ?string $pagelanguageOverride=null, ?array $parsoidSettings=null)
Create a new PageConfig.
Page-level configuration interface for Parsoid.
Definition: PageConfig.php:39
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.
Definition: SlotRecord.php:40
A registry service for SlotRoleHandlers, used to define which slot roles are available on which page.
Set options of the Parser.
setOption( $name, $value)
Set an option, generically.
static newFromUser( $user)
Get a ParserOptions object from a given user.
Represents a title within MediaWiki.
Definition: Title.php:49
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.
Definition: DataAccess.php:20
$content
Definition: router.php:76