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

Geolocate   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 60
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 6

Importance

Changes 6
Bugs 0 Features 0
Metric Value
wmc 6
c 6
b 0
f 0
lcom 0
cbo 6
dl 0
loc 60
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getLocation() 0 4 1
A __construct() 0 9 2
A __invoke() 0 14 3
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