| 1 | <?php |
|---|
| 2 | /** |
|---|
| 3 | * GeoJSON Shortcode |
|---|
| 4 | * |
|---|
| 5 | * Use with [leaflet-geojson src="..."] |
|---|
| 6 | * |
|---|
| 7 | * @category Shortcode |
|---|
| 8 | * @author Benjamin J DeLong <ben@bozdoz.com> |
|---|
| 9 | */ |
|---|
| 10 | |
|---|
| 11 | // Exit if accessed directly |
|---|
| 12 | if (!defined('ABSPATH')) { |
|---|
| 13 | exit; |
|---|
| 14 | } |
|---|
| 15 | |
|---|
| 16 | require_once LEAFLET_MAP__PLUGIN_DIR . 'shortcodes/class.shortcode.php'; |
|---|
| 17 | |
|---|
| 18 | /** |
|---|
| 19 | * GeoJSON Shortcode Class |
|---|
| 20 | */ |
|---|
| 21 | class Leaflet_Geojson_Shortcode extends Leaflet_Shortcode |
|---|
| 22 | { |
|---|
| 23 | /** |
|---|
| 24 | * Default src for geoJSON |
|---|
| 25 | * |
|---|
| 26 | * @var string $default_src |
|---|
| 27 | */ |
|---|
| 28 | protected $default_src = 'https://gist.githubusercontent.com/bozdoz/064a7101b95a324e8852fe9381ab9a18/raw/03f4f54b13a3a7e256732760a8b679818d9d36fc/map.geojson'; |
|---|
| 29 | |
|---|
| 30 | /** |
|---|
| 31 | * How leaflet renders the src |
|---|
| 32 | * |
|---|
| 33 | * @var string $type |
|---|
| 34 | */ |
|---|
| 35 | protected $type = 'json'; |
|---|
| 36 | |
|---|
| 37 | /** |
|---|
| 38 | * Get Script for Shortcode |
|---|
| 39 | * |
|---|
| 40 | * @param string $atts could be an array |
|---|
| 41 | * @param string $content |
|---|
| 42 | * |
|---|
| 43 | * @return string HTML |
|---|
| 44 | */ |
|---|
| 45 | protected function getHTML($atts='', $content=null) |
|---|
| 46 | { |
|---|
| 47 | if ($atts) { |
|---|
| 48 | extract($atts, EXTR_SKIP); |
|---|
| 49 | } |
|---|
| 50 | |
|---|
| 51 | wp_enqueue_script('leaflet_ajax_geojson_js'); |
|---|
| 52 | |
|---|
| 53 | if ($content) { |
|---|
| 54 | $content = str_replace(array("\r\n", "\n", "\r"), '<br>', $content); |
|---|
| 55 | $content = htmlspecialchars($content); |
|---|
| 56 | } |
|---|
| 57 | |
|---|
| 58 | /* only required field for geojson; accept either src or source */ |
|---|
| 59 | $source = empty($source) ? '' : $source; |
|---|
| 60 | $src = empty($src) ? $this->default_src : $src; |
|---|
| 61 | $src = empty($source) ? $src : $source; |
|---|
| 62 | |
|---|
| 63 | $style_json = $this->LM->get_style_json($atts); |
|---|
| 64 | |
|---|
| 65 | $fitbounds = empty($fitbounds) ? 0 : $fitbounds; |
|---|
| 66 | $fitbounds = filter_var($fitbounds, FILTER_VALIDATE_BOOLEAN); |
|---|
| 67 | $circleMarker = empty($circleMarker) ? 0 : $circleMarker; |
|---|
| 68 | $circleMarker = filter_var($circleMarker, FILTER_VALIDATE_BOOLEAN); |
|---|
| 69 | |
|---|
| 70 | // shortcode content becomes popup text |
|---|
| 71 | $content_text = empty($content) ? '' : $content; |
|---|
| 72 | // alternatively, the popup_text attribute works as popup text |
|---|
| 73 | $popup_text = empty($popup_text) ? '' : $popup_text; |
|---|
| 74 | // choose which one takes priority (content_text) |
|---|
| 75 | $popup_text = empty($content_text) ? $popup_text : $content_text; |
|---|
| 76 | |
|---|
| 77 | $popup_property = empty($popup_property) ? '' : $popup_property; |
|---|
| 78 | |
|---|
| 79 | $popup_text = trim($popup_text); |
|---|
| 80 | |
|---|
| 81 | $table_view = filter_var(empty($table_view) ? 0 : $table_view, FILTER_VALIDATE_INT); |
|---|
| 82 | |
|---|
| 83 | //options of iconUrl feature |
|---|
| 84 | $options = array( |
|---|
| 85 | 'iconUrl' => isset($iconurl) ? $iconurl : null, |
|---|
| 86 | 'iconSize' => isset($iconsize) ? $iconsize : null, |
|---|
| 87 | 'iconAnchor' => isset($iconanchor) ? $iconanchor : null, |
|---|
| 88 | 'popupAnchor' => isset($popupanchor) ? $popupanchor : null, |
|---|
| 89 | 'tooltipAnchor' => isset($tooltipanchor) ? $tooltipanchor : null |
|---|
| 90 | ); |
|---|
| 91 | |
|---|
| 92 | $args = array( |
|---|
| 93 | 'iconUrl' => FILTER_SANITIZE_URL, |
|---|
| 94 | 'iconSize' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, |
|---|
| 95 | 'iconAnchor' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, |
|---|
| 96 | 'popupAnchor' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, |
|---|
| 97 | 'tooltipAnchor' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, |
|---|
| 98 | ); |
|---|
| 99 | |
|---|
| 100 | $options = $this->LM->json_sanitize($options, $args); |
|---|
| 101 | |
|---|
| 102 | ob_start(); |
|---|
| 103 | ?>/*<script>*/ |
|---|
| 104 | var src = '<?php echo htmlspecialchars($src, ENT_QUOTES); ?>'; |
|---|
| 105 | var default_style = <?php echo $style_json; ?>; |
|---|
| 106 | var rewrite_keys = { |
|---|
| 107 | stroke : 'color', |
|---|
| 108 | 'stroke-width' : 'weight', |
|---|
| 109 | 'stroke-opacity' : 'opacity', |
|---|
| 110 | fill : 'fillColor', |
|---|
| 111 | 'fill-opacity' : 'fillOpacity', |
|---|
| 112 | }; |
|---|
| 113 | // htmlspecialchars converts & to "&"; maybe unnecessarily, and maybe 3x |
|---|
| 114 | var ampersandRegex = /&(?:amp;){1,3}/g |
|---|
| 115 | var layer = L.ajaxGeoJson(src.replace(ampersandRegex, '&'), { |
|---|
| 116 | type: '<?php echo $this->type; ?>', |
|---|
| 117 | style : layerStyle, |
|---|
| 118 | onEachFeature : onEachFeature, |
|---|
| 119 | pointToLayer: pointToLayer |
|---|
| 120 | }); |
|---|
| 121 | var fitbounds = <?php echo $fitbounds ? '1' : '0'; ?>; |
|---|
| 122 | var circleMarker = <?php echo $circleMarker ? '1' : '0'; ?>; |
|---|
| 123 | var popup_text = window.WPLeafletMapPlugin.unescape("<?php echo $popup_text; ?>"); |
|---|
| 124 | var popup_property = "<?php echo $popup_property; ?>"; |
|---|
| 125 | var group = window.WPLeafletMapPlugin.getCurrentGroup(); |
|---|
| 126 | var markerOptions = window.WPLeafletMapPlugin.getIconOptions(<?php echo $options; ?>); |
|---|
| 127 | layer.addTo( group ); |
|---|
| 128 | window.WPLeafletMapPlugin.geojsons.push( layer ); |
|---|
| 129 | if (fitbounds) { |
|---|
| 130 | layer.on('ready', function () { |
|---|
| 131 | this.map.fitBounds( this.getBounds() ); |
|---|
| 132 | }); |
|---|
| 133 | } |
|---|
| 134 | function layerStyle (feature) { |
|---|
| 135 | var props = feature.properties || {}; |
|---|
| 136 | var style = {}; |
|---|
| 137 | function camelFun (_, first_letter) { |
|---|
| 138 | return first_letter.toUpperCase(); |
|---|
| 139 | }; |
|---|
| 140 | for (var key in props) { |
|---|
| 141 | if (key.match('-')) { |
|---|
| 142 | var camelcase = key.replace(/-(\w)/, camelFun); |
|---|
| 143 | style[ camelcase ] = props[ key ]; |
|---|
| 144 | } |
|---|
| 145 | // rewrite style keys from geojson.io |
|---|
| 146 | if (rewrite_keys[ key ]) { |
|---|
| 147 | style[ rewrite_keys[ key ] ] = props[ key ]; |
|---|
| 148 | } |
|---|
| 149 | } |
|---|
| 150 | return L.Util.extend(style, default_style); |
|---|
| 151 | } |
|---|
| 152 | function onEachFeature (feature, layer) { |
|---|
| 153 | var props = feature.properties || {}; |
|---|
| 154 | var text; |
|---|
| 155 | if (<?php echo $table_view; ?>) { |
|---|
| 156 | text = window.WPLeafletMapPlugin.propsToTable(props); |
|---|
| 157 | } else { |
|---|
| 158 | text = popup_property |
|---|
| 159 | ? props[ popup_property ] |
|---|
| 160 | : window.WPLeafletMapPlugin.template( |
|---|
| 161 | popup_text, |
|---|
| 162 | feature.properties |
|---|
| 163 | ); |
|---|
| 164 | } |
|---|
| 165 | if (text) { |
|---|
| 166 | layer.bindPopup( text ); |
|---|
| 167 | } |
|---|
| 168 | } |
|---|
| 169 | function pointToLayer (feature, latlng) { |
|---|
| 170 | if (circleMarker) { |
|---|
| 171 | return L.circleMarker(latlng); |
|---|
| 172 | } |
|---|
| 173 | return L.marker(latlng, markerOptions); |
|---|
| 174 | }<?php |
|---|
| 175 | $script = ob_get_clean(); |
|---|
| 176 | |
|---|
| 177 | return $this->wrap_script($script, 'WPLeaflet' . $this->type .'Shortcode'); |
|---|
| 178 | } |
|---|
| 179 | } |
|---|