5 * Do a prefix search of titles and return a list of matching page names.
6 * @param string $search
8 * @param array $namespaces - used if query is not explicitely prefixed
9 * @return array of strings
11 public static function titleSearch( $search, $limit, $namespaces=array() ) {
12 $search = trim( $search );
14 return array(); // Return empty result
16 $namespaces = self
::validateNamespaces( $namespaces );
18 $title = Title
::newFromText( $search );
19 if( $title && $title->getInterwiki() == '' ) {
20 $ns = array($title->getNamespace());
22 $ns = $namespaces; // no explicit prefix, use default namespaces
23 return self
::searchBackend(
24 $ns, $title->getText(), $limit );
27 // Is this a namespace prefix?
28 $title = Title
::newFromText( $search . 'Dummy' );
29 if( $title && $title->getText() == 'Dummy'
30 && $title->getNamespace() != NS_MAIN
31 && $title->getInterwiki() == '' ) {
32 return self
::searchBackend(
33 array($title->getNamespace()), '', $limit );
36 return self
::searchBackend( $namespaces, $search, $limit );
41 * Do a prefix search of titles and return a list of matching page names.
42 * @param array $namespaces
43 * @param string $search
45 * @return array of strings
47 protected static function searchBackend( $namespaces, $search, $limit ) {
48 if( count($namespaces) == 1 ){
50 if( $ns == NS_MEDIA
) {
51 $namespaces = array(NS_IMAGE
);
52 } elseif( $ns == NS_SPECIAL
) {
53 return self
::specialSearch( $search, $limit );
57 if( wfRunHooks( 'PrefixSearchBackend', array( $namespaces, $search, $limit, &$srchres ) ) ) {
58 return self
::defaultSearchBackend( $namespaces, $search, $limit );
64 * Prefix search special-case for Special: namespace.
66 protected static function specialSearch( $search, $limit ) {
68 $searchKey = $wgContLang->caseFold( $search );
70 // Unlike SpecialPage itself, we want the canonical forms of both
71 // canonical and alias title forms...
72 SpecialPage
::initList();
73 SpecialPage
::initAliasList();
75 foreach( array_keys( SpecialPage
::$mList ) as $page ) {
76 $keys[$wgContLang->caseFold( $page )] = $page;
78 foreach( $wgContLang->getSpecialPageAliases() as $page => $aliases ) {
79 foreach( $aliases as $alias ) {
80 $keys[$wgContLang->caseFold( $alias )] = $alias;
86 foreach( $keys as $pageKey => $page ) {
87 if( $searchKey === '' ||
strpos( $pageKey, $searchKey ) === 0 ) {
88 $srchres[] = Title
::makeTitle( NS_SPECIAL
, $page )->getPrefixedText();
90 if( count( $srchres ) >= $limit ) {
98 * Unless overridden by PrefixSearchBackend hook...
99 * This is case-sensitive except the first letter (per $wgCapitalLinks)
101 * @param array $namespaces Namespaces to search in
102 * @param string $search term
103 * @param int $limit max number of items to return
104 * @return array of title strings
106 protected static function defaultSearchBackend( $namespaces, $search, $limit ) {
107 global $wgCapitalLinks, $wgContLang;
109 if( $wgCapitalLinks ) {
110 $search = $wgContLang->ucfirst( $search );
113 $ns = array_shift($namespaces); // support only one namespace
114 if( in_array(NS_MAIN
,$namespaces))
115 $ns = NS_MAIN
; // if searching on many always default to main
117 // Prepare nested request
118 $req = new FauxRequest(array (
120 'list' => 'allpages',
121 'apnamespace' => $ns,
123 'apprefix' => $search
127 $module = new ApiMain($req);
130 // Get resulting data
131 $data = $module->getResultData();
133 // Reformat useful data for future printing by JSON engine
135 foreach ($data['query']['allpages'] as & $pageinfo) {
136 // Note: this data will no be printable by the xml engine
137 // because it does not support lists of unnamed items
138 $srchres[] = $pageinfo['title'];
145 * Validate an array of numerical namespace indexes
147 * @param array $namespaces
149 protected static function validateNamespaces($namespaces){
151 $validNamespaces = $wgContLang->getNamespaces();
152 if( is_array($namespaces) && count($namespaces)>0 ){
154 foreach ($namespaces as $ns){
155 if( is_numeric($ns) && array_key_exists($ns, $validNamespaces) )
158 if( count($valid) > 0 )
162 return array( NS_MAIN
);