MediaWiki  REL1_19
SpecialLinkSearch.php
Go to the documentation of this file.
00001 <?php
00030 class LinkSearchPage extends QueryPage {
00031         function setParams( $params ) {
00032                 $this->mQuery = $params['query'];
00033                 $this->mNs = $params['namespace'];
00034                 $this->mProt = $params['protocol'];
00035         }
00036 
00037         function __construct( $name = 'LinkSearch' ) {
00038                 parent::__construct( $name );
00039         }
00040 
00041         function isCacheable() {
00042                 return false;
00043         }
00044 
00045         function execute( $par ) {
00046                 global $wgUrlProtocols, $wgMiserMode;
00047 
00048                 $this->setHeaders();
00049                 $this->outputHeader();
00050 
00051                 $out = $this->getOutput();
00052                 $out->allowClickjacking();
00053 
00054                 $request = $this->getRequest();
00055                 $target = $request->getVal( 'target', $par );
00056                 $namespace = $request->getIntorNull( 'namespace', null );
00057 
00058                 $protocols_list = array();
00059                 foreach( $wgUrlProtocols as $prot ) {
00060                         if ( $prot !== '//' ) {
00061                                 $protocols_list[] = $prot;
00062                         }
00063                 }
00064 
00065                 $target2 = $target;
00066                 $protocol = '';
00067                 $pr_sl = strpos($target2, '//' );
00068                 $pr_cl = strpos($target2, ':' );
00069                 if ( $pr_sl ) {
00070                         // For protocols with '//'
00071                         $protocol = substr( $target2, 0 , $pr_sl+2 );
00072                         $target2 = substr( $target2, $pr_sl+2 );
00073                 } elseif ( !$pr_sl && $pr_cl ) {
00074                         // For protocols without '//' like 'mailto:'
00075                         $protocol = substr( $target2, 0 , $pr_cl+1 );
00076                         $target2 = substr( $target2, $pr_cl+1 );
00077                 } elseif ( $protocol == '' && $target2 != '' ) {
00078                         // default
00079                         $protocol = 'http://';
00080                 }
00081                 if ( $protocol != '' && !in_array( $protocol, $protocols_list ) ) {
00082                         // unsupported protocol, show original search request
00083                         $target2 = $target;
00084                         $protocol = '';
00085                 }
00086 
00087                 $out->addWikiMsg( 'linksearch-text', '<nowiki>' . $this->getLanguage()->commaList( $protocols_list ) . '</nowiki>' );
00088                 $s = Xml::openElement( 'form', array( 'id' => 'mw-linksearch-form', 'method' => 'get', 'action' => $GLOBALS['wgScript'] ) ) .
00089                         Html::hidden( 'title', $this->getTitle()->getPrefixedDbKey() ) .
00090                         '<fieldset>' .
00091                         Xml::element( 'legend', array(), wfMsg( 'linksearch' ) ) .
00092                         Xml::inputLabel( wfMsg( 'linksearch-pat' ), 'target', 'target', 50, $target ) . ' ';
00093                 if ( !$wgMiserMode ) {
00094                         $s .= Xml::label( wfMsg( 'linksearch-ns' ), 'namespace' ) . ' ' .
00095                                 Xml::namespaceSelector( $namespace, '' );
00096                 }
00097                 $s .=   Xml::submitButton( wfMsg( 'linksearch-ok' ) ) .
00098                         '</fieldset>' .
00099                         Xml::closeElement( 'form' );
00100                 $out->addHTML( $s );
00101 
00102                 if( $target != '' ) {
00103                         $this->setParams( array(
00104                                 'query' => $target2,
00105                                 'namespace' => $namespace,
00106                                 'protocol' => $protocol ) );
00107                         parent::execute( $par );
00108                         if( $this->mMungedQuery === false )
00109                                 $out->addWikiMsg( 'linksearch-error' );
00110                 }
00111         }
00112 
00116         function isSyndicated() {
00117                 return false;
00118         }
00119 
00125         static function mungeQuery( $query, $prot ) {
00126                 $field = 'el_index';
00127                 $rv = LinkFilter::makeLikeArray( $query , $prot );
00128                 if ( $rv === false ) {
00129                         // LinkFilter doesn't handle wildcard in IP, so we'll have to munge here.
00130                         if (preg_match('/^(:?[0-9]{1,3}\.)+\*\s*$|^(:?[0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]*\*\s*$/', $query)) {
00131                                 $dbr = wfGetDB( DB_SLAVE );
00132                                 $rv = array( $prot . rtrim( $query, " \t*" ), $dbr->anyString() );
00133                                 $field = 'el_to';
00134                         }
00135                 }
00136                 return array( $rv, $field );
00137         }
00138 
00139         function linkParameters() {
00140                 global $wgMiserMode;
00141                 $params = array();
00142                 $params['target'] = $this->mProt . $this->mQuery;
00143                 if( isset( $this->mNs ) && !$wgMiserMode ) {
00144                         $params['namespace'] = $this->mNs;
00145                 }
00146                 return $params;
00147         }
00148 
00149         function getQueryInfo() {
00150                 global $wgMiserMode;
00151                 $dbr = wfGetDB( DB_SLAVE );
00152                 // strip everything past first wildcard, so that
00153                 // index-based-only lookup would be done
00154                 list( $this->mMungedQuery, $clause ) = self::mungeQuery(
00155                                 $this->mQuery, $this->mProt );
00156                 if( $this->mMungedQuery === false )
00157                         // Invalid query; return no results
00158                         return array( 'tables' => 'page', 'fields' => 'page_id', 'conds' => '0=1' );
00159 
00160                 $stripped = LinkFilter::keepOneWildcard( $this->mMungedQuery );
00161                 $like = $dbr->buildLike( $stripped );
00162                 $retval = array (
00163                         'tables' => array ( 'page', 'externallinks' ),
00164                         'fields' => array ( 'page_namespace AS namespace',
00165                                         'page_title AS title',
00166                                         'el_index AS value', 'el_to AS url' ),
00167                         'conds' => array ( 'page_id = el_from',
00168                                         "$clause $like" ),
00169                         'options' => array( 'USE INDEX' => $clause )
00170                 );
00171                 if ( isset( $this->mNs ) && !$wgMiserMode ) {
00172                         $retval['conds']['page_namespace'] = $this->mNs;
00173                 }
00174                 return $retval;
00175         }
00176 
00177         function formatResult( $skin, $result ) {
00178                 $title = Title::makeTitle( $result->namespace, $result->title );
00179                 $url = $result->url;
00180                 $pageLink = Linker::linkKnown( $title );
00181                 $urlLink = Linker::makeExternalLink( $url, $url );
00182 
00183                 return wfMsgHtml( 'linksearch-line', $urlLink, $pageLink );
00184         }
00185 
00189         function doQuery( $offset = false, $limit = false ) {
00190                 list( $this->mMungedQuery,  ) = LinkSearchPage::mungeQuery( $this->mQuery, $this->mProt );
00191                 if( $this->mMungedQuery === false ) {
00192                         $this->getOutput()->addWikiMsg( 'linksearch-error' );
00193                 } else {
00194                         // For debugging
00195                         // Generates invalid xhtml with patterns that contain --
00196                         //$this->getOutput()->addHTML( "\n<!-- " . htmlspecialchars( $this->mMungedQuery ) . " -->\n" );
00197                         parent::doQuery( $offset, $limit );
00198                 }
00199         }
00200 
00207         function getOrderFields() {
00208                 return array();
00209         }
00210 }