* Remove useless ?> in Diff.php
[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 (First character may
100 * be automatically capitalized by Title::secureAndSpit()
101 * later on depending on $wgCapitalLinks)
102 *
103 * @param array $namespaces Namespaces to search in
104 * @param string $search term
105 * @param int $limit max number of items to return
106 * @return array of title strings
107 */
108 protected static function defaultSearchBackend( $namespaces, $search, $limit ) {
109 $ns = array_shift($namespaces); // support only one namespace
110 if( in_array(NS_MAIN,$namespaces))
111 $ns = NS_MAIN; // if searching on many always default to main
112
113 // Prepare nested request
114 $req = new FauxRequest(array (
115 'action' => 'query',
116 'list' => 'allpages',
117 'apnamespace' => $ns,
118 'aplimit' => $limit,
119 'apprefix' => $search
120 ));
121
122 // Execute
123 $module = new ApiMain($req);
124 $module->execute();
125
126 // Get resulting data
127 $data = $module->getResultData();
128
129 // Reformat useful data for future printing by JSON engine
130 $srchres = array ();
131 foreach ($data['query']['allpages'] as & $pageinfo) {
132 // Note: this data will no be printable by the xml engine
133 // because it does not support lists of unnamed items
134 $srchres[] = $pageinfo['title'];
135 }
136
137 return $srchres;
138 }
139
140 /**
141 * Validate an array of numerical namespace indexes
142 *
143 * @param array $namespaces
144 */
145 protected static function validateNamespaces($namespaces){
146 global $wgContLang;
147 $validNamespaces = $wgContLang->getNamespaces();
148 if( is_array($namespaces) && count($namespaces)>0 ){
149 $valid = array();
150 foreach ($namespaces as $ns){
151 if( is_numeric($ns) && array_key_exists($ns, $validNamespaces) )
152 $valid[] = $ns;
153 }
154 if( count($valid) > 0 )
155 return $valid;
156 }
157
158 return array( NS_MAIN );
159 }
160 }