mirror of
https://github.com/WordPress/five-for-the-future.git
synced 2025-04-21 10:33:44 +03:00
Pledge Management: Allow pledge admins to remove the pledge (#123)
* Rename generic "frontend" file to dialog * Add a "remove pledge" action * Process pledge deactivation * Trigger an email on user-initiated pledge deactivation * Show an error when trying to manage a deactivated pledge * Add a label for "deactivated" pledges
This commit is contained in:
parent
619af97bd1
commit
bdbf6d573e
|
@ -1,4 +1,4 @@
|
||||||
/* global ajaxurl, FiveForTheFuture, fftfContributors, jQuery */
|
/* global FiveForTheFuture, fftfContributors, jQuery */
|
||||||
/* eslint no-alert: "off" */
|
/* eslint no-alert: "off" */
|
||||||
jQuery( document ).ready( function( $ ) {
|
jQuery( document ).ready( function( $ ) {
|
||||||
let ajaxurl = window.ajaxurl;
|
let ajaxurl = window.ajaxurl;
|
||||||
|
@ -153,4 +153,10 @@ jQuery( document ).ready( function( $ ) {
|
||||||
_addContributors();
|
_addContributors();
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
$( '#5ftf-pledge-remove' ).on( 'click', function( event ) {
|
||||||
|
if ( ! confirm( FiveForTheFuture.removePrompt ) ) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global FiveForTheFuture, jQuery */
|
/* global FFTF_Dialog, jQuery */
|
||||||
jQuery( document ).ready( function( $ ) {
|
jQuery( document ).ready( function( $ ) {
|
||||||
const button = document.getElementById( 'toggle-management-link-form' );
|
const button = document.getElementById( 'toggle-management-link-form' );
|
||||||
const template = wp.template( '5ftf-send-link-dialog' );
|
const template = wp.template( '5ftf-send-link-dialog' );
|
||||||
|
@ -84,12 +84,12 @@ jQuery( document ).ready( function( $ ) {
|
||||||
$( event.target.querySelector( '.message' ) ).html( '' );
|
$( event.target.querySelector( '.message' ) ).html( '' );
|
||||||
$.ajax( {
|
$.ajax( {
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: FiveForTheFuture.ajaxurl,
|
url: FFTF_Dialog.ajaxurl,
|
||||||
data: {
|
data: {
|
||||||
action: 'send-manage-email',
|
action: 'send-manage-email',
|
||||||
pledge_id: FiveForTheFuture.pledgeId,
|
pledge_id: FFTF_Dialog.pledgeId,
|
||||||
email,
|
email,
|
||||||
_ajax_nonce: FiveForTheFuture.ajaxNonce,
|
_ajax_nonce: FFTF_Dialog.ajaxNonce,
|
||||||
},
|
},
|
||||||
success( response ) {
|
success( response ) {
|
||||||
if ( response.message ) {
|
if ( response.message ) {
|
|
@ -154,3 +154,25 @@ function send_manage_pledge_link( $pledge_id ) {
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Email pledge manager to notify that the pledge has been removed.
|
||||||
|
*
|
||||||
|
* @param WP_Post $pledge The pledge object, used to add the title now that the pledge itself has been deleted.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
function send_pledge_deactivation_email( $pledge ) {
|
||||||
|
$message = sprintf(
|
||||||
|
"Your organization, %s, has been removed from the Five for the Future listing.\n\n" .
|
||||||
|
'Please reply to this email if this was a mistake.',
|
||||||
|
$pledge->post_title
|
||||||
|
);
|
||||||
|
|
||||||
|
return send_email(
|
||||||
|
$pledge->{'5ftf_org-pledge-email'},
|
||||||
|
'Pledge removed from Five for the Future',
|
||||||
|
$message,
|
||||||
|
$pledge->ID
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -123,15 +123,40 @@ function render_form_manage() {
|
||||||
$can_view_form = Auth\can_manage_pledge( $pledge_id, $auth_token );
|
$can_view_form = Auth\can_manage_pledge( $pledge_id, $auth_token );
|
||||||
|
|
||||||
if ( is_wp_error( $can_view_form ) ) {
|
if ( is_wp_error( $can_view_form ) ) {
|
||||||
// Can't manage pledge, only show errors.
|
|
||||||
$errors = array( $can_view_form->get_error_message() );
|
$errors = array( $can_view_form->get_error_message() );
|
||||||
|
} else if ( ! in_array( get_post_status( $pledge_id ), array( 'pending', 'publish' ), true ) ) {
|
||||||
|
$errors = array(
|
||||||
|
sprintf(
|
||||||
|
__( 'This pledge has been removed from Five for the Future. If this was a mistake, please <a href="%s">contact us</a> to reactivate your pledge.', 'wporg-5ftf' ),
|
||||||
|
get_permalink( get_page_by_path( 'report' ) )
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( count( $errors ) > 0 ) {
|
||||||
ob_start();
|
ob_start();
|
||||||
require FiveForTheFuture\PATH . 'views/partial-result-messages.php';
|
require FiveForTheFuture\PATH . 'views/partial-result-messages.php';
|
||||||
return ob_get_clean();
|
return ob_get_clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( 'Update Pledge' === $action ) {
|
if ( 'remove-pledge' === $action ) {
|
||||||
|
$results = process_form_remove( $pledge_id, $auth_token );
|
||||||
|
|
||||||
|
if ( is_wp_error( $results ) ) {
|
||||||
|
$errors = $results->get_error_messages();
|
||||||
|
} else {
|
||||||
|
$messages = array(
|
||||||
|
sprintf(
|
||||||
|
__( 'Your pledge has been removed. If this was a mistake, please <a href="%s">contact us</a> to reactivate your pledge.', 'wporg-5ftf' ),
|
||||||
|
get_permalink( get_page_by_path( 'report' ) )
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
require FiveForTheFuture\PATH . 'views/partial-result-messages.php';
|
||||||
|
return ob_get_clean();
|
||||||
|
} else if ( 'Update Pledge' === $action ) {
|
||||||
$results = process_form_manage( $pledge_id, $auth_token );
|
$results = process_form_manage( $pledge_id, $auth_token );
|
||||||
|
|
||||||
if ( is_wp_error( $results ) ) {
|
if ( is_wp_error( $results ) ) {
|
||||||
|
@ -215,12 +240,42 @@ function process_form_manage( $pledge_id, $auth_token ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @todo Save contributors.
|
|
||||||
|
|
||||||
// If we made it to here, we've successfully saved the pledge.
|
// If we made it to here, we've successfully saved the pledge.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a submission from the Manage Pledge form.
|
||||||
|
*
|
||||||
|
* @return WP_Error|true An error if the pledge could not be saved. Otherwise true.
|
||||||
|
*/
|
||||||
|
function process_form_remove( $pledge_id, $auth_token ) {
|
||||||
|
$errors = array();
|
||||||
|
$nonce = filter_input( INPUT_POST, '_wpnonce', FILTER_SANITIZE_STRING );
|
||||||
|
$nonce_action = 'remove_pledge_' . $pledge_id;
|
||||||
|
$has_valid_nonce = wp_verify_nonce( $nonce, $nonce_action );
|
||||||
|
$can_view_form = Auth\can_manage_pledge( $pledge_id, $auth_token );
|
||||||
|
|
||||||
|
if ( ! $has_valid_nonce || is_wp_error( $can_view_form ) ) {
|
||||||
|
return new WP_Error(
|
||||||
|
'invalid_token',
|
||||||
|
sprintf(
|
||||||
|
__( 'Your link has expired, please <a href="%s">obtain a new one</a>.', 'wporg-5ftf' ),
|
||||||
|
get_permalink( $pledge_id )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = Pledge\deactivate( $pledge_id, true );
|
||||||
|
|
||||||
|
if ( is_wp_error( $result ) ) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we made it to here, we've successfully removed the pledge.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a request to confirm a company's email address.
|
* Process a request to confirm a company's email address.
|
||||||
*
|
*
|
||||||
|
|
|
@ -549,13 +549,14 @@ function enqueue_assets() {
|
||||||
|
|
||||||
$pledge_id = is_admin() ? get_the_ID() : absint( $_REQUEST['pledge_id'] ?? 0 );
|
$pledge_id = is_admin() ? get_the_ID() : absint( $_REQUEST['pledge_id'] ?? 0 );
|
||||||
$auth_token = sanitize_text_field( $_REQUEST['auth_token'] ?? '' );
|
$auth_token = sanitize_text_field( $_REQUEST['auth_token'] ?? '' );
|
||||||
$script_data = [
|
$script_data = array(
|
||||||
// The global ajaxurl is not set on the frontend.
|
// The global ajaxurl is not set on the frontend.
|
||||||
'ajaxurl' => admin_url( 'admin-ajax.php', 'relative' ),
|
'ajaxurl' => admin_url( 'admin-ajax.php', 'relative' ),
|
||||||
'pledgeId' => $pledge_id,
|
'pledgeId' => $pledge_id,
|
||||||
'manageNonce' => wp_create_nonce( 'manage-contributors' ),
|
'manageNonce' => wp_create_nonce( 'manage-contributors' ),
|
||||||
'authToken' => $auth_token,
|
'authToken' => $auth_token,
|
||||||
];
|
'removePrompt' => __( 'Are you sure you want to remove this pledge?', 'wporg-5ftf' ),
|
||||||
|
);
|
||||||
wp_add_inline_script(
|
wp_add_inline_script(
|
||||||
'5ftf-admin',
|
'5ftf-admin',
|
||||||
sprintf(
|
sprintf(
|
||||||
|
|
|
@ -205,10 +205,7 @@ function handle_activation_action( $post_id ) {
|
||||||
$sendback = remove_query_arg( [ 'deactivated', 'reactivated' ], $sendback );
|
$sendback = remove_query_arg( [ 'deactivated', 'reactivated' ], $sendback );
|
||||||
|
|
||||||
if ( 'deactivate' === $action ) {
|
if ( 'deactivate' === $action ) {
|
||||||
wp_update_post( array(
|
deactivate( $post_id );
|
||||||
'ID' => $post_id,
|
|
||||||
'post_status' => DEACTIVE_STATUS,
|
|
||||||
) );
|
|
||||||
wp_redirect( add_query_arg( 'deactivated', 1, $sendback ) );
|
wp_redirect( add_query_arg( 'deactivated', 1, $sendback ) );
|
||||||
exit();
|
exit();
|
||||||
} else {
|
} else {
|
||||||
|
@ -355,6 +352,31 @@ function create_new_pledge( $name ) {
|
||||||
return $pledge_id;
|
return $pledge_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a pledge from view by setting its status to "deactivated".
|
||||||
|
*
|
||||||
|
* @param int $pledge_id The pledge to deactivate.
|
||||||
|
* @param bool $notify Whether the pledge admin should be notified of the deactivation.
|
||||||
|
*
|
||||||
|
* @return int|WP_Error Post ID on success. Otherwise WP_Error.
|
||||||
|
*/
|
||||||
|
function deactivate( $pledge_id, $notify = false ) {
|
||||||
|
$pledge = get_post( $pledge_id );
|
||||||
|
$result = wp_update_post(
|
||||||
|
array(
|
||||||
|
'ID' => $pledge_id,
|
||||||
|
'post_status' => DEACTIVE_STATUS,
|
||||||
|
),
|
||||||
|
true // Return a WP_Error.
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( $notify && ! is_wp_error( $result ) ) {
|
||||||
|
Email\send_pledge_deactivation_email( $pledge );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter query for archive & search pages to ensure we're only showing the expected data.
|
* Filter query for archive & search pages to ensure we're only showing the expected data.
|
||||||
*
|
*
|
||||||
|
@ -462,21 +484,26 @@ function has_existing_pledge( $key, $key_type, int $current_pledge_id = 0 ) {
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
function enqueue_assets() {
|
function enqueue_assets() {
|
||||||
wp_register_script( 'wicg-inert', plugins_url( 'assets/js/inert.min.js', __DIR__ ), [], '3.0.0', true );
|
wp_register_script( 'wicg-inert', plugins_url( 'assets/js/inert.min.js', __DIR__ ), array(), '3.0.0', true );
|
||||||
|
|
||||||
if ( CPT_ID === get_post_type() ) {
|
if ( CPT_ID === get_post_type() ) {
|
||||||
$ver = filemtime( FiveForTheFuture\PATH . '/assets/js/frontend.js' );
|
wp_enqueue_script(
|
||||||
wp_enqueue_script( '5ftf-frontend', plugins_url( 'assets/js/frontend.js', __DIR__ ), [ 'jquery', 'wp-a11y', 'wp-util', 'wicg-inert' ], $ver, true );
|
'5ftf-dialog',
|
||||||
|
plugins_url( 'assets/js/dialog.js', __DIR__ ),
|
||||||
|
array( 'jquery', 'wp-a11y', 'wp-util', 'wicg-inert' ),
|
||||||
|
filemtime( FiveForTheFuture\PATH . '/assets/js/dialog.js' ),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
$script_data = [
|
$script_data = array(
|
||||||
'ajaxurl' => admin_url( 'admin-ajax.php', 'relative' ), // The global ajaxurl is not set on the frontend.
|
'ajaxurl' => admin_url( 'admin-ajax.php', 'relative' ), // The global ajaxurl is not set on the frontend.
|
||||||
'pledgeId' => get_the_ID(),
|
'pledgeId' => get_the_ID(),
|
||||||
'ajaxNonce' => wp_create_nonce( 'send-manage-email' ),
|
'ajaxNonce' => wp_create_nonce( 'send-manage-email' ),
|
||||||
];
|
);
|
||||||
wp_add_inline_script(
|
wp_add_inline_script(
|
||||||
'5ftf-frontend',
|
'5ftf-dialog',
|
||||||
sprintf(
|
sprintf(
|
||||||
'var FiveForTheFuture = JSON.parse( decodeURIComponent( \'%s\' ) );',
|
'var FFTF_Dialog = JSON.parse( decodeURIComponent( \'%s\' ) );',
|
||||||
rawurlencode( wp_json_encode( $script_data ) )
|
rawurlencode( wp_json_encode( $script_data ) )
|
||||||
),
|
),
|
||||||
'before'
|
'before'
|
||||||
|
|
|
@ -42,4 +42,6 @@ require __DIR__ . '/partial-result-messages.php';
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<?php require get_views_path() . 'form-pledge-remove.php'; ?>
|
||||||
|
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
31
plugins/wporg-5ftf/views/form-pledge-remove.php
Normal file
31
plugins/wporg-5ftf/views/form-pledge-remove.php
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace WordPressDotOrg\FiveForTheFuture\View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool $can_view_form
|
||||||
|
* @var int $pledge_id
|
||||||
|
* @var string $auth_token
|
||||||
|
*/
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<form class="pledge-form" id="5ftf-form-pledge-remove" action="" method="post">
|
||||||
|
<h2><?php esc_html_e( 'Remove Pledge', 'wporg-5ftf' ); ?></h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<?php esc_html_e( 'This will remove your pledge from the Five for the Future listing. You will not be able to reactivate it or submit a new pledge for this company.', 'wporg-5ftf' ); ?>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<?php wp_nonce_field( 'remove_pledge_' . $pledge_id ); ?>
|
||||||
|
<input type="hidden" name="action" value="remove-pledge" />
|
||||||
|
<input type="hidden" name="auth_token" value="<?php echo esc_attr( $auth_token ); ?>" />
|
||||||
|
<input type="hidden" name="pledge_id" value="<?php echo absint( $pledge_id ); ?>" />
|
||||||
|
<button type="submit" class="button button-danger" id="5ftf-pledge-remove">
|
||||||
|
<?php esc_html_e( 'Remove Pledge', 'wporg-5ftf' ); ?>
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
</form>
|
|
@ -31,6 +31,15 @@ body.single.single-5ftf_pledge {
|
||||||
margin-top: ms(2);
|
margin-top: ms(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pledge-status {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 4px 12px;
|
||||||
|
font-size: ms(-1);
|
||||||
|
text-transform: uppercase;
|
||||||
|
background-color: $color-error-red;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.entry-title {
|
.entry-title {
|
||||||
|
|
|
@ -29,7 +29,8 @@
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
[id*="help"] p {
|
[id*="help"] p,
|
||||||
|
p[id*="help"] {
|
||||||
margin-top: ms(-5);
|
margin-top: ms(-5);
|
||||||
font-size: ms(-2);
|
font-size: ms(-2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ use WordPressDotOrg\FiveForTheFuture\XProfile;
|
||||||
use WP_Post;
|
use WP_Post;
|
||||||
|
|
||||||
use const WordPressDotOrg\FiveForTheFuture\PledgeMeta\META_PREFIX;
|
use const WordPressDotOrg\FiveForTheFuture\PledgeMeta\META_PREFIX;
|
||||||
|
use const WordPressDotOrg\FiveForTheFuture\Pledge\DEACTIVE_STATUS;
|
||||||
|
|
||||||
$contribution_data = XProfile\get_aggregate_contributor_data_for_pledge( get_the_ID() );
|
$contribution_data = XProfile\get_aggregate_contributor_data_for_pledge( get_the_ID() );
|
||||||
|
|
||||||
|
@ -30,6 +31,9 @@ get_header();
|
||||||
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
|
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
|
||||||
<header class="entry-header">
|
<header class="entry-header">
|
||||||
<div>
|
<div>
|
||||||
|
<?php if ( DEACTIVE_STATUS === get_post_status() ) : ?>
|
||||||
|
<span class="pledge-status"><?php esc_html_e( 'deactivated', 'wporg-5ftf' ); ?></span>
|
||||||
|
<?php endif; ?>
|
||||||
<?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
|
<?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
|
||||||
<span class="pledge-url">
|
<span class="pledge-url">
|
||||||
<?php
|
<?php
|
||||||
|
|
Loading…
Reference in a new issue