alcohol / iso3166

A PHP library providing ISO 3166-1 data.
https://iso3166.thephpleague.com
MIT License
640 stars 59 forks source link

Aliases #61

Closed robertdeboer closed 3 years ago

robertdeboer commented 3 years ago

If I may suggest, I would consider the use of Aliases for the most common countries.

A few examples:

I ran into an issue where I was not getting a ISO 2 letter code for US orders. Upon investigation I found out the reason was because the ordering system we use writes it as "United States" and not "United States Of America" which is what the library expects. While I can understand not wanting to add bloat by allowing any/all country alias I do feel the most common ones would be a great way to add some graceful wiggle room. I know of very few systems that use the full name for the US.

alcohol commented 3 years ago

I prefer to let the end-user implement their specific use-case modifications.

Quick (and oversimplified) example:

test.php

<?php

require_once 'vendor/autoload.php';

use League\ISO3166\ISO3166;
use League\ISO3166\ISO3166DataProvider;

class ISO3166WithAliases implements ISO3166DataProvider
{
    private ISO3166DataProvider $source;

    public function __construct(ISO3166DataProvider $iso3166)
    {
        $this->source = $iso3166;
    }

    public function name($name): array
    {
        $aliases = [
            'United States' => 'United States of America'
        ];

        return $this->source->name(array_key_exists($name, $aliases) ? $aliases[$name] : $name);
    }

    public function alpha2($alpha2): array
    {
        return $this->source->alpha2($alpha2);
    }

    public function alpha3($alpha3): array
    {
        return $this->source->alpha3($alpha3);
    }

    public function numeric($numeric): array
    {
        return $this->source->numeric($numeric);
    }
}

var_dump((new ISO3166WithAliases(new ISO3166))->name('United States'));

output

array(5) {
  ["name"]=>
  string(24) "United States of America"
  ["alpha2"]=>
  string(2) "US"
  ["alpha3"]=>
  string(3) "USA"
  ["numeric"]=>
  string(3) "840"
  ["currency"]=>
  array(1) {
    [0]=>
    string(3) "USD"
  }
}
cottton commented 2 years ago

I do feel the most common ones would be a great

Agree. Otherwise tons of ppl will do the same work independently. Im for most common ones.

alcohol commented 2 years ago

Alright, if you submit a PR I'm OK with merging it (along the lines of my proposed solution - so a new class that wraps the original).

alcohol commented 2 years ago

Though I would like to point out that it is rather uncommon to use the "name" as a key. And adding aliases does not change the returned data, only the way you lookup said data.

cottton commented 2 years ago

Just some quick notes:

  1. We COULD add the alias feature into the same|main class ISO3166.
  2. We SHOULD implement an alias setter setAliases($aliases) (overwrite) and addAliases($aliases) accepting one string or array of alias. Everybody can set up the model with a config. 2.1. We SHOULD add a 2nd parameter $aliases on __construct (default empty array). 2.2. We SHOULD add a method getAliases().
  3. Aliases SHOULD be set on a property (array). 3.1. Alias keys COULD be lowercase {lowercase(alias)} => {actual name} to prevent duplicates ("Austria" <> "austria").
  4. The method lookup() SHOULD get a parameter (something like) $allowAliases or $includeAliases. 4.1. Every method that is using lookup() (name(),alpha2(), ...) SHOULD get this parameter too. 4.2. For backwards compatibility (keep previous behavior) this parameter should be default false.
  5. The method lookup() SHOULD get a check AFTER the existing lookup-loop for an alias match.

Note: another way to implement aliases would be

This way we could benefit of getting a complete set of data on f.e. all() ect.