PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 12.9.5
Jetpack – WP Security, Backup, Speed, & Growth v12.9.5
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 2 years ago
map.php
240 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-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 /* Suppress warnings */
158 libxml_use_internal_errors( true );
159 @$post_html->loadHTML( $content ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
160 libxml_use_internal_errors( false );
161
162 $xpath = new \DOMXPath( $post_html );
163 $container = $xpath->query( '//div[ contains( @class, "wp-block-jetpack-map" ) ]' )->item( $map_block_counter - 1 );
164
165 /* Check that we have a block matching the counter position */
166 if ( ! $container ) {
167 return;
168 }
169
170 /* Compile scripts and styles */
171 ob_start();
172
173 add_filter( 'jetpack_is_amp_request', '__return_false' );
174
175 Jetpack_Gutenberg::load_assets_as_required( __DIR__ );
176 wp_scripts()->do_items();
177 wp_styles()->do_items();
178
179 add_filter( 'jetpack_is_amp_request', '__return_true' );
180
181 $head_content = ob_get_clean();
182
183 /* Put together a new complete document containing only the requested block markup and the scripts/styles needed to render it */
184 $block_markup = $post_html->saveHTML( $container );
185 $access_token = Jetpack_Mapbox_Helper::get_access_token();
186 $page_html = sprintf(
187 '<!DOCTYPE html><head><style>html, body { margin: 0; padding: 0; }</style>%s</head><body>%s</body>',
188 $head_content,
189 preg_replace( '/(?<=<div\s)/', 'data-api-key="' . esc_attr( $access_token['key'] ) . '" ', $block_markup, 1 )
190 );
191 echo $page_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
192 exit;
193 }
194 add_action( 'wp', __NAMESPACE__ . '\render_single_block_page' );
195
196 /**
197 * Helper function to generate the markup of the block in PHP.
198 *
199 * @param Array $points - Array containing geo location points.
200 *
201 * @return string Markup for the jetpack/map block.
202 */
203 function map_block_from_geo_points( $points ) {
204 $map_block_data = array(
205 'points' => $points,
206 'zoom' => 8,
207 'mapCenter' => array(
208 'lng' => $points[0]['coordinates']['longitude'],
209 'lat' => $points[0]['coordinates']['latitude'],
210 ),
211 );
212
213 $list_items = array_map(
214 function ( $point ) {
215 $link = add_query_arg(
216 array(
217 'api' => 1,
218 'query' => $point['coordinates']['latitude'] . ',' . $point['coordinates']['longitude'],
219 ),
220 'https://www.google.com/maps/search/'
221 );
222 return sprintf( '<li><a href="%s">%s</a></li>', esc_url( $link ), $point['title'] );
223 },
224 $points
225 );
226
227 $map_block = '<!-- wp:jetpack/map ' . wp_json_encode( $map_block_data ) . ' -->' . PHP_EOL;
228 $map_block .= sprintf(
229 '<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">',
230 esc_html( wp_json_encode( $map_block_data['points'] ) ),
231 (int) $map_block_data['zoom'],
232 esc_html( wp_json_encode( $map_block_data['mapCenter'] ) )
233 );
234 $map_block .= '<ul>' . implode( "\n", $list_items ) . '</ul>';
235 $map_block .= '</div>' . PHP_EOL;
236 $map_block .= '<!-- /wp:jetpack/map -->';
237
238 return $map_block;
239 }
240