Giter Club home page Giter Club logo

laravel-postal-code-validation's Introduction

Laravel Postal Code Validation

Worldwide postal code validation for Laravel, based on Google's Address Data Service.

Build status Downloads Latest version License

Requirements

This package has the following requirements:

  • PHP 7.2 or higher
  • Laravel (or Lumen) 5.5 or higher
Laravel / Lumen version Package version
5.1 - 5.4 2.x
5.5 and greater 3.x

Installation

You can install this package with Composer, by running the command below:

composer require axlon/laravel-postal-code-validation

If you have package discovery enabled, that's it, continue to the usage section. If you want to register the package manually, you can do this by adding the following line to your config/app.php file:

'providers' => [
   ...
   Axlon\PostalCodeValidation\ValidationServiceProvider::class,
   ...
],

Lumen

If you are using Lumen, register the package by adding the following line to your bootstrap/app.php file:

$app->register(Axlon\PostalCodeValidation\ValidationServiceProvider::class);

Usage

Postal code validation perfectly integrates into your Laravel application, you can use it just like you would any framework validation rule.

Available rules

This package adds the following validation rules:

postal_code:foo,bar,...

The field under validation must be a valid postal code in at least one of the given countries. Arguments must be countries in ISO 3166-1 alpha-2 format.

'postal_code' => 'postal_code:NL,DE,FR,BE'

postal_code_with:foo,bar,...

The field under validation must be a postal code in at least one of the countries in the given fields only if at least one of the specified fields is present.

'billing.country' => 'required|string|max:2',
...
'shipping.country' => 'nullable|string|max:2',
'shipping.postal_code' => 'postal_code_with:billing.country,shipping.country'

Fluent API

If you prefer using a fluent object style over string based rules, that's also available:

'postal_code' => [
    PostalCode::for('NL')->or('BE'),
],

The same goes for the postal_code_with rule:

'billing.country' => 'required|string|max:2',
...
'shipping.country' => 'nullable|string|max:2',
'shipping.postal_code' => [
    PostalCode::with('billing.country')->or('shipping.country')
],

Adding an error message

To add a meaningful error message, add the following lines to resources/lang/{your language}/validation.php:

'postal_code' => 'Your message here',
'postal_code_with' => 'Your message here',

The following placeholders will be automatically filled for you:

Placeholder Description
:attribute The name of the field that was under validation
:countries The countries that were validated against (e.g. NL, BE)*
:examples Examples of allowed postal codes (e.g. 1234 AB, 4000)*

*The :countries and :examples placeholders may be empty if no valid countries are passed.

Manually validating

If you want to validate postal codes manually outside of Laravel's validation system, you can call the validator directly, like so:

PostalCodes::passes($country, $postalCode); // returns a boolean

Overriding rules

Depending on your use case you may want to override the patterns used to validate postal codes for a country. You can do this by adding the code below in a central place in your application (e.g. a service provider):

PostalCodes::override('country', '/your pattern/');

// You can also pass overrides as an array

PostalCodes::override([
    'country 1' => '/pattern 1/',
    'country 2' => '/pattern 2/',
]);

Important: If you believe there is a bug in one of the patterns that this package ships with, please create an issue in the issue tracker.

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Credits

License

This open-source software is licenced under the MIT license. This software contains code generated from Google's Address Data Service, more information on this service can be found here.

laravel-postal-code-validation's People

Contributors

axlon avatar jpscharf avatar laravel-shift avatar mikemand avatar realrashid avatar schonhoff avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

laravel-postal-code-validation's Issues

Dutch Postal Code matches invalid postcode

  • PHP: n/a
  • Laravel: n/a
  • Postal code validation: master @ d634176 (resolved from code on GitHub)

Description:

The Dutch regex matches invalid postal codes on two parts:

  1. The postcodes cannot start with a 0, but the regex allows this.
  2. The postcodes cannot end with SA, SD or SS due to the reference to the Stormabteilung, Sicherheitsdienst and the Shutzstaffel. Credit to @wotta for learning me about this.

Steps To Reproduce:

  1. Validate against 0123 AB, 1111 SA or 5949 SS
  2. Get accepted as valid input

British Overseas Territories improvement

Hey,

I've come across a potential improvement with the British Overseas Territories.

My feeling is that the Regex is too strict and should allow for no spaces to be provided.

example: "FIQQ1ZZ" (Falkland Islands FK)

This does not pass the validation.

Here's a simple solution for the regex: "/^(?:FIQQ ?1ZZ)$/i"

This solution can be applied to many of the territories.

Resource: https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#British_Overseas_Territories

Optional postcode not possible

  • PHP: 7.4.28
  • Laravel: 8.83.2
  • Postal code validation: 3.3.0

Description:

I am trying to make an optional postcode field, so that it can either be blank or be a valid postcode only.

This doesn't seem to be possible, as the validator checks a blank empty string value and errors that it is not a valid postal code

Steps To Reproduce:

Create a Validator with rule ['postcode' => 'postal_code:GB'] and POST an empty postal code to it. Notice I haven't added required, so it should treat the field as optional but it has the validation error.

Inward code max length

Hey,

I've come across a potential issue with the Inward code for a United Kingdom postcode.

From what I've researched the length of the inward code is 3 characters.

Using this example: NN1 5LLL

Even though it's an invalid postcode (inward code being 4 characters long), it gets passed validation.

Resource: https://www.mrs.org.uk/pdf/postcodeformat.pdf

InvalidArgumentException: Unsupported country code {countryCode}

If one are using this package to validate postal codes, then there is a good chance, that one is using a country code validation package like for example the laravel-validation-rules/country-codes package

Problem 1: Invalid country code

If one is sending two fields like this:

use LVR\CountryCode\Two;

Validator::make([
    'country' => 'XX',//invliad country
    'postal_code' => '12345789',
], [
    'country' => ['required', new Two],
    'postal_code' => 'required|postal_code:country'
]);

Then the validation rule is throwing an InvalidArgumentException exception since the country XX is unknown. The problem is that this is already handled by the new Two rule, so it's unfortunate that the user gets a HTTP 500 error.

Problem 2: Unsupported country code

Let's assume that a country YY exists, but is not supported by this package.

If one is sending two fields like this:

use LVR\CountryCode\Two;

Validator::make([
    'country' => 'YY',//assume a valid country that is just not supported by this package
    'postal_code' => '12345789',
], [
    'country' => ['required', new Two],
    'postal_code' => 'required|postal_code:country'
]);

Then the validation rule is throwing an InvalidArgumentException exception since the country YY is unknown to the package. There might be use cases where would like a logic that is more like only fail for countries supported by the package and assume valid for unsupported countries.

Suggestion 1: Don't throw exceptions

I suggest that instead of throwing an InvalidArgumentException the we simply return false. That way validation will fail, but the customer will see that the

Suggestion 2: Add a new rule only for supported countries

If we add a new rule postal_code_only_supported:country which returns false for invalid postal codes in supported countries and true for valid postal codes in supported countries + true for any postalcode in unsupported countries.

With this new rule and the existing rule, then we can support all use cases.

What do you think @axlon?

Allow spaces in postcode

Hey,

I've just had another potential issue but this one is more of a suggestion that a bug.

A Customer entered the postcode: 'CF 242NY'

This came back as an invalid UK postcode.

We don't want to strip white space from the postcodes before posting to a form request but we still want it to pass validation. Is it possible to ignore whitespace when validating a UK postcode?

No error for incorrect postal codes

It doesn't show any error for incorrect postal codes, for example if i insert a postal code 55555 for IT (Italy), and it doesn't show any error.
All it does is check if the inserted postal code has the postal code length of that country:

'pattern' => '/^\d{5}$/i',

I suggest you submit postal codes from the world in this package, and then it would be available to laravel users, and updated accordingly, to avoid such problems.

Question: Correct way to accept empty postal codes in countries with none

From this list then it looks like a total of 66 countries world wide do not really use postal codes. Ireland is an example and according to one of our sources then it is only 30% of the population that live on an address with a postal code (validity not verified).

We have two fields in our request postal_code and country. I would very much like to say that the postal_code field is required if it's required in the country code provided in the field country but if the postal code is not required, then it's okay to pass null`.

I have made a test for it that fails, do you have any way of implementing this? Maybe with a required rule that can check if this is required?

/**
 * Test that empty postal codes are allowed correctly.
 *
 * @return void
 */
public function testEmptyPostalCode()
{
    $this->assertTrue(Validator::make([
        'country' => 'IR',
        'postal_code' => null,//IR does not require postal codes
    ], [
        'country' => 'required',
        'postal_code' => 'postal_code:country',
    ])->passes());//This fails

    $this->assertTrue(Validator::make([
        'country' => 'DK',
        'postal_code' => null,//DK requires postal codes
    ], [
        'country' => 'required',
        'postal_code' => 'postal_code:country',
    ])->fails());
}

[PROPOSAL] Add required format to the error message

It would be a really nice addon to the validation if the error message could contain the required postal code format for the given country.

The docs has this section:

To add an error message your users will be able to understand, open resources/lang/{your language}/validation.php and add the following line to it:

'postal_code' => 'The :attribute field must be a valid postal code.',

Imagine instead an error message like:

'postal_code' => 'The :attribute field must be a valid postal code with format :format.',

This can be done using the $validator->addReplacer() method described here. Unfortunatly I am not really sure where would be the best place in the code for placing this.

Would this feature be of interest?

Null not possible

Hello,

I get the following error after trying to pass a 'null' to the postal code validation.

TypeError
Argument 2 passed to Axlon\PostalCodeValidation\PostalCodeValidator::passes() must be of the type string,
null given, called in /html/vendor/axlon/laravel-postal-code-validation/src/Extensions/PostalCode.php on line 85

I fixed it by adding a

'bail', 'required'

to my rule set but I think the package should check itself. Maybe you can add an additional test if the given postal code is null and return false. Here my possible workaround:

 /**
     * Determine if the given postal code(s) are valid for the given country.
     *
     * @param string $countryCode
     * @param string|null ...$postalCodes
     * @return bool
     */
    public function passes(string $countryCode, ?string ...$postalCodes): bool
    {
       // Added
        if(!isset($postalCodes)) {
           return false;
        }

        if (!$this->supports($countryCode)) {
            return false;
        }

        if (($pattern = $this->patternFor($countryCode)) === null) {
            return true;
        }

        foreach ($postalCodes as $postalCode) {
            if (preg_match($pattern, $postalCode) !== 1) {
                return false;
            }
        }

        return true;
    }

Thanks for the work and if I need to check in a pr, just ask :-)

Laravel 10 support

Hey!

Description

Will Laravel 10 be supported for this package? It was released today.
Thanks for the great package. Helped me out a lot and would love to use it still in the future.

Issue with array validation

I have been playing around with this awesome package, and found this bug while trying to validate arrays.

In the following then I test with a valid postal code format 1234 for Denmark (DK) and an invalid postal code format 12345.

Bug

While trying to validate an array of countries and postal codes, then we try:

Validator::make([
    'test' => [
        [
            'postal_code' => '1234',//valid
        ],
        [
            'postal_code' => '12345',//invalid
        ],
    ],
], [
    'test.*.country' => 'required',
    'test.*.postal_code' => 'required|postal_code:DK',//Fixed country
])->errors()->toArray();

Note that we use the rule postal_code:DK where we used the fix country DK. This resulted in an error for test.1.postal_code, which is completely correct.

Not let us try to use a country field for specifying the country. An example of such use can be found in the Laravel documentation here:

Validator::make([
    'test' => [
        [
            'country' => 'DK',
            'postal_code' => '1234',//valid
        ],
        [
            'country' => 'DK',
            'postal_code' => '12345',//invalid
        ],
    ],
], [
    'test.*.country' => 'required',
    'test.*.postal_code' => 'required|postal_code:test.*.country',//Variable country
])->errors()->toArray();

Note that we used the new country field for specifying the country. Now we get an error for both entries test.0.postal_code and test.1.postal_code.

What is wrong

I am using a custom validation message:

'postal_code' => 'The :attribute field must be a valid postal code in :countries of format :formats.',

and for the working example above with fixed country code, then I get the error message:

[
     "test.1.postal_code" => [
       "The test.1.postal_code field must be a valid postal code in DK of format ####.",
     ],
   ]

while the country and format is missing from the failing example with a country field:

[
     "test.0.postal_code" => [
       "The test.0.postal_code field must be a valid postal code in  of format .",
     ],
     "test.1.postal_code" => [
       "The test.1.postal_code field must be a valid postal code in  of format .",
     ],
   ]

Note that country and format is missing.

I have not started to investigate this thoroughly yet but wanted to share my findings in case anyone else came across this issue.

@axlon Great work on this package so far ๐Ÿ‘

Wrong Validation of Irish Eircodes

It looks like the regex for the Irish post codes (AKA Eircodes) is incorrect
Please see page page 6 of the product guide (https://www.eircode.ie/docs/default-source/gating-files/ecaf---(eircode-address-file)-product-guide-edition-2-version-2---publishedb6a16c390ba0643fbc0cff00006e1d14.pdf)

I dont feel confident enough to write good regex expressions but gave it a try and I think the following should be correct /[AC-FHKNPRTVWXY]{1}[0-9]{1}[0-9W]{1}[0-9AC-FHKNPRTV-Y]{4}/

Test: https://regex101.com/r/9Jmabs/3

Validation fails for postal code starting with 0

  • PHP: 8.1
  • Laravel: 9.43.0
  • Postal code validation: 3.3

Description:

I try to add postal code 06425 for Alsleben in Germany and the validation fails.

Steps To Reproduce:

$rules = [
   'zip' => 'required|postal_code:DE,AT,LU,FR,CZ,PL,RO'
];

UK postal codes not working properly

Hei,
Great library!

I am having issues with UK postcodes, which are actually postal_code:GB

The postal code M1 does not work(which is a valid one) but M1 1AN works or any other more complex. M25, M45 doesn't work(which are valid postcodes).

I might be wrong, but googling around shows these postcodes, and in the existing codebase I have this kind of postcodes. Yet again, I might be wrong.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.