Merge "API: Add ApiPageSet accessors for just good and missing titles"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 26 Sep 2014 19:26:54 +0000 (19:26 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 26 Sep 2014 19:26:54 +0000 (19:26 +0000)
COPYING
includes/MediaWiki.php
includes/context/RequestContext.php
includes/json/FormatJson.php
languages/i18n/en.json
languages/i18n/qqq.json
tests/phpunit/includes/json/FormatJsonTest.php
tests/qunit/suites/resources/startup.test.js

diff --git a/COPYING b/COPYING
index c3bed28..1cdc9d4 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -30,8 +30,10 @@ under the GPL for use of the whole code or other sections thereof.
 MediaWiki uses the following Creative Commons icons to illustrate links to the
 CC licenses:
 
-* skins/common/images/cc-by-nc-sa.png
-* skins/common/images/cc-by-sa.png
+* resources/assets/licenses/cc-0.png
+* resources/assets/licenses/cc-by-nc-sa.png
+* resources/assets/licenses/cc-by-sa.png
+* resources/assets/licenses/cc-by.png
 
 These icons are trademarked, and used subject to the CC trademark license,
 available at http://creativecommons.org/policies#trademark
index 545a46f..87468bd 100644 (file)
@@ -121,7 +121,7 @@ class MediaWiki {
         * @return Title
         */
        public function getTitle() {
-               if ( $this->context->getTitle() === null ) {
+               if ( !$this->context->hasTitle() ) {
                        $this->context->setTitle( $this->parseTitle() );
                }
                return $this->context->getTitle();
index 952af8c..b1bebe7 100644 (file)
@@ -146,6 +146,16 @@ class RequestContext implements IContextSource {
                return $this->title;
        }
 
+       /**
+        * Check, if a Title object is set
+        *
+        * @since 1.25
+        * @return bool
+        */
+       public function hasTitle() {
+               return $this->title !== null;
+       }
+
        /**
         * Check whether a WikiPage object can be get with getWikiPage().
         * Callers should expect that an exception is thrown from getWikiPage()
index e45dd3a..5565644 100644 (file)
@@ -54,6 +54,15 @@ class FormatJson {
         */
        const ALL_OK = 3;
 
+       /**
+        * If set, treat json objects '{...}' as associative arrays. Without this option,
+        * json objects will be converted to stdClass.
+        * The value is set to 1 to be backward compatible with 'true' that was used before.
+        *
+        * @since 1.24
+        */
+       const FORCE_ASSOC = 1;
+
        /**
         * Regex that matches whitespace inside empty arrays and objects.
         *
@@ -127,6 +136,52 @@ class FormatJson {
                return json_decode( $value, $assoc );
        }
 
+       /**
+        * Decodes a JSON string.
+        *
+        * @param string $value The JSON string being decoded
+        * @param int $options A bit field that allows FORCE_ASSOC, TRY_FIXING, WRAP_RESULT
+        * For backward compatibility, FORCE_ASSOC is set to 1 to match the legacy 'true'
+        * @return Status If good, the value is available in $result->getValue()
+        */
+       public static function parse( $value, $options = 0 ) {
+               $assoc = ( $options & self::FORCE_ASSOC ) !== 0;
+               $result = json_decode( $value, $assoc );
+               $code = json_last_error();
+
+               switch ( $code ) {
+                       case JSON_ERROR_NONE:
+                               return Status::newGood( $result );
+                       default:
+                               return Status::newFatal( wfMessage( 'json-error-unknown' )->numParams( $code ) );
+                       case JSON_ERROR_DEPTH:
+                               $msg = 'json-error-depth';
+                               break;
+                       case JSON_ERROR_STATE_MISMATCH:
+                               $msg = 'json-error-state-mismatch';
+                               break;
+                       case JSON_ERROR_CTRL_CHAR:
+                               $msg = 'json-error-ctrl-char';
+                               break;
+                       case JSON_ERROR_SYNTAX:
+                               $msg = 'json-error-syntax';
+                               break;
+                       case JSON_ERROR_UTF8:
+                               $msg = 'json-error-utf8';
+                               break;
+                       case JSON_ERROR_RECURSION:
+                               $msg = 'json-error-recursion';
+                               break;
+                       case JSON_ERROR_INF_OR_NAN:
+                               $msg = 'json-error-inf-or-nan';
+                               break;
+                       case JSON_ERROR_UNSUPPORTED_TYPE:
+                               $msg = 'json-error-unsupported-type';
+                               break;
+               }
+               return Status::newFatal( $msg );
+       }
+
        /**
         * JSON encoder wrapper for PHP >= 5.4, which supports useful encoding options.
         *
index 12d1429..e8a5c3c 100644 (file)
        "mediastatistics-header-office": "Office",
        "mediastatistics-header-text": "Textual",
        "mediastatistics-header-executable": "Executables",
-       "mediastatistics-header-archive": "Compressed formats"
+       "mediastatistics-header-archive": "Compressed formats",
+       "json-error-unknown": "There was a problem with the JSON. Error: $1",
+       "json-error-depth": "The maximum stack depth has been exceeded",
+       "json-error-state-mismatch": "Invalid or malformed JSON",
+       "json-error-ctrl-char": "Control character error, possibly incorrectly encoded",
+       "json-error-syntax": "Syntax error",
+       "json-error-utf8": "Malformed UTF-8 characters, possibly incorrectly encoded",
+       "json-error-recursion": "One or more recursive references in the value to be encoded",
+       "json-error-inf-or-nan": "One or more NAN or INF values in the value to be encoded",
+       "json-error-unsupported-type": "A value of a type that cannot be encoded was given"
 }
index d480e2d..2049ae5 100644 (file)
        "mediastatistics-header-office": "Header on [[Special:MediaStatistics]] for file types that are in the Office category. This includes PDFs, OpenDocument files, Microsoft Word files, etc.",
        "mediastatistics-header-text": "Header on [[Special:MediaStatistics]] for file types that are in the text category. This includes simple text formats, including plain text formats, json, csv, and xml. Source code of compiled programming languages may be included here in the future, but isn't currently.",
        "mediastatistics-header-executable": "Header on [[Special:MediaStatistics]] for file types that are in the executable category. This includes things like source files for interpreted programming language (Shell scripts, javascript, etc).",
-       "mediastatistics-header-archive": "Header on [[Special:MediaStatistics]] for file types that are in the archive category. Includes things like tar, zip, gzip etc."
+       "mediastatistics-header-archive": "Header on [[Special:MediaStatistics]] for file types that are in the archive category. Includes things like tar, zip, gzip etc.",
+       "json-error-unknown": "User error message when there’s an unknown error.\n{{Identical|Unknown error}}. This error is shown if we received an unexpected value from PHP. See http://php.net/manual/en/function.json-last-error.php\n\nParameters:\n* $1 - integer error code",
+       "json-error-depth": "User error message when the maximum stack depth is exceeded.\nSee http://php.net/manual/en/function.json-last-error.php",
+       "json-error-state-mismatch": "User error message when underflow or the modes mismatch.\n\n'''Underflow''': A data-processing error arising when the absolute value of a computed quantity is smaller than the limits of precision of the computing device, retaining at least one significant digit.\nSee http://php.net/manual/en/function.json-last-error.php",
+       "json-error-ctrl-char": "User error message when an unexpected control character has been found.\nSee http://php.net/manual/en/function.json-last-error.php",
+       "json-error-syntax": "User error message when there is a syntax error; a malformed JSON.\nSee http://php.net/manual/en/function.json-last-error.php",
+       "json-error-utf8": "User error message when there are malformed UTF-8 characters, possibly incorrectly encoded.\nSee http://php.net/manual/en/function.json-last-error.php",
+       "json-error-recursion": "PHP JSON encoding/decoding error. See http://php.net/manual/en/function.json-last-error.php",
+       "json-error-inf-or-nan": "PHP JSON encoding/decoding error. See http://php.net/manual/en/function.json-last-error.php",
+       "json-error-unsupported-type": "PHP JSON encoding/decoding error. See http://php.net/manual/en/function.json-last-error.php"
 }
index bf58ee3..0f1cdf7 100644 (file)
@@ -123,6 +123,69 @@ class FormatJsonTest extends MediaWikiTestCase {
                );
        }
 
+       public static function provideParse() {
+               return array(
+                       array( null ),
+                       array( true ),
+                       array( false ),
+                       array( 0 ),
+                       array( 1 ),
+                       array( 1.2 ),
+                       array( '' ),
+                       array( 'str' ),
+                       array( array( 0, 1, 2 ) ),
+                       array( array( 'a' => 'b' ) ),
+                       array( array( 'a' => 'b' ) ),
+                       array( array( 'a' => 'b', 'x' => array( 'c' => 'd' ) ) ),
+               );
+       }
+
+       /**
+        * Recursively convert arrays into stdClass
+        * @param array|string|bool|int|float|null $value
+        * @return stdClass|string|bool|int|float|null
+        */
+       public static function toObject( $value ) {
+               return !is_array( $value ) ? $value : (object) array_map( __METHOD__, $value );
+       }
+
+       /**
+        * @dataProvider provideParse
+        * @param mixed $value
+        */
+       public function testParse( $value ) {
+               $expected = self::toObject( $value );
+               $json = FormatJson::encode( $expected, false, FormatJson::ALL_OK );
+               $this->assertJson( $json );
+
+               $st = FormatJson::parse( $json );
+               $this->assertType( 'Status', $st );
+               $this->assertTrue( $st->isGood() );
+               $this->assertEquals( $expected, $st->getValue() );
+
+               $st = FormatJson::parse( $json, FormatJson::FORCE_ASSOC );
+               $this->assertType( 'Status', $st );
+               $this->assertTrue( $st->isGood() );
+               $this->assertEquals( $value, $st->getValue() );
+       }
+
+       public static function provideParseErrors() {
+               return array(
+                       array( 'aaa' ),
+                       array( '{"j": 1 ] }' ),
+               );
+       }
+
+       /**
+        * @dataProvider provideParseErrors
+        * @param mixed $value
+        */
+       public function testParseErrors( $value ) {
+               $st = FormatJson::parse( $value );
+               $this->assertType( 'Status', $st );
+               $this->assertFalse( $st->isOK() );
+       }
+
        /**
         * Generate a set of test cases for a particular combination of encoder options.
         *
index ed03418..6011961 100644 (file)
@@ -96,6 +96,7 @@
                        'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.7) Gecko/20060928 (Debian|Debian-1.8.0.7-1) Epiphany/2.14',
                        'Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.8.1.6) Gecko/20070817 IceWeasel/2.0.0.6-g2',
                        // KHTML
+                       'Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.4 (like Gecko)',
                        'Mozilla/5.0 (compatible; Konqueror/4.3; Linux) KHTML/4.3.5 (like Gecko)',
                        // Text browsers
                        'Links (2.1pre33; Darwin 8.11.0 Power Macintosh; x)',