Файловый менеджер - Редактировать - /var/www/xthruster/html/wp-content/uploads/flags/subscriptions.tar
Назад
class-settings.php 0000644 00000001407 14722071517 0010230 0 ustar 00 <?php /** * The Subscriptions settings. * * This is a class that contains helper functions for the Subscriptions settings module. * * @package automattic/jetpack-subscriptions */ namespace Automattic\Jetpack\Modules\Subscriptions; /** * Class Settings */ class Settings { /** * The default reply-to option. * * @var string */ public static $default_reply_to = 'comment'; /** * Validate the reply-to option. * * @param string $reply_to The reply-to option to validate. * @return bool Whether the reply-to option is valid or not. */ public static function is_valid_reply_to( $reply_to ) { $valid_values = array( 'author', 'no-reply', 'comment' ); if ( in_array( $reply_to, $valid_values, true ) ) { return true; } return false; } } subscriptions.css 0000644 00000001212 14722071517 0010167 0 ustar 00 #subscribe-email input { width: 95%; } .comment-subscription-form { margin-bottom: 1em; } .comment-subscription-form .subscribe-label { display: inline !important; } /* Text meant only for screen readers. Provides support for themes that do not bundle this CSS yet. @see https://make.wordpress.org/accessibility/2015/02/09/hiding-text-for-screen-readers-with-wordpress-core/ ***********************************/ .screen-reader-text { border: 0; clip: rect(1px, 1px, 1px, 1px); clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute ! important; width: 1px; word-wrap: normal ! important; } readme.md 0000644 00000000415 14722071517 0006331 0 ustar 00 ## Assets for Subscriptions ### subscriptions.css CSS required to render the subscription widget ### views.php This file handles the registration of various subscriptions views, i.e. a widget and a block for the post editor. This file is shared with wordpress.com views.php 0000644 00000126075 14722071517 0006433 0 ustar 00 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName // phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed -- TODO: Move classes to appropriately-named class files. /** * Jetpack_Subscriptions_Widget main view class. */ class Jetpack_Subscriptions_Widget extends WP_Widget { const ID_BASE = 'blog_subscription'; /** * Track number of rendered Subscription widgets. The count is used for class names and widget IDs. * * @var int */ public static $instance_count = 0; /** * When printing the submit button, what tags are allowed. * * @var array */ public static $allowed_html_tags_for_submit_button = array( 'br' => array(), 's' => array(), 'strong' => array(), 'em' => array(), ); /** * Use this variable when printing the message after submitting an email in subscription widgets * * @var array what tags are allowed */ public static $allowed_html_tags_for_message = array( 'a' => array( 'href' => array(), 'title' => array(), 'rel' => array(), 'target' => array(), ), 'br' => array(), ); /** * Jetpack_Subscriptions_Widget constructor. */ public function __construct() { $widget_ops = array( 'classname' => 'widget_blog_subscription jetpack_subscription_widget', 'description' => __( 'Add an email signup form to allow people to subscribe to your blog.', 'jetpack' ), 'customize_selective_refresh' => true, 'show_instance_in_rest' => true, ); $name = self::is_jetpack() ? /** This filter is documented in modules/widgets/facebook-likebox.php */ apply_filters( 'jetpack_widget_name', __( 'Blog Subscriptions', 'jetpack' ) ) : __( 'Follow Blog', 'jetpack' ); parent::__construct( 'blog_subscription', $name, $widget_ops ); if ( self::is_jetpack() && ( is_active_widget( false, false, $this->id_base ) || is_active_widget( false, false, 'monster' ) || is_customize_preview() ) ) { add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_style' ) ); } add_filter( 'widget_types_to_hide_from_legacy_widget_block', array( $this, 'hide_widget_in_block_editor' ) ); } /** * Remove the "Blog Subscription" widget from the Legacy Widget block * * @param array $widget_types List of widgets that are currently removed from the Legacy Widget block. * @return array $widget_types New list of widgets that will be removed. */ public function hide_widget_in_block_editor( $widget_types ) { $widget_types[] = self::ID_BASE; return $widget_types; } /** * Enqueue the form's CSS. * * @since 4.5.0 */ public function enqueue_style() { wp_register_style( 'jetpack-subscriptions', plugins_url( 'subscriptions.css', __FILE__ ), array(), JETPACK__VERSION ); wp_enqueue_style( 'jetpack-subscriptions' ); } /** * Renders a full widget either within the context of WordPress widget, or in response to a shortcode. * * @param array $args Display arguments including 'before_title', 'after_title', 'before_widget', and 'after_widget'. * @param array $instance The settings for the particular instance of the widget. */ public function widget( $args, $instance ) { if ( self::is_wpcom() && ! self::wpcom_has_status_message() && self::is_current_user_subscribed() ) { return null; } if ( self::is_jetpack() && /** This filter is documented in \Automattic\Jetpack\Forms\ContactForm\Contact_Form */ false === apply_filters( 'jetpack_auto_fill_logged_in_user', false ) ) { $subscribe_email = ''; } else { $current_user = wp_get_current_user(); if ( ! empty( $current_user->user_email ) ) { $subscribe_email = esc_attr( $current_user->user_email ); } else { $subscribe_email = ''; } } $stats_action = self::is_jetpack() ? 'jetpack_subscriptions' : 'follow_blog'; /** This action is documented in modules/widgets/gravatar-profile.php */ do_action( 'jetpack_stats_extra', 'widget_view', $stats_action ); $after_widget = isset( $args['after_widget'] ) ? $args['after_widget'] : ''; $before_widget = isset( $args['before_widget'] ) ? $args['before_widget'] : ''; $instance = wp_parse_args( (array) $instance, static::defaults() ); echo $before_widget; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ++self::$instance_count; self::render_widget_title( $args, $instance ); self::render_widget_status_messages( $instance ); self::render_widget_subscription_form( $args, $instance, $subscribe_email ); echo "\n" . $after_widget; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } /** * Prints the widget's title. If show_only_email_and_button is true, we will not show a title. * * @param array $args Display arguments including 'before_title', 'after_title', 'before_widget', and 'after_widget'. * @param array $instance The settings for the particular instance of the widget. */ public static function render_widget_title( $args, $instance ) { $show_only_email_and_button = $instance['show_only_email_and_button']; $before_title = isset( $args['before_title'] ) ? $args['before_title'] : ''; $after_title = isset( $args['after_title'] ) ? $args['after_title'] : ''; if ( self::is_wpcom() && ! $show_only_email_and_button ) { if ( self::is_current_user_subscribed() ) { if ( ! empty( $instance['title_following'] ) ) { printf( '%1$s<label for="subscribe-field%2$s">%3$s</label>%4$s%5$s', $before_title, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ( self::$instance_count > 1 ? '-' . (int) self::$instance_count : '' ), esc_html( $instance['title_following'] ), $after_title, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped "\n" ); } } elseif ( ! empty( $instance['title'] ) ) { printf( '%1$s<label for="subscribe-field%2$s">%3$s</label>%4$s%5$s', $before_title, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ( self::$instance_count > 1 ? '-' . (int) self::$instance_count : '' ), esc_html( $instance['title'] ), $after_title, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped "\n" ); } } if ( self::is_jetpack() && empty( $instance['show_only_email_and_button'] ) ) { printf( '%1$s%2$s%3$s%4$s', $before_title, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped esc_html( $instance['title'] ), $after_title, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped "\n" ); } } /** * Prints the subscription block's status messages after someone has attempted to subscribe. * Either a success message or an error message. * * @param array $instance The settings for the particular instance of the widget. */ public static function render_widget_status_messages( $instance ) { if ( self::is_jetpack() && isset( $_GET['subscribe'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Non-sensitive informational output. $success_message = isset( $instance['success_message'] ) ? stripslashes( $instance['success_message'] ) : ''; $subscribers_total = self::fetch_subscriber_count(); switch ( $_GET['subscribe'] ) : // phpcs:ignore WordPress.Security.NonceVerification.Recommended case 'invalid_email': ?> <p class="error"><?php esc_html_e( 'Oops! The email you used is invalid. Please try again.', 'jetpack' ); ?></p> <?php break; case 'opted_out': ?> <p class="error"> <?php printf( wp_kses( /* translators: 1: Link to Subscription Management page https://subscribe.wordpress.com/, 2: Description of this link. */ __( 'Oops! It seems that the email you used has opted out of subscriptions. You can manage your preferences from the <a href="%1$s" title="%2$s" target="_blank">Subscriptions Manager</a>', 'jetpack' ), self::$allowed_html_tags_for_message ), 'https://subscribe.wordpress.com/', esc_attr__( 'Subscriptions Manager', 'jetpack' ) ); ?> </p> <?php break; case 'already': ?> <p class="error"> <?php printf( wp_kses( /* translators: 1: Link to Subscription Management page https://subscribe.wordpress.com/, 2: Description of this link. */ __( 'You have already subscribed to this site. Please check your email inbox. You can manage your preferences from the <a href="%1$s" title="%2$s" target="_blank">Subscriptions Manager</a>.', 'jetpack' ), self::$allowed_html_tags_for_message ), 'https://subscribe.wordpress.com/', esc_attr__( 'Subscriptions Manager', 'jetpack' ) ); ?> </p> <?php break; case 'many_pending_subs': ?> <p class="error"> <?php printf( wp_kses( /* translators: 1: Link to Subscription Management page https://subscribe.wordpress.com/, 2: Description of this link */ __( 'Oops! It seems you have several subscriptions pending confirmation. You can confirm or unsubscribe some from the <a href="%1$s" title="%2$s" target="_blank" rel="noopener noreferrer">Subscriptions Manager</a> before adding more.', 'jetpack' ), self::$allowed_html_tags_for_message ), 'https://subscribe.wordpress.com/', esc_attr__( 'Subscriptions Manager', 'jetpack' ) ); ?> </p> <?php break; case 'pending': ?> <p class="error"> <?php printf( wp_kses( /* translators: 1: Link to Subscription Management page https://subscribe.wordpress.com/, 2: Description of this link */ __( 'It seems you already tried to subscribe with this email, but have not confirmed from the email link we sent. Please check your email inbox to confirm or you can manage your preferences from the <a href="%1$s" title="%2$s" target="_blank" rel="noopener noreferrer">Subscriptions Manager</a>.', 'jetpack' ), self::$allowed_html_tags_for_message ), 'https://subscribe.wordpress.com/', esc_attr__( 'Subscriptions Manager', 'jetpack' ) ); ?> </p> <?php break; case 'success': ?> <div class="success"><?php echo wp_kses( wpautop( str_replace( '[total-subscribers]', number_format_i18n( $subscribers_total ), $success_message ) ), 'post' ); ?></div> <?php break; default: ?> <p class="error"><?php esc_html_e( 'Oops! There was an error when subscribing. Please try again.', 'jetpack' ); ?></p> <?php break; endswitch; } if ( self::is_wpcom() && self::wpcom_has_status_message() ) { global $themecolors; $message = ''; switch ( $_GET['blogsub'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated case 'confirming': $message = __( 'Thank you! You can now check your email to confirm your subscription.', 'jetpack' ); break; case 'blocked': $message = __( 'Sorry but this email has been blocked for this subscription. <a href="https://en.support.wordpress.com/contact/">Contact us</a> if needed.', 'jetpack' ); break; case 'flooded': $message = __( 'Oops! It seems you have several subscriptions pending confirmation. You can confirm or unsubscribe some from the <a href="https://subscribe.wordpress.com/">Subscriptions Manager</a> before adding more.', 'jetpack' ); break; case 'spammed': /* translators: %s is a URL */ $message = sprintf( __( 'Sorry but this email has been blocked. It has too many subscriptions pending confirmation. Please confirm or unsubscribe some from the <a href="%s">Subscriptions Manager</a>.', 'jetpack' ), 'https://subscribe.wordpress.com/' ); break; case 'subscribed': $message = __( 'Hey! You were already subscribed.', 'jetpack' ); break; case 'pending': $message = __( 'It seems you already tried to subscribe. We just sent you another email so you can confirm the subscription.', 'jetpack' ); break; case 'confirmed': $message = __( 'Cool! You are now subscribed. Now you can check your email for more details and how to manage the subscription.', 'jetpack' ); break; } $border_color = isset( $themecolors['border'] ) ? " #{$themecolors['border']}" : ''; $redirect_fragment = self::get_redirect_fragment(); printf( '<div id="%1$s" class="jetpack-sub-notification">%3$s</div>', esc_attr( $redirect_fragment ), esc_attr( $border_color ), wp_kses_post( $message ) ); } } /** * Generates the redirect fragment used after form submission. * * @param string $id is the specific id that will appear in the redirect fragment. If none is provided self::$instance_count will be used. */ protected static function get_redirect_fragment( $id = null ) { if ( $id === null ) { return 'subscribe-blog' . ( self::$instance_count > 1 ? '-' . self::$instance_count : '' ); } return 'subscribe-blog-' . $id; } /** * Renders a form allowing folks to subscribe to the blog. * * @param array $args Display arguments including 'before_title', 'after_title', 'before_widget', and 'after_widget'. * @param array $instance The settings for the particular instance of the widget. * @param string $subscribe_email The email to use to prefill the form. */ public static function render_widget_subscription_form( $args, $instance, $subscribe_email ) { $show_only_email_and_button = $instance['show_only_email_and_button']; $show_subscribers_total = (bool) $instance['show_subscribers_total']; $subscribers_total = self::fetch_subscriber_count(); $subscribe_text = empty( $instance['show_only_email_and_button'] ) ? wp_kses_post( stripslashes( $instance['subscribe_text'] ) ) : false; $referer = esc_url_raw( ( is_ssl() ? 'https' : 'http' ) . '://' . ( isset( $_SERVER['HTTP_HOST'] ) ? wp_unslash( $_SERVER['HTTP_HOST'] ) : '' ) . ( isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '' ) ); $source = 'widget'; $widget_id = ! empty( $args['widget_id'] ) ? $args['widget_id'] : self::$instance_count; $subscribe_button = ! empty( $instance['submit_button_text'] ) ? $instance['submit_button_text'] : $instance['subscribe_button']; $subscribe_placeholder = isset( $instance['subscribe_placeholder'] ) ? stripslashes( $instance['subscribe_placeholder'] ) : ''; $submit_button_classes = isset( $instance['submit_button_classes'] ) ? 'wp-block-button__link ' . $instance['submit_button_classes'] : 'wp-block-button__link'; $submit_button_styles = isset( $instance['submit_button_styles'] ) ? $instance['submit_button_styles'] : ''; $submit_button_wrapper_styles = isset( $instance['submit_button_wrapper_styles'] ) ? $instance['submit_button_wrapper_styles'] : ''; $email_field_classes = isset( $instance['email_field_classes'] ) ? $instance['email_field_classes'] : ''; $email_field_styles = isset( $instance['email_field_styles'] ) ? $instance['email_field_styles'] : ''; // We need to include those in case Jetpack blocks are disabled require_once JETPACK__PLUGIN_DIR . 'modules/memberships/class-jetpack-memberships.php'; require_once JETPACK__PLUGIN_DIR . 'extensions/blocks/premium-content/_inc/subscription-service/include.php'; $post_access_level = \Jetpack_Memberships::get_post_access_level(); if ( self::is_wpcom() && ! self::wpcom_has_status_message() ) { global $current_blog; $url = defined( 'SUBSCRIBE_BLOG_URL' ) ? SUBSCRIBE_BLOG_URL : ''; $form_id = self::get_redirect_fragment(); ?> <div class="wp-block-jetpack-subscriptions__container"> <form action="<?php echo esc_url( $url ); ?>" method="post" accept-charset="utf-8" data-blog="<?php echo esc_attr( get_current_blog_id() ); ?>" data-post_access_level="<?php echo esc_attr( $post_access_level ); ?>" id="<?php echo esc_attr( $form_id ); ?>" > <?php if ( ! $show_only_email_and_button ) { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo wpautop( $subscribe_text ); } $email_field_id = 'subscribe-field'; $email_field_id .= self::$instance_count > 1 ? '-' . self::$instance_count : ''; $label_field_id = $email_field_id . '-label'; ?> <p id="subscribe-email"> <label id="<?php echo esc_attr( $label_field_id ); ?>" for="<?php echo esc_attr( $email_field_id ); ?>" class="screen-reader-text" > <?php echo esc_html__( 'Email Address:', 'jetpack' ); ?> </label> <?php printf( '<input type="email" name="email" %1$s style="%2$s" placeholder="%3$s" value="" id="%4$s" required />', ( ! empty( $email_field_classes ) ? 'class="' . esc_attr( $email_field_classes ) . '"' : '' ), ( ! empty( $email_field_styles ) ? esc_attr( $email_field_styles ) : 'width: 95%; padding: 1px 10px' ), ( empty( $subscribe_placeholder ) ? esc_attr__( 'Enter your email address', 'jetpack' ) : esc_attr( $subscribe_placeholder ) ), esc_attr( $email_field_id ) ); ?> </p> <p id="subscribe-submit" <?php if ( ! empty( $submit_button_wrapper_styles ) ) { ?> style="<?php echo esc_attr( $submit_button_wrapper_styles ); ?>" <?php } ?> > <input type="hidden" name="action" value="subscribe"/> <input type="hidden" name="blog_id" value="<?php echo (int) $current_blog->blog_id; ?>"/> <input type="hidden" name="source" value="<?php echo esc_url( $referer ); ?>"/> <input type="hidden" name="sub-type" value="<?php echo esc_attr( $source ); ?>"/> <input type="hidden" name="redirect_fragment" value="<?php echo esc_attr( $form_id ); ?>"/> <?php wp_nonce_field( 'blogsub_subscribe_' . $current_blog->blog_id, '_wpnonce', false ); ?> <button type="submit" <?php if ( ! empty( $submit_button_classes ) ) { ?> class="<?php echo esc_attr( $submit_button_classes ); ?>" <?php } ?> <?php if ( ! empty( $submit_button_styles ) ) { ?> style="<?php echo esc_attr( $submit_button_styles ); ?>" <?php } ?> > <?php echo wp_kses( html_entity_decode( $subscribe_button, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 ), self::$allowed_html_tags_for_submit_button ); ?> </button> </p> </form> <?php if ( $show_subscribers_total && $subscribers_total > 0 ) { ?> <div class="wp-block-jetpack-subscriptions__subscount"> <?php echo esc_html( Jetpack_Memberships::get_join_others_text( $subscribers_total ) ); ?> </div> <?php } ?> </div> <?php } if ( self::is_jetpack() ) { /** * Filter the subscription form's ID prefix. * * @module subscriptions * * @since 2.7.0 * * @param string subscribe-field Subscription form field prefix. * @param int $widget_id Widget ID. */ $subscribe_field_id = apply_filters( 'subscribe_field_id', 'subscribe-field', $widget_id ); $form_id = self::get_redirect_fragment( $widget_id ); ?> <div class="wp-block-jetpack-subscriptions__container"> <form action="#" method="post" accept-charset="utf-8" id="<?php echo esc_attr( $form_id ); ?>" data-blog="<?php echo esc_attr( \Jetpack_Options::get_option( 'id' ) ); ?>" data-post_access_level="<?php echo esc_attr( $post_access_level ); ?>" > <?php if ( $subscribe_text && ( ! isset( $_GET['subscribe'] ) || 'success' !== $_GET['subscribe'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Non-sensitive informational output. ?> <div id="subscribe-text"><?php echo wp_kses( wpautop( str_replace( '[total-subscribers]', number_format_i18n( $subscribers_total ), $subscribe_text ) ), 'post' ); ?></div> <?php } if ( ! isset( $_GET['subscribe'] ) || 'success' !== $_GET['subscribe'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display of unsubmitted form. ?> <p id="subscribe-email"> <label id="jetpack-subscribe-label" class="screen-reader-text" for="<?php echo esc_attr( $subscribe_field_id . '-' . $widget_id ); ?>"> <?php echo ! empty( $subscribe_placeholder ) ? esc_html( $subscribe_placeholder ) : esc_html__( 'Email Address:', 'jetpack' ); ?> </label> <input type="email" name="email" required="required" <?php if ( ! empty( $email_field_classes ) ) { ?> class="<?php echo esc_attr( $email_field_classes ); ?> required" <?php } ?> <?php if ( ! empty( $email_field_styles ) ) { ?> style="<?php echo esc_attr( $email_field_styles ); ?>" <?php } ?> value="<?php echo esc_attr( $subscribe_email ); ?>" id="<?php echo esc_attr( $subscribe_field_id . '-' . $widget_id ); ?>" placeholder="<?php echo esc_attr( $subscribe_placeholder ); ?>" /> </p> <p id="subscribe-submit" <?php if ( ! empty( $submit_button_wrapper_styles ) ) { ?> style="<?php echo esc_attr( $submit_button_wrapper_styles ); ?>" <?php } ?> > <input type="hidden" name="action" value="subscribe"/> <input type="hidden" name="source" value="<?php echo esc_url( $referer ); ?>"/> <input type="hidden" name="sub-type" value="<?php echo esc_attr( $source ); ?>"/> <input type="hidden" name="redirect_fragment" value="<?php echo esc_attr( $form_id ); ?>"/> <?php wp_nonce_field( 'blogsub_subscribe_' . \Jetpack_Options::get_option( 'id' ) ); ?> <button type="submit" <?php if ( ! empty( $submit_button_classes ) ) { ?> class="<?php echo esc_attr( $submit_button_classes ); ?>" <?php } ?> <?php if ( ! empty( $submit_button_styles ) ) { ?> style="<?php echo esc_attr( $submit_button_styles ); ?>" <?php } ?> name="jetpack_subscriptions_widget" > <?php echo wp_kses( html_entity_decode( $subscribe_button, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 ), self::$allowed_html_tags_for_submit_button ); ?> </button> </p> <?php } ?> </form> <?php if ( $show_subscribers_total && 0 < $subscribers_total ) { ?> <div class="wp-block-jetpack-subscriptions__subscount"> <?php echo esc_html( Jetpack_Memberships::get_join_others_text( $subscribers_total ) ); ?> </div> <?php } ?> </div> <?php } } /** * Determines if the current user is subscribed to the blog. * * @return bool Is the person already subscribed. */ public static function is_current_user_subscribed() { $subscribed = isset( $_GET['subscribe'] ) && 'success' === $_GET['subscribe']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( self::is_wpcom() && class_exists( 'Blog_Subscription' ) && class_exists( 'Blog_Subscriber' ) ) { $subscribed = is_user_logged_in() && Blog_Subscription::is_subscribed( new Blog_Subscriber() ); } return $subscribed; } /** * Is this script running in the wordpress.com environment? * * @return bool */ public static function is_wpcom() { return defined( 'IS_WPCOM' ) && IS_WPCOM; } /** * Is this script running in a self-hosted environment? * * @return bool */ public static function is_jetpack() { return ! self::is_wpcom(); } /** * Used to determine if there is a valid status slug within the wordpress.com environment. * * @return bool */ public static function wpcom_has_status_message() { return isset( $_GET['blogsub'] ) && // phpcs:ignore WordPress.Security.NonceVerification.Recommended in_array( $_GET['blogsub'], // phpcs:ignore WordPress.Security.NonceVerification.Recommended array( 'confirming', 'blocked', 'flooded', 'spammed', 'subscribed', 'pending', 'confirmed', ), true ); } /** * Determine the amount of folks currently subscribed to the blog. * * @return int */ public static function fetch_subscriber_count() { $subs_count = 0; if ( self::is_jetpack() ) { $cache_key = 'wpcom_subscribers_total'; $subs_count = get_transient( $cache_key ); if ( false === $subs_count || 'failed' === $subs_count['status'] ) { $xml = new Jetpack_IXR_Client(); $xml->query( 'jetpack.fetchSubscriberCount' ); if ( $xml->isError() ) { // If we get an error from .com, set the status to failed so that we will try again next time the data is requested. $subs_count = array( 'status' => 'failed', 'code' => $xml->getErrorCode(), 'message' => $xml->getErrorMessage(), 'value' => ( isset( $subs_count['value'] ) ) ? $subs_count['value'] : 0, ); } else { $subs_count = array( 'status' => 'success', 'value' => $xml->getResponse(), ); } set_transient( $cache_key, $subs_count, 3600 ); // Try to cache the result for at least 1 hour. } return $subs_count['value']; } if ( self::is_wpcom() ) { $subs_count = wpcom_reach_total_for_blog(); return $subs_count; } } /** * Updates a particular instance of a widget when someone saves it in wp-admin. * * @param array $new_instance New widget instance settings. * @param array $old_instance Old widget instance settings. * * @return array */ public function update( $new_instance, $old_instance ) { $instance = $old_instance; if ( self::is_jetpack() ) { $instance['title'] = wp_kses( stripslashes( $new_instance['title'] ), array() ); $instance['subscribe_placeholder'] = wp_kses( stripslashes( $new_instance['subscribe_placeholder'] ), array() ); $instance['subscribe_button'] = wp_kses( stripslashes( $new_instance['subscribe_button'] ), array() ); $instance['success_message'] = wp_kses( stripslashes( $new_instance['success_message'] ), array() ); } if ( self::is_wpcom() ) { $instance['title'] = wp_strip_all_tags( stripslashes( $new_instance['title'] ) ); $instance['title_following'] = wp_strip_all_tags( stripslashes( $new_instance['title_following'] ) ); $instance['subscribe_logged_in'] = wp_filter_post_kses( stripslashes( $new_instance['subscribe_logged_in'] ) ); $instance['subscribe_button'] = wp_strip_all_tags( stripslashes( $new_instance['subscribe_button'] ) ); } $instance['show_subscribers_total'] = isset( $new_instance['show_subscribers_total'] ) && $new_instance['show_subscribers_total']; $instance['show_only_email_and_button'] = isset( $new_instance['show_only_email_and_button'] ) && $new_instance['show_only_email_and_button']; $instance['subscribe_text'] = wp_filter_post_kses( stripslashes( $new_instance['subscribe_text'] ) ); return $instance; } /** * The default args for rendering a subscription form. * * @return array */ public static function defaults() { $defaults = array( 'show_subscribers_total' => true, 'show_only_email_and_button' => false, 'include_social_followers' => true, ); $defaults['title'] = esc_html__( 'Subscribe to Blog via Email', 'jetpack' ); $defaults['subscribe_text'] = esc_html__( 'Enter your email address to subscribe to this blog and receive notifications of new posts by email.', 'jetpack' ); $defaults['subscribe_placeholder'] = esc_html__( 'Email Address', 'jetpack' ); $defaults['subscribe_button'] = esc_html__( 'Subscribe', 'jetpack' ); $defaults['success_message'] = esc_html__( "Success! An email was just sent to confirm your subscription. Please find the email now and click 'Confirm' to start subscribing.", 'jetpack' ); return $defaults; } /** * Renders the widget's options form in wp-admin. * * @param array $instance Widget instance. */ public function form( $instance ) { $instance = wp_parse_args( (array) $instance, static::defaults() ); $show_subscribers_total = checked( $instance['show_subscribers_total'], true, false ); if ( self::is_wpcom() ) { $title = ! empty( $instance['title'] ) ? esc_attr( stripslashes( $instance['title'] ) ) : ''; $title_following = ! empty( $instance['title_following'] ) ? esc_attr( stripslashes( $instance['title_following'] ) ) : ''; $subscribe_text = ! empty( $instance['subscribe_text'] ) ? esc_attr( stripslashes( $instance['subscribe_text'] ) ) : ''; $subscribe_logged_in = ! empty( $instance['subscribe_logged_in'] ) ? esc_attr( stripslashes( $instance['subscribe_logged_in'] ) ) : ''; $subscribe_button = ! empty( $instance['subscribe_button'] ) ? esc_attr( stripslashes( $instance['subscribe_button'] ) ) : ''; $subscribers_total = self::fetch_subscriber_count(); } if ( self::is_jetpack() ) { $title = ! empty( $instance['title'] ) ? stripslashes( $instance['title'] ) : ''; $subscribe_text = ! empty( $instance['subscribe_text'] ) ? stripslashes( $instance['subscribe_text'] ) : ''; $subscribe_placeholder = ! empty( $instance['subscribe_placeholder'] ) ? stripslashes( $instance['subscribe_placeholder'] ) : ''; $subscribe_button = ! empty( $instance['subscribe_button'] ) ? stripslashes( $instance['subscribe_button'] ) : ''; $success_message = ! empty( $instance['success_message'] ) ? stripslashes( $instance['success_message'] ) : ''; $subscribers_total = self::fetch_subscriber_count(); } if ( self::is_wpcom() ) : ?> <p> <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"> <?php esc_html_e( 'Widget title for non-followers:', 'jetpack' ); ?> <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>"/> </label> </p> <p> <label for="<?php echo esc_attr( $this->get_field_id( 'title_following' ) ); ?>"> <?php esc_html_e( 'Widget title for followers:', 'jetpack' ); ?> <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title_following' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title_following' ) ); ?>" type="text" value="<?php echo esc_attr( $title_following ); ?>"/> </label> </p> <p> <label for="<?php echo esc_attr( $this->get_field_id( 'subscribe_logged_in' ) ); ?>"> <?php esc_html_e( 'Optional text to display to logged in WordPress.com users:', 'jetpack' ); ?> <textarea style="width: 95%" id="<?php echo esc_attr( $this->get_field_id( 'subscribe_logged_in' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'subscribe_logged_in' ) ); ?>" type="text"><?php echo esc_html( $subscribe_logged_in ); ?></textarea> </label> </p> <p> <label for="<?php echo esc_attr( $this->get_field_id( 'subscribe_text' ) ); ?>"> <?php esc_html_e( 'Optional text to display to non-WordPress.com users:', 'jetpack' ); ?> <textarea style="width: 95%" id="<?php echo esc_attr( $this->get_field_id( 'subscribe_text' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'subscribe_text' ) ); ?>" type="text"><?php echo esc_html( $subscribe_text ); ?></textarea> </label> </p> <p> <label for="<?php echo esc_attr( $this->get_field_id( 'subscribe_button' ) ); ?>"> <?php esc_html_e( 'Follow Button Text:', 'jetpack' ); ?> <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'subscribe_button' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'subscribe_button' ) ); ?>" type="text" value="<?php echo esc_attr( $subscribe_button ); ?>"/> </label> </p> <p> <label for="<?php echo esc_attr( $this->get_field_id( 'show_subscribers_total' ) ); ?>"> <input type="checkbox" id="<?php echo esc_attr( $this->get_field_id( 'show_subscribers_total' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'show_subscribers_total' ) ); ?>" value="1"<?php echo esc_attr( $show_subscribers_total ); ?> /> <?php /* translators: %s: Number of followers. */ echo esc_html( sprintf( _n( 'Show total number of followers? (%s follower)', 'Show total number of followers? (%s followers)', $subscribers_total, 'jetpack' ), number_format_i18n( $subscribers_total ) ) ); ?> </label> </p> <?php endif; if ( self::is_jetpack() ) : ?> <p> <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"> <?php esc_html_e( 'Widget title:', 'jetpack' ); ?> <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>"/> </label> </p> <p> <label for="<?php echo esc_attr( $this->get_field_id( 'subscribe_text' ) ); ?>"> <?php esc_html_e( 'Optional text to display to your readers:', 'jetpack' ); ?> <textarea class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'subscribe_text' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'subscribe_text' ) ); ?>" rows="3"><?php echo esc_html( $subscribe_text ); ?></textarea> </label> </p> <p> <label for="<?php echo esc_attr( $this->get_field_id( 'subscribe_placeholder' ) ); ?>"> <?php esc_html_e( 'Subscribe Placeholder:', 'jetpack' ); ?> <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'subscribe_placeholder' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'subscribe_placeholder' ) ); ?>" type="text" value="<?php echo esc_attr( $subscribe_placeholder ); ?>"/> </label> </p> <p> <label for="<?php echo esc_attr( $this->get_field_id( 'subscribe_button' ) ); ?>"> <?php esc_html_e( 'Subscribe Button:', 'jetpack' ); ?> <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'subscribe_button' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'subscribe_button' ) ); ?>" type="text" value="<?php echo esc_attr( $subscribe_button ); ?>"/> </label> </p> <p> <label for="<?php echo esc_attr( $this->get_field_id( 'success_message' ) ); ?>"> <?php esc_html_e( 'Success Message Text:', 'jetpack' ); ?> <textarea class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'success_message' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'success_message' ) ); ?>" rows="5"><?php echo esc_html( $success_message ); ?></textarea> </label> </p> <p> <label for="<?php echo esc_attr( $this->get_field_id( 'show_subscribers_total' ) ); ?>"> <input type="checkbox" id="<?php echo esc_attr( $this->get_field_id( 'show_subscribers_total' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'show_subscribers_total' ) ); ?>" value="1"<?php echo esc_attr( $show_subscribers_total ); ?> /> <?php /* translators: %s: Number of subscribers. */ echo esc_html( sprintf( _n( 'Show total number of subscribers? (%s subscriber)', 'Show total number of subscribers? (%s subscribers)', $subscribers_total, 'jetpack' ), $subscribers_total ) ); ?> </label> </p> <?php endif; } } if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) { class_alias( 'Jetpack_Subscriptions_Widget', 'Blog_Subscription_Widget' ); } /** * Classname / shortcode tag to use for the Subscriptions widget. * * @return string */ function get_jetpack_blog_subscriptions_widget_classname() { return ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ? 'Blog_Subscription_Widget' : 'Jetpack_Subscriptions_Widget'; } /** * Subscriptions widget form HTML output. * * @param array $instance Widget instance data. */ function jetpack_do_subscription_form( $instance ) { if ( empty( $instance ) || ! is_array( $instance ) ) { $instance = array(); } if ( empty( $instance['show_subscribers_total'] ) || 'false' === $instance['show_subscribers_total'] ) { $instance['show_subscribers_total'] = false; } else { $instance['show_subscribers_total'] = true; } // the default behavior is to include the social followers if ( empty( $instance['include_social_followers'] ) || 'true' === $instance['include_social_followers'] ) { $instance['include_social_followers'] = true; } else { $instance['include_social_followers'] = false; } $show_only_email_and_button = isset( $instance['show_only_email_and_button'] ) ? $instance['show_only_email_and_button'] : false; $submit_button_text = isset( $instance['submit_button_text'] ) ? $instance['submit_button_text'] : ''; // Build up a string with the submit button's classes and styles and set it on the instance. $submit_button_classes = isset( $instance['submit_button_classes'] ) ? $instance['submit_button_classes'] : ''; $email_field_classes = isset( $instance['email_field_classes'] ) ? $instance['email_field_classes'] : ''; $style = ''; $submit_button_styles = ''; $submit_button_wrapper_styles = ''; $email_field_styles = ''; $success_message = ''; if ( isset( $instance['custom_background_button_color'] ) && 'undefined' !== $instance['custom_background_button_color'] ) { $submit_button_styles .= 'background: ' . $instance['custom_background_button_color'] . '; '; } if ( isset( $instance['custom_text_button_color'] ) && 'undefined' !== $instance['custom_text_button_color'] ) { $submit_button_styles .= 'color: ' . $instance['custom_text_button_color'] . '; '; } if ( isset( $instance['custom_button_width'] ) && 'undefined' !== $instance['custom_button_width'] ) { $submit_button_wrapper_styles .= 'width: ' . $instance['custom_button_width'] . '; '; $submit_button_wrapper_styles .= 'max-width: 100%; '; // Account for custom margins on inline forms. if ( ! empty( $instance['custom_spacing'] ) && ! ( isset( $instance['button_on_newline'] ) && 'true' === $instance['button_on_newline'] ) ) { $submit_button_styles .= 'width: calc(100% - ' . $instance['custom_spacing'] . 'px); '; } else { $submit_button_styles .= 'width: 100%; '; } } if ( isset( $instance['custom_font_size'] ) && 'undefined' !== $instance['custom_font_size'] ) { $style = 'font-size: ' . $instance['custom_font_size']; $style .= is_numeric( $instance['custom_font_size'] ) ? 'px; ' : '; '; // Handle deprecated numeric font size values. $submit_button_styles .= $style; $email_field_styles .= $style; } if ( isset( $instance['custom_padding'] ) && 'undefined' !== $instance['custom_padding'] ) { $style = 'padding: ' . $instance['custom_padding'] . 'px ' . round( floatval( $instance['custom_padding'] ) * 1.5 ) . 'px ' . $instance['custom_padding'] . 'px ' . round( floatval( $instance['custom_padding'] ) * 1.5 ) . 'px; '; $submit_button_styles .= $style; $email_field_styles .= $style; } $button_spacing = 0; if ( ! empty( $instance['custom_spacing'] ) ) { $button_spacing = $instance['custom_spacing']; } if ( isset( $instance['button_on_newline'] ) && 'true' === $instance['button_on_newline'] ) { $submit_button_styles .= 'margin-top: ' . $button_spacing . 'px; '; } else { $submit_button_styles .= 'margin: 0px; '; // Reset Safari's 2px default margin for buttons affecting input and button union $submit_button_styles .= 'margin-left: ' . $button_spacing . 'px; '; } if ( isset( $instance['custom_border_radius'] ) && 'undefined' !== $instance['custom_border_radius'] ) { $style = 'border-radius: ' . $instance['custom_border_radius'] . 'px; '; $submit_button_styles .= $style; $email_field_styles .= $style; } if ( isset( $instance['custom_border_weight'] ) && 'undefined' !== $instance['custom_border_weight'] ) { $style = 'border-width: ' . $instance['custom_border_weight'] . 'px; '; $submit_button_styles .= $style; $email_field_styles .= $style; } if ( isset( $instance['custom_border_color'] ) && 'undefined' !== $instance['custom_border_color'] ) { $style = 'border-color: ' . $instance['custom_border_color'] . '; ' . 'border-style: solid;'; $submit_button_styles .= $style; $email_field_styles .= $style; } if ( isset( $instance['success_message'] ) && 'undefined' !== $instance['success_message'] ) { $success_message = wp_kses( stripslashes( $instance['success_message'] ), array() ); } $instance = shortcode_atts( Jetpack_Subscriptions_Widget::defaults(), $instance, 'jetpack_subscription_form' ); // These must come after the call to shortcode_atts(). $instance['submit_button_text'] = $submit_button_text; $instance['show_only_email_and_button'] = $show_only_email_and_button; if ( ! empty( $submit_button_classes ) ) { $instance['submit_button_classes'] = $submit_button_classes; } if ( ! empty( $email_field_classes ) ) { $instance['email_field_classes'] = $email_field_classes; } if ( ! empty( $submit_button_styles ) ) { $instance['submit_button_styles'] = trim( $submit_button_styles ); } if ( ! empty( $submit_button_wrapper_styles ) ) { $instance['submit_button_wrapper_styles'] = trim( $submit_button_wrapper_styles ); } if ( ! empty( $email_field_styles ) ) { $instance['email_field_styles'] = trim( $email_field_styles ); } if ( ! empty( $success_message ) ) { $instance['success_message'] = trim( $success_message ); } $args = array( 'before_widget' => '<div class="jetpack_subscription_widget">', ); ob_start(); the_widget( get_jetpack_blog_subscriptions_widget_classname(), $instance, $args ); $output = ob_get_clean(); return $output; } add_shortcode( 'jetpack_subscription_form', 'jetpack_do_subscription_form' ); add_shortcode( 'blog_subscription_form', 'jetpack_do_subscription_form' ); /** * Register the Subscriptions widget. */ function jetpack_blog_subscriptions_init() { register_widget( get_jetpack_blog_subscriptions_widget_classname() ); } add_action( 'widgets_init', 'jetpack_blog_subscriptions_init' ); /** * Sets the default value for `subscription_options` site option. * * This default value is available across Simple, Atomic and Jetpack sites, * including the /sites/$site/settings endpoint. * * @param array $default Default `subscription_options` array. * @param string $option Option name. * @param bool $passed_default Whether `get_option()` passed a default value. * * @return array Default value of `subscription_options`. */ function subscription_options_fallback( $default, $option, $passed_default ) { if ( $passed_default ) { return $default; } $site_url = get_home_url(); $display_url = preg_replace( '(^https?://)', '', untrailingslashit( $site_url ) ); return array( /* translators: Both %1$s and %2$s is site address */ 'invitation' => sprintf( __( "Howdy,\nYou recently subscribed to <a href='%1\$s'>%2\$s</a> and we need to verify the email you provided. Once you confirm below, you'll be able to receive and read new posts.\n\nIf you believe this is an error, ignore this message and nothing more will happen.", 'jetpack' ), $site_url, $display_url ), 'comment_follow' => __( "Howdy.\n\nYou recently followed one of my posts. This means you will receive an email when new comments are posted.\n\nTo activate, click confirm below. If you believe this is an error, ignore this message and we'll never bother you again.", 'jetpack' ), /* translators: %1$s is the site address */ 'welcome' => sprintf( __( 'Cool, you are now subscribed to %1$s and will receive an email notification when a new post is published.', 'jetpack' ), $display_url ), ); } add_filter( 'default_option_subscription_options', 'subscription_options_fallback', 10, 3 ); subscribe-modal/subscribe-modal.js 0000644 00000007356 14722071517 0013251 0 ustar 00 /* global Jetpack_Subscriptions */ const { domReady } = wp; domReady( () => { const modal = document.querySelector( '.jetpack-subscribe-modal' ); const modalDismissedCookie = 'jetpack_post_subscribe_modal_dismissed'; const skipUrlParam = 'jetpack_skip_subscription_popup'; function hasEnoughTimePassed() { const lastDismissed = localStorage.getItem( modalDismissedCookie ); return lastDismissed ? Date.now() - lastDismissed > Jetpack_Subscriptions.modalInterval : true; } // Subscriber ended up here e.g. from emails: // we won't show the modal to them in future since they most likely are already a subscriber. function skipModal() { const url = new URL( window.location.href ); if ( url.searchParams.has( skipUrlParam ) ) { url.searchParams.delete( skipUrlParam ); window.history.replaceState( {}, '', url ); storeCloseTimestamp(); return true; } return false; } if ( ! modal || ! hasEnoughTimePassed() || skipModal() ) { return; } const modalLoadTimeout = setTimeout( openModal, Jetpack_Subscriptions.modalLoadTime ); const targetElement = ( document.querySelector( '.entry-content' ) || document.documentElement ).getBoundingClientRect(); function hasPassedScrollThreshold() { const scrollPosition = window.scrollY + window.innerHeight / 2; const scrollPositionThreshold = targetElement.top + ( targetElement.height * Jetpack_Subscriptions.modalScrollThreshold ) / 100; return scrollPosition > scrollPositionThreshold; } function onScroll() { requestAnimationFrame( () => { if ( hasPassedScrollThreshold() ) { openModal(); } } ); } window.addEventListener( 'scroll', onScroll, { passive: true } ); // This take care of the case where the user has multiple tabs open. function onLocalStorage( event ) { if ( event.key === modalDismissedCookie ) { closeModal(); removeEventListeners(); } } window.addEventListener( 'storage', onLocalStorage ); // When the form is submitted, and next modal loads, it'll fire "subscription-modal-loaded" signalling that this form can be hidden. const form = modal.querySelector( 'form' ); if ( form ) { form.addEventListener( 'subscription-modal-loaded', closeModal ); } // User can edit modal, and could remove close link. function onCloseButtonClick( event ) { event.preventDefault(); closeModal(); } const close = document.getElementsByClassName( 'jetpack-subscribe-modal__close' )[ 0 ]; if ( close ) { close.addEventListener( 'click', onCloseButtonClick ); } function closeOnWindowClick( event ) { if ( event.target === modal ) { closeModal(); } } function closeModalOnEscapeKeydown( event ) { if ( event.key === 'Escape' ) { closeModal(); } } function openModal() { // If the user is typing in a form, don't open the modal or has anything else focused. if ( document.activeElement && document.activeElement.tagName !== 'BODY' ) { return; } modal.classList.add( 'open' ); document.body.classList.add( 'jetpack-subscribe-modal-open' ); window.addEventListener( 'keydown', closeModalOnEscapeKeydown ); window.addEventListener( 'click', closeOnWindowClick ); removeEventListeners(); } function closeModal() { modal.classList.remove( 'open' ); document.body.classList.remove( 'jetpack-subscribe-modal-open' ); window.removeEventListener( 'keydown', closeModalOnEscapeKeydown ); window.removeEventListener( 'storage', onLocalStorage ); window.removeEventListener( 'click', closeOnWindowClick ); storeCloseTimestamp(); } // Remove all event listeners. That would add the modal again. function removeEventListeners() { window.removeEventListener( 'scroll', onScroll ); clearTimeout( modalLoadTimeout ); } function storeCloseTimestamp() { localStorage.setItem( modalDismissedCookie, Date.now() ); } } ); subscribe-modal/class-jetpack-subscribe-modal.php 0000644 00000022735 14722071517 0016144 0 ustar 00 <?php /** * Adds support for Jetpack Subscribe Modal feature * * @package automattic/jetpack-mu-wpcom * @since 12.4 */ use Automattic\Jetpack\Extensions\Premium_Content\Subscription_Service\Abstract_Token_Subscription_Service; use const Automattic\Jetpack\Extensions\Subscriptions\META_NAME_FOR_POST_LEVEL_ACCESS_SETTINGS; /** * Jetpack_Subscribe_Modal class. */ class Jetpack_Subscribe_Modal { /** * Jetpack_Subscribe_Modal singleton instance. * * @var Jetpack_Subscribe_Modal|null */ private static $instance; /** * Jetpack_Subscribe_Modal instance init. */ public static function init() { if ( self::$instance === null ) { self::$instance = new Jetpack_Subscribe_Modal(); } return self::$instance; } const BLOCK_TEMPLATE_PART_SLUG = 'jetpack-subscribe-modal'; /** * Returns the block template part ID. * * @return string */ public static function get_block_template_part_id() { return get_stylesheet() . '//' . self::BLOCK_TEMPLATE_PART_SLUG; } /** * Jetpack_Subscribe_Modal class constructor. */ public function __construct() { if ( get_option( 'sm_enabled', false ) ) { add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_assets' ) ); add_action( 'wp_footer', array( $this, 'add_subscribe_modal_to_frontend' ) ); } add_filter( 'get_block_template', array( $this, 'get_block_template_filter' ), 10, 3 ); } /** * Enqueues JS to load modal. * * @return void */ public function enqueue_assets() { if ( $this->should_user_see_modal() ) { wp_enqueue_style( 'subscribe-modal-css', plugins_url( 'subscribe-modal.css', __FILE__ ), array(), JETPACK__VERSION ); wp_enqueue_script( 'subscribe-modal-js', plugins_url( 'subscribe-modal.js', __FILE__ ), array( 'wp-dom-ready' ), JETPACK__VERSION, true ); /** * Filter how many milliseconds until the Subscribe Modal appears. * * @module subscriptions * * @since 13.4 * * @param int 60000 Time in milliseconds for the Subscribe Modal to appear. */ $load_time = absint( apply_filters( 'jetpack_subscribe_modal_load_time', 60000 ) ); /** * Filter how many percentage of the page should be scrolled before the Subscribe Modal appears. * * @module subscriptions * * @since 13.6 * * @param int Percentage of the page scrolled before the Subscribe Modal appears. */ $scroll_threshold = absint( apply_filters( 'jetpack_subscribe_modal_scroll_threshold', 50 ) ); /** * Filter to control the interval at which the subscribe modal is shown to the same user. The default interval is 24 hours. * * @since 13.7 * * @param int 24 Hours before we show the same user the Subscribe Modal to again. */ $modal_interval = absint( apply_filters( 'jetpack_subscribe_modal_interval', 24 ) ); wp_localize_script( 'subscribe-modal-js', 'Jetpack_Subscriptions', array( 'modalLoadTime' => $load_time, 'modalScrollThreshold' => $scroll_threshold, 'modalInterval' => ( $modal_interval * HOUR_IN_SECONDS * 1000 ), ) ); } } /** * Adds modal with Subscribe Modal content. * * @return void */ public function add_subscribe_modal_to_frontend() { if ( $this->should_user_see_modal() ) { ?> <div class="jetpack-subscribe-modal"> <div class="jetpack-subscribe-modal__modal-content"> <?php block_template_part( self::BLOCK_TEMPLATE_PART_SLUG ); ?> </div> </div> <?php } } /** * Makes get_block_template return the WP_Block_Template for the Subscribe Modal. * * @param WP_Block_Template $block_template The block template to be returned. * @param string $id Template unique identifier (example: theme_slug//template_slug). * @param string $template_type Template type: `'wp_template'` or '`wp_template_part'`. * * @return WP_Block_Template */ public function get_block_template_filter( $block_template, $id, $template_type ) { if ( empty( $block_template ) && $template_type === 'wp_template_part' ) { if ( $id === self::get_block_template_part_id() ) { return $this->get_template(); } } return $block_template; } /** * Returns a custom template for the Subscribe Modal. * * @return WP_Block_Template */ public function get_template() { $template = new WP_Block_Template(); $template->theme = get_stylesheet(); $template->slug = self::BLOCK_TEMPLATE_PART_SLUG; $template->id = self::get_block_template_part_id(); $template->area = 'uncategorized'; $template->content = $this->get_subscribe_template_content(); $template->source = 'plugin'; $template->type = 'wp_template_part'; $template->title = __( 'Jetpack Subscribe modal', 'jetpack' ); $template->status = 'publish'; $template->has_theme_file = false; $template->is_custom = true; $template->description = __( 'A subscribe form that pops up when someone visits your site.', 'jetpack' ); return $template; } /** * Returns the initial content of the Subscribe Modal template. * This can then be edited by the user. * * @return string */ public function get_subscribe_template_content() { // translators: %s is the name of the site. $discover_more_from = sprintf( __( 'Discover more from %s', 'jetpack' ), get_bloginfo( 'name' ) ); $continue_reading = __( 'Continue reading', 'jetpack' ); $subscribe_text = __( 'Subscribe now to keep reading and get access to the full archive.', 'jetpack' ); $group_block_name = esc_attr__( 'Subscription pop-up container', 'jetpack' ); return <<<HTML <!-- wp:group {"metadata":{"name":"$group_block_name"},"style":{"spacing":{"padding":{"top":"32px","bottom":"32px","left":"32px","right":"32px"},"margin":{"top":"0","bottom":"0"}},"border":{"color":"#dddddd","width":"1px"}},"layout":{"type":"constrained","contentSize":"450px"}} --> <div class="wp-block-group has-border-color" style="border-color:#dddddd;border-width:1px;margin-top:0;margin-bottom:0;padding-top:32px;padding-right:32px;padding-bottom:32px;padding-left:32px"> <!-- wp:heading {"textAlign":"center","style":{"typography":{"fontStyle":"normal","fontWeight":"600","fontSize":"26px"},"layout":{"selfStretch":"fit","flexSize":null},"spacing":{"margin":{"top":"4px","bottom":"10px"}}}} --> <h2 class="wp-block-heading has-text-align-center" style="margin-top:4px;margin-bottom:10px;font-size:26px;font-style:normal;font-weight:600">$discover_more_from</h2> <!-- /wp:heading --> <!-- wp:paragraph {"align":"center","style":{"typography":{"fontSize":"15px"},"spacing":{"margin":{"top":"4px","bottom":"0px"}}}} --> <p class='has-text-align-center' style='margin-top:4px;margin-bottom:1em;font-size:15px'>$subscribe_text</p> <!-- /wp:paragraph --> <!-- wp:jetpack/subscriptions {"borderRadius":50,"className":"is-style-compact","appSource":"subscribe-modal"} /--> <!-- wp:paragraph {"align":"center","style":{"spacing":{"margin":{"top":"20px"}},"typography":{"fontSize":"14px"}},"className":"jetpack-subscribe-modal__close"} --> <p class="has-text-align-center jetpack-subscribe-modal__close" style="margin-top:20px;margin-bottom:0;font-size:14px"><a href="#">$continue_reading</a></p> <!-- /wp:paragraph --> </div> <!-- /wp:group --> HTML; } /** * Returns true if a site visitor should see * the Subscribe Modal. * * @return bool */ public function should_user_see_modal() { // Only show when viewing frontend single post. if ( is_admin() || ! is_singular( 'post' ) ) { return false; } // Needed because Elementor editor makes is_admin() return false // See https://coreysalzano.com/wordpress/why-elementor-disobeys-is_admin/ // Ignore nonce warning as just checking if is set // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['elementor-preview'] ) ) { return false; } // Don't show when previewing blog posts or site's theme // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['preview'] ) || isset( $_GET['theme_preview'] ) || isset( $_GET['customize_preview'] ) || isset( $_GET['hide_banners'] ) ) { return false; } // Don't show if one of subscribe query params is set. // They are set when user submits the subscribe form. // The nonce is checked elsewhere before redirect back to this page with query params. // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['subscribe'] ) || isset( $_GET['blogsub'] ) ) { return false; } // Don't show if post is for subscribers only or has paywall block global $post; if ( defined( 'Automattic\\Jetpack\\Extensions\\Subscriptions\\META_NAME_FOR_POST_LEVEL_ACCESS_SETTINGS' ) ) { $access_level = get_post_meta( $post->ID, META_NAME_FOR_POST_LEVEL_ACCESS_SETTINGS, true ); } else { $access_level = get_post_meta( $post->ID, '_jetpack_newsletter_access', true ); } require_once JETPACK__PLUGIN_DIR . 'extensions/blocks/premium-content/_inc/subscription-service/include.php'; $is_accessible_by_everyone = Abstract_Token_Subscription_Service::POST_ACCESS_LEVEL_EVERYBODY === $access_level || empty( $access_level ); if ( ! $is_accessible_by_everyone ) { return false; } // Don't show if user is subscribed to blog. require_once __DIR__ . '/../views.php'; if ( ! class_exists( 'Jetpack_Memberships' ) || Jetpack_Memberships::is_current_user_subscribed() ) { return false; } return true; } } Jetpack_Subscribe_Modal::init(); add_action( 'rest_api_switched_to_blog', function () { Jetpack_Subscribe_Modal::init(); } ); subscribe-modal/subscribe-modal.css 0000644 00000002141 14722071517 0013410 0 ustar 00 body.jetpack-subscribe-modal-open { overflow: hidden; } .jetpack-subscribe-modal { visibility: hidden; position: fixed; z-index: 50000; /* Same as WP.com Action bar */ left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: transparent; transition: all 0.4s; } .jetpack-subscribe-modal.open { background-color: rgba(0,0,0,0.3); visibility: visible; } .jetpack-subscribe-modal__modal-content { position: relative; visibility: hidden; overflow: hidden; top: 100%; background-color: #fefefe; margin: 15% auto; width: 100%; max-width: 600px; border-radius: 10px; box-sizing: border-box; transition: all 0.4s; text-wrap: balance; } .jetpack-subscribe-modal.open .jetpack-subscribe-modal__modal-content { top: 0; visibility: visible; } /* * These text-wrap properties still have limited browser * support, but based on feedback still adding them for when * they are supported. */ .jetpack-subscribe-modal__modal-content p { text-wrap: balance; text-wrap: pretty; } @media screen and (max-width: 640px) { .jetpack-subscribe-modal__modal-content { width: 94%; } } subscribe-floating-button/class-jetpack-subscribe-floating-button.php 0000644 00000013755 14722071517 0022206 0 ustar 00 <?php /** * Adds support for Jetpack floating Subscribe button feature * * @package automattic/jetpack-subscriptions * @since 14.0 */ /** * Jetpack_Subscribe_Floating_Button class. */ class Jetpack_Subscribe_Floating_Button { /** * Jetpack_Subscribe_Floating_Button singleton instance. * * @var Jetpack_Subscribe_Floating_Button|null */ private static $instance; /** * Jetpack_Subscribe_Floating_Button instance init. */ public static function init() { if ( self::$instance === null ) { self::$instance = new Jetpack_Subscribe_Floating_Button(); } return self::$instance; } const BLOCK_TEMPLATE_PART_SLUG = 'jetpack-subscribe-floating-button'; /** * Jetpack_Subscribe_Floating_Button class constructor. */ public function __construct() { if ( get_option( 'jetpack_subscribe_floating_button_enabled', false ) ) { add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_assets' ) ); add_action( 'wp_footer', array( $this, 'add_subscribe_floating_button_to_frontend' ) ); } add_filter( 'get_block_template', array( $this, 'get_block_template_filter' ), 10, 3 ); add_filter( 'jetpack_options_whitelist', function ( $options ) { $options[] = 'jetpack_subscribe_floating_button_enabled'; return $options; } ); } /** * Returns the block template part ID. * * @return string */ public static function get_block_template_part_id() { return get_stylesheet() . '//' . self::BLOCK_TEMPLATE_PART_SLUG; } /** * Makes get_block_template return the WP_Block_Template for the floating Subscribe button. * * @param WP_Block_Template $block_template The block template to be returned. * @param string $id Template unique identifier (example: theme_slug//template_slug). * @param string $template_type Template type: `'wp_template'` or '`wp_template_part'`. * * @return WP_Block_Template|null */ public function get_block_template_filter( $block_template, $id, $template_type ) { if ( empty( $block_template ) && $template_type === 'wp_template_part' ) { if ( $id === self::get_block_template_part_id() ) { return $this->get_template(); } } return $block_template; } /** * Returns a custom template for the floating Subscribe button. * * @return WP_Block_Template */ public function get_template() { $template = new WP_Block_Template(); $template->theme = get_stylesheet(); $template->slug = self::BLOCK_TEMPLATE_PART_SLUG; $template->id = self::get_block_template_part_id(); $template->area = 'uncategorized'; $template->content = $this->get_floating_subscribe_button_template_content(); $template->source = 'plugin'; $template->type = 'wp_template_part'; $template->title = __( 'Jetpack Subscribe floating button', 'jetpack' ); $template->status = 'publish'; $template->has_theme_file = false; $template->is_custom = true; $template->description = __( 'A floating subscribe button that shows up when someone visits your site.', 'jetpack' ); return $template; } /** * Returns the initial content of the floating Subscribe button template. * This can then be edited by the user. * * @return string */ public function get_floating_subscribe_button_template_content() { $block_name = esc_attr__( 'Floating subscribe button', 'jetpack' ); return '<!-- wp:jetpack/subscriptions {"className":"is-style-button","appSource":"subscribe-floating-button","lock":{"move":false,"remove":true},"style":{"spacing":{"margin":{"right":"20px","left":"20px","top":"20px","bottom":"20px"}}},"metadata":{"name":"' . $block_name . '"}} /-->'; } /** * Enqueues styles. * * @return void */ public function enqueue_assets() { if ( $this->should_user_see_floating_button() ) { wp_enqueue_style( 'subscribe-floating-button-css', plugins_url( 'subscribe-floating-button.css', __FILE__ ), array(), JETPACK__VERSION ); // Disables WP.com action bar as the features collide/overlap add_filter( 'wpcom_disable_logged_out_follow', '__return_true', 10, 1 ); } } /** * Adds floating Subscribe button HTML wrapper * * @return void */ public function add_subscribe_floating_button_to_frontend() { if ( $this->should_user_see_floating_button() ) { ?> <div class="jetpack-subscribe-floating-button"> <?php block_template_part( self::BLOCK_TEMPLATE_PART_SLUG ); ?> </div> <?php } } /** * Returns true if a site visitor should see * the floating Subscribe button. * * @return bool */ public function should_user_see_floating_button() { // Only show when viewing frontend. if ( is_admin() ) { return false; } // Needed because Elementor editor makes is_admin() return false // See https://coreysalzano.com/wordpress/why-elementor-disobeys-is_admin/ // Ignore nonce warning as just checking if is set // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['elementor-preview'] ) ) { return false; } // Don't show when previewing blog posts or site's theme // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['preview'] ) || isset( $_GET['theme_preview'] ) || isset( $_GET['customize_preview'] ) || isset( $_GET['hide_banners'] ) ) { return false; } // Don't show if one of subscribe query params is set. // They are set when user submits the subscribe form. // The nonce is checked elsewhere before redirect back to this page with query params. // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['subscribe'] ) || isset( $_GET['blogsub'] ) ) { return false; } // Don't show if user is subscribed to blog. require_once __DIR__ . '/../views.php'; if ( ! class_exists( 'Jetpack_Memberships' ) || Jetpack_Memberships::is_current_user_subscribed() ) { return false; } return true; } } Jetpack_Subscribe_Floating_Button::init(); add_action( 'rest_api_switched_to_blog', function () { Jetpack_Subscribe_Floating_Button::init(); } ); subscribe-floating-button/subscribe-floating-button.css 0000644 00000000345 14722071517 0017454 0 ustar 00 .jetpack-subscribe-floating-button { position: fixed; z-index: 50000; /* Same as WP.com Action bar */ bottom: 0; right: 0; } @media screen and (max-width: 640px) { .jetpack-subscribe-floating-button { display: none; } } jetpack-user-content-link-redirection.php 0000644 00000005335 14722071517 0014576 0 ustar 00 <?php /** * User Content Link Redirection * * The purpose of this file is to track and redirect user content links in emails. * This renders an iframe pointing to subscribe.wordpress.com which will track and * return the destination url for the iframe parent to redirect to. * * @package automattic/jetpack */ use Automattic\Jetpack\Connection\Manager as Connection_Manager; /** * Render a page with an iframe to track and redirect user content links in emails. * * Hooked to the `init` action, this function renders a page with an iframe pointing to * subscribe.wordpress.com to track and return the destination URL for redirection. * * Redirects to the site's home page if required parameters are missing. * Returns a 400 error if the request's `blog_id` doesn't match the actual `blog_id`. * * @return never */ function jetpack_user_content_link_redirection() { // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( empty( $_SERVER['QUERY_STRING'] ) || empty( $_SERVER['HTTP_HOST'] ) || empty( $_GET['blog_id'] ) ) { wp_safe_redirect( get_home_url() ); exit(); } // phpcs:ignore WordPress.Security.NonceVerification.Recommended $request_blog_id = intval( sanitize_text_field( wp_unslash( $_GET['blog_id'] ) ) ); $actual_blog_id = Connection_Manager::get_site_id( true ); if ( $actual_blog_id !== $request_blog_id ) { wp_die( esc_html__( 'Invalid link.', 'jetpack' ), 400 ); exit(); } $query_params = sanitize_text_field( wp_unslash( $_SERVER['QUERY_STRING'] ) ); $iframe_url = "https://subscribe.wordpress.com/?$query_params"; // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped echo <<<EOF <!DOCTYPE html> <html> <head> <script> let messageReceived = false; window.addEventListener( 'message', function(event) { if ( event.origin !== 'https://subscribe.wordpress.com' || messageReceived ) { return; } if ( event.data.redirectUrl ) { messageReceived = true; window.location.href = event.data.redirectUrl; } } ); </script> </head> <body> EOF; echo '<iframe id="user-content-link-redirection" hidden aria-hidden="true" tabindex="-1" width="0" height="0" style="display: none" src="' . esc_url( $iframe_url ) . '"></iframe>'; echo <<<EOF </body> </html> EOF; // phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped exit; } // The WPCOM_USER_CONTENT_LINK_REDIRECTION flag prevents this redirection logic from running // on Atomic in case we'd like to override the redirection logic on the Atomic end. // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( ! defined( 'WPCOM_USER_CONTENT_LINK_REDIRECTION' ) && isset( $_GET['action'] ) && $_GET['action'] === 'user_content_redirect' ) { add_action( 'init', 'jetpack_user_content_link_redirection' ); } subscribe-overlay/class-jetpack-subscribe-overlay.php 0000644 00000016520 14722071517 0017111 0 ustar 00 <?php /** * Adds support for Jetpack Subscribe Overlay feature * * @package automattic/jetpack-subscriptions * @since 13.5 */ /** * Jetpack_Subscribe_Overlay class. */ class Jetpack_Subscribe_Overlay { /** * Jetpack_Subscribe_Overlay singleton instance. * * @var Jetpack_Subscribe_Overlay|null */ private static $instance; /** * Jetpack_Subscribe_Overlay instance init. */ public static function init() { if ( self::$instance === null ) { self::$instance = new Jetpack_Subscribe_Overlay(); } return self::$instance; } const BLOCK_TEMPLATE_PART_SLUG = 'jetpack-subscribe-overlay'; /** * Jetpack_Subscribe_Overlay class constructor. */ public function __construct() { if ( get_option( 'jetpack_subscribe_overlay_enabled', false ) ) { add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_assets' ) ); add_action( 'wp_footer', array( $this, 'add_subscribe_overlay_to_frontend' ) ); } add_filter( 'get_block_template', array( $this, 'get_block_template_filter' ), 10, 3 ); add_filter( 'jetpack_options_whitelist', function ( $options ) { $options[] = 'jetpack_subscribe_overlay_enabled'; return $options; } ); } /** * Returns the block template part ID. * * @return string */ public static function get_block_template_part_id() { return get_stylesheet() . '//' . self::BLOCK_TEMPLATE_PART_SLUG; } /** * Makes get_block_template return the WP_Block_Template for the Subscribe Overlay. * * @param WP_Block_Template $block_template The block template to be returned. * @param string $id Template unique identifier (example: theme_slug//template_slug). * @param string $template_type Template type: `'wp_template'` or '`wp_template_part'`. * * @return WP_Block_Template|null */ public function get_block_template_filter( $block_template, $id, $template_type ) { if ( empty( $block_template ) && $template_type === 'wp_template_part' ) { if ( $id === self::get_block_template_part_id() ) { return $this->get_template(); } } return $block_template; } /** * Returns a custom template for the Subscribe Overlay. * * @return WP_Block_Template */ public function get_template() { $template = new WP_Block_Template(); $template->theme = get_stylesheet(); $template->slug = self::BLOCK_TEMPLATE_PART_SLUG; $template->id = self::get_block_template_part_id(); $template->area = 'uncategorized'; $template->content = $this->get_subscribe_overlay_template_content(); $template->source = 'plugin'; $template->type = 'wp_template_part'; $template->title = __( 'Jetpack Subscribe overlay', 'jetpack' ); $template->status = 'publish'; $template->has_theme_file = false; $template->is_custom = true; $template->description = __( 'An overlay that shows up when someone visits your site.', 'jetpack' ); return $template; } /** * Returns the initial content of the Subscribe Overlay template. * This can then be edited by the user. * * @return string */ public function get_subscribe_overlay_template_content() { $home_url = get_home_url(); $site_tagline = get_bloginfo( 'description' ); $default_tagline = __( 'Stay informed with curated content and the latest headlines, all delivered straight to your inbox. Subscribe now to stay ahead and never miss a beat!', 'jetpack' ); $tagline_block = empty( $site_tagline ) ? '<!-- wp:paragraph {"align":"center","fontSize":"medium"} --><p class="has-text-align-center has-medium-font-size">' . $default_tagline . '</p><!-- /wp:paragraph -->' : '<!-- wp:site-tagline {"textAlign":"center","fontSize":"medium"} /-->'; $skip_to_content = __( 'Skip to content', 'jetpack' ); $group_block_name = esc_attr__( 'Subscribe overlay container', 'jetpack' ); return <<<HTML <!-- wp:group {"metadata":{"name":"$group_block_name"},"style":{"spacing":{"padding":{"top":"0","bottom":"0","left":"0","right":"0"}}},"layout":{"type":"constrained","contentSize":"400px"}} --> <div class="wp-block-group" style="padding-top:0;padding-right:0;padding-bottom:0;padding-left:0"> <!-- wp:site-logo {"width":90,"isLink":false,"shouldSyncIcon":true,"align":"center","className":"is-style-rounded"} /--> <!-- wp:site-title {"textAlign":"center","isLink":false,"fontSize":"x-large"} /--> $tagline_block <!-- wp:jetpack/subscriptions {"appSource":"subscribe-overlay"} /--> <!-- wp:paragraph {"align":"center","className":"jetpack-subscribe-overlay__to-content"} --> <p class="has-text-align-center jetpack-subscribe-overlay__to-content"><a href="$home_url">$skip_to_content ↓</a></p> <!-- /wp:paragraph --> </div> <!-- /wp:group --> HTML; } /** * Enqueues JS to load overlay. * * @return void */ public function enqueue_assets() { if ( $this->should_user_see_overlay() ) { wp_enqueue_style( 'subscribe-overlay-css', plugins_url( 'subscribe-overlay.css', __FILE__ ), array(), JETPACK__VERSION ); wp_enqueue_script( 'subscribe-overlay-js', plugins_url( 'subscribe-overlay.js', __FILE__ ), array( 'wp-dom-ready' ), JETPACK__VERSION, true ); } } /** * Adds overlay with Subscribe Overlay content. * * @return void */ public function add_subscribe_overlay_to_frontend() { if ( $this->should_user_see_overlay() ) { ?> <div class="jetpack-subscribe-overlay"> <div class="jetpack-subscribe-overlay__close"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> <path d="M5.40456 5L19 19M5 19L18.5954 5" stroke="currentColor" stroke-width="1.5"/> </svg> </div> <div class="jetpack-subscribe-overlay__content"> <?php block_template_part( self::BLOCK_TEMPLATE_PART_SLUG ); ?> </div> </div> <?php } } /** * Returns true if a site visitor should see * the Subscribe Overlay. * * @return bool */ public function should_user_see_overlay() { // Only show when viewing frontend. if ( is_admin() ) { return false; } // Needed because Elementor editor makes is_admin() return false // See https://coreysalzano.com/wordpress/why-elementor-disobeys-is_admin/ // Ignore nonce warning as just checking if is set // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['elementor-preview'] ) ) { return false; } // Don't show when previewing blog posts or site's theme // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['preview'] ) || isset( $_GET['theme_preview'] ) || isset( $_GET['customize_preview'] ) || isset( $_GET['hide_banners'] ) ) { return false; } // Don't show if one of subscribe query params is set. // They are set when user submits the subscribe form. // The nonce is checked elsewhere before redirect back to this page with query params. // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['subscribe'] ) || isset( $_GET['blogsub'] ) ) { return false; } // Don't show if user is subscribed to blog. require_once __DIR__ . '/../views.php'; if ( ! class_exists( 'Jetpack_Memberships' ) || Jetpack_Memberships::is_current_user_subscribed() ) { return false; } return is_home() || is_front_page(); } } Jetpack_Subscribe_Overlay::init(); add_action( 'rest_api_switched_to_blog', function () { Jetpack_Subscribe_Overlay::init(); } ); subscribe-overlay/subscribe-overlay.css 0000644 00000003224 14722071517 0014365 0 ustar 00 body.jetpack-subscribe-overlay-open { overflow: hidden; } .jetpack-subscribe-overlay { --jetpack-subscribe-overlay--background-color: var(--wp--preset--color--background, var(--wp--preset--color--base, var(--wp--preset--color--contrast, #F9F9F9))); visibility: hidden; position: fixed; z-index: 50001; /* WP.com Action bar and floating subscribe button are 5000 */ left: 0; top: 0; width: 100%; height: 100%; overflow: hidden; background-color: transparent; transition: background-color 0.4s, visibility 0.4s; } .jetpack-subscribe-overlay__content { position: relative; visibility: hidden; overflow: hidden; top: 100%; margin: 15% auto; width: 100%; max-width: 400px; transition: top 0.4s, visibility 0.4s; text-wrap: pretty; } .jetpack-subscribe-overlay__close { display: none; cursor: pointer; position: absolute; top: 32px; right: 32px; width: 24px; height: 24px; } body.admin-bar .jetpack-subscribe-overlay__close { top: 64px; } body.has-marketing-bar .jetpack-subscribe-overlay__close { top: 81px; } body.admin-bar.has-marketing-bar .jetpack-subscribe-overlay__close { top: 114px; } .jetpack-subscribe-overlay__to-content { display: none; position: fixed; bottom: 64px; left: 0; right: 0; margin: 0 auto; } .jetpack-subscribe-overlay.open { background-color: var(--jetpack-subscribe-overlay--background-color); visibility: visible; .jetpack-subscribe-overlay__content { top: 0; visibility: visible; } .jetpack-subscribe-overlay__close { display: block; } .jetpack-subscribe-overlay__to-content { display: block; } } @media screen and (max-width: 640px) { .jetpack-subscribe-overlay__content { width: 94%; } } subscribe-overlay/subscribe-overlay.js 0000644 00000004324 14722071517 0014213 0 ustar 00 const { domReady } = wp; domReady( function () { const overlay = document.querySelector( '.jetpack-subscribe-overlay' ); const overlayDismissedCookie = 'jetpack_post_subscribe_overlay_dismissed'; const skipUrlParam = 'jetpack_skip_subscription_popup'; const hasOverlayDismissedCookie = document.cookie && document.cookie.indexOf( overlayDismissedCookie ) > -1; // Subscriber ended up here e.g. from emails: // we won't show the overlay to them in future since they most likely are already a subscriber. function skipOverlay() { const url = new URL( window.location.href ); if ( url.searchParams.has( skipUrlParam ) ) { url.searchParams.delete( skipUrlParam ); window.history.replaceState( {}, '', url ); setOverlayDismissedCookie(); return true; } return false; } if ( ! overlay || hasOverlayDismissedCookie || skipOverlay() ) { return; } const close = overlay.querySelector( '.jetpack-subscribe-overlay__close' ); close.onclick = function ( event ) { event.preventDefault(); closeOverlay(); }; const toContent = overlay.querySelector( '.jetpack-subscribe-overlay__to-content' ); // User can edit overlay, and could remove to content link. if ( toContent ) { toContent.onclick = function ( event ) { event.preventDefault(); closeOverlay(); }; } // When the form is submitted, and next modal loads, it'll fire "subscription-modal-loaded" signalling that this form can be hidden. const form = overlay.querySelector( 'form' ); if ( form ) { form.addEventListener( 'subscription-modal-loaded', closeOverlay ); } function closeOverlayOnEscapeKeydown( event ) { if ( event.key === 'Escape' ) { closeOverlay(); } } function openOverlay() { overlay.classList.add( 'open' ); document.body.classList.add( 'jetpack-subscribe-overlay-open' ); setOverlayDismissedCookie(); window.addEventListener( 'keydown', closeOverlayOnEscapeKeydown ); } function closeOverlay() { overlay.classList.remove( 'open' ); document.body.classList.remove( 'jetpack-subscribe-overlay-open' ); window.removeEventListener( 'keydown', closeOverlayOnEscapeKeydown ); } function setOverlayDismissedCookie() { document.cookie = `${ overlayDismissedCookie }=true; path=/;`; } openOverlay(); } );
| ver. 1.4 |
Github
|
.
| PHP 7.4.3-4ubuntu2.24 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка