From 80b88399ae18f90ccd57641497b2d4a9d76bfe29 Mon Sep 17 00:00:00 2001 From: Kelly Dwan Date: Tue, 26 Nov 2019 15:37:19 -0500 Subject: [PATCH] Manage Pledge: Allow pledge admins to change email (#113) * Add the admin email field to the manage form * Fix admin email processing: When the email is changed, the pledge needs to be set back to pending, until the email is re-confirmed * Send confirmation emails for existing pledges to the "Manage Pledge" page * Process the email confirmation & resending emails actions on both shortcodes * Add a message for unconfirmed pledges --- plugins/wporg-5ftf/includes/pledge-form.php | 156 ++++++++++++------ plugins/wporg-5ftf/includes/pledge-meta.php | 12 +- .../views/form-pledge-confirm-email.php | 20 ++- .../wporg-5ftf/views/form-pledge-manage.php | 1 + .../views/inputs-pledge-org-email.php | 13 +- .../wporg-5ftf/css/objects/_pledge-form.scss | 2 +- 6 files changed, 139 insertions(+), 65 deletions(-) diff --git a/plugins/wporg-5ftf/includes/pledge-form.php b/plugins/wporg-5ftf/includes/pledge-form.php index 86755d6..056a4d5 100755 --- a/plugins/wporg-5ftf/includes/pledge-form.php +++ b/plugins/wporg-5ftf/includes/pledge-form.php @@ -15,6 +15,11 @@ defined( 'WPINC' ) || die(); add_shortcode( '5ftf_pledge_form_new', __NAMESPACE__ . '\render_form_new' ); add_shortcode( '5ftf_pledge_form_manage', __NAMESPACE__ . '\render_form_manage' ); +// Short-circuit out of both shortcodes for shared functionality (confirming admin email, resending the pledge +// confirmation email). +add_filter( 'pre_do_shortcode_tag', __NAMESPACE__ . '\process_confirmed_email', 10, 2 ); +add_filter( 'pre_do_shortcode_tag', __NAMESPACE__ . '\process_resend_confirm_email', 10, 2 ); + /** * Render the form(s) for creating new pledges. * @@ -38,18 +43,6 @@ function render_form_new() { } elseif ( is_int( $pledge_id ) ) { $complete = true; } - } elseif ( 'confirm_pledge_email' === $action ) { - $view = 'form-pledge-confirm-email.php'; - $pledge_id = filter_input( INPUT_GET, 'pledge_id', FILTER_VALIDATE_INT ); - $unverified_token = filter_input( INPUT_GET, 'auth_token', FILTER_SANITIZE_STRING ); - $email_confirmed = process_pledge_confirmation_email( $pledge_id, $action, $unverified_token ); - $pledge = get_post( $pledge_id ); - - } elseif ( filter_input( INPUT_GET, 'resend_pledge_confirmation' ) ) { - $pledge_id = filter_input( INPUT_GET, 'pledge_id', FILTER_VALIDATE_INT ); - $complete = true; - - Email\send_pledge_confirmation_email( $pledge_id, get_post()->ID ); } ob_start(); @@ -106,44 +99,6 @@ function process_form_new() { return $new_pledge_id; } -/** - * Process a request to confirm a company's email address. - * - * @param int $pledge_id - * @param string $action - * @param array $unverified_token - * - * @return bool - */ -function process_pledge_confirmation_email( $pledge_id, $action, $unverified_token ) { - $meta_key = PledgeMeta\META_PREFIX . 'pledge-email-confirmed'; - $already_confirmed = get_post( $pledge_id )->$meta_key; - - if ( $already_confirmed ) { - /* - * If they refresh the page after confirming, they'd otherwise get an error because the token had been - * used, and might be confused and think that the address wasn't confirmed. - * - * This leaks the fact that the address is confirmed, because it will return true even if the token is - * invalid, but there aren't any security/privacy implications of that. - */ - return true; - } - - $email_confirmed = Auth\is_valid_authentication_token( $pledge_id, $action, $unverified_token ); - - if ( $email_confirmed ) { - update_post_meta( $pledge_id, $meta_key, true ); - wp_update_post( array( - 'ID' => $pledge_id, - 'post_status' => 'publish', - ) ); - Email\send_contributor_confirmation_emails( $pledge_id ); - } - - return $email_confirmed; -} - /** * Render the form(s) for managing existing pledges. * @@ -182,6 +137,11 @@ function render_form_manage() { $errors = $results->get_error_messages(); } else { $messages = array( __( 'Your pledge has been updated.', 'wporg-5ftf' ) ); + + $meta_key = PledgeMeta\META_PREFIX . 'pledge-email-confirmed'; + if ( ! get_post( $pledge_id )->$meta_key ) { + $messages[] = __( 'You must confirm your new email address before it will be visible.', 'wporg-5ftf' ); + } } } @@ -189,7 +149,7 @@ function render_form_manage() { $contributors = Contributor\get_pledge_contributors_data( $pledge_id ); ob_start(); - $readonly = false; + $readonly = false; $is_manage = true; require FiveForTheFuture\PATH . 'views/form-pledge-manage.php'; @@ -224,7 +184,7 @@ function process_form_manage( $pledge_id, $auth_token ) { } $submission = get_form_submission(); - $has_error = check_invalid_submission( $submission, 'update' ); + $has_error = check_invalid_submission( $submission, 'update' ); if ( $has_error ) { return $has_error; } @@ -260,6 +220,96 @@ function process_form_manage( $pledge_id, $auth_token ) { return true; } +/** + * Process a request to confirm a company's email address. + * + * @param string|false $value Short-circuit return value. + * @param string $tag Shortcode name. + * + * @return bool|string + */ +function process_confirmed_email( $value, $tag ) { + if ( ! in_array( $tag, [ '5ftf_pledge_form_new', '5ftf_pledge_form_manage' ] ) ) { + return $value; + } + + $action = sanitize_text_field( $_REQUEST['action'] ?? '' ); + if ( 'confirm_pledge_email' !== $action ) { + return $value; + } + + $pledge_id = filter_input( INPUT_GET, 'pledge_id', FILTER_VALIDATE_INT ); + $auth_token = filter_input( INPUT_GET, 'auth_token', FILTER_SANITIZE_STRING ); + + $meta_key = PledgeMeta\META_PREFIX . 'pledge-email-confirmed'; + $already_confirmed = get_post( $pledge_id )->$meta_key; + $email_confirmed = false; + $is_new_pledge = '5ftf_pledge_form_new' === $tag; + + if ( $already_confirmed ) { + /* + * If they refresh the page after confirming, they'd otherwise get an error because the token had been + * used, and might be confused and think that the address wasn't confirmed. + * + * This leaks the fact that the address is confirmed, because it will return true even if the token is + * invalid, but there aren't any security/privacy implications of that. + */ + $email_confirmed = true; + } + + $email_confirmed = Auth\is_valid_authentication_token( $pledge_id, $action, $auth_token ); + + if ( $email_confirmed ) { + update_post_meta( $pledge_id, $meta_key, true ); + wp_update_post( array( + 'ID' => $pledge_id, + 'post_status' => 'publish', + ) ); + if ( $is_new_pledge ) { + Email\send_contributor_confirmation_emails( $pledge_id ); + } + } + + ob_start(); + $directory_url = home_url( 'pledges' ); + $pledge = get_post( $pledge_id ); + require FiveForTheFuture\get_views_path() . 'form-pledge-confirm-email.php'; + return ob_get_clean(); +} + +/** + * Process a request to resed a company's confirmation email. + * + * @param string|false $value Short-circuit return value. + * @param string $tag Shortcode name. + * + * @return bool|string + */ +function process_resend_confirm_email( $value, $tag ) { + if ( ! in_array( $tag, [ '5ftf_pledge_form_new', '5ftf_pledge_form_manage' ] ) ) { + return $value; + } + + $action = sanitize_text_field( $_REQUEST['action'] ?? '' ); + if ( 'resend_pledge_confirmation' !== $action ) { + return $value; + } + + $pledge_id = filter_input( INPUT_GET, 'pledge_id', FILTER_VALIDATE_INT ); + Email\send_pledge_confirmation_email( $pledge_id, get_post()->ID ); + + $messages = array( + sprintf( + __( 'We’ve emailed you a new link to confirm your address for %s.', 'wporg-5ftf' ), + get_the_title( $pledge_id ) + ), + ); + + ob_start(); + require FiveForTheFuture\get_views_path() . 'partial-result-messages.php'; + return ob_get_clean(); +} + /** * Get and sanitize $_POST values from a form submission. * @@ -278,7 +328,7 @@ function get_form_submission() { $result = filter_input_array( INPUT_POST, $input_filters ); if ( ! $result ) { - $result = array_fill_keys( array_keys( $input_filters ), '' ); + $result = array_fill_keys( array_keys( $input_filters ), '' ); $result['empty_post'] = true; } diff --git a/plugins/wporg-5ftf/includes/pledge-meta.php b/plugins/wporg-5ftf/includes/pledge-meta.php index 5239418..1ed2df8 100755 --- a/plugins/wporg-5ftf/includes/pledge-meta.php +++ b/plugins/wporg-5ftf/includes/pledge-meta.php @@ -280,10 +280,11 @@ function save_pledge( $pledge_id, $pledge ) { save_pledge_meta( $pledge_id, $submitted_meta ); + // Fired if the "Resend Confirmation" button was clicked in wp-admin. if ( filter_input( INPUT_POST, 'resend-pledge-confirmation' ) ) { Email\send_pledge_confirmation_email( filter_input( INPUT_GET, 'resend-pledge-id', FILTER_VALIDATE_INT ), - get_page_by_path( 'for-organizations' )->ID + get_page_by_path( 'manage-pledge' )->ID ); } } @@ -350,8 +351,15 @@ function update_generated_meta( $meta_id, $object_id, $meta_key, $_meta_value ) update_post_meta( $object_id, META_PREFIX . 'org-domain', $domain ); break; - case META_PREFIX . 'pledge-email': + case META_PREFIX . 'org-pledge-email': + $landing_page = get_page_by_path( 'manage-pledge' )->ID; + Email\send_pledge_confirmation_email( $object_id, $landing_page ); delete_post_meta( $object_id, META_PREFIX . 'pledge-email-confirmed' ); + // Flip pledge back to pending. + wp_update_post( array( + 'ID' => $object_id, + 'post_status' => 'pending', + ) ); break; } } diff --git a/plugins/wporg-5ftf/views/form-pledge-confirm-email.php b/plugins/wporg-5ftf/views/form-pledge-confirm-email.php index 8010a3f..5ec9d65 100755 --- a/plugins/wporg-5ftf/views/form-pledge-confirm-email.php +++ b/plugins/wporg-5ftf/views/form-pledge-confirm-email.php @@ -4,8 +4,9 @@ namespace WordPressDotOrg\FiveForTheFuture\View; use WP_Post; /** - * @var bool $email_confirmed * @var string $directory_url + * @var bool $email_confirmed + * @var bool $is_new_pledge * @var int $pledge_id * @var WP_Post|null $pledge */ @@ -16,10 +17,17 @@ use WP_Post;

the directory once one contributor confirms their participation.', 'wporg-5ftf' ) ), - esc_url( $directory_url ) - ); + if ( $is_new_pledge ) { + printf( + wp_kses_post( __( 'Thank you for confirming your address! We’ve emailed confirmation links to the contributors you mentioned, and your pledge will show up in the directory once one contributor confirms their participation.', 'wporg-5ftf' ) ), + esc_url( $directory_url ) + ); + } else { + printf( + wp_kses_post( __( 'Thank you for confirming your address! If you have confirmed contributors, your pledge is visible in the directory again. Otherwise, your pledge wiill show up once one contributor confirms their participation.', 'wporg-5ftf' ) ), + esc_url( $directory_url ) + ); + } ?>

@@ -54,11 +62,11 @@ use WP_Post;
+

diff --git a/plugins/wporg-5ftf/views/form-pledge-manage.php b/plugins/wporg-5ftf/views/form-pledge-manage.php index d2424e4..bc74004 100644 --- a/plugins/wporg-5ftf/views/form-pledge-manage.php +++ b/plugins/wporg-5ftf/views/form-pledge-manage.php @@ -23,6 +23,7 @@ require __DIR__ . '/partial-result-messages.php'; wp_nonce_field( 'manage_pledge_' . $pledge_id ); require get_views_path() . 'inputs-pledge-org-info.php'; + require get_views_path() . 'inputs-pledge-org-email.php'; ?>
diff --git a/plugins/wporg-5ftf/views/inputs-pledge-org-email.php b/plugins/wporg-5ftf/views/inputs-pledge-org-email.php index 3105521..4ed4624 100644 --- a/plugins/wporg-5ftf/views/inputs-pledge-org-email.php +++ b/plugins/wporg-5ftf/views/inputs-pledge-org-email.php @@ -25,9 +25,16 @@ use WP_Post; aria-describedby="5ftf-pledge-email-help" /> -

- -

+
+

+ +

+ +

+ +

+ +
diff --git a/themes/wporg-5ftf/css/objects/_pledge-form.scss b/themes/wporg-5ftf/css/objects/_pledge-form.scss index 9c08187..7b9abe0 100644 --- a/themes/wporg-5ftf/css/objects/_pledge-form.scss +++ b/themes/wporg-5ftf/css/objects/_pledge-form.scss @@ -29,7 +29,7 @@ height: auto; } - > p { + [id*="help"] p { margin-top: ms(-5); font-size: ms(-2); }