Don't look for pipes in the root node.
[lhc/web/wiklou.git] / includes / Namespace.php
1 <?php
2 /**
3 * Provide things related to namespaces
4 * @file
5 */
6
7 /**
8 * Definitions of the NS_ constants are in Defines.php
9 * @private
10 */
11 $wgCanonicalNamespaceNames = array(
12 NS_MEDIA => 'Media',
13 NS_SPECIAL => 'Special',
14 NS_TALK => 'Talk',
15 NS_USER => 'User',
16 NS_USER_TALK => 'User_talk',
17 NS_PROJECT => 'Project',
18 NS_PROJECT_TALK => 'Project_talk',
19 NS_FILE => 'File',
20 NS_FILE_TALK => 'File_talk',
21 NS_MEDIAWIKI => 'MediaWiki',
22 NS_MEDIAWIKI_TALK => 'MediaWiki_talk',
23 NS_TEMPLATE => 'Template',
24 NS_TEMPLATE_TALK => 'Template_talk',
25 NS_HELP => 'Help',
26 NS_HELP_TALK => 'Help_talk',
27 NS_CATEGORY => 'Category',
28 NS_CATEGORY_TALK => 'Category_talk',
29 );
30
31 /// @todo UGLY UGLY
32 if( is_array( $wgExtraNamespaces ) ) {
33 $wgCanonicalNamespaceNames = $wgCanonicalNamespaceNames + $wgExtraNamespaces;
34 }
35
36 /**
37 * This is a utility class with only static functions
38 * for dealing with namespaces that encodes all the
39 * "magic" behaviors of them based on index. The textual
40 * names of the namespaces are handled by Language.php.
41 *
42 * These are synonyms for the names given in the language file
43 * Users and translators should not change them
44 *
45 */
46
47 class MWNamespace {
48
49 /**
50 * These namespaces should always be first-letter capitalized, now and
51 * forevermore. Historically, they could've probably been lowercased too,
52 * but some things are just too ingrained now. :)
53 */
54 private static $alwaysCapitalizedNamespaces = array( NS_SPECIAL, NS_USER, NS_MEDIAWIKI );
55
56 /**
57 * Can pages in the given namespace be moved?
58 *
59 * @param $index Int: namespace index
60 * @return bool
61 */
62 public static function isMovable( $index ) {
63 global $wgAllowImageMoving;
64 return !( $index < NS_MAIN || ($index == NS_FILE && !$wgAllowImageMoving) || $index == NS_CATEGORY );
65 }
66
67 /**
68 * Is the given namespace is a subject (non-talk) namespace?
69 *
70 * @param $index Int: namespace index
71 * @return bool
72 */
73 public static function isMain( $index ) {
74 return !self::isTalk( $index );
75 }
76
77 /**
78 * Is the given namespace a talk namespace?
79 *
80 * @param $index Int: namespace index
81 * @return bool
82 */
83 public static function isTalk( $index ) {
84 return $index > NS_MAIN
85 && $index % 2;
86 }
87
88 /**
89 * Get the talk namespace index for a given namespace
90 *
91 * @param $index Int: namespace index
92 * @return int
93 */
94 public static function getTalk( $index ) {
95 return self::isTalk( $index )
96 ? $index
97 : $index + 1;
98 }
99
100 /**
101 * Get the subject namespace index for a given namespace
102 *
103 * @param $index Int: Namespace index
104 * @return int
105 */
106 public static function getSubject( $index ) {
107 return self::isTalk( $index )
108 ? $index - 1
109 : $index;
110 }
111
112 /**
113 * Returns whether the specified namespace exists
114 */
115 public static function exists( $index ) {
116 $nslist = self::getCanonicalNamespaces();
117 return isset( $nslist[$index] );
118 }
119
120 /**
121 * Returns array of all defined namespaces with their canonical
122 * (English) names.
123 *
124 * @return \array
125 * @since 1.17
126 */
127 public static function getCanonicalNamespaces() {
128 static $namespaces = null;
129 if ( $namespaces === null ) {
130 global $wgExtraNamespaces, $wgCanonicalNamespaceNames;
131 $namespaces = array( NS_MAIN => '' ) + $wgCanonicalNamespaceNames;
132 if ( is_array( $wgExtraNamespaces ) ) {
133 $namespaces += $wgExtraNamespaces;
134 }
135 wfRunHooks( 'CanonicalNamespaces', array( &$namespaces ) );
136 }
137 return $namespaces;
138 }
139
140 /**
141 * Returns the canonical (English) name for a given index
142 *
143 * @param $index Int: namespace index
144 * @return string or false if no canonical definition.
145 */
146 public static function getCanonicalName( $index ) {
147 $nslist = self::getCanonicalNamespaces();
148 if( isset( $nslist[$index] ) ) {
149 return $nslist[$index];
150 } else {
151 return false;
152 }
153 }
154
155 /**
156 * Returns the index for a given canonical name, or NULL
157 * The input *must* be converted to lower case first
158 *
159 * @param $name String: namespace name
160 * @return int
161 */
162 public static function getCanonicalIndex( $name ) {
163 static $xNamespaces = false;
164 if ( $xNamespaces === false ) {
165 $xNamespaces = array();
166 foreach ( self::getCanonicalNamespaces() as $i => $text ) {
167 $xNamespaces[strtolower($text)] = $i;
168 }
169 }
170 if ( array_key_exists( $name, $xNamespaces ) ) {
171 return $xNamespaces[$name];
172 } else {
173 return null;
174 }
175 }
176
177 /**
178 * Returns an array of the namespaces (by integer id) that exist on the
179 * wiki. Used primarily by the api in help documentation.
180 * @return array
181 */
182 public static function getValidNamespaces() {
183 static $mValidNamespaces = null;
184
185 if ( is_null( $mValidNamespaces ) ) {
186 foreach ( array_keys( self::getCanonicalNamespaces() ) as $ns ) {
187 if ( $ns >= 0 ) {
188 $mValidNamespaces[] = $ns;
189 }
190 }
191 }
192
193 return $mValidNamespaces;
194 }
195
196 /**
197 * Can this namespace ever have a talk namespace?
198 *
199 * @param $index Int: namespace index
200 * @return bool
201 */
202 public static function canTalk( $index ) {
203 return $index >= NS_MAIN;
204 }
205
206 /**
207 * Does this namespace contain content, for the purposes of calculating
208 * statistics, etc?
209 *
210 * @param $index Int: index to check
211 * @return bool
212 */
213 public static function isContent( $index ) {
214 global $wgContentNamespaces;
215 return $index == NS_MAIN || in_array( $index, $wgContentNamespaces );
216 }
217
218 /**
219 * Can pages in a namespace be watched?
220 *
221 * @param $index Int
222 * @return bool
223 */
224 public static function isWatchable( $index ) {
225 return $index >= NS_MAIN;
226 }
227
228 /**
229 * Does the namespace allow subpages?
230 *
231 * @param $index int Index to check
232 * @return bool
233 */
234 public static function hasSubpages( $index ) {
235 global $wgNamespacesWithSubpages;
236 return !empty( $wgNamespacesWithSubpages[$index] );
237 }
238
239 /**
240 * Get a list of all namespace indices which are considered to contain content
241 * @return array of namespace indices
242 */
243 public static function getContentNamespaces() {
244 global $wgContentNamespaces;
245 if( !is_array( $wgContentNamespaces ) || $wgContentNamespaces === array() ) {
246 return NS_MAIN;
247 } elseif ( !in_array( NS_MAIN, $wgContentNamespaces ) ) {
248 // always force NS_MAIN to be part of array (to match the algorithm used by isContent)
249 return array_merge( array( NS_MAIN ), $wgContentNamespaces );
250 } else {
251 return $wgContentNamespaces;
252 }
253 }
254 /**
255 * Is the namespace first-letter capitalized?
256 *
257 * @param $index int Index to check
258 * @return bool
259 */
260 public static function isCapitalized( $index ) {
261 global $wgCapitalLinks, $wgCapitalLinkOverrides;
262 // Turn NS_MEDIA into NS_FILE
263 $index = $index === NS_MEDIA ? NS_FILE : $index;
264
265 // Make sure to get the subject of our namespace
266 $index = self::getSubject( $index );
267
268 // Some namespaces are special and should always be upper case
269 if ( in_array( $index, self::$alwaysCapitalizedNamespaces ) ) {
270 return true;
271 }
272 if ( isset( $wgCapitalLinkOverrides[ $index ] ) ) {
273 // $wgCapitalLinkOverrides is explicitly set
274 return $wgCapitalLinkOverrides[ $index ];
275 }
276 // Default to the global setting
277 return $wgCapitalLinks;
278 }
279 }