Do not insert page titles into querycache.qc_value
[lhc/web/wiklou.git] / includes / specials / SpecialLinkSearch.php
index ef95254..60aedda 100644 (file)
@@ -29,9 +29,15 @@ use Wikimedia\Rdbms\IDatabase;
  * Special:LinkSearch to search the external-links table.
  * @ingroup SpecialPage
  */
-class LinkSearchPage extends QueryPage {
+class SpecialLinkSearch extends QueryPage {
        /** @var array|bool */
        private $mungedQuery = false;
+       /** @var string|null */
+       private $mQuery;
+       /** @var int|null */
+       private $mNs;
+       /** @var string|null */
+       private $mProt;
 
        function setParams( $params ) {
                $this->mQuery = $params['query'];
@@ -69,7 +75,7 @@ class LinkSearchPage extends QueryPage {
                        }
                }
 
-               $target2 = $target;
+               $target2 = Parser::normalizeLinkUrl( $target );
                // Get protocol, default is http://
                $protocol = 'http://';
                $bits = wfParseUrl( $target );
@@ -128,7 +134,7 @@ class LinkSearchPage extends QueryPage {
 
                if ( $target != '' ) {
                        $this->setParams( [
-                               'query' => Parser::normalizeLinkUrl( $target2 ),
+                               'query' => $target2,
                                'namespace' => $namespace,
                                'protocol' => $protocol ] );
                        parent::execute( $par );
@@ -146,37 +152,6 @@ class LinkSearchPage extends QueryPage {
                return false;
        }
 
-       /**
-        * Return an appropriately formatted LIKE query and the clause
-        *
-        * @param string $query Search pattern to search for
-        * @param string $prot Protocol, e.g. 'http://'
-        *
-        * @return array
-        */
-       static function mungeQuery( $query, $prot ) {
-               $field = 'el_index';
-               $dbr = wfGetDB( DB_REPLICA );
-
-               if ( $query === '*' && $prot !== '' ) {
-                       // Allow queries like 'ftp://*' to find all ftp links
-                       $rv = [ $prot, $dbr->anyString() ];
-               } else {
-                       $rv = LinkFilter::makeLikeArray( $query, $prot );
-               }
-
-               if ( $rv === false ) {
-                       // LinkFilter doesn't handle wildcard in IP, so we'll have to munge here.
-                       $pattern = '/^(:?[0-9]{1,3}\.)+\*\s*$|^(:?[0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]*\*\s*$/';
-                       if ( preg_match( $pattern, $query ) ) {
-                               $rv = [ $prot . rtrim( $query, " \t*" ), $dbr->anyString() ];
-                               $field = 'el_to';
-                       }
-               }
-
-               return [ $rv, $field ];
-       }
-
        function linkParameters() {
                $params = [];
                $params['target'] = $this->mProt . $this->mQuery;
@@ -189,16 +164,29 @@ class LinkSearchPage extends QueryPage {
 
        public function getQueryInfo() {
                $dbr = wfGetDB( DB_REPLICA );
-               // strip everything past first wildcard, so that
-               // index-based-only lookup would be done
-               list( $this->mungedQuery, $clause ) = self::mungeQuery( $this->mQuery, $this->mProt );
+
+               if ( $this->mQuery === '*' && $this->mProt !== '' ) {
+                       $this->mungedQuery = [
+                               'el_index_60' . $dbr->buildLike( $this->mProt, $dbr->anyString() ),
+                       ];
+               } else {
+                       $this->mungedQuery = LinkFilter::getQueryConditions( $this->mQuery, [
+                               'protocol' => $this->mProt,
+                               'oneWildcard' => true,
+                               'db' => $dbr
+                       ] );
+               }
                if ( $this->mungedQuery === false ) {
                        // Invalid query; return no results
                        return [ 'tables' => 'page', 'fields' => 'page_id', 'conds' => '0=1' ];
                }
 
-               $stripped = LinkFilter::keepOneWildcard( $this->mungedQuery );
-               $like = $dbr->buildLike( $stripped );
+               $orderBy = [];
+               if ( !isset( $this->mungedQuery['el_index_60'] ) ) {
+                       $orderBy[] = 'el_index_60';
+               }
+               $orderBy[] = 'el_id';
+
                $retval = [
                        'tables' => [ 'page', 'externallinks' ],
                        'fields' => [
@@ -207,11 +195,13 @@ class LinkSearchPage extends QueryPage {
                                'value' => 'el_index',
                                'url' => 'el_to'
                        ],
-                       'conds' => [
-                               'page_id = el_from',
-                               "$clause $like"
-                       ],
-                       'options' => [ 'USE INDEX' => $clause ]
+                       'conds' => array_merge(
+                               [
+                                       'page_id = el_from',
+                               ],
+                               $this->mungedQuery
+                       ),
+                       'options' => [ 'ORDER BY' => $orderBy ]
                ];
 
                if ( $this->mNs !== null && !$this->getConfig()->get( 'MiserMode' ) ) {
@@ -248,9 +238,7 @@ class LinkSearchPage extends QueryPage {
 
        /**
         * Override to squash the ORDER BY.
-        * We do a truncated index search, so the optimizer won't trust
-        * it as good enough for optimizing sort. The implicit ordering
-        * from the scan will usually do well enough for our needs.
+        * Not much point in descending order here.
         * @return array
         */
        function getOrderFields() {