PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 7.2.2
Jetpack – WP Security, Backup, Speed, & Growth v7.2.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.2.2, at modules/widgets/contact-info.php

392 lines 14.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 $instance = wp_parse_args( $instance, $this->defaults() );
80
81 echo $args['before_widget'];
82
83 if ( '' != $instance['title'] ) {
84 echo $args['before_title'] . $instance['title'] . $args['after_title'];
85 }
86
87 /**
88 * Fires at the beginning of the Contact Info widget, after the title.
89 *
90 * @module widgets
91 *
92 * @since 3.9.2
93 */
94 do_action( 'jetpack_contact_info_widget_start' );
95
96 echo '<div itemscope itemtype="http://schema.org/LocalBusiness">';
97
98 if ( '' != $instance['address'] ) {
99
100 $showmap = $instance['showmap'];
101
102 /** This action is documented in modules/widgets/contact-info.php */
103 if ( $showmap && $this->has_good_map( $instance ) ) {
104 /**
105 * Set a Google Maps API Key.
106 *
107 * @since 4.1.0
108 *
109 * @param string $api_key Google Maps API Key
110 */
111 $api_key = apply_filters( 'jetpack_google_maps_api_key', $instance['apikey'] );
112 echo $this->build_map( $instance['address'], $api_key );
113 }
114
115 $map_link = $this->build_map_link( $instance['address'] );
116
117 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>';
118 }
119
120 if ( '' != $instance['phone'] ) {
121 if ( wp_is_mobile() ) {
122 echo '<div class="confit-phone"><span itemprop="telephone"><a href="' . esc_url( 'tel:' . $instance['phone'] ) . '">' . esc_html( $instance['phone'] ) . '</a></span></div>';
123 } else {
124 echo '<div class="confit-phone"><span itemprop="telephone">' . esc_html( $instance['phone'] ) . '</span></div>';
125 }
126 }
127
128 if ( is_email( trim( $instance['email'] ) ) ) {
129 printf(
130 '<div class="confit-email"><a href="mailto:%1$s">%1$s</a></div>',
131 esc_html( $instance['email'] )
132 );
133 }
134
135 if ( '' != $instance['hours'] ) {
136 echo '<div class="confit-hours" itemprop="openingHours">' . str_replace( "\n", '<br/>', esc_html( $instance['hours'] ) ) . '</div>';
137 }
138
139 echo '</div>';
140
141 /**
142 * Fires at the end of Contact Info widget.
143 *
144 * @module widgets
145 *
146 * @since 3.9.2
147 */
148 do_action( 'jetpack_contact_info_widget_end' );
149
150 echo $args['after_widget'];
151
152 /** This action is documented in modules/widgets/gravatar-profile.php */
153 do_action( 'jetpack_stats_extra', 'widget_view', 'contact_info' );
154 }
155
156
157 /**
158 * Deals with the settings when they are saved by the admin. Here is
159 * where any validation should be dealt with.
160 *
161 * @param array $new_instance New configuration values
162 * @param array $old_instance Old configuration values
163 *
164 * @return array
165 */
166 function update( $new_instance, $old_instance ) {
167 $update_lat_lon = false;
168 if (
169 ! isset( $old_instance['address'] ) ||
170 $this->urlencode_address( $old_instance['address'] ) != $this->urlencode_address( $new_instance['address'] )
171 ) {
172 $update_lat_lon = true;
173 }
174
175 $instance = array();
176 $instance['title'] = wp_kses( $new_instance['title'], array() );
177 $instance['address'] = wp_kses( $new_instance['address'], array() );
178 $instance['phone'] = wp_kses( $new_instance['phone'], array() );
179 $instance['email'] = wp_kses( $new_instance['email'], array() );
180 $instance['hours'] = wp_kses( $new_instance['hours'], array() );
181 $instance['apikey'] = wp_kses( isset( $new_instance['apikey'] ) ? $new_instance['apikey'] : $old_instance['apikey'], array() );
182 $instance['lat'] = isset( $old_instance['lat'] ) ? floatval( $old_instance['lat'] ) : 0;
183 $instance['lon'] = isset( $old_instance['lon'] ) ? floatval( $old_instance['lon'] ) : 0;
184
185 if ( ! $instance['lat'] || ! $instance['lon'] ) {
186 $update_lat_lon = true;
187 }
188
189 if ( $instance['address'] && $update_lat_lon ) {
190
191 // Get the lat/lon of the user specified address.
192 $address = $this->urlencode_address( $instance['address'] );
193 $path = 'https://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=' . $address;
194 /** This action is documented in modules/widgets/contact-info.php */
195 $key = apply_filters( 'jetpack_google_maps_api_key', $instance['apikey'] );
196
197 if ( ! empty( $key ) ) {
198 $path = add_query_arg( 'key', $key, $path );
199 }
200 $json = wp_remote_retrieve_body( wp_remote_get( esc_url( $path, null, null ) ) );
201
202 if ( ! $json ) {
203 // The read failed :(
204 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' );
205 die();
206 }
207
208 $json_obj = json_decode( $json );
209
210 if ( 'ZERO_RESULTS' == $json_obj->status ) {
211 // The address supplied does not have a matching lat / lon.
212 // No map is available.
213 $instance['lat'] = '0';
214 $instance['lon'] = '0';
215 } else {
216
217 $loc = $json_obj->results[0]->geometry->location;
218
219 $lat = floatval( $loc->lat );
220 $lon = floatval( $loc->lng );
221
222 $instance['lat'] = "$lat";
223 $instance['lon'] = "$lon";
224 }
225 }
226
227 if ( ! isset( $new_instance['showmap'] ) ) {
228 $instance['showmap'] = 0;
229 } else {
230 $instance['showmap'] = intval( $new_instance['showmap'] );
231 }
232
233 return $instance;
234 }
235
236
237 /**
238 * Displays the form for this widget on the Widgets page of the WP Admin area.
239 *
240 * @param array $instance Instance configuration.
241 *
242 * @return void
243 */
244 function form( $instance ) {
245 $instance = wp_parse_args( $instance, $this->defaults() );
246 wp_enqueue_script(
247 'contact-info-admin',
248 Jetpack::get_file_url_for_environment(
249 '_inc/build/widgets/contact-info/contact-info-admin.min.js',
250 'modules/widgets/contact-info/contact-info-admin.js'
251 ),
252 array( 'jquery' ),
253 20160727
254 );
255
256 ?>
257 <p>
258 <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_html_e( 'Title:', 'jetpack' ); ?></label>
259 <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'] ); ?>" />
260 </p>
261
262 <p>
263 <label for="<?php echo esc_attr( $this->get_field_id( 'address' ) ); ?>"><?php esc_html_e( 'Address:', 'jetpack' ); ?></label>
264 <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>
265 <?php
266 if ( $this->has_good_map( $instance ) ) {
267 ?>
268 <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 ); ?> />
269 <label for="<?php echo esc_attr( $this->get_field_id( 'showmap' ) ); ?>"><?php esc_html_e( 'Show map', 'jetpack' ); ?></label>
270 <?php
271 } else {
272 ?>
273 <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>
274 <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" />
275 <?php
276 }
277 ?>
278 </p>
279
280 <p class="jp-contact-info-apikey" style="<?php echo $instance['showmap'] ? '' : 'display: none;'; ?>">
281 <label for="<?php echo esc_attr( $this->get_field_id( 'apikey' ) ); ?>">
282 <?php _e( 'Google Maps API Key', 'jetpack' ); ?>
283 <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'] ); ?>" />
284 <br />
285 <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>
286 </label>
287 </p>
288
289 <p>
290 <label for="<?php echo esc_attr( $this->get_field_id( 'phone' ) ); ?>"><?php esc_html_e( 'Phone:', 'jetpack' ); ?></label>
291 <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'] ); ?>" />
292 </p>
293
294 <p>
295 <label for="<?php echo esc_attr( $this->get_field_id( 'email' ) ); ?>"><?php esc_html_e( 'Email Address:', 'jetpack' ); ?></label>
296 <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'] ); ?>" />
297 </p>
298
299 <p>
300 <label for="<?php echo esc_attr( $this->get_field_id( 'hours' ) ); ?>"><?php esc_html_e( 'Hours:', 'jetpack' ); ?></label>
301 <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>
302 </p>
303
304 <?php
305 }
306
307
308 /**
309 * Generate a Google Maps link for the supplied address.
310 *
311 * @param string $address Address to link to.
312 *
313 * @return string
314 */
315 function build_map_link( $address ) {
316 // Google map urls have lots of available params but zoom (z) and query (q) are enough.
317 return 'https://maps.google.com/maps?z=16&q=' . $this->urlencode_address( $address );
318 }
319
320
321 /**
322 * Builds map display HTML code from the supplied latitude and longitude.
323 *
324 * @param string $address Address.
325 * @param string $api_key API Key.
326 *
327 * @return string HTML of the map.
328 */
329 function build_map( $address, $api_key = null ) {
330 $this->enqueue_scripts();
331 $src = add_query_arg( 'q', rawurlencode( $address ), 'https://www.google.com/maps/embed/v1/place' );
332 if ( ! empty( $api_key ) ) {
333 $src = add_query_arg( 'key', $api_key, $src );
334 }
335
336 $height = 216;
337
338 $iframe_attributes = sprintf(
339 ' height="%d" frameborder="0" src="%s" class="contact-map"',
340 esc_attr( $height ),
341 esc_url( $src )
342 );
343
344 $iframe_html = sprintf( '<iframe width="600" %s></iframe>', $iframe_attributes );
345
346 if ( ! Jetpack_AMP_Support::is_amp_request() ) {
347 return $iframe_html;
348 }
349
350 $amp_iframe_html = sprintf( '<amp-iframe layout="fixed-height" width="auto" sandbox="allow-scripts allow-same-origin" %s>', $iframe_attributes );
351
352 // 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).
353 $amp_iframe_html .= sprintf( '<span placeholder>%s</span>', esc_html__( 'Loading map&hellip;', 'jetpack' ) );
354
355 // Add original iframe as fallback in case JavaScript is disabled.
356 $amp_iframe_html .= sprintf( '<noscript>%s</noscript>', $iframe_html );
357
358 $amp_iframe_html .= '</amp-iframe>';
359 return $amp_iframe_html;
360 }
361
362 /**
363 * Encode an URL
364 *
365 * @param string $address The URL to encode
366 *
367 * @return string The encoded URL
368 */
369 function urlencode_address( $address ) {
370
371 $address = strtolower( $address );
372 $address = preg_replace( '/\s+/', ' ', trim( $address ) ); // Get rid of any unwanted whitespace
373 $address = str_ireplace( ' ', '+', $address ); // Use + not %20
374 return urlencode( $address );
375 }
376
377 /**
378 * Check if the instance has a valid Map location.
379 *
380 * @param array $instance Widget instance configuration.
381 *
382 * @return bool Whether or not there is a valid map.
383 */
384 function has_good_map( $instance ) {
385 // The lat and lon of an address that could not be plotted will have values of 0 and 0.
386 return ! ( '0' == $instance['lat'] && '0' == $instance['lon'] );
387 }
388
389 }
390
391 }
392