MediaWiki  REL1_20
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(), $this->msg( 'linksearch' )->text() ) .
00092                         Xml::inputLabel( $this->msg( 'linksearch-pat' )->text(), 'target', 'target', 50, $target ) . ' ';
00093                 if ( !$wgMiserMode ) {
00094                         $s .= Html::namespaceSelector(
00095                                 array(
00096                                         'selected' => $namespace,
00097                                         'all' => '',
00098                                         'label' => $this->msg( 'linksearch-ns' )->text()
00099                                 ), array(
00100                                         'name'  => 'namespace',
00101                                         'id'    => 'namespace',
00102                                         'class' => 'namespaceselector',
00103                                 )
00104                         );
00105                 }
00106                 $s .=   Xml::submitButton( $this->msg( 'linksearch-ok' )->text() ) .
00107                         '</fieldset>' .
00108                         Xml::closeElement( 'form' );
00109                 $out->addHTML( $s );
00110 
00111                 if( $target != '' ) {
00112                         $this->setParams( array(
00113                                 'query' => $target2,
00114                                 'namespace' => $namespace,
00115                                 'protocol' => $protocol ) );
00116                         parent::execute( $par );
00117                         if( $this->mMungedQuery === false )
00118                                 $out->addWikiMsg( 'linksearch-error' );
00119                 }
00120         }
00121 
00126         function isSyndicated() {
00127                 return false;
00128         }
00129 
00135         static function mungeQuery( $query, $prot ) {
00136                 $field = 'el_index';
00137                 $rv = LinkFilter::makeLikeArray( $query , $prot );
00138                 if ( $rv === false ) {
00139                         // LinkFilter doesn't handle wildcard in IP, so we'll have to munge here.
00140                         if (preg_match('/^(:?[0-9]{1,3}\.)+\*\s*$|^(:?[0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]*\*\s*$/', $query)) {
00141                                 $dbr = wfGetDB( DB_SLAVE );
00142                                 $rv = array( $prot . rtrim( $query, " \t*" ), $dbr->anyString() );
00143                                 $field = 'el_to';
00144                         }
00145                 }
00146                 return array( $rv, $field );
00147         }
00148 
00149         function linkParameters() {
00150                 global $wgMiserMode;
00151                 $params = array();
00152                 $params['target'] = $this->mProt . $this->mQuery;
00153                 if( isset( $this->mNs ) && !$wgMiserMode ) {
00154                         $params['namespace'] = $this->mNs;
00155                 }
00156                 return $params;
00157         }
00158 
00159         function getQueryInfo() {
00160                 global $wgMiserMode;
00161                 $dbr = wfGetDB( DB_SLAVE );
00162                 // strip everything past first wildcard, so that
00163                 // index-based-only lookup would be done
00164                 list( $this->mMungedQuery, $clause ) = self::mungeQuery(
00165                                 $this->mQuery, $this->mProt );
00166                 if( $this->mMungedQuery === false )
00167                         // Invalid query; return no results
00168                         return array( 'tables' => 'page', 'fields' => 'page_id', 'conds' => '0=1' );
00169 
00170                 $stripped = LinkFilter::keepOneWildcard( $this->mMungedQuery );
00171                 $like = $dbr->buildLike( $stripped );
00172                 $retval = array (
00173                         'tables' => array ( 'page', 'externallinks' ),
00174                         'fields' => array ( 'namespace' => 'page_namespace',
00175                                         'title' => 'page_title',
00176                                         'value' => 'el_index', 'url' => 'el_to' ),
00177                         'conds' => array ( 'page_id = el_from',
00178                                         "$clause $like" ),
00179                         'options' => array( 'USE INDEX' => $clause )
00180                 );
00181                 if ( isset( $this->mNs ) && !$wgMiserMode ) {
00182                         $retval['conds']['page_namespace'] = $this->mNs;
00183                 }
00184                 return $retval;
00185         }
00186 
00187         function formatResult( $skin, $result ) {
00188                 $title = Title::makeTitle( $result->namespace, $result->title );
00189                 $url = $result->url;
00190                 $pageLink = Linker::linkKnown( $title );
00191                 $urlLink = Linker::makeExternalLink( $url, $url );
00192 
00193                 return $this->msg( 'linksearch-line' )->rawParams( $urlLink, $pageLink )->escaped();
00194         }
00195 
00199         function doQuery( $offset = false, $limit = false ) {
00200                 list( $this->mMungedQuery,  ) = LinkSearchPage::mungeQuery( $this->mQuery, $this->mProt );
00201                 if( $this->mMungedQuery === false ) {
00202                         $this->getOutput()->addWikiMsg( 'linksearch-error' );
00203                 } else {
00204                         // For debugging
00205                         // Generates invalid xhtml with patterns that contain --
00206                         //$this->getOutput()->addHTML( "\n<!-- " . htmlspecialchars( $this->mMungedQuery ) . " -->\n" );
00207                         parent::doQuery( $offset, $limit );
00208                 }
00209         }
00210 
00218         function getOrderFields() {
00219                 return array();
00220         }
00221 }