MediaWiki  REL1_22
PrefixSearch.php
Go to the documentation of this file.
00001 <?php
00029 class PrefixSearch {
00038     public static function titleSearch( $search, $limit, $namespaces = array() ) {
00039         $search = trim( $search );
00040         if ( $search == '' ) {
00041             return array(); // Return empty result
00042         }
00043         $namespaces = self::validateNamespaces( $namespaces );
00044 
00045         // Find a Title which is not an interwiki and is in NS_MAIN
00046         $title = Title::newFromText( $search );
00047         if ( $title && $title->getInterwiki() == '' ) {
00048             $ns = array( $title->getNamespace() );
00049             if ( $ns[0] == NS_MAIN ) {
00050                 $ns = $namespaces; // no explicit prefix, use default namespaces
00051             }
00052             return self::searchBackend(
00053                 $ns, $title->getText(), $limit );
00054         }
00055 
00056         // Is this a namespace prefix?
00057         $title = Title::newFromText( $search . 'Dummy' );
00058         if ( $title && $title->getText() == 'Dummy'
00059             && $title->getNamespace() != NS_MAIN
00060             && $title->getInterwiki() == '' ) {
00061             return self::searchBackend(
00062                 array( $title->getNamespace() ), '', $limit );
00063         }
00064 
00065         return self::searchBackend( $namespaces, $search, $limit );
00066     }
00067 
00075     protected static function searchBackend( $namespaces, $search, $limit ) {
00076         if ( count( $namespaces ) == 1 ) {
00077             $ns = $namespaces[0];
00078             if ( $ns == NS_MEDIA ) {
00079                 $namespaces = array( NS_FILE );
00080             } elseif ( $ns == NS_SPECIAL ) {
00081                 return self::specialSearch( $search, $limit );
00082             }
00083         }
00084         $srchres = array();
00085         if ( wfRunHooks( 'PrefixSearchBackend', array( $namespaces, $search, $limit, &$srchres ) ) ) {
00086             return self::defaultSearchBackend( $namespaces, $search, $limit );
00087         }
00088         return $srchres;
00089     }
00090 
00098     protected static function specialSearch( $search, $limit ) {
00099         global $wgContLang;
00100 
00101         # normalize searchKey, so aliases with spaces can be found - bug 25675
00102         $search = str_replace( ' ', '_', $search );
00103 
00104         $searchKey = $wgContLang->caseFold( $search );
00105 
00106         // Unlike SpecialPage itself, we want the canonical forms of both
00107         // canonical and alias title forms...
00108         $keys = array();
00109         foreach ( SpecialPageFactory::getList() as $page => $class ) {
00110             $keys[$wgContLang->caseFold( $page )] = $page;
00111         }
00112 
00113         foreach ( $wgContLang->getSpecialPageAliases() as $page => $aliases ) {
00114             if ( !array_key_exists( $page, SpecialPageFactory::getList() ) ) {# bug 20885
00115                 continue;
00116             }
00117 
00118             foreach ( $aliases as $alias ) {
00119                 $keys[$wgContLang->caseFold( $alias )] = $alias;
00120             }
00121         }
00122         ksort( $keys );
00123 
00124         $srchres = array();
00125         foreach ( $keys as $pageKey => $page ) {
00126             if ( $searchKey === '' || strpos( $pageKey, $searchKey ) === 0 ) {
00127                 wfSuppressWarnings();
00128                 // bug 27671: Don't use SpecialPage::getTitleFor() here because it
00129                 // localizes its input leading to searches for e.g. Special:All
00130                 // returning Spezial:MediaWiki-Systemnachrichten and returning
00131                 // Spezial:Alle_Seiten twice when $wgLanguageCode == 'de'
00132                 $srchres[] = Title::makeTitleSafe( NS_SPECIAL, $page )->getPrefixedText();
00133                 wfRestoreWarnings();
00134             }
00135 
00136             if ( count( $srchres ) >= $limit ) {
00137                 break;
00138             }
00139         }
00140 
00141         return $srchres;
00142     }
00143 
00155     protected static function defaultSearchBackend( $namespaces, $search, $limit ) {
00156         $ns = array_shift( $namespaces ); // support only one namespace
00157         if ( in_array( NS_MAIN, $namespaces ) ) {
00158             $ns = NS_MAIN; // if searching on many always default to main
00159         }
00160 
00161         // Prepare nested request
00162         $req = new FauxRequest( array(
00163             'action' => 'query',
00164             'list' => 'allpages',
00165             'apnamespace' => $ns,
00166             'aplimit' => $limit,
00167             'apprefix' => $search
00168         ));
00169 
00170         // Execute
00171         $module = new ApiMain( $req );
00172         $module->execute();
00173 
00174         // Get resulting data
00175         $data = $module->getResultData();
00176 
00177         // Reformat useful data for future printing by JSON engine
00178         $srchres = array();
00179         foreach ( (array)$data['query']['allpages'] as $pageinfo ) {
00180             // Note: this data will no be printable by the xml engine
00181             // because it does not support lists of unnamed items
00182             $srchres[] = $pageinfo['title'];
00183         }
00184 
00185         return $srchres;
00186     }
00187 
00194     protected static function validateNamespaces( $namespaces ) {
00195         global $wgContLang;
00196 
00197         // We will look at each given namespace against wgContLang namespaces
00198         $validNamespaces = $wgContLang->getNamespaces();
00199         if ( is_array( $namespaces ) && count( $namespaces ) > 0 ) {
00200             $valid = array();
00201             foreach ( $namespaces as $ns ) {
00202                 if ( is_numeric( $ns ) && array_key_exists( $ns, $validNamespaces ) ) {
00203                     $valid[] = $ns;
00204                 }
00205             }
00206             if ( count( $valid ) > 0 ) {
00207                 return $valid;
00208             }
00209         }
00210 
00211         return array( NS_MAIN );
00212     }
00213 }