Completed
Push — master ( 00ed35...63fbb3 )
by Oscar
10:20
created

Geolocate::getGeocoder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 9.4286
cc 1
eloc 5
nc 1
nop 0
1
<?php
2
3
namespace Psr7Middlewares\Middleware;
4
5
use Psr7Middlewares\Middleware;
6
use Psr\Http\Message\ServerRequestInterface;
7
use Psr\Http\Message\ResponseInterface;
8
use Geocoder\Geocoder;
9
use Geocoder\ProviderAggregator;
10
use Geocoder\Provider\FreeGeoIp;
11
use Geocoder\Model\AddressCollection;
12
use Ivory\HttpAdapter\FopenHttpAdapter;
13
use RuntimeException;
14
15
/**
16
 * Middleware to geolocate the client using the ip.
17
 */
18
class Geolocate
19
{
20
    const KEY = 'GEOLOCATE';
21
22
    /**
23
     * @var Geocoder
24
     */
25
    private $geocoder;
26
27
    /**
28
     * Returns the client location.
29
     *
30
     * @param ServerRequestInterface $request
31
     *
32
     * @return AddressCollection|null
33
     */
34
    public static function getLocation(ServerRequestInterface $request)
35
    {
36
        return Middleware::getAttribute($request, self::KEY);
37
    }
38
39
    /**
40
     * Constructor. Set the geocoder instance.
41
     *
42
     * @param null|Geocoder $geocoder
43
     */
44
    public function __construct(Geocoder $geocoder = null)
45
    {
46
        if ($geocoder === null) {
47
            $geocoder = new ProviderAggregator();
48
            $geocoder->registerProvider(new FreeGeoIp(new FopenHttpAdapter()));
49
        }
50
51
        $this->geocoder = $geocoder;
52
    }
53
54
    /**
55
     * Execute the middleware.
56
     *
57
     * @param ServerRequestInterface $request
58
     * @param ResponseInterface      $response
59
     * @param callable               $next
60
     *
61
     * @return ResponseInterface
62
     */
63
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next)
64
    {
65
        if (!Middleware::hasAttribute($request, ClientIp::KEY)) {
66
            throw new RuntimeException('Geolocate middleware needs ClientIp executed before');
67
        }
68
69
        $ip = ClientIp::getIp($request);
70
71
        if ($ip !== null) {
72
            $request = Middleware::setAttribute($request, self::KEY, $this->geocoder->geocode($ip));
73
        }
74
75
        return $next($request, $response);
76
    }
77
}
78