summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/jetpack/extensions')
-rw-r--r--plugins/jetpack/extensions/blocks/amazon/amazon.php26
-rw-r--r--plugins/jetpack/extensions/blocks/calendly/calendly.php185
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/class-jetpack-contact-info-block.php16
-rw-r--r--plugins/jetpack/extensions/blocks/eventbrite/eventbrite.php101
-rw-r--r--plugins/jetpack/extensions/blocks/map/map.php30
-rw-r--r--plugins/jetpack/extensions/blocks/opentable/opentable.php231
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php8
7 files changed, 587 insertions, 10 deletions
diff --git a/plugins/jetpack/extensions/blocks/amazon/amazon.php b/plugins/jetpack/extensions/blocks/amazon/amazon.php
new file mode 100644
index 00000000..a368ab79
--- /dev/null
+++ b/plugins/jetpack/extensions/blocks/amazon/amazon.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Amazon Block.
+ *
+ * @since 8.x
+ *
+ * @package Jetpack
+ */
+
+jetpack_register_block(
+ 'jetpack/amazon',
+ array( 'render_callback' => 'jetpack_amazon_block_load_assets' )
+);
+
+/**
+ * Amazon block registration/dependency declaration.
+ *
+ * @param array $attr Array containing the Amazon block attributes.
+ * @param string $content String containing the Amazon block content.
+ *
+ * @return string
+ */
+function jetpack_amazon_block_load_assets( $attr, $content ) {
+ Jetpack_Gutenberg::load_assets_as_required( 'amazon' );
+ return $content;
+}
diff --git a/plugins/jetpack/extensions/blocks/calendly/calendly.php b/plugins/jetpack/extensions/blocks/calendly/calendly.php
new file mode 100644
index 00000000..0875a04e
--- /dev/null
+++ b/plugins/jetpack/extensions/blocks/calendly/calendly.php
@@ -0,0 +1,185 @@
+<?php
+/**
+ * Calendly Block.
+ *
+ * @since 8.2.0
+ *
+ * @package Jetpack
+ */
+
+namespace Jetpack\Calendly_Block;
+
+const FEATURE_NAME = 'calendly';
+const BLOCK_NAME = 'jetpack/' . FEATURE_NAME;
+
+/**
+ * Check if the block should be available on the site.
+ *
+ * @return bool
+ */
+function is_available() {
+ if (
+ defined( 'IS_WPCOM' )
+ && IS_WPCOM
+ && function_exists( 'has_any_blog_stickers' )
+ ) {
+ if ( has_any_blog_stickers(
+ array( 'premium-plan', 'business-plan', 'ecommerce-plan' ),
+ get_current_blog_id()
+ ) ) {
+ return true;
+ }
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Registers the block for use in Gutenberg
+ * This is done via an action so that we can disable
+ * registration if we need to.
+ */
+function register_block() {
+ if ( is_available() ) {
+ jetpack_register_block(
+ BLOCK_NAME,
+ array( 'render_callback' => 'Jetpack\Calendly_Block\load_assets' )
+ );
+ }
+}
+add_action( 'init', 'Jetpack\Calendly_Block\register_block' );
+
+/**
+ * Set the availability of the block as the editor
+ * is loaded
+ */
+function set_availability() {
+ if ( is_available() ) {
+ \Jetpack_Gutenberg::set_extension_available( BLOCK_NAME );
+ } else {
+ \Jetpack_Gutenberg::set_extension_unavailable(
+ BLOCK_NAME,
+ 'missing_plan',
+ array(
+ 'required_feature' => 'calendly',
+ 'required_plan' => 'value_bundle',
+ )
+ );
+ }
+}
+add_action( 'init', 'Jetpack\Calendly_Block\set_availability' );
+
+/**
+ * Calendly block registration/dependency declaration.
+ *
+ * @param array $attr Array containing the Calendly block attributes.
+ * @param string $content String containing the Calendly block content.
+ *
+ * @return string
+ */
+function load_assets( $attr, $content ) {
+ $url = get_attribute( $attr, 'url' );
+ if ( empty( $url ) ) {
+ return;
+ }
+
+ /*
+ * Enqueue necessary scripts and styles.
+ */
+ \Jetpack_Gutenberg::load_assets_as_required( 'calendly' );
+ wp_enqueue_script(
+ 'jetpack-calendly-external-js',
+ 'https://assets.calendly.com/assets/external/widget.js',
+ null,
+ JETPACK__VERSION,
+ false
+ );
+
+ $style = get_attribute( $attr, 'style' );
+ $hide_event_type_details = get_attribute( $attr, 'hideEventTypeDetails' );
+ $background_color = get_attribute( $attr, 'backgroundColor' );
+ $text_color = get_attribute( $attr, 'textColor' );
+ $primary_color = get_attribute( $attr, 'primaryColor' );
+ $submit_button_text = get_attribute( $attr, 'submitButtonText' );
+ $submit_button_text_color = get_attribute( $attr, 'customTextButtonColor' );
+ $submit_button_background_color = get_attribute( $attr, 'customBackgroundButtonColor' );
+ $classes = \Jetpack_Gutenberg::block_classes( 'calendly', $attr );
+ $block_id = wp_unique_id( 'calendly-block-' );
+
+ $url = add_query_arg(
+ array(
+ 'hide_event_type_details' => (int) $hide_event_type_details,
+ 'background_color' => sanitize_hex_color_no_hash( $background_color ),
+ 'text_color' => sanitize_hex_color_no_hash( $text_color ),
+ 'primary_color' => sanitize_hex_color_no_hash( $primary_color ),
+ ),
+ $url
+ );
+
+ if ( 'link' === $style ) {
+ wp_enqueue_style( 'jetpack-calendly-external-css', 'https://assets.calendly.com/assets/external/widget.css', null, JETPACK__VERSION );
+
+ /*
+ * If we have some additional styles from the editor
+ * (a custom text color, custom bg color, or both )
+ * Let's add that CSS inline.
+ */
+ if ( ! empty( $submit_button_text_color ) || ! empty( $submit_button_background_color ) ) {
+ $inline_styles = sprintf(
+ '#%1$s .wp-block-button__link{%2$s%3$s}',
+ esc_attr( $block_id ),
+ ! empty( $submit_button_text_color )
+ ? 'color:#' . sanitize_hex_color_no_hash( $submit_button_text_color ) . ';'
+ : '',
+ ! empty( $submit_button_background_color )
+ ? 'background-color:#' . sanitize_hex_color_no_hash( $submit_button_background_color ) . ';'
+ : ''
+ );
+ wp_add_inline_style( 'jetpack-calendly-external-css', $inline_styles );
+ }
+
+ $content = sprintf(
+ '<div class="%1$s" id="%2$s"><a class="wp-block-button__link" role="button" onclick="Calendly.initPopupWidget({url:\'%3$s\'});return false;">%4$s</a></div>',
+ esc_attr( $classes ),
+ esc_attr( $block_id ),
+ esc_js( $url ),
+ wp_kses_post( $submit_button_text )
+ );
+ } else { // Inline style.
+ $content = sprintf(
+ '<div class="calendly-inline-widget %1$s" data-url="%2$s" style="min-width:320px;height:630px;"></div>',
+ esc_attr( $classes ),
+ esc_url( $url )
+ );
+ }
+
+ return $content;
+}
+
+/**
+ * Get filtered attributes.
+ *
+ * @param array $attributes Array containing the Calendly block attributes.
+ * @param string $attribute_name String containing the attribute name to get.
+ *
+ * @return string
+ */
+function get_attribute( $attributes, $attribute_name ) {
+ if ( isset( $attributes[ $attribute_name ] ) ) {
+ return $attributes[ $attribute_name ];
+ }
+
+ $default_attributes = array(
+ 'style' => 'inline',
+ 'submitButtonText' => esc_html__( 'Schedule time with me', 'jetpack' ),
+ 'backgroundColor' => 'ffffff',
+ 'textColor' => '4D5055',
+ 'primaryColor' => '00A2FF',
+ 'hideEventTypeDetails' => false,
+ );
+
+ if ( isset( $default_attributes[ $attribute_name ] ) ) {
+ return $default_attributes[ $attribute_name ];
+ }
+}
diff --git a/plugins/jetpack/extensions/blocks/contact-info/class-jetpack-contact-info-block.php b/plugins/jetpack/extensions/blocks/contact-info/class-jetpack-contact-info-block.php
index 7a34cbbb..cecf6949 100644
--- a/plugins/jetpack/extensions/blocks/contact-info/class-jetpack-contact-info-block.php
+++ b/plugins/jetpack/extensions/blocks/contact-info/class-jetpack-contact-info-block.php
@@ -98,7 +98,8 @@ class Jetpack_Contact_Info_Block {
}
/**
- * Adds phone schema attributes.
+ * Adds phone schema attributes. Also wraps the tel link in a span so that
+ * it's recognized as a telephone number in Google's Structured Data.
*
* @param array $attr Array containing the phone block attributes.
* @param string $content String containing the phone block content.
@@ -106,9 +107,14 @@ class Jetpack_Contact_Info_Block {
* @return string
*/
public static function render_phone( $attr, $content ) {
- $content = self::has_attributes( $attr, array( 'className' ) ) ?
- str_replace( 'href="tel:', 'itemprop="telephone" href="tel:', $content ) :
- '';
- return $content;
+ if ( self::has_attributes( $attr, array( 'className' ) ) ) {
+ return str_replace(
+ array( '<a href="tel:', '</a>' ),
+ array( '<span itemprop="telephone"><a href="tel:', '</a></span>' ),
+ $content
+ );
+ }
+
+ return '';
}
}
diff --git a/plugins/jetpack/extensions/blocks/eventbrite/eventbrite.php b/plugins/jetpack/extensions/blocks/eventbrite/eventbrite.php
new file mode 100644
index 00000000..0135837e
--- /dev/null
+++ b/plugins/jetpack/extensions/blocks/eventbrite/eventbrite.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Eventbrite Block.
+ *
+ * @since 8.2.0
+ *
+ * @package Jetpack
+ */
+
+jetpack_register_block(
+ 'jetpack/eventbrite',
+ array(
+ 'render_callback' => 'jetpack_render_eventbrite_block',
+ )
+);
+
+/**
+ * Eventbrite block registration/dependency delclaration.
+ *
+ * @param array $attr Eventbrite block attributes.
+ * @param string $content Rendered embed element (without scripts) from the block editor.
+ *
+ * @return string
+ */
+function jetpack_render_eventbrite_block( $attr, $content ) {
+ if ( is_admin() || empty( $attr['eventId'] ) || empty( $attr['url'] ) ) {
+ return '';
+ }
+
+ $widget_id = wp_unique_id( 'eventbrite-widget-' );
+
+ wp_enqueue_script( 'eventbrite-widget', 'https://www.eventbrite.com/static/widgets/eb_widgets.js', array(), JETPACK__VERSION, true );
+
+ // Add CSS to hide direct link.
+ Jetpack_Gutenberg::load_assets_as_required( 'eventbrite' );
+
+ // Show the embedded version.
+ if ( empty( $attr['useModal'] ) ) {
+ wp_add_inline_script(
+ 'eventbrite-widget',
+ "window.EBWidgets.createWidget( {
+ widgetType: 'checkout',
+ eventId: " . absint( $attr['eventId'] ) . ",
+ iframeContainerId: '" . esc_js( $widget_id ) . "',
+ } );"
+ );
+
+ // $content contains a fallback link to the event that's saved in the post_content.
+ // Append a div that will hold the iframe embed created by the Eventbrite widget.js.
+ $content .= sprintf(
+ '<div id="%s" class="eventbrite__in-page-checkout"></div>',
+ esc_attr( $widget_id )
+ );
+
+ return sprintf(
+ '%s<noscript><a href="%s" rel="noopener noreferrer" target="_blank">%s</a></noscript>',
+ $content,
+ esc_url( $attr['url'] ),
+ esc_html__( 'Register on Eventbrite', 'jetpack' )
+ );
+ }
+
+ // Show the modal version.
+ wp_add_inline_script(
+ 'eventbrite-widget',
+ "window.EBWidgets.createWidget( {
+ widgetType: 'checkout',
+ eventId: " . absint( $attr['eventId'] ) . ",
+ modal: true,
+ modalTriggerElementId: '" . esc_js( $widget_id ) . "',
+ } );"
+ );
+
+ // Modal button is saved as an `<a>` element with `role="button"` because `<button>` is not allowed
+ // by WordPress.com wp_kses. This javascript adds the necessary event handling for button-like behavior.
+ // @link https://www.w3.org/TR/wai-aria-practices/examples/button/button.html.
+ wp_add_inline_script(
+ 'eventbrite-widget',
+ "( function() {
+ var widget = document.getElementById( '" . esc_js( $widget_id ) . "' );
+ if ( widget ) {
+ widget.addEventListener( 'click', function( event ) {
+ event.preventDefault();
+ } );
+
+ widget.addEventListener( 'keydown', function( event ) {
+ // Enter and space keys.
+ if ( event.keyCode === 13 || event.keyCode === 32 ) {
+ event.preventDefault();
+ event.target && event.target.click();
+ }
+ } );
+ }
+ } )();"
+ );
+
+ // Replace the placeholder id saved in the post_content with a unique id used by widget.js.
+ $content = preg_replace( '/eventbrite-widget-\d+/', $widget_id, $content );
+
+ return $content;
+}
diff --git a/plugins/jetpack/extensions/blocks/map/map.php b/plugins/jetpack/extensions/blocks/map/map.php
index d0c82a0d..d3b881be 100644
--- a/plugins/jetpack/extensions/blocks/map/map.php
+++ b/plugins/jetpack/extensions/blocks/map/map.php
@@ -15,6 +15,32 @@ jetpack_register_block(
);
/**
+ * Return the site's own Mapbox API key if set, or the WordPress.com's one otherwise.
+ *
+ * @return string
+ */
+function jetpack_get_mapbox_api_key() {
+ if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
+ $endpoint = sprintf(
+ 'https://public-api.wordpress.com/wpcom/v2/sites/%d/service-api-keys/mapbox',
+ get_current_blog_id()
+ );
+ } else {
+ $endpoint = rest_url( 'wpcom/v2/service-api-keys/mapbox' );
+ }
+
+ $response = wp_remote_get( esc_url_raw( $endpoint ) );
+ $response_code = wp_remote_retrieve_response_code( $response );
+
+ if ( 200 === $response_code ) {
+ $response_body = json_decode( wp_remote_retrieve_body( $response ) );
+ return $response_body->service_api_key;
+ }
+
+ return Jetpack_Options::get_option( 'mapbox_api_key' );
+}
+
+/**
* Map block registration/dependency declaration.
*
* @param array $attr Array containing the map block attributes.
@@ -23,7 +49,7 @@ jetpack_register_block(
* @return string
*/
function jetpack_map_block_load_assets( $attr, $content ) {
- $api_key = Jetpack_Options::get_option( 'mapbox_api_key' );
+ $api_key = jetpack_get_mapbox_api_key();
if ( class_exists( 'Jetpack_AMP_Support' ) && Jetpack_AMP_Support::is_amp_request() ) {
static $map_block_counter = array();
@@ -110,7 +136,7 @@ function jetpack_map_block_render_single_block_page() {
/* Put together a new complete document containing only the requested block markup and the scripts/styles needed to render it */
$block_markup = $post_html->saveHTML( $container );
- $api_key = Jetpack_Options::get_option( 'mapbox_api_key' );
+ $api_key = jetpack_get_mapbox_api_key();
$page_html = sprintf(
'<!DOCTYPE html><head><style>html, body { margin: 0; padding: 0; }</style>%s</head><body>%s</body>',
$head_content,
diff --git a/plugins/jetpack/extensions/blocks/opentable/opentable.php b/plugins/jetpack/extensions/blocks/opentable/opentable.php
new file mode 100644
index 00000000..1ea9cef1
--- /dev/null
+++ b/plugins/jetpack/extensions/blocks/opentable/opentable.php
@@ -0,0 +1,231 @@
+<?php
+/**
+ * OpenTable Block.
+ *
+ * @since 8.2
+ *
+ * @package Jetpack
+ */
+
+namespace Jetpack\OpenTable_Block;
+
+const FEATURE_NAME = 'opentable';
+const BLOCK_NAME = 'jetpack/' . FEATURE_NAME;
+
+/**
+ * Check if the block should be available on the site.
+ *
+ * @return bool
+ */
+function is_available() {
+ if (
+ defined( 'IS_WPCOM' )
+ && IS_WPCOM
+ && function_exists( 'has_any_blog_stickers' )
+ ) {
+ if ( has_any_blog_stickers(
+ array( 'premium-plan', 'business-plan', 'ecommerce-plan' ),
+ get_current_blog_id()
+ ) ) {
+ return true;
+ }
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Registers the block for use in Gutenberg
+ * This is done via an action so that we can disable
+ * registration if we need to.
+ */
+function register_block() {
+ if ( is_available() ) {
+ jetpack_register_block(
+ BLOCK_NAME,
+ array( 'render_callback' => 'Jetpack\OpenTable_Block\load_assets' )
+ );
+ }
+}
+add_action( 'init', 'Jetpack\OpenTable_Block\register_block' );
+
+/**
+ * Set the availability of the block as the editor
+ * is loaded.
+ */
+function set_availability() {
+ if ( is_available() ) {
+ \Jetpack_Gutenberg::set_extension_available( BLOCK_NAME );
+ } else {
+ \Jetpack_Gutenberg::set_extension_unavailable(
+ BLOCK_NAME,
+ 'missing_plan',
+ array(
+ 'required_feature' => 'opentable',
+ 'required_plan' => 'premium-plan',
+ )
+ );
+ }
+}
+add_action( 'jetpack_register_gutenberg_extensions', 'Jetpack\OpenTable_Block\set_availability' );
+
+/**
+ * Adds an inline script which updates the block editor settings to
+ * add the site locale. This feels sligktly better than calling back
+ * to the API before registering the block. It also seemed better than
+ * creating a global
+ */
+function add_language_setting() {
+ wp_add_inline_script( 'jetpack-blocks-editor', sprintf( "wp.data.dispatch( 'core/block-editor' ).updateSettings( { siteLocale: '%s' } )", str_replace( '_', '-', get_locale() ) ), 'before' );
+}
+add_action( 'enqueue_block_assets', 'Jetpack\OpenTable_Block\add_language_setting' );
+
+/**
+ * OpenTable block registration/dependency declaration.
+ *
+ * @param array $attributes Array containing the OpenTable block attributes.
+ *
+ * @return string
+ */
+function load_assets( $attributes ) {
+ \Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME );
+
+ $classes = array( sprintf( 'wp-block-jetpack-%s-theme-%s', FEATURE_NAME, get_attribute( $attributes, 'style' ) ) );
+ if ( count( $attributes['rid'] ) > 1 ) {
+ $classes[] = 'is-multi';
+ }
+ $classes = \Jetpack_Gutenberg::block_classes(
+ FEATURE_NAME,
+ $attributes,
+ $classes
+ );
+ $content = '<div class="' . esc_attr( $classes ) . '">';
+ // The OpenTable script uses multiple `rid` paramters,
+ // so we can't use WordPress to output it, as WordPress attempts to validate it and removes them.
+ // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
+ $content .= '<script type="text/javascript" src="' . esc_url( build_embed_url( $attributes ) ) . '"></script>';
+ $content .= '</div>';
+ return $content;
+}
+
+/**
+ * Get the a block attribute
+ *
+ * @param array $attributes Array of block attributes.
+ * @param string $attribute_name The attribute to get.
+ *
+ * @return string The filtered attribute
+ */
+function get_attribute( $attributes, $attribute_name ) {
+ if ( isset( $attributes[ $attribute_name ] ) ) {
+ if ( in_array( $attribute_name, array( 'iframe', 'newtab' ), true ) ) {
+ return $attributes[ $attribute_name ] ? 'true' : 'false';
+ }
+ return $attributes[ $attribute_name ];
+ }
+
+ $default_attributes = array(
+ 'style' => 'standard',
+ 'iframe' => 'true',
+ 'domain' => 'com',
+ 'lang' => 'en-US',
+ 'newtab' => 'false',
+ );
+
+ return isset( $default_attributes[ $attribute_name ] ) ? $default_attributes[ $attribute_name ] : null;
+}
+
+/**
+ * Get the block type attribute
+ *
+ * @param array $attributes Array of block attributes.
+ *
+ * @return string The filtered attribute
+ */
+function get_type_attribute( $attributes ) {
+ if ( ! empty( $attributes['rid'] ) && count( $attributes['rid'] ) > 1 ) {
+ return 'multi';
+ }
+
+ if ( empty( $attributes['style'] ) || 'button' !== $attributes['style'] ) {
+ return 'standard';
+ }
+
+ return 'button';
+}
+
+/**
+ * Get the block theme attribute
+ *
+ * OpenTable has a confusing mix of themes and types for the widget. A type
+ * can have a theme, but the button style can not have a theme. The other two
+ * types (multi and standard) can have one of the three themes.
+ *
+ * We have combined these into a `style` attribute as really there are 4 styles
+ * standard, wide, tall, and button. Multi can be determined by the number of
+ * restaurant IDs we have.
+ *
+ * This function along with `jetpack_opentable_block_get_type_attribute`, translates
+ * the style attribute to a type and theme.
+ *
+ * Type Theme Style
+ * ==========|==========|==========
+ * Multi | |
+ * Standard | Standard | Standard
+ * | Wide | Wide
+ * | Tall | Tall
+ * Button | Standard | Button
+ *
+ * @param array $attributes Array of block attributes.
+ *
+ * @return string The filtered attribute
+ */
+function get_theme_attribute( $attributes ) {
+ $valid_themes = array( 'standard', 'wide', 'tall' );
+
+ if ( empty( $attributes['style'] )
+ || ! in_array( $attributes['style'], $valid_themes, true )
+ || 'button' === $attributes['style'] ) {
+ return 'standard';
+ }
+
+ return $attributes['style'];
+}
+
+/**
+ * Build an embed URL from an array of block attributes.
+ *
+ * @param array $attributes Array of block attributess.
+ *
+ * @return string Embed URL
+ */
+function build_embed_url( $attributes ) {
+ $url = add_query_arg(
+ array(
+ 'type' => get_type_attribute( $attributes ),
+ 'theme' => get_theme_attribute( $attributes ),
+ 'iframe' => get_attribute( $attributes, 'iframe' ),
+ 'domain' => get_attribute( $attributes, 'domain' ),
+ 'lang' => get_attribute( $attributes, 'lang' ),
+ 'newtab' => get_attribute( $attributes, 'newtab' ),
+ ),
+ '//www.opentable.com/widget/reservation/loader'
+ );
+
+ if ( ! empty( $attributes['rid'] ) ) {
+ foreach ( $attributes['rid'] as $rid ) {
+ $url .= '&rid=' . $rid;
+ }
+ }
+
+ /**
+ * Filter the OpenTable URL used to embed a widget.
+ *
+ * @since 8.2.0
+ *
+ * @param string $url OpenTable embed URL.
+ * @param array $attributes Array of block attributes.
+ */
+ return apply_filters( 'jetpack_opentable_block_url', $url, $attributes );
+}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php b/plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php
index d53feae4..7900e9b6 100644
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php
+++ b/plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php
@@ -44,9 +44,11 @@ class Jetpack_Tiled_Gallery_Block {
$is_squareish_layout = self::is_squareish_layout( $attr );
- $jetpack_plan = Jetpack_Plan::get();
-
- wp_localize_script( 'jetpack-gallery-settings', 'jetpack_plan', array( 'data' => $jetpack_plan['product_slug'] ) );
+ // Jetpack_Plan does not exist on WordPress.com.
+ if ( class_exists( 'Jetpack_Plan' ) ) {
+ $jetpack_plan = Jetpack_Plan::get();
+ wp_localize_script( 'jetpack-gallery-settings', 'jetpack_plan', array( 'data' => $jetpack_plan['product_slug'] ) );
+ }
if ( preg_match_all( '/<img [^>]+>/', $content, $images ) ) {
/**