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