I am building a site where I need to store encrypted images in the database.

I'm using the module Storage API as it supports saving images to the database. I modified the db.inc file to just add an encrypt and decrypt function directly before writing to / reading from the DB.

This works perfectly however now I need to programmatically import thousands of photos.

I'm using this code to attach images to nodes:

$nid = 100;
$node = node_load($nid);
$image_path = '/var/www/coach/htdocs/photos/test.jpg';  
$file = (object) array(
    'uid' => 1,
    'uri' => $image_path,
    'filemime' => file_get_mimetype($image_path),
    'status' => 1,
    'display' => 1
$destination = 'private://';
$file = file_copy($file, $destination, FILE_EXISTS_REPLACE);
$node->field_passport_photo[LANGUAGE_NONE][0] = (array) $file;

However the destination here is wrong - I don't want to use the private scheme - I want to save the file to the database using the Storage API.

The documentation says that $destination is "A string containing the destination that $source should be copied to. This must be a stream wrapper URI."

After manually adding an image to a node and inspecting the $form item on the edit form page I can see that the #upload_location of the image is "storage-field-passport-photo://", however just passing this string into file_copy as a destination does not work as a valid file object is not returned.

So, what is the stream wrapper URI to get the file to be saved to the database?


You can get a list of the stream wrappers implemented by the storage_core_bridge module with the storage_core_bridge_stream_wrappers() function:

$wrappers = storage_core_bridge_stream_wrappers();

The name will correspond to the name of the field in which the image data is stored, so storage-field-passport-photo:// doesn't exactly sound unreasonable. You can use the above function to check for definite, though.

If it still doesn't work after you've determined the correct stream schema, you've most likely hit a bug, which you can get help for in the module's issue queue.

| improve this answer | |

Though trial and error I've eventually found solution that works.

Clive's solution confirmed I had the correct stream wrapper but it still wasn't working.

I found I needed to add the filename to the end of the stream wrapper to pass into the file_copy function.

So the final code that worked was:

$file = file_copy($file, 'storage-field-passport-photo://'.filename, FILE_EXISTS_REPLACE);

This is odd as it is behaving differently to if it was public:// or private:// which don't require the filename.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.