From 544fe391995b8a1f942a012b9a4c593d823ef92e Mon Sep 17 00:00:00 2001 From: Kelly Dwan Date: Tue, 26 Nov 2019 12:57:14 -0500 Subject: [PATCH] Manage Pledge: Enable pledge admins to edit contributors from manage form (#108) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add contributor management to manage form * Check `pledge_id` to prevent returning all contributors * Return a plain text error string – this is used in an alert box, so it can't contain HTML * Hide confirmation when pledge is a draft * Only enqueue script if the user is authorized --- plugins/wporg-5ftf/assets/js/admin.js | 13 +++- plugins/wporg-5ftf/includes/contributor.php | 3 + plugins/wporg-5ftf/includes/endpoints.php | 5 +- plugins/wporg-5ftf/includes/pledge-form.php | 7 +-- plugins/wporg-5ftf/includes/pledge-meta.php | 31 ++++++++-- .../wporg-5ftf/views/form-pledge-manage.php | 5 ++ .../wporg-5ftf/views/manage-contributors.php | 5 +- .../wporg-5ftf/css/objects/_pledge-form.scss | 59 ++++++++++++++++++- 8 files changed, 110 insertions(+), 18 deletions(-) diff --git a/plugins/wporg-5ftf/assets/js/admin.js b/plugins/wporg-5ftf/assets/js/admin.js index 4d83add..f4822dd 100644 --- a/plugins/wporg-5ftf/assets/js/admin.js +++ b/plugins/wporg-5ftf/assets/js/admin.js @@ -1,6 +1,12 @@ /* global ajaxurl, FiveForTheFuture, fftfContributors, jQuery */ /* eslint no-alert: "off" */ jQuery( document ).ready( function( $ ) { + let ajaxurl = window.ajaxurl; + // Set the ajax url if the global is undefined. + if ( 'undefined' === typeof ajaxurl ) { + ajaxurl = FiveForTheFuture.ajaxurl; + } + /** * Render the contributor lists using the contributors template into the pledge-contributors container. This * uses `_renderContributors` to render a list of contributors per status (published, pending). @@ -68,6 +74,7 @@ jQuery( document ).ready( function( $ ) { action: 'manage-contributors', pledge_id: FiveForTheFuture.pledgeId, _ajax_nonce: FiveForTheFuture.manageNonce, + _token: FiveForTheFuture.authToken, }, data ), success: callback, dataType: 'json', @@ -83,17 +90,19 @@ jQuery( document ).ready( function( $ ) { return; } + // Clear the error message field. + $( '#add-contrib-message' ).html( '' ); + sendAjaxRequest( { contributors: contribs, manage_action: 'add-contributor', }, function( response ) { if ( ! response.success ) { const $message = $( '
' ) - .attr( 'id', 'add-contrib-message' ) .addClass( 'notice notice-error notice-alt' ) .append( $( '

' ).text( response.message ) ); - $( '#add-contrib-message' ).replaceWith( $message ); + $( '#add-contrib-message' ).html( $message ); } else if ( response.contributors ) { render( response.contributors, container ); $( '#5ftf-pledge-contributors' ).val( '' ); diff --git a/plugins/wporg-5ftf/includes/contributor.php b/plugins/wporg-5ftf/includes/contributor.php index 8bc5177..83d1647 100644 --- a/plugins/wporg-5ftf/includes/contributor.php +++ b/plugins/wporg-5ftf/includes/contributor.php @@ -248,6 +248,9 @@ function get_pledge_contributors( $pledge_id, $status = 'publish', $contributor_ * @return array An array of contributor data, ready to be used in the JS templates. */ function get_pledge_contributors_data( $pledge_id ) { + if ( ! $pledge_id ) { + return array(); + } $contrib_data = array(); $contributors = get_pledge_contributors( $pledge_id, 'all' ); diff --git a/plugins/wporg-5ftf/includes/endpoints.php b/plugins/wporg-5ftf/includes/endpoints.php index ffe9c85..340d87e 100644 --- a/plugins/wporg-5ftf/includes/endpoints.php +++ b/plugins/wporg-5ftf/includes/endpoints.php @@ -8,7 +8,8 @@ namespace WordPressDotOrg\FiveForTheFuture\Endpoints; use WordPressDotOrg\FiveForTheFuture\{ Auth, Contributor, Email }; use const WordPressDotOrg\FiveForTheFuture\PledgeMeta\META_PREFIX; -add_action( 'wp_ajax_manage-contributors', __NAMESPACE__ . '\manage_contributors_handler' ); +add_action( 'wp_ajax_manage-contributors', __NAMESPACE__ . '\manage_contributors_handler' ); +add_action( 'wp_ajax_nopriv_manage-contributors', __NAMESPACE__ . '\manage_contributors_handler' ); add_action( 'wp_ajax_send-manage-email', __NAMESPACE__ . '\send_manage_email_handler' ); add_action( 'wp_ajax_nopriv_send-manage-email', __NAMESPACE__ . '\send_manage_email_handler' ); @@ -29,7 +30,7 @@ function manage_contributors_handler() { if ( is_wp_error( $authenticated ) ) { wp_die( wp_json_encode( [ 'success' => false, - 'message' => $authenticated->get_error_message(), + 'message' => __( 'Sorry, you don\'t have permissions to do that.', 'wporg-5ftf' ), ] ) ); } diff --git a/plugins/wporg-5ftf/includes/pledge-form.php b/plugins/wporg-5ftf/includes/pledge-form.php index e2fdf57..86755d6 100755 --- a/plugins/wporg-5ftf/includes/pledge-form.php +++ b/plugins/wporg-5ftf/includes/pledge-form.php @@ -175,8 +175,6 @@ function render_form_manage() { return ob_get_clean(); } - $contributors = Contributor\get_pledge_contributors( $pledge_id, $status = 'all' ); - if ( 'Update Pledge' === $action ) { $results = process_form_manage( $pledge_id, $auth_token ); @@ -187,7 +185,8 @@ function render_form_manage() { } } - $data = PledgeMeta\get_pledge_meta( $pledge_id ); + $data = PledgeMeta\get_pledge_meta( $pledge_id ); + $contributors = Contributor\get_pledge_contributors_data( $pledge_id ); ob_start(); $readonly = false; @@ -214,7 +213,7 @@ function process_form_manage( $pledge_id, $auth_token ) { */ $can_view_form = Auth\can_manage_pledge( $pledge_id, $auth_token ); - if ( ! $has_valid_nonce || ! $can_view_form ) { + if ( ! $has_valid_nonce || is_wp_error( $can_view_form ) ) { return new WP_Error( 'invalid_token', sprintf( diff --git a/plugins/wporg-5ftf/includes/pledge-meta.php b/plugins/wporg-5ftf/includes/pledge-meta.php index 1a7c07f..5239418 100755 --- a/plugins/wporg-5ftf/includes/pledge-meta.php +++ b/plugins/wporg-5ftf/includes/pledge-meta.php @@ -6,7 +6,7 @@ namespace WordPressDotOrg\FiveForTheFuture\PledgeMeta; use WordPressDotOrg\FiveForTheFuture; -use WordPressDotOrg\FiveForTheFuture\{ Contributor, Email, Pledge, PledgeForm, XProfile }; +use WordPressDotOrg\FiveForTheFuture\{ Auth, Contributor, Email, Pledge, PledgeForm, XProfile }; use WP_Post, WP_Error; defined( 'WPINC' ) || die(); @@ -18,6 +18,7 @@ add_action( 'init', __NAMESPACE__ . '\schedule_cron_jobs' ); add_action( 'admin_init', __NAMESPACE__ . '\add_meta_boxes' ); add_action( 'save_post', __NAMESPACE__ . '\save_pledge', 10, 2 ); add_action( 'admin_enqueue_scripts', __NAMESPACE__ . '\enqueue_assets' ); +add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\enqueue_assets' ); add_action( 'transition_post_status', __NAMESPACE__ . '\maybe_update_single_cached_pledge_data', 10, 3 ); add_action( 'update_all_cached_pledge_data', __NAMESPACE__. '\update_all_cached_pledge_data' ); @@ -207,6 +208,7 @@ function add_meta_boxes() { function render_meta_boxes( $pledge, $box ) { $readonly = ! current_user_can( 'edit_page', $pledge->ID ); $is_manage = true; + $pledge_id = $pledge->ID; $data = array(); foreach ( get_pledge_meta_config() as $key => $config ) { @@ -502,9 +504,14 @@ function enqueue_assets() { $ver = filemtime( FiveForTheFuture\PATH . '/assets/js/admin.js' ); wp_register_script( '5ftf-admin', plugins_url( 'assets/js/admin.js', __DIR__ ), [ 'jquery', 'wp-util' ], $ver ); + $pledge_id = is_admin() ? get_the_ID() : absint( $_REQUEST['pledge_id'] ?? 0 ); + $auth_token = sanitize_text_field( $_REQUEST['auth_token'] ?? '' ); $script_data = [ - 'pledgeId' => get_the_ID(), + // The global ajaxurl is not set on the frontend. + 'ajaxurl' => admin_url( 'admin-ajax.php', 'relative' ), + 'pledgeId' => $pledge_id, 'manageNonce' => wp_create_nonce( 'manage-contributors' ), + 'authToken' => $auth_token, ]; wp_add_inline_script( '5ftf-admin', @@ -515,9 +522,21 @@ function enqueue_assets() { 'before' ); - $current_page = get_current_screen(); - if ( Pledge\CPT_ID === $current_page->id ) { - wp_enqueue_style( '5ftf-admin' ); - wp_enqueue_script( '5ftf-admin' ); + if ( is_admin() ) { + $current_page = get_current_screen(); + if ( Pledge\CPT_ID === $current_page->id ) { + wp_enqueue_style( '5ftf-admin' ); + wp_enqueue_script( '5ftf-admin' ); + } + } else { + global $post; + if ( is_a( $post, 'WP_Post' ) ) { + $pledge_id = absint( $_REQUEST['pledge_id'] ?? 0 ); + $auth_token = sanitize_text_field( $_REQUEST['auth_token'] ?? '' ); + $can_manage = Auth\can_manage_pledge( $pledge_id, $auth_token ); + if ( ! is_wp_error( $can_manage ) && has_shortcode( $post->post_content, '5ftf_pledge_form_manage' ) ) { + wp_enqueue_script( '5ftf-admin' ); + } + } } } diff --git a/plugins/wporg-5ftf/views/form-pledge-manage.php b/plugins/wporg-5ftf/views/form-pledge-manage.php index d620b3f..d2424e4 100644 --- a/plugins/wporg-5ftf/views/form-pledge-manage.php +++ b/plugins/wporg-5ftf/views/form-pledge-manage.php @@ -33,6 +33,11 @@ require __DIR__ . '/partial-result-messages.php'; value="" />

+ +

+ + + diff --git a/plugins/wporg-5ftf/views/manage-contributors.php b/plugins/wporg-5ftf/views/manage-contributors.php index 96f6e3a..fd697d7 100644 --- a/plugins/wporg-5ftf/views/manage-contributors.php +++ b/plugins/wporg-5ftf/views/manage-contributors.php @@ -4,8 +4,7 @@ namespace WordPressDotOrg\FiveForTheFuture\View; use function WordPressDotOrg\FiveForTheFuture\get_views_path; /** @var array $contributors */ -/** @var array $data */ -/** @var bool $readonly */ +/** @var int $pledge_id */ ?>
-
+
* { + border-top-color: $color-gray-light-700; + + &:first-child { + border-left-color: $color-gray-light-700; + } + + &:last-child { + border-right-color: $color-gray-light-700; + } + } + + tr:last-child > * { + border-bottom-color: $color-gray-light-700; + } + + .avatar { + margin-right: 8px; + } + + .button-link-delete { + text-decoration: none; + + .dashicons { + margin-top: -2px; + } + } + } + + .pledge-contributors.pledge-status__draft .resend-confirm { + display: none; + } }