Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
2.84% covered (danger)
2.84%
17 / 598
15.00% covered (danger)
15.00%
3 / 20
CRAP
0.00% covered (danger)
0.00%
0 / 1
get_jetpack_blog_subscriptions_widget_classname
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
jetpack_do_subscription_form
0.00% covered (danger)
0.00%
0 / 90
0.00% covered (danger)
0.00%
0 / 1
1806
jetpack_blog_subscriptions_init
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
subscription_options_fallback
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
2
Jetpack_Subscriptions_Widget
1.64% covered (danger)
1.64%
8 / 487
12.50% covered (danger)
12.50%
2 / 16
17219.56
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
56
 hide_widget_in_block_editor
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 enqueue_style
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 widget
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
110
 render_widget_title
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 1
156
 render_widget_status_messages
0.00% covered (danger)
0.00%
0 / 100
0.00% covered (danger)
0.00%
0 / 1
462
 get_redirect_fragment
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 render_widget_subscription_form
0.00% covered (danger)
0.00%
0 / 145
0.00% covered (danger)
0.00%
0 / 1
1640
 is_current_user_subscribed
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
42
 is_wpcom
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 is_jetpack
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 wpcom_has_status_message
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
6
 fetch_subscriber_count
26.09% covered (danger)
26.09%
6 / 23
0.00% covered (danger)
0.00%
0 / 1
26.79
 update
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
56
 defaults
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 form
0.00% covered (danger)
0.00%
0 / 84
0.00% covered (danger)
0.00%
0 / 1
182
1<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
3// phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed -- TODO: Move classes to appropriately-named class files.
4
5use Automattic\Jetpack\Assets;
6
7if ( ! defined( 'ABSPATH' ) ) {
8    exit( 0 );
9}
10
11/**
12 * Jetpack_Subscriptions_Widget main view class.
13 */
14class Jetpack_Subscriptions_Widget extends WP_Widget {
15
16    const ID_BASE = 'blog_subscription';
17
18    /**
19     * Track number of rendered Subscription widgets. The count is used for class names and widget IDs.
20     *
21     * @var int
22     */
23    public static $instance_count = 0;
24
25    /**
26     * When printing the submit button, what tags are allowed.
27     *
28     * @var array
29     */
30    public static $allowed_html_tags_for_submit_button = array(
31        'br'     => array(),
32        's'      => array(),
33        'strong' => array(),
34        'em'     => array(),
35    );
36
37    /**
38     * Use this variable when printing the message after submitting an email in subscription widgets
39     *
40     * @var array what tags are allowed
41     */
42    public static $allowed_html_tags_for_message = array(
43        'a'  => array(
44            'href'   => array(),
45            'title'  => array(),
46            'rel'    => array(),
47            'target' => array(),
48        ),
49        'br' => array(),
50    );
51
52    /**
53     * Jetpack_Subscriptions_Widget constructor.
54     */
55    public function __construct() {
56        $widget_ops = array(
57            'classname'                   => 'widget_blog_subscription jetpack_subscription_widget',
58            'description'                 => __( 'Add an email signup form to allow people to subscribe to your blog.', 'jetpack' ),
59            'customize_selective_refresh' => true,
60            'show_instance_in_rest'       => true,
61        );
62
63        $name = self::is_jetpack() ?
64            /** This filter is documented in modules/widgets/facebook-likebox.php */
65            apply_filters( 'jetpack_widget_name', __( 'Blog Subscriptions', 'jetpack' ) ) :
66            __( 'Follow Blog', 'jetpack' );
67
68        parent::__construct(
69            'blog_subscription',
70            $name,
71            $widget_ops
72        );
73
74        if (
75            self::is_jetpack()
76            && (
77                is_active_widget( false, false, $this->id_base ) ||
78                is_active_widget( false, false, 'monster' ) ||
79                is_customize_preview()
80            )
81            && ! wp_is_block_theme()
82        ) {
83            add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_style' ) );
84        }
85
86        add_filter( 'widget_types_to_hide_from_legacy_widget_block', array( $this, 'hide_widget_in_block_editor' ) );
87    }
88
89    /**
90     * Remove the "Blog Subscription" widget from the Legacy Widget block
91     *
92     * @param array $widget_types List of widgets that are currently removed from the Legacy Widget block.
93     * @return array $widget_types New list of widgets that will be removed.
94     */
95    public function hide_widget_in_block_editor( $widget_types ) {
96        $widget_types[] = self::ID_BASE;
97        return $widget_types;
98    }
99
100    /**
101     * Enqueue the form's CSS.
102     *
103     * @since 4.5.0
104     */
105    public function enqueue_style() {
106        $path = Assets::get_file_url_for_environment(
107            '_inc/build/subscriptions/subscriptions.min.css',
108            'modules/subscriptions/subscriptions.css'
109        );
110
111        wp_enqueue_style(
112            'jetpack-subscriptions',
113            $path,
114            array(),
115            JETPACK__VERSION
116        );
117        wp_style_add_data( 'jetpack-subscriptions', 'path', $path );
118    }
119
120    /**
121     * Renders a full widget either within the context of WordPress widget, or in response to a shortcode.
122     *
123     * @param array $args Display arguments including 'before_title', 'after_title', 'before_widget', and 'after_widget'.
124     * @param array $instance The settings for the particular instance of the widget.
125     */
126    public function widget( $args, $instance ) {
127        if ( self::is_wpcom() && ! self::wpcom_has_status_message() && self::is_current_user_subscribed() ) {
128            return null;
129        }
130
131        // Enqueue styles.
132        self::enqueue_style();
133
134        if ( self::is_jetpack() &&
135            /** This filter is documented in \Automattic\Jetpack\Forms\ContactForm\Contact_Form */
136            false === apply_filters( 'jetpack_auto_fill_logged_in_user', false )
137        ) {
138            $subscribe_email = '';
139        } else {
140            $current_user = wp_get_current_user();
141            if ( ! empty( $current_user->user_email ) ) {
142                $subscribe_email = esc_attr( $current_user->user_email );
143            } else {
144                $subscribe_email = '';
145            }
146        }
147
148        $stats_action = self::is_jetpack() ? 'jetpack_subscriptions' : 'follow_blog';
149        /** This action is documented in modules/widgets/gravatar-profile.php */
150        do_action( 'jetpack_stats_extra', 'widget_view', $stats_action );
151
152        $after_widget  = isset( $args['after_widget'] ) ? $args['after_widget'] : '';
153        $before_widget = isset( $args['before_widget'] ) ? $args['before_widget'] : '';
154        $instance      = wp_parse_args( (array) $instance, static::defaults() );
155
156        echo $before_widget; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
157
158        ++self::$instance_count;
159
160        self::render_widget_title( $args, $instance );
161
162        self::render_widget_status_messages( $instance );
163
164        self::render_widget_subscription_form( $args, $instance, $subscribe_email );
165
166        echo "\n" . $after_widget; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
167    }
168
169    /**
170     * Prints the widget's title. If show_only_email_and_button is true, we will not show a title.
171     *
172     * @param array $args Display arguments including 'before_title', 'after_title', 'before_widget', and 'after_widget'.
173     * @param array $instance The settings for the particular instance of the widget.
174     */
175    public static function render_widget_title( $args, $instance ) {
176        $show_only_email_and_button = $instance['show_only_email_and_button'];
177        $before_title               = isset( $args['before_title'] ) ? $args['before_title'] : '';
178        $after_title                = isset( $args['after_title'] ) ? $args['after_title'] : '';
179        if ( self::is_wpcom() && ! $show_only_email_and_button ) {
180            if ( self::is_current_user_subscribed() ) {
181                if ( ! empty( $instance['title_following'] ) ) {
182                    printf(
183                        '%1$s<label for="subscribe-field%2$s">%3$s</label>%4$s%5$s',
184                        $before_title, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
185                        ( self::$instance_count > 1 ? '-' . (int) self::$instance_count : '' ),
186                        esc_html( $instance['title_following'] ),
187                        $after_title, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
188                        "\n"
189                    );
190                }
191            } elseif ( ! empty( $instance['title'] ) ) {
192                printf(
193                    '%1$s<label for="subscribe-field%2$s">%3$s</label>%4$s%5$s',
194                    $before_title, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
195                    ( self::$instance_count > 1 ? '-' . (int) self::$instance_count : '' ),
196                    esc_html( $instance['title'] ),
197                    $after_title, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
198                    "\n"
199                );
200            }
201        }
202
203        if ( self::is_jetpack() && empty( $instance['show_only_email_and_button'] ) ) {
204            printf(
205                '%1$s%2$s%3$s%4$s',
206                $before_title, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
207                esc_html( $instance['title'] ),
208                $after_title, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
209                "\n"
210            );
211        }
212    }
213
214    /**
215     * Prints the subscription block's status messages after someone has attempted to subscribe.
216     * Either a success message or an error message.
217     *
218     * @param array $instance The settings for the particular instance of the widget.
219     */
220    public static function render_widget_status_messages( $instance ) {
221        if ( self::is_jetpack() && isset( $_GET['subscribe'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Non-sensitive informational output.
222            $success_message   = isset( $instance['success_message'] ) ? stripslashes( $instance['success_message'] ) : '';
223            $subscribers_total = self::fetch_subscriber_count();
224
225            switch ( $_GET['subscribe'] ) : // phpcs:ignore WordPress.Security.NonceVerification.Recommended
226                case 'invalid_email':
227                    ?>
228                    <p class="error"><?php esc_html_e( 'Oops! The email you used is invalid. Please try again.', 'jetpack' ); ?></p>
229                    <?php
230                    break;
231                case 'opted_out':
232                    ?>
233                    <p class="error">
234                    <?php
235                    printf(
236                        wp_kses(
237                            /* translators: 1: Link to Subscription Management page https://subscribe.wordpress.com/, 2: Description of this link. */
238                            __( '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' ),
239                            self::$allowed_html_tags_for_message
240                        ),
241                        'https://subscribe.wordpress.com/',
242                        esc_attr__( 'Subscriptions Manager', 'jetpack' )
243                    );
244                    ?>
245                    </p>
246                    <?php
247                    break;
248                case 'already':
249                    ?>
250                    <p class="error">
251                    <?php
252                    printf(
253                        wp_kses(
254                            /* translators: 1: Link to Subscription Management page https://subscribe.wordpress.com/, 2: Description of this link. */
255                            __( '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' ),
256                            self::$allowed_html_tags_for_message
257                        ),
258                        'https://subscribe.wordpress.com/',
259                        esc_attr__( 'Subscriptions Manager', 'jetpack' )
260                    );
261                    ?>
262                                        </p>
263                    <?php
264                    break;
265                case 'many_pending_subs':
266                    ?>
267                    <p class="error">
268                        <?php
269                        printf(
270                            wp_kses(
271                                /* translators: 1: Link to Subscription Management page https://subscribe.wordpress.com/, 2: Description of this link */
272                                __( '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' ),
273                                self::$allowed_html_tags_for_message
274                            ),
275                            'https://subscribe.wordpress.com/',
276                            esc_attr__( 'Subscriptions Manager', 'jetpack' )
277                        );
278                        ?>
279                    </p>
280                    <?php
281                    break;
282                case 'pending':
283                    ?>
284                    <p class="error">
285                        <?php
286                        printf(
287                            wp_kses(
288                                /* translators: 1: Link to Subscription Management page https://subscribe.wordpress.com/, 2: Description of this link */
289                                __( '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' ),
290                                self::$allowed_html_tags_for_message
291                            ),
292                            'https://subscribe.wordpress.com/',
293                            esc_attr__( 'Subscriptions Manager', 'jetpack' )
294                        );
295                        ?>
296                    </p>
297                    <?php
298                    break;
299                case 'success':
300                    ?>
301                    <div class="success"><?php echo wp_kses( wpautop( str_replace( '[total-subscribers]', number_format_i18n( $subscribers_total ), $success_message ) ), 'post' ); ?></div>
302                    <?php
303                    break;
304                default:
305                    ?>
306                    <p class="error"><?php esc_html_e( 'Oops! There was an error when subscribing. Please try again.', 'jetpack' ); ?></p>
307                    <?php
308                    break;
309            endswitch;
310        }
311
312        if ( self::is_wpcom() && self::wpcom_has_status_message() ) {
313            global $themecolors;
314            $message = '';
315
316            switch ( $_GET['blogsub'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
317                case 'confirming':
318                    $message = __( 'Thank you! You can now check your email to confirm your subscription.', 'jetpack' );
319                    break;
320                case 'blocked':
321                    $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' );
322                    break;
323                case 'flooded':
324                    $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' );
325                    break;
326                case 'spammed':
327                    /* translators: %s is a URL */
328                    $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/' );
329                    break;
330                case 'subscribed':
331                    $message = __( 'Hey! You were already subscribed.', 'jetpack' );
332                    break;
333                case 'pending':
334                    $message = __( 'It seems you already tried to subscribe. We just sent you another email so you can confirm the subscription.', 'jetpack' );
335                    break;
336                case 'confirmed':
337                    $message = __( 'Cool! You are now subscribed. Now you can check your email for more details and how to manage the subscription.', 'jetpack' );
338                    break;
339            }
340
341            $border_color = isset( $themecolors['border'] ) ? " #{$themecolors['border']}" : '';
342
343            $redirect_fragment = self::get_redirect_fragment();
344            printf(
345                '<div id="%1$s" class="jetpack-sub-notification">%3$s</div>',
346                esc_attr( $redirect_fragment ),
347                esc_attr( $border_color ),
348                wp_kses_post( $message )
349            );
350        }
351    }
352
353    /**
354     * Generates the redirect fragment used after form submission.
355     *
356     * @param string $id is the specific id that will appear in the redirect fragment. If none is provided self::$instance_count will be used.
357     */
358    protected static function get_redirect_fragment( $id = null ) {
359        if ( $id === null ) {
360            return 'subscribe-blog' . ( self::$instance_count > 1 ? '-' . self::$instance_count : '' );
361        }
362
363        return 'subscribe-blog-' . $id;
364    }
365
366    /**
367     * Renders a form allowing folks to subscribe to the blog.
368     *
369     * @param array  $args Display arguments including 'before_title', 'after_title', 'before_widget', and 'after_widget'.
370     * @param array  $instance The settings for the particular instance of the widget.
371     * @param string $subscribe_email The email to use to prefill the form.
372     */
373    public static function render_widget_subscription_form( $args, $instance, $subscribe_email ) {
374        $show_only_email_and_button   = $instance['show_only_email_and_button'];
375        $show_subscribers_total       = (bool) $instance['show_subscribers_total'];
376        $subscribers_total            = self::fetch_subscriber_count();
377        $subscribe_text               = empty( $instance['show_only_email_and_button'] ) ?
378            wp_kses_post( stripslashes( $instance['subscribe_text'] ) ) :
379            false;
380        $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'] ) : '' ) );
381        $source                       = 'widget';
382        $widget_id                    = ! empty( $args['widget_id'] ) ? $args['widget_id'] : self::$instance_count;
383        $subscribe_button             = ! empty( $instance['submit_button_text'] ) ? $instance['submit_button_text'] : $instance['subscribe_button'];
384        $subscribe_placeholder        = isset( $instance['subscribe_placeholder'] ) ? stripslashes( $instance['subscribe_placeholder'] ) : '';
385        $submit_button_classes        = isset( $instance['submit_button_classes'] ) ? 'wp-block-button__link ' . $instance['submit_button_classes'] : 'wp-block-button__link';
386        $submit_button_styles         = isset( $instance['submit_button_styles'] ) ? $instance['submit_button_styles'] : '';
387        $submit_button_wrapper_styles = isset( $instance['submit_button_wrapper_styles'] ) ? $instance['submit_button_wrapper_styles'] : '';
388        $email_field_classes          = isset( $instance['email_field_classes'] ) ? $instance['email_field_classes'] : '';
389        $email_field_styles           = isset( $instance['email_field_styles'] ) ? $instance['email_field_styles'] : '';
390
391        // We need to include those in case Jetpack blocks are disabled
392        require_once JETPACK__PLUGIN_DIR . 'modules/memberships/class-jetpack-memberships.php';
393        require_once JETPACK__PLUGIN_DIR . 'extensions/blocks/premium-content/_inc/subscription-service/include.php';
394        $post_access_level = \Jetpack_Memberships::get_post_access_level();
395
396        if ( self::is_wpcom() && ! self::wpcom_has_status_message() ) {
397            global $current_blog;
398
399            $url     = defined( 'SUBSCRIBE_BLOG_URL' ) ? SUBSCRIBE_BLOG_URL : '';
400            $form_id = self::get_redirect_fragment();
401            ?>
402
403            <div class="wp-block-jetpack-subscriptions__container">
404            <form
405                action="<?php echo esc_url( $url ); ?>"
406                method="post"
407                accept-charset="utf-8"
408                data-blog="<?php echo esc_attr( get_current_blog_id() ); ?>"
409                data-post_access_level="<?php echo esc_attr( $post_access_level ); ?>"
410                id="<?php echo esc_attr( $form_id ); ?>"
411            >
412                <?php
413                if ( ! $show_only_email_and_button ) {
414                    // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
415                    echo wpautop( $subscribe_text );
416                }
417                $email_field_id  = 'subscribe-field';
418                $email_field_id .= self::$instance_count > 1
419                    ? '-' . self::$instance_count
420                    : '';
421                $label_field_id  = $email_field_id . '-label';
422                ?>
423                <p id="subscribe-email">
424                    <label
425                        id="<?php echo esc_attr( $label_field_id ); ?>"
426                        for="<?php echo esc_attr( $email_field_id ); ?>"
427                        class="screen-reader-text"
428                    >
429                        <?php echo esc_html__( 'Email Address:', 'jetpack' ); ?>
430                    </label>
431
432                    <?php
433                    printf(
434                        '<input
435                            type="email"
436                            name="email"
437                            autocomplete="email"
438                            %1$s
439                            style="%2$s"
440                            placeholder="%3$s"
441                            value=""
442                            id="%4$s"
443                            required
444                        />',
445                        ( ! empty( $email_field_classes )
446                            ? 'class="' . esc_attr( $email_field_classes ) . '"'
447                            : ''
448                        ),
449                        ( ! empty( $email_field_styles )
450                            ? esc_attr( $email_field_styles )
451                            : 'width: 95%; padding: 1px 10px'
452                        ),
453                        ( empty( $subscribe_placeholder ) ? esc_attr__( 'Enter your email address', 'jetpack' ) : esc_attr( $subscribe_placeholder ) ),
454                        esc_attr( $email_field_id )
455                    );
456                    ?>
457                </p>
458
459                <p id="subscribe-submit"
460                    <?php if ( ! empty( $submit_button_wrapper_styles ) ) { ?>
461                        style="<?php echo esc_attr( $submit_button_wrapper_styles ); ?>"
462                    <?php } ?>
463                >
464                    <input type="hidden" name="action" value="subscribe"/>
465                    <input type="hidden" name="blog_id" value="<?php echo (int) $current_blog->blog_id; ?>"/>
466                    <input type="hidden" name="source" value="<?php echo esc_url( $referer ); ?>"/>
467                    <input type="hidden" name="sub-type" value="<?php echo esc_attr( $source ); ?>"/>
468                    <input type="hidden" name="redirect_fragment" value="<?php echo esc_attr( $form_id ); ?>"/>
469                    <?php wp_nonce_field( 'blogsub_subscribe_' . $current_blog->blog_id, '_wpnonce', false ); ?>
470                    <button type="submit"
471                        <?php if ( ! empty( $submit_button_classes ) ) { ?>
472                            class="<?php echo esc_attr( $submit_button_classes ); ?>"
473                        <?php } ?>
474                        <?php if ( ! empty( $submit_button_styles ) ) { ?>
475                            style="<?php echo esc_attr( $submit_button_styles ); ?>"
476                        <?php } ?>
477                    >
478                        <?php
479                        echo wp_kses(
480                            html_entity_decode( $subscribe_button, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 ),
481                            self::$allowed_html_tags_for_submit_button
482                        );
483                        ?>
484                    </button>
485                </p>
486            </form>
487            <?php if ( $show_subscribers_total && $subscribers_total > 0 ) { ?>
488                <div class="wp-block-jetpack-subscriptions__subscount">
489                    <?php
490                    echo esc_html( Jetpack_Memberships::get_join_others_text( $subscribers_total ) );
491                    ?>
492                </div>
493            <?php } ?>
494            </div>
495            <?php
496        }
497
498        if ( self::is_jetpack() ) {
499            /**
500             * Filter the subscription form's ID prefix.
501             *
502             * @module subscriptions
503             *
504             * @since 2.7.0
505             *
506             * @param string subscribe-field Subscription form field prefix.
507             * @param int $widget_id Widget ID.
508             */
509            $subscribe_field_id = apply_filters( 'subscribe_field_id', 'subscribe-field', $widget_id );
510
511            $form_id = self::get_redirect_fragment( $widget_id );
512            ?>
513            <div class="wp-block-jetpack-subscriptions__container">
514            <form action="#" method="post" accept-charset="utf-8" id="<?php echo esc_attr( $form_id ); ?>"
515                data-blog="<?php echo esc_attr( \Jetpack_Options::get_option( 'id' ) ); ?>"
516                data-post_access_level="<?php echo esc_attr( $post_access_level ); ?>" >
517                <?php
518                if ( $subscribe_text && ( ! isset( $_GET['subscribe'] ) || 'success' !== $_GET['subscribe'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Non-sensitive informational output.
519                    ?>
520                    <div id="subscribe-text"><?php echo wp_kses( wpautop( str_replace( '[total-subscribers]', number_format_i18n( $subscribers_total ), $subscribe_text ) ), 'post' ); ?></div>
521                    <?php
522                }
523
524                if ( ! isset( $_GET['subscribe'] ) || 'success' !== $_GET['subscribe'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display of unsubmitted form.
525                    ?>
526                    <p id="subscribe-email">
527                        <label id="jetpack-subscribe-label"
528                            class="screen-reader-text"
529                            for="<?php echo esc_attr( $subscribe_field_id . '-' . $widget_id ); ?>">
530                            <?php echo ! empty( $subscribe_placeholder ) ? esc_html( $subscribe_placeholder ) : esc_html__( 'Email Address:', 'jetpack' ); ?>
531                        </label>
532                        <input type="email" name="email" autocomplete="email" required="required"
533                            <?php if ( ! empty( $email_field_classes ) ) { ?>
534                                class="<?php echo esc_attr( $email_field_classes ); ?> required"
535                            <?php } ?>
536                            <?php if ( ! empty( $email_field_styles ) ) { ?>
537                                style="<?php echo esc_attr( $email_field_styles ); ?>"
538                            <?php } ?>
539                            value="<?php echo esc_attr( $subscribe_email ); ?>"
540                            id="<?php echo esc_attr( $subscribe_field_id . '-' . $widget_id ); ?>"
541                            placeholder="<?php echo esc_attr( $subscribe_placeholder ); ?>"
542                        />
543                    </p>
544
545                    <p id="subscribe-submit"
546                        <?php if ( ! empty( $submit_button_wrapper_styles ) ) { ?>
547                            style="<?php echo esc_attr( $submit_button_wrapper_styles ); ?>"
548                        <?php } ?>
549                    >
550                        <input type="hidden" name="action" value="subscribe"/>
551                        <input type="hidden" name="source" value="<?php echo esc_url( $referer ); ?>"/>
552                        <input type="hidden" name="sub-type" value="<?php echo esc_attr( $source ); ?>"/>
553                        <input type="hidden" name="redirect_fragment" value="<?php echo esc_attr( $form_id ); ?>"/>
554                        <?php wp_nonce_field( 'blogsub_subscribe_' . \Jetpack_Options::get_option( 'id' ) ); ?>
555                        <button type="submit"
556                            <?php if ( ! empty( $submit_button_classes ) ) { ?>
557                                class="<?php echo esc_attr( $submit_button_classes ); ?>"
558                            <?php } ?>
559                            <?php if ( ! empty( $submit_button_styles ) ) { ?>
560                                style="<?php echo esc_attr( $submit_button_styles ); ?>"
561                            <?php } ?>
562                            name="jetpack_subscriptions_widget"
563                        >
564                            <?php
565                            echo wp_kses(
566                                html_entity_decode( $subscribe_button, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 ),
567                                self::$allowed_html_tags_for_submit_button
568                            );
569                            ?>
570                        </button>
571                    </p>
572                <?php } ?>
573            </form>
574            <?php if ( $show_subscribers_total && 0 < $subscribers_total ) { ?>
575                <div class="wp-block-jetpack-subscriptions__subscount">
576                    <?php
577                    echo esc_html( Jetpack_Memberships::get_join_others_text( $subscribers_total ) );
578                    ?>
579                </div>
580            <?php } ?>
581            </div>
582            <?php
583        }
584    }
585
586    /**
587     * Determines if the current user is subscribed to the blog.
588     *
589     * @return bool Is the person already subscribed.
590     */
591    public static function is_current_user_subscribed() {
592        $subscribed = isset( $_GET['subscribe'] ) && 'success' === $_GET['subscribe']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
593
594        if ( self::is_wpcom() && class_exists( 'Blog_Subscription' ) && class_exists( 'Blog_Subscriber' ) ) {
595            $subscribed = is_user_logged_in() && Blog_Subscription::is_subscribed( new Blog_Subscriber() );
596        }
597
598        return $subscribed;
599    }
600
601    /**
602     * Is this script running in the wordpress.com environment?
603     *
604     * @return bool
605     */
606    public static function is_wpcom() {
607        return defined( 'IS_WPCOM' ) && IS_WPCOM;
608    }
609
610    /**
611     * Is this script running in a self-hosted environment?
612     *
613     * @return bool
614     */
615    public static function is_jetpack() {
616        return ! self::is_wpcom();
617    }
618
619    /**
620     * Used to determine if there is a valid status slug within the wordpress.com environment.
621     *
622     * @return bool
623     */
624    public static function wpcom_has_status_message() {
625        return isset( $_GET['blogsub'] ) && // phpcs:ignore WordPress.Security.NonceVerification.Recommended
626            in_array(
627                $_GET['blogsub'], // phpcs:ignore WordPress.Security.NonceVerification.Recommended
628                array(
629                    'confirming',
630                    'blocked',
631                    'flooded',
632                    'spammed',
633                    'subscribed',
634                    'pending',
635                    'confirmed',
636                ),
637                true
638            );
639    }
640
641    /**
642     * Determine the amount of folks currently subscribed to the blog.
643     *
644     * @return int
645     */
646    public static function fetch_subscriber_count() {
647        $subs_count = 0;
648        if ( self::is_jetpack() ) {
649            $cache_key  = 'wpcom_subscribers_total';
650            $subs_count = get_transient( $cache_key );
651            if ( false === $subs_count || 'failed' === $subs_count['status'] ) {
652                $xml = new Jetpack_IXR_Client();
653                $xml->query( 'jetpack.fetchSubscriberCount' );
654
655                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.
656
657                    $subs_count = array(
658                        'status'  => 'failed',
659                        'code'    => $xml->getErrorCode(),
660                        'message' => $xml->getErrorMessage(),
661                        'value'   => ( isset( $subs_count['value'] ) ) ? $subs_count['value'] : 0,
662                    );
663                } else {
664                    $subs_count = array(
665                        'status' => 'success',
666                        'value'  => $xml->getResponse(),
667                    );
668                }
669                set_transient( $cache_key, $subs_count, 3600 ); // Try to cache the result for at least 1 hour.
670            }
671            return $subs_count['value'];
672        }
673
674        if ( self::is_wpcom() ) {
675            $subs_count = wpcom_reach_total_for_blog();
676            return $subs_count;
677        }
678    }
679
680    /**
681     * Updates a particular instance of a widget when someone saves it in wp-admin.
682     *
683     * @param array $new_instance New widget instance settings.
684     * @param array $old_instance Old widget instance settings.
685     *
686     * @return array
687     */
688    public function update( $new_instance, $old_instance ) {
689        // Merge new values over old, then fill in any missing keys with defaults
690        $instance = wp_parse_args( (array) $new_instance, wp_parse_args( (array) $old_instance, static::defaults() ) );
691
692        if ( self::is_jetpack() ) {
693            $instance['title']                 = wp_kses( stripslashes( $instance['title'] ), array() );
694            $instance['subscribe_placeholder'] = wp_kses( stripslashes( $instance['subscribe_placeholder'] ), array() );
695            $instance['subscribe_button']      = wp_kses( stripslashes( $instance['subscribe_button'] ), array() );
696            $instance['success_message']       = wp_kses( stripslashes( $instance['success_message'] ), array() );
697        }
698
699        if ( self::is_wpcom() ) {
700            $instance['title']               = wp_strip_all_tags( stripslashes( $instance['title'] ) );
701            $instance['title_following']     = isset( $instance['title_following'] ) ? wp_strip_all_tags( stripslashes( $instance['title_following'] ) ) : '';
702            $instance['subscribe_logged_in'] = isset( $instance['subscribe_logged_in'] ) ? wp_filter_post_kses( stripslashes( $instance['subscribe_logged_in'] ) ) : '';
703            $instance['subscribe_button']    = wp_strip_all_tags( stripslashes( $instance['subscribe_button'] ) );
704        }
705
706        $instance['show_subscribers_total']     = isset( $new_instance['show_subscribers_total'] ) && $new_instance['show_subscribers_total'];
707        $instance['show_only_email_and_button'] = isset( $new_instance['show_only_email_and_button'] ) && $new_instance['show_only_email_and_button'];
708        $instance['subscribe_text']             = wp_filter_post_kses( stripslashes( $instance['subscribe_text'] ) );
709
710        return $instance;
711    }
712
713    /**
714     * The default args for rendering a subscription form.
715     *
716     * @return array
717     */
718    public static function defaults() {
719        $defaults = array(
720            'show_subscribers_total'     => true,
721            'show_only_email_and_button' => false,
722            'include_social_followers'   => true,
723        );
724
725        $defaults['title']                 = esc_html__( 'Subscribe to Blog via Email', 'jetpack' );
726        $defaults['subscribe_text']        = esc_html__( 'Enter your email address to subscribe to this blog and receive notifications of new posts by email.', 'jetpack' );
727        $defaults['subscribe_placeholder'] = esc_html__( 'Email Address', 'jetpack' );
728        $defaults['subscribe_button']      = esc_html__( 'Subscribe', 'jetpack' );
729        $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' );
730
731        return $defaults;
732    }
733
734    /**
735     * Renders the widget's options form in wp-admin.
736     *
737     * @param array $instance Widget instance.
738     * @return string|void
739     */
740    public function form( $instance ) {
741        $instance               = wp_parse_args( (array) $instance, static::defaults() );
742        $show_subscribers_total = checked( $instance['show_subscribers_total'], true, false );
743
744        if ( self::is_wpcom() ) {
745            $title               = ! empty( $instance['title'] ) ? esc_attr( stripslashes( $instance['title'] ) ) : '';
746            $title_following     = ! empty( $instance['title_following'] ) ? esc_attr( stripslashes( $instance['title_following'] ) ) : '';
747            $subscribe_text      = ! empty( $instance['subscribe_text'] ) ? esc_attr( stripslashes( $instance['subscribe_text'] ) ) : '';
748            $subscribe_logged_in = ! empty( $instance['subscribe_logged_in'] ) ? esc_attr( stripslashes( $instance['subscribe_logged_in'] ) ) : '';
749            $subscribe_button    = ! empty( $instance['subscribe_button'] ) ? esc_attr( stripslashes( $instance['subscribe_button'] ) ) : '';
750            $subscribers_total   = self::fetch_subscriber_count();
751            ?>
752            <p>
753                <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>">
754                    <?php esc_html_e( 'Widget title for non-followers:', 'jetpack' ); ?>
755                    <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"
756                        name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text"
757                        value="<?php echo esc_attr( $title ); ?>"/>
758                </label>
759            </p>
760            <p>
761                <label for="<?php echo esc_attr( $this->get_field_id( 'title_following' ) ); ?>">
762                    <?php esc_html_e( 'Widget title for followers:', 'jetpack' ); ?>
763                    <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title_following' ) ); ?>"
764                        name="<?php echo esc_attr( $this->get_field_name( 'title_following' ) ); ?>" type="text"
765                        value="<?php echo esc_attr( $title_following ); ?>"/>
766                </label>
767            </p>
768            <p>
769                <label for="<?php echo esc_attr( $this->get_field_id( 'subscribe_logged_in' ) ); ?>">
770                    <?php esc_html_e( 'Optional text to display to logged in WordPress.com users:', 'jetpack' ); ?>
771                    <textarea style="width: 95%" id="<?php echo esc_attr( $this->get_field_id( 'subscribe_logged_in' ) ); ?>"
772                        name="<?php echo esc_attr( $this->get_field_name( 'subscribe_logged_in' ) ); ?>"
773                        type="text"><?php echo esc_html( $subscribe_logged_in ); ?></textarea>
774                </label>
775            </p>
776            <p>
777                <label for="<?php echo esc_attr( $this->get_field_id( 'subscribe_text' ) ); ?>">
778                    <?php esc_html_e( 'Optional text to display to non-WordPress.com users:', 'jetpack' ); ?>
779                    <textarea style="width: 95%" id="<?php echo esc_attr( $this->get_field_id( 'subscribe_text' ) ); ?>"
780                        name="<?php echo esc_attr( $this->get_field_name( 'subscribe_text' ) ); ?>"
781                        type="text"><?php echo esc_html( $subscribe_text ); ?></textarea>
782                </label>
783            </p>
784            <p>
785                <label for="<?php echo esc_attr( $this->get_field_id( 'subscribe_button' ) ); ?>">
786                    <?php esc_html_e( 'Follow Button Text:', 'jetpack' ); ?>
787                    <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'subscribe_button' ) ); ?>"
788                        name="<?php echo esc_attr( $this->get_field_name( 'subscribe_button' ) ); ?>" type="text"
789                        value="<?php echo esc_attr( $subscribe_button ); ?>"/>
790                </label>
791            </p>
792            <p>
793                <label for="<?php echo esc_attr( $this->get_field_id( 'show_subscribers_total' ) ); ?>">
794                    <input type="checkbox" id="<?php echo esc_attr( $this->get_field_id( 'show_subscribers_total' ) ); ?>"
795                        name="<?php echo esc_attr( $this->get_field_name( 'show_subscribers_total' ) ); ?>"
796                        value="1"<?php echo esc_attr( $show_subscribers_total ); ?> />
797                    <?php
798                    /* translators: %s: Number of followers. */
799                    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 ) ) );
800                    ?>
801                </label>
802            </p>
803            <?php
804        }
805
806        if ( self::is_jetpack() ) {
807            $title                 = ! empty( $instance['title'] ) ? stripslashes( $instance['title'] ) : '';
808            $subscribe_text        = ! empty( $instance['subscribe_text'] ) ? stripslashes( $instance['subscribe_text'] ) : '';
809            $subscribe_placeholder = ! empty( $instance['subscribe_placeholder'] ) ? stripslashes( $instance['subscribe_placeholder'] ) : '';
810            $subscribe_button      = ! empty( $instance['subscribe_button'] ) ? stripslashes( $instance['subscribe_button'] ) : '';
811            $success_message       = ! empty( $instance['success_message'] ) ? stripslashes( $instance['success_message'] ) : '';
812            $subscribers_total     = self::fetch_subscriber_count();
813            ?>
814            <p>
815                <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>">
816                    <?php esc_html_e( 'Widget title:', 'jetpack' ); ?>
817                    <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"
818                        name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text"
819                        value="<?php echo esc_attr( $title ); ?>"/>
820                </label>
821            </p>
822            <p>
823                <label for="<?php echo esc_attr( $this->get_field_id( 'subscribe_text' ) ); ?>">
824                    <?php esc_html_e( 'Optional text to display to your readers:', 'jetpack' ); ?>
825                    <textarea class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'subscribe_text' ) ); ?>"
826                        name="<?php echo esc_attr( $this->get_field_name( 'subscribe_text' ) ); ?>"
827                        rows="3"><?php echo esc_html( $subscribe_text ); ?></textarea>
828                </label>
829            </p>
830            <p>
831                <label for="<?php echo esc_attr( $this->get_field_id( 'subscribe_placeholder' ) ); ?>">
832                    <?php esc_html_e( 'Subscribe Placeholder:', 'jetpack' ); ?>
833                    <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'subscribe_placeholder' ) ); ?>"
834                        name="<?php echo esc_attr( $this->get_field_name( 'subscribe_placeholder' ) ); ?>" type="text"
835                        value="<?php echo esc_attr( $subscribe_placeholder ); ?>"/>
836                </label>
837            </p>
838            <p>
839                <label for="<?php echo esc_attr( $this->get_field_id( 'subscribe_button' ) ); ?>">
840                    <?php esc_html_e( 'Subscribe Button:', 'jetpack' ); ?>
841                    <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'subscribe_button' ) ); ?>"
842                        name="<?php echo esc_attr( $this->get_field_name( 'subscribe_button' ) ); ?>" type="text"
843                        value="<?php echo esc_attr( $subscribe_button ); ?>"/>
844                </label>
845            </p>
846            <p>
847                <label for="<?php echo esc_attr( $this->get_field_id( 'success_message' ) ); ?>">
848                    <?php esc_html_e( 'Success Message Text:', 'jetpack' ); ?>
849                    <textarea class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'success_message' ) ); ?>"
850                        name="<?php echo esc_attr( $this->get_field_name( 'success_message' ) ); ?>"
851                        rows="5"><?php echo esc_html( $success_message ); ?></textarea>
852                </label>
853            </p>
854            <p>
855                <label for="<?php echo esc_attr( $this->get_field_id( 'show_subscribers_total' ) ); ?>">
856                    <input type="checkbox" id="<?php echo esc_attr( $this->get_field_id( 'show_subscribers_total' ) ); ?>"
857                        name="<?php echo esc_attr( $this->get_field_name( 'show_subscribers_total' ) ); ?>"
858                        value="1"<?php echo esc_attr( $show_subscribers_total ); ?> />
859                    <?php
860                    /* translators: %s: Number of subscribers. */
861                    echo esc_html( sprintf( _n( 'Show total number of subscribers? (%s subscriber)', 'Show total number of subscribers? (%s subscribers)', $subscribers_total, 'jetpack' ), $subscribers_total ) );
862                    ?>
863                </label>
864            </p>
865            <?php
866        }
867    }
868}
869
870if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
871    class_alias( 'Jetpack_Subscriptions_Widget', 'Blog_Subscription_Widget' );
872}
873
874/**
875 * Classname / shortcode tag to use for the Subscriptions widget.
876 *
877 * @return string
878 */
879function get_jetpack_blog_subscriptions_widget_classname() {
880    return ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ?
881        'Blog_Subscription_Widget' :
882        'Jetpack_Subscriptions_Widget';
883}
884
885/**
886 * Subscriptions widget form HTML output.
887 *
888 * @param array $instance Widget instance data.
889 */
890function jetpack_do_subscription_form( $instance ) {
891    if ( empty( $instance ) || ! is_array( $instance ) ) {
892        $instance = array();
893    }
894
895    if ( empty( $instance['show_subscribers_total'] ) || 'false' === $instance['show_subscribers_total'] ) {
896        $instance['show_subscribers_total'] = false;
897    } else {
898        $instance['show_subscribers_total'] = true;
899    }
900
901    // the default behavior is to include the social followers
902    if ( empty( $instance['include_social_followers'] ) || 'true' === $instance['include_social_followers'] ) {
903        $instance['include_social_followers'] = true;
904    } else {
905        $instance['include_social_followers'] = false;
906    }
907
908    $show_only_email_and_button = isset( $instance['show_only_email_and_button'] ) ? $instance['show_only_email_and_button'] : false;
909    $submit_button_text         = isset( $instance['submit_button_text'] ) ? $instance['submit_button_text'] : '';
910
911    // Build up a string with the submit button's classes and styles and set it on the instance.
912    $submit_button_classes        = isset( $instance['submit_button_classes'] ) ? $instance['submit_button_classes'] : '';
913    $email_field_classes          = isset( $instance['email_field_classes'] ) ? $instance['email_field_classes'] : '';
914    $style                        = '';
915    $submit_button_styles         = '';
916    $submit_button_wrapper_styles = '';
917    $email_field_styles           = '';
918    $success_message              = '';
919
920    if ( isset( $instance['custom_background_button_color'] ) && 'undefined' !== $instance['custom_background_button_color'] ) {
921        $submit_button_styles .= 'background: ' . $instance['custom_background_button_color'] . '; ';
922    }
923    if ( isset( $instance['custom_text_button_color'] ) && 'undefined' !== $instance['custom_text_button_color'] ) {
924        $submit_button_styles .= 'color: ' . $instance['custom_text_button_color'] . '; ';
925    }
926    if ( isset( $instance['custom_button_width'] ) && 'undefined' !== $instance['custom_button_width'] ) {
927        $submit_button_wrapper_styles .= 'width: ' . $instance['custom_button_width'] . '; ';
928        $submit_button_wrapper_styles .= 'max-width: 100%; ';
929
930        // Account for custom margins on inline forms.
931        if (
932            ! empty( $instance['custom_spacing'] ) &&
933            ! ( isset( $instance['button_on_newline'] ) && 'true' === $instance['button_on_newline'] )
934        ) {
935            $submit_button_styles .= 'width: calc(100% - ' . $instance['custom_spacing'] . 'px); ';
936        } else {
937            $submit_button_styles .= 'width: 100%; ';
938        }
939    }
940
941    if ( isset( $instance['custom_font_size'] ) && 'undefined' !== $instance['custom_font_size'] ) {
942        $style  = 'font-size: ' . $instance['custom_font_size'];
943        $style .= is_numeric( $instance['custom_font_size'] ) ? 'px; ' : '; '; // Handle deprecated numeric font size values.
944
945        $submit_button_styles .= $style;
946        $email_field_styles   .= $style;
947    }
948    if ( isset( $instance['custom_padding'] ) && 'undefined' !== $instance['custom_padding'] ) {
949        $style = 'padding: ' .
950            $instance['custom_padding'] . 'px ' .
951            round( floatval( $instance['custom_padding'] ) * 1.5 ) . 'px ' .
952            $instance['custom_padding'] . 'px ' .
953            round( floatval( $instance['custom_padding'] ) * 1.5 ) . 'px; ';
954
955        $submit_button_styles .= $style;
956        $email_field_styles   .= $style;
957    }
958
959    $button_spacing = 0;
960    if ( ! empty( $instance['custom_spacing'] ) ) {
961        $button_spacing = $instance['custom_spacing'];
962    }
963    if ( isset( $instance['button_on_newline'] ) && 'true' === $instance['button_on_newline'] ) {
964        $submit_button_styles .= 'margin-top: ' . $button_spacing . 'px; ';
965    } else {
966        $submit_button_styles .= 'margin: 0; '; // Reset Safari's 2px default margin for buttons affecting input and button union
967        $submit_button_styles .= 'margin-left: ' . $button_spacing . 'px; ';
968    }
969
970    if ( isset( $instance['custom_border_radius'] ) && 'undefined' !== $instance['custom_border_radius'] ) {
971        $style                 = 'border-radius: ' . $instance['custom_border_radius'] . 'px; ';
972        $submit_button_styles .= $style;
973        $email_field_styles   .= $style;
974    }
975    if ( isset( $instance['custom_border_weight'] ) && 'undefined' !== $instance['custom_border_weight'] ) {
976        $style                 = 'border-width: ' . $instance['custom_border_weight'] . 'px; ';
977        $submit_button_styles .= $style;
978        $email_field_styles   .= $style;
979    }
980    if ( isset( $instance['custom_border_color'] ) && 'undefined' !== $instance['custom_border_color'] ) {
981        $style =
982            'border-color: ' . $instance['custom_border_color'] . '; ' .
983            'border-style: solid;';
984
985        $submit_button_styles .= $style;
986        $email_field_styles   .= $style;
987    }
988    if ( isset( $instance['success_message'] ) && 'undefined' !== $instance['success_message'] ) {
989        $success_message = wp_kses( stripslashes( $instance['success_message'] ), array() );
990    }
991
992    $instance = shortcode_atts(
993        Jetpack_Subscriptions_Widget::defaults(),
994        $instance,
995        'jetpack_subscription_form'
996    );
997
998    // These must come after the call to shortcode_atts().
999    $instance['submit_button_text']         = $submit_button_text;
1000    $instance['show_only_email_and_button'] = $show_only_email_and_button;
1001    if ( ! empty( $submit_button_classes ) ) {
1002        $instance['submit_button_classes'] = $submit_button_classes;
1003    }
1004    if ( ! empty( $email_field_classes ) ) {
1005        $instance['email_field_classes'] = $email_field_classes;
1006    }
1007
1008    if ( ! empty( $submit_button_styles ) ) {
1009        $instance['submit_button_styles'] = trim( $submit_button_styles );
1010    }
1011    if ( ! empty( $submit_button_wrapper_styles ) ) {
1012        $instance['submit_button_wrapper_styles'] = trim( $submit_button_wrapper_styles );
1013    }
1014    if ( ! empty( $email_field_styles ) ) {
1015        $instance['email_field_styles'] = trim( $email_field_styles );
1016    }
1017    if ( ! empty( $success_message ) ) {
1018        $instance['success_message'] = trim( $success_message );
1019    }
1020
1021    $args = array(
1022        'before_widget' => '<div class="jetpack_subscription_widget">',
1023    );
1024    ob_start();
1025    the_widget( get_jetpack_blog_subscriptions_widget_classname(), $instance, $args );
1026    $output = ob_get_clean();
1027
1028    return $output;
1029}
1030
1031add_shortcode( 'jetpack_subscription_form', 'jetpack_do_subscription_form' );
1032add_shortcode( 'blog_subscription_form', 'jetpack_do_subscription_form' );
1033
1034/**
1035 * Register the Subscriptions widget.
1036 */
1037function jetpack_blog_subscriptions_init() {
1038    register_widget( get_jetpack_blog_subscriptions_widget_classname() );
1039}
1040
1041add_action( 'widgets_init', 'jetpack_blog_subscriptions_init' );
1042
1043/**
1044 * Sets the default value for `subscription_options` site option.
1045 *
1046 * This default value is available across Simple, Atomic and Jetpack sites,
1047 * including the /sites/$site/settings endpoint.
1048 *
1049 * @param array  $default Default `subscription_options` array.
1050 * @param string $option Option name.
1051 * @param bool   $passed_default Whether `get_option()` passed a default value.
1052 *
1053 * @return array Default value of `subscription_options`.
1054 */
1055function subscription_options_fallback( $default, $option, $passed_default ) {
1056    if ( $passed_default ) {
1057        return $default;
1058    }
1059
1060    $site_url    = get_home_url();
1061    $display_url = preg_replace( '(^https?://)', '', untrailingslashit( $site_url ) );
1062
1063    return array(
1064        /* translators: Both %1$s and %2$s is site address */
1065        '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 ),
1066        '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' ),
1067        /* translators: %1$s is the site address */
1068        '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 ),
1069    );
1070}
1071
1072add_filter( 'default_option_subscription_options', 'subscription_options_fallback', 10, 3 );