copy() works only once in foreach loop

So here is the issue. I have some code that downloads an image from a source URL and saves it to the server and does a a few more things to the image through WordPress functions.

This code runs a foreach loop through the array of image urls and runs fine the first time. Once it reaches the second time through the loop, copy() doesn’t work and says error
[php]failed to open stream: No such file or directory[/php]

The thing is the urls are indeed working and the file does exists. My urls come through the function as:
[php]$file_url = “http://photos2.automanager.com/017529/3cea2be0e7839b41b5bd24b9f7b56d85/71cc0100fc_640.jpg,http://photos2.automanager.com/017529/3cea2be0e7839b41b5bd24b9f7b56d85/7de4801490_640.jpg,http://photos2.automanager.com/017529/3cea2be0e7839b41b5bd24b9f7b56d85/e4a943787c_640.jpg,http://photos2.automanager.com/017529/3cea2be0e7839b41b5bd24b9f7b56d85/d7cf552f10_640.jpg”;[/php]

The rest of my code is as follows:
[php]function fetch_media($file_url,$vin,$cacheid) {
require_once(ABSPATH . ‘wp-load.php’);
require_once(ABSPATH . ‘wp-admin/includes/image.php’);
global $wpdb;

if(!$vin) {
    $vin = $cacheid;
}

$vin = $vin . '/';

//directory to import to    
$artDir = "wp-content/uploads/vehiclephotos/$vin";

//if the directory doesn't exist, create it 
if(!file_exists(ABSPATH.$artDir)) {
    mkdir(ABSPATH.$artDir);
}

$file_url = explode(",", $file_url);
$gallery_images = array();

foreach ($file_url as $url) {
    //rename the file
    $filename = array_pop(explode("/", $url));

    echo "Next filename: $filename \n";
    if (!copy($url, ABSPATH.$artDir.$filename)) {
        $errors= error_get_last();
        echo "COPY ERROR: ".$errors['type'];
        echo "<br />\n".$errors['message']."\n";
    } 
    else {
        echo "File copied from remote! \n";
    }

    $siteurl = get_option('siteurl');
    $file_info = getimagesize(ABSPATH.$artDir.$filename);

    //create an array of attachment data to insert into wp_posts table
    $artdata = array();
    $artdata = array(
        'post_author' => 1, 
        'post_date' => current_time('mysql'),
        'post_date_gmt' => current_time('mysql'),
        'post_title' => $filename, 
        'post_status' => 'inherit',
        'comment_status' => 'closed',
        'ping_status' => 'closed',
        'post_name' => sanitize_title_with_dashes(str_replace("_", "-", $filename)),
        'post_modified' => current_time('mysql'),
        'post_modified_gmt' => current_time('mysql'),
        'post_type' => 'attachment',
        'guid' => $siteurl.'/'.$artDir.$filename,
        'post_mime_type' => $file_info['mime'],
        'post_excerpt' => '',
        'post_content' => ''
    );

    $uploads = wp_upload_dir();
    $save_path = $uploads['basedir'].'/vehiclephotos/'.$vin.$filename;

    //insert the database record
    $attach_id = wp_insert_attachment($artdata, $save_path);

    //generate metadata and thumbnails
    if ($attach_data = wp_generate_attachment_metadata( $attach_id, $save_path)) {
        wp_update_attachment_metadata($attach_id, $attach_data);
    }

    array_push($gallery_images,$attach_id);

}

return serialize($gallery_images);

}[/php]

The error output is as follows:
[php]COPY ERROR: 2
copy( http://photos2.automanager.com/017529/3cea2be0e7839b41b5bd24b9f7b56d85/7de4801490_640.jpg) [function.copy]: failed to open stream: No such file or directory[/php]

So anyone have any idea what could be causing this? I know the file exists, you can go to them (they are live images) and it runs through the loop finishes, just that my photos aren’t getting copied to my server after the first image.

I feel your logic is oddly programmed! Think of how it is worked out…

You have a list of three or whatever URL’s.
You loop thru ALL of the URL’s using a standard FOREACH

BUT, inside of the FOREACH loop, you POP off the last one and use that as the currently copied file.
Therefore, you are not really using the FOREACH, but sort-of using it as a FOR.

Note: Each time you use the POP, it shortened the array and the FOREACH loop does not know where it was.

Just remove the POP and use the explode! UNLESS you are attempting to parse them from end to start.
In that case, you just need to use a FOR loop instead and keep the POP in place. Does this make sense?

Actually what I’m popping off if the filename, which it’s popping off the last / in the URL.

I figured out (well partially figured out my issue). For some reason when it went through the loop past the first url, it was adding a space at the beginning of the URL, making the copy function not be able to read the URL.

I put some temp code to remove any spaces from the beginning of the URL and it worked fine. Any idea how the hell that space got in there? Unless the initial explode on the ‘,’ to create the array added a space?

Nvm I think I just answered my own question.

I had:
[php]$file_url = explode(",", $file_url);[/php]

Looks like there is a space right before $file_url…ouch. Wasted time haha.

Well then, doesn’t look like that space there was the culprit. It’s still adding a space from somewhere…

Well, if it is a space issue, just use the trim() function to remove it…

Change:
$filename = array_pop(explode("/", $url));

To:
$filename = trim(array_pop(explode("/", $url)));

That should remove spaces from both end of the filename…

Got it :smiley: . All is working now. Thanks!

Great! Glad to hear it is working for you. Always nice to solve a programming puzzle!

Sponsor our Newsletter | Privacy Policy | Terms of Service