PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 14.8.1
Jetpack – WP Security, Backup, Speed, & Growth v14.8.1
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 1 year ago
map.php
245 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 if ( ! class_exists( 'Jetpack_Mapbox_Helper' ) ) {
20 require_once JETPACK__PLUGIN_DIR . '_inc/lib/class-jetpack-mapbox-helper.php';
21 }
22
23 /**
24 * Registers the block for use in Gutenberg
25 * This is done via an action so that we can disable
26 * registration if we need to.
27 */
28 function register_block() {
29 Blocks::jetpack_register_block(
30 __DIR__,
31 array(
32 'render_callback' => __NAMESPACE__ . '\load_assets',
33 )
34 );
35 }
36 add_action( 'init', __NAMESPACE__ . '\register_block' );
37
38 /**
39 * Record a Tracks event every time the Map block is loaded on WordPress.com and Atomic.
40 *
41 * @param string $access_token_source The Mapbox API access token source.
42 */
43 function wpcom_load_event( $access_token_source ) {
44 if ( 'wpcom' !== $access_token_source ) {
45 return;
46 }
47
48 $event_name = 'map_block_mapbox_wpcom_key_load';
49 if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
50 require_lib( 'tracks/client' );
51 tracks_record_event( wp_get_current_user(), $event_name );
52 } elseif ( ( new Host() )->is_woa_site() && Jetpack::is_connection_ready() ) {
53 $tracking = new Tracking();
54 $tracking->record_user_event( $event_name );
55 }
56 }
57
58 /**
59 * Function to determine which map provider to choose
60 *
61 * @param array $html The block's HTML - needed for the class name.
62 *
63 * @return string The name of the map provider.
64 */
65 function get_map_provider( $html ) {
66 $mapbox_styles = array( 'is-style-terrain' );
67 // return mapbox if html contains one of the mapbox styles
68 foreach ( $mapbox_styles as $style ) {
69 if ( str_contains( $html, $style ) ) {
70 return 'mapbox';
71 }
72 }
73
74 // you can override the map provider with a cookie
75 if ( isset( $_COOKIE['map_provider'] ) ) {
76 return sanitize_text_field( wp_unslash( $_COOKIE['map_provider'] ) );
77 }
78
79 // if we don't apply the filters & default to mapbox
80 return apply_filters( 'wpcom_map_block_map_provider', 'mapbox' );
81 }
82
83 /**
84 * Map block registration/dependency declaration.
85 *
86 * @param array $attr Array containing the map block attributes.
87 * @param string $content String containing the map block content.
88 *
89 * @return string
90 */
91 function load_assets( $attr, $content ) {
92 $access_token = Jetpack_Mapbox_Helper::get_access_token();
93 wpcom_load_event( $access_token['source'] );
94
95 if ( Blocks::is_amp_request() ) {
96 static $map_block_counter = array();
97
98 $id = get_the_ID();
99 if ( ! isset( $map_block_counter[ $id ] ) ) {
100 $map_block_counter[ $id ] = 0;
101 }
102 ++$map_block_counter[ $id ];
103
104 $iframe_url = add_query_arg(
105 array(
106 'map-block-counter' => absint( $map_block_counter[ $id ] ),
107 'map-block-post-id' => $id,
108 ),
109 get_permalink()
110 );
111
112 $placeholder = preg_replace( '/(?<=<div\s)/', 'placeholder ', $content );
113
114 return sprintf(
115 '<amp-iframe src="%s" width="%d" height="%d" layout="responsive" allowfullscreen sandbox="allow-scripts">%s</amp-iframe>',
116 esc_url( $iframe_url ),
117 4,
118 3,
119 $placeholder
120 );
121 }
122
123 Jetpack_Gutenberg::load_assets_as_required( __DIR__ );
124
125 $map_provider = get_map_provider( $content );
126 if ( $map_provider === 'mapkit' ) {
127 return preg_replace( '/<div /', '<div data-map-provider="mapkit" data-api-key="' . esc_attr( $access_token['key'] ) . '" data-blog-id="' . \Jetpack_Options::get_option( 'id' ) . '" ', $content, 1 );
128 }
129
130 return preg_replace( '/<div /', '<div data-map-provider="mapbox" data-api-key="' . esc_attr( $access_token['key'] ) . '" ', $content, 1 );
131 }
132
133 /**
134 * Render a page containing only a single Map block.
135 */
136 function render_single_block_page() {
137 // phpcs:ignore WordPress.Security.NonceVerification
138 $map_block_counter = isset( $_GET['map-block-counter'] ) ? absint( $_GET['map-block-counter'] ) : null;
139 // phpcs:ignore WordPress.Security.NonceVerification
140 $map_block_post_id = isset( $_GET['map-block-post-id'] ) ? absint( $_GET['map-block-post-id'] ) : null;
141
142 if ( ! $map_block_counter || ! $map_block_post_id ) {
143 return;
144 }
145
146 /* Create an array of all root-level DIVs that are Map Blocks */
147 $post = get_post( $map_block_post_id );
148
149 if ( ! class_exists( 'DOMDocument' ) ) {
150 return;
151 }
152
153 $post_html = new \DOMDocument();
154 /** This filter is already documented in core/wp-includes/post-template.php */
155 $content = apply_filters( 'the_content', $post->post_content );
156
157 // Return early if empty to prevent DOMDocument::loadHTML fatal.
158 if ( empty( $content ) ) {
159 return;
160 }
161
162 /* Suppress warnings */
163 libxml_use_internal_errors( true );
164 @$post_html->loadHTML( $content ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
165 libxml_use_internal_errors( false );
166
167 $xpath = new \DOMXPath( $post_html );
168 $container = $xpath->query( '//div[ contains( @class, "wp-block-jetpack-map" ) ]' )->item( $map_block_counter - 1 );
169
170 /* Check that we have a block matching the counter position */
171 if ( ! $container ) {
172 return;
173 }
174
175 /* Compile scripts and styles */
176 ob_start();
177
178 add_filter( 'jetpack_is_amp_request', '__return_false' );
179
180 Jetpack_Gutenberg::load_assets_as_required( __DIR__ );
181 wp_scripts()->do_items();
182 wp_styles()->do_items();
183
184 add_filter( 'jetpack_is_amp_request', '__return_true' );
185
186 $head_content = ob_get_clean();
187
188 /* Put together a new complete document containing only the requested block markup and the scripts/styles needed to render it */
189 $block_markup = $post_html->saveHTML( $container );
190 $access_token = Jetpack_Mapbox_Helper::get_access_token();
191 $page_html = sprintf(
192 '<!DOCTYPE html><head><style>html, body { margin: 0; padding: 0; }</style>%s</head><body>%s</body>',
193 $head_content,
194 preg_replace( '/(?<=<div\s)/', 'data-api-key="' . esc_attr( $access_token['key'] ) . '" ', $block_markup, 1 )
195 );
196 echo $page_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
197 exit( 0 );
198 }
199 add_action( 'wp', __NAMESPACE__ . '\render_single_block_page' );
200
201 /**
202 * Helper function to generate the markup of the block in PHP.
203 *
204 * @param Array $points - Array containing geo location points.
205 *
206 * @return string Markup for the jetpack/map block.
207 */
208 function map_block_from_geo_points( $points ) {
209 $map_block_data = array(
210 'points' => $points,
211 'zoom' => 8,
212 'mapCenter' => array(
213 'lng' => $points[0]['coordinates']['longitude'],
214 'lat' => $points[0]['coordinates']['latitude'],
215 ),
216 );
217
218 $list_items = array_map(
219 function ( $point ) {
220 $link = add_query_arg(
221 array(
222 'api' => 1,
223 'query' => $point['coordinates']['latitude'] . ',' . $point['coordinates']['longitude'],
224 ),
225 'https://www.google.com/maps/search/'
226 );
227 return sprintf( '<li><a href="%s">%s</a></li>', esc_url( $link ), $point['title'] );
228 },
229 $points
230 );
231
232 $map_block = '<!-- wp:jetpack/map ' . wp_json_encode( $map_block_data ) . ' -->' . PHP_EOL;
233 $map_block .= sprintf(
234 '<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">',
235 esc_html( wp_json_encode( $map_block_data['points'] ) ),
236 (int) $map_block_data['zoom'],
237 esc_html( wp_json_encode( $map_block_data['mapCenter'] ) )
238 );
239 $map_block .= '<ul>' . implode( "\n", $list_items ) . '</ul>';
240 $map_block .= '</div>' . PHP_EOL;
241 $map_block .= '<!-- /wp:jetpack/map -->';
242
243 return $map_block;
244 }
245