As numerous posts out there state, this is the way to programmatically add files into Drupal 7's file module tables.
<?php
// Load the files contents
$image = file_get_contents(<path to file>);
// Returns the new file object
$file = file_save_data($image, 'public://<filename>', FILE_EXISTS_RENAME);
?>However after working on the module CCTV (Currently getting approval for Full Project) I found that this was not enough.
For some background details, CCTV is a module that turns your Drupal site into a IP Camera capture application. Based on the users preference the application can save files up to 1 day in file size (which equates to a very large file). Due to the large file sizes generated by CCTV php runs into memory both max file php configuration and local allocated memory issues. So how do we get around this?
After digging through the file modules documentation I found the following solution.
<?php
$handle = fopen('<path to local file>', 'r');
$file = file_save_data($handle, 'public://<filename>');
fclose($handle);
?>This opens the file in read only mode and using the file module's function file_save_data it copies the file to the public:// file system. This not only makes your code more efficient, but also allows for bypassing around php's max file size constraints.
Comments
use file_move
function mymodule_move_file($file) {$file->filename = basename($file->filepath);
unset($file->filepath);
$file_path = 'source/' . $file->filename;
$dest = 'images/' . $file->filename;
$file->uid =1;
$file->status = FILE_STATUS_PERMANENT;
$file->uri = file_build_uri($file_path);
if (!file_exists($file->uri)) {
error_log('filemove:' . $file_path);
return NULL;
}
return file_move($file, file_build_uri($dest) );
}
not file_move necessarily
the authors code simply reads the file contents from anywhere and places it in drupal's /files directory.
D7 file_move() deletes the source file by default if possible -- that may be an unwanted behavior. I also thought some of the drupal file commands work only from within drupals webroot, the author is moving files from anywhere on disk it looks like.
Exactly. Fewer lines of code
Exactly. Fewer lines of code and can access the servers files from outside of the webroot directory. Looking through the code of file_save_data it calls also file_unmanaged_move. In this case however, I am opening the local file with read-only permissions which negates the move.
The file API only guarantees
The file API only guarantees to work with string $data.
You are relying on an implementation detail of file_save_data, i.e. that it calls file_save_unmanaged_data which in turn uses file_put_contents($name, $data) to actually do the writing. Because the latter supports stream resources, this all works. For now.
For an import job I will
For an import job I will already have the file in the files directory. How would I save the name to file_managed?
Add new comment