$prop = array_flip( $params['prop'] );
- $scale = $this->getScale( $params );
+ $thumbParams = $this->makeThumbParams( $params );
$pageIds = $this->getPageSet()->getAllTitlesByNamespace();
if ( !empty( $pageIds[NS_FILE] ) ) {
)
{
$gotOne = true;
+ $this->validateThumbParams( $img, $thumbParams );
$fit = $this->addPageSubItem( $pageId,
- self::getInfo( $img, $prop, $result, $scale ) );
+ self::getInfo( $img, $prop, $result, $thumbParams ) );
if ( !$fit ) {
if ( count( $pageIds[NS_IMAGE] ) == 1 ) {
// See the 'the user is screwed' comment above
* @return Array or Null: key-val array of 'width' and 'height', or null
*/
public function getScale( $params ) {
+ wfDeprecated( __METHOD__ );
+ if ( !isset( $params['urlparam'] ) ) {
+ // In case there are subclasses that
+ // don't have this param set to anything.
+ $params['urlparam'] = null;
+ }
+ return $this->makeThumbParams( $params );
+ }
+
+ /* Take parameters for transforming thumbnail, validate and turn into array.
+ * @param $params Array: Parameters from the request.
+ * @return Array or null: If array, suitable to passing to $file->transform.
+ */
+ public function makeThumbParams( $params ) {
$p = $this->getModulePrefix();
+
+ // Height and width.
if ( $params['urlheight'] != -1 && $params['urlwidth'] == -1 ) {
- $this->dieUsage( "${p}urlheight cannot be used without {$p}urlwidth", "{$p}urlwidth" );
+ $this->dieUsage( "{$p}urlheight cannot be used without {$p}urlwidth", "{$p}urlwidth" );
}
if ( $params['urlwidth'] != -1 ) {
$scale['height'] = $params['urlheight'];
} else {
$scale = null;
+ if ( $params['urlparam'] ) {
+ $this->dieUsage( "{$p}urlparam requires {$p}urlwidth", "urlparam_no_width" );
+ }
+ return $scale;
+ }
+
+ // Other parameters.
+ if ( is_array( $params['urlparam'] ) ) {
+ foreach( $params['urlparam'] as $item ) {
+ $parameter = explode( '=', $item, 2 );
+
+ if ( count( $parameter ) !== 2
+ || $parameter[0] === 'width'
+ || $parameter[0] === 'height'
+ ) {
+ $this->dieUsage( "Invalid value for {$p}urlparam ($item)", "urlparam" );
+ }
+ $scale[$parameter[0]] = $parameter[1];
+ }
}
return $scale;
}
+ /** Validate the thumb parameters, give error if invalid.
+ *
+ * We do this later than makeThumbParams, since we need the image
+ * to know which handler, since handlers can make their own parameters.
+ * @param File $image Image that params are for.
+ * @param Array $thumbParams thumbnail parameters
+ */
+ protected function validateThumbParams ( $image, $thumbParams ) {
+ if ( !$thumbParams ) return;
+ $p = $this->getModulePrefix();
+
+ $h = $image->getHandler();
+ if ( !h ) {
+ // No handler, so no value for iiurlparam is valid.
+ $this->dieUsage( "Invalid value for {$p}urlparam", "urlparam" );
+ }
+ foreach ( $thumbParams as $name => $value ) {
+ if ( !$h->validateParam( $name, $value ) ) {
+ /* This doesn't work well with height=-1 placeholder */
+ if ( $name === 'height' ) continue;
+ $this->dieUsage( "Invalid value for {$p}urlparam ($name=$value)", "urlparam" );
+ }
+ }
+ // This could also potentially check normaliseParams as well, However that seems
+ // to fall more into a thumbnail rendering error than a user input error, and
+ // will be checked by the transform functions.
+ }
/**
* Get result information for an image revision
* @param $file File object
* @param $prop Array of properties to get (in the keys)
* @param $result ApiResult object
- * @param $scale Array containing 'width' and 'height' items, or null
+ * @param $thumbParams Array containing 'width' and 'height' items, or null
* @return Array: result array
*/
- static function getInfo( $file, $prop, $result, $scale = null ) {
+ static function getInfo( $file, $prop, $result, $thumbParams = null ) {
$vals = array();
if ( isset( $prop['timestamp'] ) ) {
$vals['timestamp'] = wfTimestamp( TS_ISO_8601, $file->getTimestamp() );
}
}
if ( isset( $prop['url'] ) ) {
- if ( !is_null( $scale ) && !$file->isOld() ) {
- $mto = $file->transform( array( 'width' => $scale['width'], 'height' => $scale['height'] ) );
+ if ( !is_null( $thumbParams ) && !$file->isOld() ) {
+ $mto = $file->transform( $thumbParams );
if ( $mto && !$mto->isError() ) {
$vals['thumburl'] = wfExpandUrl( $mto->getUrl() );
ApiBase::PARAM_TYPE => 'integer',
ApiBase::PARAM_DFLT => -1
),
+ 'urlparam' => array(
+ ApiBase::PARAM_ISMULTI => true,
+ ),
'continue' => null,
);
}
'urlwidth' => array( "If {$p}prop=url is set, a URL to an image scaled to this width will be returned.",
'Only the current version of the image can be scaled' ),
'urlheight' => "Similar to {$p}urlwidth. Cannot be used without {$p}urlwidth",
+ 'urlparam' => array( "Other rending parameters, such as page=2 for multipaged documents.",
+ "Multiple parameters should be seperated with a |. {$p}urlwidth must also be used"),
'limit' => 'How many image revisions to return',
'start' => 'Timestamp to start listing from',
'end' => 'Timestamp to stop listing at',
}
public function getPossibleErrors() {
+ $p = $this->getModulePrefix();
return array_merge( parent::getPossibleErrors(), array(
array( 'code' => 'iiurlwidth', 'info' => 'iiurlheight cannot be used without iiurlwidth' ),
+ array( 'code' => 'urlparam', 'info' => "Invalid value for {$p}urlparam" ),
+ array( 'code' => 'urlparam_no_width', 'info' => "iiurlparam requires {$p}urlwidth" ),
) );
}
$prop = array_flip( $params['prop'] );
- $scale = $this->getScale( $params );
+ $scale = $this->makeThumbParams( $params );
$result = $this->getResult();
foreach ( $params['sessionkey'] as $sessionkey ) {
$file = $stash->getFile( $sessionkey );
+ $this->validateThumbParams( $file, $scale );
$imageInfo = self::getInfo( $file, $prop, $result, $scale );
$result->addValue( array( 'query', $this->getModuleName() ), null, $imageInfo );
$result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), $modulePrefix );
'urlheight' => array(
ApiBase::PARAM_TYPE => 'integer',
ApiBase::PARAM_DFLT => -1
- )
+ ),
+ 'urlparam' => array(
+ ApiBase::PARAM_ISMULTI => true,
+ ),
);
}
),
'sessionkey' => 'Session key that identifies a previous upload that was stashed temporarily.',
'urlwidth' => "If {$p}prop=url is set, a URL to an image scaled to this width will be returned.",
- 'urlheight' => "Similar to {$p}urlwidth. Cannot be used without {$p}urlwidth"
+ 'urlheight' => "Similar to {$p}urlwidth. Cannot be used without {$p}urlwidth",
+ 'urlparam' => array( "Other rending parameters, such as page=2 for multipaged documents.",
+ "Multiple parameters should be seperated with a |. {$p}urlwidth must also be used" ),
);
}
return $ret;
}
- function getThumbUrl( $name, $width = -1, $height = -1, &$result = null ) {
+ function getThumbUrl( $name, $width = -1, $height = -1, &$result = null, $otherParams = '' ) {
$data = $this->fetchImageQuery( array(
'titles' => 'File:' . $name,
'iiprop' => 'url|timestamp',
'iiurlwidth' => $width,
'iiurlheight' => $height,
+ 'iiurlparam' => $otherParams,
'prop' => 'imageinfo' ) );
$info = $this->getImageInfo( $data );
* @param $name String is a dbkey form of a title
* @param $width
* @param $height
+ * @param String $param Other rendering parameters (page number, etc). | separated.
*/
- function getThumbUrlFromCache( $name, $width, $height ) {
+ function getThumbUrlFromCache( $name, $width, $height, $params="" ) {
global $wgMemc;
if ( !$this->canCacheThumbs() ) {
- return $this->getThumbUrl( $name, $width, $height );
+ return $this->getThumbUrl( $name, $width, $height, null, $params );
}
$key = $this->getLocalCacheKey( 'ForeignAPIRepo', 'ThumbUrl', $name );
- $sizekey = "$width:$height";
+ $sizekey = "$width:$height:$params";
/* Get the array of urls that we already know */
$knownThumbUrls = $wgMemc->get($key);
}
$metadata = null;
- $foreignUrl = $this->getThumbUrl( $name, $width, $height, $metadata );
+ $foreignUrl = $this->getThumbUrl( $name, $width, $height, $metadata, $params );
if( !$foreignUrl ) {
wfDebug( __METHOD__ . " Could not find thumburl\n" );
$diff = abs( $modified - $current );
if( $remoteModified < $modified && $diff < $this->fileCacheExpiry ) {
/* Use our current and already downloaded thumbnail */
- $knownThumbUrls["$width:$height"] = $localUrl;
+ $knownThumbUrls[$sizekey] = $localUrl;
$wgMemc->set( $key, $knownThumbUrls, $this->apiThumbCacheExpiry );
return $localUrl;
}