mirror of
https://github.com/WordPress/five-for-the-future.git
synced 2025-04-16 16:43:42 +03:00
Manage Pledge: Enable Manage Form functionality
* Fix issue with fetching data in `get_pledge_meta` when no submission has been POST'd * Rename to `subset`, since `context` is also used elsewhere * Show form content when there are form errors * Fix warnings on new pledge form * Skip wpautop before save, so editors don’t need to edit HTML unless they want to
This commit is contained in:
parent
b898dc23f3
commit
60b5ca5d2a
|
@ -22,6 +22,7 @@ add_shortcode( '5ftf_pledge_form_manage', __NAMESPACE__ . '\render_form_manage'
|
|||
*/
|
||||
function render_form_new() {
|
||||
$action = isset( $_GET['action'] ) ? filter_input( INPUT_GET, 'action' ) : filter_input( INPUT_POST, 'action' );
|
||||
$pledge_id = 0;
|
||||
$data = get_form_submission();
|
||||
$errors = [];
|
||||
$pledge = null;
|
||||
|
@ -65,7 +66,7 @@ function render_form_new() {
|
|||
*/
|
||||
function process_form_new() {
|
||||
$submission = get_form_submission();
|
||||
$has_error = check_invalid_submission( $submission );
|
||||
$has_error = check_invalid_submission( $submission, 'create' );
|
||||
if ( $has_error ) {
|
||||
return $has_error;
|
||||
}
|
||||
|
@ -149,56 +150,99 @@ function process_pledge_confirmation_email( $pledge_id, $action, $unverified_tok
|
|||
* @return false|string
|
||||
*/
|
||||
function render_form_manage() {
|
||||
$action = filter_input( INPUT_POST, 'action' );
|
||||
$messages = [];
|
||||
$updated = false;
|
||||
/*
|
||||
* Prevent Gutenberg from executing this on the Edit Post screen.
|
||||
* See https://github.com/WordPress/gutenberg/issues/18394
|
||||
*/
|
||||
if ( is_admin() ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// @todo Get pledge ID from somewhere.
|
||||
$data = PledgeMeta\get_pledge_meta();
|
||||
$is_manage = true;
|
||||
$messages = [];
|
||||
$errors = [];
|
||||
|
||||
$action = sanitize_text_field( $_REQUEST['action'] ?? '' );
|
||||
$pledge_id = absint( $_REQUEST['pledge_id'] ?? 0 );
|
||||
$auth_token = sanitize_text_field( $_REQUEST['auth_token'] ?? '' );
|
||||
$can_view_form = Auth\can_manage_pledge( $pledge_id, $auth_token );
|
||||
|
||||
if ( is_wp_error( $can_view_form ) ) {
|
||||
// Can't manage pledge, only show errors.
|
||||
$errors = array( $can_view_form->get_error_message() );
|
||||
|
||||
ob_start();
|
||||
require FiveForTheFuture\PATH . 'views/partial-result-messages.php';
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
$contributors = Contributor\get_pledge_contributors( $pledge_id, $status = 'all' );
|
||||
|
||||
if ( 'Update Pledge' === $action ) {
|
||||
$processed = process_form_manage();
|
||||
$results = process_form_manage( $pledge_id, $auth_token );
|
||||
|
||||
if ( is_wp_error( $processed ) ) {
|
||||
$messages = array_merge( $messages, $processed->get_error_messages() );
|
||||
} elseif ( 'success' === $processed ) {
|
||||
$updated = true;
|
||||
if ( is_wp_error( $results ) ) {
|
||||
$errors = $results->get_error_messages();
|
||||
} else {
|
||||
$messages = array( __( 'Your pledge has been updated.', 'wporg-5ftf' ) );
|
||||
}
|
||||
}
|
||||
|
||||
$data = PledgeMeta\get_pledge_meta( $pledge_id );
|
||||
|
||||
ob_start();
|
||||
$readonly = false;
|
||||
$is_manage = true;
|
||||
require FiveForTheFuture\PATH . 'views/form-pledge-manage.php';
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a submission from the Manage Existing Pledge form.
|
||||
* Process a submission from the Manage Pledge form.
|
||||
*
|
||||
* TODO This doesn't actually update any data yet when the form is submitted.
|
||||
*
|
||||
* @return string|WP_Error String "success" if the form processed correctly. Otherwise WP_Error.
|
||||
* @return WP_Error|true An error if the pledge could not be saved. Otherwise true.
|
||||
*/
|
||||
function process_form_manage() {
|
||||
function process_form_manage( $pledge_id, $auth_token ) {
|
||||
$errors = array();
|
||||
$nonce = filter_input( INPUT_POST, '_wpnonce', FILTER_SANITIZE_STRING );
|
||||
$nonce_action = 'manage_pledge_' . $pledge_id;
|
||||
$has_valid_nonce = wp_verify_nonce( $nonce, $nonce_action );
|
||||
|
||||
/*
|
||||
* This should be redundant, since it's also called by `render_form_manage()`, but it's good to also do it here
|
||||
* just in case other code changes in the future, or this gets called by another flow, etc.
|
||||
*/
|
||||
$can_view_form = Auth\can_manage_pledge( $pledge_id, $auth_token );
|
||||
|
||||
if ( ! $has_valid_nonce || ! $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 )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$submission = get_form_submission();
|
||||
$has_error = check_invalid_submission( $submission );
|
||||
$has_error = check_invalid_submission( $submission, 'update' );
|
||||
if ( $has_error ) {
|
||||
return $has_error;
|
||||
}
|
||||
|
||||
// todo email any new contributors for confirmation
|
||||
// notify any removed contributors?
|
||||
// ask them to update their profiles?
|
||||
// automatically update contributor profiles?
|
||||
// anything else?
|
||||
PledgeMeta\save_pledge_meta( $pledge_id, $submission );
|
||||
|
||||
// @todo Upload & attach logo.
|
||||
// @todo Save contributors.
|
||||
|
||||
// If we made it to here, we've successfully saved the pledge.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and sanitize $_POST values from a form submission.
|
||||
*
|
||||
* @return array|bool
|
||||
* @return array
|
||||
*/
|
||||
function get_form_submission() {
|
||||
$input_filters = array_merge(
|
||||
|
@ -213,7 +257,8 @@ function get_form_submission() {
|
|||
|
||||
$result = filter_input_array( INPUT_POST, $input_filters );
|
||||
if ( ! $result ) {
|
||||
return array_fill_keys( array_keys( $input_filters ), '' );
|
||||
$result = array_fill_keys( array_keys( $input_filters ), '' );
|
||||
$result['empty_post'] = true;
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
@ -222,10 +267,13 @@ function get_form_submission() {
|
|||
/**
|
||||
* Check the submission for valid data.
|
||||
*
|
||||
* @param array $submission The user input.
|
||||
* @param string $context Whether this is a new pledge (`create`) or an edit to an existing one (`update`).
|
||||
*
|
||||
* @return false|WP_Error Return any errors in the submission, or false if no errors.
|
||||
*/
|
||||
function check_invalid_submission( $submission ) {
|
||||
$has_required = PledgeMeta\has_required_pledge_meta( $submission );
|
||||
function check_invalid_submission( $submission, $context ) {
|
||||
$has_required = PledgeMeta\has_required_pledge_meta( $submission, $context );
|
||||
if ( is_wp_error( $has_required ) ) {
|
||||
return $has_required;
|
||||
}
|
||||
|
@ -237,20 +285,22 @@ function check_invalid_submission( $submission ) {
|
|||
Pledge\CPT_ID
|
||||
);
|
||||
|
||||
if ( Pledge\has_existing_pledge( $email, 'email' ) ) {
|
||||
return new WP_Error(
|
||||
'existing_pledge_email',
|
||||
__( 'This email address is already connected to an existing pledge.', 'wporg-5ftf' )
|
||||
);
|
||||
}
|
||||
if ( 'create' === $context ) {
|
||||
if ( Pledge\has_existing_pledge( $email, 'email' ) ) {
|
||||
return new WP_Error(
|
||||
'existing_pledge_email',
|
||||
__( 'This email address is already connected to an existing pledge.', 'wporg-5ftf' )
|
||||
);
|
||||
}
|
||||
|
||||
$domain = PledgeMeta\get_normalized_domain_from_url( $submission['org-url'] );
|
||||
$domain = PledgeMeta\get_normalized_domain_from_url( $submission['org-url'] );
|
||||
|
||||
if ( Pledge\has_existing_pledge( $domain, 'domain' ) ) {
|
||||
return new WP_Error(
|
||||
'existing_pledge_domain',
|
||||
__( 'A pledge already exists for this domain.', 'wporg-5ftf' )
|
||||
);
|
||||
if ( Pledge\has_existing_pledge( $domain, 'domain' ) ) {
|
||||
return new WP_Error(
|
||||
'existing_pledge_domain',
|
||||
__( 'A pledge already exists for this domain.', 'wporg-5ftf' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -28,34 +28,38 @@ add_action( 'added_post_meta', __NAMESPACE__ . '\update_generated_meta', 10, 4
|
|||
/**
|
||||
* Define pledge meta fields and their properties.
|
||||
*
|
||||
* @param string $context Optional. The part of the config to return. 'user_input', 'generated', or 'all'.
|
||||
* @param string $subset Optional. The part of the config to return: 'user_input', 'generated', or 'all'.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function get_pledge_meta_config( $context = 'all' ) {
|
||||
function get_pledge_meta_config( $subset = 'all' ) {
|
||||
$user_input = array(
|
||||
'org-description' => array(
|
||||
'single' => true,
|
||||
'sanitize_callback' => __NAMESPACE__ . '\sanitize_description',
|
||||
'show_in_rest' => true,
|
||||
'context' => array( 'create', 'update' ),
|
||||
'php_filter' => FILTER_UNSAFE_RAW,
|
||||
),
|
||||
'org-name' => array(
|
||||
'single' => true,
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
'show_in_rest' => true,
|
||||
'context' => array( 'create', 'update' ),
|
||||
'php_filter' => FILTER_SANITIZE_STRING,
|
||||
),
|
||||
'org-url' => array(
|
||||
'single' => true,
|
||||
'sanitize_callback' => 'esc_url_raw',
|
||||
'show_in_rest' => true,
|
||||
'context' => array( 'create', 'update' ),
|
||||
'php_filter' => FILTER_VALIDATE_URL,
|
||||
),
|
||||
'org-pledge-email' => array(
|
||||
'single' => true,
|
||||
'sanitize_callback' => 'sanitize_email',
|
||||
'show_in_rest' => false,
|
||||
'context' => array( 'create' ),
|
||||
'php_filter' => FILTER_VALIDATE_EMAIL,
|
||||
),
|
||||
);
|
||||
|
@ -83,7 +87,7 @@ function get_pledge_meta_config( $context = 'all' ) {
|
|||
),
|
||||
);
|
||||
|
||||
switch ( $context ) {
|
||||
switch ( $subset ) {
|
||||
case 'user_input':
|
||||
$return = $user_input;
|
||||
break;
|
||||
|
@ -107,7 +111,6 @@ function get_pledge_meta_config( $context = 'all' ) {
|
|||
*/
|
||||
function sanitize_description( $insecure ) {
|
||||
$secure = wp_kses_data( $insecure );
|
||||
$secure = wpautop( $secure );
|
||||
$secure = wp_unslash( wp_rel_nofollow( $secure ) );
|
||||
|
||||
return $secure;
|
||||
|
@ -243,12 +246,13 @@ function save_pledge( $pledge_id, $pledge ) {
|
|||
$get_action = filter_input( INPUT_GET, 'action' );
|
||||
$post_action = filter_input( INPUT_POST, 'action' );
|
||||
$ignored_actions = array( 'trash', 'untrash', 'restore' );
|
||||
$context = ( 'editpost' === $post_action ) ? 'update' : 'create';
|
||||
|
||||
/*
|
||||
* This is only intended to run when the front end form and wp-admin forms are submitted, not when posts are
|
||||
* programmatically updated.
|
||||
*/
|
||||
if ( 'Submit Pledge' !== $post_action && 'editpost' !== $post_action ) {
|
||||
if ( ! in_array( $post_action, [ 'Submit Pledge', 'editpost' ], true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -268,7 +272,7 @@ function save_pledge( $pledge_id, $pledge ) {
|
|||
|
||||
$submitted_meta = PledgeForm\get_form_submission();
|
||||
|
||||
if ( is_wp_error( has_required_pledge_meta( $submitted_meta ) ) ) {
|
||||
if ( is_wp_error( has_required_pledge_meta( $submitted_meta, $context ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -294,6 +298,10 @@ function save_pledge_meta( $pledge_id, $new_values ) {
|
|||
$config = get_pledge_meta_config();
|
||||
|
||||
foreach ( $new_values as $key => $value ) {
|
||||
// A null value can happen if the submission form did not have a given field.
|
||||
if ( is_null( $value ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( array_key_exists( $key, $config ) ) {
|
||||
$meta_key = META_PREFIX . $key;
|
||||
|
||||
|
@ -391,14 +399,22 @@ function update_single_cached_pledge_data( $pledge_id ) {
|
|||
/**
|
||||
* Check that an array contains values for all required keys.
|
||||
*
|
||||
* @return bool|WP_Error True if all required values are present. Otherwise WP_Error.
|
||||
* @param array $submission Form submission data.
|
||||
* @param string $context Whether this is a new pledge (`create`) or an edit to an existing one (`update`).
|
||||
*
|
||||
* @return true|WP_Error True if all required values are present. Otherwise WP_Error.
|
||||
*/
|
||||
function has_required_pledge_meta( array $submission ) {
|
||||
function has_required_pledge_meta( array $submission, $context ) {
|
||||
$error = new WP_Error();
|
||||
|
||||
$required = array_keys( get_pledge_meta_config( 'user_input' ) );
|
||||
$meta_config = get_pledge_meta_config( 'user_input' );
|
||||
$required = array_keys( $meta_config );
|
||||
|
||||
foreach ( $required as $key ) {
|
||||
if ( ! in_array( $context, $meta_config[ $key ]['context'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! isset( $submission[ $key ] ) || is_null( $submission[ $key ] ) ) {
|
||||
$error->add(
|
||||
'required_field_empty',
|
||||
|
@ -428,19 +444,23 @@ function has_required_pledge_meta( array $submission ) {
|
|||
/**
|
||||
* Get the metadata for a given pledge, or a default set if no pledge is provided.
|
||||
*
|
||||
* @param int $pledge_id
|
||||
* @param string $context
|
||||
* @param int $pledge_id Pledge to fetch data from.
|
||||
* @param string $subset Optional. The part of the config to return: 'user_input', 'generated', or 'all'.
|
||||
*
|
||||
* @return array Pledge data
|
||||
*/
|
||||
function get_pledge_meta( $pledge_id = 0, $context = '' ) {
|
||||
function get_pledge_meta( $pledge_id = 0, $subset = '' ) {
|
||||
// Get existing pledge, if it exists.
|
||||
$pledge = get_post( $pledge_id );
|
||||
|
||||
$keys = get_pledge_meta_config( $context );
|
||||
$keys = get_pledge_meta_config( $subset );
|
||||
$meta = array();
|
||||
|
||||
// Get POST'd submission, if it exists.
|
||||
$submission = PledgeForm\get_form_submission();
|
||||
if ( isset( $submission['empty_post'] ) && $submission['empty_post'] ) {
|
||||
$submission = array();
|
||||
}
|
||||
|
||||
foreach ( $keys as $key => $config ) {
|
||||
if ( isset( $submission[ $key ] ) ) {
|
||||
|
|
|
@ -1,25 +1,38 @@
|
|||
<?php
|
||||
namespace WordPressDotOrg\FiveForTheFuture\View;
|
||||
|
||||
namespace WordPressDotOrg\FiveForTheFuture\View;
|
||||
use function WordPressDotOrg\FiveForTheFuture\get_views_path;
|
||||
|
||||
/** @var array $messages */
|
||||
/** @var bool $updated */
|
||||
/**
|
||||
* @var bool $can_view_form
|
||||
* @var int $pledge_id
|
||||
* @var string $auth_token
|
||||
*/
|
||||
|
||||
require __DIR__ . '/partial-result-messages.php';
|
||||
|
||||
?>
|
||||
|
||||
<form class="pledge-form" id="5ftf-form-pledge-manage" action="" method="post" enctype="multipart/form-data">
|
||||
<?php
|
||||
require get_views_path() . 'inputs-pledge-org-info.php';
|
||||
require get_views_path() . 'manage-contributors.php';
|
||||
require get_views_path() . 'inputs-pledge-org-email.php';
|
||||
?>
|
||||
<?php if ( true === $can_view_form ) : ?>
|
||||
|
||||
<div>
|
||||
<input
|
||||
type="submit"
|
||||
id="5ftf-pledge-submit"
|
||||
name="action"
|
||||
value="<?php esc_attr_e( 'Update Pledge', 'wporg-5ftf' ); ?>"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
<form class="pledge-form" id="5ftf-form-pledge-manage" action="" method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" name="pledge_id" value="<?php echo absint( $pledge_id ); ?>" />
|
||||
<input type="hidden" name="auth_token" value="<?php echo esc_attr( $auth_token ); ?>" />
|
||||
|
||||
<?php
|
||||
wp_nonce_field( 'manage_pledge_' . $pledge_id );
|
||||
|
||||
require get_views_path() . 'inputs-pledge-org-info.php';
|
||||
?>
|
||||
|
||||
<div>
|
||||
<input
|
||||
type="submit"
|
||||
id="5ftf-pledge-submit"
|
||||
name="action"
|
||||
value="<?php esc_attr_e( 'Update Pledge', 'wporg-5ftf' ); ?>"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php endif; ?>
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace WordPressDotOrg\FiveForTheFuture\View;
|
||||
|
||||
/** @var array $data */
|
||||
/** @var bool $readonly */
|
||||
/**
|
||||
* @var array $data
|
||||
* @var int $pledge_id
|
||||
* @var bool $readonly
|
||||
*/
|
||||
|
||||
?>
|
||||
|
||||
<div class="form-field">
|
||||
|
@ -20,6 +25,11 @@ namespace WordPressDotOrg\FiveForTheFuture\View;
|
|||
</div>
|
||||
|
||||
<?php if ( ! is_admin() ) : ?>
|
||||
<?php if ( has_post_thumbnail( $pledge_id ) ) : ?>
|
||||
<div class="form-field form-field__logo-display">
|
||||
<?php echo get_the_post_thumbnail( $pledge_id, 'pledge-logo' ); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="form-field form-field__logo">
|
||||
<label for="5ftf-org-logo">
|
||||
<?php esc_html_e( 'Logo', 'wporg-5ftf' ); ?>
|
||||
|
|
Loading…
Reference in a new issue