return false;
}
+ $trees = $this->extractTreesFromMetadata( $metadata );
+ $image->djvuTextTree = $trees['TextTree'];
+ $image->dejaMetaTree = $trees['MetaTree'];
+
+ if ( $gettext ) {
+ return $image->djvuTextTree;
+ } else {
+ return $image->dejaMetaTree;
+ }
+ }
+
+ /**
+ * Extracts metadata and text trees from metadata XML in string form
+ * @param string $metadata XML metadata as a string
+ * @return array
+ */
+ protected function extractTreesFromMetadata( $metadata ) {
MediaWiki\suppressWarnings();
try {
// Set to false rather than null to avoid further attempts
- $image->dejaMetaTree = false;
- $image->djvuTextTree = false;
+ $metaTree = false;
+ $textTree = false;
$tree = new SimpleXMLElement( $metadata, LIBXML_PARSEHUGE );
if ( $tree->getName() == 'mw-djvu' ) {
/** @var SimpleXMLElement $b */
if ( $b->getName() == 'DjVuTxt' ) {
// @todo File::djvuTextTree and File::dejaMetaTree are declared
// dynamically. Add a public File::$data to facilitate this?
- $image->djvuTextTree = $b;
+ $textTree = $b;
} elseif ( $b->getName() == 'DjVuXML' ) {
- $image->dejaMetaTree = $b;
+ $metaTree = $b;
}
}
} else {
- $image->dejaMetaTree = $tree;
+ $metaTree = $tree;
}
} catch ( Exception $e ) {
- wfDebug( "Bogus multipage XML metadata on '{$image->getName()}'\n" );
+ wfDebug( "Bogus multipage XML metadata\n" );
}
MediaWiki\restoreWarnings();
- if ( $gettext ) {
- return $image->djvuTextTree;
- } else {
- return $image->dejaMetaTree;
- }
+
+ return [ 'MetaTree' => $metaTree, 'TextTree' => $textTree ];
}
function getImageSize( $image, $path ) {
$cache::TTL_INDEFINITE,
function () use ( $file ) {
$tree = $this->getMetaTree( $file );
- if ( !$tree ) {
- return false;
- }
-
- $dimsByPage = [];
- $count = count( $tree->xpath( '//OBJECT' ) );
- for ( $i = 0; $i < $count; $i++ ) {
- $o = $tree->BODY[0]->OBJECT[$i];
- if ( $o ) {
- $dimsByPage[$i] = [
- 'width' => (int)$o['width'],
- 'height' => (int)$o['height'],
- ];
- } else {
- $dimsByPage[$i] = false;
- }
- }
-
- return [ 'pageCount' => $count, 'dimensionsByPage' => $dimsByPage ];
+ return $this->getDimensionInfoFromMetaTree( $tree );
},
[ 'pcTTL' => $cache::TTL_INDEFINITE ]
);
}
+ /**
+ * Given an XML metadata tree, returns dimension information about the document
+ * @param bool|SimpleXMLElement $metatree The file's XML metadata tree
+ * @return bool|array
+ */
+ protected function getDimensionInfoFromMetaTree( $metatree ) {
+ if ( !$metatree ) {
+ return false;
+ }
+
+ $dimsByPage = [];
+ $count = count( $metatree->xpath( '//OBJECT' ) );
+ for ( $i = 0; $i < $count; $i++ ) {
+ $o = $metatree->BODY[0]->OBJECT[$i];
+ if ( $o ) {
+ $dimsByPage[$i] = [
+ 'width' => (int)$o['width'],
+ 'height' => (int)$o['height'],
+ ];
+ } else {
+ $dimsByPage[$i] = false;
+ }
+ }
+
+ return [ 'pageCount' => $count, 'dimensionsByPage' => $dimsByPage ];
+ }
+
/**
* @param File $image
* @param int $page Page number to get information for
return false;
}
}
+
+ /**
+ * Get useful response headers for GET/HEAD requests for a file with the given metadata
+ * @param $metadata Array Contains this handler's unserialized getMetadata() for a file
+ * @return array
+ */
+ public function getContentHeaders( $metadata ) {
+ if ( !is_array( $metadata ) || !isset( $metadata['xml'] ) ) {
+ return [];
+ }
+
+ $trees = $this->extractTreesFromMetadata( $metadata['xml'] );
+ $dimensionInfo = $this->getDimensionInfoFromMetaTree( $trees['MetaTree'] );
+
+ if ( !$dimensionInfo ) {
+ return [];
+ }
+
+ $pagesByDimensions = [];
+ $count = $dimensionInfo['pageCount'];
+
+ for ( $i = 1; $i <= $count; $i++ ) {
+ $dimensions = $dimensionInfo['dimensionsByPage'][ $i - 1 ];
+ $dimensionString = $dimensions['width'] . 'x' . $dimensions['height'];
+
+ if ( isset ( $pagesByDimensions[ $dimensionString ] ) ) {
+ $pagesByDimensions[ $dimensionString ][] = $i;
+ } else {
+ $pagesByDimensions[ $dimensionString ] = [ $i ];
+ }
+ }
+
+ $pageRangesByDimensions = MediaHandler::getPageRangesByDimensions( $pagesByDimensions );
+
+ return [ 'X-Content-Dimensions' => $pageRangesByDimensions ];
+ }
}