Fix some weird bugs on "you are blocked" form by unstubbing User object.
[lhc/web/wiklou.git] / includes / PrefixSearch.php
1 <?php
2
3 class PrefixSearch {
4 /**
5 * Do a prefix search of titles and return a list of matching page names.
6 * @param string $search
7 * @param int $limit
8 * @param array $namespaces - used if query is not explicitely prefixed
9 * @return array of strings
10 */
11 public static function titleSearch( $search, $limit, $namespaces=array() ) {
12 $search = trim( $search );
13 if( $search == '' ) {
14 return array(); // Return empty result
15 }
16 $namespaces = self::validateNamespaces( $namespaces );
17
18 $title = Title::newFromText( $search );
19 if( $title && $title->getInterwiki() == '' ) {
20 $ns = array($title->getNamespace());
21 if($ns[0] == NS_MAIN)
22 $ns = $namespaces; // no explicit prefix, use default namespaces
23 return self::searchBackend(
24 $ns, $title->getText(), $limit );
25 }
26
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 );
34 }
35
36 return self::searchBackend( $namespaces, $search, $limit );
37 }
38
39
40 /**
41 * Do a prefix search of titles and return a list of matching page names.
42 * @param array $namespaces
43 * @param string $search
44 * @param int $limit
45 * @return array of strings
46 */
47 protected static function searchBackend( $namespaces, $search, $limit ) {
48 if( count($namespaces) == 1 ){
49 $ns = $namespaces[0];
50 if( $ns == NS_MEDIA ) {
51 $namespaces = array(NS_IMAGE);
52 } elseif( $ns == NS_SPECIAL ) {
53 return self::specialSearch( $search, $limit );
54 }
55 }
56 $srchres = array();
57 if( wfRunHooks( 'PrefixSearchBackend', array( $namespaces, $search, $limit, &$srchres ) ) ) {
58 return self::defaultSearchBackend( $namespaces, $search, $limit );
59 }
60 return $srchres;
61 }
62
63 /**
64 * Prefix search special-case for Special: namespace.
65 */
66 protected static function specialSearch( $search, $limit ) {
67 global $wgContLang;
68 $searchKey = $wgContLang->caseFold( $search );
69
70 // Unlike SpecialPage itself, we want the canonical forms of both
71 // canonical and alias title forms...
72 SpecialPage::initList();
73 SpecialPage::initAliasList();
74 $keys = array();
75 foreach( array_keys( SpecialPage::$mList ) as $page ) {
76 $keys[$wgContLang->caseFold( $page )] = $page;
77 }
78 foreach( $wgContLang->getSpecialPageAliases() as $page => $aliases ) {
79 foreach( $aliases as $alias ) {
80 $keys[$wgContLang->caseFold( $alias )] = $alias;
81 }
82 }
83 ksort( $keys );
84
85 $srchres = array();
86 foreach( $keys as $pageKey => $page ) {
87 if( $searchKey === '' || strpos( $pageKey, $searchKey ) === 0 ) {
88 $srchres[] = Title::makeTitle( NS_SPECIAL, $page )->getPrefixedText();
89 }
90 if( count( $srchres ) >= $limit ) {
91 break;
92 }
93 }
94 return $srchres;
95 }
96
97 /**
98 * Unless overridden by PrefixSearchBackend hook...
99 * This is case-sensitive except the first letter (per $wgCapitalLinks)
100 *
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
105 */
106 protected static function defaultSearchBackend( $namespaces, $search, $limit ) {
107 global $wgCapitalLinks, $wgContLang;
108
109 if( $wgCapitalLinks ) {
110 $search = $wgContLang->ucfirst( $search );
111 }
112
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
116
117 // Prepare nested request
118 $req = new FauxRequest(array (
119 'action' => 'query',
120 'list' => 'allpages',
121 'apnamespace' => $ns,
122 'aplimit' => $limit,
123 'apprefix' => $search
124 ));
125
126 // Execute
127 $module = new ApiMain($req);
128 $module->execute();
129
130 // Get resulting data
131 $data = $module->getResultData();
132
133 // Reformat useful data for future printing by JSON engine
134 $srchres = array ();
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'];
139 }
140
141 return $srchres;
142 }
143
144 /**
145 * Validate an array of numerical namespace indexes
146 *
147 * @param array $namespaces
148 */
149 protected static function validateNamespaces($namespaces){
150 global $wgContLang;
151 $validNamespaces = $wgContLang->getNamespaces();
152 if( is_array($namespaces) && count($namespaces)>0 ){
153 $valid = array();
154 foreach ($namespaces as $ns){
155 if( is_numeric($ns) && array_key_exists($ns, $validNamespaces) )
156 $valid[] = $ns;
157 }
158 if( count($valid) > 0 )
159 return $valid;
160 }
161
162 return array( NS_MAIN );
163 }
164 }