Index: branches/category-redirects/maintenance/tables.sql |
— | — | @@ -521,7 +521,8 @@ |
522 | 522 | -- it has this name (in the Category namespace). |
523 | 523 | cat_title varchar(255) binary NOT NULL, |
524 | 524 | |
525 | | - -- The numbers of member pages (including categories and media), subcatego- |
| 525 | + -- The numbers of member pages (including categories, media and pages |
| 526 | + -- belonging to a category redirecting to this category), subcatego- |
526 | 527 | -- ries, and Image: namespace members, respectively. These are signed to |
527 | 528 | -- make underflow more obvious. We make the first number include the second |
528 | 529 | -- two for better sorting: subtracting for display is easy, adding for order- |
— | — | @@ -529,6 +530,7 @@ |
530 | 531 | cat_pages int signed NOT NULL default 0, |
531 | 532 | cat_subcats int signed NOT NULL default 0, |
532 | 533 | cat_files int signed NOT NULL default 0, |
| 534 | + cat_redir_pages int signed NOT NULL default 0, |
533 | 535 | |
534 | 536 | -- Reserved for future use |
535 | 537 | cat_hidden tinyint unsigned NOT NULL default 0, |
Index: branches/category-redirects/includes/CategoryPage.php |
— | — | @@ -231,7 +231,7 @@ |
232 | 232 | $res = $dbr->select( |
233 | 233 | array( 'page', 'categorylinks', 'category' ), |
234 | 234 | array( 'page_title', 'page_namespace', 'page_len', 'page_is_redirect', 'cl_sortkey', |
235 | | - 'cat_id', 'cat_redir', 'cat_title', 'cat_subcats', 'cat_pages', 'cat_files' ), |
| 235 | + 'cat_id', 'cat_redir', 'cat_title', 'cat_subcats', 'cat_pages', 'cat_files', 'cat_redir_pages' ), |
236 | 236 | array( $pageCondition, |
237 | 237 | 'cl_' . $linkedFrom => $cat_id ), |
238 | 238 | __METHOD__, |
Index: branches/category-redirects/includes/Article.php |
— | — | @@ -116,8 +116,9 @@ |
117 | 117 | $dbw->update( |
118 | 118 | 'category', |
119 | 119 | array( 'cat_redir' => $to_id), |
120 | | - array( 'cat_title' => $this->mTitle->getDBKey() ), |
| 120 | + array( 'cat_id' => $cur_id ), |
121 | 121 | __METHOD__ ); |
| 122 | + $to->addRedirFrom( $cur ); |
122 | 123 | $update = new CategoryLinksUpdate( $retval, $cur_id, $cur_id, $to_id ); |
123 | 124 | $update->doUpdate(); |
124 | 125 | } |
— | — | @@ -1206,8 +1207,9 @@ |
1207 | 1208 | $dbw->update( |
1208 | 1209 | 'category', |
1209 | 1210 | array( 'cat_redir' => $to_id), |
1210 | | - array( 'cat_title' => $this->mTitle->getDBKey() ), |
| 1211 | + array( 'cat_id' => $cur_id ), |
1211 | 1212 | __METHOD__ ); |
| 1213 | + $to_id->addRedirFrom( $cur ); |
1212 | 1214 | $target = $cur->getTarget(); |
1213 | 1215 | $update = new CategoryLinksUpdate( $redirectTitle, $cur_id, $target, $to_id ); |
1214 | 1216 | $update->doUpdate(); |
— | — | @@ -2383,14 +2385,18 @@ |
2384 | 2386 | |
2385 | 2387 | # Fix category table counts |
2386 | 2388 | $cats = array(); |
| 2389 | + $cats_redir = array(); |
2387 | 2390 | $res = $dbw->select( array( 'categorylinks', 'category' ), |
2388 | | - 'cat_title', |
| 2391 | + 'cat_id', 'cat_redir', |
2389 | 2392 | array( 'cl_from' => $id, 'cl_inline=cat_id' ), |
2390 | 2393 | __METHOD__ ); |
2391 | 2394 | foreach( $res as $row ) { |
2392 | | - $cats []= $row->cat_title; |
| 2395 | + $cats [] = $row->cat_id; |
| 2396 | + if ( $row->cat_redir != null ) { |
| 2397 | + $cats_redir [] = $row->cat_redir; |
| 2398 | + } |
2393 | 2399 | } |
2394 | | - $this->updateCategoryCounts( array(), $cats ); |
| 2400 | + $this->updateCategoryCounts( array(), $cats, array(), $cats_redir ); |
2395 | 2401 | |
2396 | 2402 | # Now that it's safely backed up, delete it |
2397 | 2403 | $dbw->delete( 'page', array( 'page_id' => $id ), __METHOD__); |
— | — | @@ -3483,11 +3489,13 @@ |
3484 | 3490 | * |
3485 | 3491 | * It is assumed that all categories have already an entry in the category table. |
3486 | 3492 | * |
3487 | | - * @param $added array The names of categories that were added |
3488 | | - * @param $deleted array The names of categories that were deleted |
| 3493 | + * @param $added array The ids of categories that were added |
| 3494 | + * @param $deleted array The ids of categories that were deleted |
| 3495 | + * @param $added_redir array The ids of categories that were added through a category redirect |
| 3496 | + * @param $removed_redir array The ids of categories that were removed through a category redirect |
3489 | 3497 | * @return null |
3490 | 3498 | */ |
3491 | | - public function updateCategoryCounts( $added, $deleted ) { |
| 3499 | + public function updateCategoryCounts( $added, $deleted, $added_redir, $removed_redir ) { |
3492 | 3500 | $ns = $this->mTitle->getNamespace(); |
3493 | 3501 | $dbw = wfGetDB( DB_MASTER ); |
3494 | 3502 | |
— | — | @@ -3508,7 +3516,7 @@ |
3509 | 3517 | $dbw->update( |
3510 | 3518 | 'category', |
3511 | 3519 | $addFields, |
3512 | | - array( 'cat_title' => $added ), |
| 3520 | + array( 'cat_id' => $added ), |
3513 | 3521 | __METHOD__ |
3514 | 3522 | ); |
3515 | 3523 | } |
— | — | @@ -3516,9 +3524,29 @@ |
3517 | 3525 | $dbw->update( |
3518 | 3526 | 'category', |
3519 | 3527 | $removeFields, |
3520 | | - array( 'cat_title' => $deleted ), |
| 3528 | + array( 'cat_id' => $deleted ), |
3521 | 3529 | __METHOD__ |
3522 | 3530 | ); |
3523 | 3531 | } |
| 3532 | + |
| 3533 | + $addFields[] = 'cat_redir_pages = cat_redir_pages + 1'; |
| 3534 | + $removeFields[] = 'cat_redir_pages = cat_redir_pages - 1'; |
| 3535 | + |
| 3536 | + if ( $added_redir ) { |
| 3537 | + $dbw->update( |
| 3538 | + 'category', |
| 3539 | + $addFields, |
| 3540 | + array( 'cat_id' => $added_redir ), |
| 3541 | + __METHOD__ |
| 3542 | + ); |
| 3543 | + } |
| 3544 | + if ( $deleted_redir ) { |
| 3545 | + $dbw->update( |
| 3546 | + 'category', |
| 3547 | + $removeFields, |
| 3548 | + array( 'cat_id' => $deleted_redir ), |
| 3549 | + __METHOD__ |
| 3550 | + ); |
| 3551 | + } |
3524 | 3552 | } |
3525 | 3553 | } |
Index: branches/category-redirects/includes/LinksUpdate.php |
— | — | @@ -124,7 +124,6 @@ |
125 | 125 | $this->getTemplateInsertions( $existing ) ); |
126 | 126 | |
127 | 127 | # Category links |
128 | | - ### existing doit être titres -> keys pour comparer avec this->mCategories |
129 | 128 | $existing = $this->getExistingCategories( ); |
130 | 129 | |
131 | 130 | $categoryDeletes = $this->getCategoryDeletions( $existing ); |
— | — | @@ -145,9 +144,7 @@ |
146 | 145 | |
147 | 146 | # Invalidate all categories which were added, deleted or changed (set symmetric difference) |
148 | 147 | $categoryUpdates = $categoryInserts + $categoryDeletes; |
149 | | - ### besoin des titres |
150 | 148 | $this->invalidateCategories( $categoryUpdates ); |
151 | | - ### ce serait mieux avec des IDs |
152 | 149 | $this->updateCategoryCounts( $categoryInserts, $categoryDeletes ); |
153 | 150 | |
154 | 151 | # Page properties |
— | — | @@ -300,8 +297,30 @@ |
301 | 298 | */ |
302 | 299 | function updateCategoryCounts( $added, $deleted ) { |
303 | 300 | $a = new Article($this->mTitle); |
304 | | - $a->updateCategoryCounts( |
305 | | - array_keys( $added ), array_keys( $deleted ) |
| 301 | + $added_ids = array(); |
| 302 | + $added_redir_ids = array(); |
| 303 | + foreach ( $added as $title => $sort ) { |
| 304 | + $cat = $this->mCatObjects[$title]; |
| 305 | + $id = $cat->getID(); |
| 306 | + $added_ids [] = $id; |
| 307 | + $redir = $cat->getRedir(); |
| 308 | + if ( $redir != null ) { |
| 309 | + $added_redir_ids[] = $redir; |
| 310 | + } |
| 311 | + } |
| 312 | + $deleted_ids = array(); |
| 313 | + $deleted_redir_ids = array(); |
| 314 | + foreach ( $deleted as $title => $sort ) { |
| 315 | + $cat = $this->mCatObjects[$title]; |
| 316 | + $id = $cat->getID(); |
| 317 | + $deleted_ids [] = $id; |
| 318 | + $redir = $cat->getRedir(); |
| 319 | + if ( $redir != null ) { |
| 320 | + $deleted_redir_ids[] = $redir; |
| 321 | + } |
| 322 | + } |
| 323 | + $a->updateCategoryCounts( |
| 324 | + $added_ids, $deleted_ids, $added_redir_ids, $deleted_redir_ids |
306 | 325 | ); |
307 | 326 | } |
308 | 327 | |
Index: branches/category-redirects/includes/Category.php |
— | — | @@ -14,8 +14,8 @@ |
15 | 15 | private $mRedir = null; |
16 | 16 | /** Category page title */ |
17 | 17 | private $mTitle = null; |
18 | | - /** Counts of membership (cat_pages, cat_subcats, cat_files) */ |
19 | | - private $mPages = null, $mSubcats = null, $mFiles = null; |
| 18 | + /** Counts of membership (cat_pages, cat_subcats, cat_files, cat_redir_pages) */ |
| 19 | + private $mPages = null, $mSubcats = null, $mFiles = null, $mRedirPages = null; |
20 | 20 | |
21 | 21 | private function __construct() {} |
22 | 22 | |
— | — | @@ -49,30 +49,32 @@ |
50 | 50 | # Okay, there were no contents. Nothing to initialize. |
51 | 51 | if ( $this->mTitle ) { |
52 | 52 | # If there is a title object but no record in the category table, treat this as an empty category |
53 | | - $this->mID = false; |
54 | | - $this->mRedir = false; |
55 | | - $this->mName = $this->mTitle->getDBKey(); |
56 | | - $this->mPages = 0; |
57 | | - $this->mSubcats = 0; |
58 | | - $this->mFiles = 0; |
| 53 | + $this->mID = false; |
| 54 | + $this->mRedir = false; |
| 55 | + $this->mName = $this->mTitle->getDBKey(); |
| 56 | + $this->mPages = 0; |
| 57 | + $this->mSubcats = 0; |
| 58 | + $this->mFiles = 0; |
| 59 | + $this->mRedirPages = 0; |
59 | 60 | |
60 | 61 | return true; |
61 | 62 | } else { |
62 | 63 | return false; # Fail |
63 | 64 | } |
64 | 65 | } |
65 | | - $this->mID = $row->cat_id; |
66 | | - $this->mRedir = $row->cat_redir; |
67 | | - $this->mName = $row->cat_title; |
68 | | - $this->mPages = $row->cat_pages; |
69 | | - $this->mSubcats = $row->cat_subcats; |
70 | | - $this->mFiles = $row->cat_files; |
| 66 | + $this->mID = $row->cat_id; |
| 67 | + $this->mRedir = $row->cat_redir; |
| 68 | + $this->mName = $row->cat_title; |
| 69 | + $this->mPages = $row->cat_pages; |
| 70 | + $this->mSubcats = $row->cat_subcats; |
| 71 | + $this->mFiles = $row->cat_files; |
| 72 | + $this->mRedirPages = $row->cat_redir_pages; |
71 | 73 | |
72 | 74 | # (bug 13683) If the count is negative, then 1) it's obviously wrong |
73 | 75 | # and should not be kept, and 2) we *probably* don't have to scan many |
74 | 76 | # rows to obtain the correct figure, so let's risk a one-time recount. |
75 | 77 | if( $this->mPages < 0 || $this->mSubcats < 0 || |
76 | | - $this->mFiles < 0 ) { |
| 78 | + $this->mFiles < 0 || $this->mRedirPages < 0 ) { |
77 | 79 | $this->refreshCounts(); |
78 | 80 | } |
79 | 81 | |
— | — | @@ -154,18 +156,20 @@ |
155 | 157 | $cat->mName = $title->getDBKey(); # if we have a title object, fetch the category name from there |
156 | 158 | } |
157 | 159 | |
158 | | - $cat->mID = false; |
159 | | - $cat->mRedir = false; |
160 | | - $cat->mSubcats = 0; |
161 | | - $cat->mPages = 0; |
162 | | - $cat->mFiles = 0; |
| 160 | + $cat->mID = false; |
| 161 | + $cat->mRedir = false; |
| 162 | + $cat->mSubcats = 0; |
| 163 | + $cat->mPages = 0; |
| 164 | + $cat->mFiles = 0; |
| 165 | + $cat->mRedirPages = 0; |
163 | 166 | } else { |
164 | | - $cat->mName = $row->cat_title; |
165 | | - $cat->mID = $row->cat_id; |
166 | | - $cat->mRedir = $row->cat_redir; |
167 | | - $cat->mSubcats = $row->cat_subcats; |
168 | | - $cat->mPages = $row->cat_pages; |
169 | | - $cat->mFiles = $row->cat_files; |
| 167 | + $cat->mName = $row->cat_title; |
| 168 | + $cat->mID = $row->cat_id; |
| 169 | + $cat->mRedir = $row->cat_redir; |
| 170 | + $cat->mSubcats = $row->cat_subcats; |
| 171 | + $cat->mPages = $row->cat_pages; |
| 172 | + $cat->mFiles = $row->cat_files; |
| 173 | + $cat->mRedirPages = $row->cat_redir_pages; |
170 | 174 | } |
171 | 175 | |
172 | 176 | return $cat; |
— | — | @@ -183,6 +187,11 @@ |
184 | 188 | public function getSubcatCount() { return $this->getX( 'mSubcats' ); } |
185 | 189 | /** @return mixed Number of member files, or false on failure */ |
186 | 190 | public function getFileCount() { return $this->getX( 'mFiles' ); } |
| 191 | + /** |
| 192 | + * @return mixed Number of member pages that got included through a redirect, |
| 193 | + * or false on failure |
| 194 | + **/ |
| 195 | + public function getRedirPages() { return $this->getX( 'mRedirPages' ); } |
187 | 196 | |
188 | 197 | /** |
189 | 198 | * @return mixed The Title for this category, or false on failure. |
— | — | @@ -216,6 +225,7 @@ |
217 | 226 | return $redir; |
218 | 227 | } |
219 | 228 | } |
| 229 | + |
220 | 230 | /** |
221 | 231 | * Refresh the counts for this category. |
222 | 232 | * |
— | — | @@ -235,21 +245,18 @@ |
236 | 246 | } else { |
237 | 247 | # Let's be sure that the row exists in the table. We don't need to |
238 | 248 | # do this if we got the row from the table in initialization! |
239 | | - $dbw->insert( |
240 | | - 'category', |
241 | | - array( 'cat_title' => $this->mName ), |
242 | | - __METHOD__, |
243 | | - 'IGNORE' |
244 | | - ); |
| 249 | + $this->insert(); |
245 | 250 | } |
246 | 251 | |
247 | 252 | $cond1 = $dbw->conditional( 'page_namespace='.NS_CATEGORY, 1, 'NULL' ); |
248 | 253 | $cond2 = $dbw->conditional( 'page_namespace='.NS_IMAGE, 1, 'NULL' ); |
| 254 | + $cond3 = $dbw->conditional( 'cl_target=cl_inline', 'NULL', 1 ); |
249 | 255 | $result = $dbw->selectRow( |
250 | 256 | array( 'categorylinks', 'page' ), |
251 | 257 | array( 'COUNT(*) AS pages', |
252 | 258 | "COUNT($cond1) AS subcats", |
253 | | - "COUNT($cond2) AS files" |
| 259 | + "COUNT($cond2) AS files", |
| 260 | + "COUNT($cond3) AS redirs" |
254 | 261 | ), |
255 | 262 | array( 'cl_target' => $this->mID, 'page_id = cl_from' ), |
256 | 263 | __METHOD__, |
— | — | @@ -260,17 +267,19 @@ |
261 | 268 | array( |
262 | 269 | 'cat_pages' => $result->pages, |
263 | 270 | 'cat_subcats' => $result->subcats, |
264 | | - 'cat_files' => $result->files |
| 271 | + 'cat_files' => $result->files, |
| 272 | + 'cat_redir_pages' => $result->redirs |
265 | 273 | ), |
266 | | - array( 'cat_title' => $this->mName ), |
| 274 | + array( 'cat_id' => $this->mID ), |
267 | 275 | __METHOD__ |
268 | 276 | ); |
269 | 277 | $dbw->commit(); |
270 | 278 | |
271 | 279 | # Now we should update our local counts. |
272 | | - $this->mPages = $result->pages; |
273 | | - $this->mSubcats = $result->subcats; |
274 | | - $this->mFiles = $result->files; |
| 280 | + $this->mPages = $result->pages; |
| 281 | + $this->mSubcats = $result->subcats; |
| 282 | + $this->mFiles = $result->files; |
| 283 | + $this->mRedirPages = $result->redirs; |
275 | 284 | |
276 | 285 | return $ret; |
277 | 286 | } |
— | — | @@ -394,4 +403,18 @@ |
395 | 404 | } |
396 | 405 | return true; |
397 | 406 | } |
| 407 | + |
| 408 | + /** |
| 409 | + * Update the counts of the current category : add the pages from $from |
| 410 | + */ |
| 411 | + public function addRedirFrom( Category $from ) { |
| 412 | + $dbw = wfGetDB( DB_MASTER ); |
| 413 | + $c = $from->getPageCount(); |
| 414 | + $dbw->update( |
| 415 | + 'category', |
| 416 | + array( "cat_pages = cat_pages + $c", |
| 417 | + "cat_redir_pages = cat_redir_pages + $c" ), |
| 418 | + array( 'cat_id' => $this->mId ) |
| 419 | + ); |
| 420 | + } |
398 | 421 | } |