Headline
CVE-2023-4887: index.php in intergeo-maps/tags/2.3.2 – WordPress Plugin Repository
The Google Maps Plugin by Intergeo for WordPress plugin for WordPress is vulnerable to Stored Cross-Site Scripting via ‘intergeo’ shortcode in versions up to, and including, 2.3.2 due to insufficient input sanitization and output escaping on user supplied attributes. This makes it possible for authenticated attackers with contributor-level and above permissions to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
1<?php2/**3 *4 * Plugin Name: Intergeo - Google Maps Plugin5 * Plugin URI: http://themeisle.com/plugins/intergeo-maps-lite/6 * Description: A simple, easy and quite powerful Google Map tool to create, manage and embed custom Google Maps into your WordPress posts and pages. The plugin allows you to deeply customize look and feel of a map, add overlays like markers, rectangles, circles, polylines and polygons to your map. It could even be integraded with your Google Adsense account and show ad on your maps.7 * Version: 2.3.28 * Author: Themeisle9 * Author URI: http://themeisle.com10 * License: GPL v2.0 or later11 * License URI: http://www.opensource.org/licenses/gpl-license.php12 * Text Domain: intergeo-maps13 * Domain Path: /languages14 * Requires License: no15 * WordPress Available: yes16 */1718define( 'INTERGEO_PLUGIN_NAME’, ‘intergeo’ );19define( 'TI_INTERGEO_PLUGIN_NAME’, ‘intergeo_maps’ );20define( 'INTERGEO_VERSION’, ‘2.3.2’ );21define( 'INTERGEO_ABSPATH’, dirname( __FILE__ ) );22define( 'INTERGEO_ABSURL’, plugins_url( '/’, __FILE__ ) );23defined( ‘WPLANG’ ) || define( 'WPLANG’, ‘’ );24define( 'INTERGEO_DIR’, trailingslashit( plugin_dir_path( __FILE__ ) ) );25define( 'INTERGEO_DIRNAME’, dirname( plugin_basename( __FILE__ ) ) );26define( 'INTERGEO_DEBUG’, false );2728add_filter( 'themeisle_sdk_products’, 'intergeo_register_sdk’, 10, 1 );29/**30 * Add intergeo in sdk.31 *32 * @param array $products Array of products.33 *34 * @return array Products array.35 */36function intergeo_register_sdk( $products ) {37 $products[] = __FILE__;3839 return $products;40}4142if ( ! defined( ‘INTERGEO_PRO_URL’ ) ) {43 define( 'INTERGEO_PRO_URL’, ‘http://themeisle.com/plugins/intergeo-maps/’ );44}4546add_filter( 'plugin_action_links’, 'intergeo_action_links’, 10, 2 );47/**48 * Render plugin actions links.49 *50 * @param array $links Array of actual links.51 * @param string $file Plugin file.52 *53 * @return mixed Plugin table links.54 */55function intergeo_action_links( $links, $file ) {56 if ( $file == plugin_basename( __FILE__ ) ) {57 array_unshift(58 $links,59 sprintf( '<a href="%s">%s</a>’, add_query_arg( 'page’, INTERGEO_PLUGIN_NAME, admin_url( ‘upload.php’ ) ), __( 'Maps’, ‘intergeo-maps’ ) ),60 sprintf( '<a href="%s">%s</a>’, intergeo_settings_url(), __( 'Settings’, ‘intergeo-maps’ ) )61 );62 }6364 return $links;65}6667add_action( 'admin_init’, ‘intergeo_admin_init’ );68/**69 * Init plugin logic.70 */71function intergeo_admin_init() {72 load_plugin_textdomain( INTERGEO_PLUGIN_NAME, false, dirname( plugin_basename( __FILE__ ) ) . ‘/languages/’ );73 register_post_type( INTERGEO_PLUGIN_NAME );74}7576add_action( 'wp_enqueue_scripts’, ‘intergeo_frontend_enqueue_scripts’ );77/**78 * Load frontend assets.79 */80function intergeo_frontend_enqueue_scripts() {81 wp_register_style( 'intergeo-frontend’, INTERGEO_ABSURL . 'css/frontend.css’, array(), INTERGEO_VERSION );82}8384add_action( 'plugins_loaded’, ‘intergeo_i18n’ );85/**86 * Load locales.87 */88function intergeo_i18n() {89 $pluginDirName = dirname( plugin_basename( __FILE__ ) );90 $domain = INTERGEO_PLUGIN_NAME;91 $locale = apply_filters( 'plugin_locale’, get_locale(), $domain );92 load_textdomain( $domain, WP_LANG_DIR . ‘/’ . $pluginDirName . ‘/’ . $domain . '-' . $locale . ‘.mo’ );93 load_plugin_textdomain( $domain, '’, $pluginDirName . ‘/languages/’ );94}9596/**97 * Init settings field.98 */99function intergeo_settings() {100 if ( isset( $_POST[‘sb-intergeo’] ) && wp_verify_nonce( $_POST[‘intergeo-nonce’], ‘intergeo-settings’ ) ) {101 update_option( 'intergeo_map_api_key’, sanitize_text_field( $_POST[‘intergeo_map_api_key’] ) );102 if ( intergeo_is_developer() ) {103 update_option( 'intergeo_adsense_publisher_id’, sanitize_text_field( $_POST[‘intergeo_adsense_publisher_id’] ) );104 }105 }106 echo ‘<div class="wrap">107 <h2>108 <div id="intergeo_lbrr_ttl">Inter<span style="color:#4067dc">g</span><span style="color:#e21b31">e</span><span style="color:#fcaa08">o</span>’ . __( 'Maps Settings’, ‘intergeo-maps’ ) . '</div> ';109 echo ‘<a href="’ . admin_url( ‘upload.php?page=’ . INTERGEO_PLUGIN_NAME ) . ‘" class="add-new-h2">’ . __( 'Create New Map’, ‘intergeo-maps’ ) . '</a>’;110111 echo ‘<a id="intergeo_lbrr_settings" href="’ . admin_url( ‘upload.php?page=’ . INTERGEO_PLUGIN_NAME ) . ‘" class="add-new-h2">’ . __( 'View Existing Maps’, ‘intergeo-maps’ ) . '</a>112 </h2>’;113 echo '<div class="intergeo_settings">’;114 echo '<div id="intergeo_sidebar" class="intergeo_sidebar_right">’;115 do_action( ‘intergeo_render_subscribe_box’ );116 echo '</div>’;117 echo ‘<div class="intergeo_sidebar_left">’;118 echo "<form method=’post’ action=’’>";119 register_setting( 'intergeo’, 'intergeo-settings-map-api-key’, ‘trim’ );120 add_settings_section( 'intergeo-settings-maps’, __( 'Intergeo Google Maps’, ‘intergeo-maps’ ), 'intergeo_settings_init_map’, INTERGEO_PLUGIN_NAME );121 add_settings_field(122 'intergeo_map_api_key’, __( 'Maps API Key’, ‘intergeo-maps’ ), 'intergeo_settings_print_field’, INTERGEO_PLUGIN_NAME, 'intergeo-settings-maps’, array(123 '<input type="text" name="%s" value="%s" class="regular-text">’,124 'intergeo_map_api_key’,125 esc_attr( get_option( ‘intergeo_map_api_key’ ) ),126 )127 );128129 if ( intergeo_is_developer() ) {130 register_setting( 'intergeo’, 'intergeo_adsense_publisher_id’, ‘trim’ );131 add_settings_section( 'intergeo-settings-adsense’, __( 'Intergeo Google Maps AdSense Integration’, ‘intergeo-maps’ ), 'intergeo_settings_init_adsense’, INTERGEO_PLUGIN_NAME );132 add_settings_field(133 'intergeo_adsense_publisher_id’, __( 'AdSense Publisher Id’, ‘intergeo-maps’ ), 'intergeo_settings_print_field’, INTERGEO_PLUGIN_NAME, 'intergeo-settings-adsense’, array(134 '<input type="text" name="%s" value="%s" class="regular-text">’,135 'intergeo_adsense_publisher_id’,136 esc_attr( get_option( ‘intergeo_adsense_publisher_id’ ) ),137 )138 );139 }140 do_settings_sections( INTERGEO_PLUGIN_NAME );141 submit_button( __( 'Save Changes’, ‘intergeo-maps’ ), 'primary’, ‘sb-intergeo’ );142 wp_nonce_field( 'intergeo-settings’, ‘intergeo-nonce’ );143 echo '</form>’;144 echo '</div>’;145 echo '</div>’;146 echo '</div>’;147}148149/**150 * Init map field.151 */152function intergeo_settings_init_map() {153 ?><p>154 <?php155 printf( esc_html__( ' Below shows how to find your API Key, after retrieving your key add it to the “Maps API Key” input box.’, ‘intergeo-maps’ ) );156 ?>157 </p>158 <iframe width="560" height="315" src="https://www.youtube.com/embed/rqucit5YHNk?start=030" frameborder="0"159 allowfullscreen></iframe>160 <?php161}162163/**164 * Init adsense field.165 */166function intergeo_settings_init_adsense() {167168 if ( intergeo_is_developer() ) {169 ?>170 <p>171 <?php172 printf( esc_html__( “Adding display ads to your map requires that you have an AdSense account enabled for AdSense for Content. If you don’t yet have an AdSense account, %1\$ssign up%3\$s for one. Once you have done so (or if you already have an account) make sure you’ve also enabled the account with %2\$sAdSense for Content%3\$s.", ‘intergeo-maps’ ), '<a href="https://www.google.com/adsense/support/bin/answer.py?answer=10162” target="_blank">’, '<a href="https://www.google.com/adsense/support/bin/answer.py?hl=en&answer=17470" target="_blank">’, ‘</a>’ )173 ?>174 </p><p>175 <?php176 esc_html_e( 'Once you have an Adsense for Content account, you will have received an AdSense for Content (AFC) publisher ID. This publisher ID is used to link any advertising shown to your AdSense account, allowing you to share in advertising revenue when a user clicks on one of the ads shown on your maps.’, ‘intergeo-maps’ )177 ?>178 </p>179 <?php180 }181}182183/**184 *185 * Print settings field.186 *187 * @param array $args Settings array.188 */189function intergeo_settings_print_field( array $args ) {190 vprintf( array_shift( $args ), $args );191}192193/**194 * Load libraries assets.195 *196 * @param bool $libraries LIbraries to load.197 */198function intergeo_enqueue_google_maps_script( $libraries = false ) {199 global $wp_scripts;200 if ( is_array( $libraries ) ) {201 $libraries = implode( ',’, $libraries );202 }203 if ( wp_script_is( ‘google-maps-v3’ ) ) {204 $params = array();205 $arr = explode( '?’, $wp_scripts->registered[‘google-maps-v3’]->src );206 parse_str( end( $arr ), $params );207 $params[‘libraries’] = implode( ',’, array_unique( array_merge( isset( $params[‘libraries’] ) ? explode( ',’, $params[‘libraries’] ) : array(), explode( ',’, $libraries ) ) ) );208 $wp_scripts->registered[‘google-maps-v3’]->src = ‘//maps.googleapis.com/maps/api/js?’ . http_build_query( $params );209210 } else {211 $lang = explode( '_’, WPLANG ? WPLANG : ‘en_US’ );212 $params = array(213 ‘region’ => isset( $lang[1] ) ? $lang[1] : 'US’,214 ‘language’ => $lang[0],215 );216 if ( ! empty( $libraries ) ) {217 $params[‘libraries’] = $libraries;218 }219 $api_key = get_option( ‘intergeo_map_api_key’ );220 if ( ! empty( $api_key ) ) {221 $params[‘key’] = $api_key;222 }223 if ( wp_script_is( ‘google-maps’ ) ) {224 wp_dequeue_script( ‘google-maps’ );225 }226 wp_enqueue_script( 'google-maps-v3’, ‘//maps.googleapis.com/maps/api/js?’ . http_build_query( $params ), array(), null );227 }228}229230/**231 * Check libraries to load.232 *233 * @param array $json Settings.234 * @param array $libraries Libraries.235 *236 * @return array Check libraries to load.237 */238function intergeo_check_libraries( $json, $libraries = array() ) {239 if ( isset( $json[‘layer’][‘adsense’] ) && $json[‘layer’][‘adsense’] && ! in_array( 'adsense’, $libraries ) ) {240 $libraries[] = 'adsense’;241 }242 if ( isset( $json[‘layer’][‘panoramio’] ) && $json[‘layer’][‘panoramio’] && ! in_array( 'panoramio’, $libraries ) ) {243 $libraries[] = 'panoramio’;244 }245 if ( ( isset( $json[‘layer’][‘weather’] ) && $json[‘layer’][‘weather’] ) || ( isset( $json[‘layer’][‘cloud’] ) && $json[‘layer’][‘cloud’] ) ) {246 if ( ! in_array( 'weather’, $libraries ) ) {247 $libraries[] = 'weather’;248 }249 }250251 return $libraries;252}253254/**255 * Encode post id.256 *257 * @param int $id post id.258 *259 * @return string Encoded string.260 */261function intergeo_encode( $id ) {262 return strrev( rtrim( call_user_func( ‘base64_’ . 'encode’, $id ), ‘=’ ) );263}264265/**266 * Return decoded int value.267 *268 * @param string $code Encoded id.269 *270 * @return int Return int id.271 */272function intergeo_decode( $code ) {273 return intval( call_user_func( ‘base64’ . '_decode’, strrev( $code ) ) );274}275276add_filter( 'media_upload_tabs’, ‘intergeo_media_upload_tabs’ );277/**278 * Alter the media tabs and insert the intergeo one.279 *280 * @param array $tabs The actual tabs.281 *282 * @return mixed Array of tabs.283 */284function intergeo_media_upload_tabs( $tabs ) {285 $tabs[‘intergeo_map’] = __( 'Intergeo Maps’, ‘intergeo-maps’ );286287 return $tabs;288}289290add_action( 'media_upload_intergeo_map’, ‘intergeo_map_popup_init’ );291/**292 * Routine to show the popup.293 */294function intergeo_map_popup_init() {295 $post_id = filter_input(296 INPUT_GET, 'post_id’, FILTER_VALIDATE_INT, array(297 ‘options’ => array(298 ‘min_range’ => 1,299 ),300 )301 );302 $map_id = filter_input( INPUT_GET, ‘map’ );303 $send_to_editor = false;304 if ( $_SERVER[‘REQUEST_METHOD’] == ‘POST’ ) {305 $shortcode = intergeo_save_map( $map_id, $post_id );306 if ( $post_id ) {307 $send_to_editor = $shortcode;308 } else {309 $args = array(310 ‘page’ => INTERGEO_PLUGIN_NAME,311 ‘updated’ => current_time( ‘mysql’ ),312 );313 wp_redirect( add_query_arg( $args, admin_url( ‘upload.php’ ) ) );314 exit;315 }316 }317 intergeo_enqueue_google_maps_script( ‘adsense,panoramio,weather,drawing,places’ );318 wp_enqueue_script( 'jquery-ddslick’, INTERGEO_ABSURL . 'js/jquery.ddslick.min.js’, array( ‘jquery’ ) );319 wp_enqueue_script(320 'intergeo-editor’, INTERGEO_ABSURL . 'js/editor.js’, array(321 'jquery-ddslick’,322 'wp-color-picker’,323 'google-maps-v3’,324 ), time()325 );326 wp_localize_script(327 'intergeo-editor’, 'intergeo_options’, array(328 ‘send_to_editor’ => $send_to_editor,329 ‘is_pro’ => intergeo_is_personal() ? ‘yes’ : 'no’,330 ‘adsense’ => array(331 ‘publisher_id’ => get_option( ‘intergeo_adsense_publisher_id’ ),332 ),333 ‘ajaxurl’ => admin_url( ‘admin-ajax.php’ ),334 ‘nonce’ => wp_create_nonce( ‘editor_popup’ . filter_input( INPUT_SERVER, 'REMOTE_ADDR’, FILTER_VALIDATE_IP ) ),335 ‘l10n’ => array(336 ‘marker’ => __( 'marker’, ‘intergeo-maps’ ),337 ‘error’ => array(338 ‘style’ => __( 'Styles are broken. Please, fix it and try again.’, ‘intergeo-maps’ ),339 ‘directions’ => __( 'Directions were not found. Error: ', ‘intergeo-maps’ ),340 ‘shortcode’ => __( 'Unable to render shortcode properly. Error: ', ‘intergeo-maps’ ),341 ),342 ),343 ‘show_error’ => is_user_logged_in() ? 1 : 0,344 )345 );346 wp_enqueue_style( ‘wp-color-picker’ );347 wp_enqueue_style( 'intergeo-editor’, INTERGEO_ABSURL . 'css/editor.css’, array(), INTERGEO_VERSION );348 do_action(349 'intergeo_enqueue_assets’, array( ‘intergeo-editor’ ), array(350 ‘mapID’ => $map_id,351 )352 );353354 wp_iframe( 'intergeo_iframe’, $post_id, $map_id );355}356357/**358 * Render the intergeo form iframe.359 *360 * @param int $post_id The post id.361 * @param int $map_id The map id.362 */363function intergeo_iframe( $post_id = false, $map_id = false ) {364 $publisher_id = trim( get_option( ‘intergeo_adsense_publisher_id’ ) );365 $show_map_center = get_option( 'intergeo_show_map_center’, true );366 $submit_text = __( 'Insert into post’, ‘intergeo-maps’ );367 if ( ! $post_id ) {368 $submit_text = __( 'Create the map’, ‘intergeo-maps’ );369 }370 $copy = false;371 if ( ! $map_id ) {372 $copy = true;373 $map_id = filter_input( INPUT_GET, ‘copy’ );374 }375 $json = array();376 if ( $map_id ) {377 $map = get_post( intergeo_decode( $map_id ) );378 if ( $map->post_type == INTERGEO_PLUGIN_NAME ) {379 $json = json_decode( $map->post_content, true );380 if ( ! $copy ) {381 $submit_text = __( 'Update the map’, ‘intergeo-maps’ );382 }383 }384 }385 require INTERGEO_ABSPATH . '/templates/iframe/form.php’;386}387388/**389 * Validate a value inside a haystack.390 *391 * @param string $value Value to validate.392 * @param array $array Haystack to check in.393 *394 * @return null|string Validated value.395 */396function intergeo_filter_value( $value, $array ) {397 $value = strtoupper( $value );398399 return ! in_array( $value, $array ) ? null : $value;400}401402/**403 * Validate position.404 *405 * @param string $position The position to filter.406 *407 * @return null|string Position filtered408 */409function intergeo_filter_position( $position ) {410 return intergeo_filter_value(411 $position, array(412 'TOP_LEFT’,413 'TOP_CENTER’,414 'TOP_RIGHT’,415 'RIGHT_TOP’,416 'RIGHT_CENTER’,417 'RIGHT_BOTTOM’,418 'BOTTOM_RIGHT’,419 'BOTTOM_CENTER’,420 'BOTTOM_LEFT’,421 'LEFT_BOTTOM’,422 'LEFT_CENTER’,423 'LEFT_TOP’,424 )425 );426}427428/**429 * Validate the map type.430 *431 * @param string $type Type of the map.432 *433 * @return null|string Either the map type is valid or not.434 */435function intergeo_filter_map_type( $type ) {436 return intergeo_filter_value( $type, array( 'ROADMAP’, 'TERRAIN’, 'SATELLITE’, ‘HYBRID’ ) );437}438439/**440 * Validate the map style.441 *442 * @param string $style Style to check. .443 *444 * @return null|string the valid style.445 */446function intergeo_filter_map_type_style( $style ) {447 return intergeo_filter_value( $style, array( 'DEFAULT’, 'DROPDOWN_MENU’, ‘HORIZONTAL_BAR’ ) );448}449450/**451 * Validate zoom style.452 *453 * @param string $style Filter zoom style.454 *455 * @return null|string Filtered value.456 */457function intergeo_filter_zoom_style( $style ) {458 return intergeo_filter_value( $style, array( 'DEFAULT’, 'SMALL’, ‘LARGE’ ) );459}460461/**462 * Validate unit of wind.463 *464 * @param string $unit Unit to valide.465 *466 * @return null|string Filtered value.467 */468function intergeo_filter_wind_speed_units( $unit ) {469 return intergeo_filter_value( $unit, array( 'KILOMETERS_PER_HOUR’, 'METERS_PER_SECOND’, ‘MILES_PER_HOUR’ ) );470}471472/**473 * Validate unit of temperature.474 *475 * @param string $unit Unit to validate.476 *477 * @return null|string Filtered value.478 */479function intergeo_filter_temperature_units( $unit ) {480 return intergeo_filter_value( $unit, array( 'CELSIUS’, ‘FAHRENHEIT’ ) );481}482483/**484 * Filter the format.485 *486 * @param string $format Format to filter.487 *488 * @return null|string Format to filter.489 */490function intergeo_filter_adsense_format( $format ) {491 return intergeo_filter_value(492 $format, array(493 'BANNER’,494 'BUTTON’,495 'HALF_BANNER’,496 'LARGE_HORIZONTAL_LINK_UNIT’,497 'LARGE_RECTANGLE’,498 'LARGE_VERTICAL_LINK_UNIT’,499 'LEADERBOARD’,500 'MEDIUM_RECTANGLE’,501 'MEDIUM_VERTICAL_LINK_UNIT’,502 'SKYSCRAPER’,503 'SMALL_HORIZONTAL_LINK_UNIT’,504 'SMALL_RECTANGLE’,505 'SMALL_SQUARE’,506 'SMALL_VERTICAL_LINK_UNIT’,507 'SQUARE’,508 'VERTICAL_BANNER’,509 'WIDE_SKYSCRAPER’,510 'X_LARGE_VERTICAL_LINK_UNIT’,511 )512 );513}514515/**516 * Filter custom style.517 *518 * @param string $style Filter custom style.519 *520 * @return array|mixed|null|object Filtered custom style.521 */522function intergeo_filter_custom_style( $style ) {523 $style = trim( $style );524 $json = json_decode( $style, true );525526 return empty( $json ) ? null : $json;527}528529/**530 * Filter the overlay markers.531 *532 * @param array $marker Filter the overlay marker.533 *534 * @return array|bool Filtered markers.535 */536function intergeo_filter_overlays_marker( $marker ) {537 if ( ! isset( $marker[‘position’] ) || ! preg_match( '/^-?\d+\.?\d*,-?\d+\.?\d*$/’, $marker[‘position’] ) ) {538 return false;539 }540541 return array(542 ‘position’ => explode( ',’, $marker[‘position’] ),543 ‘icon’ => isset( $marker[‘icon’] ) ? filter_var( $marker[‘icon’], FILTER_VALIDATE_URL ) : '’,544 ‘info’ => isset( $marker[‘info’] ) ? trim( preg_replace( '/\<\/?script.*?\>/is’, '’, $marker[‘info’] ) ) : '’,545 ‘title’ => isset( $marker[‘title’] ) ? strip_tags( trim( $marker[‘title’] ) ) : '’,546 ‘loc’ => isset( $marker[‘loc’] ) ? strip_tags( trim( $marker[‘loc’] ) ) : '’,547 );548}549550551/**552 * Returns the settings URL.553 *554 * @return string The settings URL.555 */556function intergeo_settings_url() {557 return admin_url( ‘options-general.php?page=’ . INTERGEO_PLUGIN_NAME );558}559560/**561 * Filter polyline.562 *563 * @param array $polyline Polyline filter.564 *565 * @return array|bool Filtered values.566 */567function intergeo_filter_overlays_polyline( $polyline ) {568 if ( ! isset( $polyline[‘path’] ) ) {569 return false;570 }571 $path = array();572 foreach ( explode( ';’, $polyline[‘path’] ) as $point ) {573 if ( preg_match( '/^-?\d+\.?\d*,-?\d+\.?\d*$/’, $point ) ) {574 $path[] = explode( ',’, $point );575 }576 }577 if ( count( $path ) < 2 ) {578 return false;579 }580581 return array(582 ‘path’ => $path,583 ‘weight’ => isset( $polyline[‘weight’] )584 ? filter_var(585 $polyline[‘weight’], FILTER_VALIDATE_INT, array(586 ‘options’ => array(587 ‘min_range’ => 1,588 ‘default’ => '’,589 ),590 )591 )592 : '’,593 ‘opacity’ => isset( $polyline[‘opacity’] )594 ? filter_var(595 $polyline[‘opacity’], FILTER_VALIDATE_FLOAT, array(596 ‘options’ => array(597 ‘min_range’ => 0,598 ‘max_range’ => 1,599 ‘default’ => '’,600 ),601 )602 )603 : '’,604 ‘color’ => isset( $polyline[‘color’] )605 ? filter_var(606 $polyline[‘color’], FILTER_VALIDATE_REGEXP, array(607 ‘options’ => array(608 ‘regexp’ => '/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/’,609 ‘default’ => '#000000’,610 ),611 )612 )613 : '#000000’,614 );615}616617/**618 * Filters polygon.619 *620 * @param array $polygon Polygon to filter.621 *622 * @return array|bool Filters polygon.623 */624function intergeo_filter_overlays_polyoverlay( $polygon ) {625 if ( ! isset( $polygon[‘path’] ) ) {626 return false;627 }628 $path = array();629 foreach ( explode( ';’, $polygon[‘path’] ) as $point ) {630 if ( preg_match( '/^-?\d+\.?\d*,-?\d+\.?\d*$/’, $point ) ) {631 $path[] = explode( ',’, $point );632 }633 }634 if ( count( $path ) < 2 ) {635 return false;636 }637 $position = isset( $polygon[‘position’] ) ? strtoupper( trim( $polygon[‘position’] ) ) : 'CENTER’;638639 return array(640 ‘path’ => $path,641 ‘position’ => in_array( $position, array( 'CENTER’, 'INSIDE’, ‘OUTSIDE’ ) ) ? $position : 'CENTER’,642 ‘weight’ => isset( $polygon[‘weight’] ) ? filter_var(643 $polygon[‘weight’], FILTER_VALIDATE_INT, array(644 ‘options’ => array(645 ‘min_range’ => 1,646 ‘default’ => '’,647 ),648 )649 ) : '’,650 ‘stroke_opacity’ => isset( $polygon[‘stroke_opacity’] ) ? filter_var(651 $polygon[‘stroke_opacity’], FILTER_VALIDATE_FLOAT, array(652 ‘options’ => array(653 ‘min_range’ => 0,654 ‘max_range’ => 1,655 ‘default’ => '’,656 ),657 )658 ) : '’,659 ‘stroke_color’ => isset( $polygon[‘stroke_color’] ) ? filter_var(660 $polygon[‘stroke_color’], FILTER_VALIDATE_REGEXP, array(661 ‘options’ => array(662 ‘regexp’ => '/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/’,663 ‘default’ => '#000000’,664 ),665 )666 ) : '#000000’,667 ‘fill_opacity’ => isset( $polygon[‘fill_opacity’] ) ? filter_var(668 $polygon[‘fill_opacity’], FILTER_VALIDATE_FLOAT, array(669 ‘options’ => array(670 ‘min_range’ => 0,671 ‘max_range’ => 1,672 ‘default’ => '’,673 ),674 )675 ) : '’,676 ‘fill_color’ => isset( $polygon[‘fill_color’] ) ? filter_var(677 $polygon[‘fill_color’], FILTER_VALIDATE_REGEXP, array(678 ‘options’ => array(679 ‘regexp’ => '/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/’,680 ‘default’ => '#000000’,681 ),682 )683 ) : '#000000’,684 );685}686687/**688 * Filter directions array.689 *690 * @param array $direction Direction array to filter.691 *692 * @return array|bool Filtered directions.693 */694function intergeo_filter_directions( $direction ) {695 $to = isset( $direction[‘to’] ) ? trim( $direction[‘to’] ) : '’;696 $from = isset( $direction[‘from’] ) ? trim( $direction[‘from’] ) : '’;697 if ( empty( $to ) || empty( $from ) ) {698 return false;699 }700 $mode = isset( $direction[‘mode’] ) ? strtoupper( trim( $direction[‘mode’] ) ) : 'DRIVING’;701702 return array(703 ‘mode’ => in_array( $mode, array( 'BICYCLING’, 'DRIVING’, 'TRANSIT’, ‘WALKING’ ) ) ? $mode : 'DRIVING’,704 ‘from’ => $from,705 ‘to’ => $to,706 );707}708709/**710 * Filter map input.711 *712 * @return array Array to filter.713 */714function intergeo_filter_input() {715 $color_regexp = '/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/’;716 $postion_filter = array(717 ‘filter’ => FILTER_CALLBACK,718 ‘options’ => 'intergeo_filter_position’,719 );720 $validationArray = array(721 ‘lat’ => array(722 ‘filter’ => FILTER_VALIDATE_FLOAT,723 ‘flags’ => FILTER_REQUIRE_SCALAR,724 ‘options’ => array(725 ‘min_range’ => - 90,726 ‘max_range’ => 90,727 ‘default’ => 48.1366069,728 ),729 ),730 ‘lng’ => array(731 ‘filter’ => FILTER_VALIDATE_FLOAT,732 ‘flags’ => FILTER_REQUIRE_SCALAR,733 ‘options’ => array(734 ‘min_range’ => - 180,735 ‘max_range’ => 180,736 ‘default’ => 11.577085099999977,737 ),738 ),739 ‘zoom’ => array(740 ‘filter’ => FILTER_VALIDATE_INT,741 ‘flags’ => FILTER_REQUIRE_SCALAR,742 ‘options’ => array(743 ‘min_range’ => 0,744 ‘max_range’ => 19,745 ‘default’ => 5,746 ),747 ),748 ‘address’ => FILTER_SANITIZE_STRING,749 ‘map_mapTypeId’ => array(750 ‘filter’ => FILTER_CALLBACK,751 ‘options’ => 'intergeo_filter_map_type’,752 ),753 ‘map_draggable’ => FILTER_VALIDATE_BOOLEAN,754 ‘map_minZoom’ => array(755 ‘filter’ => FILTER_VALIDATE_INT,756 ‘flags’ => FILTER_REQUIRE_SCALAR,757 ‘options’ => array(758 ‘min_range’ => 0,759 ‘max_range’ => 19,760 ‘default’ => 0,761 ),762 ),763 ‘map_maxZoom’ => array(764 ‘filter’ => FILTER_VALIDATE_INT,765 ‘flags’ => FILTER_REQUIRE_SCALAR,766 ‘options’ => array(767 ‘min_range’ => 0,768 ‘max_range’ => 19,769 ‘default’ => 19,770 ),771 ),772 ‘map_scrollwheel’ => FILTER_VALIDATE_BOOLEAN,773 ‘map_zoomControl’ => FILTER_VALIDATE_BOOLEAN,774 ‘map_zoomControlOptions_position’ => $postion_filter,775 ‘map_zoomControlOptions_style’ => array(776 ‘filter’ => FILTER_CALLBACK,777 ‘options’ => 'intergeo_filter_zoom_style’,778 ),779 ‘map_panControl’ => FILTER_VALIDATE_BOOLEAN,780 ‘map_panControlOptions_position’ => $postion_filter,781 ‘map_scaleControl’ => FILTER_VALIDATE_BOOLEAN,782 ‘map_scaleControlOptions_position’ => $postion_filter,783 ‘map_mapTypeControl’ => FILTER_VALIDATE_BOOLEAN,784 ‘map_mapTypeControlOptions_position’ => $postion_filter,785 ‘map_mapTypeControlOptions_style’ => array(786 ‘filter’ => FILTER_CALLBACK,787 ‘options’ => 'intergeo_filter_map_type_style’,788 ),789 ‘map_mapTypeControlOptions_mapTypeIds’ => array(790 ‘filter’ => FILTER_CALLBACK,791 ‘flags’ => FILTER_REQUIRE_ARRAY,792 ‘options’ => 'intergeo_filter_map_type’,793 ),794 ‘map_streetViewControl’ => FILTER_VALIDATE_BOOLEAN,795 ‘map_streetViewControlOptions_position’ => $postion_filter,796 ‘map_rotateControl’ => FILTER_VALIDATE_BOOLEAN,797 ‘map_rotateControlOptions_position’ => $postion_filter,798 ‘map_overviewMapControl’ => FILTER_VALIDATE_BOOLEAN,799 ‘map_overviewMapControlOptions_opened’ => FILTER_VALIDATE_BOOLEAN,800 ‘layer_traffic’ => FILTER_VALIDATE_BOOLEAN,801 ‘layer_bicycling’ => FILTER_VALIDATE_BOOLEAN,802 ‘layer_cloud’ => FILTER_VALIDATE_BOOLEAN,803 ‘layer_weather’ => FILTER_VALIDATE_BOOLEAN,804 ‘weather_temperatureUnits’ => array(805 ‘filter’ => FILTER_CALLBACK,806 ‘options’ => 'intergeo_filter_temperature_units’,807 ),808 ‘weather_windSpeedUnits’ => array(809 ‘filter’ => FILTER_CALLBACK,810 ‘options’ => 'intergeo_filter_wind_speed_units’,811 ),812 ‘layer_panoramio’ => FILTER_VALIDATE_BOOLEAN,813 ‘panoramio_tag’ => FILTER_SANITIZE_STRING,814 ‘panoramio_userId’ => FILTER_SANITIZE_STRING,815 ‘layer_adsense’ => FILTER_VALIDATE_BOOLEAN,816 ‘adsense_format’ => array(817 ‘filter’ => FILTER_CALLBACK,818 ‘options’ => 'intergeo_filter_adsense_format’,819 ),820 ‘adsense_position’ => $postion_filter,821 ‘adsense_backgroundColor’ => array(822 ‘filter’ => FILTER_VALIDATE_REGEXP,823 ‘options’ => array(824 ‘regexp’ => $color_regexp,825 ‘default’ => '#c4d4f3’,826 ),827 ),828 ‘adsense_borderColor’ => array(829 ‘filter’ => FILTER_VALIDATE_REGEXP,830 ‘options’ => array(831 ‘regexp’ => $color_regexp,832 ‘default’ => '#e5ecf9’,833 ),834 ),835 ‘adsense_titleColor’ => array(836 ‘filter’ => FILTER_VALIDATE_REGEXP,837 ‘options’ => array(838 ‘regexp’ => $color_regexp,839 ‘default’ => '#0000cc’,840 ),841 ),842 ‘adsense_textColor’ => array(843 ‘filter’ => FILTER_VALIDATE_REGEXP,844 ‘options’ => array(845 ‘regexp’ => $color_regexp,846 ‘default’ => '#000000’,847 ),848 ),849 ‘adsense_urlColor’ => array(850 ‘filter’ => FILTER_VALIDATE_REGEXP,851 ‘options’ => array(852 ‘regexp’ => $color_regexp,853 ‘default’ => '#009900’,854 ),855 ),856 ‘container_width’ => FILTER_SANITIZE_STRING,857 ‘container_height’ => FILTER_SANITIZE_STRING,858 ‘container_styles’ => FILTER_SANITIZE_STRING,859 ‘styles_type’ => FILTER_SANITIZE_STRING,860 ‘styles_custom’ => array(861 ‘filter’ => FILTER_CALLBACK,862 ‘options’ => 'intergeo_filter_custom_style’,863 ),864 ‘overlays_marker’ => array(865 ‘filter’ => FILTER_DEFAULT,866 ‘flags’ => FILTER_REQUIRE_ARRAY,867 ),868 ‘overlays_polyline’ => array(869 ‘filter’ => FILTER_DEFAULT,870 ‘flags’ => FILTER_REQUIRE_ARRAY,871 ),872 ‘overlays_polygon’ => array(873 ‘filter’ => FILTER_DEFAULT,874 ‘flags’ => FILTER_REQUIRE_ARRAY,875 ),876 ‘overlays_rectangle’ => array(877 ‘filter’ => FILTER_DEFAULT,878 ‘flags’ => FILTER_REQUIRE_ARRAY,879 ),880 ‘overlays_circle’ => array(881 ‘filter’ => FILTER_DEFAULT,882 ‘flags’ => FILTER_REQUIRE_ARRAY,883 ),884 ‘directions’ => array(885 ‘filter’ => FILTER_DEFAULT,886 ‘flags’ => FILTER_REQUIRE_ARRAY,887 ),888 );889 $defaults = array(890 ‘lat’ => 48.1366069,891 ‘lng’ => 11.577085099999977,892 ‘zoom’ => 5,893 ‘address’ => '’,894 ‘map_mapTypeId’ => 'ROADMAP’,895 ‘map_draggable’ => true,896 ‘map_minZoom’ => 0,897 ‘map_maxZoom’ => 19,898 ‘map_scrollwheel’ => true,899 ‘map_zoomControl’ => true,900 ‘map_zoomControlOptions_position’ => null,901 ‘map_zoomControlOptions_style’ => 'DEFAULT’,902 ‘map_panControl’ => true,903 ‘map_panControlOptions_position’ => null,904 ‘map_scaleControl’ => false,905 ‘map_scaleControlOptions_position’ => null,906 ‘map_mapTypeControl’ => true,907 ‘map_mapTypeControlOptions_position’ => null,908 ‘map_mapTypeControlOptions_style’ => 'DEFAULT’,909 ‘map_mapTypeControlOptions_mapTypeIds’ => array( 'ROADMAP’, 'TERRAIN’, 'SATELLITE’, ‘HYBRID’ ),910 ‘map_streetViewControl’ => true,911 ‘map_streetViewControlOptions_position’ => null,912 ‘map_rotateControl’ => true,913 ‘map_rotateControlOptions_position’ => null,914 ‘map_overviewMapControl’ => false,915 ‘map_overviewMapControlOptions_opened’ => false,916 ‘layer_traffic’ => false,917 ‘layer_bicycling’ => false,918 ‘layer_cloud’ => false,919 ‘layer_weather’ => false,920 ‘weather_temperatureUnits’ => null,921 ‘weather_windSpeedUnits’ => null,922 ‘layer_panoramio’ => false,923 ‘panoramio_tag’ => '’,924 ‘panoramio_userId’ => '’,925 ‘layer_adsense’ => false,926 ‘adsense_format’ => null,927 ‘adsense_position’ => null,928 ‘adsense_backgroundColor’ => '#c4d4f3’,929 ‘adsense_borderColor’ => '#e5ecf9’,930 ‘adsense_titleColor’ => '#0000cc’,931 ‘adsense_textColor’ => '#000000’,932 ‘adsense_urlColor’ => '#009900’,933 ‘container_width’ => '’,934 ‘container_height’ => '’,935 ‘container_styles’ => '’,936 ‘styles_type’ => 'DEFAULT’,937 ‘styles_custom’ => null,938 ‘overlays_marker’ => array(),939 ‘overlays_polyline’ => array(),940 ‘overlays_polygon’ => array(),941 ‘overlays_rectangle’ => array(),942 ‘overlays_circle’ => array(),943 ‘directions’ => array(),944 );945 $validated = apply_filters( 'intergeo_validations’, array( $validationArray, $defaults ) );946 $validationArray = $validated[0];947 $defaults = $validated[1];948 $options = filter_input_array( INPUT_POST, $validationArray );949 $results = array();950 foreach ( $options as $key => $value ) {951 if ( array_key_exists( $key, $defaults ) ) {952 $equals = $defaults[ $key ] == $value;953 if ( is_array( $value ) ) {954 $equals = ( count( $value ) == count( $defaults[ $key ] ) ) && ( count( array_diff( (array) $defaults[ $key ], $value ) ) == 0 );955 }956 if ( ! $equals ) {957 $results[ $key ] = $value;958 }959 }960 }961 if ( ! empty( $results[‘overlays_marker’] ) ) {962 $results[‘overlays_marker’] = array_filter( array_map( 'intergeo_filter_overlays_marker’, $results[‘overlays_marker’] ) );963 }964 if ( ! empty( $results[‘overlays_polyline’] ) ) {965 $results[‘overlays_polyline’] = array_filter( array_map( 'intergeo_filter_overlays_polyline’, $results[‘overlays_polyline’] ) );966 }967 if ( ! empty( $results[‘directions’] ) ) {968 $results[‘directions’] = array_filter( array_map( 'intergeo_filter_directions’, $results[‘directions’] ) );969 }970 foreach ( array( 'polygon’, 'rectangle’, ‘circle’ ) as $overlay ) {971 $overlay = ‘overlays_’ . $overlay;972 if ( ! empty( $results[ $overlay ] ) ) {973 $results[ $overlay ] = array_filter( array_map( 'intergeo_filter_overlays_polyoverlay’, $results[ $overlay ] ) );974 }975 }976 $results = apply_filters( 'intergeo_process_results’, $results );977978 return $results;979}980981/**982 * Routine to save the map.983 *984 * @param int $map_id Map id.985 * @param int $post_id Post id.986 *987 * @return bool|string Return shortcode val.988 */989function intergeo_save_map( $map_id = false, $post_id = false ) {990 $options = array();991 $array_ptr = &$options;992 foreach ( intergeo_filter_input() as $key => $value ) {993 if ( ! is_null( $value ) ) {994 $keys = explode( '_’, $key );995 $last_key = array_pop( $keys );996 while ( $arr_key = array_shift( $keys ) ) {997 if ( ! array_key_exists( $arr_key, $array_ptr ) ) {998 $array_ptr[ $arr_key ] = array();999 }1000 $array_ptr = &$array_ptr[ $arr_key ];1001 }1002 $array_ptr[ $last_key ] = $value;1003 $array_ptr = &$options;1004 }1005 }1006 $address = '’;1007 if ( ! empty( $options[‘address’] ) ) {1008 $address = $options[‘address’] = trim( $options[‘address’] );1009 }1010 $args = array(1011 ‘post_type’ => INTERGEO_PLUGIN_NAME,1012 ‘post_content’ => addcslashes( json_encode( $options ), ‘\\’ ),1013 ‘post_status’ => 'private’,1014 );1015 $update = false;1016 if ( $map_id ) {1017 $post = get_post( intergeo_decode( $map_id ) );1018 if ( $post && $post->post_type == INTERGEO_PLUGIN_NAME ) {1019 $update = true;1020 $args[‘ID’] = $post->ID;1021 }1022 }1023 $id = wp_insert_post( $args );1024 if ( ! empty( $id ) && ! is_wp_error( $id ) ) {1025 if ( ! $post_id ) {1026 intergeo_set_info(1027 $update1028 ? __( 'The map has been updated successfully.’, ‘intergeo-maps’ )1029 : __( 'The map has been created successfully.’, ‘intergeo-maps’ )1030 );1031 }10321033 return sprintf( '[intergeo id="%s"]%s[/intergeo]', intergeo_encode( $id ), $address );1034 }1035 if ( ! $post_id ) {1036 intergeo_set_error(1037 $update1038 ? __( 'The map updating failed.’, ‘intergeo-maps’ )1039 : __( 'The map creation failed.’, ‘intergeo-maps’ )1040 );1041 }10421043 return false;1044}10451046add_action( 'wp_ajax_intergeo_show_map_center’, ‘intergeo_show_map_center_changed’ );1047/**1048 * Update map status.1049 */1050function intergeo_show_map_center_changed() {1051 $nonce = filter_input( INPUT_POST, ‘nonce’ );1052 if ( wp_verify_nonce( $nonce, ‘editor_popup’ . filter_input( INPUT_SERVER, 'REMOTE_ADDR’, FILTER_VALIDATE_IP ) ) ) {1053 update_option( 'intergeo_show_map_center’, (int) filter_input( INPUT_POST, 'status’, FILTER_VALIDATE_BOOLEAN ) );1054 }1055}10561057/**1058 * Render shortcode in widget and terms description.1059 */1060add_filter( 'widget_text’, ‘do_shortcode’ );1061add_filter( 'term_description’, ‘do_shortcode’ );10621063add_shortcode( INTERGEO_PLUGIN_NAME, ‘intergeo_shortcode’ );1064/**1065 * Renders the intergeo shortcode.1066 *1067 * @param array $attrs The shortcode atts.1068 * @param string $address The address used.1069 *1070 * @return string The shortcode output.1071 */1072function intergeo_shortcode( $attrs, $address = ‘’ ) {1073 do_action( 'intergeo_shortcode_render_before’, $attrs );1074 $args = shortcode_atts(1075 array(1076 ‘id’ => false,1077 ‘hook’ => false,1078 ‘width’ => false,1079 ‘height’ => false,1080 ‘style’ => false,1081 ‘zoom’ => false,1082 ), $attrs1083 );1084 $address = trim( $address );1085 if ( empty( $args[‘id’] ) && empty( $address ) ) {1086 return '’;1087 }1088 $json = array();1089 if ( ! empty( $args[‘id’] ) ) {1090 $post = get_post( intergeo_decode( $args[‘id’] ) );1091 if ( ! $post || $post->post_type != INTERGEO_PLUGIN_NAME ) {1092 return '’;1093 }1094 $json = json_decode( $post->post_content, true );1095 } else {1096 $args[‘id’] = intergeo_encode( rand( 0, 100 ) . rand( 0, 10000 ) );1097 $json[‘zoom’] = intval( $args[‘zoom’] ) ? intval( $args[‘zoom’] ) : 15;1098 }1099 if ( ! empty( $address ) ) {1100 $json[‘address’] = $address;1101 }1102 if ( trim( $args[‘hook’] ) != ‘’ ) {1103 $json = apply_filters( $args[‘hook’], $json );1104 }1105 wp_enqueue_style( ‘intergeo-frontend’ );1106 intergeo_enqueue_google_maps_script( intergeo_check_libraries( $json ) );1107 if ( ! wp_script_is( ‘intergeo-rendering’ ) ) {1108 wp_enqueue_script(1109 'intergeo-rendering’, INTERGEO_ABSURL . 'js/rendering.js’, array(1110 'jquery’,1111 'google-maps-v3’,1112 ), INTERGEO_VERSION1113 );1114 wp_localize_script(1115 'intergeo-rendering’, 'intergeo_options’, array(1116 ‘adsense’ => array(1117 ‘publisher_id’ => get_option( ‘intergeo_adsense_publisher_id’ ),1118 ),1119 )1120 );1121 }1122 $container = array();1123 if ( isset( $json[‘container’] ) ) {1124 $container = $json[‘container’];1125 unset( $json[‘container’] );1126 }1127 $width = ! empty( $container[‘width’] ) ? esc_attr( $container[‘width’] ) : '100%’;1128 if ( trim( $args[‘width’] ) != ‘’ ) {1129 $width = $args[‘width’];1130 }1131 if ( is_numeric( $width ) ) {1132 $width .= 'px’;1133 }1134 $height = ! empty( $container[‘height’] ) ? esc_attr( $container[‘height’] ) : '300px’;1135 if ( trim( $args[‘height’] ) != ‘’ ) {1136 $height = $args[‘height’];1137 }1138 if ( is_numeric( $height ) ) {1139 $height .= 'px’;1140 }1141 $styles = ! empty( $container[‘styles’] ) ? esc_attr( $container[‘styles’] ) : '’;1142 if ( trim( $args[‘style’] ) != ‘’ ) {1143 $styles = $args[‘style’];1144 }11451146 return sprintf(1147 '1148 <div id="intergeo_map%1$s" class="intergeo_map_canvas" style="width:100%%;height:300px;width:%2$s;height:%3$s;%4$s"></div>1149 <script type="text/javascript">1150 /* <![CDATA[ */1151 if (!window.intergeo_maps) window.intergeo_maps = [];1152 window.intergeo_maps.push( { container: \’intergeo_map%1$s\’, options: %5$s } );1153 if (!window.intergeo_maps_current) window.intergeo_maps_current = null;1154 /* ]]> */1155 </script>1156 ',1157 $args[‘id’],1158 $width,1159 $height,1160 $styles,1161 json_encode( $json )1162 );1163}11641165add_action( 'admin_menu’, ‘intergeo_admin_menu’ );1166/**1167 * Adds the intergeo admin menu.1168 */1169function intergeo_admin_menu() {1170 $settings = add_options_page( __( 'Intergeo Maps Library’, ‘intergeo-maps’ ), __( 'Intergeo Maps’, ‘intergeo-maps’ ), 'edit_posts’, INTERGEO_PLUGIN_NAME, ‘intergeo_settings’ );1171 if ( $settings ) {1172 add_action( "load-{$settings}", ‘intergeo_settings_init’ );1173 }1174 $library = add_submenu_page( 'upload.php’, __( 'Intergeo Maps Library’, ‘intergeo-maps’ ), __( 'Intergeo Maps’, ‘intergeo-maps’ ), 'edit_posts’, INTERGEO_PLUGIN_NAME, ‘intergeo_library’ );1175 if ( $library ) {1176 add_action( "load-{$library}", ‘intergeo_library_init’ );1177 }1178}11791180/**1181 * Init assets for settings screen.1182 */1183function intergeo_settings_init() {1184 wp_enqueue_style( 'intergeo_library’, INTERGEO_ABSURL . 'css/library.css’, array(), INTERGEO_VERSION );1185 wp_enqueue_script( 'themeisle-subscribe’, INTERGEO_ABSURL . 'subscribe/subscribe.js’, array( ‘jquery’ ) );1186 wp_localize_script( 'themeisle-subscribe’, 'ti’, array() );1187}11881189/**1190 * Init library assets and scripts.1191 */1192function intergeo_library_init() {1193 wp_enqueue_style( 'intergeo_library’, INTERGEO_ABSURL . 'css/library.css’, array(), INTERGEO_VERSION );1194 wp_enqueue_script( 'themeisle-subscribe’, INTERGEO_ABSURL . 'subscribe/subscribe.js’, array( ‘jquery’ ) );1195 wp_localize_script( 'themeisle-subscribe’, 'ti’, array() );1196 wp_enqueue_media();1197 $screen = get_current_screen();1198 $screen->add_help_tab(1199 array(1200 ‘title’ => esc_html__( 'Overview’, ‘intergeo-maps’ ),1201 ‘id’ => 'overview’,1202 ‘content’ => sprintf(1203 '<p>%s</p>’, implode(1204 ‘</p><p>’, array(1205 esc_html__( "The library is a list to view all maps you have created in your system. The library is showing you 3x3 grid of maps’ previews. You will see the same maps embedded into your posts at front end, as you see here. The library is paginated and if you have more than 9 maps, you will see pagination links under maps grid.", ‘intergeo-maps’ ),1206 esc_html__( 'To create a new map, click on “Add New” button next to the page title and map editor popup will appear. In case you want to edit a map, you can click on pencil icon in the right bottom corner of map preview box and edit popup window will appear.’, ‘intergeo-maps’ ),1207 esc_html__( "If you want to delete a map, click on the trash icon in the right bottom corner of a map and confirm your action. Pay attention that whole information about the map will be removed from the system, but all shortcodes will be left where you embed it. However these deprecated shortcodes won’t be rendered anymore, so you don’t have to worry about it while the plugin is enabled.", ‘intergeo-maps’ ),1208 )1209 )1210 ),1211 )1212 );1213 $screen->add_help_tab(1214 array(1215 ‘title’ => esc_html__( 'Shortcodes’, ‘intergeo-maps’ ),1216 ‘id’ => 'shortcodes’,1217 ‘content’ => sprintf(1218 '<p>%s</p>’, implode(1219 '</p><p>’, array(1220 esc_html__( 'You can easily embed a map into your posts, pages, categories or tags descriptions and text widgets by copying shortcode which you can find in the input field of a map preview box.’, ‘intergeo-maps’ ),1221 esc_html__( 'To specify a certain address just type it inside a shortcode, and a map will be automatically centered at this place. Also each shortcode could be extended with custom attributes like width, height, style, zoom and hook. Use standard CSS values for such attributes as width, height and style. Type an integer between 0 and 19 for zoom attribute. You can use hook attribute to set up a filter hook which you can use in your custom plugin or theme to configure all options of a map.’, ‘intergeo-maps’ ),1222 )1223 )1224 ),1225 )1226 );1227}12281229/**1230 * Render library of maps.1231 */1232function intergeo_library() {1233 if ( filter_input( INPUT_GET, ‘do’ ) == ‘delete’ ) {1234 intergeo_library_delete();1235 }12361237 if ( filter_input( INPUT_GET, ‘do’ ) == ‘dismiss-notice’ && current_user_can( ‘manage_options’ ) ) {1238 if ( wp_verify_nonce( filter_input( INPUT_GET, ‘nonce’ ), ‘dismiss-notice’ . filter_input( INPUT_SERVER, 'REMOTE_ADDR’, FILTER_VALIDATE_IP ) ) ) {1239 update_option( 'intergeo_maps_otter_notice’, true );1240 wp_redirect( add_query_arg( 'page’, INTERGEO_PLUGIN_NAME, admin_url( ‘upload.php’ ) ) );1241 exit;1242 }1243 }12441245 $query = new WP_Query(1246 array(1247 ‘orderby’ => 'ID’,1248 ‘order’ => 'DESC’,1249 ‘post_type’ => INTERGEO_PLUGIN_NAME,1250 ‘posts_per_page’ => 9,1251 ‘paged’ => filter_input(1252 INPUT_GET, 'pagenum’, FILTER_VALIDATE_INT, array(1253 ‘options’ => array(1254 ‘min_range’ => 1,1255 ‘default’ => 1,1256 ),1257 )1258 ),1259 )1260 );1261 $libraries = array();1262 $pagination = paginate_links(1263 array(1264 ‘base’ => add_query_arg(1265 array(1266 ‘pagenum’ => '%#%’,1267 ‘updated’ => false,1268 )1269 ),1270 ‘format’ => '’,1271 ‘current’ => max( 1, $query->get( ‘paged’ ) ),1272 ‘total’ => $query->max_num_pages,1273 ‘type’ => 'array’,1274 )1275 );1276 require INTERGEO_ABSPATH . '/templates/library/list.php’;1277 intergeo_enqueue_google_maps_script( $libraries );1278 wp_enqueue_script(1279 'intergeo-rendering’, INTERGEO_ABSURL . 'js/rendering.js’, array(1280 'jquery’,1281 'google-maps-v3’,1282 ), INTERGEO_VERSION1283 );1284 wp_enqueue_script(1285 'intergeo-library’, INTERGEO_ABSURL . 'js/library.js’, array(1286 'intergeo-rendering’,1287 'media-views’,1288 ), INTERGEO_VERSION1289 );1290 wp_localize_script(1291 'intergeo-rendering’, 'intergeo_options’, array(1292 ‘adsense’ => array(1293 ‘publisher_id’ => get_option( ‘intergeo_adsense_publisher_id’ ),1294 ),1295 )1296 );1297 do_action( 'intergeo_enqueue_assets’, array( ‘intergeo-rendering’ ) );1298}12991300/**1301 * Routine to delete a map.1302 */1303function intergeo_library_delete() {1304 if ( ! current_user_can( ‘delete_posts’ ) ) {1305 return;1306 }1307 $id = intergeo_decode( trim( filter_input( INPUT_GET, ‘map’ ) ) );1308 if ( ! $id ) {1309 return;1310 }1311 $post = get_post( $id );1312 if ( wp_verify_nonce( filter_input( INPUT_GET, ‘nonce’ ), $id . filter_input( INPUT_SERVER, 'REMOTE_ADDR’, FILTER_VALIDATE_IP ) ) && $post->post_type == INTERGEO_PLUGIN_NAME ) {1313 if ( wp_delete_post( $id, true ) ) {1314 intergeo_set_info( __( 'The map was deleted successfully.’, ‘intergeo-maps’ ) );1315 }1316 }1317 if ( filter_input( INPUT_GET, 'noheader’, FILTER_VALIDATE_BOOLEAN ) ) {1318 wp_redirect( add_query_arg( 'page’, INTERGEO_PLUGIN_NAME, admin_url( ‘upload.php’ ) ) );1319 exit;1320 }1321}13221323/**1324 * Count the current maps number.1325 *1326 * @return int The current maps number.1327 */1328function intergeo_get_maps() {1329 $query = new WP_Query(1330 array(1331 ‘orderby’ => 'ID’,1332 ‘order’ => 'DESC’,1333 ‘fields’ => 'ids’,1334 ‘no_found_rows’ => true,1335 ‘update_post_meta_cache’ => false,1336 ‘update_post_term_cache’ => false,1337 ‘post_type’ => INTERGEO_PLUGIN_NAME,1338 ‘posts_per_page’ => 11,1339 )1340 );13411342 return $query->post_count;1343}13441345add_action( 'admin_notices’, ‘intergeo_print_messages’ );1346/**1347 * Print messages.1348 */1349function intergeo_print_messages() {1350 global $pagenow;1351 if ( $pagenow != ‘upload.php’ ) {1352 return;1353 }1354 $messages = get_option( 'intergeo_messages’, array() );1355 $user_id = get_current_user_id();1356 if ( ! isset( $messages[ $user_id ] ) ) {1357 return;1358 }1359 foreach ( $messages[ $user_id ] as $message ) {1360 printf( $message[1] ? ‘<div class="updated"><p>%s</p></div>’ : '<div class="error"><p>%s</p></div>’, $message[0] );1361 }1362 $messages[ $user_id ] = array();1363 update_option( 'intergeo_messages’, $messages );1364}13651366/**1367 * Add options.1368 */1369function intergeo_register_settings() {1370 add_option( 'intergeo_maps_otter_notice’, false );1371}1372add_action( 'admin_init’, ‘intergeo_register_settings’ );13731374/**1375 * Show message.1376 *1377 * @param string $message Message.1378 * @param string $is_normal Type.1379 * @param int $user_id User id.1380 */1381function intergeo_set_message( $message, $is_normal, $user_id = false ) {1382 $messages = get_option( 'intergeo_messages’, array() );1383 if ( $user_id === false ) {1384 $user_id = get_current_user_id();1385 }1386 if ( ! isset( $messages[ $user_id ] ) ) {1387 $messages[ $user_id ] = array();1388 }1389 $messages[ $user_id ][] = array( $message, $is_normal );1390 update_option( 'intergeo_messages’, $messages );1391}13921393/**1394 * Show info message.1395 *1396 * @param string $message Message to show.1397 * @param int $user_id User id.1398 */1399function intergeo_set_info( $message, $user_id = false ) {1400 intergeo_set_message( $message, 1, $user_id );1401}14021403/**1404 * Error to show.1405 *1406 * @param string $message Message.1407 * @param int $user_id User id.1408 */1409function intergeo_set_error( $message, $user_id = false ) {1410 intergeo_set_message( $message, 0, $user_id );1411}14121413/**1414 * Return the current plan that the user is using.1415 *1416 * @return int The current plan for pro version.1417 */1418function intergeo_get_plan() {14191420 $plan = intval( get_option( 'intergeo_maps_pro_license_plan’, 0 ) );14211422 return $plan;1423}14241425/**1426 * Either the user is using a personal plan or not.1427 *1428 * @return bool Personal plan status.1429 */1430function intergeo_is_personal() {1431 return ( defined( ‘IntergeoMapsPro_Version’ ) );1432}14331434/**1435 * Either the user is using a developer plan or not.1436 *1437 * @return bool Developer plan status.1438 */1439function intergeo_is_developer() {1440 $plan = intval( intergeo_get_plan() );1441 if ( $plan > 0 ) {1442 return true;1443 }14441445 return false;1446}14471448/**1449 * Either the user is using a agency plan or not.1450 *1451 * @return bool Agency plan status.1452 */1453function intergeo_is_agency() {1454 $plan = intval( intergeo_get_plan() );1455 if ( $plan > 2 ) {1456 return true;1457 }14581459 return false;1460}14611462add_filter( 'interge_maps_friendly_name’, ‘intergeo_maps_change_name’ );1463/**1464 * Change notification name.1465 *1466 * @return string New name.1467 */1468function intergeo_maps_change_name() {1469 return 'Intergeo Maps’;1470}14711472add_filter( 'intergeo_themeisle_sdk_subscribe_list’, ‘intergeo_change_subscribe_list’ );1473/**1474 * Alter the subscribe list id.1475 *1476 * @return int The list id.1477 */1478function intergeo_change_subscribe_list() {1479 return 81;1480}14811482require dirname( __FILE__ ) . '/subscribe/subscribe.php’;1483$intergeo_subscribe = new THEMEISLE_SUBSCRIBE( INTERGEO_PLUGIN_NAME );1484$vendor_file = INTERGEO_ABSPATH . '/vendor/autoload.php’;1485if ( is_readable( $vendor_file ) ) {1486 include_once( $vendor_file );1487}14881489add_filter( 'pirate_parrot_log’, 'intergeo_register_parrot’, 10, 1 );1490/**1491 * Register with parrot.1492 */1493function intergeo_register_parrot( $plugins ) {1494 $plugins[] = INTERGEO_PLUGIN_NAME;1495 return $plugins;1496}149714981499add_filter( TI_INTERGEO_PLUGIN_NAME . '_enqueue_recommend’, 'intergeo_upsell_plugins’, 10, 2 );1500/**1501 * Validates the correct screen on which the assets for upsell should be loaded.1502 */1503function intergeo_upsell_plugins( $return, $screen_id ) {1504 return $screen_id === 'media_page_intergeo’;1505}