Index: trunk/phase3/maintenance/namespaceDupes.php |
— | — | @@ -31,32 +31,59 @@ |
32 | 32 | appended after the article name. |
33 | 33 | --prefix=<text> : Do an explicit check for the given title prefix |
34 | 34 | in place of the standard namespace list. |
| 35 | + --verbose : Display output for checked namespaces without conflicts |
35 | 36 | |
36 | 37 | END; |
37 | 38 | die; |
38 | 39 | } |
39 | 40 | |
40 | 41 | class NamespaceConflictChecker { |
41 | | - function NamespaceConflictChecker( $db ) { |
| 42 | + function NamespaceConflictChecker( $db, $verbose=false ) { |
42 | 43 | $this->db = $db; |
| 44 | + $this->verbose = $verbose; |
43 | 45 | } |
44 | 46 | |
45 | 47 | function checkAll( $fix, $suffix = '' ) { |
46 | 48 | global $wgContLang, $wgNamespaceAliases, $wgCanonicalNamespaceNames; |
| 49 | + global $wgCapitalLinks; |
47 | 50 | |
48 | 51 | $spaces = array(); |
49 | | - foreach( $wgContLang->getNamespaces() as $ns => $name ) { |
50 | | - $spaces[$name] = $ns; |
| 52 | + |
| 53 | + // List interwikis first, so they'll be overridden |
| 54 | + // by any conflicting local namespaces. |
| 55 | + foreach( $this->getInterwikiList() as $prefix ) { |
| 56 | + $name = $wgContLang->ucfirst( $prefix ); |
| 57 | + $spaces[$name] = 0; |
51 | 58 | } |
| 59 | + |
| 60 | + // Now pull in all canonical and alias namespaces... |
52 | 61 | foreach( $wgCanonicalNamespaceNames as $ns => $name ) { |
53 | | - $spaces[$name] = $ns; |
| 62 | + // This includes $wgExtraNamespaces |
| 63 | + if( $name !== '' ) { |
| 64 | + $spaces[$name] = $ns; |
| 65 | + } |
54 | 66 | } |
| 67 | + foreach( $wgContLang->getNamespaces() as $ns => $name ) { |
| 68 | + if( $name !== '' ) { |
| 69 | + $spaces[$name] = $ns; |
| 70 | + } |
| 71 | + } |
55 | 72 | foreach( $wgNamespaceAliases as $name => $ns ) { |
56 | 73 | $spaces[$name] = $ns; |
57 | 74 | } |
58 | 75 | foreach( $wgContLang->namespaceAliases as $name => $ns ) { |
59 | 76 | $spaces[$name] = $ns; |
60 | 77 | } |
| 78 | + |
| 79 | + if( !$wgCapitalLinks ) { |
| 80 | + // We'll need to check for lowercase keys as well, |
| 81 | + // since we're doing case-sensitive searches in the db. |
| 82 | + foreach( array_values( $spaces ) as $name => $ns ) { |
| 83 | + $lcname = $wgContLang->lcfirst( $name ); |
| 84 | + $spaces[$lcname] = $ns; |
| 85 | + } |
| 86 | + } |
| 87 | + ksort( $spaces ); |
61 | 88 | asort( $spaces ); |
62 | 89 | |
63 | 90 | $ok = true; |
— | — | @@ -65,21 +92,34 @@ |
66 | 93 | } |
67 | 94 | return $ok; |
68 | 95 | } |
| 96 | + |
| 97 | + private function getInterwikiList() { |
| 98 | + $result = $this->db->select( 'interwiki', array( 'iw_prefix' ) ); |
| 99 | + while( $row = $this->db->fetchObject( $result ) ) { |
| 100 | + $prefixes[] = $row->iw_prefix; |
| 101 | + } |
| 102 | + $this->db->freeResult( $result ); |
| 103 | + return $prefixes; |
| 104 | + } |
69 | 105 | |
70 | 106 | function checkNamespace( $ns, $name, $fix, $suffix = '' ) { |
71 | | - echo "Checking namespace $ns: \"$name\"\n"; |
72 | | - if( $name == '' ) { |
73 | | - echo "... skipping article namespace\n"; |
74 | | - return true; |
| 107 | + if( $ns == 0 ) { |
| 108 | + $header = "Checking interwiki prefix: \"$name\"\n"; |
| 109 | + } else { |
| 110 | + $header = "Checking namespace $ns: \"$name\"\n"; |
75 | 111 | } |
76 | 112 | |
77 | 113 | $conflicts = $this->getConflicts( $ns, $name ); |
78 | 114 | $count = count( $conflicts ); |
79 | 115 | if( $count == 0 ) { |
80 | | - echo "... no conflicts detected!\n"; |
| 116 | + if( $this->verbose ) { |
| 117 | + echo $header; |
| 118 | + echo "... no conflicts detected!\n"; |
| 119 | + } |
81 | 120 | return true; |
82 | 121 | } |
83 | 122 | |
| 123 | + echo $header; |
84 | 124 | echo "... $count conflicts detected:\n"; |
85 | 125 | $ok = true; |
86 | 126 | foreach( $conflicts as $row ) { |
— | — | @@ -106,11 +146,18 @@ |
107 | 147 | |
108 | 148 | $prefix = $this->db->strencode( $name ); |
109 | 149 | $likeprefix = str_replace( '_', '\\_', $prefix); |
| 150 | + $encNamespace = $this->db->addQuotes( $ns ); |
110 | 151 | |
111 | | - $sql = "SELECT {$page}_id AS id, |
112 | | - {$page}_title AS oldtitle, |
113 | | - $ns AS namespace, |
114 | | - TRIM(LEADING '$prefix:' FROM {$page}_title) AS title |
| 152 | + $titleSql = "TRIM(LEADING '$prefix:' FROM {$page}_title)"; |
| 153 | + if( $ns == 0 ) { |
| 154 | + // An interwiki; try an alternate encoding with '-' for ':' |
| 155 | + $titleSql = "CONCAT('$prefix-',$titleSql)"; |
| 156 | + } |
| 157 | + |
| 158 | + $sql = "SELECT {$page}_id AS id, |
| 159 | + {$page}_title AS oldtitle, |
| 160 | + $encNamespace AS namespace, |
| 161 | + $titleSql AS title |
115 | 162 | FROM {$table} |
116 | 163 | WHERE {$page}_namespace=0 |
117 | 164 | AND {$page}_title LIKE '$likeprefix:%'"; |
— | — | @@ -181,12 +228,14 @@ |
182 | 229 | |
183 | 230 | $wgTitle = Title::newFromText( 'Namespace title conflict cleanup script' ); |
184 | 231 | |
| 232 | +$verbose = isset( $options['verbose'] ); |
185 | 233 | $fix = isset( $options['fix'] ); |
186 | 234 | $suffix = isset( $options['suffix'] ) ? $options['suffix'] : ''; |
187 | 235 | $prefix = isset( $options['prefix'] ) ? $options['prefix'] : ''; |
188 | 236 | $key = isset( $options['key'] ) ? intval( $options['key'] ) : 0; |
| 237 | + |
189 | 238 | $dbw = wfGetDB( DB_MASTER ); |
190 | | -$duper = new NamespaceConflictChecker( $dbw ); |
| 239 | +$duper = new NamespaceConflictChecker( $dbw, $verbose ); |
191 | 240 | |
192 | 241 | if( $prefix ) { |
193 | 242 | $retval = $duper->checkPrefix( $key, $prefix, $fix, $suffix ); |