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

Geocoder::geocode()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.0261

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 6
cts 7
cp 0.8571
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 2
nop 1
crap 3.0261
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