Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
86 / 86
100.00% covered (success)
100.00%
28 / 28
CRAP
100.00% covered (success)
100.00%
1 / 1
AddressResult
100.00% covered (success)
100.00%
86 / 86
100.00% covered (success)
100.00%
28 / 28
47
100.00% covered (success)
100.00%
1 / 1
 getStreetNumber
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 __construct
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
1
 getStreetName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 applyDirection
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getRouteType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDirection
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUnit
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCity
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPostalCode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getZip4
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getStateName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getStateCode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCountry
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasStreetNumber
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasStreetName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasRouteType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasDirection
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasUnit
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasCity
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasPostalCode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasZip4
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasStateName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasStateCode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasCountry
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isPoBox
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFullAddress
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
1 / 1
17
 toArray
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
1
 __toString
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2declare(strict_types=1);
3/**
4 * Pop PHP Framework (https://www.popphp.org/)
5 *
6 * @link       https://github.com/popphp/popphp-framework
7 * @author     Nick Sagona, III <nick@popphp.org>
8 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
9 * @license    https://www.popphp.org/license     New BSD License
10 */
11
12/**
13 * @namespace
14 */
15namespace Pop\Parser\Address;
16
17use Pop\Parser\AbstractResult;
18
19/**
20 * Address result class
21 *
22 * @category   Pop
23 * @package    Pop\Parser
24 * @author     Nick Sagona, III <nick@popphp.org>
25 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
26 * @license    https://www.popphp.org/license     New BSD License
27 * @version    1.0.0
28 */
29class AddressResult extends AbstractResult
30{
31
32    /**
33     * Street number
34     * @var ?string
35     * */
36    protected ?string $streetNumber = null;
37
38    /**
39     * Street name
40     * @var ?string
41     * */
42    protected ?string $streetName = null;
43
44    /**
45     * Route type
46     * @var ?string
47     * */
48    protected ?string $routeType = null;
49
50    /**
51     * Direction
52     * @var ?string
53     * */
54    protected ?string $direction = null;
55
56    /**
57     * Direction position
58     * @var ?int
59     * */
60    protected ?int $directionPosition = null;
61
62    /**
63     * Unit
64     * @var ?string
65     * */
66    protected ?string $unit = null;
67
68    /**
69     * City
70     * @var ?string
71     * */
72    protected ?string $city = null;
73
74    /**
75     * Postal code
76     * @var ?string
77     * */
78    protected ?string $postalCode = null;
79
80    /**
81     * Zip 4
82     * @var ?string
83     * */
84    protected ?string $zip4 = null;
85
86    /**
87     * State name
88     * @var ?string
89     * */
90    protected ?string $stateName = null;
91
92    /**
93     * State code
94     * @var ?string
95     * */
96    protected ?string $stateCode = null;
97
98    /**
99     * Country
100     * @var ?string
101     * */
102    protected ?string $country = null;
103
104    /**
105     * PO Box flag
106     * @var bool
107     * */
108    protected bool $isPoBox = false;
109
110    /**
111     * Method to get street number
112     *
113     * @return ?string
114     */
115    public function getStreetNumber(): ?string
116    {
117        return $this->streetNumber;
118    }
119
120    /**
121     * Constructor
122     *
123     * @param  array $address
124     */
125    public function __construct(array $address)
126    {
127        $this->streetNumber      = $address['streetNumber'] ?? null;
128        $this->streetName        = $address['streetName'] ?? null;
129        $this->routeType         = $address['routeType'] ?? null;
130        $this->direction         = $address['direction'] ?? null;
131        $this->directionPosition = $address['directionPosition'] ?? null;
132        $this->unit              = $address['unit'] ?? null;
133        $this->isPoBox           = $address['isPoBox'] ?? false;
134        $this->city              = $address['city'] ?? null;
135        $this->postalCode        = $address['postalCode'] ?? null;
136        $this->zip4              = $address['zip4'] ?? null;
137        $this->stateName         = $address['stateName'] ?? null;
138        $this->stateCode         = $address['stateCode'] ?? null;
139        $this->country           = $address['country'] ?? null;
140        $this->confidence        = $address['confidence'] ?? 1.0;
141    }
142
143    /**
144     * Method to get street name
145     *
146     * @param  bool $withRouteDirection
147     * @return ?string
148     */
149    public function getStreetName(bool $withRouteDirection = true): ?string
150    {
151        return $withRouteDirection ? $this->applyDirection($this->streetName) : $this->streetName;
152    }
153
154    /**
155     * Prepend/append the direction to a street name, per its recorded position
156     *
157     * @param  ?string $streetName
158     * @return ?string
159     */
160    private function applyDirection(?string $streetName): ?string
161    {
162        if (empty($this->direction)) {
163            return $streetName;
164        }
165
166        return ($this->directionPosition == 1)
167            ? $streetName . ' ' . $this->direction
168            : $this->direction . ' ' . $streetName;
169    }
170
171    /**
172     * Method to get route type
173     *
174     * @return ?string
175     */
176    public function getRouteType(): ?string
177    {
178        return $this->routeType;
179    }
180
181    /**
182     * Method to get direction
183     *
184     * @return ?string
185     */
186    public function getDirection(): ?string
187    {
188        return $this->direction;
189    }
190
191    /**
192     * Method to get unit
193     *
194     * @return ?string
195     */
196    public function getUnit(): ?string
197    {
198        return $this->unit;
199    }
200
201    /**
202     * Method to get city
203     *
204     * @return ?string
205     */
206    public function getCity(): ?string
207    {
208        return $this->city;
209    }
210
211    /**
212     * Method to get postal code
213     *
214     * @return ?string
215     */
216    public function getPostalCode(): ?string
217    {
218        return $this->postalCode;
219    }
220
221    /**
222     * Method to get zip 4
223     *
224     * @return ?string
225     */
226    public function getZip4(): ?string
227    {
228        return $this->zip4;
229    }
230
231    /**
232     * Method to get state name
233     *
234     * @return ?string
235     */
236    public function getStateName(): ?string
237    {
238        return $this->stateName;
239    }
240
241    /**
242     * Method to get state code
243     *
244     * @return ?string
245     */
246    public function getStateCode(): ?string
247    {
248        return $this->stateCode;
249    }
250
251    /**
252     * Method to get country
253     *
254     * @return ?string
255     */
256    public function getCountry(): ?string
257    {
258        return $this->country;
259    }
260
261    /**
262     * Has street number
263     *
264     * @return bool
265     */
266    public function hasStreetNumber(): bool
267    {
268        return !empty($this->streetNumber);
269    }
270
271    /**
272     * Has street name
273     *
274     * @return bool
275     */
276    public function hasStreetName(): bool
277    {
278        return !empty($this->streetName);
279    }
280
281    /**
282     * Has route type
283     *
284     * @return bool
285     */
286    public function hasRouteType(): bool
287    {
288        return !empty($this->routeType);
289    }
290
291    /**
292     * Has direction
293     *
294     * @return bool
295     */
296    public function hasDirection(): bool
297    {
298        return !empty($this->direction);
299    }
300
301    /**
302     * Has unit
303     *
304     * @return bool
305     */
306    public function hasUnit(): bool
307    {
308        return !empty($this->unit);
309    }
310
311    /**
312     * Has city
313     *
314     * @return bool
315     */
316    public function hasCity(): bool
317    {
318        return !empty($this->city);
319    }
320
321    /**
322     * Has postal code
323     *
324     * @return bool
325     */
326    public function hasPostalCode(): bool
327    {
328        return !empty($this->postalCode);
329    }
330
331    /**
332     * Has zip 4
333     *
334     * @return bool
335     */
336    public function hasZip4(): bool
337    {
338        return !empty($this->zip4);
339    }
340
341    /**
342     * Has state name
343     *
344     * @return bool
345     */
346    public function hasStateName(): bool
347    {
348        return !empty($this->stateName);
349    }
350
351    /**
352     * Has state code
353     *
354     * @return bool
355     */
356    public function hasStateCode(): bool
357    {
358        return !empty($this->stateCode);
359    }
360
361    /**
362     * Has country
363     *
364     * @return bool
365     */
366    public function hasCountry(): bool
367    {
368        return !empty($this->country);
369    }
370
371    /**
372     * Is PO Box
373     *
374     * @return bool
375     */
376    public function isPoBox(): bool
377    {
378        return $this->isPoBox;
379    }
380
381    /**
382     * Method to get full address
383     *
384     * @param  string $delimiter
385     * @param  bool   $useStateCode
386     * @param  bool   $includeCountry
387     * @return string
388     */
389    public function getFullAddress(string $delimiter = ', ', bool $useStateCode = true, bool $includeCountry = false): string
390    {
391        $fullAddress  = [];
392        $addressLine1 = null;
393
394        if (!empty($this->streetNumber)) {
395            $addressLine1 = $this->streetNumber;
396        }
397
398        if (!empty($this->streetName)) {
399            $streetName = $this->applyDirection($this->streetName);
400
401            if (!empty($this->routeType)) {
402                $streetName .= ' ' . $this->routeType;
403            }
404
405            if (!empty($addressLine1)) {
406                $addressLine1 .= ' ' . $streetName;
407            } else {
408                $addressLine1 = $streetName;
409            }
410        }
411
412        if (!empty($addressLine1)) {
413            $fullAddress[] = $addressLine1;
414        }
415
416        if (!empty($this->unit)) {
417            $fullAddress[] = $this->unit;
418        }
419
420        if (!empty($this->city) && (!empty($this->stateCode) || !empty($this->stateName))) {
421            $cityState = $this->city;
422            if (($useStateCode) && !empty($this->stateCode)) {
423                $cityState .= ', ' . $this->stateCode;
424            } else if (!empty($this->stateName)) {
425                $cityState .= ', ' . $this->stateName;
426            }
427
428            if (!empty($this->postalCode)) {
429                $cityState .= ' ' . $this->postalCode;
430                if (!empty($this->zip4)) {
431                    $cityState .= '-' . $this->zip4;
432                }
433            }
434
435            $fullAddress[] = $cityState;
436        }
437
438        if (($includeCountry) && !empty($this->country)) {
439            $fullAddress[] = $this->country;
440        }
441
442        return implode($delimiter, $fullAddress);
443    }
444
445    /**
446     * To array method
447     *
448     * @return array
449     */
450    public function toArray(): array
451    {
452        return [
453            'streetNumber' => $this->streetNumber,
454            'streetName'   => $this->streetName,
455            'routeType'    => $this->routeType,
456            'direction'    => $this->direction,
457            'unit'         => $this->unit,
458            'city'         => $this->city,
459            'postalCode'   => $this->postalCode,
460            'zip4'         => $this->zip4,
461            'stateName'    => $this->stateName,
462            'stateCode'    => $this->stateCode,
463            'country'      => $this->country,
464            'confidence'   => $this->confidence,
465        ];
466    }
467
468    /**
469     * To string method
470     *
471     * @return string
472     */
473    public function __toString(): string
474    {
475        return $this->getFullAddress();
476    }
477
478}