PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 12.3.2
Jetpack – WP Security, Backup, Speed, & Growth v12.3.2
12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 14.4.2 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 16.2-a.3 16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / extensions / blocks / map / map.php
jetpack / extensions / blocks / map Last commit date
map.php 3 years ago
map.php
243 lines
1 <?php
2 /**
3 * Map block.
4 *
5 * @since 6.8.0
6 *
7 * @package automattic/jetpack
8 */
9
10 namespace Automattic\Jetpack\Extensions\Map;
11
12 use Automattic\Jetpack\Blocks;
13 use Automattic\Jetpack\Status\Host;
14 use Automattic\Jetpack\Tracking;
15 use Jetpack;
16 use Jetpack_Gutenberg;
17 use Jetpack_Mapbox_Helper;
18
19 const FEATURE_NAME = 'map';
20 const BLOCK_NAME = 'jetpack/' . FEATURE_NAME;
21
22 if ( ! class_exists( 'Jetpack_Mapbox_Helper' ) ) {
23 require_once JETPACK__PLUGIN_DIR . '_inc/lib/class-jetpack-mapbox-helper.php';
24 }
25
26 /**
27 * Registers the block for use in Gutenberg
28 * This is done via an action so that we can disable
29 * registration if we need to.
30 */
31 function register_block() {
32 Blocks::jetpack_register_block(
33 BLOCK_NAME,
34 array(
35 'render_callback' => __NAMESPACE__ . '\load_assets',
36 )
37 );
38 }
39 add_action( 'init', __NAMESPACE__ . '\register_block' );
40
41 /**
42 * Record a Tracks event every time the Map block is loaded on WordPress.com and Atomic.
43 *
44 * @param string $access_token_source The Mapbox API access token source.
45 */
46 function wpcom_load_event( $access_token_source ) {
47 if ( 'wpcom' !== $access_token_source ) {
48 return;
49 }
50
51 $event_name = 'map_block_mapbox_wpcom_key_load';
52 if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
53 require_lib( 'tracks/client' );
54 tracks_record_event( wp_get_current_user(), $event_name );
55 } elseif ( ( new Host() )->is_woa_site() && Jetpack::is_connection_ready() ) {
56 $tracking = new Tracking();
57 $tracking->record_user_event( $event_name );
58 }
59 }
60
61 /**
62 * Function to determine which map provider to choose
63 *
64 * @param array $html The block's HTML - needed for the class name.
65 *
66 * @return string The name of the map provider.
67 */
68 function get_map_provider( $html ) {
69 $mapbox_styles = array( 'is-style-terrain' );
70 // return mapbox if html contains one of the mapbox styles
71 foreach ( $mapbox_styles as $style ) {
72 if ( strpos( $html, $style ) !== false ) {
73 return 'mapbox';
74 }
75 }
76
77 // you can override the map provider with a cookie
78 if ( isset( $_COOKIE['map_provider'] ) ) {
79 return sanitize_text_field( wp_unslash( $_COOKIE['map_provider'] ) );
80 }
81
82 // if we don't apply the filters & default to mapbox
83 return apply_filters( 'wpcom_map_block_map_provider', 'mapbox' );
84 }
85
86 /**
87 * Map block registration/dependency declaration.
88 *
89 * @param array $attr Array containing the map block attributes.
90 * @param string $content String containing the map block content.
91 *
92 * @return string
93 */
94 function load_assets( $attr, $content ) {
95 $access_token = Jetpack_Mapbox_Helper::get_access_token();
96 wpcom_load_event( $access_token['source'] );
97
98 if ( Blocks::is_amp_request() ) {
99 static $map_block_counter = array();
100
101 $id = get_the_ID();
102 if ( ! isset( $map_block_counter[ $id ] ) ) {
103 $map_block_counter[ $id ] = 0;
104 }
105 ++$map_block_counter[ $id ];
106
107 $iframe_url = add_query_arg(
108 array(
109 'map-block-counter' => absint( $map_block_counter[ $id ] ),
110 'map-block-post-id' => $id,
111 ),
112 get_permalink()
113 );
114
115 $placeholder = preg_replace( '/(?<=<div\s)/', 'placeholder ', $content );
116
117 return sprintf(
118 '<amp-iframe src="%s" width="%d" height="%d" layout="responsive" allowfullscreen sandbox="allow-scripts">%s</amp-iframe>',
119 esc_url( $iframe_url ),
120 4,
121 3,
122 $placeholder
123 );
124 }
125
126 Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME );
127
128 $map_provider = get_map_provider( $content );
129 if ( $map_provider === 'mapkit' ) {
130 return preg_replace( '/<div /', '<div data-map-provider="mapkit" data-blog-id="' . \Jetpack_Options::get_option( 'id' ) . '" ', $content, 1 );
131 }
132
133 return preg_replace( '/<div /', '<div data-map-provider="mapbox" data-api-key="' . esc_attr( $access_token['key'] ) . '" ', $content, 1 );
134 }
135
136 /**
137 * Render a page containing only a single Map block.
138 */
139 function render_single_block_page() {
140 // phpcs:ignore WordPress.Security.NonceVerification
141 $map_block_counter = isset( $_GET['map-block-counter'] ) ? absint( $_GET['map-block-counter'] ) : null;
142 // phpcs:ignore WordPress.Security.NonceVerification
143 $map_block_post_id = isset( $_GET['map-block-post-id'] ) ? absint( $_GET['map-block-post-id'] ) : null;
144
145 if ( ! $map_block_counter || ! $map_block_post_id ) {
146 return;
147 }
148
149 /* Create an array of all root-level DIVs that are Map Blocks */
150 $post = get_post( $map_block_post_id );
151
152 if ( ! class_exists( 'DOMDocument' ) ) {
153 return;
154 }
155
156 $post_html = new \DOMDocument();
157 /** This filter is already documented in core/wp-includes/post-template.php */
158 $content = apply_filters( 'the_content', $post->post_content );
159
160 /* Suppress warnings */
161 libxml_use_internal_errors( true );
162 @$post_html->loadHTML( $content ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
163 libxml_use_internal_errors( false );
164
165 $xpath = new \DOMXPath( $post_html );
166 $container = $xpath->query( '//div[ contains( @class, "wp-block-jetpack-map" ) ]' )->item( $map_block_counter - 1 );
167
168 /* Check that we have a block matching the counter position */
169 if ( ! $container ) {
170 return;
171 }
172
173 /* Compile scripts and styles */
174 ob_start();
175
176 add_filter( 'jetpack_is_amp_request', '__return_false' );
177
178 Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME );
179 wp_scripts()->do_items();
180 wp_styles()->do_items();
181
182 add_filter( 'jetpack_is_amp_request', '__return_true' );
183
184 $head_content = ob_get_clean();
185
186 /* Put together a new complete document containing only the requested block markup and the scripts/styles needed to render it */
187 $block_markup = $post_html->saveHTML( $container );
188 $access_token = Jetpack_Mapbox_Helper::get_access_token();
189 $page_html = sprintf(
190 '<!DOCTYPE html><head><style>html, body { margin: 0; padding: 0; }</style>%s</head><body>%s</body>',
191 $head_content,
192 preg_replace( '/(?<=<div\s)/', 'data-api-key="' . esc_attr( $access_token['key'] ) . '" ', $block_markup, 1 )
193 );
194 echo $page_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
195 exit;
196 }
197 add_action( 'wp', __NAMESPACE__ . '\render_single_block_page' );
198
199 /**
200 * Helper function to generate the markup of the block in PHP.
201 *
202 * @param Array $points - Array containing geo location points.
203 *
204 * @return string Markup for the jetpack/map block.
205 */
206 function map_block_from_geo_points( $points ) {
207 $map_block_data = array(
208 'points' => $points,
209 'zoom' => 8,
210 'mapCenter' => array(
211 'lng' => $points[0]['coordinates']['longitude'],
212 'lat' => $points[0]['coordinates']['latitude'],
213 ),
214 );
215
216 $list_items = array_map(
217 function ( $point ) {
218 $link = add_query_arg(
219 array(
220 'api' => 1,
221 'query' => $point['coordinates']['latitude'] . ',' . $point['coordinates']['longitude'],
222 ),
223 'https://www.google.com/maps/search/'
224 );
225 return sprintf( '<li><a href="%s">%s</a></li>', esc_url( $link ), $point['title'] );
226 },
227 $points
228 );
229
230 $map_block = '<!-- wp:jetpack/map ' . wp_json_encode( $map_block_data ) . ' -->' . PHP_EOL;
231 $map_block .= sprintf(
232 '<div class="wp-block-jetpack-map" data-map-style="default" data-map-details="true" data-points="%1$s" data-zoom="%2$d" data-map-center="%3$s" data-marker-color="red" data-show-fullscreen-button="true">',
233 esc_html( wp_json_encode( $map_block_data['points'] ) ),
234 (int) $map_block_data['zoom'],
235 esc_html( wp_json_encode( $map_block_data['mapCenter'] ) )
236 );
237 $map_block .= '<ul>' . implode( "\n", $list_items ) . '</ul>';
238 $map_block .= '</div>' . PHP_EOL;
239 $map_block .= '<!-- /wp:jetpack/map -->';
240
241 return $map_block;
242 }
243