* allpages module fix
authorYuri Astrakhan <yurik@users.mediawiki.org>
Thu, 12 Oct 2006 03:15:42 +0000 (03:15 +0000)
committerYuri Astrakhan <yurik@users.mediawiki.org>
Thu, 12 Oct 2006 03:15:42 +0000 (03:15 +0000)
* added exception handling code

includes/api/ApiMain.php
includes/api/ApiQuery.php
includes/api/ApiQueryAllpages.php
includes/api/ApiQueryRevisions.php

index f31f3e2..8394991 100644 (file)
@@ -51,6 +51,9 @@ class ApiMain extends ApiBase {
                $this->mResult = new ApiResult($this);
                $this->mShowVersions = false;
                $this->mEnableWrite = $enableWrite;
+               
+               // Initialize Error handler
+               set_exception_handler( array($this, 'exceptionHandler') );
        }
 
        public function & getResult() {
@@ -107,12 +110,7 @@ class ApiMain extends ApiBase {
                        $this->printResult(false);
 
                } catch (UsageException $e) {
-
-                       // Printer may not be initialized if the extractRequestParams() fails for the main module
-                       if (!isset ($this->mPrinter))
-                               $this->mPrinter = new $this->mFormats[API_DEFAULT_FORMAT] ($this, API_DEFAULT_FORMAT);
-                       $this->printResult(true);
-
+                       $this->printError();
                }
                $this->profileOut();
        }
@@ -130,6 +128,13 @@ class ApiMain extends ApiBase {
                $printer->closePrinter();
                $printer->profileOut();
        }
+       
+       private function printError() {
+               // Printer may not be initialized if the extractRequestParams() fails for the main module
+               if (!isset ($this->mPrinter))
+                       $this->mPrinter = new $this->mFormats[API_DEFAULT_FORMAT] ($this, API_DEFAULT_FORMAT);
+               $this->printResult(true);
+       }
 
        protected function getDescription() {
                return array (
@@ -141,22 +146,29 @@ class ApiMain extends ApiBase {
        }
 
        public function mainDieUsage($description, $errorCode, $httpRespCode = 0) {
-               $this->mResult->Reset();
                if ($httpRespCode === 0)
                        header($errorCode, true);
                else
                        header($errorCode, true, $httpRespCode);
 
+               $this->makeErrorMessage($description, $errorCode);
+
+               throw new UsageException($description, $errorCode);
+       }
+
+       public function makeErrorMessage($description, $errorCode, $customContent = null) {
+               $this->mResult->Reset();
                $data = array (
                        'code' => $errorCode,
                        'info' => $description
                );
-               ApiResult :: setContent($data, $this->makeHelpMsg());
+               
+               ApiResult :: setContent($data, 
+                       is_null($customContent) ? $this->makeHelpMsg() : $customContent);
+                       
                $this->mResult->addValue(null, 'error', $data);
-
-               throw new UsageException($description, $errorCode);
        }
-
+       
        /**
         * Override the parent to generate help messages for all available modules.
         */
@@ -188,6 +200,53 @@ class ApiMain extends ApiBase {
 
                return $msg;
        }
+       
+       /**
+        * Exception handler which simulates the appropriate catch() handling:
+        *
+        *   try {
+        *       ...
+        *   } catch ( MWException $e ) {
+        *       dieUsage()
+        *   } catch ( Exception $e ) {
+        *       echo $e->__toString();
+        *   }
+        * 
+        * 
+        * 
+        * 
+        *          !!!!!!!!!!!!! REVIEW needed !!!!!!!!!!!!!!!!!!
+        * 
+        *                        this method needs to be reviewed/cleaned up
+        * 
+        * 
+        * 
+        */
+       public function exceptionHandler( $e ) {
+               global $wgFullyInitialised;
+                if ( is_a( $e, 'MWException' ) ) {
+                        try {
+                               $msg = "Exception Caught: {$e->getMessage()}";
+                               $this->makeErrorMessage($msg, 'internal_error', "\n\n{$e->getTraceAsString()}\n\n");
+                               $this->printError();
+                        } catch (Exception $e2) {
+                 echo $e->__toString();
+             }
+                } else {
+                        echo $e->__toString();
+                }
+
+               // Final cleanup, similar to wfErrorExit()
+               if ( $wgFullyInitialised ) {
+                       try {
+                               wfLogProfilingData(); // uses $wgRequest, hence the $wgFullyInitialised condition
+                       } catch ( Exception $e ) {}
+               }
+
+               // Exit value should be nonzero for the benefit of shell jobs
+               exit( 1 );
+       }
+
 
        private $mIsBot = null;
        public function isBot() {
index be57b06..ea6d359 100644 (file)
@@ -33,6 +33,7 @@ class ApiQuery extends ApiBase {
 
        private $mPropModuleNames, $mListModuleNames, $mMetaModuleNames;
        private $mPageSet;
+       private $mValidNamespaces;
 
        private $mQueryPropModules = array (
                'info' => 'ApiQueryInfo',
@@ -69,6 +70,7 @@ class ApiQuery extends ApiBase {
                $this->mPropModuleNames = array_keys($this->mQueryPropModules);
                $this->mListModuleNames = array_keys($this->mQueryListModules);
                $this->mMetaModuleNames = array_keys($this->mQueryMetaModules);
+               $this->mValidNamespaces = null;
 
                // Allow the entire list of modules at first,
                // but during module instantiation check if it can be used as a generator.
@@ -85,6 +87,19 @@ class ApiQuery extends ApiBase {
                return $this->mPageSet;
        }
 
+       public function getValidNamespaces() {
+               global $wgContLang;
+
+               if (is_null($this->mValidNamespaces)) {
+                       $this->mValidNamespaces = array ();
+                       foreach (array_keys($wgContLang->getNamespaces()) as $ns) {
+                               if ($ns >= 0)
+                                       $this->mValidNamespaces[] = $ns; // strval($ns);                
+                       }
+               }
+               return $this->mValidNamespaces;
+       }
+
        /**
         * Query execution happens in the following steps:
         * #1 Create a PageSet object with any pages requested by the user
index 89b2266..dc7758b 100644 (file)
@@ -42,7 +42,7 @@ class ApiQueryAllpages extends ApiQueryGeneratorBase {
        public function executeGenerator($resultPageSet) {
                if ($resultPageSet->isResolvingRedirects())
                        $this->dieUsage('Use "gapfilterredir=nonredirects" option instead of "redirects" when using allpages as a generator', 'params');
-                       
+
                $this->run($resultPageSet);
        }
 
@@ -55,11 +55,11 @@ class ApiQueryAllpages extends ApiQueryGeneratorBase {
                $where = array (
                        'page_namespace' => $namespace
                );
-               
+
                if (isset ($from)) {
                        $where[] = 'page_title>=' . $db->addQuotes(ApiQueryBase :: titleToKey($from));
                }
-               
+
                if ($filterredir === 'redirects') {
                        $where['page_is_redirect'] = 1;
                }
@@ -77,12 +77,14 @@ class ApiQueryAllpages extends ApiQueryGeneratorBase {
                        $fields = $resultPageSet->getPageTableFields();
                }
 
-               $this->profileDBIn();
-               $res = $db->select('page', $fields, $where, __CLASS__ . '::' . __METHOD__, array (
+               $options = array (
                        'USE INDEX' => 'name_title',
                        'LIMIT' => $limit +1,
                        'ORDER BY' => 'page_namespace, page_title'
-               ));
+               );
+
+               $this->profileDBIn();
+               $res = $db->select('page', $fields, $where, __METHOD__, $options);
                $this->profileDBOut();
 
                $data = array ();
@@ -103,7 +105,10 @@ class ApiQueryAllpages extends ApiQueryGeneratorBase {
 
                                if (is_null($resultPageSet)) {
                                        $id = intval($row->page_id);
-                                       $data[] = $id; // in generator mode, just assemble a list of page IDs.
+                                       $data[$id] = array (
+                                               'id' => $id,
+                                               'ns' => $title->getNamespace(),
+                                               'title' => $title->getPrefixedText());
                                } else {
                                        $resultPageSet->processDbRow($row);
                                }
@@ -119,35 +124,25 @@ class ApiQueryAllpages extends ApiQueryGeneratorBase {
 
        protected function getAllowedParams() {
 
-               global $wgContLang;
-               $validNamespaces = array ();
-               foreach (array_keys($wgContLang->getNamespaces()) as $ns) {
-                       if ($ns >= 0)
-                               $validNamespaces[] = $ns; // strval($ns);               
-               }
-
                return array (
                        'from' => null,
                        'namespace' => array (
                                ApiBase :: PARAM_DFLT => 0,
-                               ApiBase :: PARAM_TYPE => $validNamespaces
-                       ),
+                               ApiBase :: PARAM_TYPE => $this->getQuery()->getValidNamespaces()),
                        'filterredir' => array (
                                ApiBase :: PARAM_DFLT => 'all',
                                ApiBase :: PARAM_TYPE => array (
                                        'all',
                                        'redirects',
                                        'nonredirects'
-                               )
-                       ),
+                               )),
                        'limit' => array (
                                ApiBase :: PARAM_DFLT => 10,
                                ApiBase :: PARAM_TYPE => 'limit',
                                ApiBase :: PARAM_MIN => 1,
                                ApiBase :: PARAM_MAX1 => 500,
                                ApiBase :: PARAM_MAX2 => 5000
-                       )
-               );
+               ));
        }
 
        protected function getParamDescription() {
index dce0a8d..65e25b6 100644 (file)
@@ -76,7 +76,7 @@ class ApiQueryRevisions extends ApiQueryBase {
                        'rev_text_id',
                        'rev_minor_edit'
                );
-               $conds = array (
+               $where = array (
                        'rev_deleted' => 0
                );
                $options = array ();
@@ -100,7 +100,7 @@ class ApiQueryRevisions extends ApiQueryBase {
                                                break;
                                        case 'content' :
                                                $tables[] = 'text';
-                                               $conds[] = 'rev_text_id=old_id';
+                                               $where[] = 'rev_text_id=old_id';
                                                $fields[] = 'old_id';
                                                $fields[] = 'old_text';
                                                $fields[] = 'old_flags';
@@ -136,13 +136,13 @@ class ApiQueryRevisions extends ApiQueryBase {
                        $after = ($dirNewer ? '>=' : '<=');
 
                        if ($startid !== 0)
-                               $conds[] = 'rev_id' . $after . intval($startid);
+                               $where[] = 'rev_id' . $after . intval($startid);
                        if ($endid !== 0)
-                               $conds[] = 'rev_id' . $before . intval($endid);
+                               $where[] = 'rev_id' . $before . intval($endid);
                        if (isset ($start))
-                               $conds[] = 'rev_timestamp' . $after . $db->addQuotes($start);
+                               $where[] = 'rev_timestamp' . $after . $db->addQuotes($start);
                        if (isset ($end))
-                               $conds[] = 'rev_timestamp' . $before . $db->addQuotes($end);
+                               $where[] = 'rev_timestamp' . $before . $db->addQuotes($end);
 
                        // must manually initialize unset limit
                        if (!isset ($limit))
@@ -151,19 +151,19 @@ class ApiQueryRevisions extends ApiQueryBase {
                        $this->validateLimit($this->encodeParamName('limit'), $limit, 1, $userMax, $botMax);
 
                        // There is only one ID, use it
-                       $conds['rev_page'] = array_pop(array_keys($pageSet->getGoodTitles()));
+                       $where['rev_page'] = array_pop(array_keys($pageSet->getGoodTitles()));
 
                }
                elseif ($pageCount > 0) {
                        // When working in multi-page non-enumeration mode,
                        // limit to the latest revision only
                        $tables[] = 'page';
-                       $conds[] = 'page_id=rev_page';
-                       $conds[] = 'page_latest=rev_id';
+                       $where[] = 'page_id=rev_page';
+                       $where[] = 'page_latest=rev_id';
                        $this->validateLimit('page_count', $pageCount, 1, $userMax, $botMax);
 
                        // Get all page IDs
-                       $conds['page_id'] = array_keys($pageSet->getGoodTitles());
+                       $where['page_id'] = array_keys($pageSet->getGoodTitles());
 
                        $limit = $pageCount; // assumption testing -- we should never get more then $pageCount rows.
                }
@@ -171,7 +171,7 @@ class ApiQueryRevisions extends ApiQueryBase {
                        $this->validateLimit('rev_count', $revCount, 1, $userMax, $botMax);
 
                        // Get all revision IDs
-                       $conds['rev_id'] = array_keys($pageSet->getRevisionIDs());
+                       $where['rev_id'] = array_keys($pageSet->getRevisionIDs());
 
                        $limit = $revCount; // assumption testing -- we should never get more then $revCount rows.
                } else
@@ -180,7 +180,7 @@ class ApiQueryRevisions extends ApiQueryBase {
                $options['LIMIT'] = $limit +1;
 
                $this->profileDBIn();
-               $res = $db->select($tables, $fields, $conds, __METHOD__, $options);
+               $res = $db->select($tables, $fields, $where, __METHOD__, $options);
                $this->profileDBOut();
 
                $data = array ();