3db1938b6405e1d3dc88b7d3d2416eb0d4b52ffa
[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 if ( is_array( $wgExtraNamespaces ) ) {
132 $namespaces = $wgCanonicalNamespaceNames + $wgExtraNamespaces;
133 } else {
134 $namespaces = $wgCanonicalNamespaceNames;
135 }
136 $namespaces[NS_MAIN] = '';
137 wfRunHooks( 'CanonicalNamespaces', array( &$namespaces ) );
138 }
139 return $namespaces;
140 }
141
142 /**
143 * Returns the canonical (English) name for a given index
144 *
145 * @param $index Int: namespace index
146 * @return string or false if no canonical definition.
147 */
148 public static function getCanonicalName( $index ) {
149 $nslist = self::getCanonicalNamespaces();
150 if( isset( $nslist[$index] ) ) {
151 return $nslist[$index];
152 } else {
153 return false;
154 }
155 }
156
157 /**
158 * Returns the index for a given canonical name, or NULL
159 * The input *must* be converted to lower case first
160 *
161 * @param $name String: namespace name
162 * @return int
163 */
164 public static function getCanonicalIndex( $name ) {
165 static $xNamespaces = false;
166 if ( $xNamespaces === false ) {
167 $xNamespaces = array();
168 foreach ( self::getCanonicalNamespaces() as $i => $text ) {
169 $xNamespaces[strtolower($text)] = $i;
170 }
171 }
172 if ( array_key_exists( $name, $xNamespaces ) ) {
173 return $xNamespaces[$name];
174 } else {
175 return null;
176 }
177 }
178
179 /**
180 * Returns an array of the namespaces (by integer id) that exist on the
181 * wiki. Used primarily by the api in help documentation.
182 * @return array
183 */
184 public static function getValidNamespaces() {
185 static $mValidNamespaces = null;
186
187 if ( is_null( $mValidNamespaces ) ) {
188 foreach ( array_keys( self::getCanonicalNamespaces() ) as $ns ) {
189 if ( $ns >= 0 ) {
190 $mValidNamespaces[] = $ns;
191 }
192 }
193 }
194
195 return $mValidNamespaces;
196 }
197
198 /**
199 * Can this namespace ever have a talk namespace?
200 *
201 * @param $index Int: namespace index
202 * @return bool
203 */
204 public static function canTalk( $index ) {
205 return $index >= NS_MAIN;
206 }
207
208 /**
209 * Does this namespace contain content, for the purposes of calculating
210 * statistics, etc?
211 *
212 * @param $index Int: index to check
213 * @return bool
214 */
215 public static function isContent( $index ) {
216 global $wgContentNamespaces;
217 return $index == NS_MAIN || in_array( $index, $wgContentNamespaces );
218 }
219
220 /**
221 * Can pages in a namespace be watched?
222 *
223 * @param $index Int
224 * @return bool
225 */
226 public static function isWatchable( $index ) {
227 return $index >= NS_MAIN;
228 }
229
230 /**
231 * Does the namespace allow subpages?
232 *
233 * @param $index int Index to check
234 * @return bool
235 */
236 public static function hasSubpages( $index ) {
237 global $wgNamespacesWithSubpages;
238 return !empty( $wgNamespacesWithSubpages[$index] );
239 }
240
241 /**
242 * Get a list of all namespace indices which are considered to contain content
243 * @return array of namespace indices
244 */
245 public static function getContentNamespaces() {
246 global $wgContentNamespaces;
247 if( !is_array( $wgContentNamespaces ) || $wgContentNamespaces === array() ) {
248 return NS_MAIN;
249 } elseif ( !in_array( NS_MAIN, $wgContentNamespaces ) ) {
250 // always force NS_MAIN to be part of array (to match the algorithm used by isContent)
251 return array_merge( array( NS_MAIN ), $wgContentNamespaces );
252 } else {
253 return $wgContentNamespaces;
254 }
255 }
256 /**
257 * Is the namespace first-letter capitalized?
258 *
259 * @param $index int Index to check
260 * @return bool
261 */
262 public static function isCapitalized( $index ) {
263 global $wgCapitalLinks, $wgCapitalLinkOverrides;
264 // Turn NS_MEDIA into NS_FILE
265 $index = $index === NS_MEDIA ? NS_FILE : $index;
266
267 // Make sure to get the subject of our namespace
268 $index = self::getSubject( $index );
269
270 // Some namespaces are special and should always be upper case
271 if ( in_array( $index, self::$alwaysCapitalizedNamespaces ) ) {
272 return true;
273 }
274 if ( isset( $wgCapitalLinkOverrides[ $index ] ) ) {
275 // $wgCapitalLinkOverrides is explicitly set
276 return $wgCapitalLinkOverrides[ $index ];
277 }
278 // Default to the global setting
279 return $wgCapitalLinks;
280 }
281 }