4

I wanted to associate a file to a node. so far so good. create a cck type file, and the problem was solved. but I can not do this, I do not want the user to choose the file. the file in question is already in the system. I have tried to place the file as # default_value field and hide it with the hook_form_FORM_ID_alter, but failed.

function my_module_form_node_form_alter(&$form, $form_state, $form_id) {
    if(isset($form['type']) && isset($form['#node'])) {
        $type = $form['#node']->type;

        if(stripos($type, 'node-type') === FALSE)
            return;

        switch($type) :
            case 'node-type_xyz':
                $fid = arg(3);
                $file = file_load($fid);

                // make a cck field_invoice a hidden field
                $form['field_invoice']['#prefix'] = '<div style="display:none;">';
                $form['field_invoice']['#suffix'] = '</div>';

                $form['field_company']['und'][0]['value']['#default_value'] = 'ABC';
                $form['field_account_number']['und'][0]['value']['#default_value'] = '09879';
                break;
        endswitch;
    }
}

anyone have any suggestions?

3

This can be a bit tricky, there are a few steps to get right. First create and save the node, then add the file to the node as a second pass. Here's an example implementation.

/** 
 * Add a file to a field on a node
 * @param int $nid  node ID to add the content to
 * @param string $field_name the machine name of the field to add to 
 * @param string $filedata the raw binary data as a string 
 * @param optional boolean is the attachment an image (should image validation 
 *        be performed)
 */
function mymodule_addfile($nid, $field_name, $filedata, $is_image = FALSE) {
  $node = node_load($nid);

  $field = content_fields($field_name, $node->type);

  // Load up the appropriate validators
  $validators = 
  filefield_widget_upload_validators($field),
  if ($is_image) {
    $validators = array_merge(
      $validators,
      imagefield_widget_upload_validators($field)
    );
  }

  // Where do we store the files?
  $tmp_files_path = file_directory_temp()."/$file_name";
  $files_path     = filefield_widget_file_path($field);

  // Put the file in the temp folder
  $ret = file_put_contents($tmp_files_path,$filedata);
  unset($filedata);
  if ($ret === FALSE) {
    watchdog('mymod_error',"Could not write $nid ($file_name) to temp: $tmp_files_path");
    drupal_set_message("Could not write $nid ($file_name) to temp: $tmp_files_path", 'error');
    return FALSE;
  }

  $path = $files_path.'/'.$file_name;

  // Create the file object
  $file = field_file_save_file($tmp_files_path, $validators, $path);

  if ($file == 0) {
    watchdog('mymod_error',"Failed to save file $file_name");
    drupal_set_message("Failed to save file $file_name",'error');
    return FALSE;
  }

  // Apply the file to the field
  $node->{$field_name}[0] = $file;

  node_save($node);
  return TRUE;
}

A variation on the bottom works too, just assign the result to the file field. 

function _fhi_add_existing_file($file_drupal_path, $uid=1, $status=FILE_STATUS_PERMANENT) {
  $fs       = filesize($file_drupal_path);

  $res = db_query("SELECT fid FROM files WHERE filepath = '%s' AND filesize = '%s'", $filepath, $fs);

  $fid = db_fetch_array($res);

  if ($fid) {
    //drupal_set_message("$filepath already found. fid: $fid");
    $fid = $fid['fid'];
    return field_file_load($fid);
  } else {
    $file=(object)array(
      'filename'  => basename($file_drupal_path),
      'filepath'  => $filepath,
      'filemime'  => file_get_mimetype($file_drupal_path),
      'filesize'  => $fs,
      'uid'       => $uid,
      'status'    => $status,
      'timestamp' => time()
    );

    drupal_write_record('files',$file);
    return field_file_load($file_drupal_path);
  }

}

This code drawn from memory and without interpreter (I've got too much time on my hands this morning) so be wary of typos I may have introduced. As with anything, not responsible for death of poodles as a result of the use of this code.

2
  • thx for responding. I have a question, how does the first step of the step to the second step? – Miguel Borges Jul 8 '11 at 16:22
  • depends on your implementation, most probably you're adding nodes in a module in which case, // Do your node create stuff node_save($node); mymodule_addfile($node->nid, "field_name", $filedata); – Jason Smith Jul 8 '11 at 16:43

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.