Sophivorus has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/334050 )

Change subject: Requested fixes
......................................................................

Requested fixes

- Break code into smaller methods
- Add error handling
- Build <span> with Html::rawElement
- Short array syntax
- Add Parser typehint
- Remove extract()
- API requests to formatversion=2
- Add user agent to API requests
- Validate language codes
- Remove <WikipediaExtract> tag and duplicate code
- Declare public and private variables and methods
- Add wgWikipediaExtractsAddCredits config variable
- Add \n to EOF

Bug: T149766
Change-Id: I33d016e0ca0c2b7a68d8760c6835efb19ea713f2
---
M WikipediaExtracts.php
M extension.json
2 files changed, 199 insertions(+), 147 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/WikipediaExtracts 
refs/changes/50/334050/1

diff --git a/WikipediaExtracts.php b/WikipediaExtracts.php
index cdfa55a..bfc36b3 100644
--- a/WikipediaExtracts.php
+++ b/WikipediaExtracts.php
@@ -2,174 +2,222 @@
 
 class WikipediaExtracts {
 
-       static function onParserFirstCallInit( &$parser ) {
-               $parser->setHook( 'WikipediaExtract', 
'WikipediaExtracts::onHook' );
+       /**
+        * User agent for querying the API
+        */
+       private static $userAgent = 'User-Agent: 
Extension:WikipediaExtracts/2.0 
(https://www.mediawiki.org/wiki/Extension:WikipediaExtracts)';
+
+       /**
+        * Parser object
+        */
+       private static $parser;
+
+       /**
+        * Language code of the local wiki
+        */
+       public static $contentLanguage;
+
+       /**
+        * Associative array of the parameters passed to the parser function
+        */
+       private static $params;
+
+       /**
+        * Title of the Wikipedia article to extract
+        */
+       private static $wikipediaTitle;
+
+       /**
+        * Language code of the Wikipedia to query
+        */
+       private static $wikipediaLanguage;
+
+       /**
+        * Main hook
+        */
+       public static function onParserFirstCallInit( Parser &$parser ) {
                $parser->setFunctionHook( 'WikipediaExtract', 
'WikipediaExtracts::onFunctionHook' );
-               return true;
        }
 
-       static function onHook( $input, array $args, Parser $parser, PPFrame 
$frame ) {
-               // Set the defaults
-               $title = $parser->getTitle()->getRootText();
-               $language = $parser->getTargetLanguage()->getCode();
-               $chars = null;
-               $sentences = null;
-               $limit = null;
-               $intro = null;
-               $plaintext = null;
-               $sectionformat = null;
-               $continue = null;
-               $variant = null;
+       /**
+        * Parser function hook
+        */
+       public static function onFunctionHook( Parser $parser, $input = null ) {
+               try {
+                       self::$parser = $parser;
+                       self::$contentLanguage = $parser->getTargetLanguage();
+                       self::$params = self::parseParams( array_slice( 
func_get_args(), 2 ) );
+                       self::$wikipediaTitle = self::getWikipediaTitle( $input 
);
+                       self::$wikipediaLanguage = self::getWikipediaLanguage( 
$input );
 
-               // Override with user input
-               extract( $args );
-               if ( $input ) {
-                       if ( filter_var( $input, FILTER_VALIDATE_URL ) ) {
-                               // Extract the title
-                               $path = parse_url( $input, PHP_URL_PATH );
-                               $PATH = explode( '/', $path );
-                               $title = $PATH[2];
+                       $html = self::getExtract();
 
-                               // Extract the language
-                               $host = parse_url( $input, PHP_URL_HOST );
-                               $HOST = explode( '.', $host );
-                               $language = $HOST[0];
-                       } else {
-                               $title = $input;
+                       global $wgWikipediaExtractsAddCredits;
+                       if ( $wgWikipediaExtractsAddCredits ) {
+                               $html .= self::getCredits();
                        }
+               } catch ( WikipediaExtractsError $error ) {
+                       $html = $error->getHtmlMessage();
                }
-
-               // Validate language code
-               if ( !Language::isValidCode( $language ) ) {
-                       return '<span class="error">' . wfMessage( 
'wikipediaextracts-invalid-language', $language ) . '</span>';
-               }
-
-               // Query the Wikipedia API
-               $data = array(
-                       'action' => 'query',
-                       'titles' => urldecode( $title ),
-                       'prop' => 'extracts',
-                       'exchars' => $chars,
-                       'exsentences' => $sentences,
-                       'exlimit' => $limit,
-                       'exintro' => $intro,
-                       'explaintext' => $plaintext,
-                       'exsectionformat' => $sectionformat,
-                       'excontinue' => $continue,
-                       'exvariant' => $variant,
-                       'redirects' => true,
-                       'format' => 'json'
-               );
-               $query = 'https://' . $language . '.wikipedia.org/w/api.php?' . 
http_build_query( $data );
-               $contents = file_get_contents( $query );
-               $contents = json_decode( $contents );
-               $pages = $contents->query->pages;
-               foreach ( $pages as $key => $value ) {
-                       if ( $key === '-1' ) {
-                               return '<span class="error">' . wfMessage( 
'wikipediaextracts-404', $title ) . '</span>';
-                       }
-                       $extract = $value->extract;
-                       $url = 'https://' . $language . '.wikipedia.org/wiki/' 
. urlencode( $title );
-                       $extract .= wfMessage( 'wikipediaextracts-credits', 
$url )->parse();
-                       return $extract;
-               }
+               return $html;
        }
 
-       static function onFunctionHook( $parser, $input = null ) {
-               // Set the defaults
-               $title = $parser->getTitle()->getRootText();
-               $language = $parser->getTargetLanguage()->getCode();
-               $chars = null;
-               $sentences = null;
-               $limit = null;
-               $intro = null;
-               $plaintext = null;
-               $sectionformat = null;
-               $continue = null;
-               $variant = null;
-
-               // Override with user input
-               $options = WikipediaExtracts::extractOptions( array_slice( 
func_get_args(), 2 ) );
-               extract( $options );
+       /**
+        * Get the title of the Wikipedia article to extract
+        */
+       private static function getWikipediaTitle( $input ) {
                if ( $input ) {
                        if ( filter_var( $input, FILTER_VALIDATE_URL ) ) {
-                               // Extract the title
-                               $path = parse_url( $input, PHP_URL_PATH );
+                               $path = parse_url( $input, PHP_URL_PATH ); // 
Example path "/wiki/Article_title"
                                $PATH = explode( '/', $path );
-                               $title = $PATH[2];
-
-                               // Extract the language
-                               $host = parse_url( $input, PHP_URL_HOST );
-                               $HOST = explode( '.', $host );
-                               $language = $HOST[0];
+                               $wikipediaTitle = urldecode( $PATH[2] );
                        } else {
-                               $title = $input;
+                               $wikipediaTitle = $input;
+                       }
+               } else {
+                       $wikipediaTitle = self::getParam( 'title', 
self::$parser->getTitle()->getRootText() );
+               }
+               return $wikipediaTitle;
+       }
+
+       /**
+        * Get the language code of the Wikipedia to query
+        */
+       private static function getWikipediaLanguage( $input ) {
+               if ( $input and filter_var( $input, FILTER_VALIDATE_URL ) ) {
+                       $host = parse_url( $input, PHP_URL_HOST ); // Example 
host "en.wikipedia.org"
+                       $HOST = explode( '.', $host );
+                       $wikipediaLanguage = $HOST[0];
+               } else {
+                       $wikipediaLanguage = self::getParam( 'language', 
self::$contentLanguage->getCode() );
+               }
+               if ( !Language::isValidCode( $wikipediaLanguage ) ) {
+                       throw new WikipediaExtractsError( 'invalid-language', 
$wikipediaLanguage );
+               }
+               return $wikipediaLanguage;
+       }
+
+       /**
+        * Get a param value out of the $params array
+        *
+        * @param string $key of the param
+        * @param string $default if no value is found
+        * @return string param value
+        */
+       private static function getParam( $key, $default = null ) {
+               if ( array_key_exists( $key, self::$params ) ) {
+                       return self::$params[ $key ];
+               }
+               return $default;
+       }
+
+       /**
+        * Convert an array of values in form [0] => "name=value"
+        * into a real associative array in form [name] => value.
+        * If no = is provided, true is assumed like this: [name] => true
+        *
+        * @param array string $params
+        * @return array $params
+        */
+       private static function parseParams( $params ) {
+               $array = [];
+               foreach ( $params as $param ) {
+                       $pair = explode( '=', $param, 2 );
+                       if ( count( $pair ) === 2 ) {
+                               $name = trim( $pair[0] );
+                               $value = trim( $pair[1] );
+                               $array[ $name ] = $value;
+                       } else if ( count( $pair ) === 1 ) {
+                               $name = trim( $pair[0] );
+                               $array[ $name ] = true;
                        }
                }
+               return $array;
+       }
 
-               // Validate language code
-               if ( !Language::isValidCode( $language ) ) {
-                       return '<span class="error">' . wfMessage( 
'wikipediaextracts-invalid-language', $language ) . '</span>';
-               }
-
-               // Query the Wikipedia API
-               $data = array(
+       /**
+        * Build the query to Wikipedia and get the extract
+        */
+       private static function getExtract() {
+               $data = [
                        'action' => 'query',
-                       'titles' => urldecode( $title ),
+                       'titles' => self::$wikipediaTitle,
                        'prop' => 'extracts',
-                       'exchars' => $chars,
-                       'exsentences' => $sentences,
-                       'exlimit' => $limit,
-                       'exintro' => $intro,
-                       'explaintext' => $plaintext,
-                       'exsectionformat' => $sectionformat,
-                       'excontinue' => $continue,
-                       'exvariant' => $variant,
+                       'exchars' => self::getParam( 'chars' ),
+                       'exsentences' => self::getParam( 'sentences' ),
+                       'exlimit' => self::getParam( 'limit' ),
+                       'exintro' => self::getParam( 'intro' ),
+                       'explaintext' => self::getParam( 'plaintext' ),
+                       'exsectionformat' => self::getParam( 'sectionformat' ),
+                       'excontinue' => self::getParam( 'continue' ),
+                       'exvariant' => self::getParam( 'variant' ),
                        'redirects' => true,
-                       'format' => 'json'
-               );
-               $query = 'https://' . $language . '.wikipedia.org/w/api.php?' . 
http_build_query( $data );
-               $contents = file_get_contents( $query );
-               $contents = json_decode( $contents );
-               $pages = $contents->query->pages;
-               foreach ( $pages as $key => $value ) {
-                       if ( $key === '-1' ) {
-                               return '<span class="error">' . wfMessage( 
'wikipediaextracts-404', $title ) . '</span>';
+                       'format' => 'json',
+                       'formatversion' => 2
+               ];
+               $query = 'https://' . self::$wikipediaLanguage . 
'.wikipedia.org/w/api.php?' . http_build_query( $data );
+               $request = MWHttpRequest::factory( $query );
+               $request->setUserAgent( self::$userAgent );
+               $status = $request->execute();
+               if ( !$status->isOK() ) {
+                       if ( $status->getValue() === 100 ) {
+                               throw new WikipediaExtractsError( 
'invalid-language', self::$wikipediaLanguage );
                        }
-                       $extract = $value->extract;
-                       $url = 'https://' . $language . '.wikipedia.org/wiki/' 
. urlencode( $title );
-                       $extract .= wfMessage( 'wikipediaextracts-credits', 
$url )->plain();
-                       return $extract;
+                       throw new WikipediaExtractsError( 'error' );
+               }
+               $content = FormatJson::decode( $request->getContent() );
+               if ( !$content ) {
+                       throw new WikipediaExtractsError( 'error' );
+               }
+               if ( array_key_exists( 'error-codes', $content ) ) {
+                       throw new WikipediaExtractsError( 'error' );
+               }
+               foreach ( $content->query->pages as $page ) {
+                       if ( property_exists( $page, 'missing' ) ) {
+                               throw new WikipediaExtractsError( '404', 
self::$wikipediaTitle );
+                       }
+                       return $page->extract;
                }
        }
 
        /**
-        * Converts an array of values in form [0] => "name=value" into a real
-        * associative array in form [name] => value. If no = is provided,
-        * true is assumed like this: [name] => true
-        *
-        * @param array string $options
-        * @return array $results
+        * Get a span with a link to Wikipedia
         */
-       static function extractOptions( $options ) {
-               $results = array();
-
-               foreach ( $options as $option ) {
-                       $pair = explode( '=', $option, 2 );
-                       if ( count( $pair ) === 2 ) {
-                               $name = trim( $pair[0] );
-                               $value = trim( $pair[1] );
-                               $results[ $name ] = $value;
-                       }
-                       if ( count( $pair ) === 1 ) {
-                               $name = trim( $pair[0] );
-                               $results[ $name ] = true;
-                       }
-               }
-               // Now you've got an array that looks like this:
-               // [foo] => "bar"
-               // [apple] => "orange"
-               // [banana] => true
-               return $results;
+       private static function getCredits() {
+               $title = Title::newFromText( self::$wikipediaTitle );
+               $url = 'https://' . self::$wikipediaLanguage . 
'.wikipedia.org/wiki/' . $title->getPartialUrl();
+               return Html::rawElement(
+                       'small', [
+                               'lang' => self::$contentLanguage->getHtmlCode(),
+                               'dir' => self::$contentLanguage->getDir()
+                       ],
+                       wfMessage( 'wikipediaextracts-credits', $url )->plain()
+               );
        }
-}
\ No newline at end of file
+}
+
+/**
+ * Error handler
+ */
+class WikipediaExtractsError extends Exception {
+
+       public $messageKey;
+
+       public $messageParam;
+
+       public function __construct( $messageKey, $messageParam = null ) {
+               $this->messageKey = $messageKey;
+               $this->messageParam = $messageParam;
+       }
+
+       public function getHtmlMessage() {
+               return Html::rawElement(
+                       'span', [
+                               'class' => 'error mw-ext-cite-error',
+                               'lang' => 
WikipediaExtracts::$contentLanguage->getHtmlCode(),
+                               'dir' => 
WikipediaExtracts::$contentLanguage->getDir()
+                       ],
+                       wfMessage( 'wikipediaextracts-' . $this->messageKey, 
$this->messageParam )
+               );
+       }
+}
diff --git a/extension.json b/extension.json
index 4ba8bdc..dc85cee 100644
--- a/extension.json
+++ b/extension.json
@@ -1,6 +1,6 @@
 {
        "name": "WikipediaExtracts",
-       "version": "1.3",
+       "version": "2.0",
        "author": "[http://mediawiki.org/wiki/User:Felipe_Schenone Felipe 
Schenone]",
        "url": "https://www.mediawiki.org/wiki/Extension:WikipediaExtracts";,
        "descriptionmsg": "wikipediaextracts-desc",
@@ -14,10 +14,14 @@
                "WikipediaExtractsAlias": "WikipediaExtracts.magic.php"
        },
        "AutoloadClasses": {
-               "WikipediaExtracts": "WikipediaExtracts.php"
+               "WikipediaExtracts": "WikipediaExtracts.php",
+               "WikipediaExtractsError": "WikipediaExtracts.php"
        },
        "Hooks": {
                "ParserFirstCallInit": 
"WikipediaExtracts::onParserFirstCallInit"
        },
+       "config": {
+               "WikipediaExtractsAddCredits": true
+       },
        "manifest_version": 1
 }

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I33d016e0ca0c2b7a68d8760c6835efb19ea713f2
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/WikipediaExtracts
Gerrit-Branch: master
Gerrit-Owner: Sophivorus <scheno...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to