Making WordPress.org

Changeset 12091


Ignore:
Timestamp:
09/26/2022 10:27:24 PM (2 years ago)
Author:
coffee2code
Message:

Photo Directory, Uploads: Enforce valid photo dimensions.

  • Add client-side JS checks
  • Add server-side checks
Location:
sites/trunk/wordpress.org/public_html/wp-content/plugins/photo-directory
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/photo-directory/assets/js/submit.js

    r12090 r12091  
    5151    photo_upload_form.addEventListener( 'submit', e => {
    5252        e.preventDefault();
     53        PhotoDir.doingSubmit = true;
    5354
    5455        const photo_upload_form = e.target;
     
    141142
    142143    let errorMessage = field.validationMessage;
    143     const cssClass = PhotoDir.error_class;
     144    const stillProcessing = errorMessage === PhotoDir.msg_validating_dimensions;
     145    const cssClass = stillProcessing ? 'processing' : PhotoDir.error_class;
    144146
    145147    if ( ! errorMessage ) {
     
    152154    }
    153155
    154     errorEl = document.createElement( 'span' );
    155     errorEl.setAttribute( 'class', cssClass );
    156     errorEl.innerHTML = errorMessage;
    157     field.insertAdjacentElement( 'afterend', errorEl );
     156    if ( PhotoDir.doingSubmit || ! stillProcessing ) {
     157        errorEl = document.createElement( 'span' );
     158        errorEl.setAttribute( 'class', cssClass );
     159        errorEl.innerHTML = errorMessage;
     160        field.insertAdjacentElement( 'afterend', errorEl );
     161    }
     162
     163    // Show an error and end pending submission state unless still processing.
     164    if ( ! stillProcessing ) {
     165        PhotoDir.doingSubmit = false;
     166        photoSetSubmitButtonDisabled( field.closest( 'form' ), false );
     167    }
    158168
    159169    return '';
     
    179189    }
    180190
     191    // Check for file dimension error.
     192    if ( ! error ) {
     193        // Hack: Wait for file dimensions check to complete before
     194        // determining true validity. Once it has done so, it will
     195        // potentially trigger submit if warranted.
     196        field.setCustomValidity( PhotoDir.msg_validating_dimensions );
     197        error = true;
     198        photoCheckFileDimensions( field );
     199    }
     200
    181201    return error;
     202}
     203
     204/**
     205 * Checks if the file selected via the file input field object is within an
     206 * acceptable file dimension range and sets custom validity message accordingly.
     207 *
     208 * An appropriate error message is defined if the file is too long or too short.
     209 * If there is no file selected, or the file is of sufficient size, then any
     210 * existing custom validity message is cleared.
     211 *
     212 * @param {HTMLElement} field - The HTML file input field element.
     213 * @return {Promise} Promise where result is true if file dimensions are invalid, else false.
     214 */
     215function photoCheckFileDimensions( field ) {
     216    const MIN_SIZE = PhotoDir.min_file_dimension; // In px.
     217    const MAX_SIZE = PhotoDir.max_file_dimension; // In px.
     218
     219    const files = field.files;
     220
     221    if ( files.length > 0 ) {
     222        const reader = new FileReader();
     223
     224        reader.addEventListener( 'load', async (e) => {
     225            const img = new Image();
     226            img.src = e.target.result;
     227
     228            img.decode().then( () => {
     229                let file_width = img.width;
     230                let file_height = img.height;
     231
     232                if ( file_height > MAX_SIZE || file_width > MAX_SIZE ) {
     233                    field.setCustomValidity( PhotoDir.err_file_too_long );
     234                } else if ( file_height < MIN_SIZE || file_width < MIN_SIZE ) {
     235                    field.setCustomValidity( PhotoDir.err_file_too_short );
     236                } else {
     237                    // No custom constraint violation.
     238                    field.setCustomValidity( '' );
     239                }
     240
     241                photoShowFileError( field );
     242            } );
     243        }, false );
     244
     245        reader.readAsDataURL( files.item( 0 ) );
     246
     247        // Return true. This will be rectified once the actual image dimensions are checked.
     248        return true;
     249    }
     250
     251    // No custom constraint violation.
     252    field.setCustomValidity( '' );
     253    return false;
    182254}
    183255
     
    220292 *
    221293 * @param {HTMLElement} field - The HTML file input field element.
    222  */
    223 function photoShowFileErrors( field ) {
     294 * @return {Promise}
     295 */
     296async function photoShowFileErrors( field ) {
    224297    // Checks custom file input validation. A custom validity error message gets
    225298    // set on the field if a validation fails.
    226     photoCheckFileValidations( field );
    227     photoShowFileError( field );
     299    photoCheckFileValidations( field ).then( () => {
     300        photoShowFileError( field )
     301    });
    228302}
    229303
     
    239313    // Remove any existing error message.
    240314    photoRemoveFieldError( field );
     315
     316    // Hack: If this gets called and everything validates, the form can be
     317    // submitted.
     318    const upload_form = field.closest( 'form' );
     319    if ( PhotoDir.doingSubmit ) {
     320        if ( upload_form.checkValidity() ) {
     321            upload_form.submit();
     322            return;
     323        } else {
     324            document.getElementById( 'wporg-photo-upload' ).scrollIntoView( true );
     325            photoSetSubmitButtonDisabled( field.closest( 'form' ), false );
     326        }
     327    }
    241328
    242329    // Return if no legitimate custom error to report.
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/photo-directory/inc/uploads.php

    r12090 r12091  
    270270                    'max_file_size' => self::get_maximum_photo_file_size(),
    271271                    'min_file_size' => self::get_minimum_photo_file_size(),
     272
     273                    // File dimensions.
     274                    'err_file_too_long'     => sprintf(
     275                        /** translators: %d: The maximum number of pixels. */
     276                        __( 'The selected file cannot be longer in either length or width than %dpx.', 'wporg-photos' ),
     277                        self::big_image_size_threshold( 0 )
     278                    ),
     279                    'err_file_too_short'    => sprintf(
     280                        /** translators: %d: The minimum number of pixels. */
     281                        __( 'The selected file must be longer in both length and width than %dpx.', 'wporg-photos' ),
     282                        self::get_minimum_photo_dimension()
     283                    ),
     284                    'max_file_dimension' => self::big_image_size_threshold( 0 ),
     285                    'min_file_dimension' => self::get_minimum_photo_dimension(),
     286                    'msg_validating_dimensions' => __( 'Validating photo dimensions&hellip;', 'wporg-photos' ),
    272287                ]
    273288            );
     
    383398                        __( 'The file size for your submission is too large. Please submit a photo smaller than %d MB in size.', 'wporg-photos' ),
    384399                        self::get_maximum_photo_file_size( false )
     400                    );
     401                    break;
     402                case 'file-too-long':
     403                    $rejection = sprintf(
     404                        __( 'Your submission is too large. Please submit a photo with length and width each smaller than %dpx.', 'wporg-photos' ),
     405                        self::big_image_size_threshold( 0 )
     406                    );
     407                    break;
     408                case 'file-too-short':
     409                    $rejection = sprintf(
     410                        __( 'Your submission is too small. Please submit a photo with length and width each larger than %dpx.', 'wporg-photos' ),
     411                        self::get_minimum_photo_dimension()
    385412                    );
    386413                    break;
     
    579606        if ( ! in_array( $image_type, [ IMG_JPG, IMG_JPEG ] ) ) {
    580607            return 'file-not-jpg';
     608        }
     609
     610        // Check image dimensions.
     611        $max_dimension = self::big_image_size_threshold( 0 );
     612        $min_dimension = self::get_minimum_photo_dimension();
     613        if ( $width > $max_dimension || $length > $max_dimension ) {
     614            return 'file-too-long';
     615        }
     616        if ( $width < $min_dimension || $length < $min_dimension ) {
     617            return 'file-too-short';
    581618        }
    582619
Note: See TracChangeset for help on using the changeset viewer.