jenkins-bot has submitted this change and it was merged.

Change subject: Add language handling to imageinfo/extmetadata API
......................................................................


Add language handling to imageinfo/extmetadata API

Adds options to return metadata in all available languages, or in
a single selected language.

Change-Id: I78f096318904a08abd317a5ed3f74ee33d3289cb
---
M docs/hooks.txt
M includes/api/ApiQueryImageInfo.php
M includes/filerepo/file/ForeignAPIFile.php
M includes/media/FormatMetadata.php
4 files changed, 135 insertions(+), 14 deletions(-)

Approvals:
  Anomie: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/docs/hooks.txt b/docs/hooks.txt
index d18679b..3f88bf5 100644
--- a/docs/hooks.txt
+++ b/docs/hooks.txt
@@ -1162,6 +1162,9 @@
 'value' => prop value, 'source' => 'name of hook' ).
 $file: File object of file in question
 $context: RequestContext (including language to use)
+$single: Only extract the current language; if false, the prop value should
+be in the metadata multi-language array format:
+mediawiki.org/wiki/Manual:File_metadata_handling#Multi-language_array_format
 &$maxCacheTime: how long the results can be cached
 
 'GetFullURL': Modify fully-qualified URLs used in redirects/export/offsite 
data.
diff --git a/includes/api/ApiQueryImageInfo.php 
b/includes/api/ApiQueryImageInfo.php
index 1e80f57..81c9faf 100755
--- a/includes/api/ApiQueryImageInfo.php
+++ b/includes/api/ApiQueryImageInfo.php
@@ -51,6 +51,8 @@
 
                $metadataOpts = array(
                        'version' => $params['metadataversion'],
+                       'language' => $params['extmetadatalanguage'],
+                       'multilang' => $params['extmetadatamultilang'],
                );
 
                $pageIds = $this->getPageSet()->getAllTitlesByNamespace();
@@ -305,12 +307,18 @@
         * @param string|array $metadataOpts Options for metadata fetching.
         *   This is an array consisting of the keys:
         *    'version': The metadata version for the metadata option
+        *    'language': The language for extmetadata property
+        *    'multilang': Return all translations in extmetadata property
         * @return Array: result array
         */
        static function getInfo( $file, $prop, $result, $thumbParams = null, 
$metadataOpts = false ) {
+               global $wgContLang;
+
                if ( !$metadataOpts || is_string( $metadataOpts ) ) {
                        $metadataOpts = array(
                                'version' => $metadataOpts ?: 'latest',
+                               'language' => $wgContLang,
+                               'multilang' => false,
                        );
                }
                $version = $metadataOpts['version'];
@@ -437,6 +445,8 @@
                        // start with a letter, and all the values are strings.
                        // Thus there should be no issue with format=xml.
                        $format = new FormatMetadata;
+                       $format->setSingleLanguage( !$metadataOpts['multilang'] 
);
+                       $format->getContext()->setLanguage( 
$metadataOpts['language'] );
                        $extmetaArray = $format->fetchExtendedMetadata( $file );
                        $vals['extmetadata'] = $extmetaArray;
                }
@@ -515,6 +525,7 @@
        }
 
        public function getAllowedParams() {
+               global $wgContLang;
                return array(
                        'prop' => array(
                                ApiBase::PARAM_ISMULTI => true,
@@ -545,6 +556,14 @@
                        'metadataversion' => array(
                                ApiBase::PARAM_TYPE => 'string',
                                ApiBase::PARAM_DFLT => '1',
+                       ),
+                       'extmetadatalanguage' => array(
+                               ApiBase::PARAM_TYPE => 'string',
+                               ApiBase::PARAM_DFLT => $wgContLang->getCode(),
+                       ),
+                       'extmetadatamultilang' => array(
+                               ApiBase::PARAM_TYPE => 'boolean',
+                               ApiBase::PARAM_DFLT => false,
                        ),
                        'urlparam' => array(
                                ApiBase::PARAM_DFLT => '',
@@ -628,6 +647,10 @@
                        'end' => 'Timestamp to stop listing at',
                        'metadataversion' => array( "Version of metadata to 
use. if 'latest' is specified, use latest version.",
                                                "Defaults to '1' for backwards 
compatibility" ),
+                       'extmetadatalanguage' => array( 'What language to fetch 
extmetadata in. This affects both which',
+                                               'translation to fetch, if 
multiple are available, as well as how things',
+                                               'like numbers and various 
values are formatted.' ),
+                       'extmetadatamultilang' => 'If translations for 
extmetadata property are available, fetch all of them.',
                        'continue' => 'If the query response includes a 
continue value, use it here to get another page of results',
                        'localonly' => 'Look only for files in the local 
repository',
                );
diff --git a/includes/filerepo/file/ForeignAPIFile.php 
b/includes/filerepo/file/ForeignAPIFile.php
index fc9e176..0b3d5df 100755
--- a/includes/filerepo/file/ForeignAPIFile.php
+++ b/includes/filerepo/file/ForeignAPIFile.php
@@ -57,7 +57,10 @@
                        'titles' => 'File:' . $title->getDBkey(),
                        'iiprop' => self::getProps(),
                        'prop' => 'imageinfo',
-                       'iimetadataversion' => 
MediaHandler::getMetadataVersion()
+                       'iimetadataversion' => 
MediaHandler::getMetadataVersion(),
+                       // extmetadata is language-dependant, accessing the 
current language here
+                       // would be problematic, so we just get them all
+                       'iiextmetadatamultilang' => 1,
                ) );
 
                $info = $repo->getImageInfo( $data );
diff --git a/includes/media/FormatMetadata.php 
b/includes/media/FormatMetadata.php
index 17de74a..b34ad65 100755
--- a/includes/media/FormatMetadata.php
+++ b/includes/media/FormatMetadata.php
@@ -48,6 +48,23 @@
 class FormatMetadata extends ContextSource {
 
        /**
+        * Only output a single language for multi-language fields
+        * @var boolean
+        * @since 1.23
+        */
+       protected $singleLang = false;
+
+       /**
+        * Trigger only outputting single language for multilanguage fields
+        *
+        * @param Boolean $val
+        * @since 1.23
+        */
+       public function setSingleLanguage( $val ) {
+               $this->singleLang = $val;
+       }
+
+       /**
         * Numbers given by Exif user agents are often magical, that is they
         * should be replaced by a detailed explanation depending on their
         * value which most of the time are plain integers. This function
@@ -935,7 +952,6 @@
                 * languages, we don't want to show them all by default
                 */
                else {
-                       global $wgContLang;
                        switch ( $type ) {
                        case 'lang':
                                // Display default, followed by ContLang,
@@ -946,7 +962,7 @@
 
                                $content = '';
 
-                               $cLang = $wgContLang->getCode();
+                               $priorityLanguages = 
$this->getPriorityLanguages();
                                $defaultItem = false;
                                $defaultLang = false;
 
@@ -961,18 +977,24 @@
                                        $defaultItem = $vals['x-default'];
                                        unset( $vals['x-default'] );
                                }
-                               // Do contentLanguage.
-                               if ( isset( $vals[$cLang] ) ) {
-                                       $isDefault = false;
-                                       if ( $vals[$cLang] === $defaultItem ) {
-                                               $defaultItem = false;
-                                               $isDefault = true;
-                                       }
-                                       $content .= $this->langItem(
-                                               $vals[$cLang], $cLang,
-                                               $isDefault, $noHtml );
+                               foreach( $priorityLanguages as $pLang ) {
+                                       if ( isset( $vals[$pLang] ) ) {
+                                               $isDefault = false;
+                                               if ( $vals[$pLang] === 
$defaultItem ) {
+                                                       $defaultItem = false;
+                                                       $isDefault = true;
+                                               }
+                                               $content .= $this->langItem(
+                                                       $vals[$pLang], $pLang,
+                                                       $isDefault, $noHtml );
 
-                                       unset( $vals[$cLang] );
+                                               unset( $vals[$pLang] );
+
+                                               if ( $this->singleLang ) {
+                                                       return 
Html::rawElement( 'span',
+                                                               array( 'lang' 
=> $pLang ), $vals[$pLang] );
+                                               }
+                                       }
                                }
 
                                // Now do the rest.
@@ -983,11 +1005,18 @@
                                        }
                                        $content .= $this->langItem( $item,
                                                $lang, false, $noHtml );
+                                       if ( $this->singleLang ) {
+                                               return Html::rawElement( 'span',
+                                                       array( 'lang' => $lang 
), $item );
+                                       }
                                }
                                if ( $defaultItem !== false ) {
                                        $content = $this->langItem( 
$defaultItem,
                                                $defaultLang, true, $noHtml ) .
                                                $content;
+                                       if ( $this->singleLang ) {
+                                               return $defaultItem;
+                                       }
                                }
                                if ( $noHtml ) {
                                        return $content;
@@ -1456,6 +1485,7 @@
                $cacheKey = wfMemcKey(
                        'getExtendedMetadata',
                        $this->getLanguage()->getCode(),
+                       (int) $this->singleLang,
                        $file->getSha1()
                );
 
@@ -1469,6 +1499,9 @@
                        $maxCacheTime = ( $file instanceof ForeignAPIFile ) ? 
60 * 60 * 12 : 60 * 60 * 24 * 30;
                        $fileMetadata = $this->getExtendedMetadataFromFile( 
$file );
                        $extendedMetadata = $this->getExtendedMetadataFromHook( 
$file, $fileMetadata, $maxCacheTime );
+                       if ( $this->singleLang ) {
+                               $this->resolveMultilangMetadata( 
$extendedMetadata );
+                       }
                        // Make sure the metadata won't break the API when an 
XML format is used.
                        // This is an API-specific function so it would be 
cleaner to call it from
                        // outside fetchExtendedMetadata, but this way we don't 
need to redo the
@@ -1558,6 +1591,7 @@
                        &$extendedMetadata,
                        $file,
                        $this->getContext(),
+                       $this->singleLang,
                        &$maxCacheTime
                ) );
 
@@ -1573,6 +1607,64 @@
        }
 
        /**
+        * Turns an XMP-style multilang array into a single value.
+        * If the value is not a multilang array, it is returned unchanged.
+        * See 
mediawiki.org/wiki/Manual:File_metadata_handling#Multi-language_array_format
+        * @param mixed $value
+        * @return mixed value in best language, null if there were no 
languages at all
+        * @since 1.23
+        */
+       protected function resolveMultilangValue( $value )
+       {
+               if (
+                       !is_array( $value )
+                       || !isset( $value['_type'] )
+                       || $value['_type'] != 'lang'
+               ) {
+                       return $value; // do nothing if not a multilang array
+               }
+
+               // choose the language best matching user or site settings
+               $priorityLanguages = $this->getPriorityLanguages();
+               foreach( $priorityLanguages as $lang ) {
+                       if ( isset( $value[$lang] ) ) {
+                               return $value[$lang];
+                       }
+               }
+
+               // otherwise go with the default language, if set
+               if ( isset( $value['x-default'] ) ) {
+                       return $value['x-default'];
+               }
+
+               // otherwise just return any one language
+               unset($value['_type']);
+               if (!empty($value)) {
+                       return reset($value);
+               }
+
+               // this should not happen; signal error
+               return null;
+       }
+
+       /**
+        * Takes an array returned by the getExtendedMetadata* functions,
+        * and resolves multi-language values in it.
+        * @param array $metadata
+        * @since 1.23
+        */
+       protected function resolveMultilangMetadata( &$metadata ) {
+               if ( !is_array( $metadata ) ) {
+                       return;
+               }
+               foreach ( $metadata as &$field ) {
+                       if ( isset( $field['value'] ) ) {
+                               $field['value'] = $this->resolveMultilangValue( 
$field['value'] );
+                       }
+               }
+       }
+
+       /**
         * Makes sure the given array is a valid API response fragment
         * (can be transformed into XML)
         * @param array $arr

-- 
To view, visit https://gerrit.wikimedia.org/r/92532
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I78f096318904a08abd317a5ed3f74ee33d3289cb
Gerrit-PatchSet: 4
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: GergÅ‘ Tisza <[email protected]>
Gerrit-Reviewer: Anomie <[email protected]>
Gerrit-Reviewer: GergÅ‘ Tisza <[email protected]>
Gerrit-Reviewer: MarkTraceur <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to