Problem/Motivation

Currently when parsing an address field, country code is used to specify country. In some conditions, for instance when having an address field having only the country part populated, this may lead to incorrect results. This is caused by country codes being ambiguous in this context, e.g. IL may indicate Illinois or Israel.

Proposed resolution

Adopt the Country name (CODE) pattern to make country unambiguous. This would lead to:

IL,United States (US)

vs

Israel (IL)

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

plach’s picture

Issue summary: View changes
plach’s picture

Status: Active » Needs review
FileSize
1.01 KB
nowidid’s picture

This patch works for me.
This code should be a regular part of the module.

Thanks
nowi

dubcanada’s picture

I'd also like to see

if (!empty($field_item['organisation_name'])) $address .= $field_item['organisation_name'] . ',';

added. So you can get the organization name as well. The more data the better the results.

Simon Georges’s picture

basvredeling’s picture

Why do we need the country suffix at all? Just the country name would suffice, wouldn't it?
Also there are cases like "Canada (ca)" leading to multiple results in both Canada and California whereas just "Canada" gives a single correct result.
I'll test this later today. Seems like a minor issue to fix.

basvredeling’s picture

New patch. Things changed:

  • Extra check if countries list is retrievable.
  • Only parse country name, parse country code if name cannot be retrieved.
  • Drupal code standards.
basvredeling’s picture

forgot to upload the patch

basvredeling’s picture

This new patch ensures the /includes/iso.inc is loaded. (also leveraged by the Drupal installer)

This functionality overlaps with #1871962: Use Countries module to improve geocoding results
This uses Drupal core countries list, whereas 1871962 uses countries module.

kerasai’s picture

@basvredeling, this works great but a couple suggestions.

Let's use country_get_list() instead of _country_get_predefined_list(). This is better as it includes an alter hook, to give other modules a chance to tweak the list of countries if desired. You'll also need to update the include to grab locale.inc instead of iso.inc.

Looks like the trailing comma is missing when you append the country. Should be something like this:

$address .= $field_item['country'] . ',';

If you would like to upload a new patch, I'll test and mark RTBC. This (referencing the country by its full name) is an important improvement and it'd be great to get this in.

Pol’s picture

Status: Needs review » Needs work
NWOM’s picture

Awesome. #9 in combination with #10, finally fixed my country issue. Locations located in Germany (DE), are no longer matched up with Delaware.

Thank you so much.

basvredeling’s picture

@kerasai #10 Initially I've opted for the private function instead because it didn't imply the locale module to be enabled. Usually the locale.inc is loaded by calling locale_init(). And I didn't want to add an additional dependency to geocoder. But we can always include it manually of course.

Here's a new patch. While I was at it, I added a todo to the last undocumented function geocoder_widget_array_recursive_diff().

basvredeling’s picture

Status: Needs work » Needs review

Review please

Pol’s picture

Status: Needs review » Fixed

Thanks mate! Committed!

  • Pol committed b95eb8f on 7.x-1.x authored by basvredeling
    Issue #2245189 by basvredeling, plach: Make address field country...

  • Pol committed b95eb8f on 7.x-2.x authored by basvredeling
    Issue #2245189 by basvredeling, plach: Make address field country...

  • Pol committed b95eb8f on 8.x-2.x authored by basvredeling
    Issue #2245189 by basvredeling, plach: Make address field country...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

basvredeling’s picture

FileSize
1.12 KB

The current solution works but taking a new look at it, it seems silly why we just didn't use the _addressfield_country_options_list() function.
Here's a patch, just for posterity.

basvredeling’s picture

izmeez’s picture

@basvredeling Would it help to put the patch in comment #20 in a new issue for review to simplify the now existing code?

basvredeling’s picture

No, I don't think it's necessary to open a new issue. I'm ever so sorry if the new patch is bigger and harder to review. I can try and explain if that helps. To summarize: the old code leverages either the countries module or core locale country list to transform a country code into a country name. But since we're parsing an addressfield anyway, there already is a list of country names. So let's just use that.

The old code is much more complex that the new code and reads roughly like this.
old:

if (module_exists('countries')) {
  $country = country_load($field_item['country']);
  $field_item['country'] = $country->name;
}
else {
  // Convert country code to country name.
  include_once DRUPAL_ROOT . '/includes/locale.inc';
  $countries = country_get_list();
  if (array_key_exists($field_item['country'], $countries)) {
    $field_item['country'] = $countries[$field_item['country']];
  }
}

new:

$countries = _addressfield_country_options_list();
if (array_key_exists($field_item['country'], $countries)) {
  $field_item['country'] = $countries[$field_item['country']];
}

As a final note, the patch also affects the solution from #1871962: Use Countries module to improve geocoding results.

izmeez’s picture

Yes, I understand from reading the patch originally. I was just concerned that in a closed issue queue the patch may be overlooked.

Simple is usually good way to go for code.

Thanks.