From 1353ce0f03cb0dc921840492b1ae48355631cd2c Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Thu, 9 Feb 2023 22:18:49 -0800 Subject: [PATCH] Disambiguate `Address.state_province_id:abbr` (PHP asort) Consider `ContactJoinTest::testCreateWithPrimaryAndBilling` which writes the value: 'address_billing.state_province_id:abbr' => 'AK', The symbol 'AK' can map to three places: Akwa Ibom (Nigeria), Atakora (Benin), and Alaska (USA). This is an ambiguous choice. It should be resolved in a consistent way. One flavor of ambiguity comes from PHP. After fetching from MySQL, there is a secondary sorting (via `CRM_Utils_Array::asort()` => `asort()`). Per https://www.php.net/asort, the outcome is quirky: > If two members compare as equal, they retain their original order. Prior > to PHP 8.0.0, their relative order in the sorted array was undefined. On PHP 7, you cannot resolve this with any of the standard sort methods (`asort`, `usort`, `ksort`, etc). They all have the same issue. However... the docs for `\Collator::asort()` indicate no such issue. Switching to `\Collator::asort()` causes the tests to pass on PHP 7.3. And we already use `\Collator::asort()`. --- CRM/Utils/Array.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CRM/Utils/Array.php b/CRM/Utils/Array.php index cf03d320b0..da71c11971 100644 --- a/CRM/Utils/Array.php +++ b/CRM/Utils/Array.php @@ -580,6 +580,10 @@ class CRM_Utils_Array { $collator = new Collator($lcMessages . '.utf8'); $collator->asort($array); } + elseif (version_compare(PHP_VERSION, '8', '<') && class_exists('Collator')) { + $collator = new Collator('en_US.utf8'); + $collator->asort($array); + } else { // This calls PHP's built-in asort(). asort($array); -- 2.25.1