PHP - Download and set featured image wordpress post - php

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 ?

Related

How to save a picture from URI given in a JSON feed

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 );

Setting the post thumbnail from code fails

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);
}

add user meta for featured image

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;
}

wrong with wp_generate_attachment_metadata()

It works (upload , send to db) but
wp_generate_attachment_metadata() returns bad letters whene file uploaded !
some of the wrong charechters :
����JFIF��;CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 90 ��C ��C ����"�� ���}!1AQa"q2���#B��R��$3br� %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz��������������������������������������������������������������������������� ���w!1AQaq"2�B���� #3R�br� $4�
the code :
if (isset($_FILES['ed_header_logo'] ) && !empty($_FILES['ed_header_logo']['name']) )
{
$filename = $_FILES['ed_header_logo']['name'];
$wp_filetype = wp_check_filetype( basename($filename), null );
$wp_upload_dir = wp_upload_dir();
move_uploaded_file( $_FILES['ed_header_logo']['tmp_name'], $wp_upload_dir['path'] . '/' . $filename );
$url = $wp_upload_dir['url'] . '/' . basename( $filename );
$attachment = array(
'guid' => $url,
'post_mime_type' => $wp_filetype['type'],
'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
'post_content' => 'weblogo',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment( $attachment, $url, 37 );
require_once( ABSPATH . 'wp-admin/includes/image.php' );
$attach_data = wp_generate_attachment_metadata( $attach_id, $url );
wp_update_attachment_metadata( $attach_id, $attach_data );
}
try this:
if (isset($_FILES['ed_header_logo'] ) && !empty($_FILES['ed_header_logo']['name']) )
{
$uploadedfile = $_FILES['ed_header_logo'];
$upload_name = $_FILES['ed_header_logoe']['name'];
$uploads = wp_upload_dir();
$filepath = $uploads['path']."/$upload_name";
if ( ! function_exists( 'wp_handle_upload' ) )
{
require_once( ABSPATH . 'wp-admin/includes/file.php' );
}
require_once( ABSPATH . 'wp-admin/includes/image.php' );
$upload_overrides = array( 'test_form' => false );
//$attach_id = media_handle_upload( $file, $new_post );
$movefile = wp_handle_upload( $uploadedfile, $upload_overrides );
//print_r($movefile);
if ( $movefile && !isset( $movefile['error'] ) ) {
$file = $movefile['file'];
$url = $movefile['url'];
$type = $movefile['type'];
//media_handle_upload( $file_handler, 0 );
$attachment = array(
'post_mime_type' => $type ,
'post_title' => $upload_name,
'post_content' => 'Image for '.$upload_name,
'post_status' => 'inherit'
);
$attach_id=wp_insert_attachment( $attachment, $file, 0);
$attach_data = wp_generate_attachment_metadata( $attach_id, $file );
wp_update_attachment_metadata( $attach_id, $attach_data );
}

wp_remote_get alternative using local files?

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 );
}

Categories