I have been using the following code to upload the first image on a page as the featured image.
function catch_that_image() {
global $post, $posts;
$first_img = '';
ob_start();
ob_end_clean();
$output = preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches);
$first_img = $matches [1] [0];
if(empty($first_img)){ //Defines a default image
$first_img = "/images/default.jpg";
}
return $first_img;
}
function save_first_image(){
global $post, $posts;
$first_image = catch_that_image();
$post_id = $post -> post_id;
$args = array('timeout' => '1200');
$get = wp_remote_get( $first_image,$args );
$type = wp_remote_retrieve_header( $get, 'content-type' );
$mirror = wp_upload_bits(rawurldecode(basename( $first_image )), '', wp_remote_retrieve_body( $get ) );
//Attachment options
$attachment = array(
'post_title'=> basename( $first_image ),
'post_mime_type' => $type
);
// Add the image to your media library and set as featured image
$attach_id = wp_insert_attachment( $attachment, $mirror['file'], $post_id );
$attach_data = wp_generate_attachment_metadata( $attach_id, $first_image );
wp_update_attachment_metadata( $attach_id, $attach_data );
set_post_thumbnail( $post_id, $attach_id );
}
It was working fine, but now seems to be always attaching a broken image.
Does anyone have experience of this - I am wondering if it is cloudflare causing the issue - but when I disable it, it is still uploading broken images.
All of the images are stored in a folder in the webroot of the site - is there a way to upload without using wp_remote_get?
Thanks
Hah, done it again - after hours of searching find the answer straight after posting here!!
function save_first_image(){
global $post, $posts;
$image_url = catch_that_image();
$post_id = $post -> 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 );
wp_update_attachment_metadata( $attach_id, $attach_data );
set_post_thumbnail( $post_id, $attach_id );
}
Related
I read a JSON feed in PHP from an external website. In this feed I have to pictures URI. I’m writing a wordpress plugin to create posts from this JSON feed but I would be able to download the pictures and save them inside my WordPress uploads folder.
Any idea how I can do this?
function to save the image:
function insert_attachment_from_url($url, $parent_post_id = null) {
if( !class_exists( 'WP_Http' ) )
include_once( ABSPATH . WPINC . '/class-http.php' );
$http = new WP_Http();
$response = $http->request( $url );
if( $response['response']['code'] != 200 ) {
return false;
}
$upload = wp_upload_bits( basename($url), null, $response['body'] );
if( !empty( $upload['error'] ) ) {
return false;
}
$file_path = $upload['file'];
$file_name = basename( $file_path );
$file_type = wp_check_filetype( $file_name, null );
$attachment_title = sanitize_file_name( pathinfo( $file_name, PATHINFO_FILENAME ) );
$wp_upload_dir = wp_upload_dir();
$post_info = array(
'guid' => $wp_upload_dir['url'] . '/' . $file_name,
'post_mime_type' => $file_type['type'],
'post_title' => $attachment_title,
'post_content' => '',
'post_status' => 'inherit',
);
$attach_id = wp_insert_attachment( $post_info, $file_path, $parent_post_id );
require_once( ABSPATH . 'wp-admin/includes/image.php' );
$attach_data = wp_generate_attachment_metadata( $attach_id, $file_path );
wp_update_attachment_metadata( $attach_id, $attach_data );
set_post_thumbnail( $parent_post_id, $attach_id );
return $attach_id;
}
and to run the function:
$image = 'YOUR_IMAGE_URL';
insert_attachment_from_url( $image );
I'm trying to upload image using wp custom template in child theme but when i upload any image. It appears in "E:\Xamp\htdocs\website\wp-content\uploads\2019\10" but not uploaded to wp dashboard media library.
I'M NOT ALLOWED TO USE ANY PLUGIN FOR THIS TASK.
$post_id = wp_insert_post($my_post);
if(isset($_FILES['file']['name'])){
if(! function_exists('wp_handle_upload')){
require_once(ABSPATH.'wp-admin/includes/file.php');
}
$uploadfile = $_FILES['file'];
print_r($uploadfile);
$upload_overrides = array('test_form' => false );
$moveupload = wp_handle_upload($uploadfile,$upload_overrides);
if($moveupload && ! isset($moveupload['error'])){
echo "</Pre";
wp_update_attachment_metadata( $post_id, $moveupload);
print_r($moveupload);
echo "Post/>";
}else{
echo $moveupload['error'];
}
}
Can try out another piece of code here:
--------------------------
$upload_overrides = array( "test_form" => false );
$uploaded_file = wp_handle_upload ($file, $upload_overrides);
if( isset( $uploaded_file ["file"] )) {
$file_name_and_location = $uploaded_file ["file"];
$file_title_for_media_library = $title;
$attachment = array(
"post_mime_type" => $uploaded_file_type,
"post_title" => addslashes( $file_title_for_media_library ),
"post_content" => "",
"post_status" => "inherit"
);
if( ! is_null( $post )) {
if ( ! is_numeric( $post )) {
$post = $post->ID;
} // if ()
$attachment ['post_parent'] = $post;
} // if ()
$id = wp_insert_attachment( $attachment, $file_name_and_location );
require_once( ABSPATH."wp-admin/includes/image.php" );
$attach_data = wp_generate_attachment_metadata( $id, $file_name_and_location );
wp_update_attachment_metadata( $id, $attach_data );
} // if ()
Uploading files into the wp-content/uploads won't show up in the Media Library , those media ID's needs to be there in the database to show up in the Media Library.
If you already have files in the uploads folder and want to add them into the database
But this is not the correct solution instead fix the permissions issue for that uploads folder.
Thanks
i solved it by using custom php code.
$upload = wp_upload_bits($_FILES["file"]["name"], null, file_get_contents($_FILES["file"]["tmp_name"]));
$filename = $upload['file'];
$wp_filetype = wp_check_filetype($filename, null );
// print_r($filename);
$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, $filename, $post_id );
require_once(ABSPATH . 'wp-admin/includes/image.php');
$attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
wp_update_attachment_metadata( $attach_id, $attach_data );
set_post_thumbnail( $post_id, $attach_id );
I had a non-finished version for setting a post thumbnail from a base64 encoded image (from an API) which i dind't use at the time but now i need it.
function attach_image ( $base64, $post_id, $filename ) {
if ( empty($base64) ) {
return false;
}
$upload_dir = wp_upload_dir();
$upload_path = str_replace( '/', DIRECTORY_SEPARATOR, $upload_dir['path'] ) . DIRECTORY_SEPARATOR;
$decoded = base64_decode($base64) ;
$hashed_filename = md5( $filename . microtime() ) . '_' . $filename;
$image_upload = file_put_contents( $upload_path . $hashed_filename, $decoded );
if( !function_exists( 'wp_handle_sideload' ) ) {
require_once( ABSPATH . 'wp-admin/includes/file.php' );
}
$wp_filetype = wp_check_filetype(basename($filename), null );
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment( $attachment, $hashed_filename, $parent_id );
$attach_data = wp_generate_attachment_metadata( $attach_id, $hashed_filename );
wp_update_attachment_metadata( $attach_id, $attach_data );
add_post_meta($post_id, '_thumbnail_id', $attach_id, true);
}
This almost work,
The images gets copied to the current wp-content/year/month folder
The image has the hash prepended in the name ( 0acaa00c73c27baa3277ff22ba5acf05_xk35480.jpg )
The image is set as the post thumbnail (for the $post_id )
But the problem is that,
If the image saved is:
wp-content/uploads/2019/09/0acaa00c73c27baa3277ff22ba5acf05_xk35480.jpg
The post thumnail url is:
wp-content/uploads/xk35480.jpg
Note that the year, month and hash are lost. So obviously the thumbnail url returns 404
So the question is, can you spot the problem?
I was able to make it work by prepending wp_upload_dir()['path'].'/' to the wp_insert_attachment and to the wp_generate_attachment_metadata functions but I wonder if it can be done "better"
function attach_image ( $base64, $post_id, $filename ) {
if ( empty($base64) ) {
return false;
}
$upload_dir = wp_upload_dir();
$upload_path = str_replace( '/', DIRECTORY_SEPARATOR, $upload_dir['path'] ) . DIRECTORY_SEPARATOR;
$decoded = base64_decode($base64) ;
$hashed_filename = md5( $filename . microtime() ) . '_' . $filename;
$image_upload = file_put_contents( $upload_path . $hashed_filename, $decoded );
if( !function_exists( 'wp_handle_sideload' ) ) {
require_once( ABSPATH . 'wp-admin/includes/file.php' );
}
$wp_filetype = wp_check_filetype(basename($filename), null );
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment( $attachment, wp_upload_dir()['path'].'/'.$hashed_filename, $post_id );
$attach_data = wp_generate_attachment_metadata( $attach_id, wp_upload_dir()['path'].'/'.$hashed_filename );
wp_update_attachment_metadata( $attach_id, $attach_data );
add_post_meta($post_id, '_thumbnail_id', $attach_id, true);
}
I'am using WP trying to download image from another servee and download, and then i wan to update featured image and my script here :
<?php
include_once ("../wp-load.php");
$post_id = 4376;
$image_url = "https://www.sepatuonline.co.id/wp-content/uploads/raindoz/RSR-006.jpg";
update_images($post_id, $image_url);
function update_images($post_id, $image_url) {
$image_name = 'wp-header-logo.png'; $upload_dir = wp_upload_dir();
$image_data = wp_remote_get($image_url);
$image_data = $image_data['body'];
$image_data = json_decode($image_data, true);
$unique_file_name = wp_unique_filename( $upload_dir['path'], $image_name );
$filename = basename( $unique_file_name );
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 );
wp_update_attachment_metadata( $attach_id, $attach_data );
set_post_thumbnail( $post_id, $attach_id );
}
But just return broken file, whats wrong ?
I'm developing a site in which a user is able to capture his/her pic(via .getusermedia) which updated as the post thumbnail.
The problem is that the post thumbnail gets updated for all users - I want the post thumbnail to be updated only for that particular user
function Generate_Featured_Image( $filename, $parent_post_id ){
require('/wp-load.php');
$filetype = wp_check_filetype( basename( $filename ), null );
$wp_upload_dir = wp_upload_dir();
$attachment = array(
'guid' => $wp_upload_dir['url'] . '/' . basename( $filename ),
'post_mime_type' => $filetype['type'],
'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment( $attachment, $filename, $parent_post_id );
require_once( ABSPATH . 'wp-admin/includes/image.php' );
$attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
wp_update_attachment_metadata( $attach_id, $attach_data );
//add_user_meta( $current_user_id, $parent_post_id, $attach_id);
set_post_thumbnail( $parent_post_id, $attach_id );
}
script.php
Generate_Featured_Image( $addroot.$current_user_id.$extimage, 88 );
// addroot=path ext-extension(.jpg) (this is name of file saved)
i tried to user add_user_meta to accomplish the task but couldn't even get a start
UPDATE
<?php
// $filename is succesfully saved as currentuserid+.jpg.
$addroot = '/wp-content/uploads/2016/09/';
$current_user_id = get_current_user_id();
$extimage = '.jpg';
$filename = $addroot.$current_user_id.$extimage;
$filetype = wp_check_filetype( basename( $filename ), 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( $filename ),
'post_mime_type' => $filetype['type'],
'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
'post_content' => '',
'post_status' => 'inherit'
);
// Insert the attachment.
$attach_id = wp_insert_attachment( $attachment, $filename, 0 );
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, $filename );
wp_update_attachment_metadata( $attach_id, $attach_data );
update_user_meta( get_the_ID(), $filename , $_POST[ $filename ] );
?>
how to proceed further by calling the image to by $attach_id from usermeta and displayinf it to user as thumbnail- unable to figure this step
You can't really set a different featured image for post based on a user. There is just one post, therefore only one featured image for it.
If you want to display a different image, based on which user is viewing the post, save that use wp_insert_attachment( $attachment, $filename, 0) to insert attachment without binding it to the post. Then save that $attach_id to the usermeta table. Then, when user is viewing that post, simply get $attach_id with get_user_meta and display that image (you can use wp_get_attachment_url for example) instead of featured image of the post.
UPDATE
First, saving user meta should look like this
update_user_meta($current_user_id, '_avatar_id', $attach_id);
Second, in the beginning, you should check if user is logged in with is_user_logged_in function.
Third, you should check for user had avatar before and remove it (I mean, why store their old one after they have a new one, right?) like so:
$old_attach=get_user_meta($current_user_id, '_avatar_id', true);
if(is_numeric($old_attach))
{
wp_delete_attachment($old_attach, true);
}
Your final code to save avatar should look like:
if (is_user_logged_in())
{
$addroot = '/wp-content/uploads/2016/09/';
$current_user_id = get_current_user_id();
$extimage = '.jpg';
$filename = $addroot . $current_user_id . $extimage;
$filetype = wp_check_filetype(basename($filename), null);
$wp_upload_dir = wp_upload_dir();
$attachment = array(
'guid' => $wp_upload_dir['url'] . '/' . basename($filename),
'post_mime_type' => $filetype['type'],
'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment($attachment, $filename, 0);
require_once( ABSPATH . 'wp-admin/includes/image.php' );
wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $filename));
$old_attach = get_user_meta($current_user_id, '_avatar_id', true);
if (is_numeric($old_attach))
{
wp_delete_attachment($old_attach, true);
}
update_user_meta($current_user_id, '_avatar_id', $attach_id);
}
else
{
//show error here or something
}
Now, to access it, you can write a simple function, like this:
function get_user_avatar()
{
if (is_user_logged_in())
{
$avatar_id = get_user_meta(get_current_user_id(), '_avatar_id', true);
if (is_numeric($avatar_id))
{
return'<img src="' . wp_get_attachment_url($avatar_id) . '" alt="User avatar"/>';
}
else
{
return '<img src="url_to_your_default_avatar" alt="User avatar"/>';
}
}
return false;
}