Hi guys,

I've been struggling to find a solution to this for a while so I hope you can help me out.

I have been working on a custom module which populates some CCK fields I created in a new content type. All the CCK fields are of type Text except for one which is an Image type.

My module updates the text by writing the data directly to the database for each of the CCK fields. That's how I achieve the text updates.

The image is the problem. I have a remote url for the image but I have no idea how to upload it programmatically so the image can then go through the normal image upload process.

My expertise is a bit lacking and I could not find a way to make this work ( if it can ).

Please help, this is important for my project.

Comments

kellytong’s picture

oh, I'm really sorry, I've no idea on this.

sisko’s picture

it's a though cookie ;-)

I appreciate you looking in.

sisko’s picture

Anyone have any images ?

dmitry.sevostyanov’s picture

Hello,

Maybe this module will help you to upload images: http://drupal.org/project/aurigma

sisko’s picture

that only leads me back to a module which can upload an image for me but not the solution I want.

I need a technique to upload an image using PHP code.

Perhaps someone know of a fileField function I can call which will take my image remote url address and upload the remote image?
I need to do things this way so my content is all exposed to views.

ps:

thanks for the suggestions ;-)

sisko’s picture

Really looking for a solution to this. Anyone have any suggestions ?

Or perhaps there is module which will allow a remote url to an image and uploads it to imagefield ???

Please, really really need help.

sisko’s picture

Bump

sisko’s picture

Hello guys,

So, I've been making some progress but things are not working perfectly.

In my custom module I have the following code :

$file_temp = file_get_contents('http://upload.wikimedia.org/wikipedia/en/thumb/a/a7/Batman_Lee.png/250px-Batman_Lee.png');
				$file_temp = file_save_data($file_temp, file_directory_path() .'/http://upload.wikimedia.org/wikipedia/en/thumb/a/a7/Batman_Lee.png/250px-Batman_Lee.png', FILE_EXISTS_RENAME);
				$node->field_photo = array(
				  array(
				    'fid' => 'upload',
				    'title' => basename($file_temp),
				    'filename' => basename($file_temp),
				    'filepath' => $file_temp,
				    'filesize' => filesize($file_temp),
				  ),
				);

But I get the following nasty error messages :




    * The selected file /home/myuser/public_html/sites/default/files/mytmp/fileMOKsKk could not be uploaded, because the destination is not properly configured.
    * warning: filesize() [function.filesize]: stat failed for 0 in /home/myuser/public_html/sites/all/modules/mymodule/mymodule.module on line 47.
    * The selected file /home/myuser/public_html/sites/default/files/mytmp/filelzTAd3 could not be uploaded, because the destination is not properly configured.
    * warning: filesize() [function.filesize]: stat failed for 0 in /home/myuser/public_html/sites/all/modules/mymodule/mymodule.module on line 47.
    * The selected file /home/myuser/public_html/sites/default/files/mytmp/filenFoEvP could not be uploaded, because the destination is not properly configured.
    * warning: filesize() [function.filesize]: stat failed for 0 in /home/myuser/public_html/sites/all/modules/mymodule/mymodule.module on line 47.



Line 47 is the following line from the above code :

	'filesize' => filesize($file_temp),

So, I don't know what's up. As you can see I setup an alternate tmp directory because the default one gave the same errors. My alternate tmp directory obviously made no difference :-(

Please help. I feel it coming - this will work eventually but I don't know what I'm doing wrong here.

Thanks guys :-)

Karlheinz’s picture

Found another mistake in your code. Take a look at your write destination path:

$file_temp = file_save_data($file_temp, file_directory_path() . '/http://upload.wikimedia.org/wikipedia/en/thumb/a/a7/Batman_Lee.png/250px-Batman_Lee.png', FILE_EXISTS_RENAME);

The second parameter is giving an invalid file location, e.g. sites/default/files/http://upload.wikimedia.org/(etc). There's no way Drupal could write to this destination. It should be something like this:

$file_temp = file_save_data($file_temp, file_directory_path() . '/250px-Batman_Lee.png', FILE_EXISTS_RENAME);

If you have the URL of the original file, you can get its filename using PHP's basename() function.

EDIT:

One more thing: usually, the "fid" field would be a distinct ID for each uploaded file. If you've set it to be a serial value ('type' => 'serial' in your schema), then you would just leave it blank or undefined, and it would automatically be assigned a value when you added it to the database.

Assuming that array is for your database schema. If it's supposed to be a file field in the $form array, then you're probably not doing it right. You would simply have a text field for the file's URL, and actually move it to your server when the form is submitted. (You could also do that in an AJAX call, but that's more complicated.)

-Karlheinz

joachim’s picture

Won't the filefield_sources module do what you want? Or at any rate, provide you with example code.

sisko’s picture

I looked at this module sometime ago. What I don't yet know is how to use filefield_sources hooks in my own code.

On the other hand, if you meant to copy thier approach to uploading files - I honestly would appreciate a point in the right direction.
I am simply not yet that comfortably good at understanding and implemnting drupal code.

Karlheinz’s picture

The image is the problem. I have a remote url for the image but I have no idea how to upload it programmatically so the image can then go through the normal image upload process.

This is something I've been considering as well. The question is what module you're going to use for handling images (e.g. image_attach vs. the File interface). Each one has its own API. As far as I can tell, any function that uploads a file from the user's computer, will not work with a URL.

So in any case, you're going to need to copy the remote image to your server. This is something I found on the net, that I adapted for Drupal:

function copy_remote_file($url, $local_dir) { 
    @$file = fopen ($url, "rb"); 
    if (!$file) { 
        drupal_set_message(t("Failed to open %url", array('url' => $url)), 'error'); 
        return false; 
    } else { 
        $filename = basename($url);
        $to = $local_dir . $filename;
        $fc = fopen($to, "wb"); 
        while (!feof ($file)) { 
           $line = fread ($file, 1028); 
           fwrite($fc, $line); 
        } 
        fclose($fc);
        drupal_set_message(t('File %url saved to %to', array('url' => $url, 'to' => $to))); 
        return true; 
    } 
} 

This is an even simpler version using PHP copy(), but I haven't tested it so it's probably buggy:

function copy_remote_file_simple($url, $local_dir) {
    if (@copy($url, $local_dir)) {
        drupal_set_message(t('File %url saved to %to', array('url' => $url, 'to' => $to))); 
        return true;
    } else {
        drupal_set_message(t("Failed to copy %url", array('url' => $url)), 'error'); 
        return false;
    }
} 

For $local_dir, you would either use file_directory_path() or file_directory_temp(), depending upon your intent.

If you surf the PHP manual for the copy() and fopen() functions, you'll find a ton of resources in the comments.

EDIT: After looking at your code above:

  • Do not use file_get_contents() for binary files. This function will return a string. That's probably a good portion of your problem right there.
  • Be careful, because files read over a network are read in packets. This means that a packet might end before you get all of the file. See Example #3 in the PHP manual for fread().

There's probably some more I haven't found, but I think that you can get on the right track now.

-Karlheinz