From 63601400e476c6cf43d985f3e7b9864681695ed4 Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Fri, 18 Jan 2013 16:46:04 +0100 Subject: Update to MediaWiki 1.20.2 this update includes: * adjusted Arch Linux skin * updated FluxBBAuthPlugin * patch for https://bugzilla.wikimedia.org/show_bug.cgi?id=44024 --- includes/api/ApiQueryInfo.php | 259 +++++++++++++++++++++++++++++------------- 1 file changed, 179 insertions(+), 80 deletions(-) (limited to 'includes/api/ApiQueryInfo.php') diff --git a/includes/api/ApiQueryInfo.php b/includes/api/ApiQueryInfo.php index f0d0faa3..5d4f0346 100644 --- a/includes/api/ApiQueryInfo.php +++ b/includes/api/ApiQueryInfo.php @@ -4,7 +4,7 @@ * * Created on Sep 25, 2006 * - * Copyright © 2006 Yuri Astrakhan @gmail.com + * Copyright © 2006 Yuri Astrakhan "@gmail.com" * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,7 +33,7 @@ class ApiQueryInfo extends ApiQueryBase { private $fld_protection = false, $fld_talkid = false, $fld_subjectid = false, $fld_url = false, - $fld_readable = false, $fld_watched = false, + $fld_readable = false, $fld_watched = false, $fld_notificationtimestamp = false, $fld_preload = false, $fld_displaytitle = false; private $params, $titles, $missing, $everything, $pageCounter; @@ -41,7 +41,7 @@ class ApiQueryInfo extends ApiQueryBase { private $pageRestrictions, $pageIsRedir, $pageIsNew, $pageTouched, $pageLatest, $pageLength; - private $protections, $watched, $talkids, $subjectids, $displaytitles; + private $protections, $watched, $notificationtimestamps, $talkids, $subjectids, $displaytitles; private $tokenFunctions; @@ -57,7 +57,10 @@ class ApiQueryInfo extends ApiQueryBase { global $wgDisableCounters; $pageSet->requestField( 'page_restrictions' ); - $pageSet->requestField( 'page_is_redirect' ); + // when resolving redirects, no page will have this field + if( !$pageSet->isResolvingRedirects() ) { + $pageSet->requestField( 'page_is_redirect' ); + } $pageSet->requestField( 'page_is_new' ); if ( !$wgDisableCounters ) { $pageSet->requestField( 'page_counter' ); @@ -99,6 +102,12 @@ class ApiQueryInfo extends ApiQueryBase { return $this->tokenFunctions; } + static $cachedTokens = array(); + + public static function resetTokenCache() { + ApiQueryInfo::$cachedTokens = array(); + } + public static function getEditToken( $pageid, $title ) { // We could check for $title->userCan('edit') here, // but that's too expensive for this purpose @@ -108,14 +117,12 @@ class ApiQueryInfo extends ApiQueryBase { return false; } - // The edit token is always the same, let's exploit that - static $cachedEditToken = null; - if ( !is_null( $cachedEditToken ) ) { - return $cachedEditToken; + // The token is always the same, let's exploit that + if ( !isset( ApiQueryInfo::$cachedTokens[ 'edit' ] ) ) { + ApiQueryInfo::$cachedTokens[ 'edit' ] = $wgUser->getEditToken(); } - $cachedEditToken = $wgUser->getEditToken(); - return $cachedEditToken; + return ApiQueryInfo::$cachedTokens[ 'edit' ]; } public static function getDeleteToken( $pageid, $title ) { @@ -124,13 +131,12 @@ class ApiQueryInfo extends ApiQueryBase { return false; } - static $cachedDeleteToken = null; - if ( !is_null( $cachedDeleteToken ) ) { - return $cachedDeleteToken; + // The token is always the same, let's exploit that + if ( !isset( ApiQueryInfo::$cachedTokens[ 'delete' ] ) ) { + ApiQueryInfo::$cachedTokens[ 'delete' ] = $wgUser->getEditToken(); } - $cachedDeleteToken = $wgUser->getEditToken(); - return $cachedDeleteToken; + return ApiQueryInfo::$cachedTokens[ 'delete' ]; } public static function getProtectToken( $pageid, $title ) { @@ -139,13 +145,12 @@ class ApiQueryInfo extends ApiQueryBase { return false; } - static $cachedProtectToken = null; - if ( !is_null( $cachedProtectToken ) ) { - return $cachedProtectToken; + // The token is always the same, let's exploit that + if ( !isset( ApiQueryInfo::$cachedTokens[ 'protect' ] ) ) { + ApiQueryInfo::$cachedTokens[ 'protect' ] = $wgUser->getEditToken(); } - $cachedProtectToken = $wgUser->getEditToken(); - return $cachedProtectToken; + return ApiQueryInfo::$cachedTokens[ 'protect' ]; } public static function getMoveToken( $pageid, $title ) { @@ -154,13 +159,12 @@ class ApiQueryInfo extends ApiQueryBase { return false; } - static $cachedMoveToken = null; - if ( !is_null( $cachedMoveToken ) ) { - return $cachedMoveToken; + // The token is always the same, let's exploit that + if ( !isset( ApiQueryInfo::$cachedTokens[ 'move' ] ) ) { + ApiQueryInfo::$cachedTokens[ 'move' ] = $wgUser->getEditToken(); } - $cachedMoveToken = $wgUser->getEditToken(); - return $cachedMoveToken; + return ApiQueryInfo::$cachedTokens[ 'move' ]; } public static function getBlockToken( $pageid, $title ) { @@ -169,13 +173,12 @@ class ApiQueryInfo extends ApiQueryBase { return false; } - static $cachedBlockToken = null; - if ( !is_null( $cachedBlockToken ) ) { - return $cachedBlockToken; + // The token is always the same, let's exploit that + if ( !isset( ApiQueryInfo::$cachedTokens[ 'block' ] ) ) { + ApiQueryInfo::$cachedTokens[ 'block' ] = $wgUser->getEditToken(); } - $cachedBlockToken = $wgUser->getEditToken(); - return $cachedBlockToken; + return ApiQueryInfo::$cachedTokens[ 'block' ]; } public static function getUnblockToken( $pageid, $title ) { @@ -189,13 +192,12 @@ class ApiQueryInfo extends ApiQueryBase { return false; } - static $cachedEmailToken = null; - if ( !is_null( $cachedEmailToken ) ) { - return $cachedEmailToken; + // The token is always the same, let's exploit that + if ( !isset( ApiQueryInfo::$cachedTokens[ 'email' ] ) ) { + ApiQueryInfo::$cachedTokens[ 'email' ] = $wgUser->getEditToken(); } - $cachedEmailToken = $wgUser->getEditToken(); - return $cachedEmailToken; + return ApiQueryInfo::$cachedTokens[ 'email' ]; } public static function getImportToken( $pageid, $title ) { @@ -204,13 +206,12 @@ class ApiQueryInfo extends ApiQueryBase { return false; } - static $cachedImportToken = null; - if ( !is_null( $cachedImportToken ) ) { - return $cachedImportToken; + // The token is always the same, let's exploit that + if ( !isset( ApiQueryInfo::$cachedTokens[ 'import' ] ) ) { + ApiQueryInfo::$cachedTokens[ 'import' ] = $wgUser->getEditToken(); } - $cachedImportToken = $wgUser->getEditToken(); - return $cachedImportToken; + return ApiQueryInfo::$cachedTokens[ 'import' ]; } public static function getWatchToken( $pageid, $title ) { @@ -219,13 +220,26 @@ class ApiQueryInfo extends ApiQueryBase { return false; } - static $cachedWatchToken = null; - if ( !is_null( $cachedWatchToken ) ) { - return $cachedWatchToken; + // The token is always the same, let's exploit that + if ( !isset( ApiQueryInfo::$cachedTokens[ 'watch' ] ) ) { + ApiQueryInfo::$cachedTokens[ 'watch' ] = $wgUser->getEditToken( 'watch' ); } - $cachedWatchToken = $wgUser->getEditToken( 'watch' ); - return $cachedWatchToken; + return ApiQueryInfo::$cachedTokens[ 'watch' ]; + } + + public static function getOptionsToken( $pageid, $title ) { + global $wgUser; + if ( !$wgUser->isLoggedIn() ) { + return false; + } + + // The token is always the same, let's exploit that + if ( !isset( ApiQueryInfo::$cachedTokens[ 'options' ] ) ) { + ApiQueryInfo::$cachedTokens[ 'options' ] = $wgUser->getEditToken(); + } + + return ApiQueryInfo::$cachedTokens[ 'options' ]; } public function execute() { @@ -234,6 +248,7 @@ class ApiQueryInfo extends ApiQueryBase { $prop = array_flip( $this->params['prop'] ); $this->fld_protection = isset( $prop['protection'] ); $this->fld_watched = isset( $prop['watched'] ); + $this->fld_notificationtimestamp = isset( $prop['notificationtimestamp'] ); $this->fld_talkid = isset( $prop['talkid'] ); $this->fld_subjectid = isset( $prop['subjectid'] ); $this->fld_url = isset( $prop['url'] ); @@ -269,7 +284,10 @@ class ApiQueryInfo extends ApiQueryBase { } $this->pageRestrictions = $pageSet->getCustomField( 'page_restrictions' ); - $this->pageIsRedir = $pageSet->getCustomField( 'page_is_redirect' ); + // when resolving redirects, no page will have this field + $this->pageIsRedir = !$pageSet->isResolvingRedirects() + ? $pageSet->getCustomField( 'page_is_redirect' ) + : array(); $this->pageIsNew = $pageSet->getCustomField( 'page_is_new' ); global $wgDisableCounters; @@ -286,7 +304,7 @@ class ApiQueryInfo extends ApiQueryBase { $this->getProtectionInfo(); } - if ( $this->fld_watched ) { + if ( $this->fld_watched || $this->fld_notificationtimestamp ) { $this->getWatchedInfo(); } @@ -322,7 +340,10 @@ class ApiQueryInfo extends ApiQueryBase { */ private function extractPageInfo( $pageid, $title ) { $pageInfo = array(); - if ( $title->exists() ) { + $titleExists = $pageid > 0; //$title->exists() needs pageid, which is not set for all title objects + $ns = $title->getNamespace(); + $dbkey = $title->getDBkey(); + if ( $titleExists ) { global $wgDisableCounters; $pageInfo['touched'] = wfTimestamp( TS_ISO_8601, $this->pageTouched[$pageid] ); @@ -332,7 +353,7 @@ class ApiQueryInfo extends ApiQueryBase { : intval( $this->pageCounter[$pageid] ); $pageInfo['length'] = intval( $this->pageLength[$pageid] ); - if ( $this->pageIsRedir[$pageid] ) { + if ( isset( $this->pageIsRedir[$pageid] ) && $this->pageIsRedir[$pageid] ) { $pageInfo['redirect'] = ''; } if ( $this->pageIsNew[$pageid] ) { @@ -355,23 +376,30 @@ class ApiQueryInfo extends ApiQueryBase { if ( $this->fld_protection ) { $pageInfo['protection'] = array(); - if ( isset( $this->protections[$title->getNamespace()][$title->getDBkey()] ) ) { + if ( isset( $this->protections[$ns][$dbkey] ) ) { $pageInfo['protection'] = - $this->protections[$title->getNamespace()][$title->getDBkey()]; + $this->protections[$ns][$dbkey]; } $this->getResult()->setIndexedTagName( $pageInfo['protection'], 'pr' ); } - if ( $this->fld_watched && isset( $this->watched[$title->getNamespace()][$title->getDBkey()] ) ) { + if ( $this->fld_watched && isset( $this->watched[$ns][$dbkey] ) ) { $pageInfo['watched'] = ''; } - if ( $this->fld_talkid && isset( $this->talkids[$title->getNamespace()][$title->getDBkey()] ) ) { - $pageInfo['talkid'] = $this->talkids[$title->getNamespace()][$title->getDBkey()]; + if ( $this->fld_notificationtimestamp ) { + $pageInfo['notificationtimestamp'] = ''; + if ( isset( $this->notificationtimestamps[$ns][$dbkey] ) ) { + $pageInfo['notificationtimestamp'] = wfTimestamp( TS_ISO_8601, $this->notificationtimestamps[$ns][$dbkey] ); + } + } + + if ( $this->fld_talkid && isset( $this->talkids[$ns][$dbkey] ) ) { + $pageInfo['talkid'] = $this->talkids[$ns][$dbkey]; } - if ( $this->fld_subjectid && isset( $this->subjectids[$title->getNamespace()][$title->getDBkey()] ) ) { - $pageInfo['subjectid'] = $this->subjectids[$title->getNamespace()][$title->getDBkey()]; + if ( $this->fld_subjectid && isset( $this->subjectids[$ns][$dbkey] ) ) { + $pageInfo['subjectid'] = $this->subjectids[$ns][$dbkey]; } if ( $this->fld_url ) { @@ -383,7 +411,7 @@ class ApiQueryInfo extends ApiQueryBase { } if ( $this->fld_preload ) { - if ( $title->exists() ) { + if ( $titleExists ) { $pageInfo['preload'] = ''; } else { $text = null; @@ -394,8 +422,8 @@ class ApiQueryInfo extends ApiQueryBase { } if ( $this->fld_displaytitle ) { - if ( isset( $this->displaytitles[$title->getArticleId()] ) ) { - $pageInfo['displaytitle'] = $this->displaytitles[$title->getArticleId()]; + if ( isset( $this->displaytitles[$pageid] ) ) { + $pageInfo['displaytitle'] = $this->displaytitles[$pageid]; } else { $pageInfo['displaytitle'] = $title->getPrefixedText(); } @@ -415,15 +443,14 @@ class ApiQueryInfo extends ApiQueryBase { // Get normal protections for existing titles if ( count( $this->titles ) ) { $this->resetQueryParams(); - $this->addTables( array( 'page_restrictions', 'page' ) ); - $this->addWhere( 'page_id=pr_page' ); + $this->addTables( 'page_restrictions' ); $this->addFields( array( 'pr_page', 'pr_type', 'pr_level', - 'pr_expiry', 'pr_cascade', 'page_namespace', - 'page_title' ) ); + 'pr_expiry', 'pr_cascade' ) ); $this->addWhereFld( 'pr_page', array_keys( $this->titles ) ); $res = $this->select( __METHOD__ ); foreach ( $res as $row ) { + $title = $this->titles[$row->pr_page]; $a = array( 'type' => $row->pr_type, 'level' => $row->pr_level, @@ -432,11 +459,14 @@ class ApiQueryInfo extends ApiQueryBase { if ( $row->pr_cascade ) { $a['cascade'] = ''; } - $this->protections[$row->page_namespace][$row->page_title][] = $a; - - // Also check old restrictions - if ( $this->pageRestrictions[$row->pr_page] ) { - $restrictions = explode( ':', trim( $this->pageRestrictions[$row->pr_page] ) ); + $this->protections[$title->getNamespace()][$title->getDBkey()][] = $a; + } + // Also check old restrictions + foreach( $this->titles as $pageId => $title ) { + if ( $this->pageRestrictions[$pageId] ) { + $namespace = $title->getNamespace(); + $dbKey = $title->getDBkey(); + $restrictions = explode( ':', trim( $this->pageRestrictions[$pageId] ) ); foreach ( $restrictions as $restrict ) { $temp = explode( '=', trim( $restrict ) ); if ( count( $temp ) == 1 ) { @@ -446,12 +476,12 @@ class ApiQueryInfo extends ApiQueryBase { if ( $restriction == '' ) { continue; } - $this->protections[$row->page_namespace][$row->page_title][] = array( + $this->protections[$namespace][$dbKey][] = array( 'type' => 'edit', 'level' => $restriction, 'expiry' => 'infinity', ); - $this->protections[$row->page_namespace][$row->page_title][] = array( + $this->protections[$namespace][$dbKey][] = array( 'type' => 'move', 'level' => $restriction, 'expiry' => 'infinity', @@ -461,7 +491,7 @@ class ApiQueryInfo extends ApiQueryBase { if ( $restriction == '' ) { continue; } - $this->protections[$row->page_namespace][$row->page_title][] = array( + $this->protections[$namespace][$dbKey][] = array( 'type' => $temp[0], 'level' => $restriction, 'expiry' => 'infinity', @@ -612,6 +642,7 @@ class ApiQueryInfo extends ApiQueryBase { /** * Get information about watched status and put it in $this->watched + * and $this->notificationtimestamps */ private function getWatchedInfo() { $user = $this->getUser(); @@ -621,6 +652,7 @@ class ApiQueryInfo extends ApiQueryBase { } $this->watched = array(); + $this->notificationtimestamps = array(); $db = $this->getDB(); $lb = new LinkBatch( $this->everything ); @@ -628,6 +660,7 @@ class ApiQueryInfo extends ApiQueryBase { $this->resetQueryParams(); $this->addTables( array( 'watchlist' ) ); $this->addFields( array( 'wl_title', 'wl_namespace' ) ); + $this->addFieldsIf( 'wl_notificationtimestamp', $this->fld_notificationtimestamp ); $this->addWhere( array( $lb->constructSet( 'wl', $db ), 'wl_user' => $user->getID() @@ -636,7 +669,12 @@ class ApiQueryInfo extends ApiQueryBase { $res = $this->select( __METHOD__ ); foreach ( $res as $row ) { - $this->watched[$row->wl_namespace][$row->wl_title] = true; + if ( $this->fld_watched ) { + $this->watched[$row->wl_namespace][$row->wl_title] = true; + } + if ( $this->fld_notificationtimestamp ) { + $this->notificationtimestamps[$row->wl_namespace][$row->wl_title] = $row->wl_notificationtimestamp; + } } } @@ -671,6 +709,7 @@ class ApiQueryInfo extends ApiQueryBase { 'protection', 'talkid', 'watched', # private + 'notificationtimestamp', # private 'subjectid', 'url', 'readable', # private @@ -692,20 +731,80 @@ class ApiQueryInfo extends ApiQueryBase { return array( 'prop' => array( 'Which additional properties to get:', - ' protection - List the protection level of each page', - ' talkid - The page ID of the talk page for each non-talk page', - ' watched - List the watched status of each page', - ' subjectid - The page ID of the parent page for each talk page', - ' url - Gives a full URL to the page, and also an edit URL', - ' readable - Whether the user can read this page', - ' preload - Gives the text returned by EditFormPreloadText', - ' displaytitle - Gives the way the page title is actually displayed', + ' protection - List the protection level of each page', + ' talkid - The page ID of the talk page for each non-talk page', + ' watched - List the watched status of each page', + ' notificationtimestamp - The watchlist notification timestamp of each page', + ' subjectid - The page ID of the parent page for each talk page', + ' url - Gives a full URL to the page, and also an edit URL', + ' readable - Whether the user can read this page', + ' preload - Gives the text returned by EditFormPreloadText', + ' displaytitle - Gives the way the page title is actually displayed', ), 'token' => 'Request a token to perform a data-modifying action on a page', 'continue' => 'When more results are available, use this to continue', ); } + public function getResultProperties() { + $props = array( + ApiBase::PROP_LIST => false, + '' => array( + 'touched' => 'timestamp', + 'lastrevid' => 'integer', + 'counter' => array( + ApiBase::PROP_TYPE => 'integer', + ApiBase::PROP_NULLABLE => true + ), + 'length' => 'integer', + 'redirect' => 'boolean', + 'new' => 'boolean', + 'starttimestamp' => array( + ApiBase::PROP_TYPE => 'timestamp', + ApiBase::PROP_NULLABLE => true + ) + ), + 'watched' => array( + 'watched' => 'boolean' + ), + 'notificationtimestamp' => array( + 'notificationtimestamp' => array( + ApiBase::PROP_TYPE => 'timestamp', + ApiBase::PROP_NULLABLE => true + ) + ), + 'talkid' => array( + 'talkid' => array( + ApiBase::PROP_TYPE => 'integer', + ApiBase::PROP_NULLABLE => true + ) + ), + 'subjectid' => array( + 'subjectid' => array( + ApiBase::PROP_TYPE => 'integer', + ApiBase::PROP_NULLABLE => true + ) + ), + 'url' => array( + 'fullurl' => 'string', + 'editurl' => 'string' + ), + 'readable' => array( + 'readable' => 'boolean' + ), + 'preload' => array( + 'preload' => 'string' + ), + 'displaytitle' => array( + 'displaytitle' => 'string' + ) + ); + + self::addTokenProperties( $props, $this->getTokenFunctions() ); + + return $props; + } + public function getDescription() { return 'Get basic page information such as namespace, title, last touched date, ...'; } -- cgit v1.2.3-54-g00ecf