Completed
Push — master ( 9e6196...c56468 )
by Daryl
02:13
created

Geocoder   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 171
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 98.25%

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 2
dl 0
loc 171
ccs 56
cts 57
cp 0.9825
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A api_key() 0 5 1
A geocode() 0 14 3
A _make_url() 0 9 1
A _make_location() 0 17 1
A _get_state_from_results() 0 5 1
A _get_zip_from_results() 0 5 1
A _get_value_from_results() 0 16 4
A _make_request() 0 18 3
A _get_data() 0 12 2
1
<?php
2
3
namespace Clubdeuce\WPGoogleMaps;
4
5
/**
6
 * Class Geocoder
7
 * @package Clubdeuce\WPGoogleMaps
8
 */
9
class Geocoder {
10
11
	/**
12
	 * @var string
13
	 */
14
	protected $_api_key;
15
16
	/**
17
	 * KSA_Geocoder constructor.
18
	 *
19
	 * @param array $args
20
	 */
21 1
	function __construct( $args = array() ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
22
23 1
		$args = wp_parse_args( $args, array(
24 1
			'api_key' => Google_Maps::api_key(),
25
		) );
26
27 1
		$this->_api_key = $args['api_key'];
28
29 1
	}
30
31
	/**
32
	 * @return string
33
	 */
34 1
	function api_key() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
35
36 1
		return $this->_api_key;
37
38
	}
39
40
	/**
41
	 * @param  string $address
42
	 * @return Location|\WP_Error
43
	 */
44 1
	function geocode( $address ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
45
46 1
		$location = new \WP_Error(100, 'No results found', array( 'address' => $address ) );
47 1
		$url = $this->_make_url( $address );
48
49 1
		$response = $this->_make_request( $url );
50
51 1
		if ( ! is_wp_error( $response ) && count( $response['results'] ) > 0 ) {
52
			$location = $this->_make_location( $response['results'][0] );
53
		}
54
55 1
		return $location;
56
57
	}
58
59
	/**
60
	 * @param  string $address
61
	 * @return string
62
	 */
63 2
	private function _make_url( $address ) {
64
65 2
		return sprintf(
66 2
			'https://maps.googleapis.com/maps/api/geocode/json?address=%1$s&key=%2$s',
67 2
			urlencode( filter_var( $address, FILTER_SANITIZE_STRING ) ),
68 2
			self::api_key()
69
		);
70
71
	}
72
73
	/**
74
	 * Convert the response body into an a Location object
75
	 *
76
	 * @param  array $results
77
	 * @return Location
78
	 */
79 1
	private function _make_location( $results ) {
80
81 1
		$response = new Location( array(
82 1
			'address'           => $results['formatted_address'],
83 1
			'formatted_address' => $results['formatted_address'],
84 1
			'state'             => self::_get_state_from_results( $results ),
85 1
			'zip_code'          => self::_get_zip_from_results( $results ),
86 1
			'latitude'          => $results['geometry']['location']['lat'],
87 1
			'longitude'         => $results['geometry']['location']['lng'],
88 1
			'place_id'          => $results['place_id'],
89 1
			'types'             => $results['types'],
90 1
			'viewport'          => $results['geometry']['viewport'],
91
		) );
92
93 1
		return $response;
94
95
	}
96
97
	/**
98
	 * @param  array  $results
99
	 * @return string
100
	 */
101 1
	private function _get_state_from_results( $results ) {
102
103 1
		return self::_get_value_from_results( 'administrative_area_level_1', $results );
104
105
	}
106
107
	/**
108
	 * @param  array $results
109
	 * @return string
110
	 */
111 1
	private function _get_zip_from_results( $results ) {
112
113 1
		return self::_get_value_from_results( 'postal_code', $results );
114
115
	}
116
117
	/**
118
	 * @param  string $value
119
	 * @param  array  $results
120
	 * @return string
121
	 */
122 2
	private function _get_value_from_results( $value, $results ) {
123
124 2
		$result_value = '';
125
126 2
		if ( isset( $results['address_components'] ) ) {
127 2
			foreach ( $results['address_components'] as $component ) {
128 2
				if ( $component['types'][0] === $value ) {
129 2
					$result_value = $component['short_name'];
130 2
					break;
131
				}
132
			}
133
		}
134
135 2
		return $result_value;
136
137
	}
138
139
	/**
140
	 * @param  string $url
141
	 * @return array|\WP_Error
142
	 */
143 2
	private function _make_request( $url ) {
144
145 2
		$return = new \WP_Error( 1, 'Invalid URL', $url );
146
147 2
		if ( wp_http_validate_url( $url ) ) {
148 1
			$request = $this->_get_data( $url );
149
150 1
			$return = new \WP_Error( $request['response']['code'], $request['response']['message'] );
151
152 1
			if ( 200 == $request['response']['code'] ) {
153 1
				$return = json_decode( $request['body'], true );
154
			}
155
156
		}
157
158 2
		return $return;
159
160
	}
161
162
	/**
163
	 * @param $url
164
	 * @return array|\WP_Error
165
	 */
166 2
	private function _get_data( $url ) {
167
168 2
		$cache_key = md5( serialize( $url ) );
169
170 2
		if ( ! $data = wp_cache_get( $cache_key ) ) {
171 1
			$data = wp_remote_get( $url );
172 1
			wp_cache_add( $cache_key, $data, 300 );
173
		}
174
175 2
		return $data;
176
177
	}
178
179
}
180