diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a4b5ef260..aa18d1b61d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -456,7 +456,6 @@ ress/* packages # [4.4.0](https://github.com/Automattic/newspack-plugin/compare/v4.3.4...v4.4.0) (2024-07-01) - ### Bug Fixes * add modified check before updating donation product ([#3183](https://github.com/Automattic/newspack-plugin/issues/3183)) ([208c55e](https://github.com/Automattic/newspack-plugin/commit/208c55e21ac8f6a4b6736f89c25cf12994f2cbaf)) @@ -563,6 +562,13 @@ ress/* packages * **ia:** back to `trunk` ([69b2ba0](https://github.com/Automattic/newspack-plugin/commit/69b2ba09a222e7c1b84b9cba0b97c36881cda63f)) +## [4.3.4](https://github.com/Automattic/newspack-plugin/compare/v4.3.3...v4.3.4) (2024-06-27) + +### Bug Fixes + +* variable name > constant ([#3203](https://github.com/Automattic/newspack-plugin/issues/3203)) ([46c5651](https://github.com/Automattic/newspack-plugin/commit/46c5651cf48e88abef3b8f3855b8fd3f5860c2a3)) + + ## [4.3.3](https://github.com/Automattic/newspack-plugin/compare/v4.3.2...v4.3.3) (2024-06-24) diff --git a/includes/class-blocks.php b/includes/class-blocks.php index eccc0fafa8..a315a121af 100644 --- a/includes/class-blocks.php +++ b/includes/class-blocks.php @@ -42,7 +42,7 @@ public static function enqueue_block_editor_assets() { 'has_reader_activation' => Reader_Activation::is_enabled(), 'newsletters_url' => Wizards::get_wizard( 'engagement' )->newsletters_settings_url(), 'has_google_oauth' => Google_OAuth::is_oauth_configured(), - 'google_logo_svg' => file_get_contents( dirname( NEWSPACK_PLUGIN_FILE ) . '/src/blocks/reader-registration/icons/google.svg' ), + 'google_logo_svg' => \Newspack\Newspack_UI_Icons::get_svg( 'google' ), 'reader_activation_terms' => Reader_Activation::get_setting( 'terms_text' ), 'reader_activation_url' => Reader_Activation::get_setting( 'terms_url' ), 'has_recaptcha' => Recaptcha::can_use_captcha(), diff --git a/includes/class-donations.php b/includes/class-donations.php index 54d21e369a..06c2b44a38 100644 --- a/includes/class-donations.php +++ b/includes/class-donations.php @@ -64,18 +64,24 @@ class Donations { * @codeCoverageIgnore */ public static function init() { - self::$donation_product_name = __( 'Donate', 'newspack' ); - if ( ! is_admin() ) { - add_action( 'wp_loaded', [ __CLASS__, 'process_donation_form' ], 99 ); - add_action( 'woocommerce_checkout_update_order_meta', [ __CLASS__, 'woocommerce_checkout_update_order_meta' ] ); - add_filter( 'woocommerce_billing_fields', [ __CLASS__, 'woocommerce_billing_fields' ] ); - add_filter( 'pre_option_woocommerce_enable_guest_checkout', [ __CLASS__, 'disable_guest_checkout' ] ); - add_action( 'woocommerce_check_cart_items', [ __CLASS__, 'handle_cart' ] ); - add_filter( 'amp_skip_post', [ __CLASS__, 'should_skip_amp' ], 10, 2 ); - add_filter( 'newspack_blocks_donate_billing_fields_keys', [ __CLASS__, 'get_billing_fields' ] ); - add_action( 'woocommerce_checkout_create_order_line_item', [ __CLASS__, 'checkout_create_order_line_item' ], 10, 4 ); - add_action( 'woocommerce_coupons_enabled', [ __CLASS__, 'disable_coupons' ] ); - } + self::$donation_product_name = __( 'Donate', 'newspack-plugin' ); + + // Process donation request. + add_action( 'wp_ajax_modal_checkout_request', [ __CLASS__, 'process_donation_request' ] ); + add_action( 'wp_ajax_nopriv_modal_checkout_request', [ __CLASS__, 'process_donation_request' ] ); + add_action( 'wp_loaded', [ __CLASS__, 'process_donation_request' ], 99 ); + + add_action( 'woocommerce_checkout_update_order_meta', [ __CLASS__, 'woocommerce_checkout_update_order_meta' ] ); + add_filter( 'woocommerce_billing_fields', [ __CLASS__, 'woocommerce_billing_fields' ] ); + add_filter( 'pre_option_woocommerce_enable_guest_checkout', [ __CLASS__, 'disable_guest_checkout' ] ); + add_action( 'woocommerce_check_cart_items', [ __CLASS__, 'handle_cart' ] ); + add_filter( 'amp_skip_post', [ __CLASS__, 'should_skip_amp' ], 10, 2 ); + add_filter( 'newspack_blocks_donate_billing_fields_keys', [ __CLASS__, 'get_billing_fields' ] ); + add_action( 'woocommerce_checkout_create_order_line_item', [ __CLASS__, 'checkout_create_order_line_item' ], 10, 4 ); + add_filter( 'woocommerce_coupons_enabled', [ __CLASS__, 'disable_coupons' ] ); + add_filter( 'wcs_place_subscription_order_text', [ __CLASS__, 'order_button_text' ], 9 ); + add_filter( 'woocommerce_order_button_text', [ __CLASS__, 'order_button_text' ], 9 ); + add_filter( 'option_woocommerce_subscriptions_order_button_text', [ __CLASS__, 'order_button_text' ], 9 ); } /** @@ -647,7 +653,11 @@ public static function is_platform_other() { /** * Handle submission of the donation form. */ - public static function process_donation_form() { + public static function process_donation_request() { + if ( is_admin() && ! defined( 'DOING_AJAX' ) ) { + return; + } + $is_wc = self::is_platform_wc(); $donation_form_submitted = filter_input( INPUT_GET, 'newspack_donate', FILTER_SANITIZE_NUMBER_INT ); @@ -737,6 +747,11 @@ function ( $item ) { [], $cart_item_data ); + + // Set checkout registration flag if user is not logged in. + if ( ! is_user_logged_in() && class_exists( '\Newspack_Blocks\Modal_Checkout' ) ) { + \Newspack_Blocks\Modal_Checkout::set_checkout_registration_flag(); + } } $query_args = []; @@ -771,8 +786,16 @@ function ( $item ) { ); // Redirect to checkout. - \wp_safe_redirect( apply_filters( 'newspack_donation_checkout_url', $checkout_url, $donation_value, $donation_frequency ) ); - exit; + $checkout_url = apply_filters( 'newspack_donation_checkout_url', $checkout_url, $donation_value, $donation_frequency ); + + if ( defined( 'DOING_AJAX' ) ) { + echo wp_json_encode( [ 'url' => $checkout_url ] ); + exit; + } else { + // Redirect to checkout. + \wp_safe_redirect( $checkout_url ); + exit; + } } /** @@ -1085,6 +1108,9 @@ public static function update_billing_fields( $billing_fields ) { * @return bool */ public static function disable_coupons( $enabled ) { + if ( is_admin() ) { + return $enabled; + } $cart = WC()->cart; if ( ! $cart ) { return $enabled; @@ -1094,5 +1120,17 @@ public static function disable_coupons( $enabled ) { } return false; } + + /** + * Set the "Place order" button text. + * + * @param string $text The button text. + */ + public static function order_button_text( $text ) { + if ( self::is_donation_cart() ) { + return __( 'Donate now', 'newspack-plugin' ); + } + return $text; + } } Donations::init(); diff --git a/includes/class-magic-link.php b/includes/class-magic-link.php index 9213a408e6..2a36744359 100644 --- a/includes/class-magic-link.php +++ b/includes/class-magic-link.php @@ -21,8 +21,9 @@ final class Magic_Link { 'enable' => 'np_magic_link_enable', ]; - const TOKENS_META = 'np_magic_link_tokens'; - const DISABLED_META = 'np_magic_link_disabled'; + const TOKENS_META = 'np_magic_link_tokens'; + const DISABLED_META = 'np_magic_link_disabled'; + const USER_SECRET_META = 'np_magic_link_secret'; const AUTH_ACTION = 'np_auth_link'; const AUTH_ACTION_RESULT = 'np_auth_link_result'; @@ -34,6 +35,9 @@ final class Magic_Link { const OTP_MAX_ATTEMPTS = 5; const OTP_AUTH_ACTION = 'np_otp_auth'; const OTP_HASH_COOKIE = 'np_otp_hash'; + const ACCEPTED_PARAMS = [ + 'checkout', + ]; /** * Current session secret. @@ -61,6 +65,7 @@ public static function init() { /** Replace Newspack Newsletters Verification Email */ \add_filter( 'newspack_newsletters_email_verification_email', [ __CLASS__, 'newsletters_email_verification_email' ], 10, 3 ); + \add_action( 'wp_logout', [ __CLASS__, 'clear_user_tokens' ], 10, 1 ); } /** @@ -255,10 +260,11 @@ private static function get_client_hash( $user, $reset_secret = false ) { /** * Clear all user tokens. * - * @param \WP_User $user User to clear tokens for. + * @param \WP_User|int $user User or user ID to clear tokens for. */ public static function clear_user_tokens( $user ) { - \delete_user_meta( $user->ID, self::TOKENS_META ); + $user_id = $user instanceof \WP_User ? $user->ID : $user; + \delete_user_meta( $user_id, self::TOKENS_META ); /** * Fires after all user tokens are cleared. @@ -334,7 +340,7 @@ private static function generate_otp( $user ) { */ public static function generate_token( $user ) { if ( ! self::can_magic_link( $user->ID ) ) { - return new \WP_Error( 'newspack_magic_link_invalid_user', __( 'Invalid user.', 'newspack' ) ); + return new \WP_Error( 'newspack_magic_link_invalid_user', __( 'Invalid user.', 'newspack-plugin' ) ); } $now = time(); @@ -345,6 +351,14 @@ public static function generate_token( $user ) { $expire = $now - self::get_token_expiration_period(); if ( ! empty( $tokens ) ) { + + /** + * Filters the magic link rate interval. + * + * @param int $rate_interval Magic link rate interval. + */ + $rate_interval = apply_filters( 'newspack_magic_link_rate_interval', self::RATE_INTERVAL ); + /** Limit maximum tokens to 5. */ $tokens = array_slice( $tokens, -4, 4 ); foreach ( $tokens as $index => $token_data ) { @@ -353,8 +367,8 @@ public static function generate_token( $user ) { unset( $tokens[ $index ] ); } /** Rate limit token generation. */ - if ( $token_data['time'] + self::RATE_INTERVAL > $now ) { - return new \WP_Error( 'rate_limit_exceeded', __( 'Please wait a minute before requesting another authorization code.', 'newspack' ) ); + if ( $token_data['time'] + $rate_interval > $now ) { + return new \WP_Error( 'rate_limit_exceeded', __( 'Please wait a minute before requesting another authorization code.', 'newspack-plugin' ) ); } } $tokens = array_values( $tokens ); @@ -374,6 +388,60 @@ public static function generate_token( $user ) { return $token_data; } + /** + * Generate secret. + * + * @param \WP_User $user User to generate the secret for. + * + * @return string + */ + public static function generate_secret( $user ) { + $secret = \get_user_meta( $user->ID, self::USER_SECRET_META, true ); + if ( ! empty( $secret ) ) { + return $secret; + } + $secret = wp_hash( $user->user_email ); + \update_user_meta( $user->ID, self::USER_SECRET_META, $secret ); + return $secret; + } + + /** + * Check for active magic link tokens. + * + * @param \WP_User $user User to check the active magic link token for. + * + * @return bool|\WP_Error + */ + public static function has_active_token( $user ) { + if ( ! self::can_magic_link( $user->ID ) ) { + return new \WP_Error( 'newspack_magic_link_invalid_user', __( 'Invalid user.', 'newspack-plugin' ) ); + } + + // If an OTP hash cookie is not set, ignore any active tokens. + if ( ! isset( $_COOKIE[ self::OTP_HASH_COOKIE ] ) ) { + return false; + } + + $now = time(); + $tokens = \get_user_meta( $user->ID, self::TOKENS_META, true ); + + $expire = $now - self::get_token_expiration_period(); + if ( ! empty( $tokens ) ) { + foreach ( $tokens as $index => $token_data ) { + /** Clear expired tokens. */ + if ( $token_data['time'] < $expire ) { + unset( $tokens[ $index ] ); + } + } + } + + if ( empty( $tokens ) ) { + return false; + } + + return true; + } + /** * Generate a magic link. * @@ -392,8 +460,8 @@ public static function generate_url( $user, $url = '' ) { return \add_query_arg( [ 'action' => self::AUTH_ACTION, - 'email' => urlencode( $user->user_email ), 'token' => $token_data['token'], + 'secret' => self::generate_secret( $user ), ], ! empty( $url ) ? $url : \home_url() ); @@ -413,11 +481,16 @@ public static function send_email( $user, $redirect_to = '', $use_otp = true ) { if ( \is_wp_error( $token_data ) ) { return $token_data; } - $url = \add_query_arg( + + $key = \get_password_reset_key( $user ); + if ( is_wp_error( $key ) ) { + return $key; + } + $url = \add_query_arg( [ 'action' => self::AUTH_ACTION, - 'email' => urlencode( $user->user_email ), 'token' => $token_data['token'], + 'secret' => self::generate_secret( $user ), ], ! empty( $redirect_to ) ? $redirect_to : \home_url() ); @@ -427,6 +500,10 @@ public static function send_email( $user, $redirect_to = '', $use_otp = true ) { 'template' => '*MAGIC_LINK_URL*', 'value' => $url, ], + [ + 'template' => '*SET_PASSWORD_LINK*', + 'value' => Emails::get_password_reset_url( $user, $key ), + ], ]; if ( $use_otp && ! empty( $token_data['otp'] ) ) { $email_type = 'OTP_AUTH'; @@ -466,13 +543,13 @@ public static function validate_token( $user_id, $client, $token ) { $user = \get_user_by( 'id', $user_id ); if ( ! $user ) { - $errors->add( 'invalid_user', __( 'User not found.', 'newspack' ) ); + $errors->add( 'invalid_user', __( 'User not found.', 'newspack-plugin' ) ); } elseif ( ! self::can_magic_link( $user->ID ) ) { - $errors->add( 'invalid_user_type', __( 'Not allowed for this user', 'newspack' ) ); + $errors->add( 'invalid_user_type', __( 'Not allowed for this user', 'newspack-plugin' ) ); } else { $tokens = \get_user_meta( $user->ID, self::TOKENS_META, true ); if ( empty( $tokens ) || empty( $token ) ) { - $errors->add( 'invalid_token', __( 'Invalid token.', 'newspack' ) ); + $errors->add( 'invalid_token', __( 'Invalid token.', 'newspack-plugin' ) ); } } @@ -493,7 +570,7 @@ public static function validate_token( $user_id, $client, $token ) { /** If token data has a client hash, it must be equal to the user's. */ if ( ! empty( $token_data['client'] ) && $token_data['client'] !== $client ) { - $errors->add( 'invalid_client', __( 'Invalid client.', 'newspack' ) ); + $errors->add( 'invalid_client', __( 'Invalid client.', 'newspack-plugin' ) ); } unset( $tokens[ $index ] ); @@ -502,7 +579,7 @@ public static function validate_token( $user_id, $client, $token ) { } if ( empty( $valid_token ) ) { - $errors->add( 'invalid_token', __( 'Invalid token.', 'newspack' ) ); + $errors->add( 'invalid_token', __( 'Invalid token.', 'newspack-plugin' ) ); } self::clear_token_cookies(); @@ -536,17 +613,17 @@ public static function validate_otp( $user_id, $hash, $code ) { $user = \get_user_by( 'id', $user_id ); if ( ! $user ) { - $errors->add( 'invalid_user', __( 'User not found.', 'newspack' ) ); + $errors->add( 'invalid_user', __( 'User not found.', 'newspack-plugin' ) ); } elseif ( ! self::can_magic_link( $user->ID ) ) { - $errors->add( 'invalid_user_type', __( 'Not allowed for this user', 'newspack' ) ); + $errors->add( 'invalid_user_type', __( 'Not allowed for this user', 'newspack-plugin' ) ); } elseif ( ! self::is_otp_enabled( $user ) ) { - $errors->add( 'invalid_otp', __( 'OTP is not enabled.', 'newspack' ) ); + $errors->add( 'invalid_otp', __( 'OTP is not enabled.', 'newspack-plugin' ) ); } else { $tokens = \get_user_meta( $user->ID, self::TOKENS_META, true ); if ( empty( $tokens ) || empty( $hash ) ) { - $errors->add( 'invalid_hash', __( 'Invalid hash.', 'newspack' ) ); + $errors->add( 'invalid_hash', __( 'Invalid hash.', 'newspack-plugin' ) ); } elseif ( empty( $code ) ) { - $errors->add( 'invalid_otp', __( 'Invalid OTP.', 'newspack' ) ); + $errors->add( 'invalid_otp', __( 'Invalid OTP.', 'newspack-plugin' ) ); } } @@ -572,18 +649,18 @@ public static function validate_otp( $user_id, $hash, $code ) { // Handle OTP attempts from given hash. $tokens[ $index ]['otp']['attempts']++; if ( $token_data['otp']['attempts'] >= self::OTP_MAX_ATTEMPTS ) { - $errors->add( 'max_otp_attempts', __( 'Maximum OTP attempts reached.', 'newspack' ) ); + $errors->add( 'max_otp_attempts', __( 'Maximum OTP attempts reached.', 'newspack-plugin' ) ); unset( $tokens[ $index ] ); self::clear_token_cookies(); } - $errors->add( 'invalid_otp', __( 'Invalid OTP.', 'newspack' ) ); + $errors->add( 'invalid_otp', __( 'Invalid OTP.', 'newspack-plugin' ) ); } break; } } if ( empty( $valid_token ) ) { - $errors->add( 'invalid_hash', __( 'Invalid hash.', 'newspack' ) ); + $errors->add( 'invalid_hash', __( 'Invalid hash.', 'newspack-plugin' ) ); } $tokens = array_values( $tokens ); @@ -619,12 +696,12 @@ private static function authenticate( $user_id, $token_or_otp_hash, $otp_code = $user = \get_user_by( 'id', $user_id ); if ( ! $user ) { - return new \WP_Error( 'invalid_user', __( 'User not found.', 'newspack' ) ); + return new \WP_Error( 'invalid_user', __( 'User not found.', 'newspack-plugin' ) ); } if ( ! empty( $otp_hash ) ) { if ( ! self::is_otp_enabled( $user ) ) { - return new \WP_Error( 'invalid_otp', __( 'OTP is not enabled.', 'newspack' ) ); + return new \WP_Error( 'invalid_otp', __( 'OTP is not enabled.', 'newspack-plugin' ) ); } $token_data = self::validate_otp( $user_id, $otp_hash, $otp_code ); } else { @@ -660,7 +737,6 @@ public static function process_token_request() { if ( ! Reader_Activation::is_enabled() ) { return; } - // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET[ self::AUTH_ACTION_RESULT ] ) && 0 === \absint( $_GET[ self::AUTH_ACTION_RESULT ] ) ) { \add_action( @@ -676,58 +752,64 @@ function () { } self::USER_SECRET_META, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key + 'meta_value' => $secret, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value + 'number' => 1, + 'count_total' => false, + ] + ); + $users = $user_query->get_results(); + if ( empty( $users ) ) { $errored = true; + } else { + $user = $users[0]; } } else { $errored = true; } } - $authenticated = false; - - if ( ! $errored ) { - // phpcs:ignore WordPress.Security.NonceVerification.Recommended - $token = \sanitize_text_field( \wp_unslash( $_GET['token'] ) ); + if ( ! $errored && ! empty( $user ) ) { + $token = \sanitize_text_field( \wp_unslash( $_GET['token'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended $authenticated = self::authenticate( $user->ID, $token ); } - - $redirect = \wp_validate_redirect( + $query_args = [ self::AUTH_ACTION_RESULT => true === $authenticated ? '1' : '0' ]; + foreach ( self::ACCEPTED_PARAMS as $param ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended - \sanitize_text_field( \wp_unslash( $_GET['redirect'] ?? '' ) ), - \remove_query_arg( [ 'action', 'email', 'token' ] ) - ); - - \wp_safe_redirect( - \add_query_arg( - [ self::AUTH_ACTION_RESULT => true === $authenticated ? '1' : '0' ], - $redirect - ) + if ( isset( $_GET[ $param ] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $query_args[ $param ] = \sanitize_text_field( \wp_unslash( $_GET[ $param ] ) ); + } + } + $redirect = \sanitize_url( \wp_unslash( $_GET['redirect'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $redirect = \wp_validate_redirect( + \add_query_arg( $query_args, $redirect ), + \remove_query_arg( [ 'action', 'secret', 'token' ] ) ); + \wp_safe_redirect( $redirect ); exit; } @@ -740,7 +822,7 @@ function () { */ private static function send_otp_request_response( $message = '', $success = false, $data = [] ) { if ( ! \wp_is_json_request() ) { - \wp_die( \esc_html__( 'Unsupported request method', 'newspack' ) ); + \wp_die( \esc_html__( 'Unsupported request method', 'newspack-plugin' ) ); } \wp_send_json( [ @@ -773,16 +855,16 @@ public static function process_otp_request() { // phpcs:enable if ( ! \wp_is_json_request() ) { - \wp_die( \esc_html__( 'Unsupported request method', 'newspack' ) ); + \wp_die( \esc_html__( 'Unsupported request method', 'newspack-plugin' ) ); } if ( empty( $hash ) || empty( $code ) || empty( $email ) ) { - return self::send_otp_request_response( __( 'Missing required parameters', 'newspack' ), false ); + return self::send_otp_request_response( __( 'Missing required parameters', 'newspack-plugin' ), false ); } $user = \get_user_by( 'email', $email ); if ( ! $user ) { - return self::send_otp_request_response( __( 'Invalid user', 'newspack' ), false ); + return self::send_otp_request_response( __( 'Invalid user', 'newspack-plugin' ), false ); } if ( ! self::is_otp_enabled( $user ) ) { return; @@ -792,18 +874,18 @@ public static function process_otp_request() { if ( is_wp_error( $authenticated ) ) { if ( 'max_otp_attempts' === $authenticated->get_error_code() ) { - return self::send_otp_request_response( __( "You've reached the maximum attempts for this code. Please try again.", 'newspack' ), false, [ 'expired' => true ] ); + return self::send_otp_request_response( __( "You've reached the maximum attempts for this code, try again.", 'newspack-plugin' ), false, [ 'expired' => true ] ); } if ( 'invalid_otp' === $authenticated->get_error_code() ) { - return self::send_otp_request_response( __( 'The code does not match.', 'newspack' ), false ); + return self::send_otp_request_response( __( 'Code not recognized, try again.', 'newspack-plugin' ), false ); } } if ( true !== $authenticated ) { - return self::send_otp_request_response( __( 'Unable to authenticated. Please try again.', 'newspack' ), false, [ 'expired' => true ] ); + return self::send_otp_request_response( __( 'Unable to authenticate, try again.', 'newspack-plugin' ), false, [ 'expired' => true ] ); } - return self::send_otp_request_response( __( 'Login successful!', 'newspack' ), true ); + return self::send_otp_request_response( __( 'Login successful!', 'newspack-plugin' ), true ); } /** @@ -845,7 +927,7 @@ public static function wp_cli() { } if ( ! $user || \is_wp_error( $user ) ) { - \WP_CLI::error( __( 'User not found.', 'newspack' ) ); + \WP_CLI::error( __( 'User not found.', 'newspack-plugin' ) ); } $result = self::send_email( $user ); @@ -855,13 +937,13 @@ public static function wp_cli() { } // translators: %s is the email address of the user. - \WP_CLI::success( sprintf( __( 'Email sent to %s.', 'newspack' ), $user->user_email ) ); + \WP_CLI::success( sprintf( __( 'Email sent to %s.', 'newspack-plugin' ), $user->user_email ) ); }; \WP_CLI::add_command( 'newspack magic-link send', $send, [ - 'shortdesc' => __( 'Send a magic link to a reader.', 'newspack' ), + 'shortdesc' => __( 'Send a magic link to a reader.', 'newspack-plugin' ), ] ); } @@ -905,7 +987,7 @@ public static function user_row_actions( $actions, $user ) { } if ( self::can_magic_link( $user->ID ) && \current_user_can( 'edit_user', $user->ID ) ) { $url = self::get_admin_action_url( 'send', $user->ID ); - $actions['newspack-magic-link-send'] = '' . \esc_html__( 'Send authentication link', 'newspack' ) . ''; + $actions['newspack-magic-link-send'] = '' . \esc_html__( 'Send authentication link', 'newspack-plugin' ) . ''; } return $actions; } @@ -926,16 +1008,16 @@ public static function process_admin_action() { $message = ''; switch ( $update ) { case $actions['send']: - $message = __( 'Authentication link sent.', 'newspack' ); + $message = __( 'Authentication link sent.', 'newspack-plugin' ); break; case $actions['clear']: - $message = __( 'All authentication link tokens were removed.', 'newspack' ); + $message = __( 'All authentication link tokens were removed.', 'newspack-plugin' ); break; case $actions['disable']: - $message = __( 'Authentication links are now disabled.', 'newspack' ); + $message = __( 'Authentication links are now disabled.', 'newspack-plugin' ); break; case $actions['enable']: - $message = __( 'Authentication links are now enabled.', 'newspack' ); + $message = __( 'Authentication links are now enabled.', 'newspack-plugin' ); break; } if ( ! empty( $message ) ) { @@ -957,23 +1039,23 @@ function() use ( $message ) { $action = \sanitize_text_field( \wp_unslash( $_GET['action'] ) ); if ( ! isset( $_GET['uid'] ) ) { - \wp_die( \esc_html__( 'Invalid request.', 'newspack' ) ); + \wp_die( \esc_html__( 'Invalid request.', 'newspack-plugin' ) ); } if ( ! \check_admin_referer( $action ) ) { - \wp_die( \esc_html__( 'Invalid request.', 'newspack' ) ); + \wp_die( \esc_html__( 'Invalid request.', 'newspack-plugin' ) ); } $user_id = \absint( \wp_unslash( $_GET['uid'] ) ); if ( ! \current_user_can( 'edit_user', $user_id ) ) { - \wp_die( \esc_html__( 'You do not have permission to do that.', 'newspack' ) ); + \wp_die( \esc_html__( 'You do not have permission to do that.', 'newspack-plugin' ) ); } $user = \get_user_by( 'id', $user_id ); if ( ! $user || \is_wp_error( $user ) ) { - \wp_die( \esc_html__( 'User not found.', 'newspack' ) ); + \wp_die( \esc_html__( 'User not found.', 'newspack-plugin' ) ); } switch ( $action ) { @@ -1017,10 +1099,10 @@ public static function edit_user_profile( $user ) { $disabled = (bool) \get_user_meta( $user->ID, self::DISABLED_META, true ); ?>