I am trying to upload base 64 encoded images to my website media library via API. API returns with image ID but these images are displaying as blank images in my media library. Here is my code
add_action('rest_api_init', function () {
register_rest_route( 'api/v1', 'upload_image/',array(
'methods' => 'POST',
'callback' => 'accept_image'
));
});
function accept_image($request){
$parameters = $request->get_query_params();
$parameters = $parameters['image'];
$decoded = base64_decode(str_replace('data:image/png;base64,','',$parameters));
$upload_dir = wp_upload_dir();
$upload_path = str_replace( '/', DIRECTORY_SEPARATOR, $upload_dir['path'] ) . DIRECTORY_SEPARATOR;
$filename = 'my_image.png';
$hashed_filename = md5( $filename . microtime() ) . '_' . $filename;
$image_upload = file_put_contents( $upload_path . $hashed_filename, $decoded );
//HANDLE UPLOADED FILE
if( !function_exists( 'wp_handle_sideload' ) ) {
require_once( ABSPATH . 'wp-admin/includes/file.php' );
}
// Without that I'm getting a debug error!?
if( !function_exists( 'wp_get_current_user' ) ) {
require_once( ABSPATH . 'wp-includes/pluggable.php' );
}
// @new
$file = array();
$file['error'] = '';
$file['tmp_name'] = $upload_path . $hashed_filename;
$file['name'] = $hashed_filename;
$file['type'] = 'image/png';
$file['size'] = filesize( $upload_path . $hashed_filename );
// upload file to server
// @new use $file instead of $image_upload
$file_return = wp_handle_sideload( $file, array( 'test_form' => false ) );
$filename = $file_return['file'];
$attachment = array(
'post_mime_type' => $file_return['type'],
'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
'post_content' => '',
'post_status' => 'inherit',
'guid' => $wp_upload_dir['url'] . '/' . basename($filename)
);
$attach_id = wp_insert_attachment( $attachment, $filename );
return $attach_id;
}
I want to know where I have issue and how I can fix this. I will really appreciate your help.
I am trying to upload base 64 encoded images to my website media library via API. API returns with image ID but these images are displaying as blank images in my media library. Here is my code
add_action('rest_api_init', function () {
register_rest_route( 'api/v1', 'upload_image/',array(
'methods' => 'POST',
'callback' => 'accept_image'
));
});
function accept_image($request){
$parameters = $request->get_query_params();
$parameters = $parameters['image'];
$decoded = base64_decode(str_replace('data:image/png;base64,','',$parameters));
$upload_dir = wp_upload_dir();
$upload_path = str_replace( '/', DIRECTORY_SEPARATOR, $upload_dir['path'] ) . DIRECTORY_SEPARATOR;
$filename = 'my_image.png';
$hashed_filename = md5( $filename . microtime() ) . '_' . $filename;
$image_upload = file_put_contents( $upload_path . $hashed_filename, $decoded );
//HANDLE UPLOADED FILE
if( !function_exists( 'wp_handle_sideload' ) ) {
require_once( ABSPATH . 'wp-admin/includes/file.php' );
}
// Without that I'm getting a debug error!?
if( !function_exists( 'wp_get_current_user' ) ) {
require_once( ABSPATH . 'wp-includes/pluggable.php' );
}
// @new
$file = array();
$file['error'] = '';
$file['tmp_name'] = $upload_path . $hashed_filename;
$file['name'] = $hashed_filename;
$file['type'] = 'image/png';
$file['size'] = filesize( $upload_path . $hashed_filename );
// upload file to server
// @new use $file instead of $image_upload
$file_return = wp_handle_sideload( $file, array( 'test_form' => false ) );
$filename = $file_return['file'];
$attachment = array(
'post_mime_type' => $file_return['type'],
'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
'post_content' => '',
'post_status' => 'inherit',
'guid' => $wp_upload_dir['url'] . '/' . basename($filename)
);
$attach_id = wp_insert_attachment( $attachment, $filename );
return $attach_id;
}
I want to know where I have issue and how I can fix this. I will really appreciate your help.
Share Improve this question asked May 22, 2019 at 21:05 wplearnerwplearner 4892 gold badges9 silver badges27 bronze badges 3- Did my answer help? Do you need any more details? If you used a different solution, let us know about it. – Sally CJ Commented Jun 9, 2019 at 23:59
- 1 Yes I have used a different solution and I have posted that in my answer. Thank you for your help @SallyCJ – wplearner Commented Jun 14, 2019 at 15:55
- Thanks for letting me know. :) – Sally CJ Commented Jun 15, 2019 at 5:39
2 Answers
Reset to default 1You should generate the attachment metadata such as width and height — and file path, and also thumbnails, after you created the attachment:
- Using
wp_generate_attachment_metadata()
:
$attach_id = wp_insert_attachment( $attachment, $filename );
if ( $attach_id ) {
require_once ABSPATH . 'wp-admin/includes/image.php';
$metadata = wp_generate_attachment_metadata( $attach_id, $filename );
wp_update_attachment_metadata( $attach_id, $metadata );
}
- Using
wp_maybe_generate_attachment_metadata()
:
$attach_id = wp_insert_attachment( $attachment, $filename );
if ( $attachment = get_post( $attach_id ) ) {
require_once ABSPATH . 'wp-admin/includes/image.php';
wp_maybe_generate_attachment_metadata( $attachment );
}
Or you could simply use media_handle_sideload()
instead of wp_handle_sideload()
to create the attachment (and its metadata). So you'd use this in place of what you currently have in between the // upload file to server
and return $attach_id;
:
// upload file to server
require_once ABSPATH . 'wp-admin/includes/media.php';
require_once ABSPATH . 'wp-admin/includes/image.php';
$attach_id = media_handle_sideload( $file, 0 );
return $attach_id;
This function worked for me finally.
function accept_image($request){
error_reporting(E_ALL);
//Image should be set as the body of the POST request, as a base-64 encoded string.
//It should NOT include decorations such as data:image/png;base64, at the beginning. It should only be the encoded file itself.
//Everything else should be sent via the header
$is_valid = false;
header('Content-Type: application/json', true);
$response = array('success'=> $is_valid, 'message' => '');
$image = $request->get_body();
$decoded_file = base64_decode($image, true);
if(strlen($image) == 0 || $decoded_file === false){
return api_msg(false, 'An error occurred during base64_decode().');
}
$content_type = $request->get_header("Content-Type");
$ext = '';
switch($content_type){
case "image/jpg":
case "image/jpeg":
$ext = "jpg";
break;
case "image/png";
$ext = "png";
break;
default:
return api_msg(false, "Invalid Content-Type in request header. Acceptable formats are 'image/jpg' or 'image/png'.");
break;
}
$upload_dir = wp_upload_dir();
$upload_path = str_replace( '/', DIRECTORY_SEPARATOR, $upload_dir['path'] ) . DIRECTORY_SEPARATOR;
$rand = md5( rand(3,10) . microtime() );
$hashed_filename = "api_upload_{$rand}.{$ext}";
$image_upload = file_put_contents( $upload_path . $hashed_filename, $decoded_file );
if($image_upload === false)
return api_msg(false, "An error occurred during file_put_contents().");
$url_path = $upload_dir['url'] . '/' . $hashed_filename;
$abs_path = $upload_path . $hashed_filename;
$attachment = array(
'post_mime_type' => $content_type,
'post_title' => "API Upload - " . date('y-m-d H:i:s', time()),
'post_content' => '',
'post_status' => 'inherit',
'guid' => $url_path,
);
$attach_id = wp_insert_attachment( $attachment, $abs_path );
// Make sure that this file is included, as wp_generate_attachment_metadata() depends on it.
require_once( ABSPATH . 'wp-admin/includes/image.php' );
// Generate the metadata for the attachment, and update the database record.
$attach_data = wp_generate_attachment_metadata( $attach_id, $abs_path );
wp_update_attachment_metadata( $attach_id, $attach_data );
return api_msg(true, "Image Saved", $attach_id, $url_path);
}
function api_msg($is_valid, $message, $id = null, $url = null){
$resp = array(
'success' => $is_valid,
'message' => $message
);
if(!empty($id))
$resp['id'] = $id;
if(!empty($url))
$resp['url'] = $url;
return $resp;
}