Completed
Push — master ( 4f129d...e0da6a )
by Tobias
01:36
created

Chain::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Geocoder package.
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @license    MIT License
11
 */
12
13
namespace Geocoder\Provider\Chain;
14
15
use Geocoder\Collection;
16
use Geocoder\Model\AddressCollection;
17
use Geocoder\Query\GeocodeQuery;
18
use Geocoder\Query\ReverseQuery;
19
use Geocoder\Provider\Provider;
20
use Psr\Log\LoggerAwareInterface;
21
use Psr\Log\LoggerAwareTrait;
22
use Psr\Log\LogLevel;
23
24
/**
25
 * @author Markus Bachmann <[email protected]>
26
 */
27
final class Chain implements Provider, LoggerAwareInterface
28
{
29
    use LoggerAwareTrait;
30
31
    /**
32
     * @var string
33
     */
34
    private $geocodeQueryLogLevel = LogLevel::ALERT;
35
36
    /**
37
     * @var string
38
     */
39
    private $reverseQueryLogLevel = LogLevel::ALERT;
40
41
    /**
42
     * @var Provider[]
43
     */
44
    private $providers = [];
45
46
    /**
47
     * @param Provider[] $providers
48
     */
49 4
    public function __construct(array $providers = [])
50
    {
51 4
        $this->providers = $providers;
52 4
    }
53
54
    public function setGeocodeQueryLogLevel(string $level)
55
    {
56
        $this->geocodeQueryLogLevel = $level;
57
    }
58
59
    public function setReverseQueryLogLevel(string $level)
60
    {
61
        $this->reverseQueryLogLevel = $level;
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67 1
    public function geocodeQuery(GeocodeQuery $query): Collection
68
    {
69 1
        foreach ($this->providers as $provider) {
70
            try {
71 1
                $result = $provider->geocodeQuery($query);
72
73 1
                if (!$result->isEmpty()) {
74 1
                    return $result;
75
                }
76 1
            } catch (\Throwable $e) {
77 1
                $this->log(
78 1
                    $this->geocodeQueryLogLevel,
79 1
                    'Provider "{providerName}" could not geocode address: "{address}".',
80
                    [
81 1
                        'exception' => $e,
82 1
                        'providerName' => $provider->getName(),
83 1
                        'address' => $query->getText(),
84
                    ]
85
                );
86
            }
87
        }
88
89
        return new AddressCollection();
90
    }
91
92
    /**
93
     * {@inheritdoc}
94
     */
95 1
    public function reverseQuery(ReverseQuery $query): Collection
96
    {
97 1
        foreach ($this->providers as $provider) {
98
            try {
99 1
                $result = $provider->reverseQuery($query);
100
101 1
                if (!$result->isEmpty()) {
102 1
                    return $result;
103
                }
104 1
            } catch (\Throwable $e) {
105 1
                $coordinates = $query->getCoordinates();
106
107 1
                $this->log(
108 1
                    $this->reverseQueryLogLevel,
109 1
                    'Provider "{providerName}" could not reverse geocode coordinates: {latitude}, {longitude}".',
110
                    [
111 1
                        'exception' => $e,
112 1
                        'providerName' => $provider->getName(),
113 1
                        'latitude' => $coordinates->getLatitude(),
114 1
                        'longitude' => $coordinates->getLongitude(),
115
                    ]
116
                );
117
            }
118
        }
119
120
        return new AddressCollection();
121
    }
122
123
    /**
124
     * {@inheritdoc}
125
     */
126 1
    public function getName(): string
127
    {
128 1
        return 'chain';
129
    }
130
131
    /**
132
     * Adds a provider.
133
     *
134
     * @param Provider $provider
135
     *
136
     * @return Chain
137
     */
138 1
    public function add(Provider $provider): self
139
    {
140 1
        $this->providers[] = $provider;
141
142 1
        return $this;
143
    }
144
145
    /**
146
     * @param $level
147
     * @param $message
148
     * @param array $context
149
     */
150 2
    private function log($level, $message, array $context = [])
151
    {
152 2
        if ($this->logger) {
153
            $this->logger->log($level, $message, $context);
154
        }
155 2
    }
156
}
157