Completed
Push — add/remote-google-maps-key-syn... ( 366608 )
by
unknown
15:01 queued 03:52
created

Jetpack_Contact_Info_Widget::update()   D

Complexity

Conditions 14
Paths 192

Size

Total Lines 75
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 14
eloc 45
nc 192
nop 2
dl 0
loc 75
rs 4.9339
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
if ( ! class_exists( 'Jetpack_Contact_Info_Widget' ) ) {
4
5
	//register Contact_Info_Widget widget
6
	function jetpack_contact_info_widget_init() {
7
		register_widget( 'Jetpack_Contact_Info_Widget' );
8
	}
9
10
	add_action( 'widgets_init', 'jetpack_contact_info_widget_init' );
11
12
	/**
13
	 * Makes a custom Widget for displaying Restaurant Location/Map, Hours, and Contact Info available.
14
	 *
15
	 * @package WordPress
16
	 */
17
	class Jetpack_Contact_Info_Widget extends WP_Widget {
18
19
		/**
20
		 * Constructor
21
		 */
22
		function __construct() {
23
			$widget_ops = array(
24
				'classname' => 'widget_contact_info',
25
				'description' => __( 'Display a map with your location, hours, and contact information.', 'jetpack' ),
26
				'customize_selective_refresh' => true,
27
			);
28
			parent::__construct(
29
				'widget_contact_info',
30
				/** This filter is documented in modules/widgets/facebook-likebox.php */
31
				apply_filters( 'jetpack_widget_name', __( 'Contact Info & Map', 'jetpack' ) ),
32
				$widget_ops
33
			);
34
			$this->alt_option_name = 'widget_contact_info';
35
36
			if ( is_customize_preview() ) {
37
				add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
38
			}
39
		}
40
41
		/**
42
		 * Enqueue scripts and styles.
43
		 */
44
		public function enqueue_scripts() {
45
			wp_enqueue_style( 'contact-info-map-css', plugins_url( 'contact-info/contact-info-map.css', __FILE__ ), null, 20160623 );
46
		}
47
48
49
		/**
50
		 * Return an associative array of default values
51
		 *
52
		 * These values are used in new widgets.
53
		 *
54
		 * @return array Array of default values for the Widget's options
55
		 */
56
		public function defaults() {
57
			return array(
58
				'title'   => __( 'Hours & Info', 'jetpack' ),
59
				'address' => __( "3999 Mission Boulevard,\nSan Diego CA 92109", 'jetpack' ),
60
				'phone'   => _x( '1-202-555-1212', 'Example of a phone number', 'jetpack' ),
61
				'hours'   => __( "Lunch: 11am - 2pm \nDinner: M-Th 5pm - 11pm, Fri-Sat:5pm - 1am", 'jetpack' ),
62
				'email'   => null,
63
				'showmap' => 0,
64
				'apikey'  => null,
65
				'lat'     => null,
66
				'lon'     => null
67
			);
68
		}
69
70
		/**
71
		 * Outputs the HTML for this widget.
72
		 *
73
		 * @param array $args     An array of standard parameters for widgets in this theme
74
		 * @param array $instance An array of settings for this widget instance
75
		 *
76
		 * @return void Echoes it's output
77
		 **/
78
		function widget( $args, $instance ) {
79
			jetpack_require_lib('class.jetpack-google-maps-api-key' );
80
			$google_maps = new Jetpack_Google_Maps_Api_Key();
81
			$google_maps->init();
82
			$instance = wp_parse_args( $instance, $this->defaults() );
83
84
			echo $args['before_widget'];
85
86
			if ( '' != $instance['title'] ) {
87
				echo $args['before_title'] . $instance['title'] . $args['after_title'];
88
			}
89
90
			/**
91
			 * Fires at the beginning of the Contact Info widget, after the title.
92
			 *
93
			 * @module widgets
94
			 *
95
			 * @since 3.9.2
96
			 */
97
			do_action( 'jetpack_contact_info_widget_start' );
98
99
			echo '<div itemscope itemtype="http://schema.org/LocalBusiness">';
100
101
			if ( '' != $instance['address'] ) {
102
103
				$showmap = $instance['showmap'];
104
105
				/** This action is documented in modules/widgets/contact-info.php */
106
				if ( $showmap && $this->has_good_map( $instance ) ) {
107
					/**
108
					 * Set a Google Maps API Key.
109
					 *
110
					 * @since 4.1.0
111
					 *
112
					 * @param string $api_key Google Maps API Key
113
					 */
114
					$api_key = apply_filters( 'jetpack_google_maps_api_key', $instance['apikey'] );
115
					echo $this->build_map( $instance['address'], $api_key );
116
				}
117
118
				$map_link = $this->build_map_link( $instance['address'] );
119
120
				echo '<div class="confit-address" itemscope itemtype="http://schema.org/PostalAddress" itemprop="address"><a href="' . esc_url( $map_link ) . '" target="_blank">' . str_replace( "\n", "<br/>", esc_html( $instance['address'] ) ) . "</a></div>";
121
			}
122
123
			if ( '' != $instance['phone'] ) {
124
				if ( wp_is_mobile() ) {
125
					echo '<div class="confit-phone"><span itemprop="telephone"><a href="' . esc_url( 'tel:' . $instance['phone'] ) . '">' . esc_html( $instance['phone'] ) . "</a></span></div>";
126
				}
127
				else {
128
					echo '<div class="confit-phone"><span itemprop="telephone">' . esc_html( $instance['phone'] ) . '</span></div>';
129
				}
130
			}
131
132
			if ( is_email( trim( $instance['email'] ) ) ) {
133
				printf(
134
					'<div class="confit-email"><a href="mailto:%1$s">%1$s</a></div>',
135
					esc_html( $instance['email'] )
136
				);
137
			}
138
139
			if ( '' != $instance['hours'] ) {
140
				echo '<div class="confit-hours" itemprop="openingHours">' . str_replace( "\n", "<br/>", esc_html( $instance['hours'] ) ) . "</div>";
141
			}
142
143
			echo '</div>';
144
145
			/**
146
			 * Fires at the end of Contact Info widget.
147
			 *
148
			 * @module widgets
149
			 *
150
			 * @since 3.9.2
151
			 */
152
			do_action( 'jetpack_contact_info_widget_end' );
153
154
			echo $args['after_widget'];
155
156
			/** This action is documented in modules/widgets/gravatar-profile.php */
157
			do_action( 'jetpack_stats_extra', 'widget_view', 'contact_info' );
158
		}
159
160
161
		/**
162
		 * Deals with the settings when they are saved by the admin. Here is
163
		 * where any validation should be dealt with.
164
		 *
165
		 * @param array $new_instance New configuration values
166
		 * @param array $old_instance Old configuration values
167
		 *
168
		 * @return array
169
		 */
170
		function update( $new_instance, $old_instance ) {
171
			jetpack_require_lib('class.jetpack-google-maps-api-key' );
172
			$google_maps = new Jetpack_Google_Maps_Api_Key();
173
			$google_maps->init();
174
175
			$update_lat_lon = false;
176
			if (
177
				! isset( $old_instance['address'] ) ||
178
				$this->urlencode_address( $old_instance['address'] ) != $this->urlencode_address( $new_instance['address'] )
179
			) {
180
				$update_lat_lon = true;
181
			}
182
183
			$instance            = array();
184
			$instance['title']   = wp_kses( $new_instance['title'], array() );
185
			$instance['address'] = wp_kses( $new_instance['address'], array() );
186
			$instance['phone']   = wp_kses( $new_instance['phone'], array() );
187
			$instance['email']   = wp_kses( $new_instance['email'], array() );
188
			$instance['hours']   = wp_kses( $new_instance['hours'], array() );
189
			$instance['apikey']  = wp_kses( isset( $new_instance['apikey'] ) ? $new_instance['apikey'] : $old_instance['apikey'], array() );
190
			$instance['lat']     = isset( $old_instance['lat'] ) ? floatval( $old_instance['lat'] ) : 0;
191
			$instance['lon']     = isset( $old_instance['lon'] ) ? floatval( $old_instance['lon'] ) : 0;
192
193
			if ( ! $instance['lat'] || ! $instance['lon'] ) {
194
				$update_lat_lon = true;
195
			}
196
197
			if ( $instance['address'] && $update_lat_lon ) {
198
199
				// Get the lat/lon of the user specified address.
200
				$address = $this->urlencode_address( $instance['address'] );
201
				$path    = "https://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=" . $address;
202
				/** This action is documented in modules/widgets/contact-info.php */
203
				$key = apply_filters( 'jetpack_google_maps_api_key', $instance['apikey'] );
204
205
				if ( ! empty( $key ) ) {
206
					$path = add_query_arg( 'key', $key, $path );
207
				}
208
				$json    = wp_remote_retrieve_body( wp_remote_get( esc_url( $path, null, null ) ) );
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 4 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
209
210
				if ( ! $json ) {
211
					// The read failed :(
212
					esc_html_e( "There was a problem getting the data to display this address on a map.  Please refresh your browser and try again.", 'jetpack' );
213
					die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method update() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
214
				}
215
216
				$json_obj = json_decode( $json );
217
218
				if ( "ZERO_RESULTS" == $json_obj->status ) {
219
					// The address supplied does not have a matching lat / lon.
220
					// No map is available.
221
					$instance['lat'] = "0";
222
					$instance['lon'] = "0";
223
				}
224
				else {
225
226
					$loc = $json_obj->results[0]->geometry->location;
227
228
					$lat = floatval( $loc->lat );
229
					$lon = floatval( $loc->lng );
230
231
					$instance['lat'] = "$lat";
232
					$instance['lon'] = "$lon";
233
				}
234
			}
235
236
			if ( ! isset( $new_instance['showmap'] ) ) {
237
				$instance['showmap'] = 0;
238
			}
239
			else {
240
				$instance['showmap'] = intval( $new_instance['showmap'] );
241
			}
242
243
			return $instance;
244
		}
245
246
247
		/**
248
		 * Displays the form for this widget on the Widgets page of the WP Admin area.
249
		 *
250
		 * @param array $instance Instance configuration.
251
		 *
252
		 * @return void
253
		 */
254
		function form( $instance ) {
255
			$instance = wp_parse_args( $instance, $this->defaults() );
256
			wp_enqueue_script(
257
				'contact-info-admin',
258
				Jetpack::get_file_url_for_environment(
259
					'_inc/build/widgets/contact-info/contact-info-admin.min.js',
260
					'modules/widgets/contact-info/contact-info-admin.js'
261
				),
262
				array( 'jquery' ),
263
				20160727
264
			);
265
266
			?>
267
			<p>
268
				<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_html_e( 'Title:', 'jetpack' ); ?></label>
269
				<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $instance['title'] ); ?>" />
270
			</p>
271
272
			<p>
273
				<label for="<?php echo esc_attr( $this->get_field_id( 'address' ) ); ?>"><?php esc_html_e( 'Address:', 'jetpack' ); ?></label>
274
				<textarea class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'address' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'address' ) ); ?>"><?php echo esc_textarea( $instance['address'] ); ?></textarea>
275
				<?php
276
				if ( $this->has_good_map( $instance ) ) {
277
					?>
278
					<input class="jp-contact-info-showmap" id="<?php echo esc_attr( $this->get_field_id( 'showmap' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'showmap' ) ); ?>" value="1" type="checkbox" <?php checked( $instance['showmap'], 1 ); ?> />
279
					<label for="<?php echo esc_attr( $this->get_field_id( 'showmap' ) ); ?>"><?php esc_html_e( 'Show map', 'jetpack' ); ?></label>
280
					<?php
281
				}
282
				else {
283
					?>
284
					<span class="error-message"><?php _e( 'Sorry. We can not plot this address. A map will not be displayed. Is the address formatted correctly?', 'jetpack' ); ?></span>
285
					<input id="<?php echo esc_attr( $this->get_field_id( 'showmap' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'showmap' ) ); ?>" value="<?php echo( intval( $instance['showmap'] ) ); ?>" type="hidden" />
286
					<?php
287
				}
288
				?>
289
			</p>
290
291
			<p class="jp-contact-info-apikey" style="<?php echo $instance['showmap'] ? '' : 'display: none;'; ?>">
292
				<label for="<?php echo esc_attr( $this->get_field_id( 'apikey' ) ); ?>">
293
					<?php _e( 'Google Maps API Key', 'jetpack' ); ?>
294
					<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'apikey' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'apikey' ) ); ?>" type="text" value="<?php echo esc_attr( $instance['apikey'] ); ?>" />
295
					<br />
296
					<small><?php printf( wp_kses( __( 'Google now requires an API key to use their maps on your site. <a href="%s">See our documentation</a> for instructions on acquiring a key.', 'jetpack' ), array( 'a' => array( 'href' => true ) ) ), 'https://jetpack.com/support/extra-sidebar-widgets/contact-info-widget/' ); ?></small>
297
				</label>
298
			</p>
299
300
			<p>
301
				<label for="<?php echo esc_attr( $this->get_field_id( 'phone' ) ); ?>"><?php esc_html_e( 'Phone:', 'jetpack' ); ?></label>
302
				<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'phone' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'phone' ) ); ?>" type="text" value="<?php echo esc_attr( $instance['phone'] ); ?>" />
303
			</p>
304
305
			<p>
306
				<label for="<?php echo esc_attr( $this->get_field_id( 'email' ) ); ?>"><?php esc_html_e( 'Email Address:', 'jetpack' ); ?></label>
307
				<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'email' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'email' ) ); ?>" type="text" value="<?php echo esc_attr( $instance['email'] ); ?>" />
308
			</p>
309
310
			<p>
311
				<label for="<?php echo esc_attr( $this->get_field_id( 'hours' ) ); ?>"><?php esc_html_e( 'Hours:', 'jetpack' ); ?></label>
312
				<textarea class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'hours' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'hours' ) ); ?>"><?php echo esc_textarea( $instance['hours'] ); ?></textarea>
313
			</p>
314
315
			<?php
316
		}
317
318
319
		/**
320
		 * Generate a Google Maps link for the supplied address.
321
		 *
322
		 * @param string $address Address to link to.
323
		 *
324
		 * @return string
325
		 */
326
		function build_map_link( $address ) {
327
			// Google map urls have lots of available params but zoom (z) and query (q) are enough.
328
			return "https://maps.google.com/maps?z=16&q=" . $this->urlencode_address( $address );
329
		}
330
331
332
		/**
333
		 * Builds map display HTML code from the supplied latitude and longitude.
334
		 *
335
		 * @param float $lat Map Latitude
0 ignored issues
show
Bug introduced by
There is no parameter named $lat. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
336
		 * @param float $lon Map Longitude
0 ignored issues
show
Bug introduced by
There is no parameter named $lon. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
337
		 *
338
		 * @return string HTML of the map
339
		 */
340
		function build_map( $address, $api_key = null ) {
341
			$this->enqueue_scripts();
342
			$src = add_query_arg( 'q', urlencode( $address ), 'https://www.google.com/maps/embed/v1/place' );
343
			if ( ! empty( $api_key ) ) {
344
				$src = add_query_arg( 'key', $api_key, $src );
345
			}
346
347
			return '<iframe width="600" height="216" frameborder="0" src="' . esc_url( $src ) . '" class="contact-map"></iframe>';
348
		}
349
350
		/**
351
		 * Encode an URL
352
		 *
353
		 * @param string $address The URL to encode
354
		 *
355
		 * @return string The encoded URL
356
		 */
357
		function urlencode_address( $address ) {
358
359
			$address = strtolower( $address );
360
			$address = preg_replace( "/\s+/", " ", trim( $address ) ); // Get rid of any unwanted whitespace
361
			$address = str_ireplace( " ", "+", $address ); // Use + not %20
362
			urlencode( $address );
363
364
			return $address;
365
		}
366
367
		/**
368
		 * Check if the instance has a valid Map location.
369
		 *
370
		 * @param array $instance Widget instance configuration.
371
		 *
372
		 * @return bool Whether or not there is a valid map.
373
		 */
374
		function has_good_map( $instance ) {
375
			// The lat and lon of an address that could not be plotted will have values of 0 and 0.
376
			return ! ( "0" == $instance['lat'] && "0" == $instance['lon'] );
377
		}
378
379
	}
380
381
}
382