I'm modifying the story module to create a custom staff content type that basically has a photo, their role and a biography. I've got the module modified and saving the custom data to my custom table except for the image. I've been looking through the image module and the upload module and come across file_check_upload and file_save_upload but I can't seem to get them to work.

/**
 * Implementation of hook_prepare
 */
function staff_prepare(&$node) {
  $file = file_check_upload('photo');
  if ($file) {
    $file = file_save_upload('photo', file_directory_path());
    $node->photo = $file->filename;
  }
}

I thought that this would move the file from the temp folder to the files folder and put the name of the file into the database but I end up with just the full path and filename of the original file on my PC. My file upload field is called 'photo'

Can someone please help me to get this code right, I basically want to have a single photo associated with each staff record and just the filename stored in the record.

Comments

ninetwenty’s picture

I've got this working by enabling the upload module, is this module the key or is there something I'm missing from my code? Here's what I've got so far:

/**
 * @file
 * Enables users to submit staff bios.
 */

/**
 * Implementation of hook_help().
 */
function staff_help($section) {
  switch ($section) {
    case 'admin/modules#description':
      return t('Allows users to submit staff biographies.');
    case 'node/add#staff':
      return t('This allows you to submit staff biographies to your site.');
  }
}

/**
 * Implementation of hook_node_info().
 */
function staff_node_info() {
  return array('staff' => array('name' => t('staff bio'), 'base' => 'staff'));
}

/**
 * Implementation of hook_perm().
 */
function staff_perm() {
  return array('create staff bios', 'edit own staff bios', 'delete own staff bios', 'edit any staff bio', 'delete any staff bio');
}

/**
 * Implementation of hook_access().
 */
function staff_access($op, $node) {
  global $user;

  if ($op == 'create') {
    return user_access('create staff bios');
  }

  if ($op == 'update') {
    if (user_access('edit any staff bio') || (user_access('edit own staff bios') && ($user->uid == $node->uid))) {
      return TRUE;
    }
  }
  
  if ($op == 'delete') {
    if (user_access('delete any staff bio') || (user_access('delete own staff bios') && ($user->uid == $node->uid))) {
      return TRUE;
    }
  }  
}

/**
 * Implementation of hook_menu().
 */
function staff_menu($may_cache) {
  $items = array();

  if ($may_cache) {
    $items[] = array('path' => 'node/add/staff', 'title' => t('staff bio'),
      'access' => user_access('create staff bios'));
  }

  return $items;
}

/**
 * Implementation of hook_form().
 */
function staff_form(&$node) {
  $form['title'] = array('#type' => 'textfield', '#title' => t('Name'), '#required' => TRUE, '#default_value' => $node->title, '#weight' => -6);
  $form['role'] = array('#type' => 'textfield', '#title' => t('Role'), '#required' => FALSE, '#default_value' => $node->role, '#weight' => -5);
  $form['photo'] = array('#type' => 'file', '#title' => t('Photo'), '#required' => FALSE, '#weight' => -4);
  $form['body']['body'] = array('#type' => 'textarea', '#title' => t('Biography'), '#default_value' => $node->body, '#rows' => 25, '#required' => TRUE);
  $form['body']['format'] = filter_form($node->format);
  return $form;
}

/**
 * Implementation of hook_load()
 */
function staff_load(&$node) {
  $ob = db_fetch_object(db_query("SELECT role, photo FROM {staff} WHERE nid = %d", $node->nid));
  return array('role' => $ob->role, 'photo' => $ob->photo);
}

/**
 * Implementation of hook_delete()
 */
function staff_delete(&$node) {
  db_query("DELETE FROM {staff} WHERE nid = %d", $node->nid);
}

/**
 * Implementation of hook_insert()
 */
function staff_insert(&$node) {
  db_query("INSERT INTO {staff} (nid, role, photo) VALUES (%d, '%s', '%s')", $node->nid, $node->role, $node->photo);
}

/**
 * Implementation of hook_update()
 */
function staff_update(&$node) {
  db_query("UPDATE {staff} SET role = '%s', photo = '%s' WHERE nid = %d", $node->role, $node->photo, $node->nid);
}

/**
 * Implementation of hook_validate
 */
function staff_validate(&$node) {
  $file = file_check_upload('photo');
  if ($file) {
    file_save_upload('photo', file_directory_path());
    $node->photo = $file->filename;
  }
}

One thing it is not doing is storing the filename in the table, can anyone please help?

nevets’s picture

Not sure if is the only issue but in the form hook you need

$form['#attributes'] = array("enctype" => "multipart/form-data");

otherwise the file field does not work.

ekitel’s picture

are you sure it isn't supposed to be like this:

$form['attributes'] = array("#enctype" => "multipart/form-data");

cbovard’s picture

I used the above snippet and it did not work at all.
Here is the right attribute:

$form['#attributes'] = array("enctype" => "multipart/form-data");

Alot of time was wasted on this.

chris

www.chrisbovard.com | Drupal Developer / Themer

ninetwenty’s picture

Thank you so very much. I can't believe I missed that. Works perfectly now.

ninetwenty’s picture

Got the file uploading but for some reason the filename still doesn't get stored in the table. When I set $node->photo in the validate hook it seems to have lost its value by the time it gets to the insert or update hook. Anyone spot my glaring error?

nevets’s picture

You can not change to form field values in the validate hook. Instead you want to do this in the submit hook (common to both insert and update). And yes, this means running the same code twice since you still want to validate the file.

ninetwenty’s picture

Thanks for that, looks like the documentation needs changing because in the docs for hook_validate it says:

It can also be used to make changes to the node before submission

Which is either wrong or I've misunderstood.

Thanks again for the help, now works 100%.

dman’s picture

It is out-of-date.
validate no longer allows changes. Pity.

Mmm. Docs should be updated there.
Search for ways around it. I believe you use 'submit' (which no longer actually submits anything *sigh*)

.dan.
How to troubleshoot Drupal | http://www.coders.co.nz/

ekitel’s picture

I got this working nicely, though it doesn't update the files table the way I thought it would, but the important thing is it puts the file name in the right field of the table for my custom content type...

I also added the ability to over write existing file with the same name, and delete existing files when the name is different

here are the relevent parts of my code, the rest is pretty much what I got at http://api.drupal.org/api/4.7/file/developer/examples/nodeapi_example.mo...

function fashion_form(&$node) { 
$form['attributes'] = array("#enctype" => "multipart/form-data");
  // We need to define form elements for the node's title and body. 
  $form['title'] = array( 
    '#type' => 'textfield', 
    '#title' => t('Title'), 
    '#required' => TRUE, 
    '#default_value' => $node->title, 
    '#weight' => -5 
  ); 
  // We want the body and filter elements to be adjacent. We could try doing 
  // this by setting their weights, but another module might add elements to the 
  // form with the same weights and end up between ours. By putting them into a 
  // sub-array together, we're able force them to be rendered together. 
  $form['body_filter']['body'] = array( 
    '#type' => 'textarea', 
    '#title' => t('Body'), 
	'#rows' => 20,
    '#default_value' => $node->body, 
    '#required' => FALSE 
  ); 
  $form['body_filter']['filter'] = filter_form($node->format); 

  // Now we define the form elements specific to our node type. 
  $form['hed'] = array( 
    '#type' => 'textfield', 
    '#title' => t('Hed'), 
	'#description' => t('Headline'),
    '#default_value' => $node->hed,
	'#required' => FALSE
  ); 
  $form['dek'] = array( 
    '#type' => 'textfield', 
    '#title' => t('Dek'), 
	'#description' => t('Short description'),
    '#default_value' => $node->dek,
	'#required' => FALSE
  );

  $form['des'] = array( 
    '#type' => 'textarea', 
    '#title' => t('Description'), 
	'#rows' => 10,
    '#default_value' => $node->des,
	'#required' => FALSE
  );

  $form['thumbnail'] = array(
	'#type' => 'file', 
	'#title' => t('Thumbnail'), 
	'#description' => t('currently: ') . $node->thumbnail,
	'#default_value' => $node->thumbnail,
	'#required' => FALSE
	);
	
	$form['large'] = array(
	'#type' => 'file', 
	'#title' => t('Large Image'),
	'#description' => t('currently: ') . $node->large,
	'#default_value' => $node->large,
	'#required' => FALSE
	);


  $form['caption'] = array( 
    '#type' => 'textfield', 
    '#title' => t('Caption'), 
    '#default_value' => $node->caption,
	'#required' => FALSE
  );

  return $form; 
}

function fashion_insert($node) { 
	$file = file_check_upload('thumbnail');
  if ($file) {
    file_save_upload('thumbnail', file_directory_path(), FILE_EXISTS_REPLACE);
    $node->thumbnail = $file->filename;
  }
	$file = file_check_upload('large');
  if ($file) {
    file_save_upload('large', file_directory_path(), FILE_EXISTS_REPLACE);
    $node->large = $file->filename;
  }
  db_query("INSERT INTO {fashion} (vid, nid, hed, dek, des, thumbnail, large, caption) VALUES (%d, %d, '%s', '%s', '%s', '%s', '%s', '%s')", $node->vid, $node->nid, $node->hed, $node->dek, $node->des, $node->thumbnail, $node->large, $node->caption); 

} 


function fashion_update($node) { 
  // if this is a new node or we're adding a new revision, 
  if ($node->revision) { 
    fashion_insert($node); 
  } 
  else { 
	  $file = file_check_upload('thumbnail');
	  	if ($file) {
			file_delete(file_directory_path()."/".$node->thumbnail);
			file_save_upload('thumbnail', file_directory_path(), FILE_EXISTS_REPLACE);
	    	$node->thumbnail = $file->filename;
		}
		$file = file_check_upload('large');
	  if ($file) {
		file_delete(file_directory_path()."/".$node->large);
	    file_save_upload('large', file_directory_path(), FILE_EXISTS_REPLACE);
	    $node->large = $file->filename;
	  }
    db_query("UPDATE {fashion} SET hed = '%s', dek = '%s', des = '%s', thumbnail = '%s', large = '%s',  caption = '%s' WHERE vid = %d", $node->hed, $node->dek, $node->des, $node->thumbnail, $node->large, $node->caption, $node->vid); 

  }

} 

function fashion_load($node) { 
  $additions = db_fetch_object(db_query('SELECT hed, dek, des, thumbnail, large, caption FROM {fashion} WHERE vid = %d', $node->vid)); 
  return $additions; 
}