Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
15.00% covered (danger)
15.00%
3 / 20
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
HttpGeoLocation
15.00% covered (danger)
15.00%
3 / 20
0.00% covered (danger)
0.00%
0 / 2
71.41
0.00% covered (danger)
0.00%
0 / 1
 __construct
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
3.14
 locate
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
56
1<?php
2
3namespace CookieWarning;
4
5use InvalidArgumentException;
6use MediaWiki\Http\HttpRequestFactory;
7use Wikimedia\IPUtils;
8
9/**
10 * Implements the GeoLocation class, which allows to locate the user based on the IP address.
11 */
12class HttpGeoLocation implements GeoLocation {
13    /** @var string */
14    private $geoIPServiceURL;
15    /** @var array */
16    private $locatedIPs = [];
17
18    /** @var HttpRequestFactory */
19    private $httpRequestFactory;
20
21    /**
22     * @param string $geoIPServiceURL
23     * @param HttpRequestFactory $httpRequestFactory
24     */
25    public function __construct( $geoIPServiceURL, HttpRequestFactory $httpRequestFactory ) {
26        if ( !is_string( $geoIPServiceURL ) || !$geoIPServiceURL ) {
27            throw new InvalidArgumentException( 'The geoIPServiceUL is invalid' );
28        }
29        $this->geoIPServiceURL = $geoIPServiceURL;
30        $this->httpRequestFactory = $httpRequestFactory;
31    }
32
33    /**
34     * {@inheritdoc}
35     * @param string $ip The IP address to lookup
36     * @return string|null
37     */
38    public function locate( $ip ) {
39        if ( isset( $this->locatedIPs[$ip] ) ) {
40            return $this->locatedIPs[$ip];
41        }
42        if ( !IPUtils::isValid( $ip ) ) {
43            throw new InvalidArgumentException( "$ip is not a valid IP address." );
44        }
45        if ( substr( $this->geoIPServiceURL, -1 ) !== '/' ) {
46            $this->geoIPServiceURL .= '/';
47        }
48        $json = $this->httpRequestFactory->get( $this->geoIPServiceURL . $ip, [
49            'timeout' => '2',
50        ] );
51        if ( !$json ) {
52            return null;
53        }
54        $returnObject = json_decode( $json );
55        if ( $returnObject === null || !property_exists( $returnObject, 'country_code' ) ) {
56            return null;
57        }
58        $this->locatedIPs[$ip] = $returnObject->country_code;
59
60        return $this->locatedIPs[$ip];
61    }
62}