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
* @return Title
*/
public function getTitle() {
- if ( $this->context->getTitle() === null ) {
+ if ( !$this->context->hasTitle() ) {
$this->context->setTitle( $this->parseTitle() );
}
return $this->context->getTitle();
private $mAllPages = array(); // [ns][dbkey] => page_id or negative when missing
private $mTitles = array();
+ private $mGoodAndMissingPages = array(); // [ns][dbkey] => page_id or negative when missing
+ private $mGoodPages = array(); // [ns][dbkey] => page_id
private $mGoodTitles = array();
+ private $mMissingPages = array(); // [ns][dbkey] => fake page_id
private $mMissingTitles = array();
private $mInvalidTitles = array();
private $mMissingPageIDs = array();
return count( $this->mTitles );
}
+ /**
+ * Returns an array [ns][dbkey] => page_id for all good titles.
+ * @return array
+ */
+ public function getGoodTitlesByNamespace() {
+ return $this->mGoodPages;
+ }
+
/**
* Title objects that were found in the database.
* @return Title[] Array page_id (int) => Title (obj)
return count( $this->mGoodTitles );
}
+ /**
+ * Returns an array [ns][dbkey] => fake_page_id for all missing titles.
+ * fake_page_id is a unique negative number.
+ * @return array
+ */
+ public function getMissingTitlesByNamespace() {
+ return $this->mMissingPages;
+ }
+
/**
* Title objects that were NOT found in the database.
* The array's index will be negative for each item
return $this->mMissingTitles;
}
+ /**
+ * Returns an array [ns][dbkey] => page_id for all good and missing titles.
+ * @return array
+ */
+ public function getGoodAndMissingTitlesByNamespace() {
+ return $this->mGoodAndMissingPages;
+ }
+
+ /**
+ * Title objects for good and missing titles.
+ * @return array
+ */
+ public function getGoodAndMissingTitles() {
+ return $this->mGoodTitles + $this->mMissingTitles;
+ }
+
/**
* Titles that were deemed invalid by Title::newFromText()
* The array's index will be unique and negative for each item
if ( $this->mResolveRedirects && $row->page_is_redirect == '1' ) {
$this->mPendingRedirectIDs[$pageId] = $title;
} else {
+ $this->mGoodPages[$row->page_namespace][$row->page_title] = $pageId;
+ $this->mGoodAndMissingPages[$row->page_namespace][$row->page_title] = $pageId;
$this->mGoodTitles[$pageId] = $title;
}
foreach ( array_keys( $dbkeys ) as $dbkey ) {
$title = Title::makeTitle( $ns, $dbkey );
$this->mAllPages[$ns][$dbkey] = $this->mFakePageId;
+ $this->mMissingPages[$ns][$dbkey] = $this->mFakePageId;
+ $this->mGoodAndMissingPages[$ns][$dbkey] = $this->mFakePageId;
$this->mMissingTitles[$this->mFakePageId] = $title;
$this->mFakePageId--;
$this->mTitles[] = $title;
$emptyString = $db->addQuotes( '' );
$pageSet = $this->getPageSet();
- $titles = $pageSet->getGoodTitles() + $pageSet->getMissingTitles();
- $map = $pageSet->getAllTitlesByNamespace();
+ $titles = $pageSet->getGoodAndMissingTitles();
+ $map = $pageSet->getGoodAndMissingTitlesByNamespace();
// Determine our fields to query on
$p = $settings['prefix'];
public function execute() {
$params = $this->extractRequestParams();
- $alltitles = $this->getPageSet()->getAllTitlesByNamespace();
+ $alltitles = $this->getPageSet()->getGoodAndMissingTitlesByNamespace();
if ( empty( $alltitles[NS_CATEGORY] ) ) {
return;
}
$categories = $alltitles[NS_CATEGORY];
- $titles = $this->getPageSet()->getGoodTitles() +
- $this->getPageSet()->getMissingTitles();
+ $titles = $this->getPageSet()->getGoodAndMissingTitles();
$cattitles = array();
foreach ( $categories as $c ) {
/** @var $t Title */
*/
private function run( $resultPageSet = null ) {
$params = $this->extractRequestParams();
- $namespaces = $this->getPageSet()->getAllTitlesByNamespace();
+ $namespaces = $this->getPageSet()->getGoodAndMissingTitlesByNamespace();
if ( empty( $namespaces[NS_FILE] ) ) {
return;
}
'revdelUser' => $this->getUser(),
);
- $pageIds = $this->getPageSet()->getAllTitlesByNamespace();
+ $pageIds = $this->getPageSet()->getGoodAndMissingTitlesByNamespace();
if ( !empty( $pageIds[NS_FILE] ) ) {
$titles = array_keys( $pageIds[NS_FILE] );
asort( $titles ); // Ensure the order is always the same
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()
*/
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.
*
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.
*
/**
* Get special page names, as an associative array
- * case folded alias => real name
+ * canonical name => array of valid names, including aliases
* @return array
*/
function getSpecialPageAliases() {
"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"
}
"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"
}
);
}
+ 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.
*
'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)',