]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - includes/PrefixSearch.php
MediaWiki 1.15.4-scripts
[autoinstalls/mediawiki.git] / includes / PrefixSearch.php
1 <?php
2
3 /**
4  * PrefixSearch - Handles searching prefixes of titles and finding any page
5  * names that match. Used largely by the OpenSearch implementation.
6  * 
7  * @ingroup Search
8  */
9
10 class PrefixSearch {
11         /**
12          * Do a prefix search of titles and return a list of matching page names.
13          * @param string $search
14          * @param int $limit
15          * @param array $namespaces - used if query is not explicitely prefixed
16          * @return array of strings
17          */
18         public static function titleSearch( $search, $limit, $namespaces=array() ) {
19                 $search = trim( $search );
20                 if( $search == '' ) {
21                         return array(); // Return empty result
22                 }
23                 $namespaces = self::validateNamespaces( $namespaces );
24                 
25                 $title = Title::newFromText( $search );
26                 if( $title && $title->getInterwiki() == '' ) {
27                         $ns = array($title->getNamespace());
28                         if($ns[0] == NS_MAIN) 
29                                 $ns = $namespaces; // no explicit prefix, use default namespaces
30                         return self::searchBackend(
31                                 $ns, $title->getText(), $limit );
32                 }
33
34                 // Is this a namespace prefix?
35                 $title = Title::newFromText( $search . 'Dummy' );
36                 if( $title && $title->getText() == 'Dummy'
37                         && $title->getNamespace() != NS_MAIN
38                         && $title->getInterwiki() == '' ) {
39                         return self::searchBackend(
40                                 array($title->getNamespace()), '', $limit );
41                 }
42                                 
43                 return self::searchBackend( $namespaces, $search, $limit );
44         }
45
46
47         /**
48          * Do a prefix search of titles and return a list of matching page names.
49          * @param array $namespaces
50          * @param string $search
51          * @param int $limit
52          * @return array of strings
53          */
54         protected static function searchBackend( $namespaces, $search, $limit ) {
55                 if( count($namespaces) == 1 ){
56                         $ns = $namespaces[0];
57                         if( $ns == NS_MEDIA ) {
58                                 $namespaces = array(NS_FILE);
59                         } elseif( $ns == NS_SPECIAL ) {
60                                 return self::specialSearch( $search, $limit );
61                         }
62                 }
63                 $srchres = array();
64                 if( wfRunHooks( 'PrefixSearchBackend', array( $namespaces, $search, $limit, &$srchres ) ) ) {
65                         return self::defaultSearchBackend( $namespaces, $search, $limit );
66                 }
67                 return $srchres;
68         }
69
70         /**
71          * Prefix search special-case for Special: namespace.
72          */
73         protected static function specialSearch( $search, $limit ) {
74                 global $wgContLang;
75                 $searchKey = $wgContLang->caseFold( $search );
76
77                 // Unlike SpecialPage itself, we want the canonical forms of both
78                 // canonical and alias title forms...
79                 SpecialPage::initList();
80                 SpecialPage::initAliasList();
81                 $keys = array();
82                 foreach( array_keys( SpecialPage::$mList ) as $page ) {
83                         $keys[$wgContLang->caseFold( $page )] = $page;
84                 }
85                 foreach( $wgContLang->getSpecialPageAliases() as $page => $aliases ) {
86                         foreach( $aliases as $alias ) {
87                                 $keys[$wgContLang->caseFold( $alias )] = $alias;
88                         }
89                 }
90                 ksort( $keys );
91
92                 $srchres = array();
93                 foreach( $keys as $pageKey => $page ) {
94                         if( $searchKey === '' || strpos( $pageKey, $searchKey ) === 0 ) {
95                                 $srchres[] = Title::makeTitle( NS_SPECIAL, $page )->getPrefixedText();
96                         }
97                         if( count( $srchres ) >= $limit ) {
98                                 break;
99                         }
100                 }
101                 return $srchres;
102         }
103
104         /**
105          * Unless overridden by PrefixSearchBackend hook...
106          * This is case-sensitive (First character may
107          * be automatically capitalized by Title::secureAndSpit()
108          * later on depending on $wgCapitalLinks)
109          *
110          * @param array $namespaces Namespaces to search in
111          * @param string $search term
112          * @param int $limit max number of items to return
113          * @return array of title strings
114          */
115         protected static function defaultSearchBackend( $namespaces, $search, $limit ) {
116                 $ns = array_shift($namespaces); // support only one namespace
117                 if( in_array(NS_MAIN,$namespaces))
118                         $ns = NS_MAIN; // if searching on many always default to main 
119                 
120                 // Prepare nested request
121                 $req = new FauxRequest(array (
122                         'action' => 'query',
123                         'list' => 'allpages',
124                         'apnamespace' => $ns,
125                         'aplimit' => $limit,
126                         'apprefix' => $search
127                 ));
128
129                 // Execute
130                 $module = new ApiMain($req);
131                 $module->execute();
132
133                 // Get resulting data
134                 $data = $module->getResultData();
135
136                 // Reformat useful data for future printing by JSON engine
137                 $srchres = array ();
138                 foreach ((array)$data['query']['allpages'] as $pageinfo) {
139                         // Note: this data will no be printable by the xml engine
140                         // because it does not support lists of unnamed items
141                         $srchres[] = $pageinfo['title'];
142                 }
143
144                 return $srchres;
145         }
146         
147         /**
148          * Validate an array of numerical namespace indexes
149          * 
150          * @param array $namespaces
151          */
152         protected static function validateNamespaces($namespaces){
153                 global $wgContLang;
154                 $validNamespaces = $wgContLang->getNamespaces();
155                 if( is_array($namespaces) && count($namespaces)>0 ){
156                         $valid = array();
157                         foreach ($namespaces as $ns){
158                                 if( is_numeric($ns) && array_key_exists($ns, $validNamespaces) )
159                                         $valid[] = $ns;
160                         }
161                         if( count($valid) > 0 )
162                                 return $valid;
163                 }
164                 
165                 return array( NS_MAIN );
166         }
167 }