PageRenderTime 28ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/jetpack/extensions/blocks/map/map.php

https://gitlab.com/chernushov881/charity-fund
PHP | 213 lines | 136 code | 34 blank | 43 comment | 11 complexity | 9f4a13197d1604c26d16b76d9822e8a9 MD5 | raw file
  1. <?php
  2. /**
  3. * Map block.
  4. *
  5. * @since 6.8.0
  6. *
  7. * @package automattic/jetpack
  8. */
  9. namespace Automattic\Jetpack\Extensions\Map;
  10. use Automattic\Jetpack\Blocks;
  11. use Automattic\Jetpack\Status\Host;
  12. use Automattic\Jetpack\Tracking;
  13. use Jetpack;
  14. use Jetpack_Gutenberg;
  15. use Jetpack_Mapbox_Helper;
  16. const FEATURE_NAME = 'map';
  17. const BLOCK_NAME = 'jetpack/' . FEATURE_NAME;
  18. if ( ! class_exists( 'Jetpack_Mapbox_Helper' ) ) {
  19. \jetpack_require_lib( 'class-jetpack-mapbox-helper' );
  20. }
  21. /**
  22. * Registers the block for use in Gutenberg
  23. * This is done via an action so that we can disable
  24. * registration if we need to.
  25. */
  26. function register_block() {
  27. Blocks::jetpack_register_block(
  28. BLOCK_NAME,
  29. array(
  30. 'render_callback' => __NAMESPACE__ . '\load_assets',
  31. )
  32. );
  33. }
  34. add_action( 'init', __NAMESPACE__ . '\register_block' );
  35. /**
  36. * Record a Tracks event every time the Map block is loaded on WordPress.com and Atomic.
  37. *
  38. * @param string $access_token_source The Mapbox API access token source.
  39. */
  40. function wpcom_load_event( $access_token_source ) {
  41. if ( 'wpcom' !== $access_token_source ) {
  42. return;
  43. }
  44. $event_name = 'map_block_mapbox_wpcom_key_load';
  45. if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
  46. jetpack_require_lib( 'tracks/client' );
  47. tracks_record_event( wp_get_current_user(), $event_name );
  48. } elseif ( ( new Host() )->is_woa_site() && Jetpack::is_connection_ready() ) {
  49. $tracking = new Tracking();
  50. $tracking->record_user_event( $event_name );
  51. }
  52. }
  53. /**
  54. * Map block registration/dependency declaration.
  55. *
  56. * @param array $attr Array containing the map block attributes.
  57. * @param string $content String containing the map block content.
  58. *
  59. * @return string
  60. */
  61. function load_assets( $attr, $content ) {
  62. $access_token = Jetpack_Mapbox_Helper::get_access_token();
  63. wpcom_load_event( $access_token['source'] );
  64. if ( Blocks::is_amp_request() ) {
  65. static $map_block_counter = array();
  66. $id = get_the_ID();
  67. if ( ! isset( $map_block_counter[ $id ] ) ) {
  68. $map_block_counter[ $id ] = 0;
  69. }
  70. $map_block_counter[ $id ]++;
  71. $iframe_url = add_query_arg(
  72. array(
  73. 'map-block-counter' => absint( $map_block_counter[ $id ] ),
  74. 'map-block-post-id' => $id,
  75. ),
  76. get_permalink()
  77. );
  78. $placeholder = preg_replace( '/(?<=<div\s)/', 'placeholder ', $content );
  79. return sprintf(
  80. '<amp-iframe src="%s" width="%d" height="%d" layout="responsive" allowfullscreen sandbox="allow-scripts">%s</amp-iframe>',
  81. esc_url( $iframe_url ),
  82. 4,
  83. 3,
  84. $placeholder
  85. );
  86. }
  87. Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME );
  88. return preg_replace( '/<div /', '<div data-api-key="' . esc_attr( $access_token['key'] ) . '" ', $content, 1 );
  89. }
  90. /**
  91. * Render a page containing only a single Map block.
  92. */
  93. function render_single_block_page() {
  94. // phpcs:ignore WordPress.Security.NonceVerification
  95. $map_block_counter = isset( $_GET, $_GET['map-block-counter'] ) ? absint( $_GET['map-block-counter'] ) : null;
  96. // phpcs:ignore WordPress.Security.NonceVerification
  97. $map_block_post_id = isset( $_GET, $_GET['map-block-post-id'] ) ? absint( $_GET['map-block-post-id'] ) : null;
  98. if ( ! $map_block_counter || ! $map_block_post_id ) {
  99. return;
  100. }
  101. /* Create an array of all root-level DIVs that are Map Blocks */
  102. $post = get_post( $map_block_post_id );
  103. if ( ! class_exists( 'DOMDocument' ) ) {
  104. return;
  105. }
  106. $post_html = new \DOMDocument();
  107. /** This filter is already documented in core/wp-includes/post-template.php */
  108. $content = apply_filters( 'the_content', $post->post_content );
  109. /* Suppress warnings */
  110. libxml_use_internal_errors( true );
  111. @$post_html->loadHTML( $content ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
  112. libxml_use_internal_errors( false );
  113. $xpath = new \DOMXPath( $post_html );
  114. $container = $xpath->query( '//div[ contains( @class, "wp-block-jetpack-map" ) ]' )->item( $map_block_counter - 1 );
  115. /* Check that we have a block matching the counter position */
  116. if ( ! $container ) {
  117. return;
  118. }
  119. /* Compile scripts and styles */
  120. ob_start();
  121. add_filter( 'jetpack_is_amp_request', '__return_false' );
  122. Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME );
  123. wp_scripts()->do_items();
  124. wp_styles()->do_items();
  125. add_filter( 'jetpack_is_amp_request', '__return_true' );
  126. $head_content = ob_get_clean();
  127. /* Put together a new complete document containing only the requested block markup and the scripts/styles needed to render it */
  128. $block_markup = $post_html->saveHTML( $container );
  129. $access_token = Jetpack_Mapbox_Helper::get_access_token();
  130. $page_html = sprintf(
  131. '<!DOCTYPE html><head><style>html, body { margin: 0; padding: 0; }</style>%s</head><body>%s</body>',
  132. $head_content,
  133. preg_replace( '/(?<=<div\s)/', 'data-api-key="' . esc_attr( $access_token['key'] ) . '" ', $block_markup, 1 )
  134. );
  135. echo $page_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
  136. exit;
  137. }
  138. add_action( 'wp', __NAMESPACE__ . '\render_single_block_page' );
  139. /**
  140. * Helper function to generate the markup of the block in PHP.
  141. *
  142. * @param Array $points - Array containing geo location points.
  143. *
  144. * @return string Markup for the jetpack/map block.
  145. */
  146. function map_block_from_geo_points( $points ) {
  147. $map_block_data = array(
  148. 'points' => $points,
  149. 'zoom' => 8,
  150. 'mapCenter' => array(
  151. 'lng' => $points[0]['coordinates']['longitude'],
  152. 'lat' => $points[0]['coordinates']['latitude'],
  153. ),
  154. );
  155. $list_items = array_map(
  156. function ( $point ) {
  157. $link = add_query_arg(
  158. array(
  159. 'api' => 1,
  160. 'query' => $point['coordinates']['latitude'] . ',' . $point['coordinates']['longitude'],
  161. ),
  162. 'https://www.google.com/maps/search/'
  163. );
  164. return sprintf( '<li><a href="%s">%s</a></li>', esc_url( $link ), $point['title'] );
  165. },
  166. $points
  167. );
  168. $map_block = '<!-- wp:jetpack/map ' . wp_json_encode( $map_block_data ) . ' -->' . PHP_EOL;
  169. $map_block .= sprintf(
  170. '<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">',
  171. esc_html( wp_json_encode( $map_block_data['points'] ) ),
  172. (int) $map_block_data['zoom'],
  173. esc_html( wp_json_encode( $map_block_data['mapCenter'] ) )
  174. );
  175. $map_block .= '<ul>' . implode( "\n", $list_items ) . '</ul>';
  176. $map_block .= '</div>' . PHP_EOL;
  177. $map_block .= '<!-- /wp:jetpack/map -->';
  178. return $map_block;
  179. }