PluginProbe ʕ •ᴥ•ʔ
Secure Custom Fields / 6.9.1
Secure Custom Fields v6.9.1
6.9.1 6.9.0 6.8.9 6.8.7 6.8.8 6.8.6 6.8.4 6.8.5 trunk 6.4.0-beta1 6.4.0-beta2 6.4.1 6.4.1-beta3 6.4.1-beta4 6.4.1-beta5 6.4.1-beta6 6.4.1-beta7 6.4.2 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 6.5.5 6.5.6 6.5.7 6.6.0 6.7.0 6.7.1 6.8.0 6.8.1 6.8.2 6.8.3
secure-custom-fields / includes / fields / class-acf-field-google-map.php
secure-custom-fields / includes / fields Last commit date
FlexibleContent 2 months ago class-acf-field-accordion.php 2 months ago class-acf-field-button-group.php 2 months ago class-acf-field-checkbox.php 2 days ago class-acf-field-clone.php 2 months ago class-acf-field-color_picker.php 2 months ago class-acf-field-date_picker.php 2 months ago class-acf-field-date_time_picker.php 2 months ago class-acf-field-email.php 2 months ago class-acf-field-file.php 2 months ago class-acf-field-flexible-content.php 1 week ago class-acf-field-gallery.php 3 weeks ago class-acf-field-google-map.php 2 months ago class-acf-field-group.php 2 months ago class-acf-field-icon_picker.php 7 months ago class-acf-field-image.php 2 months ago class-acf-field-link.php 2 months ago class-acf-field-message.php 1 year ago class-acf-field-nav-menu.php 1 week ago class-acf-field-number.php 2 months ago class-acf-field-oembed.php 3 weeks ago class-acf-field-output.php 1 year ago class-acf-field-page_link.php 3 weeks ago class-acf-field-password.php 2 months ago class-acf-field-post_object.php 3 weeks ago class-acf-field-radio.php 2 days ago class-acf-field-range.php 2 months ago class-acf-field-relationship.php 3 weeks ago class-acf-field-repeater.php 3 weeks ago class-acf-field-select.php 2 days ago class-acf-field-separator.php 1 year ago class-acf-field-tab.php 1 year ago class-acf-field-taxonomy.php 3 weeks ago class-acf-field-text.php 3 weeks ago class-acf-field-textarea.php 3 weeks ago class-acf-field-time_picker.php 2 months ago class-acf-field-true_false.php 2 months ago class-acf-field-url.php 3 weeks ago class-acf-field-user.php 3 weeks ago class-acf-field-wysiwyg.php 2 months ago class-acf-field.php 2 months ago class-acf-repeater-table.php 1 year ago index.php 1 year ago
class-acf-field-google-map.php
539 lines
1 <?php
2
3 if ( ! class_exists( 'acf_field_google_map' ) ) :
4 class acf_field_google_map extends acf_field {
5
6 /**
7 * Default values.
8 *
9 * @var string $default_values
10 */
11 public $default_values = array();
12
13 /**
14 * This function will setup the field type data
15 *
16 * @type function
17 * @date 5/03/2014
18 * @since ACF 5.0.0
19 *
20 * @param n/a
21 * @return n/a
22 */
23 function initialize() {
24
25 // vars
26 $this->name = 'google_map';
27 $this->label = __( 'Google Map', 'secure-custom-fields' );
28 $this->category = 'advanced';
29 $this->description = __( 'An interactive UI for selecting a location using Google Maps. Requires a Google Maps API key and additional configuration to display correctly.', 'secure-custom-fields' );
30 $this->preview_image = acf_get_url() . '/assets/images/field-type-previews/field-preview-google-map.png';
31 $this->doc_url = 'https://developer.wordpress.org/secure-custom-fields/features/fields/google-map/';
32 $this->tutorial_url = 'https://developer.wordpress.org/secure-custom-fields/features/fields/google-map/google-map-tutorial/';
33 $this->defaults = array(
34 'height' => '',
35 'center_lat' => '',
36 'center_lng' => '',
37 'zoom' => '',
38 );
39 $this->default_values = array(
40 'height' => '400',
41 'center_lat' => '-37.81411',
42 'center_lng' => '144.96328',
43 'zoom' => '14',
44 );
45 }
46
47
48 /**
49 * description
50 *
51 * @type function
52 * @date 16/12/2015
53 * @since ACF 5.3.2
54 *
55 * @param $post_id (int)
56 * @return $post_id (int)
57 */
58 function input_admin_enqueue_scripts() {
59
60 // localize
61 acf_localize_text(
62 array(
63 'Sorry, this browser does not support geolocation' => __( 'Sorry, this browser does not support geolocation', 'secure-custom-fields' ),
64 )
65 );
66
67 // bail early if no enqueue
68 if ( ! acf_get_setting( 'enqueue_google_maps' ) ) {
69 return;
70 }
71
72 // vars
73 $api = array(
74 'key' => acf_get_setting( 'google_api_key' ),
75 'client' => acf_get_setting( 'google_api_client' ),
76 'libraries' => 'places',
77 'ver' => 3,
78 'callback' => 'Function.prototype',
79 'language' => acf_get_locale(),
80 );
81
82 // filter
83 $api = apply_filters( 'acf/fields/google_map/api', $api );
84
85 // remove empty
86 if ( empty( $api['key'] ) ) {
87 unset( $api['key'] );
88 }
89 if ( empty( $api['client'] ) ) {
90 unset( $api['client'] );
91 }
92
93 // construct url
94 $url = add_query_arg( $api, 'https://maps.googleapis.com/maps/api/js' );
95
96 // localize
97 acf_localize_data(
98 array(
99 'google_map_api' => $url,
100 )
101 );
102 }
103
104
105 /**
106 * Create the HTML interface for your field
107 *
108 * @param $field - an array holding all the field's data
109 *
110 * @type action
111 * @since ACF 3.6
112 * @date 23/01/13
113 */
114 function render_field( $field ) {
115
116 // Apply defaults.
117 foreach ( $this->default_values as $k => $v ) {
118 if ( ! $field[ $k ] ) {
119 $field[ $k ] = $v;
120 }
121 }
122
123 // Attrs.
124 $attrs = array(
125 'id' => $field['id'],
126 'class' => "acf-google-map {$field['class']}",
127 'data-lat' => $field['center_lat'],
128 'data-lng' => $field['center_lng'],
129 'data-zoom' => $field['zoom'],
130 );
131
132 $search = '';
133 if ( $field['value'] ) {
134 $attrs['class'] .= ' -value';
135 $search = $field['value']['address'];
136 } else {
137 $field['value'] = '';
138 }
139
140 ?>
141 <div <?php echo acf_esc_attrs( $attrs ); ?>>
142
143 <?php
144 acf_hidden_input(
145 array(
146 'name' => $field['name'],
147 'value' => $field['value'],
148 )
149 );
150 ?>
151
152 <div class="title">
153
154 <input class="search" type="text" placeholder="<?php esc_attr_e( 'Search for address...', 'secure-custom-fields' ); ?>" value="<?php echo esc_attr( $search ); ?>" />
155
156 <div class="acf-actions -hover">
157 <button type="button" data-name="search" class="acf-icon -search grey" aria-label="<?php esc_attr_e( 'Search', 'secure-custom-fields' ); ?>"></button>
158 <button type="button" data-name="clear" class="acf-icon -cancel grey" aria-label="<?php esc_attr_e( 'Clear location', 'secure-custom-fields' ); ?>"></button>
159 <button type="button" data-name="locate" class="acf-icon -location grey" aria-label="<?php esc_attr_e( 'Find current location', 'secure-custom-fields' ); ?>"></button>
160 </div>
161
162 <i class="acf-loading"></i>
163
164 </div>
165
166 <div class="canvas" style="<?php echo esc_attr( 'height: ' . $field['height'] . 'px' ); ?>"></div>
167
168 </div>
169 <?php
170 }
171
172
173 /**
174 * Create extra options for your field. This is rendered when editing a field.
175 * The value of $field['name'] can be used (like bellow) to save extra data to the $field
176 *
177 * @type action
178 * @since ACF 3.6
179 * @date 23/01/13
180 *
181 * @param $field - an array holding all the field's data
182 */
183 function render_field_settings( $field ) {
184
185 // center_lat
186 acf_render_field_setting(
187 $field,
188 array(
189 'label' => __( 'Center', 'secure-custom-fields' ),
190 'hint' => __( 'Center the initial map', 'secure-custom-fields' ),
191 'type' => 'text',
192 'name' => 'center_lat',
193 'prepend' => 'lat',
194 'placeholder' => $this->default_values['center_lat'],
195 )
196 );
197
198 // center_lng
199 acf_render_field_setting(
200 $field,
201 array(
202 'label' => __( 'Center', 'secure-custom-fields' ),
203 'hint' => __( 'Center the initial map', 'secure-custom-fields' ),
204 'type' => 'text',
205 'name' => 'center_lng',
206 'prepend' => 'lng',
207 'placeholder' => $this->default_values['center_lng'],
208 '_append' => 'center_lat',
209 )
210 );
211
212 // zoom
213 acf_render_field_setting(
214 $field,
215 array(
216 'label' => __( 'Zoom', 'secure-custom-fields' ),
217 'instructions' => __( 'Set the initial zoom level', 'secure-custom-fields' ),
218 'type' => 'text',
219 'name' => 'zoom',
220 'placeholder' => $this->default_values['zoom'],
221 )
222 );
223
224 // allow_null
225 acf_render_field_setting(
226 $field,
227 array(
228 'label' => __( 'Height', 'secure-custom-fields' ),
229 'instructions' => __( 'Customize the map height', 'secure-custom-fields' ),
230 'type' => 'text',
231 'name' => 'height',
232 'append' => 'px',
233 'placeholder' => $this->default_values['height'],
234 )
235 );
236 }
237
238 /**
239 * load_value
240 *
241 * Filters the value loaded from the database.
242 *
243 * @date 16/10/19
244 * @since ACF 5.8.1
245 *
246 * @param mixed $value The value loaded from the database.
247 * @param mixed $post_id The post ID where the value is saved.
248 * @param array $field The field settings array.
249 * @return (array|false)
250 */
251 function load_value( $value, $post_id, $field ) {
252
253 // Ensure value is an array.
254 if ( $value ) {
255 return wp_parse_args(
256 $value,
257 array(
258 'address' => '',
259 'lat' => 0,
260 'lng' => 0,
261 )
262 );
263 }
264
265 // Return default.
266 return false;
267 }
268
269
270 /**
271 * This filter is applied to the $value before it is updated in the db
272 *
273 * @type filter
274 * @since ACF 3.6
275 * @date 23/01/13
276 *
277 * @param $value - the value which will be saved in the database
278 * @param $post_id - the post_id of which the value will be saved
279 * @param $field - the field array holding all the field options
280 *
281 * @return $value - the modified value
282 */
283 function update_value( $value, $post_id, $field ) {
284
285 // decode JSON string.
286 if ( is_string( $value ) ) {
287 $value = json_decode( wp_unslash( $value ), true );
288 }
289
290 // Ensure value is an array.
291 if ( $value ) {
292 return (array) $value;
293 }
294
295 // Return default.
296 return false;
297 }
298
299 /**
300 * Return the schema array for the REST API.
301 *
302 * @param array $field
303 * @return array
304 */
305 public function get_rest_schema( array $field ) {
306 return array(
307 'type' => array( 'object', 'null' ),
308 'required' => ! empty( $field['required'] ),
309 'properties' => array(
310 'address' => array(
311 'type' => 'string',
312 ),
313 'lat' => array(
314 'type' => array( 'string', 'float' ),
315 ),
316 'lng' => array(
317 'type' => array( 'string', 'float' ),
318 ),
319 'zoom' => array(
320 'type' => array( 'string', 'int' ),
321 ),
322 'place_id' => array(
323 'type' => 'string',
324 ),
325 'name' => array(
326 'type' => 'string',
327 ),
328 'street_number' => array(
329 'type' => array( 'string', 'int' ),
330 ),
331 'street_name' => array(
332 'type' => 'string',
333 ),
334 'street_name_short' => array(
335 'type' => 'string',
336 ),
337 'city' => array(
338 'type' => 'string',
339 ),
340 'state' => array(
341 'type' => 'string',
342 ),
343 'state_short' => array(
344 'type' => 'string',
345 ),
346 'post_code' => array(
347 'type' => array( 'string', 'int' ),
348 ),
349 'country' => array(
350 'type' => 'string',
351 ),
352 'country_short' => array(
353 'type' => 'string',
354 ),
355 ),
356 );
357 }
358
359 /**
360 * Apply basic formatting to prepare the value for default REST output.
361 *
362 * @param mixed $value
363 * @param string|integer $post_id
364 * @param array $field
365 * @return mixed
366 */
367 public function format_value_for_rest( $value, $post_id, array $field ) {
368 if ( ! $value ) {
369 return null;
370 }
371
372 return acf_format_numerics( $value );
373 }
374
375 /**
376 * Returns an array of JSON-LD Property output types that are supported by this field type.
377 *
378 * @since 6.8
379 *
380 * @return string[]
381 */
382 public function get_jsonld_output_types(): array {
383 return array( 'Place', 'GeoCoordinates', 'PostalAddress' );
384 }
385
386 /**
387 * Formats the field value for JSON-LD output.
388 *
389 * @since 6.8.0
390 *
391 * @param mixed $value The value of the field.
392 * @param integer|string $post_id The ID of the post.
393 * @param array $field The field array.
394 * @return mixed
395 */
396 public function format_value_for_jsonld( $value, $post_id, $field ) {
397 if ( empty( $value ) || ! is_array( $value ) ) {
398 return null;
399 }
400
401 // Get output format with fallback.
402 $output_format = $field['schema_output_format'] ?? '';
403 if ( empty( $output_format ) ) {
404 $property = $field['schema_property'] ?? '';
405 $output_format = \SCF\AI\GEO\Schema::get_default_output_format( $this->name, $property );
406 }
407
408 // Default to Place if no format determined.
409 if ( empty( $output_format ) ) {
410 $output_format = 'Place';
411 }
412
413 switch ( $output_format ) {
414 case 'GeoCoordinates':
415 return $this->format_geo_coordinates( $value );
416
417 case 'PostalAddress':
418 return $this->format_postal_address( $value );
419
420 case 'Place':
421 default:
422 return $this->format_place( $value );
423 }
424 }
425
426 /**
427 * Format value as GeoCoordinates.
428 *
429 * @since 6.8.0
430 *
431 * @param array $value The google map value array.
432 * @return array|null
433 */
434 private function format_geo_coordinates( $value ) {
435 if ( empty( $value['lat'] ) || empty( $value['lng'] ) ) {
436 return null;
437 }
438
439 return array(
440 '@type' => 'GeoCoordinates',
441 'latitude' => (float) $value['lat'],
442 'longitude' => (float) $value['lng'],
443 );
444 }
445
446 /**
447 * Format value as PostalAddress.
448 *
449 * @since 6.8.0
450 *
451 * @param array $value The google map value array.
452 * @return array|null
453 */
454 private function format_postal_address( $value ) {
455 $address = array(
456 '@type' => 'PostalAddress',
457 );
458
459 // Build street address from components.
460 $street_parts = array();
461 if ( ! empty( $value['street_number'] ) ) {
462 $street_parts[] = $value['street_number'];
463 }
464 if ( ! empty( $value['street_name'] ) ) {
465 $street_parts[] = $value['street_name'];
466 }
467 if ( ! empty( $street_parts ) ) {
468 $address['streetAddress'] = implode( ' ', $street_parts );
469 }
470
471 if ( ! empty( $value['city'] ) ) {
472 $address['addressLocality'] = $value['city'];
473 }
474
475 if ( ! empty( $value['state'] ) ) {
476 $address['addressRegion'] = $value['state'];
477 }
478
479 if ( ! empty( $value['post_code'] ) ) {
480 $address['postalCode'] = (string) $value['post_code'];
481 }
482
483 if ( ! empty( $value['country'] ) ) {
484 $address['addressCountry'] = $value['country'];
485 }
486
487 // Only return if we have at least one address property beyond @type.
488 if ( count( $address ) > 1 ) {
489 return $address;
490 }
491
492 return null;
493 }
494
495 /**
496 * Format value as Place.
497 *
498 * @since 6.8.0
499 *
500 * @param array $value The google map value array.
501 * @return array|null
502 */
503 private function format_place( $value ) {
504 $place = array(
505 '@type' => 'Place',
506 );
507
508 // Add name if available.
509 if ( ! empty( $value['name'] ) ) {
510 $place['name'] = $value['name'];
511 }
512
513 // Add full address as formatted string.
514 if ( ! empty( $value['address'] ) ) {
515 $place['address'] = $value['address'];
516 }
517
518 // Add geo coordinates.
519 $geo = $this->format_geo_coordinates( $value );
520 if ( $geo ) {
521 $place['geo'] = $geo;
522 }
523
524 // Only return if we have meaningful data beyond @type.
525 if ( count( $place ) > 1 ) {
526 return $place;
527 }
528
529 return null;
530 }
531 }
532
533
534 // initialize
535 acf_register_field_type( 'acf_field_google_map' );
536 endif; // class_exists check
537
538 ?>
539