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
00034 class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase {
00035
00036 public function __construct( $query, $moduleName ) {
00037 parent :: __construct( $query, $moduleName, 'eu' );
00038 }
00039
00040 public function execute() {
00041 $this->run();
00042 }
00043
00044 public function getCacheMode( $params ) {
00045 return 'public';
00046 }
00047
00048 public function executeGenerator( $resultPageSet ) {
00049 $this->run( $resultPageSet );
00050 }
00051
00052 private function run( $resultPageSet = null ) {
00053
00054 $params = $this->extractRequestParams();
00055
00056 $protocol = $params['protocol'];
00057 $query = $params['query'];
00058
00059
00060 global $wgUrlProtocols;
00061 if ( $protocol && !in_array( $protocol, $wgUrlProtocols ) )
00062 {
00063 foreach ( $wgUrlProtocols as $p ) {
00064 if ( substr( $p, 0, strlen( $protocol ) ) === $protocol ) {
00065 $protocol = $p;
00066 break;
00067 }
00068 }
00069 }
00070 else
00071 $protocol = null;
00072
00073 $db = $this->getDB();
00074 $this->addTables( array( 'page', 'externallinks' ) );
00075 $this->addOption( 'USE INDEX', 'el_index' );
00076 $this->addWhere( 'page_id=el_from' );
00077 $this->addWhereFld( 'page_namespace', $params['namespace'] );
00078
00079 if ( !is_null( $query ) || $query != '' )
00080 {
00081 if ( is_null( $protocol ) )
00082 $protocol = 'http://';
00083
00084 $likeQuery = LinkFilter::makeLikeArray( $query, $protocol );
00085 if ( !$likeQuery )
00086 $this->dieUsage( 'Invalid query', 'bad_query' );
00087
00088 $likeQuery = LinkFilter::keepOneWildcard( $likeQuery );
00089 $this->addWhere( 'el_index ' . $db->buildLike( $likeQuery ) );
00090 }
00091 else if ( !is_null( $protocol ) )
00092 $this->addWhere( 'el_index ' . $db->buildLike( "$protocol", $db->anyString() ) );
00093
00094 $prop = array_flip( $params['prop'] );
00095 $fld_ids = isset( $prop['ids'] );
00096 $fld_title = isset( $prop['title'] );
00097 $fld_url = isset( $prop['url'] );
00098
00099 if ( is_null( $resultPageSet ) ) {
00100 $this->addFields( array (
00101 'page_id',
00102 'page_namespace',
00103 'page_title'
00104 ) );
00105 $this->addFieldsIf( 'el_to', $fld_url );
00106 } else {
00107 $this->addFields( $resultPageSet->getPageTableFields() );
00108 }
00109
00110 $limit = $params['limit'];
00111 $offset = $params['offset'];
00112 $this->addOption( 'LIMIT', $limit + 1 );
00113 if ( isset ( $offset ) )
00114 $this->addOption( 'OFFSET', $offset );
00115
00116 $res = $this->select( __METHOD__ );
00117
00118 $result = $this->getResult();
00119 $count = 0;
00120 while ( $row = $db->fetchObject( $res ) ) {
00121 if ( ++ $count > $limit ) {
00122
00123 $this->setContinueEnumParameter( 'offset', $offset + $limit );
00124 break;
00125 }
00126
00127 if ( is_null( $resultPageSet ) ) {
00128 $vals = array();
00129 if ( $fld_ids )
00130 $vals['pageid'] = intval( $row->page_id );
00131 if ( $fld_title ) {
00132 $title = Title :: makeTitle( $row->page_namespace, $row->page_title );
00133 ApiQueryBase::addTitleInfo( $vals, $title );
00134 }
00135 if ( $fld_url )
00136 $vals['url'] = $row->el_to;
00137 $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $vals );
00138 if ( !$fit )
00139 {
00140 $this->setContinueEnumParameter( 'offset', $offset + $count - 1 );
00141 break;
00142 }
00143 } else {
00144 $resultPageSet->processDbRow( $row );
00145 }
00146 }
00147 $db->freeResult( $res );
00148
00149 if ( is_null( $resultPageSet ) ) {
00150 $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ),
00151 $this->getModulePrefix() );
00152 }
00153 }
00154
00155 public function getAllowedParams() {
00156 global $wgUrlProtocols;
00157 $protocols = array( '' );
00158 foreach ( $wgUrlProtocols as $p ) {
00159 $protocols[] = substr( $p, 0, strpos( $p, ':' ) );
00160 }
00161
00162 return array (
00163 'prop' => array (
00164 ApiBase :: PARAM_ISMULTI => true,
00165 ApiBase :: PARAM_DFLT => 'ids|title|url',
00166 ApiBase :: PARAM_TYPE => array (
00167 'ids',
00168 'title',
00169 'url'
00170 )
00171 ),
00172 'offset' => array (
00173 ApiBase :: PARAM_TYPE => 'integer'
00174 ),
00175 'protocol' => array (
00176 ApiBase :: PARAM_TYPE => $protocols,
00177 ApiBase :: PARAM_DFLT => '',
00178 ),
00179 'query' => null,
00180 'namespace' => array (
00181 ApiBase :: PARAM_ISMULTI => true,
00182 ApiBase :: PARAM_TYPE => 'namespace'
00183 ),
00184 'limit' => array (
00185 ApiBase :: PARAM_DFLT => 10,
00186 ApiBase :: PARAM_TYPE => 'limit',
00187 ApiBase :: PARAM_MIN => 1,
00188 ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
00189 ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
00190 )
00191 );
00192 }
00193
00194 public function getParamDescription() {
00195 return array (
00196 'prop' => 'What pieces of information to include',
00197 'offset' => 'Used for paging. Use the value returned for "continue"',
00198 'protocol' => array( 'Protocol of the url. If empty and euquery set, the protocol is http.',
00199 'Leave both this and euquery empty to list all external links' ),
00200 'query' => 'Search string without protocol. See [[Special:LinkSearch]]. Leave empty to list all external links',
00201 'namespace' => 'The page namespace(s) to enumerate.',
00202 'limit' => 'How many pages to return.'
00203 );
00204 }
00205
00206 public function getDescription() {
00207 return 'Enumerate pages that contain a given URL';
00208 }
00209
00210 public function getPossibleErrors() {
00211 return array_merge( parent::getPossibleErrors(), array(
00212 array( 'code' => 'bad_query', 'info' => 'Invalid query' ),
00213 ) );
00214 }
00215
00216 protected function getExamples() {
00217 return array (
00218 'api.php?action=query&list=exturlusage&euquery=www.mediawiki.org'
00219 );
00220 }
00221
00222 public function getVersion() {
00223 return __CLASS__ . ': $Id: ApiQueryExtLinksUsage.php 69932 2010-07-26 08:03:21Z tstarling $';
00224 }
00225 }