]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blobdiff - includes/api/ApiQueryBacklinks.php
MediaWiki 1.15.0
[autoinstallsdev/mediawiki.git] / includes / api / ApiQueryBacklinks.php
index f67e0044a887dfcd32483a287b44fd728a26cd6f..959723921093be6f1ecb74db3cbecadcbf9484b2 100644 (file)
@@ -38,7 +38,9 @@ if (!defined('MEDIAWIKI')) {
  */
 class ApiQueryBacklinks extends ApiQueryGeneratorBase {
 
-       private $params, $rootTitle, $contRedirs, $contLevel, $contTitle, $contID, $redirID;
+       private $params, $rootTitle, $contRedirs, $contLevel, $contTitle, $contID, $redirID, $redirect;
+       private $bl_ns, $bl_from, $bl_table, $bl_code, $bl_title, $bl_sort, $bl_fields, $hasNS;
+       private $pageMap, $resultArr;
 
        // output element name, database column field prefix, database table
        private $backlinksSettings = array (
@@ -61,6 +63,7 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
 
        public function __construct($query, $moduleName) {
                extract($this->backlinksSettings[$moduleName]);
+               $this->resultArr = array();
 
                parent :: __construct($query, $moduleName, $code);
                $this->bl_ns = $prefix . '_namespace';
@@ -137,11 +140,11 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
                $this->addFields($this->bl_title);
                if($this->hasNS)
                        $this->addFields($this->bl_ns);
+               // We can't use LinkBatch here because $this->hasNS may be false
                $titleWhere = array();
                foreach($this->redirTitles as $t)
-                       $titleWhere[] = "({$this->bl_title} = ".$db->addQuotes($t->getDBKey()).
-                                       ($this->hasNS ? " AND {$this->bl_ns} = '{$t->getNamespace()}'" : "") .
-                                       ")";
+                       $titleWhere[] = "{$this->bl_title} = ".$db->addQuotes($t->getDBKey()).
+                                       ($this->hasNS ? " AND {$this->bl_ns} = '{$t->getNamespace()}'" : "");
                $this->addWhere($db->makeList($titleWhere, LIST_OR));
                $this->addWhereFld('page_namespace', $this->params['namespace']);
                if(!is_null($this->redirID))
@@ -168,6 +171,7 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
                        $this->addWhereFld('page_is_redirect', 0);
                $this->addOption('LIMIT', $this->params['limit'] + 1);
                $this->addOption('ORDER BY', $this->bl_sort);
+               $this->addOption('USE INDEX', array('page' => 'PRIMARY'));
        }
 
        private function run($resultPageSet = null) {
@@ -187,7 +191,7 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
                $res = $this->select(__METHOD__.'::firstQuery');
 
                $count = 0;
-               $this->data = array ();
+               $this->pageMap = array(); // Maps ns and title to pageid
                $this->continueStr = null;
                $this->redirTitles = array();
                while ($row = $db->fetchObject($res)) {
@@ -202,6 +206,7 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
                                $this->extractRowInfo($row);
                        else
                        {
+                               $this->pageMap[$row->page_namespace][$row->page_title] = $row->page_id;
                                if($row->page_is_redirect)
                                        $this->redirTitles[] = Title::makeTitle($row->page_namespace, $row->page_title);
                                $resultPageSet->processDbRow($row);
@@ -222,10 +227,10 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
                                        // We've reached the one extra which shows that there are additional pages to be had. Stop here...
                                        // We need to keep the parent page of this redir in
                                        if($this->hasNS)
-                                               $contTitle = Title::makeTitle($row->{$this->bl_ns}, $row->{$this->bl_title});
+                                               $parentID = $this->pageMap[$row->{$this->bl_ns}][$row->{$this->bl_title}];
                                        else
-                                               $contTitle = Title::makeTitle(NS_FILE, $row->{$this->bl_title});
-                                       $this->continueStr = $this->getContinueRedirStr($contTitle->getArticleID(), $row->page_id);
+                                               $parentID = $this->pageMap[NS_IMAGE][$row->{$this->bl_title}];
+                                               $this->continueStr = $this->getContinueRedirStr($parentID, $row->page_id);
                                        break;
                                }
 
@@ -236,41 +241,80 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
                        }
                        $db->freeResult($res);
                }
-               if(!is_null($this->continueStr))
-                       $this->setContinueEnumParameter('continue', $this->continueStr);
-
                if (is_null($resultPageSet)) {
-                       $resultData = array();
-                       foreach($this->data as $ns => $a)
-                               foreach($a as $title => $arr)
-                                       $resultData[] = $arr;
-                       $result = $this->getResult();
-                       $result->setIndexedTagName($resultData, $this->bl_code);
-                       $result->addValue('query', $this->getModuleName(), $resultData);
+                       // Try to add the result data in one go and pray that it fits
+                       $fit = $this->getResult()->addValue('query', $this->getModuleName(), array_values($this->resultArr));
+                       if(!$fit)
+                       {
+                               // It didn't fit. Add elements one by one until the
+                               // result is full.
+                               foreach($this->resultArr as $pageID => $arr)
+                               {
+                                       // Add the basic entry without redirlinks first
+                                       $fit = $this->getResult()->addValue(
+                                               array('query', $this->getModuleName()),
+                                               null, array_diff_key($arr, array('redirlinks' => '')));
+                                       if(!$fit)
+                                       {
+                                               $this->continueStr = $this->getContinueStr($pageID);
+                                               break;
+                                       }
+
+                                       $hasRedirs = false;
+                                       foreach((array)@$arr['redirlinks'] as $key => $redir)
+                                       {
+                                               $fit = $this->getResult()->addValue(
+                                                       array('query', $this->getModuleName(), $pageID, 'redirlinks'),
+                                                       $key, $redir);
+                                               if(!$fit)
+                                               {
+                                                       $this->continueStr = $this->getContinueRedirStr($pageID, $redir['pageid']);
+                                                       break;
+                                               }
+                                               $hasRedirs = true;
+                                       }
+                                       if($hasRedirs)
+                                               $this->getResult()->setIndexedTagName_internal(
+                                                       array('query', $this->getModuleName(), $pageID, 'redirlinks'),
+                                                       $this->bl_code);
+                                       if(!$fit)
+                                               break;
+                               }
+                       }               
+
+                       $this->getResult()->setIndexedTagName_internal(
+                                        array('query', $this->getModuleName()),
+                                        $this->bl_code);
                }
+               if(!is_null($this->continueStr))
+                       $this->setContinueEnumParameter('continue', $this->continueStr);
        }
 
        private function extractRowInfo($row) {
-               if(!isset($this->data[$row->page_namespace][$row->page_title])) {
-                       $this->data[$row->page_namespace][$row->page_title]['pageid'] = $row->page_id;
-                       ApiQueryBase::addTitleInfo($this->data[$row->page_namespace][$row->page_title], Title::makeTitle($row->page_namespace, $row->page_title));
-                       if($row->page_is_redirect)
-                       {
-                               $this->data[$row->page_namespace][$row->page_title]['redirect'] = '';
-                               $this->redirTitles[] = Title::makeTitle($row->page_namespace, $row->page_title);
-                       }
+               $this->pageMap[$row->page_namespace][$row->page_title] = $row->page_id;
+               $t = Title::makeTitle($row->page_namespace, $row->page_title);
+               $a = array('pageid' => intval($row->page_id));
+               ApiQueryBase::addTitleInfo($a, $t);
+               if($row->page_is_redirect)
+               {
+                       $a['redirect'] = '';
+                       $this->redirTitles[] = $t;
                }
+               // Put all the results in an array first
+               $this->resultArr[$a['pageid']] = $a;
        }
 
        private function extractRedirRowInfo($row)
        {
-               $a['pageid'] = $row->page_id;
+               $a['pageid'] = intval($row->page_id);
                ApiQueryBase::addTitleInfo($a, Title::makeTitle($row->page_namespace, $row->page_title));
                if($row->page_is_redirect)
                        $a['redirect'] = '';
                $ns = $this->hasNS ? $row->{$this->bl_ns} : NS_FILE;
-               $this->data[$ns][$row->{$this->bl_title}]['redirlinks'][] = $a;
-               $this->getResult()->setIndexedTagName($this->data[$ns][$row->{$this->bl_title}]['redirlinks'], $this->bl_code);
+               $parentID = $this->pageMap[$ns][$row->{$this->bl_title}];
+               // Put all the results in an array first
+               $this->resultArr[$parentID]['redirlinks'][] = $a;
+               $this->getResult()->setIndexedTagName($this->resultArr[$parentID]['redirlinks'], $this->bl_code);
        }
 
        protected function processContinue() {
@@ -404,8 +448,8 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
                                "api.php?action=query&generator=embeddedin&geititle=Template:Stub&prop=info"
                        ),
                        'imageusage' => array (
-                               "api.php?action=query&list=imageusage&iutitle=Image:Albert%20Einstein%20Head.jpg",
-                               "api.php?action=query&generator=imageusage&giutitle=Image:Albert%20Einstein%20Head.jpg&prop=info"
+                               "api.php?action=query&list=imageusage&iutitle=File:Albert%20Einstein%20Head.jpg",
+                               "api.php?action=query&generator=imageusage&giutitle=File:Albert%20Einstein%20Head.jpg&prop=info"
                        )
                );
 
@@ -413,6 +457,6 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
        }
 
        public function getVersion() {
-               return __CLASS__ . ': $Id: ApiQueryBacklinks.php 46135 2009-01-24 13:03:40Z catrope $';
+               return __CLASS__ . ': $Id: ApiQueryBacklinks.php 50217 2009-05-05 13:12:16Z tstarling $';
        }
 }