Actual file location of a WordPress featured image? - php

I'm generating a query for certain posts in 'Trash'. I can retrieve the featured image URL, but I'm looking for a way to get the featured image file location on the server.
# generate the query
foreach ( $query as $post ) {
$thumbID = get_post_thumbnail_id( $post->ID );
$thumbObj = get_post( $thumbID );
$source_url = $thumbObj->guid;
# how do I get the string "/path/to/wordpress/media/library/thumbnail.jpg" ?
}
I can't find any WordPress function that returns the actual featured image file location.

$post_thumbnail_id = get_post_thumbnail_id($post->ID);
var_dump(get_attached_file($post_thumbnail_id));

There is no wp function but its easy enough to make your own, e.g.
function return_image_path($thumbID) {
$image= wp_get_attachment_image_src($thumbID);
$imagepath= str_replace(get_site_url(), $_SERVER['DOCUMENT_ROOT'], $image[0]);
if($imagepath) return $imagepath;
return false;
}

Expanding on David's answer, this worked for me:
function return_image_path($thumbID) {
$thumbID = get_post_thumbnail_id( $post->ID );
$image= wp_get_attachment_image_src($thumbID);
$upload_dir = wp_upload_dir();
$base_dir = $upload_dir['basedir'];
$base_url = $upload_dir['baseurl'];
$imagepath= str_replace($base_url, $base_dir, $image[0]);
if ( file_exists( $imagepath) ) return $imagepath;
return false;
}

Related

Renaming attachment files to the post title it's being added to in Wordpress

Like the title says, I am trying to rename media gallery uploads to the title of the initial post the file is being added to.
I found the following function and modified it to change the filename to the file's author slug
// file renamer (used for EDL images)
function file_renamer( $filename ) {
$info = pathinfo( $filename );
$ext = empty( $info['extension'] ) ? '' : '.' . $info['extension'];
$name = basename( $filename, $ext );
global $current_user;
get_currentuserinfo();
return $current_user->user_login . $ext;
}
However- that wasn't good enough for the client. I haven't found any solutions to this yet online. Any help would be greatly appreciated!
Edit - Just want to add that I am using advanced custom fields for this as well. Here is the rest of the code for this process, which directs specific custom field images to a certain directory-
// EDL uploaded images will go to the /edl directory in uploads for these fields.
add_filter('acf/upload_prefilter/name=edl_dealer_logo', 'field_name_upload_prefilter');
add_filter('acf/upload_prefilter/name=edl_image', 'field_name_upload_prefilter');
add_filter('acf/upload_prefilter/name=edl_gallery_image', 'field_name_upload_prefilter');
function field_name_upload_prefilter($file) {
// in this filter we add a WP filter that alters the upload path
add_filter( 'sanitize_file_name', 'file_renamer', 10 );
add_filter('upload_dir', 'field_name_upload_dir');
return $file;
}
// second filter
function field_name_upload_dir($uploads) {
$mydir = '/edl';
// here is where we later the path
$uploads['path'] = $uploads['basedir'].$mydir;
$uploads['url'] = $uploads['baseurl'].$mydir;
$uploads['subdir'] = '/edl';
return $uploads;
}
I suppose you might be able look at $_POST["post_ID"], use WP's get_post() and then if a post has been found, call get $post->post_title for the filename.
Or does ACF upload those asynchronously via Ajax? In any case, the post ID should be transmitted when uploading I believe, but you might have to look at your browser's developer tools to find out what the field name is.
The following works in my install. Be advised that this would run for all file uploads, so you might want to add some precautions.
function file_renamer( $filename ) {
$info = pathinfo( $filename );
$ext = empty( $info['extension'] ) ? '' : '.' . $info['extension'];
$name = basename( $filename, $ext );
if( $post_id = array_key_exists("post_id", $_POST) ? $_POST["post_id"] : null) {
if($post = get_post($post_id)) {
return $post->post_title . $ext;
}
}
get_currentuserinfo();
return $current_user->user_login . $ext;
}
add_filter( 'sanitize_file_name', 'file_renamer', 10, 1 );

How to set featured image programmatically from url?

I have some post id's and I want to set these posts' featured images from same url.
Here is my adding post codes:
$catid = get_cat_ID("XX Cat");
$my_post = array();
$my_post['post_title'] = $title;
$my_post['post_content'] = $description;
$my_post['post_status'] = 'publish';
$my_post['post_author'] = 1;
$my_post['post_category'] = array( $catid );
$post_id = wp_insert_post( $my_post );
Example: post_id = 1 I want to set featured image to: example.com/image.png
How can I do this?
You can set an image as post featured thumbnail when it is in your media library. To add an image in your media library you need to upload it to your server.
try this code:
// Add Featured Image to Post
$image_url = 'http://s.wordpress.org/style/images/wp-header-logo.png'; // Define the image URL here
$image_name = 'wp-header-logo.png';
$upload_dir = wp_upload_dir(); // Set upload folder
$image_data = file_get_contents($image_url); // Get image data
$unique_file_name = wp_unique_filename( $upload_dir['path'], $image_name ); // Generate unique name
$filename = basename( $unique_file_name ); // Create image file name
// Check folder permission and define file location
if( wp_mkdir_p( $upload_dir['path'] ) ) {
$file = $upload_dir['path'] . '/' . $filename;
} else {
$file = $upload_dir['basedir'] . '/' . $filename;
}
// Create the image file on the server
file_put_contents( $file, $image_data );
// Check image file type
$wp_filetype = wp_check_filetype( $filename, null );
// Set attachment data
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => sanitize_file_name( $filename ),
'post_content' => '',
'post_status' => 'inherit'
);
// Create the attachment
$attach_id = wp_insert_attachment( $attachment, $file, $post_id );
// Include image.php
require_once(ABSPATH . 'wp-admin/includes/image.php');
// Define attachment metadata
$attach_data = wp_generate_attachment_metadata( $attach_id, $file );
// Assign metadata to attachment
wp_update_attachment_metadata( $attach_id, $attach_data );
// And finally assign featured image to post
set_post_thumbnail( $post_id, $attach_id );
ref url : http://www.wpexplorer.com/wordpress-featured-image-url/
Modified as your requirement:
or that purpose ignore WordPress standard and upload your all post single image on your custom folder and add this image path or direct external image url into post as extra attribute meta field and when you will show post on your theme then just use your img with help of post id.
demo code:
for setting image
<?php
update_post_meta ( 7, 'imgkey', 'www.url.path' );//7 is post id
?>
for getting image on your theme page where you want to show it
<?php
$img_value = get_post_meta( get_the_ID(), 'imgkey', true );
?>
<img src="<?php echo $img_value?>">
Note if you are new in WordPress post custom meta fields then read this article:
https://codex.wordpress.org/Custom_Fields
or
unofficial article about custom fields: https://premium.wpmudev.org/blog/creating-custom-fields-manually
if you have to load an image and then assign as thumbnail of the post, the quicker way is to use media_sideload_image and then set_post_thumbnail
https://developer.wordpress.org/reference/functions/media_sideload_image/
$url = "http://url-of-the-image.jpg";
$post_id = [post id]
$desc = "image description";
$image = media_sideload_image( $url, $post_id, $desc,'id' );
set_post_thumbnail( $post_id, $image );
Just to complement #Naraj answer, if you are working in an external file, remember to add:
require_once(ABSPATH . 'wp-admin/includes/media.php');
require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/image.php');
if you do not add that you will get an error message saying that media_sideload_image is undefined.

Wordpress - Hook don't fire until update post manually from backend

I'm trying to run a function that prints watermark on image when a new post is creates from a plugin that generates a new post and associates an uploaded photo as featured image.
Function works well only if i manually update/create posts from back-end and not working when posts is create from front-end.
here my code on functions.php:
// stampa watermark
function stampa_watermark () {
$slug = 'foto';
$post_id = get_the_ID();
$post_type = get_post_type($post_id);
$attachment_id = get_post_thumbnail_id( $post_id, 'full' );
$image_size = 'full';
$filepath = get_attached_file( $attachment_id );
$upload_dir = wp_upload_dir();
if ( $slug != $post_type ) {
return;
}
else {
$IW = new Image_Watermark;
$IW->do_watermark( $attachment_id, $filepath, $image_size, $upload_dir );
}
}
add_action( 'updated_postmeta', 'stampa_watermark' );
add_action( 'save_post', 'stampa_watermark' );
// fine

Copy a Wordpress featured image over multisite

I have the following function to copy across a post as it's created on one site, to then move it over to a specific multisite blog:
function copy_across_to_multisite( $post_id ) {
// If this is just a revision, don't send the email.
if ( wp_is_post_revision( $post_id ) )
return $post_id;
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return $post_id;
if ($post_id && get_current_blog_id() == 1) {
$post = get_post($post_id, ARRAY_A); // get the original post
if ($post->post_status == 'trash' || $post->post_status == 'auto-draft') {
return $post_id;
}
$meta = get_post_meta($post_id);
$post_thumbnail_id = get_post_thumbnail_id($post_id);
$post_thumbnail = get_post($post_thumbnail_id, ARRAY_A);
$post['ID'] = ''; // empty id field, to tell wordpress that this will be a new post
$post_thumbnail['ID'] = '';
switch_to_blog(2); // switch to target blog
$inserted_post_id = wp_insert_post($post); // insert the post
$inserted_thumbnail = wp_insert_post($post_thumbnail);
foreach($meta as $key=>$value) {
update_post_meta($inserted_post_id,$key,$value[0]);
}
set_post_thumbnail($inserted_post_id, $inserted_thumbnail);
restore_current_blog(); // return to original blog
}
}
add_action( 'save_post', 'copy_across_to_multisite' );
This works great, but it doesn't bring across the featured image; I'm assuming because I need to also move the featured image into the upload folder for that multisite? The image does come across in the media library (albeit with no thumbnail and linking back to the other site - which I don't mind) but doesn't 'attach' onto the post and show up as a featured image.
Can anyone help out with this? Has anyone done anything similar? Thanks
Well, finally managed to (pretty much) cobble together a solution.
So in case anyone needs a similar function, it will take a little tweaking depending on your situation (changing the number in the switch_to_blog function as needed).
function copy_across_to_multisite( $post_id ) {
// If this is just a revision, don't send the email.
if ( wp_is_post_revision( $post_id ) )
return $post_id;
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return $post_id;
if ($post_id && get_current_blog_id() == 1) {
$post = get_post($post_id, ARRAY_A); // get the original post
if ($post->post_status['trash'] || $post['post_status'] == 'auto-draft') {
return $post_id;
}
$meta = get_post_meta($post_id);
$post_thumbnail_id = get_post_thumbnail_id($post_id);
$image_url = wp_get_attachment_image_src($post_thumbnail_id, 'full');
$image_url = $image_url[0];
$post['ID'] = ''; // empty id field, to tell wordpress that this will be a new post
switch_to_blog(2); // switch to target blog
$inserted_post_id = wp_insert_post($post); // insert the post
foreach($meta as $key=>$value) {
update_post_meta($inserted_post_id,$key,$value[0]);
}
// Add Featured Image to Post
$upload_dir = wp_upload_dir(); // Set upload folder
$image_data = file_get_contents($image_url); // Get image data
$filename = basename($image_url); // Create image file name
// Check folder permission and define file location
if( wp_mkdir_p( $upload_dir['path'] ) ) {
$file = $upload_dir['path'] . '/' . $filename;
} else {
$file = $upload_dir['basedir'] . '/' . $filename;
}
// Create the image file on the server
file_put_contents( $file, $image_data );
// Check image file type
$wp_filetype = wp_check_filetype( $filename, null );
// Set attachment data
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => sanitize_file_name( $filename ),
'post_content' => '',
'post_status' => 'inherit'
);
// Create the attachment
$attach_id = wp_insert_attachment( $attachment, $file, $post_id );
// Include image.php
require_once(ABSPATH . 'wp-admin/includes/image.php');
// Define attachment metadata
$attach_data = wp_generate_attachment_metadata( $attach_id, $file );
// Assign metadata to attachment
wp_update_attachment_metadata( $attach_id, $attach_data );
// And finally assign featured image to post
set_post_thumbnail( $inserted_post_id, $attach_id );
restore_current_blog(); // return to original blog
}
}
add_action( 'save_post', 'copy_across_to_multisite' );

WordPress Featured Image | All Post Slugs Matching Image File Name

I have a bunch of old posts on a blog that I would like to assign a featured image to.
I have retrieved all the images I would like to use for each post.
I saved each image file name after the slug of each post.
I would like to retrieve all posts, grab the slug name from each post, search the specified directory where the image files are uploaded, when the post slug matches the image file name, set that image as the featured image for that particular post, and iterate through all posts.
I am not sure how to go about doing this, but I have provided some example code I found, along with a few useful (hopefully) links.
The following code is used to retrieve all posts and update a particular post:
$allPosts = get_posts(array('numberposts' => -1, 'post_type' => 'post'));
foreach($allPosts as $thePost){
$my_post = array();
$my_post['post_type'] = $thePost->post_type;
$my_post['ID'] = $thePost->ID;
$my_post['post_name'] = autoSlug($thePost->post_title);
wp_update_post($my_post);
}
Note: I have a special function for generating post slugs based off the post_title. (I don't use the WP default slug.)
Useful links:
http://codex.wordpress.org/Template_Tags/get_posts
http://codex.wordpress.org/Function_Reference/wp_update_post
http://codex.wordpress.org/Post_Thumbnails
http://codex.wordpress.org/Function_Reference/wp_upload_dir
http://codex.wordpress.org/Function_Reference/wp_insert_attachment
Wrote a script myself, along with a blog post. Contributions for improvements are appreciated. Refer to this link for answer Set WordPress Featured Image For All Post Slugs Matching Image File Name in Specified Directory:
<?php
// Get All Posts.
$allPosts = get_posts(array('numberposts' => -1, 'post_type' => 'post'));
// Specify where the images are located.
$themePATH = get_theme_root().'/'.get_template().'/thumbs/';
// The uploads directory for your blog.
$uploads= wp_upload_dir();
// List of images including extensions.
$images = listImages($themePATH,true);
// List of images without extensions.
$imageNames = listImages($themePATH,false);
function reverseSlug($string){
$string = str_replace("-", " ", $string);// Convert hyphen to space
$string = ucwords($string);// Capitalize the beginning of each word
return $string;
}
// Retrieve all images from the specified directory.
// Output array with and without file extensions.
function listImages($dirname=".",$display) {
$ext = array("jpg", "png", "jpeg", "gif");
$files = array();
if($handle = opendir($dirname)){
while(false !== ($file = readdir($handle))){
for($i=0;$i<sizeof($ext);$i++){
if(strstr($file, ".".$ext[$i])){
$files[] = $file;
}
}
}
closedir($handle);
}
sort($files);
foreach($files as $theFile){
$info = pathinfo($theFile);
$fileName = basename($theFile,'.'.$info['extension']);
$files1[] = $fileName;
}
if($display == false){
return ($files1);
}
if($display == true){
return($files);
}
}
for($i = 0; $i < count($allPosts); $i++){
// Check if post slugs match image slugs.
$check[$i] = in_array($allPosts[$i]->post_name, $imageNames);
if($check[$i] == 1){
echo 'Yes, post title matches image name.<br />'.PHP_EOL;
// Search through the image slugs for a direct match with the post slug.
$search[$i] = array_search($allPosts[$i]->post_name, $imageNames);
$filename = $images[$search[$i]];
$newfile = $uploads['path'].'/'.$filename;
// Copy the image from theme folder to uploads directory.
copy($themePATH.$filename, $newfile);
// Delete image from theme folder.
unlink($themePATH.$filename);
// Retrieve the file type from the file name.
$wp_filetype = wp_check_filetype(basename($filename), null);
// Construct the attachment array.
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'guid' => $uploads['url'].'/'.$filename,
'post_title' => preg_replace('/\.[^.]+$/', '', reverseSlug(basename($filename))),
'post_content' => '',
'post_status' => 'inherit'
);
// This function inserts an attachment into the media library.
$attach_id = wp_insert_attachment($attachment, $newfile, $allPosts[$i]->ID);
// You must first include the image.php file
// For the function wp_generate_attachment_metadata() to work.
require_once(ABSPATH . 'wp-admin/includes/image.php');
// This function generates metadata for an image attachment.
// It also creates a thumbnail and other intermediate sizes
// of the image attachment based on the sizes defined on
// the Settings_Media_Screen.
$attach_data = wp_generate_attachment_metadata($attach_id, $newfile);
if(!is_wp_error($attach_id)){
// Update metadata for an attachment.
wp_update_attachment_metadata($attach_id, $attach_data);
// Updates the value of an existing meta key (custom field) for the specified post.
update_post_meta($allPosts[$i]->ID, '_thumbnail_id', $attach_id);
}
}
else{
echo 'No matches found.<br />'.PHP_EOL;
}
}
?>
you save my life, your code just needs some adjustments and works like a charm. here it is.
<?php
// Get All Posts.
$allPosts = get_posts(array('numberposts' => -1, 'post_type' => 'wpdmpro'));
// Specify where the images are located.
$themePATH = get_theme_root().'/'.get_stylesheet().'/thumbs/';
// The uploads directory for your blog.
$uploads= wp_upload_dir();
// List of images including extensions.
$images = listImages($themePATH,true);
// List of images without extensions.
$imageNames = listImages($themePATH,false);
function reverseSlug($string){
$string = str_replace("-", " ", $string);// Convert hyphen to space
$string = ucwords($string);// Capitalize the beginning of each word
return $string;
}
// Retrieve all images from the specified directory.
// Output array with and without file extensions.
function listImages($dirname=".",$display) {
$ext = array("jpg", "png", "jpeg", "gif");
$files = array();
if($handle = opendir($dirname)){
while(false !== ($file = readdir($handle))){
for($i=0;$i<sizeof($ext);$i++){
if(strstr($file, ".".$ext[$i])){
$files[] = $file;
}
}
}
closedir($handle);
}
sort($files);
foreach($files as $theFile){
$info = pathinfo($theFile);
$fileName = basename($theFile,'.'.$info['extension']);
$files1[] = $fileName;
}
if($display == false){
return ($files1);
}
if($display == true){
return($files);
}
}
for($i = 0; $i < count($allPosts); $i++){
// Check if post slugs match image slugs.
if (is_array($imageNames)) {
$check[$i] = in_array($allPosts[$i]->post_name, $imageNames);
} else {
echo 'error';
};
if($check[$i] == 1){
echo 'Yes, post title matches image name.<br />'.PHP_EOL;
// Search through the image slugs for a direct match with the post slug.
$search[$i] = array_search($allPosts[$i]->post_name, $imageNames);
$filename = $images[$search[$i]];
$newfile = $uploads['path'].'/'.$filename;
// Copy the image from theme folder to uploads directory.
copy($themePATH.$filename, $newfile);
// Delete image from theme folder.
unlink($themePATH.$filename);
// Retrieve the file type from the file name.
$wp_filetype = wp_check_filetype(basename($filename), null);
// Construct the attachment array.
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'guid' => $uploads['url'].'/'.$filename,
'post_title' => preg_replace('/\.[^.]+$/', '', reverseSlug(basename($filename))),
'post_content' => '',
'post_status' => 'inherit'
);
// This function inserts an attachment into the media library.
$attach_id = wp_insert_attachment($attachment, $newfile, $allPosts[$i]->ID);
// You must first include the image.php file
// For the function wp_generate_attachment_metadata() to work.
require_once(ABSPATH . 'wp-admin/includes/image.php');
// This function generates metadata for an image attachment.
// It also creates a thumbnail and other intermediate sizes
// of the image attachment based on the sizes defined on
// the Settings_Media_Screen.
$attach_data = wp_generate_attachment_metadata($attach_id, $newfile);
if(!is_wp_error($attach_id)){
// Update metadata for an attachment.
wp_update_attachment_metadata($attach_id, $attach_data);
// Updates the value of an existing meta key (custom field) for the specified post.
update_post_meta($allPosts[$i]->ID, '_thumbnail_id', $attach_id);
}
}
else{
echo 'No matches found.<br />'.PHP_EOL;
}
}
?>

Categories