PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.3-beta
16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 All 507 releases
← All changes | modules/subscriptions.php +175 -183 13.0.2 → 16.3-beta View file →
@@ -1,14 +1,14 @@
1 1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName)
2 2 /**
3 3 * Module Name: Newsletter
4 - * Module Description: Let visitors subscribe to new posts and comments via email
4 + * Module Description: Grow your subscriber list and deliver your content directly to their email inbox.
5 5 * Sort Order: 9
6 6 * Recommendation Order: 8
7 7 * First Introduced: 1.2
8 8 * Requires Connection: Yes
9 9 * Requires User Connection: Yes
10 - * Auto Activate: No
10 + * Auto Activate: Yes
11 11 * Module Tags: Social
12 12 * Feature: Engagement
13 13 * Additional Search Queries: subscriptions, subscription, email, follow, followers, subscribers, signup, newsletter, creator
14 14 */
@@ -14,14 +14,21 @@
14 14 */
15 15
16 16 // phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed -- TODO: Move classes to appropriately-named class files.
17 17
18 +use Automattic\Jetpack\Admin_UI\Admin_Menu;
18 19 use Automattic\Jetpack\Connection\Manager as Connection_Manager;
19 20 use Automattic\Jetpack\Connection\XMLRPC_Async_Call;
21 +use Automattic\Jetpack\Newsletter\Settings as Newsletter_Settings;
22 +use Automattic\Jetpack\Newsletter\Urls as Newsletter_Urls;
20 23 use Automattic\Jetpack\Redirect;
21 24 use Automattic\Jetpack\Status;
22 25 use Automattic\Jetpack\Status\Host;
23 26
27 +if ( ! defined( 'ABSPATH' ) ) {
28 + exit( 0 );
29 +}
30 +
24 31 add_action( 'jetpack_modules_loaded', 'jetpack_subscriptions_load' );
25 32
26 33 // Loads the User Content Link Redirection feature.
27 34 require_once __DIR__ . '/subscriptions/jetpack-user-content-link-redirection.php';
@@ -57,8 +64,10 @@
57 64 }
58 65
59 66 /**
60 67 * Main class file for the Subscriptions module.
68 + *
69 + * @phan-constructor-used-for-side-effects
61 70 */
62 71 class Jetpack_Subscriptions {
63 72 /**
64 73 * Whether Jetpack has been instantiated or not.
@@ -127,8 +136,10 @@
127 136 add_filter( 'post_updated_messages', array( $this, 'update_published_message' ), 18, 1 );
128 137
129 138 // Set "social_notifications_subscribe" option during the first-time activation.
130 139 add_action( 'jetpack_activate_module_subscriptions', array( $this, 'set_social_notifications_subscribe' ) );
140 + add_action( 'jetpack_activate_module_subscriptions', array( $this, 'set_featured_image_in_email_default' ) );
141 + add_action( 'jetpack_activate_module_subscriptions', array( $this, 'set_newsletter_send_default' ) );
131 142
132 143 // Hide subscription messaging in Publish panel for posts that were published in the past
133 144 add_action( 'init', array( $this, 'register_post_meta' ), 20 );
134 145 add_action( 'transition_post_status', array( $this, 'maybe_set_first_published_status' ), 10, 3 );
@@ -134,8 +145,22 @@
134 145 add_action( 'transition_post_status', array( $this, 'maybe_set_first_published_status' ), 10, 3 );
135 146
136 147 // Add Subscribers menu to Jetpack navigation.
137 148 add_action( 'jetpack_admin_menu', array( $this, 'add_subscribers_menu' ) );
149 +
150 + // Customize the configuration URL to lead to the Subscriptions settings.
151 + add_filter(
152 + 'jetpack_module_configuration_url_subscriptions',
153 + function () {
154 + return Newsletter_Urls::get_newsletter_settings_url();
155 + }
156 + );
157 +
158 + // Track categories created through the category editor page
159 + add_action( 'wp_ajax_add-tag', array( $this, 'track_newsletter_category_creation' ), 1 );
160 +
161 + $newsletter_settings = new Newsletter_Settings();
162 + $newsletter_settings::init();
138 163 }
139 164
140 165 /**
141 166 * Jetpack_Subscriptions::xmlrpc_methods()
@@ -357,29 +382,14 @@
357 382 'discussion',
358 383 'stc_enabled'
359 384 );
360 385
361 - /** Enable Subscribe Modal */
362 -
363 - add_settings_field(
364 - 'jetpack_subscriptions_comment_subscribe',
365 - __( 'Enable Subscribe Modal', 'jetpack' ),
366 - array( $this, 'subscribe_modal_setting' ),
367 - 'discussion',
368 - 'jetpack_subscriptions'
369 - );
370 -
371 - register_setting(
372 - 'discussion',
373 - 'sm_enabled'
374 - );
375 -
376 - /** Email me whenever: Someone follows my blog */
386 + /** Email me whenever: Someone subscribes to my blog */
377 387 /* @since 8.1 */
378 388
379 389 add_settings_section(
380 390 'notifications_section',
381 - __( 'Someone follows my blog', 'jetpack' ),
391 + __( 'Someone subscribes to my blog', 'jetpack' ),
382 392 array( $this, 'social_notifications_subscribe_section' ),
383 393 'discussion'
384 394 );
385 395
@@ -395,47 +405,8 @@
395 405 'discussion',
396 406 'social_notifications_subscribe',
397 407 array( $this, 'social_notifications_subscribe_validate' )
398 408 );
399 -
400 - /** Subscription Messaging Options */
401 -
402 - register_setting(
403 - 'reading',
404 - 'subscription_options',
405 - array( $this, 'validate_settings' )
406 - );
407 -
408 - add_settings_section(
409 - 'email_settings',
410 - __( 'Follower Settings', 'jetpack' ),
411 - array( $this, 'reading_section' ),
412 - 'reading'
413 - );
414 -
415 - add_settings_field(
416 - 'invitation',
417 - __( 'Blog follow email text', 'jetpack' ),
418 - array( $this, 'setting_invitation' ),
419 - 'reading',
420 - 'email_settings'
421 - );
422 -
423 - add_settings_field(
424 - 'comment-follow',
425 - __( 'Comment follow email text', 'jetpack' ),
426 - array( $this, 'setting_comment_follow' ),
427 - 'reading',
428 - 'email_settings'
429 - );
430 -
431 - add_settings_field(
432 - 'welcome',
433 - __( 'Welcome email text', 'jetpack' ),
434 - array( $this, 'setting_welcome' ),
435 - 'reading',
436 - 'email_settings'
437 - );
438 409 }
439 410
440 411 /**
441 412 * Discussions setting section blurb.
@@ -494,25 +465,9 @@
494 465 <?php
495 466 }
496 467
497 468 /**
498 - * Subscribe Modal Toggle.
499 - */
500 - public function subscribe_modal_setting() {
501 -
502 - $sm_enabled = get_option( 'sm_enabled', 1 );
503 - ?>
504 -
505 - <p class="description">
506 - <input type="checkbox" name="sm_enabled" id="jetpack-subscribe-modal" value="1" <?php checked( $sm_enabled, 1 ); ?> />
507 - <?php esc_html_e( 'Show a popup subscribe modal to readers.', 'jetpack' ); ?>
508 - </p>
509 -
510 - <?php
511 - }
512 -
513 - /**
514 - * Someone follows my blog section
469 + * Someone subscribes to my blog section
515 470 *
516 471 * @since 8.1
517 472 */
518 473 public function social_notifications_subscribe_section() {
@@ -536,9 +491,9 @@
536 491 <?php
537 492 }
538 493
539 494 /**
540 - * Someone follows my blog Toggle
495 + * Someone subscribes to my blog Toggle
541 496 *
542 497 * @since 8.1
543 498 */
544 499 public function social_notifications_subscribe_field() {
@@ -548,9 +503,9 @@
548 503 <label>
549 504 <input type="checkbox" name="social_notifications_subscribe" id="social_notifications_subscribe" value="1" <?php checked( $checked ); ?> />
550 505 <?php
551 506 /* translators: this is a label for a setting that starts with "Email me whenever" */
552 - esc_html_e( 'Someone follows my blog', 'jetpack' );
507 + esc_html_e( 'Someone subscribes to my blog', 'jetpack' );
553 508 ?>
554 509 </label>
555 510 <?php
556 511 }
@@ -555,9 +510,9 @@
555 510 <?php
556 511 }
557 512
558 513 /**
559 - * Validate "Someone follows my blog" option
514 + * Validate "Someone subscribes to my blog" option
560 515 *
561 516 * @since 8.1
562 517 *
563 518 * @param String $input the input string to be validated.
@@ -573,92 +528,8 @@
573 528 return 'on';
574 529 }
575 530
576 531 /**
577 - * Validate settings for the Subscriptions module.
578 - *
579 - * @param array $settings Settings to be validated.
580 - */
581 - public function validate_settings( $settings ) {
582 - global $allowedposttags;
583 -
584 - $default = $this->get_default_settings();
585 -
586 - // Blog Follow.
587 - $settings['invitation'] = trim( wp_kses( $settings['invitation'], $allowedposttags ) );
588 - if ( empty( $settings['invitation'] ) ) {
589 - $settings['invitation'] = $default['invitation'];
590 - }
591 -
592 - // Comments Follow (single post).
593 - $settings['comment_follow'] = trim( wp_kses( $settings['comment_follow'], $allowedposttags ) );
594 - if ( empty( $settings['comment_follow'] ) ) {
595 - $settings['comment_follow'] = $default['comment_follow'];
596 - }
597 -
598 - return $settings;
599 - }
600 -
601 - /**
602 - * HTML output helper for Reading section.
603 - */
604 - public function reading_section() {
605 - echo '<p id="follower-settings">';
606 - esc_html_e( 'These settings change emails sent from your blog to followers.', 'jetpack' );
607 - echo '</p>';
608 - }
609 -
610 - /**
611 - * HTML output helper for Invitation section.
612 - */
613 - public function setting_invitation() {
614 - $settings = $this->get_settings();
615 - echo '<textarea name="subscription_options[invitation]" class="large-text" cols="50" rows="5">' . esc_textarea( $settings['invitation'] ) . '</textarea>';
616 - 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>';
617 - }
618 -
619 - /**
620 - * HTML output helper for Comment Follow section.
621 - */
622 - public function setting_comment_follow() {
623 - $settings = $this->get_settings();
624 - echo '<textarea name="subscription_options[comment_follow]" class="large-text" cols="50" rows="5">' . esc_textarea( $settings['comment_follow'] ) . '</textarea>';
625 - 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>';
626 - }
627 -
628 - /**
629 - * HTML output helper for Welcome section.
630 - */
631 - public function setting_welcome() {
632 - $settings = $this->get_settings();
633 - echo '<textarea name="subscription_options[welcome]" class="large-text" cols="50" rows="5">' . esc_textarea( $settings['welcome'] ) . '</textarea>';
634 - echo '<p><span class="description">' . esc_html__( 'Welcome text sent when someone follows your blog.', 'jetpack' ) . '</span></p>';
635 - }
636 -
637 - /**
638 - * Get default settings for the Subscriptions module.
639 - */
640 - public function get_default_settings() {
641 - $site_url = get_home_url();
642 - $display_url = preg_replace( '(^https?://)', '', untrailingslashit( $site_url ) );
643 -
644 - return array(
645 - /* translators: Both %1$s and %2$s is site address */
646 - '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 ),
647 - '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' ),
648 - /* translators: %1$s is the site address */
649 - '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 ),
650 - );
651 - }
652 -
653 - /**
654 - * Reeturn merged `subscription_options` option with module default settings.
655 - */
656 - public function get_settings() {
657 - return wp_parse_args( (array) get_option( 'subscription_options' ), $this->get_default_settings() );
658 - }
659 -
660 - /**
661 532 * Jetpack_Subscriptions::subscribe()
662 533 *
663 534 * Send a synchronous XML-RPC subscribe to blog posts or subscribe to post comments request.
664 535 *
@@ -697,8 +568,9 @@
697 568
698 569 if ( $async ) {
699 570 XMLRPC_Async_Call::add_call( 'jetpack.subscribeToSite', 0, $email, $post_id, serialize( $extra_data ) ); //phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
700 571 } else {
572 + // @phan-suppress-next-line PhanPossiblyUndeclaredVariable -- $xml is set when $async is false
701 573 $xml->addCall( 'jetpack.subscribeToSite', $email, $post_id, serialize( $extra_data ) ); //phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
702 574 }
703 575 }
704 576
@@ -706,19 +578,24 @@
706 578 return;
707 579 }
708 580
709 581 // Call.
582 + // @phan-suppress-next-line PhanPossiblyUndeclaredVariable -- $xml is set when $async is false, otherwise we return early
710 583 $xml->query();
711 584
585 + // @phan-suppress-next-line PhanPossiblyUndeclaredVariable -- $xml is set when $async is false, otherwise we return early
712 586 if ( $xml->isError() ) {
587 + // @phan-suppress-next-line PhanPossiblyUndeclaredVariable -- $xml is set when $async is false, otherwise we return early
713 588 return $xml->get_jetpack_error();
714 589 }
715 590
591 + // @phan-suppress-next-line PhanPossiblyUndeclaredVariable -- $xml is set when $async is false
716 592 $responses = $xml->getResponse();
717 593
718 594 $r = array();
719 595 foreach ( (array) $responses as $response ) {
720 596 if ( isset( $response['faultCode'] ) || isset( $response['faultString'] ) ) {
597 + // @phan-suppress-next-line PhanPossiblyUndeclaredVariable -- $xml is set when $async is false
721 598 $r[] = $xml->get_jetpack_error( $response['faultCode'], $response['faultString'] );
722 599 continue;
723 600 }
724 601
@@ -836,9 +713,9 @@
836 713 */
837 714 do_action( 'jetpack_subscriptions_form_submission', $result );
838 715
839 716 wp_safe_redirect( "$redirect#$redirect_fragment" );
840 - exit;
717 + exit( 0 );
841 718 }
842 719
843 720 /**
844 721 * Jetpack_Subscriptions::comment_subscribe_init()
@@ -849,8 +726,13 @@
849 726 */
850 727 public function comment_subscribe_init( $submit_button ) {
851 728 global $post;
852 729
730 + // Subscriptions are only available for posts so far.
731 + if ( ! $post || 'post' !== $post->post_type ) {
732 + return $submit_button;
733 + }
734 +
853 735 $comments_checked = '';
854 736 $blog_checked = '';
855 737
856 738 // Check for a comment / blog submission and set a cookie to retain the setting and check the boxes.
@@ -929,8 +811,19 @@
929 811 * @param int|string $comment_id Comment thread being subscribed to.
930 812 * @param string $approved Comment status.
931 813 */
932 814 public function comment_subscribe_submit( $comment_id, $approved ) {
815 + /**
816 + * Filters whether to skip comment subscription processing.
817 + *
818 + * @since 15.5
819 + *
820 + * @param bool $skip Whether to skip comment subscription. Default false.
821 + */
822 + if ( apply_filters( 'jetpack_subscription_comment_subscribe_skip', false ) ) {
823 + return;
824 + }
825 +
933 826 if ( 'spam' === $approved ) {
934 827 return;
935 828 }
936 829
@@ -993,9 +886,9 @@
993 886 public function set_cookies( $subscribe_to_post = false, $post_id = null, $subscribe_to_blog = false ) {
994 887 $post_id = (int) $post_id;
995 888
996 889 /** This filter is already documented in core/wp-includes/comment-functions.php */
997 - $cookie_lifetime = apply_filters( 'comment_cookie_lifetime', 30000000 );
890 + $cookie_lifetime = apply_filters( 'comment_cookie_lifetime', YEAR_IN_SECONDS );
998 891
999 892 /**
1000 893 * Filter the Jetpack Comment cookie path.
1001 894 *
@@ -1018,15 +911,15 @@
1018 911 */
1019 912 $cookie_domain = apply_filters( 'jetpack_comment_cookie_domain', COOKIE_DOMAIN );
1020 913
1021 914 if ( $subscribe_to_post && $post_id >= 0 ) {
1022 - setcookie( 'jetpack_comments_subscribe_' . self::$hash . '_' . $post_id, 1, time() + $cookie_lifetime, $cookie_path, $cookie_domain, is_ssl(), true );
915 + setcookie( 'jetpack_comments_subscribe_' . self::$hash . '_' . $post_id, '1', time() + $cookie_lifetime, $cookie_path, $cookie_domain, is_ssl(), true );
1023 916 } else {
1024 917 setcookie( 'jetpack_comments_subscribe_' . self::$hash . '_' . $post_id, '', time() - 3600, $cookie_path, $cookie_domain, is_ssl(), true );
1025 918 }
1026 919
1027 920 if ( $subscribe_to_blog ) {
1028 - setcookie( 'jetpack_blog_subscribe_' . self::$hash, 1, time() + $cookie_lifetime, $cookie_path, $cookie_domain, is_ssl(), true );
921 + setcookie( 'jetpack_blog_subscribe_' . self::$hash, '1', time() + $cookie_lifetime, $cookie_path, $cookie_domain, is_ssl(), true );
1029 922 } else {
1030 923 setcookie( 'jetpack_blog_subscribe_' . self::$hash, '', time() - 3600, $cookie_path, $cookie_domain, is_ssl(), true );
1031 924 }
1032 925 }
@@ -1044,8 +937,26 @@
1044 937 }
1045 938 }
1046 939
1047 940 /**
941 + * Set the featured image in email option to `1` when the Subscriptions module is activated in the first time.
942 + *
943 + * @return void
944 + */
945 + public function set_featured_image_in_email_default() {
946 + add_option( 'wpcom_featured_image_in_email', 1 );
947 + }
948 +
949 + /**
950 + * Set the email post to subscribers default option to `1` when the Subscriptions module is activated for the first time.
951 + *
952 + * @return void
953 + */
954 + public function set_newsletter_send_default() {
955 + add_option( 'wpcom_newsletter_send_default', 1 );
956 + }
957 +
958 + /**
1048 959 * Save a flag when a post was ever published.
1049 960 *
1050 961 * It saves the post meta when the post was published and becomes a draft.
1051 962 * Then this meta is used to hide subscription messaging in Publish panel.
@@ -1054,8 +965,13 @@
1054 965 * @param string $old_status The "old" post status of the transition when saved.
1055 966 * @param object $post obj The post object.
1056 967 */
1057 968 public function maybe_set_first_published_status( $new_status, $old_status, $post ) {
969 + // Subscriptions are only available for posts so far.
970 + if ( ! $post instanceof \WP_Post || 'post' !== $post->post_type ) {
971 + return;
972 + }
973 +
1058 974 $was_post_ever_published = get_post_meta( $post->ID, '_jetpack_post_was_ever_published', true );
1059 975 if ( ! $was_post_ever_published && 'publish' === $old_status && 'draft' === $new_status ) {
1060 976 update_post_meta( $post->ID, '_jetpack_post_was_ever_published', true );
1061 977 }
@@ -1061,14 +977,24 @@
1061 977 }
1062 978 }
1063 979
1064 980 /**
1065 - * Checks if the current user can publish posts.
981 + * Checks if the current user can edit posts.
1066 982 *
1067 983 * @return bool
1068 984 */
1069 985 public function first_published_status_meta_auth_callback() {
1070 - if ( current_user_can( 'publish_posts' ) ) {
986 + /**
987 + * Filter the capability required to edit the "was ever published" post meta.
988 + *
989 + * @module subscriptions
990 + *
991 + * @since 13.4
992 + *
993 + * @param string $capability User capability needed to edit the "was ever published" meta. Default to edit_posts.
994 + */
995 + $capability = apply_filters( 'jetpack_subscriptions_post_was_ever_published_capability', 'edit_posts' );
996 + if ( current_user_can( $capability ) ) {
1071 997 return true;
1072 998 }
1073 999 return false;
1074 1000 }
@@ -1077,16 +1003,17 @@
1077 1003 * Registers the 'post_was_ever_published' post meta for use in the REST API.
1078 1004 */
1079 1005 public function register_post_meta() {
1080 1006 $jetpack_post_was_ever_published = array(
1081 - 'type' => 'boolean',
1082 - 'description' => __( 'Whether the post was ever published.', 'jetpack' ),
1083 - 'single' => true,
1084 - 'default' => false,
1085 - 'show_in_rest' => array(
1007 + 'type' => 'boolean',
1008 + 'description' => __( 'Whether the post was ever published.', 'jetpack' ),
1009 + 'single' => true,
1010 + 'default' => false,
1011 + 'show_in_rest' => array(
1086 1012 'name' => 'jetpack_post_was_ever_published',
1087 1013 ),
1088 - 'auth_callback' => array( $this, 'first_published_status_meta_auth_callback' ),
1014 + 'auth_callback' => array( $this, 'first_published_status_meta_auth_callback' ),
1015 + 'object_subtype' => 'post', // Subscriptions are only for the post post type so far, so we can limit this meta to posts only.
1089 1016 );
1090 1017
1091 1018 register_meta( 'post', '_jetpack_post_was_ever_published', $jetpack_post_was_ever_published );
1092 1019 }
@@ -1095,17 +1022,28 @@
1095 1022 * Create a Subscribers menu displayed on self-hosted sites.
1096 1023 *
1097 1024 * - It is not displayed on WordPress.com sites.
1098 1025 * - It directs you to Calypso to the existing Subscribers page.
1026 + * - It is retired once the Newsletter modernization filter is on, since the
1027 + * unified Newsletter page then owns the Subscribers tab.
1099 1028 *
1100 1029 * @return void
1101 1030 */
1102 1031 public function add_subscribers_menu() {
1103 1032 /*
1104 - * Do not display any menu on WoA and WordPress.com Simple sites.
1033 + * Referenced as a string literal (mirrors Newsletter\Settings::MODERNIZATION_FILTER)
1034 + * to keep this bootstrap path safe if the packaged Newsletter Settings class does
1035 + * not expose the constant yet.
1036 + */
1037 + if ( apply_filters( 'rsm_jetpack_ui_modernization_newsletter', true ) ) {
1038 + return;
1039 + }
1040 +
1041 + /*
1042 + * Do not display any menu on WoA and WordPress.com Simple sites (unless Classic wp-admin is enabled).
1105 1043 * They already get a menu item under Users via nav-unification.
1106 1044 */
1107 - if ( ( new Host() )->is_wpcom_platform() ) {
1045 + if ( ( new Host() )->is_wpcom_platform() && get_option( 'wpcom_admin_interface' ) !== 'wp-admin' ) {
1108 1046 return;
1109 1047 }
1110 1048
1111 1049 $status = new Status();
@@ -1120,22 +1058,69 @@
1120 1058 ) {
1121 1059 return;
1122 1060 }
1123 1061
1062 + /**
1063 + * Enables the new in development subscribers in wp-admin dashboard.
1064 + *
1065 + * @since 9.5.0
1066 + *
1067 + * @param bool If the new dashboard is enabled. Defaults on for every site; hosts
1068 + * can opt out with this filter.
1069 + */
1070 + if ( apply_filters( 'jetpack_wp_admin_subscriber_management_enabled', true ) ) {
1071 + return;
1072 + }
1073 +
1074 + $blog_id = Connection_Manager::get_site_id( true );
1075 +
1124 1076 $link = Redirect::get_url(
1125 - 'jetpack-menu-calypso-subscribers',
1126 - array( 'site' => $status->get_site_suffix() )
1077 + 'jetpack-menu-jetpack-manage-subscribers',
1078 + array( 'site' => $blog_id ? $blog_id : $status->get_site_suffix() )
1127 1079 );
1128 1080
1129 - add_submenu_page(
1130 - 'jetpack',
1131 - esc_attr__( 'Subscribers', 'jetpack' ),
1132 - __( 'Subscribers', 'jetpack' ) . ' <span class="dashicons dashicons-external"></span>',
1081 + $position = defined( Admin_Menu::class . '::POSITION_EXTERNAL' ) ? Admin_Menu::POSITION_EXTERNAL : 100;
1082 +
1083 + Admin_Menu::add_menu(
1084 + __( 'Subscribers', 'jetpack' ),
1085 + __( 'Subscribers', 'jetpack' ) . ' <span aria-hidden="true">↗</span>',
1133 1086 'manage_options',
1134 1087 esc_url( $link ),
1135 - null
1088 + null,
1089 + $position,
1090 + array( 'key' => 'jetpack-subscribers' )
1136 1091 );
1137 1092 }
1093 +
1094 + /**
1095 + * Record tracks event if categories is created when user enters
1096 + * the edit category page through the newsletter settings page.
1097 + *
1098 + * @return void
1099 + */
1100 + public function track_newsletter_category_creation() {
1101 +
1102 + // phpcs:disable WordPress.Security.NonceVerification.Missing
1103 + if ( empty( $_POST['_wp_http_referer'] ) ) {
1104 + return;
1105 + }
1106 +
1107 + if ( strpos( sanitize_url( wp_unslash( $_POST['_wp_http_referer'] ) ), 'referer=newsletter-categories' ) > -1 ) {
1108 +
1109 + $parent = filter_var( empty( $_POST['parent'] ) ? 0 : wp_unslash( $_POST['parent'] ), FILTER_SANITIZE_NUMBER_INT );
1110 +
1111 + $is_child_category = $parent > 0;
1112 +
1113 + $tracking = new Automattic\Jetpack\Tracking();
1114 + $tracking->tracks_record_event(
1115 + wp_get_current_user(),
1116 + 'jetpack_newsletter_add_category',
1117 + array(
1118 + 'is_child_category' => $is_child_category,
1119 + )
1120 + );
1121 + }
1122 + }
1138 1123 }
1139 1124
1140 1125 Jetpack_Subscriptions::init();
1141 1126
@@ -1140,4 +1125,11 @@
1140 1125 Jetpack_Subscriptions::init();
1141 1126
1142 1127 require __DIR__ . '/subscriptions/views.php';
1143 1128 require __DIR__ . '/subscriptions/subscribe-modal/class-jetpack-subscribe-modal.php';
1129 +require __DIR__ . '/subscriptions/subscribe-overlay/class-jetpack-subscribe-overlay.php';
1130 +require __DIR__ . '/subscriptions/subscribe-floating-button/class-jetpack-subscribe-floating-button.php';
1131 +require __DIR__ . '/subscriptions/newsletter-widget/class-jetpack-newsletter-dashboard-widget.php';
1132 +require_once __DIR__ . '/subscriptions/email-design-editor/class-jetpack-email-design-editor.php';
1133 +
1134 +require_once __DIR__ . '/subscriptions/abilities/class-newsletter-abilities.php';
1135 +\Automattic\Jetpack\Plugin\Abilities\Newsletter_Abilities::init();