Create a Pledge: Upload a logo (#45)

* Allow image uploads

* Add the logo as "generated" meta

This will be attached after we've processed the `$_FILES` object into an upload.

* Load image into media library, attach to the submitted pledge as a featured image.

* Move where image handling happens so we can pass back errors

* Pass back error if upload fails

* Create a validation function to do basic checking of form data

* Move logo uploading to a separate function, and rely on core checks for mime & filesize checking

* Tweak function name to be more clear

* Remove bmp, tiff, and ico file types
This commit is contained in:
Kelly Dwan 2019-10-28 11:47:56 -04:00 committed by GitHub
parent 3f774fdb78
commit f9d4a0bd59
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 120 additions and 64 deletions

View file

@ -62,46 +62,21 @@ function render_form_new() {
*/
function process_form_new() {
$submission = get_form_submission();
$has_required = PledgeMeta\has_required_pledge_meta( $submission );
if ( is_wp_error( $has_required ) ) {
return $has_required;
}
$email = sanitize_meta(
PledgeMeta\META_PREFIX . 'org-pledge-email',
$submission['org-pledge-email'],
'post',
Pledge\CPT_ID
);
// todo make this validation DRY w/ process_form_manage().
if ( has_existing_pledge( $email, 'email' ) ) {
return new WP_Error(
'existing_pledge_email',
__( 'This email address is already connected to an existing pledge.', 'wporg' )
);
}
// todo should probably verify that email address is for the same domain as URL. do here and for manage.
$domain = PledgeMeta\get_normalized_domain_from_url( $submission['org-url'] );
if ( has_existing_pledge( $domain, 'domain' ) ) {
return new WP_Error(
'existing_pledge_domain',
__( 'A pledge already exists for this domain.', 'wporg' )
);
$has_error = check_invalid_submission( $submission );
if ( $has_error ) {
return $has_error;
}
$contributors = parse_contributors( $submission['pledge-contributors'] );
if ( is_wp_error( $contributors ) ) {
return $contributors;
}
$logo_attachment_id = upload_image( $_FILES['org-logo'] );
if ( is_wp_error( $logo_attachment_id ) ) {
return $logo_attachment_id;
}
$name = sanitize_meta(
PledgeMeta\META_PREFIX . 'org-name',
$submission['org-name'],
@ -119,6 +94,13 @@ function process_form_new() {
Contributor\create_new_contributor( $wporg_username, $new_pledge_id );
}
// Attach logo to the pledge.
wp_update_post( array(
'ID' => $logo_attachment_id,
'post_parent' => $new_pledge_id,
) );
set_post_thumbnail( $new_pledge_id, $logo_attachment_id );
return 'success';
}
@ -244,34 +226,9 @@ function render_form_manage() {
*/
function process_form_manage() {
$submission = get_form_submission();
$has_required = PledgeMeta\has_required_pledge_meta( $submission );
if ( is_wp_error( $has_required ) ) {
return $has_required;
}
$email = sanitize_meta(
PledgeMeta\META_PREFIX . 'org-pledge-email',
$submission['org-pledge-email'],
'post',
Pledge\CPT_ID
);
if ( has_existing_pledge( $email, 'email' ) ) {
return new WP_Error(
'existing_pledge_email',
__( 'This email address is already connected to an existing pledge.', 'wporg' )
);
}
$domain = PledgeMeta\get_normalized_domain_from_url( $submission['org-url'] );
if ( has_existing_pledge( $domain, 'domain' ) ) {
return new WP_Error(
'existing_pledge',
__( 'A pledge already exists for this domain.', 'wporg' )
);
$has_error = check_invalid_submission( $submission );
if ( $has_error ) {
return $has_error;
}
// todo email any new contributors for confirmation
@ -392,3 +349,98 @@ function parse_contributors( $contributors ) {
return $sanitized_contributors;
}
/**
* Check the submission for valid data.
*
* @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 );
if ( is_wp_error( $has_required ) ) {
return $has_required;
}
$email = sanitize_meta(
PledgeMeta\META_PREFIX . 'org-pledge-email',
$submission['org-pledge-email'],
'post',
Pledge\CPT_ID
);
if ( has_existing_pledge( $email, 'email' ) ) {
return new WP_Error(
'existing_pledge_email',
__( 'This email address is already connected to an existing pledge.', 'wporg' )
);
}
$domain = PledgeMeta\get_normalized_domain_from_url( $submission['org-url'] );
if ( has_existing_pledge( $domain, 'domain' ) ) {
return new WP_Error(
'existing_pledge_domain',
__( 'A pledge already exists for this domain.', 'wporg' )
);
}
return false;
}
/**
* Upload the logo image into the media library.
*
* @param array $logo $_FILES array for the uploaded logo.
* @return int|WP_Error Upload attachment ID, or WP_Error if there was an error.
*/
function upload_image( $logo ) {
if ( ! $logo ) {
return false;
}
// Process image.
if ( ! function_exists('media_handle_upload') ) {
require_once ABSPATH . 'wp-admin/includes/image.php';
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/media.php';
}
if ( ! function_exists('check_upload_size') ) {
require_once ABSPATH . 'wp-includes/ms-functions.php';
require_once ABSPATH . 'wp-admin/includes/ms.php';
}
add_filter( 'upload_mimes', __NAMESPACE__ . '\safelist_image_mimes' );
add_filter( 'pre_site_option_fileupload_maxk', __NAMESPACE__ . '\restrict_file_size' );
add_filter( 'wp_handle_sideload_prefilter', 'check_upload_size' );
$logo_id = \media_handle_sideload( $logo, 0 );
remove_filter( 'upload_mimes', __NAMESPACE__ . '\safelist_image_mimes' );
remove_filter( 'pre_site_option_fileupload_maxk', __NAMESPACE__ . '\restrict_file_size' );
remove_filter( 'wp_handle_sideload_prefilter', 'check_upload_size' );
return $logo_id;
}
/**
* Only allow image mime types.
*
* @param array $mimes Mime types keyed by the file extension regex corresponding to those types.
*/
function safelist_image_mimes( $mimes ) {
return array(
'jpg|jpeg|jpe' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
);
}
/**
* Restrict images uploaded by this form to be less than 5MB.
*
* @param bool $value Null returning a value will short-circuit the option lookup.
*/
function restrict_file_size( $value ) {
return 5 * MB_IN_BYTES;
}

View file

@ -7,7 +7,7 @@ use function WordPressDotOrg\FiveForTheFuture\get_views_path;
/** @var bool $updated */
?>
<form class="pledge-form" id="5ftf-form-pledge-manage" action="" method="post">
<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';

View file

@ -51,7 +51,7 @@ use function WordPressDotOrg\FiveForTheFuture\get_views_path;
<?php else : ?>
<form class="pledge-form" id="5ftf-form-pledge-new" action="" method="post">
<form class="pledge-form" id="5ftf-form-pledge-new" action="" method="post" enctype="multipart/form-data">
<?php
require get_views_path() . 'inputs-pledge-org-info.php';
require get_views_path() . 'inputs-pledge-contributors.php';

View file

@ -24,7 +24,11 @@ namespace WordPressDotOrg\FiveForTheFuture\View;
<?php esc_html_e( 'Logo', 'wordpressorg' ); ?>
</label>
<br />
<?php /* @todo Display existing logo here */ ?>
<?php if ( is_admin() && has_post_thumbnail() ) : ?>
<div class="form-field__logo-display">
<?php the_post_thumbnail(); ?>
</div>
<?php endif; ?>
<input
type="file"
id="5ftf-org-logo"