From f9d4a0bd594a363c705c1e4dc68064f7fdd281f5 Mon Sep 17 00:00:00 2001 From: Kelly Dwan Date: Mon, 28 Oct 2019 11:47:56 -0400 Subject: [PATCH] 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 --- plugins/wporg-5ftf/includes/pledge-form.php | 174 ++++++++++++------ .../wporg-5ftf/views/form-pledge-manage.php | 2 +- plugins/wporg-5ftf/views/form-pledge-new.php | 2 +- .../views/inputs-pledge-org-info.php | 6 +- 4 files changed, 120 insertions(+), 64 deletions(-) diff --git a/plugins/wporg-5ftf/includes/pledge-form.php b/plugins/wporg-5ftf/includes/pledge-form.php index c41f8cb..3173efe 100755 --- a/plugins/wporg-5ftf/includes/pledge-form.php +++ b/plugins/wporg-5ftf/includes/pledge-form.php @@ -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; +} diff --git a/plugins/wporg-5ftf/views/form-pledge-manage.php b/plugins/wporg-5ftf/views/form-pledge-manage.php index 1b7bdc2..ec0901d 100644 --- a/plugins/wporg-5ftf/views/form-pledge-manage.php +++ b/plugins/wporg-5ftf/views/form-pledge-manage.php @@ -7,7 +7,7 @@ use function WordPressDotOrg\FiveForTheFuture\get_views_path; /** @var bool $updated */ ?> -
+ - +
- + +
+ +
+