Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve how we get parents for subdivision fields #15584

Merged
merged 4 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Unreleased

- Fixed a bug where it wasn’t possible to override named transforms in GraphQL queries. ([#15572](https://github.com/craftcms/cms/issues/15572))
- Fixed a bug where address subdivision fields could be incorrectly labelled and/or populated with the wrong options. ([#15551](https://github.com/craftcms/cms/issues/15551), [#15584](https://github.com/craftcms/cms/pull/15584))

## 4.11.4 - 2024-08-21

Expand Down
50 changes: 48 additions & 2 deletions src/helpers/Cp.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace craft\helpers;

use CommerceGuys\Addressing\Subdivision\SubdivisionRepository as BaseSubdivisionRepository;
use Craft;
use craft\base\Element;
use craft\base\ElementInterface;
Expand Down Expand Up @@ -1301,6 +1302,8 @@ public static function addressFieldsHtml(Address $address): string
$addressesService->getUsedSubdivisionFields($address->countryCode),
)) + $requiredFields;

$parents = self::_getSubdivisionParents($address, $visibleFields);

return
static::textFieldHtml([
'status' => $address->getAttributeStatus('addressLine1'),
Expand Down Expand Up @@ -1337,7 +1340,7 @@ public static function addressFieldsHtml(Address $address): string
$belongsToCurrentUser ? 'address-level2' : 'off',
isset($visibleFields['locality']),
isset($requiredFields['locality']),
[$address->countryCode, $address->administrativeArea],
$parents['locality'],
true,
) .
self::_subdivisionField(
Expand All @@ -1346,7 +1349,7 @@ public static function addressFieldsHtml(Address $address): string
$belongsToCurrentUser ? 'address-level3' : 'off',
isset($visibleFields['dependentLocality']),
isset($requiredFields['dependentLocality']),
[$address->countryCode, $address->administrativeArea, $address->locality],
$parents['dependentLocality'],
false,
) .
static::textFieldHtml([
Expand Down Expand Up @@ -1378,6 +1381,49 @@ public static function addressFieldsHtml(Address $address): string
]);
}

/**
* Get parents array that needs to be passed to the subdivision repository getList() method to get the list of subdivisions back.
*
* For the administrativeArea, the parent is always just the country code.
*
* For the locality:
* - it could be just the country code
* - for countries that don't use administrativeArea field; that's the case with Andorra
* - it could be the country code and the administrative area code
* - for countries that use both administrative areas and localities; e.g. Chile (Chile => Araucania > Carahue)
* - the administrative area can be passed as null too;
* this will be triggered for the United Kingdom (GB), where you can conditionally turn on administrativeArea;
* in the case of GB, not passing null as the second value would result
* in the administrativeAreas list being returned for the locality field (https://github.com/craftcms/cms/issues/15551);
*
* For the dependentLocality:
* - as above but taking locality into consideration too; e.g. China has all 3 levels of subdivisions and has lists for all 3 of them
* (China => Heilongjiang Sheng > Hegang Shi > Dongshan Qu)
*
* @param Address $address
* @param array $visibleFields
* @return array
*/
private static function _getSubdivisionParents(Address $address, array $visibleFields): array
{
$baseSubdivisionRepository = new BaseSubdivisionRepository();

$localityParents = [$address->countryCode];
$administrativeAreas = $baseSubdivisionRepository->getList([$address->countryCode]);

if (array_key_exists('administrativeArea', $visibleFields) || empty($administrativeAreas)) {
$localityParents[] = $address->administrativeArea;
}

$dependentLocalityParents = $localityParents;
$localities = $baseSubdivisionRepository->getList($localityParents);
if (array_key_exists('locality', $visibleFields) || empty($localities)) {
$dependentLocalityParents[] = $address->locality;
}

return ['locality' => $localityParents, 'dependentLocality' => $dependentLocalityParents];
}

private static function _subdivisionField(
Address $address,
string $name,
Expand Down