assets_enqueued) { return; } wp_enqueue_style( 'mximap-public', MXIMAP_PLUGIN_URL . 'public/css/mximap-public.css', array(), MXIMAP_VERSION ); wp_enqueue_script( 'mximap-public', MXIMAP_PLUGIN_URL . 'public/js/mximap-public.js', array(), MXIMAP_VERSION, true ); $this->assets_enqueued = true; } /** * Keep a late/fragment render styled after the normal asset output has run. * Return markup with the shortcode so fragment/cache consumers retain it. */ private function render_late_assets() { if (!did_action('wp_print_footer_scripts') && !wp_doing_ajax()) { return ''; } ob_start(); if (!wp_style_is('mximap-public', 'done')) { wp_print_styles(array('mximap-public')); } if (!wp_script_is('mximap-public', 'done')) { wp_print_scripts(array('mximap-public')); } return ob_get_clean(); } /** * Render the shortcode */ public function render_shortcode($atts) { $atts = shortcode_atts(array( 'id' => 0, ), $atts, 'mximap_map'); $map_id = absint($atts['id']); // Validate map exists if (!$map_id) { return $this->render_error(__('No map ID specified.', 'max-interactive-maps')); } $map_post = get_post($map_id); if (!$map_post || MXIMAP_Post_Type::POST_TYPE !== $map_post->post_type) { return $this->render_error(__('Map not found.', 'max-interactive-maps')); } if ('publish' !== $map_post->post_status) { return $this->render_error(__('This map is not published.', 'max-interactive-maps')); } // Keep the first legacy ID; suffix only later valid renders of this map. $render_count = ($this->map_render_counts[$map_id] ?? 0) + 1; $this->map_render_counts[$map_id] = $render_count; $map_dom_id = 'mximap-map-' . $map_id; if ($render_count > 1) { $map_dom_id .= '-instance-' . $render_count; } // Enqueue assets $this->enqueue_assets(); $late_assets = $this->render_late_assets(); // Get map data $pins = get_post_meta($map_id, '_mximap_pins', true); $pins = MXIMAP_Post_Type::readable_pins($pins); $settings = get_post_meta($map_id, '_mximap_settings', true); $settings = MXIMAP_Post_Type::resolve_settings($settings); $map_title = wp_strip_all_tags(get_the_title($map_post)); /* translators: %s: map title. */ $map_label = $map_title ? sprintf(__('Interactive map: %s', 'max-interactive-maps'), $map_title) : __('Interactive map', 'max-interactive-maps'); // Build output ob_start(); ?>
get_world_map_svg(); ?>
render_pin($pin); ?>
get_pin_icon($style); $tag = $url ? 'a' : 'span'; // Build label styles $label_styles = array('color: ' . esc_attr($color)); // Font size mapping $font_sizes = array( 'small' => '10px', 'medium' => '12px', 'large' => '14px' ); $label_styles[] = 'font-size: ' . ($font_sizes[$font_size] ?? '12px'); // Font style mapping switch ($font_style) { case 'bold': $label_styles[] = 'font-weight: 700'; break; case 'italic': $label_styles[] = 'font-style: italic'; break; case 'uppercase': $label_styles[] = 'text-transform: uppercase'; $label_styles[] = 'letter-spacing: 0.5px'; break; default: $label_styles[] = 'font-weight: 500'; } $label_style_attr = implode('; ', $label_styles); // Build the pin HTML with proper escaping $pin_classes = 'mximap-pin mximap-pin-' . esc_attr($style); if ($label) { $pin_classes .= ' mximap-pin-has-label'; } $pin_style = sprintf( 'left: %s%%; top: %s%%; --pin-color: %s;', esc_attr($x), esc_attr($y), esc_attr($color) ); $html = '<' . esc_attr($tag); $html .= ' class="' . esc_attr($pin_classes) . '"'; $html .= ' style="' . esc_attr($pin_style) . '"'; if ($url) { $html .= ' href="' . esc_url($url) . '"'; } else { $html .= ' role="img"'; } if ($label) { $html .= ' title="' . esc_attr($label) . '"'; } /* translators: %s: destination URL of an unlabeled location link. */ $accessible_label = '' !== $label ? $label : ($url ? sprintf(__('View location: %s', 'max-interactive-maps'), $url) : __('Location marker', 'max-interactive-maps')); $html .= ' aria-label="' . esc_attr($accessible_label) . '">'; // Pin icon - SVG is hardcoded and safe $html .= ''; // Label if present if ($label) { $html .= '' . esc_html($label) . ''; } $html .= ''; return $html; } /** * Get SVG icon for pin style */ private function get_pin_icon($style) { $icons = array( 'dot' => '', 'teardrop' => '', 'star' => '', 'flag' => '', 'pushpin' => '', ); return str_replace(''; } /** * Render error message */ private function render_error($message) { if (current_user_can('edit_posts')) { return '
' . esc_html($message) . '
'; } return ''; } }