Postcode::__toString()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * Postcode
4
 *
5
 * @copyright Copyright (c) Vasil Dakov <[email protected]>
6
 * @license http://opensource.org/licenses/MIT MIT
7
 */
8
namespace VasilDakov\Postcode;
9
10
use VasilDakov\Postcode\Exception;
11
12
class Postcode implements PostcodeInterface, \Serializable, \JsonSerializable
13
{
14
    /**
15
     * Regular expression pattern for Outward code
16
     */
17
18
    const REGEXP_POSTCODE_UKGOV = "/^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$/";
19
20
    /**
21
     * Regular expression pattern for Outward code
22
     */
23
    const REGEXP_POSTCODE     = "/^[A-Za-z]{1,2}\d[a-z\d]?\s*\d[A-Za-z]{2}$/i";
24
25
26
    /**
27
     * Regular expression pattern for Outward code
28
     */
29
    const REGEXP_OUTWARD     = "/\d[A-Za-z]{1,2}$/i";
30
31
32
    /**
33
     * Regular expression pattern for Inward code
34
     */
35
    const REGEXP_INWARD      = "/\d[A-Za-z]{2}$/i";
36
37
38
    /**
39
     * Regular expression pattern for Area code
40
     */
41
    const REGEXP_AREA        = "/^[A-Za-z]{1,2}/i";
42
43
44
    /**
45
     * Regular expression pattern for Sector code
46
     */
47
    const REGEXP_SECTOR      = "/^[A-Za-z]{1,2}\d[A-Za-z\d]?\s*\d/i";
48
49
50
    /**
51
     * Regular expression pattern for Unit code
52
     */
53
    const REGEXP_UNIT        =  "/[A-Za-z]{2}$/i";
54
55
56
    /**
57
     * Regular expression pattern for District code
58
     */
59
    const REGEXP_DISTRICT    = "/^([A-Za-z]{1,2}\d)([A-Za-z])$/i";
60
61
62
    /**
63
     * Regular expression pattern for Subdistrict code
64
     */
65
    const REGEXP_SUBDISTRICT = "/^([A-Za-z]{1,2}\d)([A-Za-z])$/i";
66
67
68
    /**
69
     * @var string $value
70
     */
71
    protected $value;
72
73
74
    /**
75
     * Constructor
76
     *
77
     * @param string $value  e.g. "AA9A 9AA"
78
     */
79
    public function __construct($value)
80
    {
81
        if (!self::isValid($value)) {
82
            throw new Exception\InvalidArgumentException;
83
        }
84
85
        $this->value = $value;
86
    }
87
88
89
    /**
90
     * Normalise
91
     *
92
     * @return string  Example: "AA9A 9AA"
93
     */
94
    public function normalise()
95
    {
96
        return \strtoupper(sprintf("%s %s", $this->outward(), $this->inward()));
97
    }
98
99
100
    /**
101
     * Outward code
102
     *
103
     * The outward code is the part of the postcode before the single space in the middle.
104
     * It is between two and four characters long. A few outward codes are non-geographic,
105
     * not divulging where mail is to be sent. Examples of outward codes include "L1", "W1A",
106
     * "RH1", "RH10" or "SE1P".
107
     *
108
     * @return string Example: "AA9A"
109
     */
110
    public function outward()
111
    {
112
        return \trim(
113
            \preg_replace(self::REGEXP_OUTWARD, "", $this->value)
114
        );
115
    }
116
117
118
    /**
119
     * Backward compatibility with version 1.0
120
     *
121
     * @return string Example: "AA9A"
122
     */
123
    public function outcode()
124
    {
125
        return $this->outward();
126
    }
127
128
129
    /**
130
     * Inward code
131
     *
132
     * The inward part is the part of the postcode after the single space in the middle.
133
     * It is three characters long. The inward code assists in the delivery of post within
134
     * a postal district. Examples of inward codes include "0NY", "7GZ", "7HF", or "8JQ".
135
     *
136
     * @return string  Example: "9AA"
137
     */
138
    public function inward()
139
    {
140
        return (\preg_match(self::REGEXP_INWARD, $this->value, $matches)) ? $matches[0] : "";
141
    }
142
143
144
    /**
145
     * Backward compatibility with version 1.0
146
     *
147
     * @return string  Example: "9AA"
148
     */
149
    public function incode()
150
    {
151
        return $this->inward();
152
    }
153
154
155
    /**
156
     * Area code
157
     *
158
     * The postcode area is part of the outward code. The postcode area is either one or two
159
     * characters long and is all letters. Examples of postcode areas include "L" for Liverpool,
160
     * "RH" for Redhill and "EH" for Edinburgh. A postal area may cover a wide area, for example
161
     * "RH" covers north Sussex, and "BT" (Belfast) covers the whole of Northern Ireland.
162
     * There are 124 postcode areas in the UK.
163
     *
164
     * @return string  Example: "AA"
165
     */
166
    public function area()
167
    {
168
        return (\preg_match(self::REGEXP_AREA, $this->value, $matches)) ? $matches[0] : "";
169
    }
170
171
172
    /**
173
     * District code
174
     *
175
     * The postcode district is the outward code. It is made of the postcode area
176
     * plus one or two digits (and sometimes a final letter). The outward code is
177
     * between two and four characters long. Examples of postcode districts include
178
     * "W1A", "RH1", "RH10" or "SE1P".
179
     * There are approximately 2,900 postcode districts.
180
     *
181
     * @return string  Example: "AA9"
182
     */
183
    public function district()
184
    {
185
        return (\preg_match(self::REGEXP_DISTRICT, $this->outward(), $matches)) ? $matches[1] : "";
186
    }
187
188
189
    /**
190
     * Sector code
191
     *
192
     * The postcode sector is made up of the postcode district, the single space, and the
193
     * first character of the inward code. It is between four and six characters long
194
     * (including the single space). Examples of postcode sectors include "SW1W 0", "PO16 7",
195
     * "GU16 7", or "L1 8", "CV1 4". There are approximately 9,650 postcode sectors.
196
     *
197
     * @return string    Example: "AA9A 9"
198
     */
199
    public function sector()
200
    {
201
        return (\preg_match(self::REGEXP_SECTOR, $this->value, $matches)) ? $matches[0] : "";
202
    }
203
204
205
    /**
206
     * Unit code
207
     *
208
     * Identifies one or more small user delivery points or an individual large user.
209
     * There are approximately 1.71 million unit postcodes in the UK.
210
     *
211
     * @return string  Example: "AA"
212
     */
213
    public function unit()
214
    {
215
        return (\preg_match(self::REGEXP_UNIT, $this->value, $matches)) ? $matches[0] : "";
216
    }
217
218
219
    /**
220
     * Subdistrict code
221
     *
222
     * @return string  Example: "AA9A"
223
     */
224
    public function subdistrict()
225
    {
226
        return (\preg_match(self::REGEXP_SUBDISTRICT, $this->outward(), $matches)) ? $matches[0] : "";
227
    }
228
229
230
    /**
231
     * Returns true if the value is a valid UK postcode
232
     *
233
     * @param  string  $value
234
     * @return boolean
235
     */
236
    public static function isValid($value)
237
    {
238
        if (!\preg_match(self::REGEXP_POSTCODE, $value)) {
239
            return false;
240
        }
241
        return true;
242
    }
243
244
245
    /**
246
     * Returns a object taking PHP native value(s) as argument(s).
247
     *
248
     * @return Postcode
249
     */
250
    public static function fromNative()
251
    {
252
        $value = func_get_arg(0);
253
        return new static($value);
254
    }
255
256
257
    /**
258
     * Returns the value of the string
259
     *
260
     * @return string
261
     */
262
    public function toNative()
263
    {
264
        return $this->value;
265
    }
266
267
268
    /**
269
     * Returns TRUE if this Postcode object equals to another.
270
     *
271
     * @param  Postcode $other
272
     * @return boolean
273
     */
274
    public function equals(Postcode $other)
275
    {
276
        return $this->compareTo($other) == 0;
277
    }
278
279
280
    /**
281
     * Compare two Postcode and tells whether they can be considered equal
282
     *
283
     * @todo Replace toNative with toString
284
     * @todo strcmp — Binary safe string comparison
285
     *
286
     * @param  Postcode $object
0 ignored issues
show
Bug introduced by
There is no parameter named $object. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
287
     * @return bool
288
     */
289
    public function compareTo(Postcode $other)
290
    {
291
        return (strcmp($this->toNative(), $other->toNative()) !== 0);
292
    }
293
294
295
    /**
296
     * Returns an array with postcode elements
297
     *
298
     * @return array
299
     */
300
    public function split()
301
    {
302
        return [
303
            'outward'     => $this->outward(),
304
            'inward'      => $this->inward(),
305
            'area'        => $this->area(),
306
            'district'    => $this->district(),
307
            'subdistrict' => $this->subdistrict(),
308
            'sector'      => $this->sector(),
309
            'unit'        => $this->unit(),
310
            'normalise'   => $this->normalise(),
311
        ];
312
    }
313
314
315
    /**
316
     * Returns a string representation of the object
317
     *
318
     * @return string
319
     */
320
    public function __toString()
321
    {
322
        return (string) $this->normalise();
323
    }
324
325
326
    /**
327
     * Generates a storable representation of a value
328
     *
329
     * @return string
330
     */
331
    public function serialize()
332
    {
333
        return serialize($this->value);
334
    }
335
336
    /**
337
     * Creates a PHP value from a stored representation
338
     *
339
     * @param  string $serialized
340
     * @return string $value
341
     */
342
    public function unserialize($serialized)
343
    {
344
        $this->value = unserialize($serialized);
345
346
        return $this->value;
347
    }
348
349
350
    /**
351
     * Specify data which should be serialized to JSON
352
     *
353
     * @return mixed data which can be serialized by <b>json_encode</b>,
354
     * @link   http://php.net/manual/en/jsonserializable.jsonserialize.php
355
     */
356
    public function jsonSerialize()
357
    {
358
        return [
359
            'postcode' => (string) $this->normalise()
360
        ];
361
    }
362
}
363