X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fapi%2FApiQueryExtLinksUsage.php;h=4294f0ad8c857b2067083b30a5646f01bb9b7225;hb=a5c7fd0db2d962834127ec2362d0dfe8ef6852d5;hp=fc5d8a042598552bd871bd1f2ecc221264986daa;hpb=925c20a9ca669c67cc44f4468d0e0f3b33b94213;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/api/ApiQueryExtLinksUsage.php b/includes/api/ApiQueryExtLinksUsage.php index fc5d8a0425..4294f0ad8c 100644 --- a/includes/api/ApiQueryExtLinksUsage.php +++ b/includes/api/ApiQueryExtLinksUsage.php @@ -47,12 +47,12 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase { */ private function run( $resultPageSet = null ) { $params = $this->extractRequestParams(); + $db = $this->getDB(); $query = $params['query']; $protocol = self::getProtocolPrefix( $params['protocol'] ); - $this->addTables( [ 'page', 'externallinks' ] ); // must be in this order for 'USE INDEX' - $this->addOption( 'USE INDEX', 'el_index' ); + $this->addTables( [ 'page', 'externallinks' ] ); $this->addWhere( 'page_id=el_from' ); $miser_ns = []; @@ -62,15 +62,46 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase { $this->addWhereFld( 'page_namespace', $params['namespace'] ); } - // Normalize query to match the normalization applied for the externallinks table - $query = Parser::normalizeLinkUrl( $query ); + $orderBy = []; - $whereQuery = $this->prepareUrlQuerySearchString( $query, $protocol ); + if ( $query !== null && $query !== '' ) { + if ( $protocol === null ) { + $protocol = 'http://'; + } + + // Normalize query to match the normalization applied for the externallinks table + $query = Parser::normalizeLinkUrl( $protocol . $query ); + + $conds = LinkFilter::getQueryConditions( $query, [ + 'protocol' => '', + 'oneWildcard' => true, + 'db' => $db + ] ); + if ( !$conds ) { + $this->dieWithError( 'apierror-badquery' ); + } + $this->addWhere( $conds ); + if ( !isset( $conds['el_index_60'] ) ) { + $orderBy[] = 'el_index_60'; + } + } else { + $orderBy[] = 'el_index_60'; - if ( $whereQuery !== null ) { - $this->addWhere( $whereQuery ); + if ( $protocol !== null ) { + $this->addWhere( 'el_index_60' . $db->buildLike( "$protocol", $db->anyString() ) ); + } else { + // We're querying all protocols, filter out duplicate protocol-relative links + $this->addWhere( $db->makeList( [ + 'el_to NOT' . $db->buildLike( '//', $db->anyString() ), + 'el_index_60 ' . $db->buildLike( 'http://', $db->anyString() ), + ], LIST_OR ) ); + } } + $orderBy[] = 'el_id'; + $this->addOption( 'ORDER BY', $orderBy ); + $this->addFields( $orderBy ); // Make sure + $prop = array_flip( $params['prop'] ); $fld_ids = isset( $prop['ids'] ); $fld_title = isset( $prop['title'] ); @@ -88,10 +119,19 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase { } $limit = $params['limit']; - $offset = $params['offset']; $this->addOption( 'LIMIT', $limit + 1 ); - if ( isset( $offset ) ) { - $this->addOption( 'OFFSET', $offset ); + + if ( $params['continue'] !== null ) { + $cont = explode( '|', $params['continue'] ); + $this->dieContinueUsageIf( count( $cont ) !== count( $orderBy ) ); + $i = count( $cont ) - 1; + $cond = $orderBy[$i] . ' >= ' . $db->addQuotes( rawurldecode( $cont[$i] ) ); + while ( $i-- > 0 ) { + $field = $orderBy[$i]; + $v = $db->addQuotes( rawurldecode( $cont[$i] ) ); + $cond = "($field > $v OR ($field = $v AND $cond))"; + } + $this->addWhere( $cond ); } $res = $this->select( __METHOD__ ); @@ -102,7 +142,7 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase { if ( ++$count > $limit ) { // We've reached the one extra which shows that there are // additional pages to be had. Stop here... - $this->setContinueEnumParameter( 'offset', $offset + $limit ); + $this->setContinue( $orderBy, $row ); break; } @@ -115,7 +155,7 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase { ApiResult::META_TYPE => 'assoc', ]; if ( $fld_ids ) { - $vals['pageid'] = intval( $row->page_id ); + $vals['pageid'] = (int)$row->page_id; } if ( $fld_title ) { $title = Title::makeTitle( $row->page_namespace, $row->page_title ); @@ -131,7 +171,7 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase { } $fit = $result->addValue( [ 'query', $this->getModuleName() ], null, $vals ); if ( !$fit ) { - $this->setContinueEnumParameter( 'offset', $offset + $count - 1 ); + $this->setContinue( $orderBy, $row ); break; } } else { @@ -145,6 +185,14 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase { } } + private function setContinue( $orderBy, $row ) { + $fields = []; + foreach ( $orderBy as $field ) { + $fields[] = strtr( $row->$field, [ '%' => '%25', '|' => '%7C' ] ); + } + $this->setContinueEnumParameter( 'continue', implode( '|', $fields ) ); + } + public function getAllowedParams() { $ret = [ 'prop' => [ @@ -157,8 +205,7 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase { ], ApiBase::PARAM_HELP_MSG_PER_VALUE => [], ], - 'offset' => [ - ApiBase::PARAM_TYPE => 'integer', + 'continue' => [ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue', ], 'protocol' => [