• Resolved hombero

    (@hombero)


    Hello,

    I am attempting to write a PHP script which downloads an off-site image from url, saves it to a permanent directory, and then attach it to a post as a thumbnail. The script successfully saves the temp file, and then saves a permanent file in the wp-content/uploads/… directory, but the call to media_handle_sideload() halts execution.

    This is what I have so far:

    function wp_sideload_image($post_id, $file, $desc = null)
    {
    	if ( ! empty($file) ) {
    		// Download file to temp location
    		$tmp = download_url( $file );
    		// Set variables for storage
    		// fix file filename for query strings
    		preg_match('/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $file, $matches);
    		$file_array['name'] = basename($matches[0]);
    		$file_array['tmp_name'] = $tmp;
    
    		// If error storing temporarily, unlink
    		if ( is_wp_error( $tmp ) ) {
    			@unlink($file_array['tmp_name']);
    			$file_array['tmp_name'] ='';
    		}
    
    		// do the validation and storage stuff
    		if ($debug) { echo 'File array: <br />';
    			var_dump($file_array);
    			echo 'Post id: <br />';
    			echo $post_id;
    			echo 'Desc: <br />';
    			echo $desc;
    		}
    // Execution fails on next line
    		$id = media_handle_sideload( $file_array, $post_id, $desc );
    
    		// If error storing permanently, unlink
    		if ( is_wp_error($id) ) {@unlink($file_array['tmp_name']);}
    		add_post_meta($post_id, '_thumbnail_id', $id, true);
    	}
    }

    The parameters being passed are:
    $post_id -> an integer representing the post to which to attach
    $file -> the url to the remote file
    $desc (optional) -> the description of the attachment

    I have confirmed that the variables are valid when entering the function, though the script halts when media_handle_sideload() is called.

    Any insight and/or help with this issue will be extremely appreciated, thank you!

Viewing 6 replies - 1 through 6 (of 6 total)
  • First issue is undefined variable $debug which could be fatal erroring out. Do you have WP_DEBUG turned on?

    If you are getting an error object when you call media_handle_sideload, you need to print out the WP_Error response to see what is happening.

    if ( is_wp_error($id) ) {
         @unlink($file_array['tmp_name']);
         var_dump( $id->get_error_messages( ) );
    }

    Also you are still calling add_post_meta even if $id is returning a WP_Error object so you probably have a bunch of WP_Error objects saved to postmeta instead of the file data you want. Have you looked at the example code at http://codex.wordpress.org/Function_Reference/media_handle_sideload ?

    Thread Starter hombero

    (@hombero)

    Hello, thank you for your reply. I should have mentioned in the original post that $debug is a variable I have defined at the beginning of this script as True to echo debugging information. I did not have WP_DEBUG turned on but I have since turned it on at the top of the script as well.

    I’ve incorporated the is_wp_error($id) check as you have suggested, though the script seems to halt at the media_handle_sideload() call so it never prints the error message.

    This is what I have now:

    function wp_sideload_image($post_id, $file, $desc = null)
    {	
    
    	global $debug; // defined outside of function as True
    
    	if ( ! empty($file) ) {
    		if ($debug) { echo 'File not empty <br />'; }
    		// Download file to temp location
    		$tmp = download_url( $file );
    		// Set variables for storage
    		// fix file filename for query strings
    		preg_match('/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $file, $matches);
    		$file_array['name'] = basename($matches[0]);
    		$file_array['tmp_name'] = $tmp;
    
    		// If error storing temporarily, unlink
    		if ( is_wp_error( $tmp ) ) {
    			@unlink($file_array['tmp_name']);
    			$file_array['tmp_name'] ='';
    			if ($debug) { echo 'Error storing temp file! <br />'; }
    		}
    
    		// do the validation and storage stuff
    		if ($debug) { echo 'File array: <br />';
    			var_dump($file_array);
    			echo '<br /> Post id: ' . $post_id . '<br />';
    		}
    
    		$id = media_handle_sideload( $file_array, $post_id, $desc );
    
    		// check for error in $id
    		if ( is_wp_error($id) ) {
    			@unlink($file_array['tmp_name']);
    			var_dump( $id->get_error_messages( ) );
    		}
    		else {
    			add_post_meta($post_id, '_thumbnail_id', $id, true);
    		}
    	}
    }

    It produces this output:

    File not empty
    File array:
    array(2) { [“name”]=> string(6) “16.png” [“tmp_name”]=> string(12) “/tmp/161.tmp” }
    Post id: 1160

    I’m not sure what I’m doing wrong, I’ve read the media_handle_sideload() docs and it seems that this is what the function expects as parameters along with the description.

    Please help and thank you again!

    Moderator bcworkz

    (@bcworkz)

    It’s strange you are not getting any error message or return. FWIW, your function ran fine on my installation with no error. The only change I made was to hardcode the parameters instead of passing them in the call.

    I’m inclined to suspect a plugin interference even though I just tried that diagnosis in another situation and was quite wrong. Fortunately, Chris O. set them straight. My fault in that case was not looking at their code close enough. In your case, I tested it, so I’m not making the same mistake twice. Try deactivating all your plugins and see if the problem goes away.

    If not, you will need to drill into media_handle_sideload() source code and do a detailed trace much like you’ve done for your own code. Backup the original file first of course. It may take some work, but you’ll eventually find where things are going wrong.

    I had a similar issue in the past with media_handle_upload and I’ve recently had it happen to me again with this function.

    You might be calling the function in a context where it has not been declared yet. This would cause the script to fatal error out. Try wrapping your code in a condition that checks if the function exists before calling it. If not, there are a few files that you’ll have to include.

    The following might be a little excessive, but I’ve found that it adds all of the necessary file and media handling code that may otherwise not have been loaded. Note that it’s currently written for the media_handle_upload function, but you can easily replace it with media_handle_sideload

    if ( !function_exists('media_handle_upload') ) {
      require_once(ABSPATH . "wp-admin" . '/includes/image.php');
      require_once(ABSPATH . "wp-admin" . '/includes/file.php');
      require_once(ABSPATH . "wp-admin" . '/includes/media.php');
    }

    Let me know if that works out for you! The code above comes second hand and I can no longer recall the original source, but thank you kind stranger… Wherever you are!

    Moderator bcworkz

    (@bcworkz)

    Thanks pandymic, that is a very likely cause of the problem. I neglected to ask for the first thing in debugging: What does the error message say? (hombero, enable error messages by defining WP_DEBUG as true in wp-config.php. The error message will make clear if pandymic’s suspicion is correct or not.)

    If correct, another possible solution would be to call the function from an action that fires late enough, such as ‘wp_loaded’. Which approach is best would depend on the context of the upload.

    Thread Starter hombero

    (@hombero)

    The issue was indeed due to a missing include that a function inside of media_handle_sideload!

    Including the files that pandymic mentioned solved the issue.

    Thank you very much to everybody for their help!

Viewing 6 replies - 1 through 6 (of 6 total)
  • The topic ‘media_handle_sideload() not working, halts execution’ is closed to new replies.