WordPress: creare un form di upload AJAX per impostare l'immagine in evidenza di un post

Short link

In WordPress possiamo creare un upload in AJAX per impostare l'immagine in evidenza di un post.

Creiamo il seguente form di upload.


<form action="" method="post" id="upload-form" enctype="multipart/form-data">
    <div>
        <input type="hidden" name="post_id" value="10">
        <input type="file" name="image">
        <input type="submit" value="Upload">
    </div>
</form>

Vogliamo accettare solo immagini JPEG, con una dimensione massima di 500 Kb e una larghezza non inferiore ai 1920 pixel. In altre parole, accettiamo solo immagini già ottimizzate per il web.

Possiamo definire la seguente soluzione AJAX nel file functions.php.


define( 'MAX_IMAGE_SIZE', 500000 );
define( 'MIN_IMAGE_WIDTH', 1920 );

function my_validate_file_upload( $filename ) {
	$valid = true;
	switch ( $_FILES[$filename]['error'] ) {
		case UPLOAD_ERR_OK:
			break;
		case UPLOAD_ERR_NO_FILE:
			$valid = false;
			break;
		case UPLOAD_ERR_INI_SIZE:
		case UPLOAD_ERR_FORM_SIZE:
			$valid = false;
			break;
		default:
			$valid = false;
			break;
	}
	if ( $_FILES[$filename]['size'] > MAX_IMAGE_SIZE ) {
		$valid = false;
	}

	$finfo = new finfo(FILEINFO_MIME_TYPE);
	if (false === $ext = array_search(
			$finfo->file( $_FILES[ $filename ]['tmp_name'] ),
			array(
				'jpg' => 'image/jpeg'
			),
			true
		)) {
		$valid = false;
	}

	list( $width ) = getimagesize( $_FILES[ $filename ]['tmp_name'] );

	if( intval( $width ) < MIN_IMAGE_WIDTH ) {
		$valid = false;
	}

	return $valid;
}


function my_upload_featured_image() {
	if( !my_validate_file_upload( 'image' ) ) {
		wp_send_json( array( 'error' => __( 'Upload non valido', 'textdomain' ) ) );
	}
	$posted_data =  isset( $_POST ) ? $_POST : array();
	$file_data = isset( $_FILES ) ? $_FILES : array();
	$data = array_merge( $posted_data, $file_data );
	$attachment_id = media_handle_upload( 'image', 0 );
	$output = array();

	if( !is_wp_error( $attachment_id ) ) {
		$id = intval( $data['post_id'] );
		set_post_thumbnail( $id, $attachment_id );
		$output['success'] = true;
		wp_send_json( $output );
	} else {
		wp_send_json( array( 'error' => __( 'Upload non valido', 'textdomain' ) ) );
	}
}

add_action( 'wp_ajax_my_upload_featured_image', 'my_upload_featured_image' );

In pratica la nostra funzione di validazione va invocata prima della funzione media_handle_upload(). Quest'ultima funzione deve essere invocata solo se la validazione viene superata.

Definiamo quindi il codice lato client.


$( "#upload-form" ).on( "submit", function( e ) {
    e.preventDefault();

    var $form = $( this );
    var image = $( "[name=image]", $form )[0].files.length > 0 ? $( "[name=image]", $form )[0].files[0] : "";

    var formData = new FormData();

    formData.append( "action", "my_upload_featured_image" );
    formData.append( "post_id", $( "[name=post_id]", $form ).val() );
    formData.append( "image", image );

    $.ajax({
        url: "/wp-admin/admin-ajax.php",
        type: "POST",
        data: formData,
        cache: false,
        dataType: "json",
        processData: false,
        contentType: false,
        success: function( resp ) {
            if( resp.error ) {
                // Upload non riuscito
            } else if( resp.success ) {
                // Upload riuscito
            }
        }

    });
});

La action AJAX è riservata ai soli utenti che abbiano effettuato il login sul nostro sito.

L'autore

Gabriele Romanato, sviluppatore web full stack specializzato in siti, applicativi web ed e-commerce con Node.js e PHP.