Here is how I get my image:
$coverurl = 'https://api.someurl/api/v1/img/' . $somenumber . '/l';
//$iheaders contains: 'Content-type' => 'image/jpeg'
$iresponse = wp_remote_get($coverurl, $iheaders);
$img = $iresponse['body'];
$testimg = base64_encode($img);
When I echo $testimg with an img-tag, everything works fine.
echo '<img class="attachment-shop_single size-shop_single wp-post-image" src="data:image/jpeg;base64,'.$testimg.'" width="274" />';
Since I need to convert the string into a jpg and save it to my uploads folder, I tried to use imagecreatefromstring().
$imgx = imagecreatefromstring($testimg);
if ($imgx !== false) {
header('Content-Type: image/jpeg');
imagejpeg($imgx);
imagedestroy($imgx);
} else {
echo 'An error occurred.';
}
But I never get to the point of saving anything, because of the following warning:
Warning: imagecreatefromstring(): Data is not in a recognized format in /etc.
When I echo $testimg I get:
/9j/4AAQSkZJRgABAQAAAQABAAD ...Many number and characters.. Ggm2JUsEvfqnxAhGFDP/9k=
What must I do to make createimagefromstring work? Do I have to modify the $testimg string? Thanks for your interest.
The method imagecreatefromstring does not take a base_64 encoded string. Try this instead:
$imgx = imagecreatefromstring($img); // Contents of $iresponse['body']
You can see this in the topmost comment in the documentation page (linked above):
<?php
$data = 'iVBORw0KGgoAAAANSUhEUgAAABwAAAASCAMAAAB/2U7WAAAABl'
. 'BMVEUAAAD///+l2Z/dAAAASUlEQVR4XqWQUQoAIAxC2/0vXZDr'
. 'EX4IJTRkb7lobNUStXsB0jIXIAMSsQnWlsV+wULF4Avk9fLq2r'
. '8a5HSE35Q3eO2XP1A1wQkZSgETvDtKdQAAAABJRU5ErkJggg==';
$data = base64_decode($data);
$im = imagecreatefromstring($data);
After looking at the codex https://codex.wordpress.org/Function_Reference/wp_insert_attachment, I found the solution:
//get the image from internet
$coverurl = 'https://api.someurl/api/v1/img/' . $somenumber . '/l';
$iresponse = wp_remote_get($coverurl, $iheaders);
$img = $iresponse['body'];
$directory = "/".date('Y')."/".date('m')."/";
$wp_upload_dir = wp_upload_dir();
//encode $img as with html image tag
$imgdata = base64_encode($img);
$filename = "gtb_". $isbnraw.".jpg";
$fileurl = "../wp-content/uploads".$directory.$filename;
$filetype = wp_check_filetype( basename($fileurl), null);
file_put_contents($fileurl, $img);
$attachment = array(
'guid' => $wp_upload_dir['url'] . '/' . basename( $fileurl ),
'post_mime_type' => $filetype['type'],
'post_title' => preg_replace('/\.[^.]+$/', '', basename($fileurl)),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment($attachment, $fileurl, $post_id);
require_once('../wp-admin/includes/image.php');
// Generate the metadata for the attachment, and update the database record.
$attach_data = wp_generate_attachment_metadata($attach_id, $fileurl);
wp_update_attachment_metadata($attach_id, $attach_data);
set_post_thumbnail($post_id, $attach_id);
//add media_category
wp_set_object_terms($attach_id, $mediacat, 'media_category');
This converts a base64 into a jpg and imports it into Wordpress plus attaches it to the post/product. It seems to work well. Thanks for your interest.
Related
I am using the instagram PHP scraper to get some Images from a Instagram once a Day and now I want to save them to WP to comply with the new Instagram API "cross-origin-resource-policy: same-origin" restriction.
Unfortunatly downloading the Images seems to be problematic for me. I am getting URL's like this one:
https://scontent-frt3-2.cdninstagram.com/v/t51.2885-15/e35/s1080x1080/180944446_818094295796893_2664338416777947736_n.jpg?tp=1&_nc_ht=scontent-frt3-2.cdninstagram.com&_nc_cat=101&_nc_ohc=IeiX9KxK83IAX_dtO18&edm=APU89FABAAAA&ccb=7-4&oh=78ad506e5ddbbcf3adfe3000d0a9a794&oe=60B3A80A&_nc_sid=86f79a
Should be simply saving the jpg but unfortunatly file_get_contents returns an empty file.
I am currently using this code:
$imagetype = end(explode('/', getimagesize($imageurl)['mime']));
$uniq_name = date('dmY').''.(int) microtime(true);
$filename = $uniq_name.'.'.$imagetype;
$uploaddir = wp_upload_dir();
$uploadfile = $uploaddir['path'] . '/' . $filename;
$contents= file_get_contents($imageurl);
$savefile = fopen($uploadfile, 'w');
fwrite($savefile, $contents);
fclose($savefile);
$wp_filetype = wp_check_filetype(basename($filename), null );
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => $filename,
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment( $attachment, $uploadfile );
$imagenew = get_post( $attach_id );
$fullsizepath = get_attached_file( $imagenew->ID );
$attach_data = wp_generate_attachment_metadata( $attach_id, $fullsizepath );
wp_update_attachment_metadata( $attach_id, $attach_data );
$this->conlog(wp_get_attachment_url($attach_id));
return wp_get_attachment_url($attach_id);
$imagetype is empty too, as getimagesize()['mime'] is empty.
I dont really know how to download the image, as I am not relally fluend in PHP.
Do you know how this would be archived best?
Thanks a lot!
For you $imagetype , use pathinfo
https://www.php.net/manual/fr/function.pathinfo.php
$imagetype = pathinfo($image_url, PATHINFO_EXTENSION);
We are uploading custom posts to our wordpress site using the code below. Basically the posts are a folder containing 10-15 image files which are being recursively retrieved from the C:/******/S1/ folder. A post is created using the name of the folder and the contents, being image files are created as attachment types and associated with that particular post. We are using the groups plugin to handle access control.
The problem is when we first started using this code we could upload 100 custom types in 14-15 mins. But the time is consistently increasing and now it takes around 30-35 mins for the same number of posts, the size and number remaining the same. We are not sure how long this time will reach as we continue to upload posts, we intend to create around 30000 posts over a period of a month. Hence the time is a critical factor. We have uploaded around 3000 till now.
We are not sure why this time period is increasing and we need to keep it constant. We have currently hosted this application on a 4 GB RAM, 2.6Ghz 2 core processor system. Currently posts table has around 53000 entries and post_meta has around 70000 entries. Any suggestions/advice are most welcome!!
Thanks in advance!!
function upload_service_register_call_func2() {
echo "<form id=\"featured_upload\" method=\"post\" action =\"/wordpress/index.php/upload-sr-status-v2/\" />";
echo "<input type=\"text\" name=\"my_image_upload\" value=\"C:/******/S1/\" id=\"my_image_upload\" />";
echo"<input id=\"submit_my_image_upload\" name=\"submit_my_image_upload\" type=\"submit\" value=\"Upload\" />";
echo"</form>";
}
function upload_service_register_func2() {
$filename = $_POST[my_image_upload];
$results = array();
$directory1 = $filename;
$handler1 = opendir($directory1);
$uploads_dir=wp_upload_dir();
// open directory and walk through the filenames
while ($file1 = readdir($handler1)) {
if ($file1 != "." && $file1 != "..") {
$directory = $filename."/".$file1;
$handler = opendir($directory);
$myproducts = get_posts( array(
'post_type' => 'se******rs',
'meta_query' => array(
array(
'key' => 's*******o',
'value' => $file1
)
)
) );
$uploaddir = wp_upload_dir();
if (file_exists($uploaddir['path'] . '/'. 'ST' . '/' . $file1)) {
delete_directory($uploaddir['path'] . '/'. 'ST' . '/' . $file1);
}
if(!empty($myproducts)){
foreach($myproducts as $myproduct)
{
wp_delete_post( $myproduct->ID, true);
}
}
$post["id"] = wp_insert_post( array(
"post_title" => $file1,
"post_content" => "",
"post_type" => "se******rs",
"post_status" => "publish",
'meta_query' => array(
array(
'key' => 's*******o',
'value' => $file1
)
)));
$content="";
$files = array();
while ($file = readdir($handler)) {
if ($file != "." && $file != "..") {
array_push($files,$file);
}
}
natsort($files);
$count=0;
foreach($files as $file)
{
$date = date_create();
$timestamp = date_timestamp_get($date);
$foldercreate = wp_mkdir_p($uploaddir['path'] . '/'. 'ST' . '/' . $file1);
$uploadfile = $uploaddir['path'] . '/'. 'ST' . '/' . $file1. '/' .$timestamp $file;
$contents= file_get_contents($directory."/".$file);
$savefile = fopen($uploadfile, 'w');
fwrite($savefile, $contents);
fclose($savefile);
if($count==0)
{
copy('C:\********************\uploads\STORE\index.html',$uploaddir['path'] . '/'. 'ST' . '/' . $file1 . '/index.html' );
copy('C:\********************\uploads\STORE\.htaccess',$uploaddir['path'] . '/'. 'ST' . '/' . $file1 . '/.htaccess');
}
$count++;
$parent_post_id = $post["id"];
// Check the type of file. We'll use this as the 'post_mime_type'.
$filetype = wp_check_filetype( basename( $file ), null );
// Get the path to the upload directory.
$wp_upload_dir = wp_upload_dir();
// Prepare an array of post data for the attachment.
$attachment = array(
'guid' => $wp_upload_dir['url'] .'/'. 'ST'. '/' . $file1. '/' . basename( $uploadfile ),
'post_mime_type' => $filetype['type'],
'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $file ) ),
'post_content' => '',
'post_status' => 'inherit'
);
// Insert the attachment.
$attach_id = wp_insert_attachment( $attachment, $uploadfile, $parent_post_id );
// 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, $file );
wp_update_attachment_metadata( $attach_id, $attach_data );
$image = $wp_upload_dir['url'] .'/'. 'ST'. '/' . $file1. '/' . basename( $uploadfile );
$content = $content."<img style=\"width:150px;height:150px\"; class=\"alignleft size-thumbnail wp-image-".$attach_id."\" src=\"".$image."\" />";
}
$content=$content."";
$my_post = array(
'ID' => $post["id"],
'post_content' => $content,
);
wp_update_post($my_post);
$group_id=get_group_id_by_name( $file1 );
if(!$group_id) $group_id=4;
add_post_meta($post["id"],"groups-read",$group_id);
add_post_meta($post["id"],"groups-read","2");
add_post_meta($post["id"],"s******o",$file1);
$em***=$file1;
$sql2="SELECT de**,bi******* FROM b**********8 WHERE em*** = %s";
$results2=prdt_run_sql($sql2,$em***);
if($results2)
{
foreach($results2 as $data)
{
$de**='SR_'.$data->de**;
$bi******='SR_'.$data->bi*******;
break;
}
$group_id=get_group_id_by_name($de**);
add_post_meta($post["id"],"groups-read",$group_id);
$group_id=get_group_id_by_name($bi*****);
add_post_meta($post["id"],"groups-read",$group_id);
echo "Uploaded folder ".$file1." with permissions<br/>";
}
else
{
echo "Uploaded folder ".$file1." without permissions<br/>";
}
}
}
echo"Completed Uploading folders <br/>";
}
I was trying to make a plugin which would get images from instagram API and then put them in shortcodes which would set the featured image in where the shortcode is. I have this code for the function for setting featured images:
<?php
function Generate_Featured_Image( $image_url, $post_id ){
$upload_dir = wp_upload_dir();
$image_data = file_get_contents($image_url);
$filename = basename($image_url);
if(wp_mkdir_p($upload_dir['path'])) $file = $upload_dir['path'] . '/' . $filename;
else $file = $upload_dir['basedir'] . '/' . $filename;
file_put_contents($file, $image_data);
$wp_filetype = wp_check_filetype($filename, null );
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => sanitize_file_name($filename),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment( $attachment, $file, $post_id );
require_once(ABSPATH . 'wp-admin/includes/image.php');
$attach_data = wp_generate_attachment_metadata( $attach_id, $file );
$res1= wp_update_attachment_metadata( $attach_id, $attach_data );
$res2= set_post_thumbnail( $post_id, $attach_id );
}
Then I have this code for getting the API and putting the images in an array :
//define Access token
$accesst= "3219594850.1677ed0.cb21f3e34b7c4030a8ba364d35ec284b";
//userid
$userid= 3219594850;
//image count to get
$count=20;
//get api contents
$content = file_get_contents('https://api.instagram.com/v1/users/self/media/recent/?access_token='.$accesst.'&count='.$count);
//converting JSON to object
$standardres = json_decode($content, true);
//array method
$images= array();
foreach($standardres['data'] as $photo) {
$imageData =file_get_contents($photo['images']['standard_resolution']['url']);
array_push ($images, $imageData);
}
This should be the function which makes the post as a featured image:
//create functions for shortcodes with definition
function fone(){
global $post;
$fid = $post->ID;
global $images;
Generate_Featured_Image($images[0], $fid);
}
add_shortcode( 'one', 'fone');
?>
But I only get an error displaying :
Warning: file_get_contents() expects parameter 1 to be a valid path, string given in D:\XEMP\htdocs\xd\wordpress\wp-content\plugins\insta-live\insta-live.php on line 56
Warning: file_put_contents() expects parameter 1 to be a valid path, string given in D:\XEMP\htdocs\xd\wordpress\wp-content\plugins\insta-live\insta-live.php on line 60
...
Any ideas where did I go wrong? Line 56 and 60 is :
$image_data = file_get_contents($image_url);
file_put_contents($file, $image_data);
I'm writing a Wordpress plugin to download remote images on my blog.
I made a function to upload a remote image locally, then returning its ID.
All seems OK except that
$attach_data = wp_generate_attachment_metadata( $attach_id, $local_file );
returns me an empty array - and it should not.
wp_generate_attachment_metadata is, among others, responsible of generating the thumbnails of the uploaded image. But I have no thumbnails created when I run my code.
I checked the values I send to the function and they seems correct : I have an ID and an absolute path to the uploaded file, as documented in the codex.
Still, I can't manage to have my code working :
$attach_data should not be empty...
Can anyone help ?
function upload_from_remote_url($url,$post_id){
$url = $this->validate_remote_media_url($url); //check file is not on local server
if (!$url) return false;
if ($existing_id = $this->media_already_exists($url)) return $existing_id; //url already has been downloaded
$upload_dir = wp_upload_dir();
$wp_mime_types = wp_get_mime_types();
//fetch image
$response = wp_remote_get( $url );
//get filename without extension
$filename = basename( $url ); //get filename & extension
$filename_strip = preg_replace('/\.[^.]*$/', '', $filename); //strip extension
//get extension from content type,
//because wp_upload_bits needs an extension and certain url don't have one.
$file_type = wp_remote_retrieve_header( $response, 'content-type' );
$extensions = array_search($file_type,$wp_mime_types);
$extensions_arr = explode('|',$extensions);
$extension = $extensions_arr[0];
$new_filename = $filename_strip.'.'.$extension; //full name
$new_filename = wp_unique_filename($upload_dir['path'], $new_filename); // be sure this name do not exist already
$uploaded = wp_upload_bits($new_filename, '', wp_remote_retrieve_body( $response ) );
if ($uploaded['error']) return false;
$local_file = $uploaded['file'];
$local_filename = basename($local_file);
$local_filetype = wp_check_filetype( $local_filename, null );
//Attachment options
$attachment = array(
'post_title'=> $local_filename,
'post_mime_type' => $local_filetype,
'post_status' => 'inherit'
);
// Add the image to your media library
$attach_id = wp_insert_attachment( $attachment, $local_file, $post_id );
if (!$attach_id) return false;
$attach_data = wp_generate_attachment_metadata( $attach_id, $local_file );
wp_update_attachment_metadata( $attach_id, $attach_data );
//save source link so we do not import several times the same media
update_post_meta($attach_id, 'grm_source', $url);
return $attach_id;
}
BTW, if any WP gourou had anything to say about this code... I'll be happy to read it, as the WP documentation about uploading files is a bit messy. I needed some specific stuff here, as being able to retrieve the file extension. I ended up to this but maybe you have some better ideas !
I've had a similar problem where mime type was missing. Since I use only one mime type, it was fixed by
'post_mime_type' => 'image/jpeg'
After that, it was still not updating the metadata, but forcing the update with "wp_update_attachment_metadata" solved the problem:
$attach_data = wp_generate_attachment_metadata($attach_id, $file_path);
wp_update_attachment_metadata($attach_id, $attach_data);
This is, what finally fixed it for me:
apply_filters('wp_handle_upload', array(
'file' => $file_path,
'url' => $file_url,
'type' => $file_type),
'upload');
Explanation: I'm not quite sure why this fixed the error for me, but I assume that this either has something to do with plugins using the wp_handle_upload hook or that the filters add meta-data to the attachment, which otherwise would be missing in the wp_generate_attachment_metadata function.
Full function:
function add_to_media_lib($file_url, $file_path, $parent_post_id)
{
require_once(ABSPATH . 'wp-admin/includes/image.php');
require_once(ABSPATH . 'wp-admin/includes/file.php');
// Check the type of tile. We'll use this as the 'post_mime_type'.
$file_type = wp_check_filetype(basename($file_url), null);
// Get the path to the upload directory.
$wp_upload_dir = wp_upload_dir();
// Prepare an array of post data for the attachment.
$attachment = array(
'guid' => $wp_upload_dir['url'] . '/' . basename($file_url),
'post_mime_type' => $file_type['type'],
'post_title' => preg_replace('/\.[^.]+$/', '', basename($file_url)),
'post_content' => '',
'post_status' => 'inherit',
'post_parent' => $parent_post_id
);
// Insert the attachment.
$attach_id = wp_insert_attachment($attachment, $file_url, $parent_post_id);
// apply filters (important in some environments)
apply_filters('wp_handle_upload', array('file' => $file_path, 'url' => $file_url, 'type' => $file_type), 'upload');
// Generate the metadata for the attachment, and update the database record.
if ($attach_data = wp_generate_attachment_metadata($attach_id, $file_path)) {
wp_update_attachment_metadata($attach_id, $attach_data);
} else {
echo '<div id="message" class="error"><h1>Failed to create PDF-thumbnail Meta-Data</h1><pre>' . print_r($attach_data) . '</pre></div>';
}
return $attach_id;
}
I know the topic is old but I was facing a similar issue and what worked for me was enabling the Crop thumbnail to exact dimensions (normally thumbnails are proportional) under Settings >> Media. I am using the media_handle_sideload() function by the way.
I'm trying to create plugin importing posts to WordPress. Imported articles (XML) contain "image-name" attribute and this image is already uploaded to the server.
I would like to, however, make WordPress do its "magic" and import the image to the system (create thumbnails, attach it to the post, place it under the wp-uploads directory scheme)... I found function media_handle_upload($file_id, $post_id, $post_data, $overrides) but it requires array $_FILES to be filled with actual upload (and I'm not uploading file - it is already placed on the server) so it's not very useful
Do you have any hint how to proceed?
Thanks
Check the following script to get the idea. (It does work.)
$title = 'Title for the image';
$post_id = YOUR_POST_ID_HERE; // get it from return value of wp_insert_post
$image = $this->cache_image($YOUR_IMAGE_URL);
if($image) {
$attachment = array(
'guid' => $image['full_path'],
'post_type' => 'attachment',
'post_title' => $title,
'post_content' => '',
'post_parent' => $post_id,
'post_status' => 'publish',
'post_mime_type' => $image['type'],
'post_author' => 1
);
// Attach the image to post
$attach_id = wp_insert_attachment( $attachment, $image['full_path'], $post_id );
// update metadata
if ( !is_wp_error($attach_id) )
{
/** Admin Image API for metadata updating */
require_once(ABSPATH . '/wp-admin/includes/image.php');
wp_update_attachment_metadata
( $attach_id, wp_generate_attachment_metadata
( $attach_id, $image['full_path'] ) );
}
}
function cache_image($url) {
$contents = #file_get_contents($url);
$filename = basename($url);
$dir = wp_upload_dir();
$cache_path = $dir['path'];
$cache_url = $dir['url'];
$image['path'] = $cache_path;
$image['url'] = $cache_url;
$new_filename = wp_unique_filename( $cache_path, $filename );
if(is_writable($cache_path) && $contents)
{
file_put_contents($cache_path . '/' . $new_filename, $contents);
$image['type'] = $this->mime_type($cache_path . '/' . $new_filename); //where is function mime_type() ???
$image['filename'] = $new_filename;
$image['full_path'] = $cache_path . '/' . $new_filename;
$image['full_url'] = $cache_url . '/' . $new_filename;
return $image;
}
return false;
}