From: Aryeh Gregor Date: Tue, 3 Aug 2010 20:50:01 +0000 (+0000) Subject: Enable new category sort by default X-Git-Tag: 1.31.0-rc.0~35751 X-Git-Url: http://git.cyclocoop.org/?a=commitdiff_plain;h=7ec501be6a20672f61f2f4d0e84df9bbbab4bc6d;p=lhc%2Fweb%2Fwiklou.git Enable new category sort by default Patch best viewed with whitespace changes ignored. This will doubtless introduce a bunch of bugs. Please report any so I can fix them. If they're big enough and the fix isn't obvious, please revert. --- diff --git a/includes/CategoryPage.php b/includes/CategoryPage.php index 2b6a4c1be1..b12c13fe78 100644 --- a/includes/CategoryPage.php +++ b/includes/CategoryPage.php @@ -51,17 +51,12 @@ class CategoryPage extends Article { } function closeShowCategory() { - global $wgOut, $wgRequest, $wgExperimentalCategorySort; + global $wgOut, $wgRequest; - if ( $wgExperimentalCategorySort ) { - $from = $until = array(); - foreach ( array( 'page', 'subcat', 'file' ) as $type ) { - $from[$type] = $wgRequest->getVal( "{$type}from" ); - $until[$type] = $wgRequest->getVal( "{$type}until" ); - } - } else { - $from = $wgRequest->getVal( 'from' ); - $until = $wgRequest->getVal( 'until' ); + $from = $until = array(); + foreach ( array( 'page', 'subcat', 'file' ) as $type ) { + $from[$type] = $wgRequest->getVal( "{$type}from" ); + $until[$type] = $wgRequest->getVal( "{$type}until" ); } $viewer = new CategoryViewer( $this->mTitle, $from, $until, $wgRequest->getValues() ); @@ -184,7 +179,7 @@ class CategoryViewer { * else use sortkey... */ function getSubcategorySortChar( $title, $sortkey ) { - global $wgContLang, $wgExperimentalCategorySort; + global $wgContLang; if ( $title->getPrefixedText() == $sortkey ) { $word = $title->getDBkey(); @@ -192,11 +187,7 @@ class CategoryViewer { $word = $sortkey; } - if ( $wgExperimentalCategorySort ) { - $firstChar = $wgContLang->firstLetterForLists( $word ); - } else { - $firstChar = $wgContLang->firstChar( $word ); - } + $firstChar = $wgContLang->firstLetterForLists( $word ); return $wgContLang->convert( $firstChar ); } @@ -206,12 +197,7 @@ class CategoryViewer { */ function addImage( Title $title, $sortkey, $pageLength, $isRedirect = false ) { if ( $this->showGallery ) { - global $wgExperimentalCategorySort; - if ( $wgExperimentalCategorySort ) { - $flip = $this->flip['file']; - } else { - $flip = $this->flip; - } + $flip = $this->flip['file']; if ( $flip ) { $this->gallery->insert( $title ); } else { @@ -226,7 +212,7 @@ class CategoryViewer { * Add a miscellaneous page */ function addPage( $title, $sortkey, $pageLength, $isRedirect = false ) { - global $wgContLang, $wgExperimentalCategorySort; + global $wgContLang; $this->articles[] = $isRedirect ? '' . $this->getSkin()->link( @@ -238,29 +224,22 @@ class CategoryViewer { ) . '' : $this->getSkin()->link( $title ); - if ( $wgExperimentalCategorySort ) { - $this->articles_start_char[] = $wgContLang->convert( $wgContLang->firstLetterForLists( $sortkey ) ); - } else { - $this->articles_start_char[] = $wgContLang->convert( $wgContLang->firstChar( $sortkey ) ); - } + $this->articles_start_char[] = $wgContLang->convert( $wgContLang->firstLetterForLists( $sortkey ) ); } function finaliseCategoryState() { - global $wgExperimentalCategorySort; - if ( ( !$wgExperimentalCategorySort && $this->flip ) - || ( $wgExperimentalCategorySort && $this->flip['subcat'] ) ) { + if ( $this->flip['subcat'] ) { $this->children = array_reverse( $this->children ); $this->children_start_char = array_reverse( $this->children_start_char ); } - if ( ( !$wgExperimentalCategorySort && $this->flip ) - || ( $wgExperimentalCategorySort && $this->flip['page'] ) ) { + if ( $this->flip['page'] ) { $this->articles = array_reverse( $this->articles ); $this->articles_start_char = array_reverse( $this->articles_start_char ); } } function doCategoryQuery() { - global $wgExperimentalCategorySort, $wgContLang; + global $wgContLang; $dbr = wfGetDB( DB_SLAVE, 'category' ); @@ -276,107 +255,56 @@ class CategoryViewer { $joins = array( 'categorylinks' => array( 'INNER JOIN', 'cl_from = page_id' ), 'category' => array( 'LEFT JOIN', 'cat_title = page_title AND page_namespace = ' . NS_CATEGORY ) ); - if ( $wgExperimentalCategorySort ) { - # Copy-pasted from below, but that's okay, because the stuff below - # will be deleted when this becomes the default. - $this->nextPage = array( - 'page' => null, - 'subcat' => null, - 'file' => null, - ); - $this->flip = array( 'page' => false, 'subcat' => false, 'file' => false ); - - foreach ( array( 'page', 'subcat', 'file' ) as $type ) { - # Get the sortkeys for start/end, if applicable. Note that if - # the collation in the database differs from the one - # $wgContLang is using, pagination might go totally haywire. - $extraConds = array( 'cl_type' => $type ); - if ( $this->from[$type] !== null ) { - $extraConds[] = 'cl_sortkey >= ' - . $dbr->addQuotes( $wgContLang->convertToSortkey( $this->from[$type] ) ); - } elseif ( $this->until[$type] !== null ) { - $extraConds[] = 'cl_sortkey < ' - . $dbr->addQuotes( $wgContLang->convertToSortkey( $this->until[$type] ) ); - $this->flip[$type] = true; - } - - $res = $dbr->select( - $tables, - array_merge( $fields, array( 'cl_sortkey_prefix' ) ), - $conds + $extraConds, - __METHOD__, - $opts + array( 'ORDER BY' => $this->flip[$type] ? 'cl_sortkey DESC' : 'cl_sortkey' ), - $joins - ); - - $count = 0; - foreach ( $res as $row ) { - $title = Title::newFromRow( $row ); - $rawSortkey = $title->getCategorySortkey( $row->cl_sortkey_prefix ); - - if ( ++$count > $this->limit ) { - # We've reached the one extra which shows that there - # are additional pages to be had. Stop here... - $this->nextPage[$type] = $rawSortkey; - break; - } - - if ( $title->getNamespace() == NS_CATEGORY ) { - $cat = Category::newFromRow( $row, $title ); - $this->addSubcategoryObject( $cat, $rawSortkey, $row->page_len ); - } elseif ( $this->showGallery && $title->getNamespace() == NS_FILE ) { - $this->addImage( $title, $rawSortkey, $row->page_len, $row->page_is_redirect ); - } else { - $this->addPage( $title, $rawSortkey, $row->page_len, $row->page_is_redirect ); - } - } - } - - return; - } - - # Non-$wgExperimentalCategorySort stuff - - if ( $this->from != '' ) { - $pageCondition = 'cl_sortkey >= ' . $dbr->addQuotes( $this->from ); - $this->flip = false; - } elseif ( $this->until != '' ) { - $pageCondition = 'cl_sortkey < ' . $dbr->addQuotes( $this->until ); - $this->flip = true; - } else { - $pageCondition = '1 = 1'; - $this->flip = false; - } - - $res = $dbr->select( - $tables, - $fields, - $conds + array( $pageCondition ), - __METHOD__, - $opts + array( 'ORDER BY' => $this->flip ? 'cl_sortkey DESC' : 'cl_sortkey' ), - $joins + $this->nextPage = array( + 'page' => null, + 'subcat' => null, + 'file' => null, ); + $this->flip = array( 'page' => false, 'subcat' => false, 'file' => false ); + + foreach ( array( 'page', 'subcat', 'file' ) as $type ) { + # Get the sortkeys for start/end, if applicable. Note that if + # the collation in the database differs from the one + # $wgContLang is using, pagination might go totally haywire. + $extraConds = array( 'cl_type' => $type ); + if ( $this->from[$type] !== null ) { + $extraConds[] = 'cl_sortkey >= ' + . $dbr->addQuotes( $wgContLang->convertToSortkey( $this->from[$type] ) ); + } elseif ( $this->until[$type] !== null ) { + $extraConds[] = 'cl_sortkey < ' + . $dbr->addQuotes( $wgContLang->convertToSortkey( $this->until[$type] ) ); + $this->flip[$type] = true; + } - $count = 0; - $this->nextPage = null; + $res = $dbr->select( + $tables, + array_merge( $fields, array( 'cl_sortkey_prefix' ) ), + $conds + $extraConds, + __METHOD__, + $opts + array( 'ORDER BY' => $this->flip[$type] ? 'cl_sortkey DESC' : 'cl_sortkey' ), + $joins + ); - foreach ( $res as $row ) { - if ( ++$count > $this->limit ) { - // We've reached the one extra which shows that there are - // additional pages to be had. Stop here... - $this->nextPage = $row->cl_sortkey; - break; - } + $count = 0; + foreach ( $res as $row ) { + $title = Title::newFromRow( $row ); + $rawSortkey = $title->getCategorySortkey( $row->cl_sortkey_prefix ); - $title = Title::newFromRow( $row ); + if ( ++$count > $this->limit ) { + # We've reached the one extra which shows that there + # are additional pages to be had. Stop here... + $this->nextPage[$type] = $rawSortkey; + break; + } - if ( $title->getNamespace() == NS_CATEGORY ) { - $cat = Category::newFromRow( $row, $title ); - $this->addSubcategoryObject( $cat, $row->cl_sortkey, $row->page_len ); - } elseif ( $this->showGallery && $title->getNamespace() == NS_FILE ) { - $this->addImage( $title, $row->cl_sortkey, $row->page_len, $row->page_is_redirect ); - } else { - $this->addPage( $title, $row->cl_sortkey, $row->page_len, $row->page_is_redirect ); + if ( $title->getNamespace() == NS_CATEGORY ) { + $cat = Category::newFromRow( $row, $title ); + $this->addSubcategoryObject( $cat, $rawSortkey, $row->page_len ); + } elseif ( $this->showGallery && $title->getNamespace() == NS_FILE ) { + $this->addImage( $title, $rawSortkey, $row->page_len, $row->page_is_redirect ); + } else { + $this->addPage( $title, $rawSortkey, $row->page_len, $row->page_is_redirect ); + } } } } @@ -460,10 +388,6 @@ class CategoryViewer { * @return String: HTML output, possibly empty if there are no other pages */ private function getSectionPagingLinks( $type ) { - global $wgExperimentalCategorySort; - if ( !$wgExperimentalCategorySort ) { - return ''; - } if ( $this->until[$type] !== null ) { return $this->pagingLinks( $this->nextPage[$type], $this->until[$type], $type ); } elseif ( $this->nextPage[$type] !== null || $this->from[$type] !== null ) { @@ -474,18 +398,7 @@ class CategoryViewer { } function getCategoryBottom() { - global $wgExperimentalCategorySort; - if ( $wgExperimentalCategorySort ) { - # We have per-section paging links, no global ones. - return ''; - } - if ( $this->until != '' ) { - return $this->pagingLinks( $this->nextPage, $this->until ); - } elseif ( $this->nextPage != '' || $this->from != '' ) { - return $this->pagingLinks( $this->from, $this->nextPage ); - } else { - return ''; - } + return ''; } /** diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index e60d817998..91914026bc 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -4472,16 +4472,6 @@ $wgCategoryPagingLimit = 200; */ $wgCategoryPrefixedDefaultSortkey = true; -/** - * Enable experimental support for non-braindead collation on category pages. - * For this to work, you need to alter your categorylinks table by applying - * maintenance/archives/patch-categorylinks-better-collation.sql, then keep - * up-to-date with changes that are made to that file (they won't be - * automatically applied). You should also set $wgUseDumbLinkUpdate = true and - * run maintenance/refreshLinks.php. - */ -$wgExperimentalCategorySort = false; - /** * A version indicator for collations that will be stored in cl_collation for * all new rows. Used when the collation algorithm changes: a script checks diff --git a/includes/LinksUpdate.php b/includes/LinksUpdate.php index b7ad29cd95..5fb7c05da6 100644 --- a/includes/LinksUpdate.php +++ b/includes/LinksUpdate.php @@ -426,57 +426,48 @@ class LinksUpdate { * @private */ function getCategoryInsertions( $existing = array() ) { - global $wgContLang, $wgExperimentalCategorySort, $wgCollationVersion; + global $wgContLang, $wgCollationVersion; $diffs = array_diff_assoc( $this->mCategories, $existing ); $arr = array(); foreach ( $diffs as $name => $sortkey ) { $nt = Title::makeTitleSafe( NS_CATEGORY, $name ); $wgContLang->findVariantLink( $name, $nt, true ); - if ( $wgExperimentalCategorySort ) { - if ( $this->mTitle->getNamespace() == NS_CATEGORY ) { - $type = 'subcat'; - } elseif ( $this->mTitle->getNamespace() == NS_FILE ) { - $type = 'file'; - } else { - $type = 'page'; - } - - # TODO: This is kind of wrong, because someone might set a sort - # key prefix that's the same as the default sortkey for the - # title. This should be fixed by refactoring code to replace - # $sortkey in this array by a prefix, but it's basically harmless - # (Title::moveTo() has had the same issue for a long time). - if ( $this->mTitle->getCategorySortkey() == $sortkey ) { - $prefix = ''; - $sortkey = $wgContLang->convertToSortkey( $sortkey ); - } else { - # Treat custom sortkeys as a prefix, so that if multiple - # things are forced to sort as '*' or something, they'll - # sort properly in the category rather than in page_id - # order or such. - $prefix = $sortkey; - $sortkey = $wgContLang->convertToSortkey( - $this->mTitle->getCategorySortkey( $prefix ) ); - } + if ( $this->mTitle->getNamespace() == NS_CATEGORY ) { + $type = 'subcat'; + } elseif ( $this->mTitle->getNamespace() == NS_FILE ) { + $type = 'file'; + } else { + $type = 'page'; + } - $arr[] = array( - 'cl_from' => $this->mId, - 'cl_to' => $name, - 'cl_sortkey' => $sortkey, - 'cl_timestamp' => $this->mDb->timestamp(), - 'cl_sortkey_prefix' => $prefix, - 'cl_collation' => $wgCollationVersion, - 'cl_type' => $type, - ); + # TODO: This is kind of wrong, because someone might set a sort + # key prefix that's the same as the default sortkey for the + # title. This should be fixed by refactoring code to replace + # $sortkey in this array by a prefix, but it's basically harmless + # (Title::moveTo() has had the same issue for a long time). + if ( $this->mTitle->getCategorySortkey() == $sortkey ) { + $prefix = ''; + $sortkey = $wgContLang->convertToSortkey( $sortkey ); } else { - $arr[] = array( - 'cl_from' => $this->mId, - 'cl_to' => $name, - 'cl_sortkey' => $sortkey, - 'cl_timestamp' => $this->mDb->timestamp() - ); + # Treat custom sortkeys as a prefix, so that if multiple + # things are forced to sort as '*' or something, they'll + # sort properly in the category rather than in page_id + # order or such. + $prefix = $sortkey; + $sortkey = $wgContLang->convertToSortkey( + $this->mTitle->getCategorySortkey( $prefix ) ); } + + $arr[] = array( + 'cl_from' => $this->mId, + 'cl_to' => $name, + 'cl_sortkey' => $sortkey, + 'cl_timestamp' => $this->mDb->timestamp(), + 'cl_sortkey_prefix' => $prefix, + 'cl_collation' => $wgCollationVersion, + 'cl_type' => $type, + ); } return $arr; } diff --git a/includes/installer/MysqlUpdater.php b/includes/installer/MysqlUpdater.php index 03b2dfdb2d..3111ae568b 100644 --- a/includes/installer/MysqlUpdater.php +++ b/includes/installer/MysqlUpdater.php @@ -158,6 +158,8 @@ class MysqlUpdater extends DatabaseUpdater { array( 'add_field', 'interwiki', 'iw_api', 'patch-iw_api_and_wikiid.sql' ), array( 'drop_index_if_exists', 'iwlinks', 'iwl_prefix', 'patch-kill-iwl_prefix.sql' ), array( 'drop_index_if_exists', 'iwlinks', 'iwl_prefix_from_title', 'patch-kill-iwl_pft.sql' ), + array( 'add_field', 'categorylinks', 'cl_collation', 'patch-categorylinks-better-collation.sql' ), + array( 'do_collation_update' ), ), ); } diff --git a/maintenance/archives/patch-categorylinks-better-collation.sql b/maintenance/archives/patch-categorylinks-better-collation.sql index 5722a33c95..ad41f087ec 100644 --- a/maintenance/archives/patch-categorylinks-better-collation.sql +++ b/maintenance/archives/patch-categorylinks-better-collation.sql @@ -1,12 +1,7 @@ -- -- patch-categorylinks-better-collation.sql -- --- Bugs 164, 1211, 23682. This is currently experimental and subject to --- change. You need to set $wgExperimentalCategorySort = true; to use this. --- You also need to manually apply any changes that are made to this file, --- since they will not be automatically applied. This patch is only intended --- to work for MySQL for now, without table prefixes, possibly other random --- limitations. +-- Bugs 164, 1211, 23682. ALTER TABLE categorylinks ADD COLUMN cl_sortkey_prefix varchar(255) binary NOT NULL default '', ADD COLUMN cl_collation tinyint NOT NULL default 0, diff --git a/maintenance/updateCollation.php b/maintenance/updateCollation.php index 60578ce084..c41d95c05c 100644 --- a/maintenance/updateCollation.php +++ b/maintenance/updateCollation.php @@ -37,7 +37,7 @@ TEXT; __METHOD__ ); - $this->output( "Fixing around $count rows (estimate might be wrong).\n" ); + $this->output( "Fixing collation for around $count rows (estimate might be wrong).\n" ); $count = 0; do { diff --git a/maintenance/updaters.inc b/maintenance/updaters.inc index 7efe3a6b62..748d46feaf 100644 --- a/maintenance/updaters.inc +++ b/maintenance/updaters.inc @@ -1086,6 +1086,21 @@ function do_populate_rev_len() { $task->execute(); } +function do_collation_update() { + global $wgDatabase, $wgCollationVersion; + if ( $wgDatabase->selectField( + 'categorylinks', + 'COUNT(*)', + 'cl_collation != ' . $wgDatabase->addQuotes( $wgCollationVersion ), + __FUNCTION__ + ) == 0 ) { + wfOut( "...collations up-to-date.\n" ); + } + require_once( 'updateCollation.php' ); + $task = new UpdateCollation(); + $task->execute(); +} + function sqlite_initial_indexes() { global $wgDatabase; // initial-indexes.sql fails if the indexes are already present, so we perform a quick check if our database is newer.