Implementing a DataProvider Service Manager
Closed this issue · 10 comments
great job on releasing the package.
I was thinking if it was possible to implement a service manager to
- decouple the countries data from the ISO3166.php
- enable refreshing the data with a script without having to upgrade to a new fix version ?
Like how Jeremy Kendall did with his php domain parser.
Because of politics country data change a lot and with the current architecture it would mean a security fix upgrade each time a country is added/changed/removed from the list
Could you elaborate a bit more about what you mean by "refreshing the data using a script"?
Personally I think the data changes rarely at most, but definitely not "often" or "a lot". This is subjective though, of course. A patch version is easily created and released when that does happen. So I am not entirely sure this warrants such a complex approach to keeping the data up to date. What is your thought on this?
Well I come from an area of the world were believe me these data changed a lot the last 10 years. And technically I find it strange to have to update a library while the only thing that have change is just the provided data. If I had a service that can do that in the package it would be better IMHO.
Also, by decoupling the data from the class you would have to inject it into the class which improve:
- testing
- make it simpler to use with historical or legacy or deprecated codes (which I believe are not present in your class)
That why I think decoupling the data is important and maybe having a service to retrieve this data from ISO would be awesome.
Those are some valid arguments regarding decoupling. I will look into this when I have some more spare time :-)
retrieve this data from ISO
This unfortunately will not be as easy. Most of this data I gathered from wikipedia.org and iso.org by hand. Automating this might take a significant effort.
at least for currency you have this service
http://www.currency-iso.org/dam/downloads/lists/list_one.xml
but for iso code its more difficult I could only found this link
http://www.iso.org/iso/home/store/publication_item.htm?pid=PUB500001%3aen
Seems getting access to this data freely from a trusted source is not that simple
would be interesting to work out a way of versioning the data so that by default it loads the latest, but dev's could load up an older revision (i.e. they may be working with another system that isn't as up to date).
In addition to this (no it's not just a +1 post), it would be useful to be able to load up the data in various languages (see: https://en.wikipedia.org/wiki/List_of_country_names_in_various_languages_(A%E2%80%93C) ).
Obviously this turns into a mammoth content curation task if you can't automate it from a reliable source, however i think if you provide the schema for these things to be able to work, the community will help fill in the blanks as it get's used more (won't take a native speaker more than 10 minutes to run through and translate the country names in there own language after all).
Alternatively reddit i believe uses crowdin.com who give free OS licenses if you wanted to go down the gettext route
Localization has always been on my personal todo-list yeah, so it will probably make it into this package eventually. Just need to find the time, and consider the various implementations possible :-)
localisation is very simple to achieve using the intl extension If have a POC I'm working on but major bc in it :)
the difficult part is localization of the currencies
There is no localization for the currencies as they are just linked by their ISO codes (which are language agnostic) o_O
So I've here's my Proof of Concept .. feel free to dig in and to get what you like and trash what you don't like ... I didn't make any Test suite though so might be buggy 👍
https://github.com/nyamsprod/iso3166/tree/feature/decoupling
Major BC break:
- introduce a CountryInterface and a Country implementation
- ISO3166 is a collection class which accept a array of Country object
- because Country is an object localization is done using PHP intl extension
- currencies are always arrays
and here's a simple usage
<?php
require 'vendor/autoload.php';
use League\ISO3166\ISO3166;
$data = require __DIR__.'/data/public-country-list.php';
$collection = ISO3166::createFromArray($data);
$country = $collection->getByAlpha3('SEN'); //returns a CountryInterface object
$country->toArray(); //convert the object into your "array" the name is missing
$country->getName(); //current locale may vary depending on your server settings
$country->getName('en'); // displays 'Senegal' the full name in english
$country->getName('fr'); // displays 'Sénégal' the full name in french
$country->getCurrencies(); //always an array because some countries may have multiple currencies legals at a given time
$country->getAlpha3();
$country->getAlpha2();
$country->getNumeric();
$country->hasCurrency('XOF'); //returns true detect if the currencies is legal in the country boolean
$country->hasCurrency('USD'); // returns false
$country->hasIsoCode('SN'); //returns true
$country->hasIsoCode('COD'); //return false
What's left is to get a good service manager to populate/maintain/update/ the public-country-list.php file/data.
This change is too rigorous for my taste, sorry.
I would like to avoid wrapping the data in a 'Country' entity (or any other entity). I suspect most end users would like to create and use their own types/entities. This project simply aims at providing the data to populate those.
I do think it would be nice if the ISO3166
class had a constructor that accepted an array to replace the default value of $countries
. That would be a backwards-compatible step towards supporting localization.