commerceguys / addressing Goto Github PK
View Code? Open in Web Editor NEWA PHP addressing library, powered by CLDR and Google's address data.
License: MIT License
A PHP addressing library, powered by CLDR and Google's address data.
License: MIT License
Not sure why an address with country code "SG" isn't validating. I added it as a test to find out what happens:
// tests/Validator/Constraints/AddressFormatValidatorConstraint
public function testSingapore()
{
$address = new Address();
$address = $address
->withCountryCode('SG')
->withLocality('Singapore')
->withPostalCode('79903')
->withAddressLine1('10 Anson Road#22-09, Internat.Plaza')
;
$this->validator->validate($address, $this->constraint);
$this->assertNoViolation();
}
If I comment out ->withCountryCode('SG')
the validation passes.
I'm using the library in a Symfony 3.3 project and checked if the country code may be invalid, but it shows up in the Symfony Intl region data sets.
When adding the country code to CommerceGuys\Addressing\Tests\Validator\Constraints\CountryValidatorTest:getValidCountries()
it validates so I guess it has to do with the AddressFormat
Is it possible to implement this package within an active record app / framework?
From my brief look over the codebase, the models seem to be plain php objects... using Doctrine I'm guessing?
thanks!
Our current requirement is "symfony/validator": ">=2.5" but we still use the pre 2.5 API.
Let's see if it's possible to lower the requirement to >=2.3.
Right now, tests fail on 2.4, to be investigated.
Now that the PostalCodeHelper has been moved here, we need to also address this bug: commerceguys/zone#5
We have 3 major integration use cases: Doctrine, Drupal, Eloquent (Laravel).
Not one of them needs setters. Drupal and Eloquent allow access to public properties.
Doctrine supports embeddables which allow an immutable value object to be a part of the parent entity.
We want to:
We'll probably want to do this in parallel with finishing the symfony form type and the bundle, to make sure we don't miss anything.
Right now they are stored in resources/subdivision/depths.json. Another file to load for no reason.
Let's move the depths to $addressFormat->getSubdivisionDepth() and save on performance.
The data provider is a facade over the three repositories (address format, country, subdivision).
It was introduced to allow external systems (Drupal, anything Doctrine based) to use a database as the storage for all three, replacing only the facade (and using their internal entity managers) instead of replacing all three repositories.
However, practice has shown that subdivisions must be loaded from disk, since there's too many to import (~ 13 000) and they are frequently updated. The address formats are also kept on disk by most systems (apart from Drupal). So, the storage swap is less frequent than expected.
Therefore, the weight of the additional concept is no longer justified. To simplify things we can just remove the data provider and inject the needed repositories. We'll also need to create our own CountryRepositoryInterface, and move the runtime switching between commerceguys/intl and symfony/intl there.
Is there a function to get the full value given abbrev administrative_area and Country Code
some_function('IL', 'US') = Illinois
The addressing library needs a country list. The code that supports both commerceguys/intl and symfony/intl is clunky, and creates a need for requiring another library after the initial Composer install is done. At the same time, commerceguys/intl needs to be split, cause it has too much unrelated data. So, let's move countries from commerceguys/intl to commerceguys/addressing.
Hey,
given you are working on the Google info base, I guess you have no further data on how to map the single address_components coming from the Google Geocoding API to the address formats?
The pretty simple example question would be which comes first in the address line 1, [Street] [Number] or [Number] [Street], the former i.e. US, the latter in Germany.
I cannot find any useful mapping data for this.
--strict is deprecated, we should replace it with --report-useless-tests.
We don't want to check unintentionally covered code anymore, it results in a ton of @uses statements in tests that contribute nothing and make refactorings difficult. It's a silly idea at best and I can see why it's not on by default.
Along with the initial version of commerceguys/addressing, we also implemented commerceguys/zone, intentionally placed into another library because we figured not everyone using addressing would need that extra functionality.
For the 1.x branch of addressing we moved away from the idea of address formats and subdivisions as entities, preferring to provide immutable domain objects that can be populated from any source (db row, entity, json, code, etc). Internally we've been working on a new prototype for commerceguys/tax, which follows the same approach, and that includes the zones as well.
So, the plan is to:
For now it's enough to do #1 and #2, add a note to the commerceguys/zone page, see how users react.
The postal code patterns for subdivisions only looks for a partial match, however, if there is a subdivision postal code pattern, the country postal code pattern is not checked.
This means that any string that contains a subset of the subdivision postal code pattern tests as valid, even if the string is the wrong format otherwise.
Unfortunately, it appears that some countries (China/Taiwan) do not have a consistent country-wide postal code format, so just applying the country format in addition to the subdivision format test will not fix the issue. I'm not sure what the right solution is, but it would be good if the format of a postal code were tested in addition to the subdivision string where a consistent format is available.
I initially implemented the library to have a single 'name' property, since I didn't feel like it should be our job to solve the complexities of name formatting. This was supported by some research, all shipping APIs use a single name column, as does Amazon. Same thing is done by Google's version of the library, written in jAva.
However, payment APIs (PayPal, Authorize.net, Stripe, Braintree) require separate first_name and last_name columns. User feedback also showed that people want the ability to identify parts of the name.
So, how do we solve this?
Most sites use first_name / last_name, mapping them to the given and family name, but there are plenty of exceptions to that rule, where Hungary and most of Asia actually write the family name first.
Since what comes first and what comes last is country specific, I suggest going with givenName and familyName for the property names. We can still use First name and Last name as the default labels.
The AddressFormat entity can have an additional "name_format" that shows how the country formats names ("%familyName %givenName" or "%givenName %familyName"),. That allows us to present the fields in a country specific order. (or we extract it from the main format string)
We need to add an AddressMetadataRepository test (use https://github.com/commerceguys/intl/blob/master/tests/Country/CountryRepositoryTest.php as an example), and make sure that all classes under the Metadata namespace have 100% test coverage.
SubdivisionTest will need to mock a repository in order to complete its coverage of getParent() / getChildren().
If "en-US" was requested but there is only a translation for "en", return it.
Symfony 3.0 has made a few minor changes to the Symfony form component. Are there any plans to tag a release of commerceguys/addressing that is compatible with Symfony 3.0?
Is it intentional that the country validator returns no violation with an empty or null country?
We use the CountryConstraint which depends on symfony/intl.
Since we are trying to support multiple intl libraries, we should provide our own CountryConstraint/CountryConstraintValidator that takes the list of countries from the DataProvider.
The order of subdivisions is significant, with some countries preferring to order first by the type of subdivision on the same level (independent cities, then states, for example). The dataset also updates the ordering from time to time.
So, it makes sense for subivisions to have some kind of an ordering field (weight/priority) that would be used when generating the list. Users would be able to change this in the UI if the parent project allows.
Hey,
First thanks for the project. It's amazing.
I'm writing some unit tests in my local app using your package. Everything is working for others countries like Brazil, for example, but I cannot get any city from any US state, like Colorado, for example.
I was checking the resources/subdivisions
folder and I could find only a US.json
file, not a US-XX.json
one.
Is that right? Are the US states .json
files really missing?
Thanks for any support. Best regards.
We should use the examples from Google's java library:
https://github.com/googlei18n/libaddressinput/blob/master/java/test/com/android/i18n/addressinput/FieldVerifierTest.java
I would be fine with using the real metadata repository for the initial test, then replacing it with a dummy in the next pass. (This will be needed for the formatter tests as well).
It would be useful for me (and maybe others) if there was an easy way to turn an AddressFormat object and perhaps an array of Subdivision objects into a format that would be easily usable for a client side library like Angular. Perhaps some method/class that converts this information to JSON, so that forms that are being generated and updated by js on the client side can still take advantage of the power of the addressing library. (Of course, for validation purposes, the library could still be used server side).
I know that the formats and subdivisions are already stored in JSON, but going through the repositories seems more appropriate than digging into the data stores (which could change with time) directly.
We've backported a big piece of the dataset into addressfield for Drupal 7, and by doing that found a number of issues, reported at https://github.com/googlei18n/libaddressinput/issues
We need to make sure all of them get fixed.
/resources/subdivisions/HR.json
{ "country_code": "HR", "subdivisions": { "1": { "name": "Zagrebačka", "iso_code": "HR-01", "postal_code_prefix":"10" }, "21": { "name": "Grad Zagreb", "iso_code": "HR-21", "postal_code_prefix": "10" }, "2": { "name": "Krapinsko-Zagorska", "iso_code": "HR-02", "postal_code_prefix": "49" }, "3": { "name": "Sisačko-Moslavačka", "iso_code": "HR-03", "postal_code_prefix": "44" }, "4": { "name": "Karlovačka", "iso_code": "HR-04", "postal_code_prefix": "47" }, "5": { "name": "Varaždinska", "iso_code": "HR-05", "postal_code_prefix": "42" }, "6": { "name": "Koprivničko-Križevačka", "iso_code": "HR-06", "postal_code_prefix": "48" }, "7": { "name": "Bjelovarsko-Bilogorska", "iso_code": "HR-07", "postal_code_prefix": "43" }, "8": { "name": "Primorsko-Goranska", "iso_code": "HR-08", "postal_code_prefix": "51" }, "9": { "name": "Ličko-Senjska", "iso_code": "HR-09", "postal_code_prefix": "53" }, "10": { "name": "Virovitičko-Podravska", "iso_code": "HR-10", "postal_code_prefix": "33" }, "11": { "name": "Požeško-Slavonska", "iso_code": "HR-11", "postal_code_prefix": "34" }, "12": { "name": "Brodsko-Posavska", "iso_code": "HR-12", "postal_code_prefix": "35" }, "13": { "name": "Zadarska", "iso_code": "HR-13", "postal_code_prefix": "23" }, "14": { "name": "Osječko-Baranjska", "iso_code": "HR-14", "postal_code_prefix": "31" }, "15": { "name": "Šibensko-Kninska", "iso_code": "HR-15", "postal_code_prefix": "22" }, "16": { "name": "Vukovarsko-Srijemska", "iso_code": "HR-16", "postal_code_prefix": "32" }, "17": { "name": "Splitsko-Dalmatinska", "iso_code": "HR-17", "postal_code_prefix": "21" }, "18": { "name": "Istarska", "iso_code": "HR-18", "postal_code_prefix": "52" }, "19": { "name": "Dubrovačko-Neretvanska", "iso_code": "HR-19", "postal_code_prefix": "20" }, "20": { "name": "Međimurska", "iso_code": "HR-20", "postal_code_prefix": "40" } } }
The address format storage layer (repository/model) was written with the intention of being stored in a database and being user editable. This proved to be a bad idea because it created the need for an update process that kept those formats up to date. This update process usually clobbers any made customizations, removing the benefits of having a UI in the first place. Futhermore, updates are much more common than customizations, which are an edge case.
So, let's simplify.
Plan:
This also prepares us for a similar task on the subdivision side.
Could you add support for translating form field labels? The address form itself works great but all labels are always displayed in English. I don't know which translation keys I should translate for all the possible form fields.
Hi,
I've noticed that we don't have Netherlands Provinces as a filter. I would like to add it, how can I do that?
Hi,
class CountryRepository in CommerceGuys\Addressing\Repository
The path to the country definitions ($definitionPath) missing, so it can be passthrough to
\CommerceGuys\Intl\Country\CountryRepository if necesary
Do you think it is worth having FormatStringTrait::getUsedFields()
return the fields in the order they are actually used? The use case I have in mind is when presenting a form to a user to enter an address, you may want to show the fields in the correct order, but with each field on its own line. It would be easy to just use the grouped fields for that purpose, but the used fields array seems like the more appropriate data source if you don't actually want to group them.
Hi! I was searching for PHP Packages for my projects when I found this. This package is amazing. But I cant understand how to validate an address. The README.md speaks little about it. I tryed look the code, but no success. Can you show me an example, or update the README.md? Thanks.
The old integration was removed in 8b770ff.
Needs to be updated for the new subdivision storage, and for Symfony 3.0.
Also needs to be finished, in regards to AJAX.
The Drupal form implementation is a good one to investigate, but it won't be a 1-1 mapping cause symfony/form is a lot less flexible.
Guam (GU) does not have administrative areas, or states. This is causing issues. Can it be removed and not marked as required? Wikipedia
I can provide a PR.
We currently rely on commerceguys/intl for the country list.
Recently, symfony/intl has received the full multilingual dataset, and we're planning to push the remaining commerceguys/intl pieces there for 2.7, so it's a good time to start supporting both.
Concrete plan:
move commerceguys/int into "suggests", expand the DataProvider to check which country repository exists (commerceguys, then symfony), then use that.
I have an address with a postal code in the México (MEX) subdivision and it's failing validation.
The postal code is '03400' and appears accurate according to Wikipedia https://en.wikipedia.org/wiki/List_of_postal_codes_in_Mexico#0xxxx-1xxxx:_Mexican_Federal_District_.28M.C3.A9xico.2C_D.F..29
One strangeness I noticed was that it passes for the $fullPattern match in AddressFormatValidator::validatePostalCode(), but fails the $startPattern match. I would expect it to get validated against one or the other.
The existing pattern is "5[0-7]". In MX.json I set it to "[0-1][0-9]" and it resolved my issue.
It looks like the update should happen further upstream in library_customizations.php or the generate.php script if it is in fact the wrong regex pattern.
Hello guys I'm using this library in a project Symfony 3.0.
I have the need to set different fields in different form.
eg:
I have a form that needs fields: Country, Administrative Area, Locality, Postal code, Address line 1
and another form that should only have Country, Administrative area.
How can I do?
Thanks.
Problem 1
- Installation request for __root__ 8.0.9999999.9999999-dev -> satisfiable by __root__[8.0.9999999.9999999-dev].
- commerceguys/addressing dev-master requires symfony/validator 2.5.* -> satisfiable by symfony/validator[2.5.x-dev, v2.5.0, v2.5.0-BETA1, v2.5.0-BETA2, v2.5.0-RC1, v2.5.1, v2.5.2, v2.5.3, v2.5.4, v2.5.5, v2.5.6].
- don't install symfony/validator 2.5.x-dev|remove __root__ 8.0.9999999.9999999-dev
- don't install symfony/validator v2.5.0|remove __root__ 8.0.9999999.9999999-dev
- don't install symfony/validator v2.5.0-BETA1|remove __root__ 8.0.9999999.9999999-dev
- don't install symfony/validator v2.5.0-BETA2|remove __root__ 8.0.9999999.9999999-dev
- don't install symfony/validator v2.5.0-RC1|remove __root__ 8.0.9999999.9999999-dev
- don't install symfony/validator v2.5.1|remove __root__ 8.0.9999999.9999999-dev
- don't install symfony/validator v2.5.2|remove __root__ 8.0.9999999.9999999-dev
- don't install symfony/validator v2.5.3|remove __root__ 8.0.9999999.9999999-dev
- don't install symfony/validator v2.5.4|remove __root__ 8.0.9999999.9999999-dev
- don't install symfony/validator v2.5.5|remove __root__ 8.0.9999999.9999999-dev
- don't install symfony/validator v2.5.6|remove __root__ 8.0.9999999.9999999-dev
- Installation request for commerceguys/addressing dev-master -> satisfiable by commerceguys/addressing[dev-master].
We should use the examples from Google's tests:
https://github.com/googlei18n/libaddressinput/blob/master/java/test/com/android/i18n/addressinput/FormatInterpreterTest.java
I would be fine with using the real metadata repository for the initial tests, then replacing it with a dummy in the next pass. (This will be needed for the validator tests as well).
Now that we have separate name fields, it would be great to have a way to get the name formatted per country rules (last name before first name, or the opposite, etc).
So let's create a NameFormatter that has a format($address) method which returns a formatted name in plain text.
https://mattstauffer.co/blog/how-to-organize-class-namespaces
Currently the classes are organized by pattern. Wanted to explore grouping by context (something I've done in commerceguys/intl but switched away from since).
An example of that new layout is here: https://github.com/commerceguys/addressing/tree/new-layout/src
Unsure about the whole move, and which version is better, so keeping this issue open for feedback, and will decide before tagging 1.0.
Problems:
Solution:
When both recipient and org are present the german addresses seem incorrectly formatted. In Germany postal addresses have the organization come before the recipient.
However it seems odd that Google might be wrong here:
https://github.com/commerceguys/addressing/blob/master/resources/address_format/DE.json
http://i18napis.appspot.com/address/data/DE
In case this is just me getting the semantics wrong, feel free to close the ticket.
Thanks for the great library!
Hi,
a question:
how do I get the populations of Spain?. Is there any way to add them with them postal code...?
Thanks for your job.
The current .patch format makes it hard to extend. Meanwhile, Google has been super slow in responding to our bug reports (2 out of 15 resolved in the past 11 months). So we need to move our changes to PHP to allow people to extend the list of changes more easily.
Could you create version tags?
Right now we are required to use dev-master in composer. which is bad.
It's possible to get the GPS coordinates to display on a map?
Although $addressLine2
is a property of Address
, there is no field-mapping constant available from the AddressFormatInterface
. So far as I can determine, this means that addressLine2 will never appear in any address form.
Is this an oversight? Or is there some other way that addressLine2 should be added to an address form?
I discussed this briefly with @bojanz on Twitter, but I'm still a bit confused about the role of the locale (third argument of the constructor) in the postal label formatter.
In particular, it seems to me to be serving two purposes: one relates to the ordering of the address elements and the translation of the subdivisions, which would be relevant when the item arrives in the destination country. So if someone from China orders something from France, and enters the address in Chinese, the locale (and ordering and subdivisions) would be for the Chinese locale.
However, locale also determines the name of the country in the postal label. So for our example above again, the formatter would be instantiates with origin country "FR" and locale "zh", and thus would have the destination country in Chinese and English, but NOT French. The Universal Postal Union recommendations that you reference suggest that the country be named preferable in the language of the dispatching country, which may not match the locale.
Does this seem like a problem, or am I confused by how locale is intended to be used?
The validation example in the readme looks a lot different from the code in the tests. Method validateValue()
for instance was deprecated in symfony/validator in version 2.5.
When using the approach from the tests, I ran across this error when trying to validate without first setting a $context
:
FatalThrowableError in AddressFormatValidator.php line 212:
Call to undefined method CommerceGuys\Addressing\Validator\Constraints\AddressFormatValidator::buildViolation()
Could we add more levels for USA, like county and city? (and maybe zip)
But I'm not sure it's doable with Google Dataset...
What do you think?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.