Drupal 7中的自定义字段,包含多个文件字段

时间:2012-01-04 02:49:42

标签: php drupal drupal-7 drupal-fields drupal-field-api

我正在制作一个自定义的“视频”字段,该字段应该接受多个文件(针对不同的视频格式)和标题。到目前为止,架构很好,但我无法上传和存储实际文件。

hook_field_widget_form中的代码如下所示(仅粘贴相关位):

$element['mp4'] = array(
  '#type' => 'file',
  '#title' => 'MP4 file',
  '#delta' => $delta,
);
$element['ogg'] = ... /* similar to the mp4 one */
$element['caption'] = array(
  '#type' => 'textfield',
  '#title' => 'Caption',
  '#delta' => $delta,
);

另外,在我的.install文件中:

function customvideofield_field_schema($field) {
  return array(
    'columns' => array(
      'mp4' => array(
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'ogg' => ... /* similar to mp4 */
      'caption' => array(
        'type' => 'varchar',
        'length' => 255,
      ),
    )
  );
}

我得到的错误是当我尝试存储数据时。我得到表单ok,数据库看起来很好(Drupal至少生成字段),但是当它尝试执行INSERT时,它会失败,因为它尝试进入这些整数字段的值是一个空字符串。

据我所知,他们必须是整数,对吧? (fid s?)但我猜这些文件没有被上传,即使我确实得到了正确的上传文件界面。

Drupal向您显示它尝试执行的INSERT查询,这在此处发布时间过长,但我可以看到caption字段(只是文本字段)的值很好查询,所以这只是文件字段的问题。

2 个答案:

答案 0 :(得分:3)

您可能希望使用managed_file字段类型,它会处理上传文件并在managed_files表中为您注册该文件。然后,您只需向窗口小部件表单添加一个提交函数,并将以下代码(来自链接到上面的FAPI页面):

// Load the file via file.fid.
$file = file_load($form_state['values']['mp4']);

// Change status to permanent.
$file->status = FILE_STATUS_PERMANENT;

// Save.
file_save($file);

// Record that the module (in this example, user module) is using the file. 
file_usage_add($file, 'customvideofield', 'customvideofield', $file->fid);

希望有所帮助

修改

核心文件模块使用hook_field_presave()处理实际的提交,我最好的猜测是这段代码可以正常工作:

function customvideofield_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
  // Make sure that each file which will be saved with this object has a
  // permanent status, so that it will not be removed when temporary files are
  // cleaned up.
  foreach ($items as $item) {
    $file = file_load($item['mp4']);
    if (!$file->status) {
      $file->status = FILE_STATUS_PERMANENT;
      file_save($file);
    }
  }
}

假设您的字段的文件ID列是名为mp4的文件ID。

请记住在实现新挂钩时清除Drupal的缓存,否则它将无法注册。

答案 1 :(得分:0)

我还没有尝试在我的Drupal模块中上传文件,但是你可以检查你的表单标签是否具有属性enctype = “多部分/格式数据”?

我希望Drupal应该自动包含它,但如果没有它,文件字段将无法正常工作,这似乎就是您所遇到的。

詹姆斯