PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.2
Jetpack – WP Security, Backup, Speed, & Growth v16.2
16.2 16.2-beta 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 All 502 releases
jetpack / extensions / blocks / eventbrite / render.php

render.php in Jetpack – WP Security, Backup, Speed, & Growth 16.2, at extensions/blocks/eventbrite/render.php

255 lines 7.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Eventbrite block render implementation.
4 *
5 * Loaded lazily from eventbrite.php only when the block is rendered, to keep the
6 * render body out of the eager front-end PHP/opcache footprint.
7 *
8 * @package automattic/jetpack
9 */
10
11 namespace Automattic\Jetpack\Extensions\Eventbrite;
12
13 use Automattic\Jetpack\Blocks;
14 use Jetpack_Gutenberg;
15
16 if ( ! defined( 'ABSPATH' ) ) {
17 exit( 0 );
18 }
19
20 /**
21 * Get current URL.
22 *
23 * @return string Current URL.
24 */
25 function get_current_url() {
26 if ( isset( $_SERVER['HTTP_HOST'] ) ) {
27 $host = wp_unslash( $_SERVER['HTTP_HOST'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
28 } else {
29 $host = wp_parse_url( home_url(), PHP_URL_HOST );
30 }
31 if ( isset( $_SERVER['REQUEST_URI'] ) ) {
32 $path = wp_unslash( $_SERVER['REQUEST_URI'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
33 } else {
34 $path = '/';
35 }
36 return esc_url_raw( ( is_ssl() ? 'https' : 'http' ) . '://' . $host . $path );
37 }
38
39 /**
40 * Eventbrite block registration/dependency delclaration.
41 *
42 * @param array $attr Eventbrite block attributes.
43 * @param string $content Rendered embed element (without scripts) from the block editor.
44 *
45 * @return string Rendered block.
46 */
47 function render( $attr, $content ) {
48 if ( is_admin() || empty( $attr['eventId'] ) || empty( $attr['url'] ) ) {
49 return '';
50 }
51
52 $attr['url'] = Jetpack_Gutenberg::validate_block_embed_url(
53 $attr['url'],
54 array( '#^https?:\/\/(?:[0-9a-z]+\.)?eventbrite\.(?:com|co\.uk|com\.ar|com\.au|be|com\.br|ca|cl|co|dk|de|es|fi|fr|hk|ie|it|com\.mx|nl|co\.nz|at|com\.pe|pt|ch|sg|se)\/e\/[^\/]*?(?:\d+)\/?(?:\?[^\/]*)?$#' ),
55 true
56 );
57
58 $widget_id = wp_unique_id( 'eventbrite-widget-' );
59
60 // Show the embedded version.
61 if ( empty( $attr['useModal'] ) && ( empty( $attr['style'] ) || 'modal' !== $attr['style'] ) ) {
62 return render_embed_block( $widget_id, Blocks::is_amp_request(), $attr );
63 } else {
64 return render_modal_block( $widget_id, Blocks::is_amp_request(), $attr, $content );
65 }
66 }
67
68 /**
69 * Render block with embed style.
70 *
71 * @param string $widget_id Widget ID to use.
72 * @param bool $is_amp Whether AMP page.
73 * @param array $attr Eventbrite block attributes.
74 * @return string Rendered block.
75 */
76 function render_embed_block( $widget_id, $is_amp, $attr ) {
77 /*
78 * $content contains a fallback link to the event that's saved in the post_content.
79 * Append a div that will hold the iframe embed created by the Eventbrite widget.js.
80 */
81 $classes = Blocks::classes( Blocks::get_block_feature( __DIR__ ), $attr );
82
83 $classes .= ' wp-block-jetpack-eventbrite--embed';
84
85 $direct_link = sprintf(
86 '<a href="%s" rel="noopener noreferrer" target="_blank" class="eventbrite__direct-link" %s>%s</a>',
87 esc_url( $attr['url'] ),
88 $is_amp ? 'placeholder fallback' : '',
89 esc_html__( 'Register on Eventbrite', 'jetpack' )
90 );
91
92 if ( $is_amp ) {
93 $embed = sprintf(
94 '<amp-iframe src="%s" layout="responsive" resizable width="1" height="1" sandbox="allow-scripts allow-same-origin allow-forms"><button overflow>%s</button>%s</amp-iframe>',
95 esc_url(
96 add_query_arg(
97 array(
98 'eid' => $attr['eventId'],
99 'parent' => rawurlencode( get_current_url() ),
100 ),
101 'https://www.eventbrite.com/checkout-external'
102 )
103 ),
104 esc_html__( 'Expand', 'jetpack' ),
105 $direct_link
106 );
107 } else {
108 $embed = $direct_link;
109
110 wp_enqueue_script( 'eventbrite-widget', 'https://www.eventbrite.com/static/widgets/eb_widgets.js', array(), JETPACK__VERSION, true );
111
112 // Add CSS to hide direct link.
113 Jetpack_Gutenberg::load_assets_as_required( __DIR__ );
114
115 wp_add_inline_script(
116 'eventbrite-widget',
117 "window.EBWidgets.createWidget( {
118 widgetType: 'checkout',
119 eventId: " . absint( $attr['eventId'] ) . ',
120 iframeContainerId: ' . wp_json_encode( $widget_id, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ) . ',
121 } );'
122 );
123 }
124
125 return sprintf(
126 '<div id="%1$s" class="%2$s">%3$s</div>',
127 esc_attr( $widget_id ),
128 esc_attr( $classes ),
129 $embed
130 );
131 }
132
133 /**
134 * Render block with modal style.
135 *
136 * @param string $widget_id Widget ID to use.
137 * @param bool $is_amp Whether AMP page.
138 * @param array $attr Eventbrite block attributes.
139 * @param string $content Rendered embed element (without scripts) from the block editor.
140 * @return string Rendered block.
141 */
142 function render_modal_block( $widget_id, $is_amp, $attr, $content ) {
143
144 if ( $is_amp ) {
145 $lightbox_id = "{$widget_id}-lightbox";
146
147 // Add CSS to for lightbox.
148 Jetpack_Gutenberg::load_assets_as_required( __DIR__ );
149
150 $content = preg_replace(
151 '/\shref="#" target="_blank/',
152 sprintf( ' on="%s" ', esc_attr( "tap:{$lightbox_id}.open" ) ),
153 $content
154 );
155
156 $iframe_src = add_query_arg(
157 array(
158 // Note that modal=1 is intentionally omitted here since we need to put the close button inside the amp-lightbox.
159 'eid' => $attr['eventId'],
160 'parent' => rawurlencode( get_current_url() ),
161 ),
162 'https://www.eventbrite.com/checkout-external'
163 );
164
165 $lightbox = sprintf(
166 '<amp-lightbox id="%1$s" on="%2$s" class="eventbrite__lightbox" layout="nodisplay">%3$s</amp-lightbox>',
167 esc_attr( $lightbox_id ),
168 esc_attr( "tap:{$lightbox_id}.close" ),
169 sprintf(
170 '
171 <div class="eventbrite__lighbox-inside">
172 <div class="eventbrite__lighbox-iframe-wrapper">
173 <amp-iframe class="eventbrite__lighbox-iframe" src="%s" layout="fill" sandbox="allow-scripts allow-same-origin allow-forms">
174 <span placeholder=""></span>
175 </amp-iframe>
176 <span class="eventbrite__lighbox-close" on="%s" role="button" tabindex="0" aria-label="%s">
177 <svg viewBox="0 0 24 24">
178 <path d="M13.4 12l3.5-3.5-1.4-1.4-3.5 3.5-3.5-3.5-1.4 1.4 3.5 3.5-3.5 3.5 1.4 1.4 3.5-3.5 3.5 3.5 1.4-1.4z"></path>
179 </svg>
180 </span>
181 </div>
182 </div>
183 ',
184 esc_url( $iframe_src ),
185 esc_attr( "tap:{$lightbox_id}.close" ),
186 esc_attr__( 'Close', 'jetpack' )
187 )
188 );
189
190 $content = preg_replace(
191 ':(?=</div>\s*$):',
192 $lightbox,
193 $content
194 );
195
196 return $content;
197 }
198
199 wp_enqueue_script( 'eventbrite-widget', 'https://www.eventbrite.com/static/widgets/eb_widgets.js', array(), JETPACK__VERSION, true );
200
201 // Show the modal version.
202 wp_add_inline_script(
203 'eventbrite-widget',
204 "window.EBWidgets.createWidget( {
205 widgetType: 'checkout',
206 eventId: " . absint( $attr['eventId'] ) . ',
207 modal: true,
208 modalTriggerElementId: ' . wp_json_encode( $widget_id, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ) . ',
209 } );'
210 );
211
212 /*
213 * Modal button is saved as an `<a>` element with `role="button"` because `<button>` is not allowed
214 * by WordPress.com wp_kses. This javascript adds the necessary event handling for button-like behavior.
215 * @link https://www.w3.org/TR/wai-aria-practices/examples/button/button.html.
216 */
217 wp_add_inline_script(
218 'eventbrite-widget',
219 '( function() {
220 var widget = document.getElementById( ' . wp_json_encode( $widget_id, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ) . " );
221 if ( widget ) {
222 widget.addEventListener( 'click', function( event ) {
223 event.preventDefault();
224 } );
225
226 widget.addEventListener( 'keydown', function( event ) {
227 // Enter and space keys.
228 if ( event.keyCode === 13 || event.keyCode === 32 ) {
229 event.preventDefault();
230 event.target && event.target.click();
231 }
232 } );
233 }
234 } )();"
235 );
236
237 // Replace the placeholder id saved in the post_content with a unique id used by widget.js.
238 $content = str_replace( 'eventbrite-widget-id', esc_attr( $widget_id ), $content );
239
240 // Fallback for block version deprecated/v2.
241 $content = preg_replace( '/eventbrite-widget-\d+/', esc_attr( $widget_id ), $content );
242
243 // Inject URL to event in case the JS for the lightbox fails to load.
244 $content = preg_replace(
245 '/\shref="#"/',
246 sprintf(
247 ' href="%s" rel="noopener noreferrer" target="_blank"',
248 esc_url( $attr['url'] )
249 ),
250 $content
251 );
252
253 return $content;
254 }
255