理解本文需要先知道如何创建一个Drupal 7模块。
1. Drupal 7的文件目录分类
Drupal 7的文件API分为unmanaged file和managed file两种类型,managed file会在数据库中记录文件的信息及引用记录。
Drupal文件对象有一个uri属性,它的形式如public://myfile.jpg,通过file_create_url($file->uri)可以把uri转换成web可访问的路径,如http://howto.eguidedog.net/sites/default/files/myfile.jpg
Drupal内建了public、private和temporary流报装器(stream wrapper),PHP文件操作函数可以直接操作这些uri,例如我们可以通过filesize(‘public://myfile.jpg')获取文件大小,而不需要先转换成本地文件的地址。
Drupal中的private目录应该是放在一个不能直接从Web访问的目录,其内容通过PHP返回(这里有一个副作用是增加了系统开销)。
2. 怎样使用ummanaged file
在表单生成函数中添加文件控件:
$form[‘unmanaged_file’] = array(
‘#type’ => ‘file’,
‘#title’ => ‘文件’,
);
在表单validate函数中把POST的文件数据保存到临时文件:
// 限制文件后缀
$validators = array(
‘file_validate_extensions’ => array(‘jpg jpeg png gif’),
);
$file = file_save_upload(‘unmanaged_file’, $validators, FALSE, FILE_EXISTS_REPLACE);if (isset($file) {
// 有文件被上传
if ($file) {
$form_state[‘values’][‘unmanaged_file’] = $file;
} else {
form_set_error(‘unmanaged_file’, ‘文件上传失败’);
}
}
在表单submit函数里把文件从临时文件夹(temporary)复制到public文件夹:
if ($file = $form_state[‘values’][‘unmanaged_file’]) {
$dir = ‘public://assets/unmanaged';
// file_prepare_directory会检查目录是否存在,如果不存在则创建,也会检查文件权限是否正确。
file_prepare_directory($dir, FILE_CREATE_DIRECTORY);
$filename = file_unmanaged_copy($file->uri, $dir, FILE_EXISTS_RENAME);
}
3. 怎样下载private file
function mymodule_file_download($uri) { // mymodule需要改成具体的模块名称
$path = file_uri_target($uri);
if (strpos($path, 'mydir') === 0 { // mydir是需要处理的目录的前缀,我们不需要处理其它模块的文件
if (user_access('view mymodule private file') { // 这里需要改成具体的权限
$file = new stdClass();
$file->filename = basename($uri);
$file->uri = $uri;
$file->filemime = file_get_mimetype($uri);
$file->filesize = filesize($uri);
return file_get_content_headers($file);
}
return -1;
}
}
4. 怎样使用managed file
$form[‘manage_file’] = array(
‘#type’ => ‘managed_file’,
‘#title’ => ‘managed file example’,
‘#upload_validators’ => array(
‘file_validate_extensions’ => array(‘jpg jpeg png gif’), // 限制后缀名
),
‘#upload_location’ => ‘public://assets/managed', // 指定上传的位置
‘#progress_indicator’ => ‘bar’, // 指定上传进度条效果
);
在hook_submit函数里保存文件:
if ($form_state[‘values’][‘managed_file’]) {
$file = file_load($form_state[‘values’][‘managed_file’];
$file->status = FILE_STATUS_PERMANENT;
file_save($file);// 添加文件引用,如果不添加引用,该文件6小时候内会被cron run删除掉
file_useage_add($file, ‘my_module’, ‘my_module_config_file’, 1);
}
查找文件的方法如下,通常在是在文件表单控件的#default_value值赋值时需要使用:
// file_usage表中对type, id做了索引,但module,type,id没有做索引,所以我们通过type,id来查询文件的fid
$result = db_query(‘SELECT fid FROM file_usage WHERE type = :type AND id = :id’,
array(‘:type’ => ‘my_module_config_file’, ‘:id’ => 1)->fetch();
if ($result) {
$file = file_load($result->fid);
}
下面是删除文件的办法:
// 先判断文件是否被替换,如果被替换则删除旧文件
if ($form_state['values']['file'] != $form['file']['#default_value'] &&
$form['file']['#default_value']) {
$file = file_load($form['file']['#default_value']);
file_usage_delete($file, 'overall_performance', 'overall_performance_config');
file_delete($file);
}
5. File API
http://api.drupal.org/api/drupal/includes--file.inc/group/file/7
5.1 drupal_realpath($uri)
把public://路径转换成服务器文件系统的绝对路径(/srv/www/…)
5.2 file_create_url($uri)
创建一个网络可访问的链接,即http开头的地址
5.3 file_create_filename($filename)
创建文件名,如果系统已有重名文件,可以自动加后缀。
5.4 file_destination($destination, FILE_EXISTS_RENAME)
获取文件名,如果系统已有重名文件,可以自动加后缀。
5.5 $base_url
Drupal根目录,通过global $base_url获取。
5.6 $base_path
不含域名
5.7 drupal_get_path
http://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_get_path/7
drupal_get_path('module', 'name_of_module');
5.8 libraries_get_path($library_name)
获取library的路径(例如sites/all/libraries/mylibrary)
5.9 url
把相对路径转换成绝对路径
5.10 获取public path
$files_dir = variable_get('file_public_path', conf_path() . '/files')
5.11 获取temporary path
file_directory_temp()
5.12 file_get_content_headers
构造文件头,如果想改文件名可修改返回的数组。
http://api.drupal.org/api/drupal/includes%21file.inc/function/file_get_content_headers/7
5.13 file_transfer
把文件传回客户端,此函数不再返回,整个PHP程序会终止。
http://api.drupal.org/api/drupal/includes%21file.inc/function/file_transfer/7
$headers = array(...);
$path_to_file = "/bla/bla/blabla";
file_transfer($path_to_file, $headers);
5.14 module_load_include($type, $module, $name)
引用模块
module_load_include('inc', 'transliteration');
5.15 file_usage_list
https://api.drupal.org/api/drupal/includes%21file.inc/function/file_usage_list/7
获取文件引用情况
5.16 file_usage_add
增加文件引用计数
评论