From 8cc843f25ce401ced9abc6318a281235aece4b5c Mon Sep 17 00:00:00 2001 From: Roan Kattouw Date: Sun, 17 Apr 2011 12:41:29 +0000 Subject: [PATCH] API: BREAKING CHANGE: (bug 28541) Output of binary ICU sortkeys is broken. Change sortkey fields in prop=categories and list=categorymembers to hexadecimal strings, that way we don't have any issues with scary binary stuff. Also change cmcontinue to take hex-encoded sortkeys and swap the order back to normal (previously sortkey was at the end because it could contain pipe characters, but that's not an issue with hex). --- includes/api/ApiQueryCategories.php | 7 ++++--- includes/api/ApiQueryCategoryMembers.php | 20 +++++++++----------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/includes/api/ApiQueryCategories.php b/includes/api/ApiQueryCategories.php index b8f4a258c0..b65ea4bf06 100644 --- a/includes/api/ApiQueryCategories.php +++ b/includes/api/ApiQueryCategories.php @@ -70,7 +70,7 @@ class ApiQueryCategories extends ApiQueryGeneratorBase { 'cl_to' ) ); - $this->addFieldsIf( 'cl_sortkey', isset( $prop['sortkey'] ) ); + $this->addFieldsIf( array( 'cl_sortkey', 'cl_sortkey_prefix' ), isset( $prop['sortkey'] ) ); $this->addFieldsIf( 'cl_timestamp', isset( $prop['timestamp'] ) ); $this->addTables( 'categorylinks' ); @@ -151,7 +151,8 @@ class ApiQueryCategories extends ApiQueryGeneratorBase { $vals = array(); ApiQueryBase::addTitleInfo( $vals, $title ); if ( isset( $prop['sortkey'] ) ) { - $vals['sortkey'] = $row->cl_sortkey; + $vals['sortkey'] = bin2hex( $row->cl_sortkey ); + $vals['sortkeyprefix'] = $row->cl_sortkey_prefix; } if ( isset( $prop['timestamp'] ) ) { $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->cl_timestamp ); @@ -219,7 +220,7 @@ class ApiQueryCategories extends ApiQueryGeneratorBase { return array( 'prop' => array( 'Which additional properties to get for each category', - ' sortkey - Adds the sortkey for the category', + ' sortkey - Adds the sortkey (hexadecimal string) and sortkey prefix (human-readable part) for the category', ' timestamp - Adds timestamp of when the category was added', ' hidden - Tags categories that are hidden with __HIDDENCAT__', ), diff --git a/includes/api/ApiQueryCategoryMembers.php b/includes/api/ApiQueryCategoryMembers.php index d48458d6b8..93918f794d 100644 --- a/includes/api/ApiQueryCategoryMembers.php +++ b/includes/api/ApiQueryCategoryMembers.php @@ -123,7 +123,6 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase { $this->addOption( 'USE INDEX', 'cl_timestamp' ); } else { if ( $params['continue'] ) { - // type|from|sortkey $cont = explode( '|', $params['continue'], 3 ); if ( count( $cont ) != 3 ) { $this->dieUsage( 'Invalid continue param. You should pass the original value returned '. @@ -136,8 +135,9 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase { $queryTypes = array_slice( $queryTypes, $contTypeIndex ); // Add a WHERE clause for sortkey and from - $from = intval( $cont[1] ); - $escSortkey = $this->getDB()->addQuotes( $cont[2] ); + // pack( "H*", $foo ) is used to convert hex back to binary + $escSortkey = $this->getDB()->addQuotes( pack( "H*", $cont[1] ) ); + $from = intval( $cont[2] ); $op = $dir == 'newer' ? '>' : '<'; // $contWhere is used further down $contWhere = "cl_sortkey $op $escSortkey OR " . @@ -197,12 +197,9 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase { if ( $params['sort'] == 'timestamp' ) { $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->cl_timestamp ) ); } else { - // Continue format is type|from|sortkey - // The order is a bit weird but it's convenient to put the sortkey at the end - // because we don't have to worry about pipes in the sortkey that way - // (and type and from can't contain pipes anyway) + $sortkey = bin2hex( $row->cl_sortkey ); $this->setContinueEnumParameter( 'continue', - "{$row->cl_type}|{$row->cl_from}|{$row->cl_sortkey}" + "{$row->cl_type}|$sortkey|{$row->cl_from}" ); } break; @@ -226,7 +223,7 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase { ApiQueryBase::addTitleInfo( $vals, $title ); } if ( $fld_sortkey ) { - $vals['sortkey'] = $row->cl_sortkey; + $vals['sortkey'] = bin2hex( $row->cl_sortkey ); } if ( $fld_sortkeyprefix ) { $vals['sortkeyprefix'] = $row->cl_sortkey_prefix; @@ -243,8 +240,9 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase { if ( $params['sort'] == 'timestamp' ) { $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->cl_timestamp ) ); } else { + $sortkey = bin2hex( $row->cl_sortkey ); $this->setContinueEnumParameter( 'continue', - "{$row->cl_type}|{$row->cl_from}|{$row->cl_sortkey}" + "{$row->cl_type}|$sortkey|{$row->cl_from}" ); } break; @@ -336,7 +334,7 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase { 'What pieces of information to include', ' ids - Adds the page ID', ' title - Adds the title and namespace ID of the page', - ' sortkey - Adds the sortkey used for sorting in the category (may not be human-readble)', + ' sortkey - Adds the sortkey used for sorting in the category (hexadecimal string)', ' sortkeyprefix - Adds the sortkey prefix used for sorting in the category (human-readable part of the sortkey)', ' type - Adds the type that the page has been categorised as (page, subcat or file)', ' timestamp - Adds the timestamp of when the page was included', -- 2.20.1