Skip to content

Commit 7b76bdd

Browse files
authored
Enhancements to exceptions and BE, LU formatters (#13)
1 parent c8c53ee commit 7b76bdd

File tree

10 files changed

+120
-3
lines changed

10 files changed

+120
-3
lines changed

src/FormatHelper/StripPrefix.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Brick\Postcode\FormatHelper;
6+
7+
/**
8+
* Strip country code prefix from postalcode if it is valid.
9+
*
10+
* In some countries like Belgium or Luxembourg its common to provide a country code prefix in a postalcode,
11+
* Although the format is incorrect, many government agencies, businesses and people still use this.
12+
* Rather than failing this format into an exception, this helper class strips the prefix off before validating it,
13+
* Thus providing you with the correct format without the country code prefix in it.
14+
*
15+
* @see https://en.wikipedia.org/wiki/Postal_codes_in_Belgium
16+
*
17+
* @internal
18+
*/
19+
trait StripPrefix
20+
{
21+
/**
22+
* @param string $postcode
23+
* @param string $prefix
24+
* @return string
25+
*/
26+
public function stripPrefix(string $postcode, string $prefix): string
27+
{
28+
$prefixLength = strlen($prefix);
29+
30+
if (substr($postcode, 0, $prefixLength) === $prefix) {
31+
$postcode = substr($postcode, $prefixLength);
32+
}
33+
34+
return $postcode;
35+
}
36+
}

src/Formatter/ATFormatter.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Brick\Postcode\Formatter;
66

77
use Brick\Postcode\CountryPostcodeFormatter;
8+
use Brick\Postcode\FormatHelper\StripPrefix;
89

910
/**
1011
* Validates and formats postcodes in Austria.
@@ -16,8 +17,12 @@
1617
*/
1718
class ATFormatter implements CountryPostcodeFormatter
1819
{
20+
use StripPrefix;
21+
1922
public function format(string $postcode) : ?string
2023
{
24+
$postcode = $this->stripPrefix($postcode, 'A');
25+
2126
if (preg_match('/^[1-9][0-9]{3}$/', $postcode) !== 1) {
2227
return null;
2328
}

src/Formatter/BEFormatter.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Brick\Postcode\Formatter;
66

77
use Brick\Postcode\CountryPostcodeFormatter;
8+
use Brick\Postcode\FormatHelper\StripPrefix;
89

910
/**
1011
* Validates and formats postcodes in Belgium.
@@ -16,8 +17,12 @@
1617
*/
1718
class BEFormatter implements CountryPostcodeFormatter
1819
{
20+
use StripPrefix;
21+
1922
public function format(string $postcode) : ?string
2023
{
24+
$postcode = $this->stripPrefix($postcode, 'B');
25+
2126
if (preg_match('/^[0-9]{4}$/', $postcode) !== 1) {
2227
return null;
2328
}

src/Formatter/LUFormatter.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Brick\Postcode\Formatter;
66

77
use Brick\Postcode\CountryPostcodeFormatter;
8+
use Brick\Postcode\FormatHelper\StripPrefix;
89

910
/**
1011
* Validates and formats postcodes in Luxembourg.
@@ -16,8 +17,12 @@
1617
*/
1718
class LUFormatter implements CountryPostcodeFormatter
1819
{
20+
use StripPrefix;
21+
1922
public function format(string $postcode) : ?string
2023
{
24+
$postcode = $this->stripPrefix($postcode, 'L');
25+
2126
if (preg_match('/^[0-9]{4}$/', $postcode) !== 1) {
2227
return null;
2328
}

src/InvalidPostcodeException.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,39 @@
99
*/
1010
class InvalidPostcodeException extends \Exception
1111
{
12+
protected string $postcode;
13+
protected string $country;
14+
15+
/**
16+
* Construct exception thrown when trying to format an invalid postcode.
17+
*
18+
* @param string $postcode
19+
* @param string $country
20+
*/
21+
public function __construct(string $postcode, string $country)
22+
{
23+
parent::__construct('Invalid postcode: ' . $postcode);
24+
$this->postcode = $postcode;
25+
$this->country = $country;
26+
}
27+
28+
/**
29+
* Get the invalid postcode associated with this exception.
30+
*
31+
* @return string
32+
*/
33+
public function getPostcode(): string
34+
{
35+
return $this->postcode;
36+
}
37+
38+
/**
39+
* Get the country ISO2 code associated with this exception.
40+
*
41+
* @return string
42+
*/
43+
public function getCountry(): string
44+
{
45+
return $this->country;
46+
}
1247
}

src/PostcodeFormatter.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,17 @@ public function format(string $country, string $postcode) : string
3838
$formatter = $this->getFormatter($country);
3939

4040
if ($formatter === null) {
41-
throw new UnknownCountryException('Unknown country: ' . $country);
41+
throw new UnknownCountryException($country);
4242
}
4343

4444
if (preg_match('/^[A-Z0-9]+$/', $postcode) !== 1) {
45-
throw new InvalidPostcodeException('Invalid postcode: ' . $postcode);
45+
throw new InvalidPostcodeException($postcode, $country);
4646
}
4747

4848
$formatted = $formatter->format($postcode);
4949

5050
if ($formatted === null) {
51-
throw new InvalidPostcodeException('Invalid postcode: ' . $postcode);
51+
throw new InvalidPostcodeException($postcode, $country);
5252
}
5353

5454
return $formatted;

src/UnknownCountryException.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,26 @@
99
*/
1010
class UnknownCountryException extends \Exception
1111
{
12+
protected string $country;
13+
14+
/**
15+
* Construct exception thrown when an unknown country code is provided.
16+
*
17+
* @param string $country
18+
*/
19+
public function __construct(string $country)
20+
{
21+
parent::__construct('Unknown country: ' . $country);
22+
$this->country = $country;
23+
}
24+
25+
/**
26+
* Get the unknown country ISO2 code associated with this exception.
27+
*
28+
* @return string
29+
*/
30+
public function getCountry(): string
31+
{
32+
return $this->country;
33+
}
1234
}

tests/Formatter/ATFormatterTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ public function providerFormat() : array
3737
['ABCD', null],
3838
['ABCDE', null],
3939
['ABCDEF', null],
40+
41+
['A8084', '8084'],
42+
['X8084', null],
4043
];
4144
}
4245
}

tests/Formatter/BEFormatterTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ public function providerFormat() : array
3636
['ABCD', null],
3737
['ABCDE', null],
3838
['ABCDEF', null],
39+
40+
['B8084', '8084'],
41+
['X8084', null],
3942
];
4043
}
4144
}

tests/Formatter/LUFormatterTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ public function providerFormat() : array
3434
['ABC', null],
3535
['ABCD', null],
3636
['ABCDE', null],
37+
38+
['L8084', '8084'],
39+
['X8084', null],
3740
];
3841
}
3942
}

0 commit comments

Comments
 (0)