MediaWiki  master
MediaLinksHandler.php
Go to the documentation of this file.
1 <?php
2 
3 namespace MediaWiki\Rest\Handler;
4 
5 use MediaFileTrait;
11 use RepoGroup;
15 
20  use MediaFileTrait;
21 
23  private const MAX_NUM_LINKS = 100;
24 
26  private $loadBalancer;
27 
29  private $repoGroup;
30 
32  private $pageLookup;
33 
37  private $page = false;
38 
44  public function __construct(
48  ) {
49  $this->loadBalancer = $loadBalancer;
50  $this->repoGroup = $repoGroup;
51  $this->pageLookup = $pageLookup;
52  }
53 
57  private function getPage(): ?ExistingPageRecord {
58  if ( $this->page === false ) {
59  $this->page = $this->pageLookup->getExistingPageByText(
60  $this->getValidatedParams()['title']
61  );
62  }
63  return $this->page;
64  }
65 
71  public function run( $title ) {
72  $page = $this->getPage();
73  if ( !$page ) {
74  throw new LocalizedHttpException(
75  MessageValue::new( 'rest-nonexistent-title' )->plaintextParams( $title ),
76  404
77  );
78  }
79 
80  if ( !$this->getAuthority()->authorizeRead( 'read', $page ) ) {
81  throw new LocalizedHttpException(
82  MessageValue::new( 'rest-permission-denied-title' )->plaintextParams( $title ),
83  403
84  );
85  }
86 
87  // @todo: add continuation if too many links are found
88  $results = $this->getDbResults( $page->getId() );
89  if ( count( $results ) > self::MAX_NUM_LINKS ) {
90  throw new LocalizedHttpException(
91  MessageValue::new( 'rest-media-too-many-links' )
92  ->plaintextParams( $title )
93  ->numParams( self::MAX_NUM_LINKS ),
94  500
95  );
96  }
97  $response = $this->processDbResults( $results );
98  return $this->getResponseFactory()->createJson( $response );
99  }
100 
105  private function getDbResults( int $pageId ) {
106  $dbr = $this->loadBalancer->getConnectionRef( DB_REPLICA );
107  return $dbr->selectFieldValues(
108  'imagelinks',
109  'il_to',
110  [ 'il_from' => $pageId ],
111  __METHOD__,
112  [
113  'ORDER BY' => 'il_to',
114  'LIMIT' => self::MAX_NUM_LINKS + 1,
115  ]
116  );
117  }
118 
123  private function processDbResults( $results ) {
124  // Using "private" here means an equivalent of the Action API's "anon-public-user-private"
125  // caching model would be necessary, if caching is ever added to this endpoint.
126  $performer = $this->getAuthority();
127  $findTitles = array_map( static function ( $title ) use ( $performer ) {
128  return [
129  'title' => $title,
130  'private' => $performer,
131  ];
132  }, $results );
133 
134  $files = $this->repoGroup->findFiles( $findTitles );
135  list( $maxWidth, $maxHeight ) = self::getImageLimitsFromOption(
136  $this->getAuthority()->getUser(),
137  'imagesize'
138  );
139  $transforms = [
140  'preferred' => [
141  'maxWidth' => $maxWidth,
142  'maxHeight' => $maxHeight,
143  ]
144  ];
145  $response = [];
146  foreach ( $files as $file ) {
147  $response[] = $this->getFileInfo( $file, $performer, $transforms );
148  }
149 
150  $response = [
151  'files' => $response
152  ];
153 
154  return $response;
155  }
156 
157  public function needsWriteAccess() {
158  return false;
159  }
160 
161  public function getParamSettings() {
162  return [
163  'title' => [
164  self::PARAM_SOURCE => 'path',
165  ParamValidator::PARAM_TYPE => 'string',
167  ],
168  ];
169  }
170 
175  protected function getETag(): ?string {
176  $page = $this->getPage();
177  if ( !$page ) {
178  return null;
179  }
180 
181  // XXX: use hash of the rendered HTML?
182  return '"' . $page->getLatest() . '@' . wfTimestamp( TS_MW, $page->getTouched() ) . '"';
183  }
184 
189  protected function getLastModified(): ?string {
190  $page = $this->getPage();
191  if ( !$page ) {
192  return null;
193  }
194 
195  return $page->getTouched();
196  }
197 
201  protected function hasRepresentation() {
202  return (bool)$this->getPage();
203  }
204 }
getUser()
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
if(!defined('MW_SETUP_CALLBACK'))
The persistent session ID (if any) loaded at startup.
Definition: WebStart.php:82
Handler class for Core REST API endpoints that perform operations on revisions.
__construct(ILoadBalancer $loadBalancer, RepoGroup $repoGroup, PageLookup $pageLookup)
const MAX_NUM_LINKS
int The maximum number of media links to return
getParamSettings()
Fetch ParamValidator settings for parameters.
ExistingPageRecord false null $page
needsWriteAccess()
Indicates whether this route requires write access.
getValidatedParams()
Fetch the validated parameters.
Definition: Handler.php:322
getAuthority()
Get the current acting authority.
Definition: Handler.php:156
getResponseFactory()
Get the ResponseFactory which can be used to generate Response objects.
Definition: Handler.php:178
Prioritized list of file repositories.
Definition: RepoGroup.php:29
Value object representing a message for i18n.
static new( $key, $params=[])
Static constructor for easier chaining of ->params() methods.
Service for formatting and validating API parameters.
const PARAM_TYPE
(string|array) Type of the parameter.
const PARAM_REQUIRED
(bool) Indicate that the parameter is required.
Data record representing a page that currently exists as an editable page on a wiki.
Service for looking up information about wiki pages.
Definition: PageLookup.php:16
Database cluster connection, tracking, load balancing, and transaction manager interface.
Copyright (C) 2011-2020 Wikimedia Foundation and others.
const DB_REPLICA
Definition: defines.php:26
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42