PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 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 All 508 releases
← All changes | extensions/blocks/eventbrite/render.php +254 -0 16.2-beta → 16.3 View file →
@@ -1,0 +1,254 @@
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 +}