FormAddressGeocoder::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 22
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 8
dl 0
loc 22
ccs 9
cts 9
cp 1
crap 2
rs 10
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace WebTheory\Saveyour\Processor;
4
5
use CommerceGuys\Addressing\Address;
6
use CommerceGuys\Addressing\AddressFormat\AddressFormatRepository;
7
use CommerceGuys\Addressing\Country\CountryRepository;
8
use CommerceGuys\Addressing\Formatter\DefaultFormatter;
9
use CommerceGuys\Addressing\Subdivision\SubdivisionRepository;
10
use Geocoder\Provider\Provider;
11
use Geocoder\Query\GeocodeQuery;
12
use Psr\Http\Message\ServerRequestInterface;
13
use WebTheory\Saveyour\Contracts\Data\FieldDataManagerInterface;
14
use WebTheory\Saveyour\Contracts\Formatting\InputFormatterInterface;
15
use WebTheory\Saveyour\Contracts\Processor\FormDataProcessorInterface;
16
use WebTheory\Saveyour\Contracts\Report\FormProcessReportInterface;
17
use WebTheory\Saveyour\Formatting\LazyDataFormatter;
18
use WebTheory\Saveyour\Processor\Abstracts\AbstractRestrictedFormDataProcessor;
19
use WebTheory\Saveyour\Report\Builder\FormProcessReportBuilder;
20
21
class FormAddressGeocoder extends AbstractRestrictedFormDataProcessor implements FormDataProcessorInterface
22
{
23
    protected string $countryCode = 'US';
24
25
    protected Provider $provider;
26
27
    protected FieldDataManagerInterface $addressDataManager;
28
29
    protected InputFormatterInterface $geoDataFormatter;
30
31
    protected FieldDataManagerInterface $geoDataManager;
32
33
    protected InputFormatterInterface $addressDataFormatter;
34
35
    /**
36
     * {@inheritDoc}
37
     */
38
    public const ACCEPTED_FIELDS = ['street', 'city', 'state', 'zip', 'country'];
39
40 9
    public function __construct(
41
        string $name,
42
        array $fields,
43
        Provider $provider,
44
        FieldDataManagerInterface $geoDataManager,
45
        ?InputFormatterInterface $geoDataFormatter = null,
46
        ?FieldDataManagerInterface $addressDataManager = null,
47
        ?InputFormatterInterface $addressDataFormatter = null,
48
        string $countryCode = 'US'
49
    ) {
50 9
        parent::__construct($name, $fields);
51
52 9
        $this->provider = $provider;
53 9
        $this->geoDataManager = $geoDataManager;
54 9
        $this->geoDataFormatter = $geoDataFormatter ?? new LazyDataFormatter();
55
56 9
        if ($addressDataManager) {
57 9
            $this->addressDataManager = $addressDataManager;
58 9
            $this->addressDataFormatter = $addressDataFormatter ?? new LazyDataFormatter();
59
        }
60
61 9
        $this->countryCode = $countryCode;
62
    }
63
64 9
    public function process(ServerRequestInterface $request, array $results): ?FormProcessReportInterface
65
    {
66 9
        return $this->valueUpdated($results)
67 9
            ? $this->processResults($request, $results)
68 9
            : null;
69
    }
70
71 9
    protected function processResults(ServerRequestInterface $request, $results): FormProcessReportInterface
72
    {
73 9
        $address = $this->getFormattedAddress($this->extractValues($results));
74
75 9
        $query = $this->provider->geocodeQuery(GeocodeQuery::create($address));
76 9
        $data = $query->first()->getCoordinates();
77
78 6
        $coordinates = [
79 9
            'lat' => $data->getLatitude(),
80 9
            'lng' => $data->getLongitude(),
81
        ];
82
83 9
        $geoUpdated = $this->geoDataManager->handleSubmittedData(
84
            $request,
85 9
            $this->formatGeoDataInput($coordinates)
86
        );
87
88 9
        if (isset($this->addressDataManager)) {
89 6
            $addressUpdated = $this->addressDataManager->handleSubmittedData(
90
                $request,
91 6
                $this->formatAddressInput($address)
92
            );
93
        }
94
95 9
        $reportBuilder = new FormProcessReportBuilder();
96
97
        return $reportBuilder
98 9
            ->withProcessResult('coordinates', $coordinates)
99 9
            ->withProcessResult('coordinates_updated', $geoUpdated)
100 9
            ->withProcessResult('address_updated', $addressUpdated ?? false)
101 9
            ->build();
102
    }
103
104 9
    protected function getFormattedAddress(array $fields): string
105
    {
106 9
        $address = (new Address())
107 9
            ->withAddressLine1($fields['street'])
108 9
            ->withLocality($fields['city'])
109 9
            ->withAdministrativeArea($fields['state'])
110 9
            ->withPostalCode($fields['zip'])
111 9
            ->withCountryCode($fields['country'] ?? $this->countryCode);
112
113 6
        $options = [
114
            'html' => false,
115
        ];
116
117 9
        $formatter = new DefaultFormatter(
118 9
            new AddressFormatRepository(),
119 9
            new CountryRepository(),
120 9
            new SubdivisionRepository(),
121
            $options
122
        );
123
124 9
        return str_replace("\n", ", ", $formatter->format($address));
125
    }
126
127 9
    protected function formatGeoDataInput($value)
128
    {
129 9
        return $this->geoDataFormatter->formatInput($value);
130
    }
131
132 6
    protected function formatAddressInput($value)
133
    {
134 6
        return $this->addressDataFormatter->formatInput($value);
135
    }
136
}
137