MediaWiki  REL1_19
PrefixSearch.php
Go to the documentation of this file.
00001 <?php
00009 class PrefixSearch {
00018         public static function titleSearch( $search, $limit, $namespaces = array() ) {
00019                 $search = trim( $search );
00020                 if( $search == '' ) {
00021                         return array(); // Return empty result
00022                 }
00023                 $namespaces = self::validateNamespaces( $namespaces );
00024 
00025                 // Find a Title which is not an interwiki and is in NS_MAIN
00026                 $title = Title::newFromText( $search );
00027                 if( $title && $title->getInterwiki() == '' ) {
00028                         $ns = array($title->getNamespace());
00029                         if( $ns[0] == NS_MAIN ) {
00030                                 $ns = $namespaces; // no explicit prefix, use default namespaces
00031                         }
00032                         return self::searchBackend(
00033                                 $ns, $title->getText(), $limit );
00034                 }
00035 
00036                 // Is this a namespace prefix?
00037                 $title = Title::newFromText( $search . 'Dummy' );
00038                 if( $title && $title->getText() == 'Dummy'
00039                         && $title->getNamespace() != NS_MAIN
00040                         && $title->getInterwiki() == '' ) {
00041                         return self::searchBackend(
00042                                 array( $title->getNamespace() ), '', $limit );
00043                 }
00044 
00045                 return self::searchBackend( $namespaces, $search, $limit );
00046         }
00047 
00055         protected static function searchBackend( $namespaces, $search, $limit ) {
00056                 if( count( $namespaces ) == 1 ) {
00057                         $ns = $namespaces[0];
00058                         if( $ns == NS_MEDIA ) {
00059                                 $namespaces = array( NS_FILE );
00060                         } elseif( $ns == NS_SPECIAL ) {
00061                                 return self::specialSearch( $search, $limit );
00062                         }
00063                 }
00064                 $srchres = array();
00065                 if( wfRunHooks( 'PrefixSearchBackend', array( $namespaces, $search, $limit, &$srchres ) ) ) {
00066                         return self::defaultSearchBackend( $namespaces, $search, $limit );
00067                 }
00068                 return $srchres;
00069         }
00070 
00078         protected static function specialSearch( $search, $limit ) {
00079                 global $wgContLang;
00080 
00081                 # normalize searchKey, so aliases with spaces can be found - bug 25675
00082                 $search = str_replace( ' ', '_', $search );
00083 
00084                 $searchKey = $wgContLang->caseFold( $search );
00085 
00086                 // Unlike SpecialPage itself, we want the canonical forms of both
00087                 // canonical and alias title forms...
00088                 $keys = array();
00089                 foreach( SpecialPageFactory::getList() as $page => $class ) {
00090                         $keys[$wgContLang->caseFold( $page )] = $page;
00091                 }
00092 
00093                 foreach( $wgContLang->getSpecialPageAliases() as $page => $aliases ) {
00094                         if( !array_key_exists( $page, SpecialPageFactory::getList() ) ) {# bug 20885
00095                                 continue;
00096                         }
00097 
00098                         foreach( $aliases as $alias ) {
00099                                 $keys[$wgContLang->caseFold( $alias )] = $alias;
00100                         }
00101                 }
00102                 ksort( $keys );
00103 
00104                 $srchres = array();
00105                 foreach( $keys as $pageKey => $page ) {
00106                         if( $searchKey === '' || strpos( $pageKey, $searchKey ) === 0 ) {
00107                                 wfSuppressWarnings();
00108                                 // bug 27671: Don't use SpecialPage::getTitleFor() here because it
00109                                 // localizes its input leading to searches for e.g. Special:All
00110                                 // returning Spezial:MediaWiki-Systemnachrichten and returning
00111                                 // Spezial:Alle_Seiten twice when $wgLanguageCode == 'de'
00112                                 $srchres[] = Title::makeTitleSafe( NS_SPECIAL, $page )->getPrefixedText();
00113                                 wfRestoreWarnings();
00114                         }
00115 
00116                         if( count( $srchres ) >= $limit ) {
00117                                 break;
00118                         }
00119                 }
00120 
00121                 return $srchres;
00122         }
00123 
00135         protected static function defaultSearchBackend( $namespaces, $search, $limit ) {
00136                 $ns = array_shift( $namespaces ); // support only one namespace
00137                 if( in_array( NS_MAIN, $namespaces ) ) {
00138                         $ns = NS_MAIN; // if searching on many always default to main
00139                 }
00140 
00141                 // Prepare nested request
00142                 $req = new FauxRequest( array(
00143                         'action' => 'query',
00144                         'list' => 'allpages',
00145                         'apnamespace' => $ns,
00146                         'aplimit' => $limit,
00147                         'apprefix' => $search
00148                 ));
00149 
00150                 // Execute
00151                 $module = new ApiMain( $req );
00152                 $module->execute();
00153 
00154                 // Get resulting data
00155                 $data = $module->getResultData();
00156 
00157                 // Reformat useful data for future printing by JSON engine
00158                 $srchres = array ();
00159                 foreach ( (array)$data['query']['allpages'] as $pageinfo ) {
00160                         // Note: this data will no be printable by the xml engine
00161                         // because it does not support lists of unnamed items
00162                         $srchres[] = $pageinfo['title'];
00163                 }
00164 
00165                 return $srchres;
00166         }
00167 
00174         protected static function validateNamespaces( $namespaces ) {
00175                 global $wgContLang;
00176 
00177                 // We will look at each given namespace against wgContLang namespaces
00178                 $validNamespaces = $wgContLang->getNamespaces();
00179                 if( is_array( $namespaces ) && count( $namespaces ) > 0 ) {
00180                         $valid = array();
00181                         foreach ( $namespaces as $ns ) {
00182                                 if( is_numeric( $ns ) && array_key_exists( $ns, $validNamespaces ) ) {
00183                                         $valid[] = $ns;
00184                                 }
00185                         }
00186                         if( count( $valid ) > 0 ) {
00187                                 return $valid;
00188                         }
00189                 }
00190 
00191                 return array( NS_MAIN );
00192         }
00193 }