Skip to content

Instantly share code, notes, and snippets.

@itzikbenh
Last active January 14, 2022 13:42
Show Gist options
  • Save itzikbenh/ffe94224e9e78872e5ba897b89d92d06 to your computer and use it in GitHub Desktop.
Save itzikbenh/ffe94224e9e78872e5ba897b89d92d06 to your computer and use it in GitHub Desktop.
WordPress - How to upload images from a frontend form via the rest-api.

Before you go over the snippets I will summarize which functions are being used.

media_handle_upload('image', 0);

That's it! one function that would insert the image into the DB, create four copies with different sizes, and upload to the uploads directory. Regarding the arguments:

'image' is what holds all the data about the image. It comes from the POST request. In the JS file you will see what I mean.

'0' This is the $post_id. I set it to zero, because i'm not asigning this image to any post at the moment. In order for this function to work we need to add above it:

require_once( ABSPATH . 'wp-admin/includes/image.php' );
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/media.php' );

NOTE

You will probably want to create your own validation rules. Even before you send the AJAX call. I'm only showing you how to upload the image, but not to secure it. Maybe I will add it later.

//Here we send the AJAX call on user submit
(function($){
$(document).ready(function(){
$('.add-event').on('click', function(event){
event.preventDefault();
var title = $('#post_title').val();
var event_date = $('#datepicker-front').val();
var event_location = $('#event_location').val();
var event_details = $('#event_details').val();
//We must create a FormData instance, because we are uploading an image
var form = new FormData();
var image = $('#image')[0].files[0]; //We have only one file and this is how we get it.
//Now we add all the data to the form instance in a key value pair.
//Notice that we called it image here. if you change it then change it in the
//media_handle_upload('image', 0); function as well.
form.append('image', image);
form.append('title', title);
form.append('event_date', event_date);
form.append('event_location', event_location);
form.append('event_details', event_details);
//Using localize script to pass "site_url" and "nonce"
$.ajax({
url: theme_data.site_url + 'wp-json/add-event/v1/event',
method: 'POST',
beforeSend: function(xhr) {
xhr.setRequestHeader( 'X-WP-Nonce', theme_data.nonce );
},
data: form,
processData: false, //Very important
contentType:false, //Very important
}).done(function(data){
console.log("data is: ", data);
}).fail(function(data){
console.log("errors are: ", error);
});
});
});
})(jQuery);
//I will just show you how to register an API endpoint and pass data via localize script:
function theme_js()
{
wp_localize_script( 'theme_js', 'theme_data', array('nonce' => wp_create_nonce( 'wp_rest' ), 'site_url' => network_site_url( '/' )) );
}
add_action( 'wp_enqueue_scripts', 'theme_js' );
//Endpoint for adding event
function water_endpoints()
{
register_rest_route('add-event/v1', '/event/', array(
'methods' => 'POST',
'callback' => 'add_event'
));
}
add_action( 'rest_api_init', 'water_endpoints' );
<!-- Lets assume you want to add an event: -->
<form class="form-horizontal" method="post" enctype="multipart/form-data">
<div class="form-group">
<div class="col-md-6 col-md-offset-3">
<input type="text" class="form-control" id="post_title" name="post_title" placeholder="Title">
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-3">
<input type="text" class="form-control" id="datepicker-front" name="event_date" placeholder="Event Date">
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-3">
<input type="text" class="form-control" id="event_location" name="event_location" placeholder="Location">
</div>
</div>
<!-- The file input -->
<div class="form-group">
<div class="col-md-6 col-md-offset-3">
<input id="image" type="file" />
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-3">
<textarea class="form-control" id="event_details" name="event_details" rows="8" cols="40" placeholder="Details"></textarea>
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-3">
<button type="submit" class="ath-btn ath-btn-primary add-event">
ADD EVENT
</button>
</div>
</div>
</form>
<?php
function add_event(WP_REST_Request $request)
{
//We simply get the data and store it. Don't forget to add validation as needed.
$title = sanitize_text_field( trim( $request['title'] ) );
$event_date = trim( $request['event_date'] );
$event_location = sanitize_text_field( trim( $request['event_location'] ) );
$event_details = sanitize_text_field( trim( $request['event_details'] ) );
require_once( ABSPATH . 'wp-admin/includes/image.php' );
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/media.php' );
//On success it returns attachment ID
$attachment_id = media_handle_upload('image', 0);
//Check for errors
if ( is_wp_error( $attachment_id ) )
{
// There was an error uploading the image.
}
else
{
// The image was uploaded successfully!
}
$event = array(
'post_title' => $title,
'post_status' => 'publish',
'post_type' => 'event',
'meta_input' => array(
'event_date' => $event_date,
'event_location' => $event_location,
'event_details' => $event_details
)
);
$post_id = wp_insert_post( $event );
if( is_wp_error( $post_id ) )
{
$error = "Something went wrong";
return new WP_Error( 'server_error', $error );
}
return "Event has been added successfully";
}
?>
Copy link

ghost commented Oct 10, 2018

Hi, thanks for the script, but what about, if I want to attach the image to the specific category, how can I do that ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment