WordPress file "upload" from plugin - php

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

Related

WordPress / PHP 'Trying to get property 'feeds' of non object when trying to upload image from remote url

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.

How to add Woocommerce Product Gallery using Gravity Forms

I am trying to add WooCommerce Product Gallery using Gravity forms multiple file upload but product gallery should not be added
add_action( 'gform_after_submission_3', 'set_post_content', 10, 2 );
function set_post_content( $entry, $form ) {
if (!function_exists('wp_generate_attachment_metadata')) {
require_once(ABSPATH . 'wp-admin/includes/image.php');
}
$uploaded_files = json_decode(rgpost("gform_uploaded_files"));
foreach($uploaded_files->input_76 as $key => $data){
if (isset($_FILES[$data])) {
$file_url = $data->input_76; //great but what is its url?
$upload_dir = wp_upload_dir(); //where do you want to put it?
$file_data = file_get_contents($file_url); //show me what you're made of
$filename = basename($file_url); //so cute but what's its name?
if (wp_mkdir_p($upload_dir['path'])) //can we put it there?
$file = $upload_dir['path'] . '/' . $filename; //yes great
else //or no, okay fine let's try somewhere else
$file = $upload_dir['basedir'] . '/' . $filename; //get the whole location
file_put_contents($file, $file_data); // tada home at last
//$wp_filetype = wp_check_filetype($filename, array('pdf' => 'application/pdf','pdf' => 'application/x-pdf') ); //is it the right type of of file?
$attachment = array(//set up the attachment
//'post_mime_type' => $wp_filetype['type'],
'post_title' => sanitize_file_name($filename),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment($attachment, $file, $entry['post_id']); //insert attachment
$attach_data = wp_generate_attachment_metadata($attach_id, $file); //asign the meta
wp_update_attachment_metadata($attach_id, $attach_data); //update the post
update_post_meta($entry['post_id'], '_product_image_gallery', $attach_id);
}
}
}

Create new post via PHP including external feature image in WordPress

I've heard it's kind of impossible to do, but I had to ask anyway.
I use PHP to create new posts in WP, like so:
<?php
$postType = 'post'; // set to post or page
$userID = 1; // set to user id
$categoryID = '4'; // set to category id.
$postStatus = 'publish'; // set to future, draft, or publish
$leadTitle = $post_title;
$leadContent = $post_content;
/*******************************************************
** TIME VARIABLES / CALCULATIONS
*******************************************************/
// VARIABLES
$timeStamp = $minuteCounter = 0; // set all timers to 0;
$iCounter = 1; // number use to multiply by minute increment;
$minuteIncrement = 1; // increment which to increase each post time for future schedule
$adjustClockMinutes = 0; // add 1 hour or 60 minutes - daylight savings
// CALCULATIONS
$minuteCounter = $iCounter * $minuteIncrement; // setting how far out in time to post if future.
$minuteCounter = $minuteCounter + $adjustClockMinutes; // adjusting for server timezone
$timeStamp = date('Y-m-d H:i:s', strtotime("+$minuteCounter min")); // format needed for WordPress
/*******************************************************
** WordPress Array and Variables for posting
*******************************************************/
$new_post = array(
'post_title' => $leadTitle,
'post_content' => $leadContent,
'post_status' => $postStatus,
'post_date' => $timeStamp,
'post_author' => $userID,
'post_type' => $postType,
'post_category' => array($categoryID)
);
// /*******************************************************
// ** WordPress Post Function
// *******************************************************/
$post_id = wp_insert_post($new_post);
?>
I need to also include an image, say from another website, and set it as Feature Image. How can I do that?
Try to use 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 );
Code taken from this article.

Generating Wordpress featured image in foreach loop, showing same image for multiple posts

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.

Create jpgs from pdf with WordPress plugin

I'm working on a plugin which creates jpgs from every page of an uploaded pdf file.
I use the wp_handle_upload action and check if the mime type is pdf.
After that, I use Imagick to get the page count and create a new jpg from every page. Then the file gets uploaded.
I think Wordpress doesn't support ImageMagick from scratch so I installed the ImageMagick Engine Plugin.
When I now upload a file in Wordpress I just get an error. I don't know what exactly doesn't work.
Any idea about what is going wrong?
Thanks, Oliver
function process_pdf($results) {
if( $results['type'] === 'application/pdf' ) {
$filename = $results[ 'file' ];
$filename_wo_extension = basename( $filename );
$url = $results[ 'url' ];
$im = new Imagick();
$im->setResolution(300, 300);
$pages = $im->getNumberImages();
for($p = 0; $p < $pages; $p++){
// http://stackoverflow.com/questions/467793/how-do-i-convert-a-pdf-document-to-a-preview-image-in-php
// http://stackoverflow.com/questions/1143841/count-the-number-of-pages-in-a-pdf-in-only-php
$im->readImage( $url.'['.p.']');
$im->setImageFormat('jpg');
$filename_neu = $filename_wo_extension .'_'. $p .'.jpg';
// https://codex.wordpress.org/Function_Reference/wp_insert_attachment
$upload_file = wp_upload_bits($filename_neu, null, $im);
if (!$upload_file['error']) {
$attachment = array(
'post_mime_type' => 'image/jpeg',
'post_title' => preg_replace('/\.[^.]+$/', '', $filename_neu),
'post_content' => '',
'post_status' => 'inherit'
);
$attachment_id = wp_insert_attachment( $attachment, $upload_file['file'] );
if (!is_wp_error($attachment_id)) {
require_once(ABSPATH . "wp-admin" . '/includes/image.php');
$attachment_data = wp_generate_attachment_metadata( $attachment_id, $upload_file['file'] );
wp_update_attachment_metadata( $attachment_id, $attachment_data );
}
}
}
}
}
add_action('wp_handle_upload', 'process_pdf');
Here is the code for achieving this.
The pdf file has to be uploaded to a post, otherwise there is no $post_id.
The only thing now is, that when clicking on save, the custom field (gallery) gets overwritten. When the post is not saved after uploading the pdf, the images are in the gallery.
function process_pdf( $file ) {
if( $file['type'] === 'application/pdf' ) {
// Get the parent post ID, if there is one
if( isset($_REQUEST['post_id']) ) {
$post_id = $_REQUEST['post_id'];
$filename = $file[ 'name' ];
$filename_wo_extension = basename( $filename, ".pdf" );
$im = new Imagick();
$im->setResolution(300, 300);
$im->readimage( $file[ 'tmp_name' ] );
$pages = $im->getNumberImages();
$attachments_array = array();
// iterate over pages of the pdf file
for($p = 1; $p <= $pages; $p++){
$im->setIteratorIndex( $p - 1 );
$im->setImageFormat('jpeg');
$filename_neu = $filename_wo_extension .'_'. $p .'.jpg';
// upload new image to wordpress
// https://codex.wordpress.org/Function_Reference/wp_insert_attachment
$upload_file = wp_upload_bits($filename_neu, null, $im);
if (!$upload_file['error']) {
$attachment = array(
'post_mime_type' => 'image/jpeg',
'post_title' => preg_replace( '/\.[^.]+$/', '', $filename_neu),
'post_content' => '',
'post_status' => 'inherit'
);
$attachment_id = wp_insert_attachment( $attachment, $upload_file['file'] );
if (!is_wp_error( $attachment_id )) {
require_once(ABSPATH . "wp-admin" . '/includes/image.php');
$attachment_data = wp_generate_attachment_metadata( $attachment_id, $upload_file['file'] );
wp_update_attachment_metadata( $attachment_id, $attachment_data );
$attachments_array[] = $attachment_id;
}
}
}
// add new images to a gallery (advanced custom fields plugin)
// http://www.advancedcustomfields.com/resources/update_field/
update_field( 'field_55b0a473da995', $attachments_array, $post_id );
$im->destroy();
}
}
return $file;
}
add_filter('wp_handle_upload_prefilter', 'process_pdf' );
I know this is an old thread, but anyway, I would like to say that there is a very fine WordPress plugin that deals with PDF files, converting the first page into an image, using either ImageMagick or IMagik (it let's you chose what you have installed on your site).
As the source code if freely available, I guess it might be of some help for whoever might be researching on this matter:
PDF IMAGE GENERATOR
https://wordpress.org/plugins/pdf-image-generator/

Categories