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.