00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 if ( !defined( 'MEDIAWIKI' ) ) {
00027
00028 require_once ( "ApiQueryBase.php" );
00029 }
00030
00036 class ApiQueryCategories extends ApiQueryGeneratorBase {
00037
00038 public function __construct( $query, $moduleName ) {
00039 parent :: __construct( $query, $moduleName, 'cl' );
00040 }
00041
00042 public function execute() {
00043 $this->run();
00044 }
00045
00046 public function getCacheMode( $params ) {
00047 return 'public';
00048 }
00049
00050 public function executeGenerator( $resultPageSet ) {
00051 $this->run( $resultPageSet );
00052 }
00053
00054 private function run( $resultPageSet = null ) {
00055
00056 if ( $this->getPageSet()->getGoodTitleCount() == 0 )
00057 return;
00058
00059 $params = $this->extractRequestParams();
00060 $prop = array_flip( (array)$params['prop'] );
00061 $show = array_flip( (array)$params['show'] );
00062
00063 $this->addFields( array (
00064 'cl_from',
00065 'cl_to'
00066 ) );
00067
00068 $this->addFieldsIf( 'cl_sortkey', isset( $prop['sortkey'] ) );
00069 $this->addFieldsIf( 'cl_timestamp', isset( $prop['timestamp'] ) );
00070
00071 $this->addTables( 'categorylinks' );
00072 $this->addWhereFld( 'cl_from', array_keys( $this->getPageSet()->getGoodTitles() ) );
00073 if ( !is_null( $params['categories'] ) )
00074 {
00075 $cats = array();
00076 foreach ( $params['categories'] as $cat )
00077 {
00078 $title = Title::newFromText( $cat );
00079 if ( !$title || $title->getNamespace() != NS_CATEGORY )
00080 $this->setWarning( "``$cat'' is not a category" );
00081 else
00082 $cats[] = $title->getDBkey();
00083 }
00084 $this->addWhereFld( 'cl_to', $cats );
00085 }
00086
00087 if ( !is_null( $params['continue'] ) ) {
00088 $cont = explode( '|', $params['continue'] );
00089 if ( count( $cont ) != 2 )
00090 $this->dieUsage( "Invalid continue param. You should pass the " .
00091 "original value returned by the previous query", "_badcontinue" );
00092 $clfrom = intval( $cont[0] );
00093 $clto = $this->getDB()->strencode( $this->titleToKey( $cont[1] ) );
00094 $this->addWhere( "cl_from > $clfrom OR " .
00095 "(cl_from = $clfrom AND " .
00096 "cl_to >= '$clto')" );
00097 }
00098
00099 if ( isset( $show['hidden'] ) && isset( $show['!hidden'] ) )
00100 $this->dieUsageMsg( array( 'show' ) );
00101 if ( isset( $show['hidden'] ) || isset( $show['!hidden'] ) || isset( $prop['hidden'] ) )
00102 {
00103 $this->addOption( 'STRAIGHT_JOIN' );
00104 $this->addTables( array( 'page', 'page_props' ) );
00105 $this->addFieldsIf( 'pp_propname', isset( $prop['hidden'] ) );
00106 $this->addJoinConds( array(
00107 'page' => array( 'LEFT JOIN', array(
00108 'page_namespace' => NS_CATEGORY,
00109 'page_title = cl_to' ) ),
00110 'page_props' => array( 'LEFT JOIN', array(
00111 'pp_page=page_id',
00112 'pp_propname' => 'hiddencat' ) )
00113 ) );
00114 if ( isset( $show['hidden'] ) )
00115 $this->addWhere( array( 'pp_propname IS NOT NULL' ) );
00116 else if ( isset( $show['!hidden'] ) )
00117 $this->addWhere( array( 'pp_propname IS NULL' ) );
00118 }
00119
00120 $this->addOption( 'USE INDEX', array( 'categorylinks' => 'cl_from' ) );
00121
00122 if ( count( $this->getPageSet()->getGoodTitles() ) == 1 )
00123 $this->addOption( 'ORDER BY', 'cl_to' );
00124 else
00125 $this->addOption( 'ORDER BY', "cl_from, cl_to" );
00126
00127 $db = $this->getDB();
00128 $res = $this->select( __METHOD__ );
00129
00130 if ( is_null( $resultPageSet ) ) {
00131
00132 $count = 0;
00133 while ( $row = $db->fetchObject( $res ) ) {
00134 if ( ++$count > $params['limit'] ) {
00135
00136
00137 $this->setContinueEnumParameter( 'continue', $row->cl_from .
00138 '|' . $this->keyToTitle( $row->cl_to ) );
00139 break;
00140 }
00141
00142 $title = Title :: makeTitle( NS_CATEGORY, $row->cl_to );
00143 $vals = array();
00144 ApiQueryBase :: addTitleInfo( $vals, $title );
00145 if ( isset( $prop['sortkey'] ) )
00146 $vals['sortkey'] = $row->cl_sortkey;
00147 if ( isset( $prop['timestamp'] ) )
00148 $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->cl_timestamp );
00149 if ( isset( $prop['hidden'] ) && !is_null( $row->pp_propname ) )
00150 $vals['hidden'] = '';
00151
00152 $fit = $this->addPageSubItem( $row->cl_from, $vals );
00153 if ( !$fit )
00154 {
00155 $this->setContinueEnumParameter( 'continue', $row->cl_from .
00156 '|' . $this->keyToTitle( $row->cl_to ) );
00157 break;
00158 }
00159 }
00160 } else {
00161
00162 $titles = array();
00163 while ( $row = $db->fetchObject( $res ) ) {
00164 if ( ++$count > $params['limit'] ) {
00165
00166
00167 $this->setContinueEnumParameter( 'continue', $row->cl_from .
00168 '|' . $this->keyToTitle( $row->cl_to ) );
00169 break;
00170 }
00171
00172 $titles[] = Title :: makeTitle( NS_CATEGORY, $row->cl_to );
00173 }
00174 $resultPageSet->populateFromTitles( $titles );
00175 }
00176
00177 $db->freeResult( $res );
00178 }
00179
00180 public function getAllowedParams() {
00181 return array (
00182 'prop' => array (
00183 ApiBase :: PARAM_ISMULTI => true,
00184 ApiBase :: PARAM_TYPE => array (
00185 'sortkey',
00186 'timestamp',
00187 'hidden',
00188 )
00189 ),
00190 'show' => array(
00191 ApiBase :: PARAM_ISMULTI => true,
00192 ApiBase :: PARAM_TYPE => array(
00193 'hidden',
00194 '!hidden',
00195 )
00196 ),
00197 'limit' => array(
00198 ApiBase :: PARAM_DFLT => 10,
00199 ApiBase :: PARAM_TYPE => 'limit',
00200 ApiBase :: PARAM_MIN => 1,
00201 ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
00202 ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
00203 ),
00204 'continue' => null,
00205 'categories' => array(
00206 ApiBase :: PARAM_ISMULTI => true,
00207 ),
00208 );
00209 }
00210
00211 public function getParamDescription() {
00212 return array (
00213 'prop' => 'Which additional properties to get for each category.',
00214 'limit' => 'How many categories to return',
00215 'show' => 'Which kind of categories to show',
00216 'continue' => 'When more results are available, use this to continue',
00217 'categories' => 'Only list these categories. Useful for checking whether a certain page is in a certain category',
00218 );
00219 }
00220
00221 public function getDescription() {
00222 return 'List all categories the page(s) belong to';
00223 }
00224
00225 public function getPossibleErrors() {
00226 return array_merge( parent::getPossibleErrors(), array(
00227 array( 'show' ),
00228 ) );
00229 }
00230
00231 protected function getExamples() {
00232 return array (
00233 "Get a list of categories [[Albert Einstein]] belongs to:",
00234 " api.php?action=query&prop=categories&titles=Albert%20Einstein",
00235 "Get information about all categories used in the [[Albert Einstein]]:",
00236 " api.php?action=query&generator=categories&titles=Albert%20Einstein&prop=info"
00237 );
00238 }
00239
00240 public function getVersion() {
00241 return __CLASS__ . ': $Id: ApiQueryCategories.php 69932 2010-07-26 08:03:21Z tstarling $';
00242 }
00243 }