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;
}
}
?>
Related
Struggling to upload image to media library from form, I don't think I'm fully understanding the function. With my current code I'm successfully uploading file with file name, file type and author, but the file size and the file itself (the content) is not uploaded.
Current code:
if (isset($_POST['settings-submit'])) {
$file = $_FILES['settings-upload-image'];
$file_name = sanitize_file_name($file['name']);
$file_type = $file['type'];
$args = array(
'guid' => $file['url'], // just realized that this doesn't even exist in my array
'post_title' => $file_name,
'post_mime_type' => $file_type,
);
wp_insert_attachment($args, $file_name);
}
Ignoring validation for now. Possibly I'm not even using the right function?
Try to remove everything after line $file_type = $file['type']; and put this code instead:
// first checking if tmp_name is not empty
if (!empty($file['tmp_name'])) {
// if not, then try creating a file on disk
$upload = wp_upload_bits($file_name, null, file_get_contents($file['tmp_name']));
// if wp does not return a file creation error
if ($upload['error'] === false) {
// then you can create an attachment
$attachment = array(
'post_mime_type' => $upload['type'],
'post_title' => $file_name,
'post_content' => '',
'post_status' => 'inherit'
);
// creating an attachment in db and saving its ID to a variable
$attach_id = wp_insert_attachment($attachment, $upload['file']);
// generation of attachment metadata
$attach_data = wp_generate_attachment_metadata($attach_id, $upload['file']);
// attaching metadata and creating a thumbnail
wp_update_attachment_metadata($attach_id, $attach_data);
}
}
I think this code should easily create a file in the uploads folder and be visible in the media library. I wrote something similar when I was doing an integration with an external site in wordpress and it works for me without any problem.
I'm trying to scrape some JSON data (that part works fine), but when I try and add the featured image, (a blank icon appears in the media library, with correct filename, but the url field says 'false' & I get this error:-
Notice: Trying to get property 'feeds' of non-object in
/Users/macbook/Documents/www/news_test/wp-includes/post.php on line
4482
Fatal error: Uncaught Error: Call to a member function
using_permalinks() on null in
/Users/macbook/Documents/www/news_test/wp-includes/link-template.php:423
Stack trace: #0
/Users/macbook/Documents/www/news_test/wp-includes/link-template.php(147):
get_attachment_link(Object(WP_Post), false) #1
/Users/macbook/Documents/www/news_test/wp-includes/post.php(4105):
get_permalink(Object(WP_Post)) #2
/Users/macbook/Documents/www/news_test/wp-includes/post.php(5740):
wp_insert_post(Array, false) #3
/Users/macbook/Documents/www/news_test/wp-content/plugins/code-snippets/php/snippet-ops.php(446)
: eval()'d code(92): wp_insert_attachment(Array, '/Users/macbook/...',
293) #4
/Users/macbook/Documents/www/news_test/wp-content/plugins/code-snippets/php/snippet-ops.php(446):
eval() #5
/Users/macbook/Documents/www/news_test/wp-content/plugins/code-snippets/php/snippet-ops.php(534):
execute_snippet('ini_set('displa...', 6) #6
/Users/macbook/Documents/www/news_test/wp-includes/class-wp-hook.php(287):
execute_active_snippets('') #7 /Users/ma in
/Users/macbook/Documents/www/news_test/wp-includes/link-template.php
on line 423 There has been a critical error on your website. Please
check your site admin email inbox for instructions.
Here's the code:
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
global $wpdb;
$json = "http://newsapi.org/v2/top-headlines?country=ie&apiKey=**************";
$response = file_get_contents($json);
$mydecode = json_decode($response, true);
$mydecode = $mydecode['articles'];
// error_log(printf($mydecode));
foreach ($mydecode as $key => $value) {
$title = str_replace("&", "&", $value['title']);
$content = str_replace("&", "&", $value['content']);
//error_log("LOG: " . $title[0]);
// $description = str_replace("&", "&", $mydecode.articles->description);
// $article_url = $mydecode.articles->url;
$image_url = $value['urlToImage'];
// $content = $mydecode.content;
// Insert post
$new_post = array(
'post_title' => $title,
'post_content' => $content,
'post_status' => 'draft',
'post_author' => 1,
'post_category' => array(2),
'post_type' => 'post'
);
// Insert post
$post_id = wp_insert_post($new_post);
// Insert post meta if available
// add_post_meta( $post_id, 'meta_key', 'meta_value' );
// Add Featured Image to Post
// Add Featured Image to Post
// $image_url = $urlToImage; // Define the image URL here
//now to try and get actual image name
$headers = wp_get_http_headers( $image_url );
$mime_type = $headers['content-type'];
$ext = '';
foreach ( wp_get_mime_types() as $exts => $mime ) {
if ( $mime == $mime_type ) {
$ext = $exts;
break;
}
}
//now to apply extension if it didn't have one
if( $ext ){
$exts = explode('|', $ext);
$ext = '.'.$exts[0];
}
$image_name = 'image';
$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 . $ext ); // Generate unique name
$filename = basename( $unique_file_name ); // Create image file name
error_log("Filenames: ".$filename);
// 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;
}
error_log("file: ".$file);
// Create the image file on the server
file_put_contents( $file, $image_data );
// Check image file type
$wp_filetype = $exts[0];
// Set attachment data
$attachment = array(
'post_mime_type' => $wp_filetype,
'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 );
}
I'm working on WordPress 5.5, and using the snippets plugin to execute the code.
tl;dr
This is happening because you are calling wp_update_post too early in WordPress lifecycle. Hook your update logic to init and you will be fine.
Long story
This warning is coming from WordPress trying to find a pretty slug for the post, but being unable to do so because the Permalink logic has not loaded yet.
The warning comes from this line: https://github.com/WordPress/WordPress/blob/master/wp-includes/post.php#L4776
As you can see, the $wp_permalink global is populated kinda late in the lifecycle, AFTER plugins_loaded and before init: https://github.com/WordPress/WordPress/blob/master/wp-settings.php#L473-L479
So if you call wp_update_post on a plugin without a hook, the permalink global will not be populated yet.
So you should change your code flow to make sure it only runs wp_update_post after init has fired.
Good evening. I've written a function to programmatically insert a Wordpress post for each of our YouTube videos, using a foreach loop.
Everything is working wonderfully, until I get to inserting the post thumbnail. I am using a function that automatically handles the uploading and inserting of a thumbnail, and associating it with a post (below):
function Generate_Featured_Image($image_url, $post_id) {
$upload_dir = wp_upload_dir();
$image_data = file_get_contents($image_url);
$filename = basename($post_id.'-'.$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 );
}
This function does work, but for some odd reason, it only uploads the image from the last video in the loop. For example, if I have 5 videos, 5 posts will be created. Each containing it's own specific information, but the post thumbnail will all be the image from the last (5th) video. None of them have their own thumbnail.
Here's a slimmed down verson of my function that creates the posts:
function createYouTubePost() {
...some other code...
$JSON = file_get_contents('https://www.googleapis.com/youtube/v3/search?order='.$api_order.'&part='.$api_part.'&channelId='.$channel_id.'&maxResults='.$max_results.'&key='.$api_key);
$json_data = json_decode($JSON, true);
foreach ($json_data['items'] as $data) {
$video_id = $data['id']['videoId'];
$video_title = $data['snippet']['title'];
$video_description = $data['snippet']['description'];
$video_thumb_url = $data['snippet']['thumbnails']['high']['url'];
$video_thumb_width = $data['snippet']['thumbnails']['high']['width'];
$video_thumb_height = $data['snippet']['thumbnails']['high']['height'];
$video_publish_date = $data['snippet']['publishedAt'];
$args = array(
'post_title' => substr($video_title, 0, strrpos($video_title, '(')),
'post_content' => $video_description,
'post_status' => 'publish',
'post_type' => 'download',
);
if (!if_download_exists(substr($video_title, 0, strrpos($video_title, '(')))) {
$new_post_id = wp_insert_post($args, true);
if ($new_post_id == 0) {
echo '<br>Could not create the post.';
var_dump($new_post_id);
}
else {
Generate_Featured_Image($video_thumb_url, $new_post_id);
...lots of code to update various post_meta fields...
echo '<br>New post created.<br>';
var_dump($new_post_id);
}
}
}
}
Here you can see the media attachments and how they're all the same:
And here are the individual posts that were created:
As you can see, each image is assigned to it's respective post, but the image is the same.
I have even tried setting the filename of each picture with a unique ID so that they're all different, but that didnt help. I have also confirmed that the image url's that I am passing to the function are all different.
My question is, if I am using my function Generate_Featured_Image() in a foreach loop, and provding it with unique information, why is it only using the last picture in the loop?
Thanks for any help!
I went with another solution. Wordpress' media_sideload_image() function works and is a more straight forward solution for my situation.
Here is the function that I'm now using to assign a thumbnail to a post:
function generateFeaturedImage($image_url, $post_id) {
// required libraries for media_sideload_image
require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/media.php');
require_once(ABSPATH . 'wp-admin/includes/image.php');
// $post_id == the post you want the image to be attached to
// $video_thumb_url == the vimeo video's thumb url
// $description == optional description
// load the image
$result = media_sideload_image($image_url, $post_id);
// then find the last image added to the post attachments
$attachments = get_posts(array('numberposts' => '1', 'post_parent' => $post_id, 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC'));
if (sizeof($attachments) > 0) {
// set image as the post thumbnail
set_post_thumbnail($post_id, $attachments[0]->ID);
}
}
Here's the link to the stack exchange solution that I found.
I am trying to make an image gallery system with keywords.
Each image has a .php file with a few variables:
$keywords = 'Keywords that describe the image';
$src = 'directory path leading to the image';
$other = 'any specific remarks about the image';
the files of each image are stored in a directory called imageinfo.
How can I get all the images listed in the files in the directory imageinfo to display in one .phpfile? They all have the same variable names. Can I make a search engine system to search the files?
This is very hard to explain, and I understand if you don't understand - feel free to grab a diet coke and come and write your problems in the comments!
Try this:
(you have to fille the right imageinfo folder in)
<?php
// Folder with all the Info PHP files
$infodir = __DIR__ .'/imageinfo/';
// read Folder contens
$files = scandir( $infodir );
// Array to store all image infos
$allimages = array();
// loop, file for file
foreach ($files as $file) {
// . and .. are in the array of files, but we don't need them
if( $file != '..' && $file != '.' ){
//path to actual Image Info file
$thisfile = $infodir.'/'.$file;
//Check if file exists
if( is_file( $thisfile ) ){
//parse file
include( $thisfile );
//add vars to Array
$allimages[] = array(
'keywords' => $keywords,
'src' => $src,
'other '=> $other
);
}
}
}
//Output Data of all files
echo '<pre>';
print_r( $allimages );
echo '<pre>';
//show images in browser
foreach ($allimages as $image ) {
echo '<div class="img">';
echo '<img src="'.$image['src'].'" title="" alt="" >';
echo '<br />';
echo $image['keywords'];
echo '<br />';
echo $image['other'];
echo '</div>';
}
?>
So I'm making a simple file uploader with wordpress where users don't need to go into wp-admin to add a file.
I have it working great, it uploads the file to the correct folder..etc but the only problem I'm running into is its returning the wrong file url.
For example when uploading a file it goes to '/wp-content/uploads/2014/01/file.png' but it returns the attachment URL as '/uploads/file.png'
My code:
define('WP_USE_THEMES', false);
require_once($_SERVER['DOCUMENT_ROOT']. '/wp-load.php');
include_once($_SERVER['DOCUMENT_ROOT']. '/wp-admin/includes/media.php');
include_once($_SERVER['DOCUMENT_ROOT']. '/wp-admin/includes/file.php');
include_once($_SERVER['DOCUMENT_ROOT']. '/wp-admin/includes/image.php');
if(!$_FILES) exit;
if (!defined("PHP_EOL")) define("PHP_EOL", "\r\n");
//define variables
if(isset($_FILES['fileUpload']))
{
$files = $_FILES['fileUpload'];
}
$upload_dir = wp_upload_dir();
$file_name = $files['name'];
$file_vars = array('test_form' => FALSE); //Allows form submission
$file_post = wp_handle_upload($files, $file_vars); //Posts File
$file_link = $file_post['url']; //Full URL
$file_type = wp_check_filetype(basename($file_link), null); //File Extension
$post_name = preg_replace('/\.[^.]+$/', '', basename($file_link)); //Post Name
$attachment = array(
'guid' => $file_link,
'post_mime_type' => $file_type['type'],
'post_title' => $post_name,
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment($attachment, $file_name);
//Generates meta
$attach_data = wp_generate_attachment_metadata($attach_id, $file_name);
//Updates meta
$attach_final = wp_update_attachment_metadata($attach_id, $attach_data);
Any idea what I'm doing wrong?
I've figured out what I was doing wrong!
Basically when generating attachment metadata I was giving it the wrong path..
I was giving it the path of the actual file '/wp-content/uploads/2014/01/file.png'
but really it needed the path of the folder the file was in '/wp-content/uploads/2014/01/'