Add mw-body-content to indicators
[lhc/web/wiklou.git] / includes / api / ApiQueryInfo.php
index 3aa0122..e789dd4 100644 (file)
@@ -23,6 +23,8 @@
  *
  * @file
  */
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Linker\LinkTarget;
 
 /**
  * A query module to show basic page information.
@@ -90,7 +92,7 @@ class ApiQueryInfo extends ApiQueryBase {
         * The prototype for a token function is func($pageid, $title)
         * it should return a token or false (permission denied)
         * @deprecated since 1.24
-        * @return array Array(tokenname => function)
+        * @return array [ tokenname => function ]
         */
        protected function getTokenFunctions() {
                // Don't call the hooks twice
@@ -425,7 +427,7 @@ class ApiQueryInfo extends ApiQueryBase {
                        foreach ( $this->params['token'] as $t ) {
                                $val = call_user_func( $tokenFunctions[$t], $pageid, $title );
                                if ( $val === false ) {
-                                       $this->setWarning( "Action '$t' is not allowed for the current user" );
+                                       $this->addWarning( [ 'apiwarn-tokennotallowed', $t ] );
                                } else {
                                        $pageInfo[$t . 'token'] = $val;
                                }
@@ -448,18 +450,20 @@ class ApiQueryInfo extends ApiQueryBase {
                        ApiResult::setIndexedTagName( $pageInfo['restrictiontypes'], 'rt' );
                }
 
-               if ( $this->fld_watched ) {
-                       $pageInfo['watched'] = isset( $this->watched[$ns][$dbkey] );
+               if ( $this->fld_watched && $this->watched !== null ) {
+                       $pageInfo['watched'] = $this->watched[$ns][$dbkey];
                }
 
                if ( $this->fld_watchers ) {
-                       if ( $this->watchers[$ns][$dbkey] !== 0 || $this->showZeroWatchers ) {
+                       if ( $this->watchers !== null && $this->watchers[$ns][$dbkey] !== 0 ) {
                                $pageInfo['watchers'] = $this->watchers[$ns][$dbkey];
+                       } elseif ( $this->showZeroWatchers ) {
+                               $pageInfo['watchers'] = 0;
                        }
                }
 
                if ( $this->fld_visitingwatchers ) {
-                       if ( isset( $this->visitingwatchers[$ns][$dbkey] ) ) {
+                       if ( $this->visitingwatchers !== null && $this->visitingwatchers[$ns][$dbkey] !== 0 ) {
                                $pageInfo['visitingwatchers'] = $this->visitingwatchers[$ns][$dbkey];
                        } elseif ( $this->showZeroWatchers ) {
                                $pageInfo['visitingwatchers'] = 0;
@@ -468,7 +472,7 @@ class ApiQueryInfo extends ApiQueryBase {
 
                if ( $this->fld_notificationtimestamp ) {
                        $pageInfo['notificationtimestamp'] = '';
-                       if ( isset( $this->notificationtimestamps[$ns][$dbkey] ) ) {
+                       if ( $this->notificationtimestamps[$ns][$dbkey] ) {
                                $pageInfo['notificationtimestamp'] =
                                        wfTimestamp( TS_ISO_8601, $this->notificationtimestamps[$ns][$dbkey] );
                        }
@@ -531,7 +535,6 @@ class ApiQueryInfo extends ApiQueryBase {
         * Get information about protections and put it in $protections
         */
        private function getProtectionInfo() {
-               global $wgContLang;
                $this->protections = [];
                $db = $this->getDB();
 
@@ -550,7 +553,7 @@ class ApiQueryInfo extends ApiQueryBase {
                                $a = [
                                        'type' => $row->pr_type,
                                        'level' => $row->pr_level,
-                                       'expiry' => $wgContLang->formatExpiry( $row->pr_expiry, TS_ISO_8601 )
+                                       'expiry' => ApiResult::formatExpiry( $row->pr_expiry )
                                ];
                                if ( $row->pr_cascade ) {
                                        $a['cascade'] = true;
@@ -610,7 +613,7 @@ class ApiQueryInfo extends ApiQueryBase {
                                $this->protections[$row->pt_namespace][$row->pt_title][] = [
                                        'type' => 'create',
                                        'level' => $row->pt_create_perm,
-                                       'expiry' => $wgContLang->formatExpiry( $row->pt_expiry, TS_ISO_8601 )
+                                       'expiry' => ApiResult::formatExpiry( $row->pt_expiry )
                                ];
                        }
                }
@@ -648,7 +651,7 @@ class ApiQueryInfo extends ApiQueryBase {
                                $this->protections[$row->tl_namespace][$row->tl_title][] = [
                                        'type' => $row->pr_type,
                                        'level' => $row->pr_level,
-                                       'expiry' => $wgContLang->formatExpiry( $row->pr_expiry, TS_ISO_8601 ),
+                                       'expiry' => ApiResult::formatExpiry( $row->pr_expiry ),
                                        'source' => $source->getPrefixedText()
                                ];
                        }
@@ -671,7 +674,7 @@ class ApiQueryInfo extends ApiQueryBase {
                                $this->protections[NS_FILE][$row->il_to][] = [
                                        'type' => $row->pr_type,
                                        'level' => $row->pr_level,
-                                       'expiry' => $wgContLang->formatExpiry( $row->pr_expiry, TS_ISO_8601 ),
+                                       'expiry' => ApiResult::formatExpiry( $row->pr_expiry ),
                                        'source' => $source->getPrefixedText()
                                ];
                        }
@@ -756,30 +759,23 @@ class ApiQueryInfo extends ApiQueryBase {
 
                $this->watched = [];
                $this->notificationtimestamps = [];
-               $db = $this->getDB();
-
-               $lb = new LinkBatch( $this->everything );
 
-               $this->resetQueryParams();
-               $this->addTables( [ 'watchlist' ] );
-               $this->addFields( [ 'wl_title', 'wl_namespace' ] );
-               $this->addFieldsIf( 'wl_notificationtimestamp', $this->fld_notificationtimestamp );
-               $this->addWhere( [
-                       $lb->constructSet( 'wl', $db ),
-                       'wl_user' => $user->getId()
-               ] );
-
-               $res = $this->select( __METHOD__ );
+               $store = MediaWikiServices::getInstance()->getWatchedItemStore();
+               $timestamps = $store->getNotificationTimestampsBatch( $user, $this->everything );
 
-               foreach ( $res as $row ) {
-                       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;
+               if ( $this->fld_watched ) {
+                       foreach ( $timestamps as $namespaceId => $dbKeys ) {
+                               $this->watched[$namespaceId] = array_map(
+                                       function( $x ) {
+                                               return $x !== false;
+                                       },
+                                       $dbKeys
+                               );
                        }
                }
+               if ( $this->fld_notificationtimestamp ) {
+                       $this->notificationtimestamps = $timestamps;
+               }
        }
 
        /**
@@ -804,7 +800,7 @@ class ApiQueryInfo extends ApiQueryBase {
                        $countOptions['minimumWatchers'] = $unwatchedPageThreshold;
                }
 
-               $this->watchers = WatchedItemStore::getDefaultInstance()->countWatchersMultiple(
+               $this->watchers = MediaWikiServices::getInstance()->getWatchedItemStore()->countWatchersMultiple(
                        $this->everything,
                        $countOptions
                );
@@ -829,14 +825,7 @@ class ApiQueryInfo extends ApiQueryBase {
 
                $this->showZeroWatchers = $canUnwatchedpages;
 
-               // Assemble a WHERE condition to find:
-               // * if the page exists, number of users watching who have
-               //   visited the page recently
-               // * if the page doesn't exist, number of users that have
-               //   the page on their watchlist
-               $whereStrings = [];
-
-               // For pages that exist
+               $titlesWithThresholds = [];
                if ( $this->titles ) {
                        $lb = new LinkBatch( $this->titles );
 
@@ -851,55 +840,38 @@ class ApiQueryInfo extends ApiQueryBase {
                        $this->addOption( 'GROUP BY', [ 'page_namespace', 'page_title' ] );
                        $timestampRes = $this->select( __METHOD__ );
 
-                       // Assemble SQL WHERE condition to find number of page watchers who also
-                       // visited a "recent" edit (last visited about 26 weeks before latest edit)
                        $age = $config->get( 'WatchersMaxAge' );
                        $timestamps = [];
                        foreach ( $timestampRes as $row ) {
                                $revTimestamp = wfTimestamp( TS_UNIX, (int)$row->rev_timestamp );
-                               $threshold = $db->timestamp( $revTimestamp - $age );
-                               $timestamps[$row->page_namespace][$row->page_title] = $threshold;
-                       }
-
-                       foreach ( $timestamps as $ns_key => $namespace ) {
-                               $pageStrings = [];
-                               foreach ( $namespace as $pg_key => $threshold ) {
-                                       $pageStrings[] = "wl_title = '$pg_key' AND" .
-                                               ' (wl_notificationtimestamp >= ' .
-                                               $db->addQuotes( $threshold ) .
-                                               ' OR wl_notificationtimestamp IS NULL)';
-                               }
-                               $whereStrings[] = "wl_namespace = '$ns_key' AND (" .
-                                       $db->makeList( $pageStrings, LIST_OR ) . ')';
+                               $timestamps[$row->page_namespace][$row->page_title] = $revTimestamp - $age;
                        }
+                       $titlesWithThresholds = array_map(
+                               function( LinkTarget $target ) use ( $timestamps ) {
+                                       return [
+                                               $target, $timestamps[$target->getNamespace()][$target->getDBkey()]
+                                       ];
+                               },
+                               $this->titles
+                       );
                }
 
-               // For nonexistant pages
                if ( $this->missing ) {
-                       $lb = new LinkBatch( $this->missing );
-                       $whereStrings[] = $lb->constructSet( 'wl', $db );
-               }
-
-               // Make the actual string and do the query
-               $whereString = $db->makeList( $whereStrings, LIST_OR );
-
-               $this->resetQueryParams();
-               $this->addTables( [ 'watchlist' ] );
-               $this->addFields( [
-                       'wl_namespace',
-                       'wl_title',
-                       'count' => 'COUNT(*)'
-               ] );
-               $this->addWhere( [ $whereString ] );
-               $this->addOption( 'GROUP BY', [ 'wl_namespace', 'wl_title' ] );
-               if ( !$canUnwatchedpages ) {
-                       $this->addOption( 'HAVING', "COUNT(*) >= $unwatchedPageThreshold" );
-               }
-
-               $res = $this->select( __METHOD__ );
-               foreach ( $res as $row ) {
-                       $this->visitingwatchers[$row->wl_namespace][$row->wl_title] = (int)$row->count;
-               }
+                       $titlesWithThresholds = array_merge(
+                               $titlesWithThresholds,
+                               array_map(
+                                       function( LinkTarget $target ) {
+                                               return [ $target, null ];
+                                       },
+                                       $this->missing
+                               )
+                       );
+               }
+               $store = MediaWikiServices::getInstance()->getWatchedItemStore();
+               $this->visitingwatchers = $store->countVisitingWatchersMultiple(
+                       $titlesWithThresholds,
+                       !$canUnwatchedpages ? $unwatchedPageThreshold : null
+               );
        }
 
        public function getCacheMode( $params ) {