PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 11.1
Jetpack – WP Security, Backup, Speed, & Growth v11.1
16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 All 501 releases
← All changes | modules/subscriptions.php +117 -182 14.4.211.1 View file →
@@ -1,7 +1,7 @@
1 1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName)
2 2 /**
3 - * Module Name: Newsletter
3 + * Module Name: Subscriptions
4 4 * Module Description: Let visitors subscribe to new posts and comments via email
5 5 * Sort Order: 9
6 6 * Recommendation Order: 8
7 7 * First Introduced: 1.2
@@ -9,25 +9,15 @@
9 9 * Requires User Connection: Yes
10 10 * Auto Activate: No
11 11 * Module Tags: Social
12 12 * Feature: Engagement
13 - * Additional Search Queries: subscriptions, subscription, email, follow, followers, subscribers, signup, newsletter, creator
13 + * Additional Search Queries: subscriptions, subscription, email, follow, followers, subscribers, signup
14 14 */
15 15
16 -// phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed -- TODO: Move classes to appropriately-named class files.
17 -
18 -use Automattic\Jetpack\Admin_UI\Admin_Menu;
19 -use Automattic\Jetpack\Connection\Manager as Connection_Manager;
20 16 use Automattic\Jetpack\Connection\XMLRPC_Async_Call;
21 -use Automattic\Jetpack\Redirect;
22 -use Automattic\Jetpack\Status;
23 -use Automattic\Jetpack\Status\Host;
24 17
25 18 add_action( 'jetpack_modules_loaded', 'jetpack_subscriptions_load' );
26 19
27 -// Loads the User Content Link Redirection feature.
28 -require_once __DIR__ . '/subscriptions/jetpack-user-content-link-redirection.php';
29 -
30 20 /**
31 21 * Loads the Subscriptions module.
32 22 */
33 23 function jetpack_subscriptions_load() {
@@ -44,13 +34,13 @@
44 34 function jetpack_subscriptions_cherry_pick_server_data() {
45 35 $data = array();
46 36
47 37 foreach ( $_SERVER as $key => $value ) {
48 - if ( ! is_string( $value ) || str_starts_with( $key, 'HTTP_COOKIE' ) ) {
38 + if ( ! is_string( $value ) || 0 === strpos( $key, 'HTTP_COOKIE' ) ) {
49 39 continue;
50 40 }
51 41
52 - if ( str_starts_with( $key, 'HTTP_' ) || in_array( $key, array( 'REMOTE_ADDR', 'REQUEST_URI', 'DOCUMENT_URI' ), true ) ) {
42 + if ( 0 === strpos( $key, 'HTTP_' ) || in_array( $key, array( 'REMOTE_ADDR', 'REQUEST_URI', 'DOCUMENT_URI' ), true ) ) {
53 43 $data[ $key ] = $value;
54 44 }
55 45 }
56 46
@@ -128,26 +118,8 @@
128 118 add_filter( 'post_updated_messages', array( $this, 'update_published_message' ), 18, 1 );
129 119
130 120 // Set "social_notifications_subscribe" option during the first-time activation.
131 121 add_action( 'jetpack_activate_module_subscriptions', array( $this, 'set_social_notifications_subscribe' ) );
132 -
133 - // Hide subscription messaging in Publish panel for posts that were published in the past
134 - add_action( 'init', array( $this, 'register_post_meta' ), 20 );
135 - add_action( 'transition_post_status', array( $this, 'maybe_set_first_published_status' ), 10, 3 );
136 -
137 - // Add Subscribers menu to Jetpack navigation.
138 - add_action( 'jetpack_admin_menu', array( $this, 'add_subscribers_menu' ) );
139 -
140 - // Customize the configuration URL to lead to the Subscriptions settings.
141 - add_filter(
142 - 'jetpack_module_configuration_url_subscriptions',
143 - function () {
144 - return Jetpack::admin_url( array( 'page' => 'jetpack#/newsletter' ) );
145 - }
146 - );
147 -
148 - // Track categories created through the category editor page
149 - add_action( 'wp_ajax_add-tag', array( $this, 'track_newsletter_category_creation' ), 1 );
150 122 }
151 123
152 124 /**
153 125 * Jetpack_Subscriptions::xmlrpc_methods()
@@ -369,14 +341,14 @@
369 341 'discussion',
370 342 'stc_enabled'
371 343 );
372 344
373 - /** Email me whenever: Someone subscribes to my blog */
345 + /** Email me whenever: Someone follows my blog */
374 346 /* @since 8.1 */
375 347
376 348 add_settings_section(
377 349 'notifications_section',
378 - __( 'Someone subscribes to my blog', 'jetpack' ),
350 + __( 'Someone follows my blog', 'jetpack' ),
379 351 array( $this, 'social_notifications_subscribe_section' ),
380 352 'discussion'
381 353 );
382 354
@@ -392,8 +364,39 @@
392 364 'discussion',
393 365 'social_notifications_subscribe',
394 366 array( $this, 'social_notifications_subscribe_validate' )
395 367 );
368 +
369 + /** Subscription Messaging Options */
370 +
371 + register_setting(
372 + 'reading',
373 + 'subscription_options',
374 + array( $this, 'validate_settings' )
375 + );
376 +
377 + add_settings_section(
378 + 'email_settings',
379 + __( 'Follower Settings', 'jetpack' ),
380 + array( $this, 'reading_section' ),
381 + 'reading'
382 + );
383 +
384 + add_settings_field(
385 + 'invitation',
386 + __( 'Blog follow email text', 'jetpack' ),
387 + array( $this, 'setting_invitation' ),
388 + 'reading',
389 + 'email_settings'
390 + );
391 +
392 + add_settings_field(
393 + 'comment-follow',
394 + __( 'Comment follow email text', 'jetpack' ),
395 + array( $this, 'setting_comment_follow' ),
396 + 'reading',
397 + 'email_settings'
398 + );
396 399 }
397 400
398 401 /**
399 402 * Discussions setting section blurb.
@@ -452,9 +455,9 @@
452 455 <?php
453 456 }
454 457
455 458 /**
456 - * Someone subscribes to my blog section
459 + * Someone follows my blog section
457 460 *
458 461 * @since 8.1
459 462 */
460 463 public function social_notifications_subscribe_section() {
@@ -478,9 +481,9 @@
478 481 <?php
479 482 }
480 483
481 484 /**
482 - * Someone subscribes to my blog Toggle
485 + * Someone follows my blog Toggle
483 486 *
484 487 * @since 8.1
485 488 */
486 489 public function social_notifications_subscribe_field() {
@@ -490,9 +493,9 @@
490 493 <label>
491 494 <input type="checkbox" name="social_notifications_subscribe" id="social_notifications_subscribe" value="1" <?php checked( $checked ); ?> />
492 495 <?php
493 496 /* translators: this is a label for a setting that starts with "Email me whenever" */
494 - esc_html_e( 'Someone subscribes to my blog', 'jetpack' );
497 + esc_html_e( 'Someone follows my blog', 'jetpack' );
495 498 ?>
496 499 </label>
497 500 <?php
498 501 }
@@ -497,9 +500,9 @@
497 500 <?php
498 501 }
499 502
500 503 /**
501 - * Validate "Someone subscribes to my blog" option
504 + * Validate "Someone follows my blog" option
502 505 *
503 506 * @since 8.1
504 507 *
505 508 * @param String $input the input string to be validated.
@@ -515,8 +518,81 @@
515 518 return 'on';
516 519 }
517 520
518 521 /**
522 + * Validate settings for the Subscriptions module.
523 + *
524 + * @param array $settings Settings to be validated.
525 + */
526 + public function validate_settings( $settings ) {
527 + global $allowedposttags;
528 +
529 + $default = $this->get_default_settings();
530 +
531 + // Blog Follow.
532 + $settings['invitation'] = trim( wp_kses( $settings['invitation'], $allowedposttags ) );
533 + if ( empty( $settings['invitation'] ) ) {
534 + $settings['invitation'] = $default['invitation'];
535 + }
536 +
537 + // Comments Follow (single post).
538 + $settings['comment_follow'] = trim( wp_kses( $settings['comment_follow'], $allowedposttags ) );
539 + if ( empty( $settings['comment_follow'] ) ) {
540 + $settings['comment_follow'] = $default['comment_follow'];
541 + }
542 +
543 + return $settings;
544 + }
545 +
546 + /**
547 + * HTML output helper for Reading section.
548 + */
549 + public function reading_section() {
550 + echo '<p id="follower-settings">';
551 + esc_html_e( 'These settings change emails sent from your blog to followers.', 'jetpack' );
552 + echo '</p>';
553 + }
554 +
555 + /**
556 + * HTML output helper for Invitation section.
557 + */
558 + public function setting_invitation() {
559 + $settings = $this->get_settings();
560 + echo '<textarea name="subscription_options[invitation]" class="large-text" cols="50" rows="5">' . esc_textarea( $settings['invitation'] ) . '</textarea>';
561 + echo '<p><span class="description">' . esc_html__( 'Introduction text sent when someone follows your blog. (Site and confirmation details will be automatically added for you.)', 'jetpack' ) . '</span></p>';
562 + }
563 +
564 + /**
565 + * HTML output helper for Comment Follow section.
566 + */
567 + public function setting_comment_follow() {
568 + $settings = $this->get_settings();
569 + echo '<textarea name="subscription_options[comment_follow]" class="large-text" cols="50" rows="5">' . esc_textarea( $settings['comment_follow'] ) . '</textarea>';
570 + echo '<p><span class="description">' . esc_html__( 'Introduction text sent when someone follows a post on your blog. (Site and confirmation details will be automatically added for you.)', 'jetpack' ) . '</span></p>';
571 + }
572 +
573 + /**
574 + * Get default settings for the Subscriptions module.
575 + */
576 + public function get_default_settings() {
577 + $site_url = get_home_url();
578 + $display_url = preg_replace( '(^https?://)', '', untrailingslashit( $site_url ) );
579 +
580 + return array(
581 + /* translators: Both %1$s and %2$s is site address */
582 + '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 ),
583 + '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' ),
584 + );
585 + }
586 +
587 + /**
588 + * Reeturn merged `subscription_options` option with module default settings.
589 + */
590 + public function get_settings() {
591 + return wp_parse_args( (array) get_option( 'subscription_options', array() ), $this->get_default_settings() );
592 + }
593 +
594 + /**
519 595 * Jetpack_Subscriptions::subscribe()
520 596 *
521 597 * Send a synchronous XML-RPC subscribe to blog posts or subscribe to post comments request.
522 598 *
@@ -616,10 +692,10 @@
616 692 * When a user submits their email via the blog subscription widget, check the details and call the subsribe() method.
617 693 */
618 694 public function widget_submit() {
619 695 // Check the nonce.
620 - if ( ! wp_verify_nonce( isset( $_REQUEST['_wpnonce'] ) ? sanitize_key( $_REQUEST['_wpnonce'] ) : '', 'blogsub_subscribe_' . \Jetpack_Options::get_option( 'id' ) ) ) {
621 - return false;
696 + if ( is_user_logged_in() ) {
697 + check_admin_referer( 'blogsub_subscribe_' . get_current_blog_id() );
622 698 }
623 699
624 700 if ( empty( $_REQUEST['email'] ) || ! is_string( $_REQUEST['email'] ) ) {
625 701 return false;
@@ -694,9 +770,9 @@
694 770 */
695 771 do_action( 'jetpack_subscriptions_form_submission', $result );
696 772
697 773 wp_safe_redirect( "$redirect#$redirect_fragment" );
698 - exit( 0 );
774 + exit;
699 775 }
700 776
701 777 /**
702 778 * Jetpack_Subscriptions::comment_subscribe_init()
@@ -707,13 +783,8 @@
707 783 */
708 784 public function comment_subscribe_init( $submit_button ) {
709 785 global $post;
710 786
711 - // Subscriptions are only available for posts so far.
712 - if ( ! $post || 'post' !== $post->post_type ) {
713 - return $submit_button;
714 - }
715 -
716 787 $comments_checked = '';
717 788 $blog_checked = '';
718 789
719 790 // Check for a comment / blog submission and set a cookie to retain the setting and check the boxes.
@@ -906,145 +977,9 @@
906 977 add_option( 'social_notifications_subscribe', 'off' );
907 978 }
908 979 }
909 980
910 - /**
911 - * Save a flag when a post was ever published.
912 - *
913 - * It saves the post meta when the post was published and becomes a draft.
914 - * Then this meta is used to hide subscription messaging in Publish panel.
915 - *
916 - * @param string $new_status Tthe "new" post status of the transition when saved.
917 - * @param string $old_status The "old" post status of the transition when saved.
918 - * @param object $post obj The post object.
919 - */
920 - public function maybe_set_first_published_status( $new_status, $old_status, $post ) {
921 - $was_post_ever_published = get_post_meta( $post->ID, '_jetpack_post_was_ever_published', true );
922 - if ( ! $was_post_ever_published && 'publish' === $old_status && 'draft' === $new_status ) {
923 - update_post_meta( $post->ID, '_jetpack_post_was_ever_published', true );
924 - }
925 - }
926 -
927 - /**
928 - * Checks if the current user can publish posts.
929 - *
930 - * @return bool
931 - */
932 - public function first_published_status_meta_auth_callback() {
933 - /**
934 - * Filter the capability to view if a post was ever published in the Subscription Module.
935 - *
936 - * @module subscriptions
937 - *
938 - * @since 13.4
939 - *
940 - * @param string $capability User capability needed to view if a post was ever published. Default to publish_posts.
941 - */
942 - $capability = apply_filters( 'jetpack_subscriptions_post_was_ever_published_capability', 'publish_posts' );
943 - if ( current_user_can( $capability ) ) {
944 - return true;
945 - }
946 - return false;
947 - }
948 -
949 - /**
950 - * Registers the 'post_was_ever_published' post meta for use in the REST API.
951 - */
952 - public function register_post_meta() {
953 - $jetpack_post_was_ever_published = array(
954 - 'type' => 'boolean',
955 - 'description' => __( 'Whether the post was ever published.', 'jetpack' ),
956 - 'single' => true,
957 - 'default' => false,
958 - 'show_in_rest' => array(
959 - 'name' => 'jetpack_post_was_ever_published',
960 - ),
961 - 'auth_callback' => array( $this, 'first_published_status_meta_auth_callback' ),
962 - );
963 -
964 - register_meta( 'post', '_jetpack_post_was_ever_published', $jetpack_post_was_ever_published );
965 - }
966 -
967 - /**
968 - * Create a Subscribers menu displayed on self-hosted sites.
969 - *
970 - * - It is not displayed on WordPress.com sites.
971 - * - It directs you to Calypso to the existing Subscribers page.
972 - *
973 - * @return void
974 - */
975 - public function add_subscribers_menu() {
976 - /*
977 - * Do not display any menu on WoA and WordPress.com Simple sites (unless Classic wp-admin is enabled).
978 - * They already get a menu item under Users via nav-unification.
979 - */
980 - if ( ( new Host() )->is_wpcom_platform() && get_option( 'wpcom_admin_interface' ) !== 'wp-admin' ) {
981 - return;
982 - }
983 -
984 - $status = new Status();
985 -
986 - /*
987 - * Do not display if we're in Offline mode,
988 - * or if the user is not connected.
989 - */
990 - if (
991 - $status->is_offline_mode()
992 - || ! ( new Connection_Manager( 'jetpack' ) )->is_user_connected()
993 - ) {
994 - return;
995 - }
996 -
997 - $blog_id = Connection_Manager::get_site_id( true );
998 -
999 - $link = Redirect::get_url(
1000 - 'jetpack-menu-jetpack-manage-subscribers',
1001 - array( 'site' => $blog_id ? $blog_id : $status->get_site_suffix() )
1002 - );
1003 -
1004 - Admin_Menu::add_menu(
1005 - __( 'Subscribers', 'jetpack' ),
1006 - __( 'Subscribers', 'jetpack' ) . ' <span class="dashicons dashicons-external"></span>',
1007 - 'manage_options',
1008 - esc_url( $link ),
1009 - null,
1010 - 11
1011 - );
1012 - }
1013 -
1014 - /**
1015 - * Record tracks event if categories is created when user enters
1016 - * the edit category page through the newsletter settings page.
1017 - *
1018 - * @return void
1019 - */
1020 - public function track_newsletter_category_creation() {
1021 -
1022 - // phpcs:disable WordPress.Security.NonceVerification.Missing
1023 - if ( empty( $_POST['_wp_http_referer'] ) ) {
1024 - return;
1025 - }
1026 -
1027 - if ( strpos( sanitize_url( wp_unslash( $_POST['_wp_http_referer'] ) ), 'referer=newsletter-categories' ) > -1 ) {
1028 -
1029 - $parent = filter_var( empty( $_POST['parent'] ) ? 0 : wp_unslash( $_POST['parent'] ), FILTER_SANITIZE_NUMBER_INT );
1030 -
1031 - $is_child_category = $parent > 0;
1032 -
1033 - $tracking = new Automattic\Jetpack\Tracking();
1034 - $tracking->tracks_record_event(
1035 - wp_get_current_user(),
1036 - 'jetpack_newsletter_add_category',
1037 - array(
1038 - 'is_child_category' => $is_child_category,
1039 - )
1040 - );
1041 - }
1042 - }
1043 981 }
1044 982
1045 983 Jetpack_Subscriptions::init();
1046 984
1047 985 require __DIR__ . '/subscriptions/views.php';
1048 -require __DIR__ . '/subscriptions/subscribe-modal/class-jetpack-subscribe-modal.php';
1049 -require __DIR__ . '/subscriptions/subscribe-overlay/class-jetpack-subscribe-overlay.php';
1050 -require __DIR__ . '/subscriptions/subscribe-floating-button/class-jetpack-subscribe-floating-button.php';