我正在使用CURL抓取一个文件,并希望将其保存在本地,但是它会插入到Drupal的文件系统中。我是否必须进行手动插入或是否有更好的方法?我能找到的最接近的是:
function image_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items);
但我不知道如何使用它。还有更好的建议吗?
答案 0 :(得分:2)
有两种方法,但最简单的方法是使用file_save_upload()
:
$source = '/path/to/file.ext';
$dest = 'public://uploads/'; // Or whatever
$file = file_save_upload($source, array(), $dest, FILE_EXISTS_RENAME);
if ($file) {
// file_save_upload marks the file as temporary, we need to mark as permanent or it will be cleared from the database in a few hours
$file->status = FILE_STATUS_PERMANENT;
file_save($file);
}
答案 1 :(得分:1)
这只是让我离开了我的脑海,试图找出一种简单的方法来规避表格API期望我遇到了这个问题。 Clive的答案是我如何弄清楚的开始,因为看起来你可以提供一个源作为file_save_upload()的第一个arg,但事实证明,你做不到。至少在目前的drupal 7.30中没有。
我检查了他提供的链接并解构了该功能。基本上,即使您传递完整的源路径,它仍然会在$ _FILES数组的路径中查找第一个arg。谁知道为什么,但多么愚蠢的想法。所以我这样做了:
//after verifying all post fields are set...
$node = new stdClass();
$node->type = 'user_files';
node_object_prepare($node);
$node->title = $_POST['title'];
$node->author = 2; //hardcoded because only admin uses this form
$node->uid = 2;
$node->language = LANGUAGE_NONE;
$node->body[$node->language][0]['value'] = $_POST['body'];
$node->body[$node->language][0]['summary'] = text_summary($_POST['body']);
$node->body[$node->language][0]['format'] = 'filtered_html';
$node->field_first_name[$node->language][0]['value'] = $_POST['first_name'];
$node->field_last_name[$node->language][0]['value'] = $_POST['last_name'];
node_save($node);
if(isset($_FILES['file']['tmp_name']) && $_FILES['file']['name'] != '')
{
//upload file
$file = new stdClass();
$file->uid = 2;
$file->status = 0;
$file->filename = trim(drupal_basename($_FILES['file']['name']), '.');
$file->uri = $_FILES['file']['name'];
$file->filemime = file_get_mimetype($file->filename);
$file->filesize = $_FILES['file']['size'];
$file->filename = file_munge_filename($file->filename, 'jpg jpeg gif png doc docx pdf');
$file->destination = file_destination('private://' . $file->filename, FILE_EXISTS_RENAME);
$file->uri = $file->destination;
if (!drupal_move_uploaded_file($_FILES['file']['tmp_name'], $file->uri)) {
return false; //set errors or do whatever you want on error
}
else
{
drupal_chmod($file->uri);
$existing_files = file_load_multiple(array(), array('uri' => $file->uri));
if (count($existing_files)) {
$existing = reset($existing_files);
$file->fid = $existing->fid;
}
if ($file = file_save($file)) {
// Add file to the cache.
$node->field_file[$node->language][0]['uri'] = 'private://'.$file->filename;
$node->field_file[$node->language][0]['fid'] = $file->fid;
$node->field_file[$node->language][0]['display'] = 1;
$node->field_file[$node->language][0]['description'] = 'User uploaded file';
node_save($node);
//do we notify someone?
}
}
}
这样做会创建指定类型的节点。在这种情况下,user_files,然后如果上传文件,则将文件添加到媒体表,或文件表或其调用的任何内容。然后将关联添加到新创建的节点。
难看吗?是啊。为什么我不使用内部drupal表单API?闭嘴,这就是原因。我们并不总是有选择权,因此当客户要求提供只发送电子邮件的基本表单时,可以快速轻松地创建一个通过邮件黑猩猩API或其他内容发送的简单字段。然后他们补充说他们想要文件。然后他们希望它添加到drupal后端,突然间你会有一个恐怖的雪球,如果用表格API开始这样做会更容易。我不知道是谁开始的,但我不得不结束它,我用这个可怕的黑客做到了。希望它可以帮助你或其他任何人正在恐怖的drupal漩涡中旋转。
答案 2 :(得分:0)
我能够执行以下操作,使用file_save
从public://
Drupal文件夹(通常为sites/default/files
或sites/DOMAIN/files
)添加文件。
$uri = 'public://filename.pdf';
$file = file_save((object) array(
'filename' => basename($uri),
'uri' => $uri,
'status' => FILE_STATUS_PERMANENT,
'filemime' => file_get_mimetype($uri),
));
这会在Drupal核心file_managed
表中添加适当的条目。如果安装了File Entity模块,那么也会创建一个条目。
返回的文件对象将数据库ID包含为$file->fid
。