MediaWiki  master
PageContentHelper.php
Go to the documentation of this file.
1 <?php
2 
3 namespace MediaWiki\Rest\Handler;
4 
5 use Config;
17 use TextContent;
18 use TitleFormatter;
21 
26  private const MAX_AGE_200 = 5;
27 
29  protected $config;
30 
32  protected $revisionLookup;
33 
35  protected $titleFormatter;
36 
38  protected $pageLookup;
39 
41  protected $authority = null;
42 
44  protected $parameters = null;
45 
47  protected $targetRevision = false;
48 
50  protected $pageRecord = false;
51 
58  public function __construct(
63  ) {
64  $this->config = $config;
65  $this->revisionLookup = $revisionLookup;
66  $this->titleFormatter = $titleFormatter;
67  $this->pageLookup = $pageLookup;
68  }
69 
74  public function init( Authority $authority, array $parameters ) {
75  $this->authority = $authority;
76  $this->parameters = $parameters;
77  }
78 
82  public function getTitleText(): ?string {
83  return $this->parameters['title'] ?? null;
84  }
85 
89  public function getPage(): ?ExistingPageRecord {
90  if ( $this->pageRecord === false ) {
91  $titleText = $this->getTitleText();
92  if ( !$titleText ) {
93  return null;
94  }
95  $this->pageRecord = $this->pageLookup->getExistingPageByText( $titleText );
96  }
97  return $this->pageRecord;
98  }
99 
105  public function getTargetRevision(): ?RevisionRecord {
106  if ( $this->targetRevision === false ) {
107  $page = $this->getPage();
108  if ( $page ) {
109  $this->targetRevision = $this->revisionLookup->getRevisionByTitle( $page );
110  } else {
111  $this->targetRevision = null;
112  }
113  }
114  return $this->targetRevision;
115  }
116 
117  // Default to main slot
118  public function getRole(): string {
119  return SlotRecord::MAIN;
120  }
121 
126  public function getContent(): TextContent {
127  $revision = $this->getTargetRevision();
128 
129  if ( !$revision ) {
130  $titleText = $this->getTitleText() ?? '';
131  throw new LocalizedHttpException(
132  MessageValue::new( 'rest-no-revision' )->plaintextParams( $titleText ),
133  404
134  );
135  }
136 
137  $slotRole = $this->getRole();
138 
139  try {
140  $content = $revision
141  ->getSlot( $slotRole, RevisionRecord::FOR_THIS_USER, $this->authority )
142  ->getContent()
143  ->convert( CONTENT_MODEL_TEXT );
144  if ( !( $content instanceof TextContent ) ) {
145  throw new LocalizedHttpException( MessageValue::new( 'rest-page-source-type-error' ), 400 );
146  }
147  } catch ( SuppressedDataException $e ) {
148  throw new LocalizedHttpException(
149  MessageValue::new( 'rest-permission-denied-revision' )->numParams( $revision->getId() ),
150  403
151  );
152  } catch ( RevisionAccessException $e ) {
153  throw new LocalizedHttpException(
154  MessageValue::new( 'rest-nonexistent-revision' )->numParams( $revision->getId() ),
155  404
156  );
157  }
158  return $content;
159  }
160 
164  public function isAccessible(): bool {
165  $page = $this->getPage();
166  return $page && $this->authority->probablyCan( 'read', $page );
167  }
168 
175  public function getETag(): ?string {
176  $revision = $this->getTargetRevision();
177  $revId = $revision ? $revision->getId() : 'e0';
178 
179  $isAccessible = $this->isAccessible();
180  $accessibleTag = $isAccessible ? 'a1' : 'a0';
181 
182  $revisionTag = $revId . $accessibleTag;
183  return '"' . sha1( $revisionTag ) . '"';
184  }
185 
189  public function getLastModified(): ?string {
190  if ( !$this->isAccessible() ) {
191  return null;
192  }
193 
194  $revision = $this->getTargetRevision();
195  if ( $revision ) {
196  return $revision->getTimestamp();
197  }
198  return null;
199  }
200 
206  public function hasContent(): bool {
207  return (bool)$this->getPage();
208  }
209 
213  public function constructMetadata(): array {
214  $page = $this->getPage();
215  $revision = $this->getTargetRevision();
216  return [
217  'id' => $page->getId(),
218  'key' => $this->titleFormatter->getPrefixedDBkey( $page ),
219  'title' => $this->titleFormatter->getPrefixedText( $page ),
220  'latest' => [
221  'id' => $revision->getId(),
222  'timestamp' => wfTimestampOrNull( TS_ISO_8601, $revision->getTimestamp() )
223  ],
224  'content_model' => $this->getTargetRevision()
225  ->getSlot( SlotRecord::MAIN, RevisionRecord::RAW )
226  ->getModel(),
227  'license' => [
228  'url' => $this->config->get( 'RightsUrl' ),
229  'title' => $this->config->get( 'RightsText' )
230  ],
231  ];
232  }
233 
237  public function getParamSettings(): array {
238  return [
239  'title' => [
240  Handler::PARAM_SOURCE => 'path',
241  ParamValidator::PARAM_TYPE => 'string',
242  ParamValidator::PARAM_REQUIRED => true,
243  ],
244  ];
245  }
246 
252  public function setCacheControl( ResponseInterface $response, int $expiry = null ) {
253  if ( $expiry === null ) {
254  $maxAge = self::MAX_AGE_200;
255  } else {
256  $maxAge = min( self::MAX_AGE_200, $expiry );
257  }
258  $response->setHeader(
259  'Cache-Control',
260  'max-age=' . $maxAge
261  );
262  }
263 
267  public function checkAccess() {
268  $titleText = $this->getTitleText() ?? '';
269 
270  if ( !$this->hasContent() ) {
271  throw new LocalizedHttpException(
272  MessageValue::new( 'rest-nonexistent-title' )->plaintextParams( $titleText ),
273  404
274  );
275  }
276 
277  if ( !$this->authority->authorizeRead( 'read', $this->getPage() ) ) {
278  throw new LocalizedHttpException(
279  MessageValue::new( 'rest-permission-denied-title' )->plaintextParams( $titleText ),
280  403
281  );
282  }
283 
284  $revision = $this->getTargetRevision();
285  if ( !$revision ) {
286  throw new LocalizedHttpException(
287  MessageValue::new( 'rest-no-revision' )->plaintextParams( $titleText ),
288  404
289  );
290  }
291  }
292 
293 }
MediaWiki\Revision\RevisionRecord\RAW
const RAW
Definition: RevisionRecord.php:64
MediaWiki\Rest\Handler\PageContentHelper\getPage
getPage()
Definition: PageContentHelper.php:89
MediaWiki\Rest\Handler\PageContentHelper\isAccessible
isAccessible()
Definition: PageContentHelper.php:164
MediaWiki\Rest\Handler
Definition: AbstractContributionHandler.php:3
MediaWiki\Revision\RevisionAccessException
Exception representing a failure to look up a revision.
Definition: RevisionAccessException.php:37
MediaWiki\Revision\RevisionRecord
Page revision base class.
Definition: RevisionRecord.php:47
MediaWiki\Rest\Handler\PageContentHelper\$titleFormatter
TitleFormatter $titleFormatter
Definition: PageContentHelper.php:35
MediaWiki\Rest\Handler\PageContentHelper\getTitleText
getTitleText()
Definition: PageContentHelper.php:82
MediaWiki\Revision\SuppressedDataException
Exception raised in response to an audience check when attempting to access suppressed information wi...
Definition: SuppressedDataException.php:33
MediaWiki\Rest\Handler\PageContentHelper\init
init(Authority $authority, array $parameters)
Definition: PageContentHelper.php:74
MediaWiki\Rest\Handler\PageContentHelper\getTargetRevision
getTargetRevision()
Returns the target revision.
Definition: PageContentHelper.php:105
MediaWiki\Rest\Handler\PARAM_SOURCE
const PARAM_SOURCE
(string) ParamValidator constant to specify the source of the parameter.
Definition: Handler.php:26
MediaWiki\Rest\Handler\PageContentHelper\checkAccess
checkAccess()
Definition: PageContentHelper.php:267
MediaWiki\Rest\Handler\PageContentHelper\$pageLookup
PageLookup $pageLookup
Definition: PageContentHelper.php:38
MediaWiki\Revision\RevisionLookup
Service for looking up page revisions.
Definition: RevisionLookup.php:38
Wikimedia\Message\MessageValue
Value object representing a message for i18n.
Definition: MessageValue.php:16
MediaWiki\Rest\Handler\PageContentHelper\getParamSettings
getParamSettings()
Definition: PageContentHelper.php:237
Config
Interface for configuration instances.
Definition: Config.php:30
MediaWiki\Rest\Handler\PageContentHelper\hasContent
hasContent()
Checks whether content exists.
Definition: PageContentHelper.php:206
MediaWiki\Rest\ResponseInterface\setHeader
setHeader( $name, $value)
Set or replace the specified header.
MediaWiki\Rest\Handler\PageContentHelper\$authority
Authority null $authority
Definition: PageContentHelper.php:41
wfTimestampOrNull
wfTimestampOrNull( $outputtype=TS_UNIX, $ts=null)
Return a formatted timestamp, or null if input is null.
Definition: GlobalFunctions.php:1707
MediaWiki\Rest\Handler\PageContentHelper\$pageRecord
ExistingPageRecord false null $pageRecord
Definition: PageContentHelper.php:50
MediaWiki\Rest\Handler\PageContentHelper\setCacheControl
setCacheControl(ResponseInterface $response, int $expiry=null)
Sets the 'Cache-Control' header no more then provided $expiry.
Definition: PageContentHelper.php:252
MediaWiki\Rest\Handler\PageContentHelper\MAX_AGE_200
const MAX_AGE_200
Definition: PageContentHelper.php:26
MediaWiki\Rest\Handler\PageContentHelper\getETag
getETag()
Returns an ETag representing a page's source.
Definition: PageContentHelper.php:175
MediaWiki\Rest\Handler\PageContentHelper\getRole
getRole()
Definition: PageContentHelper.php:118
MediaWiki\Permissions\Authority
This interface represents the authority associated the current execution context, such as a web reque...
Definition: Authority.php:37
Page\ExistingPageRecord
Data record representing a page that currently exists as an editable page on a wiki.
Definition: ExistingPageRecord.php:15
$content
$content
Definition: router.php:76
MediaWiki\Rest\ResponseInterface
An interface similar to PSR-7's ResponseInterface, the primary difference being that it is mutable.
Definition: ResponseInterface.php:41
Page\PageLookup
Service interface for looking up infermation about wiki pages.
Definition: PageLookup.php:14
MediaWiki\Rest\Handler\PageContentHelper\$parameters
string[] $parameters
Definition: PageContentHelper.php:44
MediaWiki\Rest\Handler\PageContentHelper\__construct
__construct(Config $config, RevisionLookup $revisionLookup, TitleFormatter $titleFormatter, PageLookup $pageLookup)
Definition: PageContentHelper.php:58
MediaWiki\Rest\Handler\PageContentHelper\constructMetadata
constructMetadata()
Definition: PageContentHelper.php:213
MediaWiki\Rest\Handler\PageContentHelper
Definition: PageContentHelper.php:25
TextContent
Content object implementation for representing flat text.
Definition: TextContent.php:39
CONTENT_MODEL_TEXT
const CONTENT_MODEL_TEXT
Definition: Defines.php:211
TitleFormatter
A title formatter service for MediaWiki.
Definition: TitleFormatter.php:35
Wikimedia\Message\MessageValue\new
static new( $key, $params=[])
Static constructor for easier chaining of ->params() methods.
Definition: MessageValue.php:42
MediaWiki\Revision\RevisionRecord\FOR_THIS_USER
const FOR_THIS_USER
Definition: RevisionRecord.php:63
MediaWiki\Rest\Handler\PageContentHelper\getContent
getContent()
Definition: PageContentHelper.php:126
MediaWiki\Rest\Handler\PageContentHelper\$targetRevision
RevisionRecord false null $targetRevision
Definition: PageContentHelper.php:47
Wikimedia\ParamValidator\ParamValidator
Service for formatting and validating API parameters.
Definition: ParamValidator.php:42
MediaWiki\Rest\LocalizedHttpException
@newable
Definition: LocalizedHttpException.php:10
MediaWiki\Revision\SlotRecord
Value object representing a content slot associated with a page revision.
Definition: SlotRecord.php:40
MediaWiki\Rest\Handler\PageContentHelper\getLastModified
getLastModified()
Definition: PageContentHelper.php:189
MediaWiki\Rest\Handler\PageContentHelper\$revisionLookup
RevisionLookup $revisionLookup
Definition: PageContentHelper.php:32
MediaWiki\Rest\Handler\PageContentHelper\$config
Config $config
Definition: PageContentHelper.php:29