PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 7.6.2
Jetpack – WP Security, Backup, Speed, & Growth v7.6.2
16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 All 503 releases
jetpack / modules / widgets / contact-info.php

contact-info.php in Jetpack – WP Security, Backup, Speed, & Growth 7.6.2, at modules/widgets/contact-info.php

397 lines 14.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 use Automattic\Jetpack\Assets;
4
5 if ( ! class_exists( 'Jetpack_Contact_Info_Widget' ) ) {
6
7 //register Contact_Info_Widget widget
8 function jetpack_contact_info_widget_init() {
9 register_widget( 'Jetpack_Contact_Info_Widget' );
10 }
11
12 add_action( 'widgets_init', 'jetpack_contact_info_widget_init' );
13
14 /**
15 * Makes a custom Widget for displaying Restaurant Location/Map, Hours, and Contact Info available.
16 *
17 * @package WordPress
18 */
19 class Jetpack_Contact_Info_Widget extends WP_Widget {
20
21 /**
22 * Constructor
23 */
24 function __construct() {
25 $widget_ops = array(
26 'classname' => 'widget_contact_info',
27 'description' => __( 'Display a map with your location, hours, and contact information.', 'jetpack' ),
28 'customize_selective_refresh' => true,
29 );
30 parent::__construct(
31 'widget_contact_info',
32 /** This filter is documented in modules/widgets/facebook-likebox.php */
33 apply_filters( 'jetpack_widget_name', __( 'Contact Info & Map', 'jetpack' ) ),
34 $widget_ops
35 );
36 $this->alt_option_name = 'widget_contact_info';
37
38 if ( is_customize_preview() ) {
39 add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
40 }
41 }
42
43 /**
44 * Enqueue scripts and styles.
45 */
46 public function enqueue_scripts() {
47 wp_enqueue_style( 'contact-info-map-css', plugins_url( 'contact-info/contact-info-map.css', __FILE__ ), null, 20160623 );
48 }
49
50
51 /**
52 * Return an associative array of default values
53 *
54 * These values are used in new widgets.
55 *
56 * @return array Array of default values for the Widget's options
57 */
58 public function defaults() {
59 return array(
60 'title' => __( 'Hours & Info', 'jetpack' ),
61 'address' => __( "3999 Mission Boulevard,\nSan Diego CA 92109", 'jetpack' ),
62 'phone' => _x( '1-202-555-1212', 'Example of a phone number', 'jetpack' ),
63 'hours' => __( "Lunch: 11am - 2pm \nDinner: M-Th 5pm - 11pm, Fri-Sat:5pm - 1am", 'jetpack' ),
64 'email' => null,
65 'showmap' => 0,
66 'apikey' => null,
67 'lat' => null,
68 'lon' => null,
69 );
70 }
71
72 /**
73 * Outputs the HTML for this widget.
74 *
75 * @param array $args An array of standard parameters for widgets in this theme
76 * @param array $instance An array of settings for this widget instance
77 *
78 * @return void Echoes it's output
79 **/
80 function widget( $args, $instance ) {
81 $instance = wp_parse_args( $instance, $this->defaults() );
82
83 echo $args['before_widget'];
84
85 if ( '' != $instance['title'] ) {
86 echo $args['before_title'] . $instance['title'] . $args['after_title'];
87 }
88
89 /**
90 * Fires at the beginning of the Contact Info widget, after the title.
91 *
92 * @module widgets
93 *
94 * @since 3.9.2
95 */
96 do_action( 'jetpack_contact_info_widget_start' );
97
98 echo '<div itemscope itemtype="http://schema.org/LocalBusiness">';
99
100 if ( '' != $instance['address'] ) {
101
102 $showmap = $instance['showmap'];
103
104 /** This action is documented in modules/widgets/contact-info.php */
105 if ( $showmap && $this->has_good_map( $instance ) ) {
106 /**
107 * Set a Google Maps API Key.
108 *
109 * @since 4.1.0
110 *
111 * @param string $api_key Google Maps API Key
112 */
113 $api_key = apply_filters( 'jetpack_google_maps_api_key', $instance['apikey'] );
114 echo $this->build_map( $instance['address'], $api_key );
115 }
116
117 $map_link = $this->build_map_link( $instance['address'] );
118
119 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>';
120 }
121
122 if ( '' != $instance['phone'] ) {
123 if ( wp_is_mobile() ) {
124 echo '<div class="confit-phone"><span itemprop="telephone"><a href="' . esc_url( 'tel:' . $instance['phone'] ) . '">' . esc_html( $instance['phone'] ) . '</a></span></div>';
125 } else {
126 echo '<div class="confit-phone"><span itemprop="telephone">' . esc_html( $instance['phone'] ) . '</span></div>';
127 }
128 }
129
130 if ( is_email( trim( $instance['email'] ) ) ) {
131 printf(
132 '<div class="confit-email"><a href="mailto:%1$s">%1$s</a></div>',
133 esc_html( $instance['email'] )
134 );
135 }
136
137 if ( '' != $instance['hours'] ) {
138 echo '<div class="confit-hours" itemprop="openingHours">' . str_replace( "\n", '<br/>', esc_html( $instance['hours'] ) ) . '</div>';
139 }
140
141 echo '</div>';
142
143 /**
144 * Fires at the end of Contact Info widget.
145 *
146 * @module widgets
147 *
148 * @since 3.9.2
149 */
150 do_action( 'jetpack_contact_info_widget_end' );
151
152 echo $args['after_widget'];
153
154 /** This action is documented in modules/widgets/gravatar-profile.php */
155 do_action( 'jetpack_stats_extra', 'widget_view', 'contact_info' );
156 }
157
158
159 /**
160 * Deals with the settings when they are saved by the admin. Here is
161 * where any validation should be dealt with.
162 *
163 * @param array $new_instance New configuration values
164 * @param array $old_instance Old configuration values
165 *
166 * @return array
167 */
168 function update( $new_instance, $old_instance ) {
169 $update_lat_lon = false;
170 if (
171 ! isset( $old_instance['address'] ) ||
172 $this->urlencode_address( $old_instance['address'] ) != $this->urlencode_address( $new_instance['address'] )
173 ) {
174 $update_lat_lon = true;
175 }
176
177 $instance = array();
178 $instance['title'] = wp_kses( $new_instance['title'], array() );
179 $instance['address'] = wp_kses( $new_instance['address'], array() );
180 $instance['phone'] = wp_kses( $new_instance['phone'], array() );
181 $instance['email'] = wp_kses( $new_instance['email'], array() );
182 $instance['hours'] = wp_kses( $new_instance['hours'], array() );
183 $instance['apikey'] = wp_kses( isset( $new_instance['apikey'] ) ? $new_instance['apikey'] : $old_instance['apikey'], array() );
184 $instance['lat'] = isset( $old_instance['lat'] ) ? floatval( $old_instance['lat'] ) : 0;
185 $instance['lon'] = isset( $old_instance['lon'] ) ? floatval( $old_instance['lon'] ) : 0;
186
187 if ( ! $instance['lat'] || ! $instance['lon'] ) {
188 $update_lat_lon = true;
189 }
190
191 if ( $instance['address'] && $update_lat_lon ) {
192
193 // Get the lat/lon of the user specified address.
194 $address = $this->urlencode_address( $instance['address'] );
195 $path = 'https://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=' . $address;
196 /** This action is documented in modules/widgets/contact-info.php */
197 $key = apply_filters( 'jetpack_google_maps_api_key', $instance['apikey'] );
198
199 if ( ! empty( $key ) ) {
200 $path = add_query_arg( 'key', $key, $path );
201 }
202 $json = wp_remote_retrieve_body( wp_remote_get( esc_url( $path, null, null ) ) );
203
204 if ( ! $json ) {
205 // The read failed :(
206 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' );
207 die();
208 }
209
210 $json_obj = json_decode( $json );
211
212 if ( 'ZERO_RESULTS' == $json_obj->status ) {
213 // The address supplied does not have a matching lat / lon.
214 // No map is available.
215 $instance['lat'] = '0';
216 $instance['lon'] = '0';
217 } else {
218
219 $loc = $json_obj->results[0]->geometry->location;
220
221 $lat = floatval( $loc->lat );
222 $lon = floatval( $loc->lng );
223
224 $instance['lat'] = "$lat";
225 $instance['lon'] = "$lon";
226 }
227 }
228
229 if ( ! isset( $new_instance['showmap'] ) ) {
230 $instance['showmap'] = 0;
231 } else {
232 $instance['showmap'] = intval( $new_instance['showmap'] );
233 }
234
235 return $instance;
236 }
237
238
239 /**
240 * Displays the form for this widget on the Widgets page of the WP Admin area.
241 *
242 * @param array $instance Instance configuration.
243 *
244 * @return void
245 */
246 function form( $instance ) {
247 $instance = wp_parse_args( $instance, $this->defaults() );
248 wp_enqueue_script(
249 'contact-info-admin',
250 Assets::get_file_url_for_environment(
251 '_inc/build/widgets/contact-info/contact-info-admin.min.js',
252 'modules/widgets/contact-info/contact-info-admin.js'
253 ),
254 array( 'jquery' ),
255 20160727
256 );
257
258 ?>
259 <p>
260 <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_html_e( 'Title:', 'jetpack' ); ?></label>
261 <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'] ); ?>" />
262 </p>
263
264 <p>
265 <label for="<?php echo esc_attr( $this->get_field_id( 'address' ) ); ?>"><?php esc_html_e( 'Address:', 'jetpack' ); ?></label>
266 <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>
267 <?php
268 if ( $this->has_good_map( $instance ) ) {
269 ?>
270 <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 ); ?> />
271 <label for="<?php echo esc_attr( $this->get_field_id( 'showmap' ) ); ?>"><?php esc_html_e( 'Show map', 'jetpack' ); ?></label>
272 <?php
273 } else {
274 ?>
275 <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>
276 <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" />
277 <?php
278 }
279 ?>
280 </p>
281
282 <p class="jp-contact-info-apikey" style="<?php echo $instance['showmap'] ? '' : 'display: none;'; ?>">
283 <label for="<?php echo esc_attr( $this->get_field_id( 'apikey' ) ); ?>">
284 <?php _e( 'Google Maps API Key', 'jetpack' ); ?>
285 <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'] ); ?>" />
286 <br />
287 <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>
288 </label>
289 </p>
290
291 <p>
292 <label for="<?php echo esc_attr( $this->get_field_id( 'phone' ) ); ?>"><?php esc_html_e( 'Phone:', 'jetpack' ); ?></label>
293 <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'] ); ?>" />
294 </p>
295
296 <p>
297 <label for="<?php echo esc_attr( $this->get_field_id( 'email' ) ); ?>"><?php esc_html_e( 'Email Address:', 'jetpack' ); ?></label>
298 <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'] ); ?>" />
299 </p>
300
301 <p>
302 <label for="<?php echo esc_attr( $this->get_field_id( 'hours' ) ); ?>"><?php esc_html_e( 'Hours:', 'jetpack' ); ?></label>
303 <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>
304 </p>
305
306 <?php
307 }
308
309
310 /**
311 * Generate a Google Maps link for the supplied address.
312 *
313 * @param string $address Address to link to.
314 *
315 * @return string
316 */
317 function build_map_link( $address ) {
318 // Google map urls have lots of available params but zoom (z) and query (q) are enough.
319 return 'https://maps.google.com/maps?z=16&q=' . $this->urlencode_address( $address );
320 }
321
322
323 /**
324 * Builds map display HTML code from the supplied latitude and longitude.
325 *
326 * @param string $address Address.
327 * @param string $api_key API Key.
328 *
329 * @return string HTML of the map.
330 */
331 function build_map( $address, $api_key = null ) {
332 $this->enqueue_scripts();
333 $src = add_query_arg( 'q', rawurlencode( $address ), 'https://www.google.com/maps/embed/v1/place' );
334 if ( ! empty( $api_key ) ) {
335 $src = add_query_arg( 'key', $api_key, $src );
336 }
337
338 $height = 216;
339
340 $iframe_attributes = sprintf(
341 ' height="%d" frameborder="0" src="%s" class="contact-map"',
342 esc_attr( $height ),
343 esc_url( $src )
344 );
345
346 $iframe_html = sprintf( '<iframe width="600" %s></iframe>', $iframe_attributes );
347
348 if (
349 ! class_exists( 'Jetpack_AMP_Support' )
350 || ! Jetpack_AMP_Support::is_amp_request()
351 ) {
352 return $iframe_html;
353 }
354
355 $amp_iframe_html = sprintf( '<amp-iframe layout="fixed-height" width="auto" sandbox="allow-scripts allow-same-origin" %s>', $iframe_attributes );
356
357 // Add placeholder to avoid AMP error: <amp-iframe> elements must be positioned outside the first 75% of the viewport or 600px from the top (whichever is smaller).
358 $amp_iframe_html .= sprintf( '<span placeholder>%s</span>', esc_html__( 'Loading map&hellip;', 'jetpack' ) );
359
360 // Add original iframe as fallback in case JavaScript is disabled.
361 $amp_iframe_html .= sprintf( '<noscript>%s</noscript>', $iframe_html );
362
363 $amp_iframe_html .= '</amp-iframe>';
364 return $amp_iframe_html;
365 }
366
367 /**
368 * Encode an URL
369 *
370 * @param string $address The URL to encode
371 *
372 * @return string The encoded URL
373 */
374 function urlencode_address( $address ) {
375
376 $address = strtolower( $address );
377 $address = preg_replace( '/\s+/', ' ', trim( $address ) ); // Get rid of any unwanted whitespace
378 $address = str_ireplace( ' ', '+', $address ); // Use + not %20
379 return urlencode( $address );
380 }
381
382 /**
383 * Check if the instance has a valid Map location.
384 *
385 * @param array $instance Widget instance configuration.
386 *
387 * @return bool Whether or not there is a valid map.
388 */
389 function has_good_map( $instance ) {
390 // The lat and lon of an address that could not be plotted will have values of 0 and 0.
391 return ! ( '0' == $instance['lat'] && '0' == $instance['lon'] );
392 }
393
394 }
395
396 }
397