__( 'Site default', 'maps-by-deltabreen' ), 'auto' => __( 'Light or dark, as the visitor\'s device is', 'maps-by-deltabreen' ), ); foreach ( DELTABREEN_MAPS_LOOKS as $look ) { $out[ $look ] = ucfirst( $look ); } return $out; } /** The places from posts a site chose to carry them. */ protected function posts_options() { $out = array( '' => __( 'None', 'maps-by-deltabreen' ) ); foreach ( deltabreen_maps_place_types() as $type ) { $object = get_post_type_object( $type ); $out[ $type ] = $object ? $object->labels->name : $type; } return $out; } /** The look and behaviour every map shares, each the site's default until changed. */ protected function feel_controls() { $default = array( '' => __( 'Site default', 'maps-by-deltabreen' ) ); $this->add_control( 'style', array( 'label' => __( 'Look', 'maps-by-deltabreen' ), 'type' => Controls_Manager::SELECT, 'options' => $this->look_options(), 'default' => '' ) ); $this->add_control( 'height', array( 'label' => __( 'Height', 'maps-by-deltabreen' ), 'type' => Controls_Manager::TEXT, 'placeholder' => '400px', 'description' => __( 'For example 400px or 60vh; empty for the site default.', 'maps-by-deltabreen' ) ) ); $this->add_control( 'directions', array( 'label' => __( 'Directions', 'maps-by-deltabreen' ), 'type' => Controls_Manager::SELECT, 'default' => '', 'options' => $default + array( 'auto' => __( 'The visitor\'s own maps app', 'maps-by-deltabreen' ), 'google' => __( 'Always Google Maps', 'maps-by-deltabreen' ), 'apple' => __( 'Always Apple Maps', 'maps-by-deltabreen' ), 'off' => __( 'No Directions link', 'maps-by-deltabreen' ), 'route' => __( 'Drawn on this page (each route uses one search)', 'maps-by-deltabreen' ) ) ) ); $this->add_control( 'consent', array( 'label' => __( 'Ask before showing the map', 'maps-by-deltabreen' ), 'type' => Controls_Manager::SELECT, 'default' => '', 'options' => $default + array( 'click' => __( 'Ask first', 'maps-by-deltabreen' ), 'false' => __( 'Show it at once', 'maps-by-deltabreen' ) ) ) ); $this->add_control( 'controls', array( 'label' => __( 'Buttons', 'maps-by-deltabreen' ), 'type' => Controls_Manager::SELECT, 'default' => '', 'options' => $default + array( 'zoom,fullscreen' => __( 'Zoom and full screen', 'maps-by-deltabreen' ), 'zoom' => __( 'Zoom only', 'maps-by-deltabreen' ), 'zoom,fullscreen,scale' => __( 'Zoom, full screen and a distance scale', 'maps-by-deltabreen' ), 'none' => __( 'None', 'maps-by-deltabreen' ) ) ) ); $this->add_control( 'gestures', array( 'label' => __( 'Scrolling past the map', 'maps-by-deltabreen' ), 'type' => Controls_Manager::SELECT, 'default' => '', 'options' => $default + array( 'auto' => __( 'Two fingers or Ctrl move the map, so the page scrolls past it', 'maps-by-deltabreen' ), 'greedy' => __( 'One finger or the mouse wheel moves the map', 'maps-by-deltabreen' ), 'off' => __( 'The map stays still', 'maps-by-deltabreen' ) ) ) ); $this->add_control( 'theme', array( 'label' => __( 'Panels and popups', 'maps-by-deltabreen' ), 'type' => Controls_Manager::SELECT, 'default' => '', 'options' => $default + array( 'auto' => __( 'Light or dark, as the visitor\'s device is', 'maps-by-deltabreen' ), 'light' => __( 'Light', 'maps-by-deltabreen' ), 'dark' => __( 'Dark', 'maps-by-deltabreen' ) ) ) ); $this->add_control( 'accent', array( 'label' => __( 'Accent colour', 'maps-by-deltabreen' ), 'type' => Controls_Manager::COLOR ) ); } /** The settings as the shortcode's attributes, empty ones left to the site's defaults. */ protected function atts( $keys ) { $s = $this->get_settings_for_display(); $out = array(); foreach ( $keys as $key ) { $v = $s[ $key ] ?? ''; if ( 'yes' === $v ) { $v = 'true'; } if ( is_scalar( $v ) && '' !== (string) $v ) { $out[ $key ] = (string) $v; } } return $out; } /** In Elementor's editor a map waits behind "Show map", so editing never counts a load. */ protected function editing() { return class_exists( '\Elementor\Plugin' ) && ( \Elementor\Plugin::$instance->editor->is_edit_mode() || \Elementor\Plugin::$instance->preview->is_preview_mode() ); } /** The element, with a word to the editor while editing. */ protected function output( $html ) { if ( $this->editing() ) { echo '

' . esc_html__( 'Press Show map to preview it: a preview counts one map load. The page shows the map as set.', 'maps-by-deltabreen' ) . '

'; } echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- every attribute is escaped where the element is built. } } /** A map with pins: the site's locations, places from its posts, a list, a search box and a file. */ class Deltabreen_Maps_Elementor_Map extends Deltabreen_Maps_Elementor_Widget { public function get_name() { return 'deltabreen-map'; } public function get_title() { return __( 'Map (Maps by DeltaBreen)', 'maps-by-deltabreen' ); } public function get_icon() { return 'eicon-google-maps'; } public function get_keywords() { return array( 'map', 'pins', 'locations', 'markers', 'openstreetmap' ); } protected function register_controls() { $sources = array( '' => __( 'None', 'maps-by-deltabreen' ), 'all' => __( 'All my locations', 'maps-by-deltabreen' ), ); foreach ( deltabreen_maps_categories() as $term ) { /* translators: %s: a location category's name. */ $sources[ $term->slug ] = sprintf( __( 'Category: %s', 'maps-by-deltabreen' ), $term->name ); } $this->start_controls_section( 'map', array( 'label' => __( 'Map', 'maps-by-deltabreen' ) ) ); $this->add_control( 'map', array( 'label' => __( 'A map from your dashboard', 'maps-by-deltabreen' ), 'type' => Controls_Manager::TEXT, 'placeholder' => __( 'The map\'s address or id', 'maps-by-deltabreen' ), 'description' => __( 'Paste it from Maps in your Maps by DeltaBreen dashboard. Its pins, look and settings come from there, and edits saved there show on this page within a minute. Leave it empty to make the map here.', 'maps-by-deltabreen' ) ) ); $this->add_control( 'locations', array( 'label' => __( 'Also show my map locations', 'maps-by-deltabreen' ), 'type' => Controls_Manager::SELECT, 'options' => $sources, 'default' => 'all' ) ); $this->add_control( 'posts', array( 'label' => __( 'Also show places from your posts', 'maps-by-deltabreen' ), 'type' => Controls_Manager::SELECT, 'options' => $this->posts_options(), 'default' => '' ) ); $this->add_control( 'center', array( 'label' => __( 'Centre (longitude, latitude)', 'maps-by-deltabreen' ), 'type' => Controls_Manager::TEXT, 'placeholder' => '-6.26,53.35', 'description' => __( 'For example -6.26, 53.35. Leave empty to fit the map to its pins.', 'maps-by-deltabreen' ) ) ); $this->add_control( 'zoom', array( 'label' => __( 'Zoom', 'maps-by-deltabreen' ), 'type' => Controls_Manager::NUMBER, 'min' => 0, 'max' => 22, 'default' => 13 ) ); $this->add_control( 'marker', array( 'label' => __( 'Marker at the centre', 'maps-by-deltabreen' ), 'type' => Controls_Manager::SWITCHER, 'description' => __( 'Only when the map has no pins.', 'maps-by-deltabreen' ) ) ); $this->end_controls_section(); $this->start_controls_section( 'more', array( 'label' => __( 'More options', 'maps-by-deltabreen' ) ) ); $this->add_control( 'list', array( 'label' => __( 'A list of the pins', 'maps-by-deltabreen' ), 'type' => Controls_Manager::SELECT, 'default' => '', 'options' => array( '' => __( 'None', 'maps-by-deltabreen' ), 'left' => __( 'On the left', 'maps-by-deltabreen' ), 'right' => __( 'On the right', 'maps-by-deltabreen' ), 'below' => __( 'Below the map', 'maps-by-deltabreen' ) ) ) ); $this->add_control( 'filter', array( 'label' => __( 'Category buttons over the map', 'maps-by-deltabreen' ), 'type' => Controls_Manager::SWITCHER ) ); $this->add_control( 'search', array( 'label' => __( 'A search box on the map', 'maps-by-deltabreen' ), 'type' => Controls_Manager::SWITCHER ) ); $this->add_control( 'file', array( 'label' => __( 'A trail or areas from a file', 'maps-by-deltabreen' ), 'type' => Controls_Manager::TEXT, 'placeholder' => 'https://…/trail.gpx' ) ); $this->feel_controls(); $this->end_controls_section(); } protected function render() { $atts = $this->atts( array( 'locations', 'posts', 'center', 'zoom', 'marker', 'list', 'filter', 'search', 'file', 'style', 'height', 'directions', 'consent', 'controls', 'gestures', 'theme', 'accent' ) ); if ( isset( $atts['marker'] ) ) { $atts['marker'] = 'center'; } // A map from the dashboard brings its own pins and settings: only its height, and asking first, go with it. $saved = deltabreen_maps_clean_map( $this->get_settings_for_display( 'map' ) ); if ( '' !== $saved ) { $atts = array_intersect_key( $atts, array( 'height' => true, 'consent' => true ) ) + array( 'map' => $saved ); } if ( $this->editing() ) { $atts['consent'] = 'click'; $atts['lazy'] = 'false'; } $this->output( deltabreen_maps_render( $atts ) ); } } /** A store locator of the site's locations, and places from its posts when asked. */ class Deltabreen_Maps_Elementor_Locator extends Deltabreen_Maps_Elementor_Widget { public function get_name() { return 'deltabreen-store-locator'; } public function get_title() { return __( 'Store locator (Maps by DeltaBreen)', 'maps-by-deltabreen' ); } public function get_icon() { return 'eicon-search'; } public function get_keywords() { return array( 'store locator', 'map', 'branches', 'dealers', 'locations' ); } protected function register_controls() { $cats = array( '' => __( 'All my locations', 'maps-by-deltabreen' ) ); foreach ( deltabreen_maps_categories() as $term ) { $cats[ $term->slug ] = $term->name; } $this->start_controls_section( 'locator', array( 'label' => __( 'Store locator', 'maps-by-deltabreen' ) ) ); $this->add_control( 'category', array( 'label' => __( 'Locations', 'maps-by-deltabreen' ), 'type' => Controls_Manager::SELECT, 'options' => $cats, 'default' => '' ) ); $this->add_control( 'posts', array( 'label' => __( 'Also show places from your posts', 'maps-by-deltabreen' ), 'type' => Controls_Manager::SELECT, 'options' => $this->posts_options(), 'default' => '' ) ); $this->add_control( 'radius', array( 'label' => __( 'Starting radius', 'maps-by-deltabreen' ), 'type' => Controls_Manager::NUMBER, 'min' => 1, 'max' => 1000, 'default' => 25 ) ); $this->add_control( 'units', array( 'label' => __( 'Distances in', 'maps-by-deltabreen' ), 'type' => Controls_Manager::SELECT, 'default' => '', 'options' => array( '' => __( 'Site default', 'maps-by-deltabreen' ), 'km' => __( 'Kilometres', 'maps-by-deltabreen' ), 'mi' => __( 'Miles', 'maps-by-deltabreen' ) ) ) ); $this->end_controls_section(); $this->start_controls_section( 'more', array( 'label' => __( 'More options', 'maps-by-deltabreen' ) ) ); $this->feel_controls(); $this->end_controls_section(); } protected function render() { $atts = $this->atts( array( 'category', 'posts', 'radius', 'units', 'style', 'height', 'directions', 'consent', 'controls', 'gestures', 'theme', 'accent' ) ); if ( $this->editing() ) { $atts['consent'] = 'click'; $atts['lazy'] = 'false'; } $this->output( deltabreen_maps_render_locator( $atts ) ); } }