r12146 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r12145‎ | r12146 | r12147 >
Date:06:31, 19 December 2005
Author:eloquence
Status:old
Tags:
Comment:
1) Cache namespace definitions in memcached etc. if available.
2) Do not respect "hidden" attribute of namespaces in [[Special:Allpages]]
and in the namespace manager itself.
3) Basic logging of all namespace operations.
4) Add missing docs to Namespace.php and restructure a bit.
5) Bugfixes.

This should now be shaping up to be ready for code review and inclusion.
Modified paths:
  • /branches/wikidata/phase3/includes/ChangesList.php (modified) (history)
  • /branches/wikidata/phase3/includes/GlobalFunctions.php (modified) (history)
  • /branches/wikidata/phase3/includes/LogPage.php (modified) (history)
  • /branches/wikidata/phase3/includes/Namespace.php (modified) (history)
  • /branches/wikidata/phase3/includes/SpecialAllpages.php (modified) (history)
  • /branches/wikidata/phase3/includes/SpecialNamespaces.php (modified) (history)
  • /branches/wikidata/phase3/includes/SpecialUndelete.php (modified) (history)
  • /branches/wikidata/phase3/languages/Language.php (modified) (history)

Diff [purge]

Index: branches/wikidata/phase3/includes/SpecialAllpages.php
@@ -52,7 +52,9 @@
5353 global $wgContLang, $wgScript;
5454 $t = Title::makeTitle( NS_SPECIAL, $this->name );
5555
56 - $namespaceselect = HTMLnamespaceselector($namespace, null);
 56+ # Selector needs to include hidden namespace, hence the "true"
 57+ # parameter
 58+ $namespaceselect = HTMLnamespaceselector($namespace, null, true);
5759
5860 $frombox = "<input type='text' size='20' name='from' id='nsfrom' value=\""
5961 . htmlspecialchars ( $from ) . '"/>';
Index: branches/wikidata/phase3/includes/GlobalFunctions.php
@@ -1369,9 +1369,10 @@
13701370 *
13711371 * @param mixed $selected The namespace which should be selected, default ''
13721372 * @param string $allnamespaces Value of a special item denoting all namespaces. Null to not include (default)
 1373+ * @param bool $includehidden Include hidden namespaces?
13731374 * @return Html string containing the namespace selector
13741375 */
1375 -function &HTMLnamespaceselector($selected = '', $allnamespaces = null) {
 1376+function &HTMLnamespaceselector($selected = '', $allnamespaces = null, $includehidden=false) {
13761377 if( $selected !== '' ) {
13771378 if( is_null( $selected ) ) {
13781379 // No namespace selected; let exact match work without hitting Main
@@ -1382,7 +1383,7 @@
13831384 }
13841385 }
13851386 $s = "<select name='namespace' class='namespaceselector'>\n\t";
1386 - $arr = Namespace::getFormattedDefaultNamespaces();
 1387+ $arr = Namespace::getFormattedDefaultNamespaces($includehidden);
13871388 if( !is_null($allnamespaces) ) {
13881389 $arr = array($allnamespaces => wfMsgHtml('namespacesall')) + $arr;
13891390 }
Index: branches/wikidata/phase3/includes/ChangesList.php
@@ -125,7 +125,7 @@
126126 $r .= $this->skin->commentBlock( $rc_comment, $rcObj->getTitle() );
127127 }
128128
129 - if ($rcObj->numberofWatchingusers > 0) {
 129+ if (isset($rcObj->numberofWatchingusers) && $rcObj->numberofWatchingusers > 0) {
130130 $r .= wfMsg('number_of_watching_users_RCview', $wgContLang->formatNum($rcObj->numberofWatchingusers));
131131 }
132132
@@ -346,7 +346,7 @@
347347 $this->insertUserRelatedLinks($s,$rc);
348348 $this->insertComment($s, $rc);
349349
350 - if ($rc->numberofWatchingusers > 0) {
 350+ if (isset($rc->numberofWatchingusers) && $rc->numberofWatchingusers > 0) {
351351 $s .= ' ' . wfMsg('number_of_watching_users_RCview', $wgContLang->formatNum($rc->numberofWatchingusers));
352352 }
353353
Index: branches/wikidata/phase3/includes/SpecialUndelete.php
@@ -383,7 +383,7 @@
384384 $undelete =& Title::makeTitle( NS_SPECIAL, 'Undelete' );
385385 $wgOut->addHTML( "<ul>\n" );
386386 while( $row = $result->fetchObject() ) {
387 - $n = ($row->ar_namespace ?
 387+ $n = ($row->ar_namespace && array_key_exists($row->ar_namespace,$wgNamespaces) ?
388388 ($wgNamespaces[$row->ar_namespace]->getDefaultName(). ":") : "").
389389 $row->ar_title;
390390 $link = $sk->makeKnownLinkObj( $undelete,
Index: branches/wikidata/phase3/includes/Namespace.php
@@ -107,6 +107,9 @@
108108 $defaultNameIndex, # Index of the name all other names redirect to?
109109 $canonicalNameIndex; # Index of the name that's valid everywhere
110110
 111+ /**
 112+ * Constructor with reasonable defaults.
 113+ */
111114 function Namespace() {
112115
113116 $this->setIndex(NULL);
@@ -115,26 +118,54 @@
116119 $this->setSubpages(false);
117120 $this->setSearchedByDefault(false);
118121 $this->setTarget(NULL);
119 - $this->setHidden(false);
120 -
 122+ $this->setHidden(false);
121123 }
 124+
 125+ /**
 126+ * @return index to the correct $wgNamespaces object
 127+ * or database record for this namespace.
 128+ */
122129 function getIndex() {
123130 return $this->index;
124131 }
125132
 133+ /**
 134+ * @param $index New index for this namespace.
 135+ * Generally only used during creation.
 136+ */
126137 function setIndex($index) {
127138 $this->index=$index;
128139 }
129 -
 140+
 141+ /**
 142+ * @return String like NS_MAIN for identifying
 143+ * system namespaces (see Defines.php).
 144+ */
130145 function getSystemType() {
131146 return $this->systemType;
132147 }
133148
 149+ /**
 150+ * Set the system type for this namespace.
 151+ * @param string Constant name - needs to exist
 152+ * in Defines.php.
 153+ * @return bool depending on success
 154+ *
 155+ */
134156 function setSystemType($type) {
135 - // TODO: check for valid types
136 - $this->systemType=(string)$type;
 157+ $typeString=(string)$type;
 158+ if(defined($typeString)) {
 159+ $this->systemType=$typeString;
 160+ return true;
 161+ } else {
 162+ return false;
 163+ }
137164 }
138 -
 165+
 166+ /**
 167+ * Is this a system namsepace?
 168+ * @return bool
 169+ */
139170 function isSystemNamespace() {
140171 $sys=$this->getSystemType();
141172 return !empty($sys);
@@ -148,23 +179,43 @@
149180 function isMovable() {
150181 return $this->isMovable;
151182 }
152 -
 183+
 184+ /**
 185+ * Can pages in this namespace be moved?
 186+ * @param bool
 187+ */
153188 function setMovable($movable=true) {
154 - $this->movable=(bool)$movable;
 189+ $this->isMovable=(bool)$movable;
155190 }
156 -
 191+
 192+ /**
 193+ * Are pages from this namespace hidden in lists?
 194+ * @return bool
 195+ */
157196 function isHidden() {
158197 return $this->isHidden;
159198 }
160199
 200+ /**
 201+ * Should pages from this namespace be hidden in lists?
 202+ * @param bool
 203+ */
161204 function setHidden($hidden=true) {
162205 $this->isHidden=(bool)$hidden;
163206 }
164207
 208+ /**
 209+ * @return int Index of the parent namespace to a
 210+ * child namespace (talk or otherwise), NULL if none
 211+ */
165212 function getParentIndex() {
166213 return $this->parentIndex;
167214 }
168215
 216+ /**
 217+ * @return int Same as getParentIndex(), but returns
 218+ * this namespace's index if no parent namespace exists.
 219+ */
169220 function getSubject() {
170221 if($this->isTalk()) {
171222 return $this->getParentIndex();
@@ -173,42 +224,77 @@
174225 }
175226 }
176227
 228+ /**
 229+ * Set parent namespace
 230+ * @param int
 231+ */
177232 function setParentIndex($index) {
178233 $this->parentIndex=$index;
179234 }
180 -
 235+
 236+ /**
 237+ * Does this namespace have a parent namespace?
 238+ * @return bool
 239+ */
181240 function hasParent() {
182241 return ($this->getParentIndex()!=NULL);
183242 }
184 -
 243+
 244+ /**
 245+ * Synonym for hasParent(), but might be logically
 246+ * different in the near future, if parent/child
 247+ * relationships go beyond talk pages.
 248+ * @return bool
 249+ */
185250 function isTalk() {
186251 return $this->hasParent();
187252 }
188253
189 - /*
 254+ /**
190255 * Check if the given namespace is not a talk page
191256 * @return bool
192257 */
193258 function isMain( $index ) {
194259 return !$this->isTalk();
195260 }
196 -
 261+
 262+ /**
 263+ * Is this a "special" namespace (Media:, Special:)?
 264+ * Special namespaces cannot contain any pages.
 265+ * @return bool
 266+ */
197267 function isSpecial() {
198268 return($this->getIndex()<NS_MAIN);
199269 }
200270
 271+ /**
 272+ * Is content in this namespace searched by default?
 273+ * @return bool
 274+ */
201275 function isSearchedByDefault() {
202276 return $this->isSearchedByDefault;
203277 }
204278
 279+ /**
 280+ * Should this namespace be searched by default?
 281+ * @param bool
 282+ */
205283 function setSearchedByDefault($search=true) {
206284 $this->isSearchedByDefault=(bool)$search;
207285 }
208286
209 - /* TODO: support multiple discussion namespaces,
210 - so that things like a Review: namespace
211 - become possible in parallel to normal talk
212 - pages. */
 287+ /**
 288+ Get the index of the discussion namespace associated
 289+ with a namespace. If this _is_ a discussion namespace,
 290+ return its index.
 291+
 292+ @return int
 293+
 294+ TODO: support multiple discussion namespaces,
 295+ so that things like a Review: namespace
 296+ become possible in parallel to normal talk
 297+ pages.
 298+ */
213299 function getTalk() {
214300 global $wgNamespaces;
215301 /* This behavior is expected by Title.php! */
@@ -221,14 +307,49 @@
222308 return null;
223309 }
224310
 311+ /**
 312+ * Return the default prefix for unprefixed links
 313+ * from this namespace.
 314+ * @return string
 315+ */
225316 function getTarget() {
226317 return $this->target;
227318 }
228 -
 319+
 320+ /**
 321+ * Set the default prefix for unprefixed links, e.g.
 322+ * "User:" (local namespace prefix) or "MeatBall:"
 323+ * (InterWiki prefix).
 324+ *
 325+ * @param string
 326+ */
229327 function setTarget($target) {
230328 $this->target=(string)$target;
231329 }
 330+
 331+ /**
 332+ * Does this namespace allow [[/subpages]]?
 333+ * @return bool
 334+ */
 335+ function allowsSubpages() {
 336+ return $this->allowsSubpages;
232337
 338+ }
 339+
 340+ /**
 341+ * Should this namespace allow [[/subpages]]?
 342+ * @param bool
 343+ */
 344+ function setSubpages($subpages=true) {
 345+ $this->allowsSubpages=(bool)$subpages;
 346+ }
 347+
 348+ /**
 349+ * Return the default name for this namespace, if any.
 350+ * The default name is the one all others redirect to.
 351+ *
 352+ * @return string
 353+ */
233354 function getDefaultName() {
234355 if(isset($this->defaultNameIndex) && array_key_exists($this->defaultNameIndex,$this->names)) {
235356 return $this->names[$this->defaultNameIndex];
@@ -250,24 +371,33 @@
251372 }
252373 return null;
253374 }
254 -
 375+
 376+ /**
 377+ * Among the names of this namespace, which one should
 378+ * be set as the default name?
 379+ * @param int Key to the names array
 380+ */
255381 function setDefaultNameIndex($index) {
256382 $this->defaultNameIndex=$index;
257383 }
258384
 385+ /**
 386+ * Among the names of this namespace, which one
 387+ * should be "canonical" (i.e. not editable, and
 388+ * assumed to exist under this name in other
 389+ * wikis)?
 390+ * @param int Key to the names array
 391+ */
259392 function setCanonicalNameIndex($index) {
260393 $this->canonicalNameIndex=$index;
261394 }
262395
263 - function allowsSubpages() {
264 - return $this->allowsSubpages;
265 -
266 - }
267 -
268 - function setSubpages($subpages=true) {
269 - $this->allowsSubpages=(bool)$subpages;
270 - }
271 -
 396+ /**
 397+ * Add a name to the list of names for this
 398+ * namespace.
 399+ * @return index of the newly added name,
 400+ * or NULL if hte name is not valid.
 401+ */
272402 function addName($name) {
273403 $index=count($this->names);
274404 if($this->isValidName($name)) {
@@ -278,7 +408,12 @@
279409 return NULL;
280410 }
281411 }
282 -
 412+
 413+ /**
 414+ * Return the key in the name list for a given
 415+ * name.
 416+ * @return int Matching key or NULL
 417+ */
283418 function getNameIndexForName($findname) {
284419 foreach($this->names as $nsi=>$name) {
285420 if($name==$findname) {
@@ -288,6 +423,13 @@
289424 return null;
290425 }
291426
 427+ /**
 428+ * Change a namespace name.
 429+ * @param $oldname The old name
 430+ * @param $newname The new name
 431+ * @param $checkvalid Does the new name have to be
 432+ * valid? (is checked by save() in any case)
 433+ */
292434 function setName($oldname,$newname,$checkvalid=true) {
293435 if($checkvalid && !$this->isValidName($newname)) {
294436 return NULL;
@@ -302,7 +444,11 @@
303445 }
304446 }
305447
306 - /* static */
 448+ /**
 449+ * Is this a valid namespace name? Valid characters
 450+ * are defined in the NS_CHAR constant.
 451+ * @return bool
 452+ */
307453 function isValidName($name) {
308454 # Consist only of (at least one) valid char(s)
309455 if(preg_match("/^".NS_CHAR."+$/",$name)) {
@@ -311,96 +457,49 @@
312458 return false;
313459 }
314460 }
315 -
 461+
 462+ /**
 463+ * How many pages does this namespace contain?
 464+ * @return The number of pages
 465+ */
 466+ function countPages() {
 467+ $dbs =& wfGetDB(DB_SLAVE);
 468+ return $dbs->selectField(
 469+ 'page',
 470+ 'count(*)',
 471+ array('page_namespace'=>$this->getIndex())
 472+ );
 473+ }
 474+
 475+ /**
 476+ * Get the default name with spaces instead of
 477+ * underscores.
 478+ * @return string
 479+ */
316480 function getFormattedDefaultName() {
317481 $ns=$this->getDefaultName();
318482 return strtr($ns, '_',' ');
319483 }
320 -
321484 /**
322 - * Returns the namespace index for a given name or synonym,
323 - * if valid
324 - *
325 - * @static
326 - */
327 - function getIndexForName ( $name ) {
328 - global $wgNamespaces;
329 - foreach ($wgNamespaces as $ns) {
330 - foreach($ns->names as $synonym) {
331 - if(strcasecmp($synonym,$name)==0) {
332 - return $ns->getIndex();
333 - }
334 - }
335 - }
336 - return NULL;
337 - }
338 -
339 - /**
340 - * Return the default name for any namespace name
341 - * given as a parameter, even if it is the default
342 - * name already.
343 - *
344 - * @static
345 - */
346 - function getDefaultNameForName ( $name ) {
347 - global $wgNamespaces;
348 - $index=Namespace::getIndexForName($name);
349 - if(!is_null($index)) {
350 - return $wgNamespaces[$index]->getDefaultName();
351 - } else {
352 - return null;
353 - }
354 - }
355 -
356 - /**
357 - *
358 - * resets array pointer
359 - *
360 - * @param $includeHidden
361 - *
362 - * @static
 485+ * @return the key in the names array for the default
 486+ * name of this namespace
363487 */
364 - function &getDefaultNamespaces($includeHidden=false) {
365 - global $wgNamespaces;
366 - $dns=array();
367 - foreach($wgNamespaces as $ns) {
368 - if(!$ns->isHidden()) {
369 - $dn=$ns->getDefaultName();
370 - if(!is_null($dn)) {
371 - $dns[$ns->getIndex()]=$dn;
372 - } else {
373 - $dns[$ns->getIndex()]='';
374 - }
375 - }
376 - }
377 - return $dns;
378 - }
379 -
380 - /**
381 - * A convenience function that returns the same thing as
382 - * getDefaultNamespaces() except with the array values changed to ' '
383 - * where it found '_', useful for producing output to be displayed
384 - * e.g. in <select> forms.
385 - *
386 - * @static
387 - * @param $includeHidden
388 - * @return array
389 - */
390 - function &getFormattedDefaultNamespaces($includeHidden=false) {
391 - $ns = Namespace::getDefaultNamespaces($includeHidden);
392 - foreach($ns as $k => $v) {
393 - $ns[$k] = strtr($v, '_', ' ');
394 - }
395 - return $ns;
396 - }
397 -
398488 function getDefaultNameIndex() {
399489 return $this->defaultNameIndex;
400490 }
 491+
 492+ /**
 493+ * @return the key in the names array for the
 494+ * canonical name of this namespace
 495+ */
401496 function getCanonicalNameIndex() {
402497 return $this->canonicalNameIndex;
403498 }
404499
 500+ /**
 501+ * @return The canonical name associated with
 502+ * this namespace, or NULL
 503+ */
405504 function getCanonicalName() {
406505 if(!is_null($this->getCanonicalNameIndex())) {
407506 return $this->names[$this->getCanonicalNameIndex()];
@@ -408,14 +507,36 @@
409508 return null;
410509 }
411510 }
 511+
 512+ /**
 513+ * @param int Key to the names array of the name
 514+ * which should be removed.
 515+ */
 516+ function removeNameByIndex($index) {
 517+ if(array_key_exists($index,$this->names)) {
 518+ unset($this->names[$index]);
 519+ return true;
 520+ } else {
 521+ return false;
 522+ }
 523+ }
412524
413525 /**
 526+ * Kill them all! Well, all the ones in this namespace
 527+ * object. And only if we save().
 528+ */
 529+ function removeAllNames() {
 530+ $this->names=array();
 531+ return true;
 532+ }
 533+
 534+ /**
414535 * Serialize this namespace to the database.
415536 * No part of the operation will be completed
416537 * unless it cannot be fully done.
417538 *
418 - * If the index of the namespace index is NULL,
419 - * a new namespace will be created.
 539+ * If the namespace index is NULL, a new namespace
 540+ * will be created.
420541 *
421542 * @param boolean $testSave
422543 * If this is set to true, no actual changes
@@ -425,8 +546,7 @@
426547 * all of them will succeed.
427548 * @param boolean $overrideInterwiki
428549 * If a namespace name overlaps with an Interwiki
429 - * prefix, should it be created anyway? Note that
430 - * you can only override one Interwiki prefix at
 550+ * prefix, should it be created anyway?
431551 *
432552 * @return array()
433553 * An array that describes the results of the
@@ -441,7 +561,6 @@
442562 * NS_DUPLICATE_NAMES=>array(names)
443563 * NS_INTERWIKI_NAMES=>array(names)
444564 * NS_PREFIX_NAMES=>array(names)
445 - * NS_LINKED_NAMES=>array(names)
446565 * )
447566 *
448567 * NS_RESULT can be:
@@ -474,13 +593,6 @@
475594 * NS_PREFIX_NAMES
476595 * names which are used as hardcoded title prefixes
477596 *
478 - * - For removed or renamed names:
479 - *
480 - * NS_LINKED_NAMES
481 - * names which are still in use (linked to) from some
482 - * pages -- these links would become invalid if the
483 - * name was changed or removed.
484 - *
485597 * How this function works:
486598 * ------------------------
487599 * Check if the namespace has a valid ID (not null)
@@ -516,8 +628,7 @@
517629 NS_ILLEGAL_NAMES=>array(),
518630 NS_DUPLICATE_NAMES=>array(),
519631 NS_INTERWIKI_NAMES=>array(),
520 - NS_PREFIX_NAMES=>array(),
521 - NS_LINKED_NAMES=>array()
 632+ NS_PREFIX_NAMES=>array()
522633 );
523634 $nameOperations=array();
524635 $dbs =& wfGetDB( DB_SLAVE );
@@ -607,38 +718,8 @@
608719 }
609720 $dbs->freeResult($res);
610721 }
611 - # Check first if the name to be deleted
612 - # has not just moved to another slot.
613 - elseif($operation==NS_NAME_DELETE
614 - && is_null($this->getNameIndexForName($name))) {
615 -
616 - # Would any broken links result from deletion?
617 - $match=$dbs->addQuotes("%[[$name:%");
 722+ }
618723
619 - # Query needs to be optimized/simplified,
620 - # but will generally be run very rarely.
621 - $res = $dbs->select(
622 - array('page', /* FROM */
623 - 'pagelinks',
624 - 'revision',
625 - 'text'),
626 - array('DISTINCT page_title',
627 - 'page_namespace'),
628 - array('pl_namespace='.$index,
629 - 'page_id=pl_from',
630 - 'rev_id=page_latest',
631 - 'rev_text_id=old_id',
632 - 'old_text like '.$match),
633 - array('LIMIT'=>1)
634 - );
635 - if($dbs->numRows($res) > 0) {
636 - $rv[NS_RESULT]=NS_NAME_ISSUES;
637 - $rv[NS_LINKED_NAMES][]=$name;
638 - }
639 - $dbs->freeResult($res);
640 - }
641 - }
642 -
643724 # If there are problems, return the array
644725 if($rv[NS_RESULT]==NS_NAME_ISSUES) {
645726 return $rv;
@@ -789,6 +870,8 @@
790871 * This function allows deleting system namespaces if explicitly
791872 * specified; this should however not be possible through the
792873 * user interface.
 874+ *
 875+ * @param $deleteSystem bool Override system namespace protection
793876 */
794877 function deleteNamespace($deleteSystem=false) {
795878 global $wgNamespaces;
@@ -826,30 +909,112 @@
827910 unset($wgNamespaces[$this->getIndex()]);
828911 return array(NS_RESULT=>NS_DELETED);
829912 }
 913+
 914+ /* ---------- all static functions below ----------- */
 915+
 916+ /**
 917+ * For _any_ name (among all namespaces), return
 918+ * the index of the namespace to which it belongs.
 919+ *
 920+ * @param string Name to search for
 921+ * @return int Index of the namespace associated
 922+ * with this name (or NULL)
 923+ * @static
 924+ */
 925+ function getIndexForName ( $name ) {
 926+ global $wgNamespaces;
 927+ foreach ($wgNamespaces as $ns) {
 928+ foreach($ns->names as $synonym) {
 929+ if(strcasecmp($synonym,$name)==0) {
 930+ return $ns->getIndex();
 931+ }
 932+ }
 933+ }
 934+ return NULL;
 935+ }
830936
831 - function removeNameByIndex($index) {
832 - if(array_key_exists($index,$this->names)) {
833 - unset($this->names[$index]);
834 - return true;
835 - } else {
836 - return false;
837 - }
 937+ /**
 938+ * Return the default name for any namespace name
 939+ * given as a parameter, even if it is the default
 940+ * name already. Searches all namespaces.
 941+ *
 942+ * @param string Any namespace name
 943+ * @return string The name (may be identical)
 944+ * @static
 945+ */
 946+ function getDefaultNameForName ( $name ) {
 947+ global $wgNamespaces;
 948+ $index=Namespace::getIndexForName($name);
 949+ if(!is_null($index)) {
 950+ return $wgNamespaces[$index]->getDefaultName();
 951+ } else {
 952+ return null;
 953+ }
838954 }
839955
840 - function removeAllNames() {
841 - $this->names=array();
842 - return true;
 956+ /**
 957+ * Return an array of the default names of all
 958+ * namespaces. Resets array pointer of $wgNamespaces.
 959+ * @param $includeHidden Should hidden namespaces
 960+ * be part of the array?
 961+ * @return array
 962+ * @static
 963+ */
 964+ function &getDefaultNamespaces($includeHidden=false) {
 965+ global $wgNamespaces;
 966+ $dns=array();
 967+ foreach($wgNamespaces as $ns) {
 968+ if(!$ns->isHidden() || $includeHidden) {
 969+ $dn=$ns->getDefaultName();
 970+ if(!is_null($dn)) {
 971+ $dns[$ns->getIndex()]=$dn;
 972+ } else {
 973+ $dns[$ns->getIndex()]='';
 974+ }
 975+ }
 976+ }
 977+ return $dns;
843978 }
 979+
 980+ /**
 981+ * A convenience function that returns the same thing as
 982+ * getDefaultNamespaces() except with the array values changed to ' '
 983+ * where it found '_', useful for producing output to be displayed
 984+ * e.g. in <select> forms.
 985+ *
 986+ * @static
 987+ * @param $includeHidden
 988+ * @return array
 989+ */
 990+ function &getFormattedDefaultNamespaces($includeHidden=false) {
 991+ $ns = Namespace::getDefaultNamespaces($includeHidden);
 992+ foreach($ns as $k => $v) {
 993+ $ns[$k] = strtr($v, '_', ' ');
 994+ }
 995+ return $ns;
 996+ }
844997
845998 /**
846999 * Load or reload namespace definitions from the database
8471000 * into a global array.
8481001 *
 1002+ * @param $purgeCache If definitions exist in memory, should
 1003+ * they be reloaded anyway?
 1004+ *
8491005 * @static
8501006 */
851 - function load() {
 1007+ function load($purgeCache=false) {
8521008
853 - global $wgNamespaces;
 1009+ global $wgNamespaces, $wgMemc, $wgDBname;
 1010+ $key="$wgDBname:namespaces:list";
 1011+ if(!$purgeCache) {
 1012+ $fromMemory = $wgMemc->get($key);
 1013+ if(is_array($fromMemory)) {
 1014+ # Cached definitions found
 1015+ $wgNamespaces=$fromMemory;
 1016+ return true;
 1017+ }
 1018+ }
8541019 $wgNamespaces = array();
8551020 $dbr =& wfGetDB( DB_SLAVE );
8561021 $res = $dbr->select( 'namespace',
@@ -863,6 +1028,12 @@
8641029 # properties which are accessed below.
8651030 $id=$row->ns_id;
8661031 $wgNamespaces[$id]=new Namespace();
 1032+
 1033+ # Cannot currently be changed through the UI - is
 1034+ # there a need for it to be changeable?
 1035+ $wgNamespaces[$id]->setMovable(
 1036+ $id < NS_MAIN || $id==NS_IMAGE ||
 1037+ $id==NS_CATEGORY ? false : true );
8671038 $wgNamespaces[$id]->setIndex($id);
8681039 $wgNamespaces[$id]->setSystemType($row->ns_system);
8691040 $wgNamespaces[$id]->setSearchedByDefault($row->ns_search_default);
@@ -886,6 +1057,7 @@
8871058 }
8881059 }
8891060 $dbr->freeResult( $res );
 1061+ $wgMemc->set($key,$wgNamespaces);
8901062 }
8911063
8921064 /**
@@ -973,18 +1145,6 @@
9741146 return array(NS_RESULT=>NS_PSEUDO_CONVERTED);
9751147
9761148 }
977 - /**
978 - * How many pages does this namespace contain?
979 - * @return The number of pages
980 - */
981 - function countPages() {
982 - $dbs =& wfGetDB(DB_SLAVE);
983 - return $dbs->selectField(
984 - 'page',
985 - 'count(*)',
986 - array('page_namespace'=>$this->getIndex())
987 - );
988 - }
9891149
9901150 }
9911151
Index: branches/wikidata/phase3/includes/LogPage.php
@@ -41,7 +41,7 @@
4242 * Constructor
4343 *
4444 * @param string $type One of '', 'block', 'protect', 'rights', 'delete',
45 - * 'upload', 'move'
 45+ * 'upload', 'move', 'namespace'
4646 * @param bool $rc Whether to update recent changes as well as the logging table
4747 */
4848 function LogPage( $type, $rc = true ) {
@@ -92,7 +92,7 @@
9393 * @static
9494 */
9595 function validTypes() {
96 - static $types = array( '', 'block', 'protect', 'rights', 'delete', 'upload', 'move' );
 96+ static $types = array( '', 'block', 'protect', 'rights', 'delete', 'upload', 'move', 'namespace' );
9797 wfRunHooks( 'LogPageValidTypes', array( &$types ) );
9898 return $types;
9999 }
@@ -115,7 +115,8 @@
116116 'rights' => 'bureaucratlog',
117117 'delete' => 'dellogpage',
118118 'upload' => 'uploadlogpage',
119 - 'move' => 'movelogpage'
 119+ 'move' => 'movelogpage',
 120+ 'namespace' => 'namespacelogpage',
120121 );
121122 wfRunHooks( 'LogPageLogName', array( &$typeText ) );
122123
@@ -133,7 +134,8 @@
134135 'rights' => 'rightslogtext',
135136 'delete' => 'dellogpagetext',
136137 'upload' => 'uploadlogpagetext',
137 - 'move' => 'movelogpagetext'
 138+ 'move' => 'movelogpagetext',
 139+ 'namespace' => 'namespacelogtext',
138140 );
139141 wfRunHooks( 'LogPageLogHeader', array( &$headerText ) );
140142
@@ -162,7 +164,12 @@
163165 'upload/upload' => 'uploadedimage',
164166 'upload/revert' => 'uploadedimage',
165167 'move/move' => '1movedto2',
166 - 'move/move_redir' => '1movedto2_redir'
 168+ 'move/move_redir' => '1movedto2_redir',
 169+
 170+ 'namespace/add' => 'namespaceaddlog',
 171+ 'namespace/delete' => 'namespacedeletelog',
 172+ 'namespace/modify' => 'namespacemodifylog',
 173+ 'namespace/pseudo' => 'namespacepseudolog',
167174 );
168175 wfRunHooks( 'LogPageActionText', array( &$actions ) );
169176
@@ -206,7 +213,7 @@
207214
208215 /**
209216 * Add a log entry
210 - * @param string $action one of '', 'block', 'protect', 'rights', 'delete', 'upload', 'move', 'move_redir'
 217+ * @param string $action one of '', 'block', 'protect', 'rights', 'delete', 'upload', 'move', 'move_redir', 'namespace'
211218 * @param object &$target A title object.
212219 * @param string $comment Description associated
213220 * @param array $params Parameters passed later to wfMsg.* functions
Index: branches/wikidata/phase3/includes/SpecialNamespaces.php
@@ -69,7 +69,7 @@
7070 $talksuffix = wfEscapeJsString(wfMsgForContent('talkpagesuffix'));
7171
7272 # For the namespace selection box
73 - $name_array = Namespace::getFormattedDefaultNamespaces();
 73+ $name_array = Namespace::getFormattedDefaultNamespaces(true);
7474 $noparent = wfMsg('no_parent_namespace');
7575 $name_array[key($name_array)-1] = $noparent;
7676
@@ -323,7 +323,7 @@
324324 $wgOut->addHTML( $htmlform );
325325
326326 // Pseudonamespace converter
327 - $all_name_array = Namespace::getFormattedDefaultNamespaces();
 327+ $all_name_array = Namespace::getFormattedDefaultNamespaces(true);
328328 $pseudons_select=$this->getSelector($all_name_array);
329329 $wgOut->addWikiText( wfMsg( 'fix_pseudonamespaces_header' ) );
330330 $phtmlform ='
@@ -447,9 +447,32 @@
448448 // Report success to user
449449 $wgOut->addWikiText($complete);
450450 $this->showForm();
 451+
 452+ $this->logNs('add',$nsname);
 453+ if($nscreatetalk) {
 454+ $this->logNs('add',$nstalkname);
 455+ }
451456 }
452457
453458 /**
 459+ * Convenient access to the logging functions
 460+ * @param $action - 'add','delete','modify' or 'pseudo'
 461+ * @param $ns - name of the namespace
 462+ * @param $tns - for pseudonamespaces, name of the target namespace
 463+ */
 464+ function logNs($action,$ns='',$tns='') {
 465+ $log = new LogPage( 'namespace' );
 466+ $dummyTitle = Title::makeTitle( 0, '' );
 467+ if($action=='pseudo') {
 468+ $log->addEntry( $action,$dummyTitle,'',array($ns,$tns));
 469+ } elseif($action=='modify') {
 470+ $log->addEntry( $action,$dummyTitle,'');
 471+ } else {
 472+ $log->addEntry( $action,$dummyTitle,'',array($ns));
 473+ }
 474+ }
 475+
 476+ /**
454477 * Modify, delete or add namespace names, set default names,
455478 * or change namespace properties. Uses the request data from
456479 * the form. Note that we have to create a new namespace object,
@@ -545,15 +568,18 @@
546569 # Does the name exist and is it non-empty?
547570 if(
548571 !is_null($dindex)
549 - && array_key_exists($dindex, $newns[$nsindex]->names)
 572+ && array_key_exists($dindex,
 573+ $newns[$nsindex]->names)
550574 && !empty($newns[$nsindex]->names[$dindex])
551575 ) {
552576 # Use this default name.
553577 $newns[$nsindex]->setDefaultNameIndex($dindex);
554578 } else {
555 - # We have lost our default name, perhaps it was deleted.
556 - # Get a new one if possible.
557 - $newns[$nsindex]->setDefaultNameIndex($newns[$nsindex]->getNewDefaultNameIndex());
 579+ # We have lost our default name, perhaps it
 580+ # was deleted. Get a new one if possible.
 581+ $newns[$nsindex]->setDefaultNameIndex(
 582+ $newns[$nsindex]->getNewDefaultNameIndex()
 583+ );
558584 }
559585 }
560586
@@ -562,20 +588,34 @@
563589 if( $nrv[NS_RESULT] == NS_NAME_ISSUES ) {
564590 $this->showForm(
565591 wfMsg(
566 - 'namespace_error',
567 - $nns->getDefaultName()),
568 - $this->nameIssues($nrv)
 592+ 'namespace_error',
 593+ $nns->getDefaultName()),
 594+ $this->nameIssues($nrv)
569595 );
570596 return false;
 597+ } elseif($nrv[NS_RESULT] == NS_MISSING) {
 598+ $this->showForm(
 599+ wfmsg('namespace_has_gone_missing',
 600+ $nns->getIndex())
 601+ );
 602+ return false;
571603 }
 604+ }
 605+
 606+ # Only do anything if everything can be done successfully.
 607+ foreach($newns as $nns) {
572608 $nns->save();
573609 }
574610
 611+ # Unfortunately, NS_IDENTICAL does not work consistently
 612+ # atm, so we can only add a generic log entry.
 613+ $this->logNs('modify');
 614+
575615 # IMPORTANT: The namespace name indexes are unpredictable when
576616 # serialized, so we have to reload the definitions from the
577617 # database at this point; otherwise, there could be index
578618 # mismatches.
579 - Namespace::load();
 619+ Namespace::load(true);
580620
581621 # Return to the namespace manager with the changes made.
582622 $wgOut->addWikiText( wfMsg('namespace_changes_saved') );
@@ -677,7 +717,7 @@
678718 /* There should be no delete links for namespaces which cannot
679719 be deleted, but let's catch two possible problems just in case. */
680720 if(!array_key_exists( $nsid, $wgNamespaces) ) {
681 - $this->showForm( wfMsg('namespace_not_deletable') , wfMsg('namespace_not_deletable_missing', $nsid) );
 721+ $this->showForm( wfMsg('namespace_not_deletable') , wfMsg('namespace_has_gone_missing', $nsid) );
682722 return false;
683723 } elseif( $wgNamespaces[$nsid]->isSystemNamespace() ) {
684724 $this->showForm( wfMsg('namespace_not_deletable') , wfMsg('namespace_not_deletable_system', $nsid) );
@@ -696,6 +736,7 @@
697737 if( $drv[NS_RESULT] == NS_DELETED ) {
698738 $wgOut->addWikiText( wfMsg('namespace_deleted',$nsdeletename) );
699739 $this->showForm();
 740+ $this->logNs('delete',$nsdeletename);
700741 return true;
701742 } elseif( $drv[NS_RESULT] == NS_NAME_ISSUES ) {
702743 $this->showForm( wfMsg('namespace_delete_error',$nsdeletename),$this->nameIssues($drv) );
@@ -750,6 +791,7 @@
751792 }
752793 } else {
753794 $wgOut->addWikiText(wfMsg('pseudonamespace_converted', $prefix, $wgNamespaces[$targetid]->getDefaultName()));
 795+ $this->logNs('pseudo',$prefix,$wgNamespaces[$targetid]->getDefaultName());
754796 }
755797 if($converttalk) {
756798 # A pseudonamespace, by definition, exists in the
Index: branches/wikidata/phase3/languages/Language.php
@@ -2226,6 +2226,14 @@
22272227 'pseudonamespace_cannot_merge'=>'The target namespace contains pages. You have not specified that you want to merge into a non-empty namespace, or do not have permission to do so. This action is restricted because it is potentially irreversible.',
22282228 'pseudonamespace_title_dupes'=>'The target namespace already contains pages with the following titles:',
22292229
 2230+# Namespace logging
 2231+'namespacelogpage'=>'Namespace_log',
 2232+'namespacelogtext'=>'This is a log of all changes made through the namespace manager.',
 2233+'namespaceaddlog'=>'Added namespace "$2"',
 2234+'namespacedeletelog'=>'Deleted namespace "$2"',
 2235+'namespacemodifylog'=>'Modified namespace definitions',
 2236+'namespacepseudolog'=>'Converted pseudonamespace "$2" into real namespace "$3"',
 2237+
22302238 # This is appended via JavaScript to the entered namsepace name
22312239 # as a suggested talkpage name in Special:Namespaces. If set to '-',
22322240 # it will not be used.
@@ -2247,7 +2255,7 @@
22482256 'namespace_delete_name'=>'Delete',
22492257 'namespace_save_changes'=>'Save changes',
22502258 'namespace_not_deletable'=>'The namespace cannot be deleted.',
2251 -'namespace_not_deletable_missing'=>'A namespace with the number $1 was not found.',
 2259+'namespace_has_gone_missing'=>'A namespace with the number $1 was not found.',
22522260 'namespace_not_deletable_system'=>'The namespace with the number $1 is a system namespace which is required for the operation of MediaWiki.',
22532261
22542262 # Other namespace stuff

Status & tagging log