Hello all!

I'm having a heck of a time trying to create a subdirectory for my users to upload a pdf file. I've looked at the file section of the API, but the functions there don't seem to want to help me. I've tried:

file_check_directory(&$dirpath, FILE_CREATE_DIRECTORY);

and

file_create_path($dirpath);

But neither of those are working. I've scoured the user.module and imce.module code for help, but I can't figure out how to create a simple directory in my files section. In case it helps, here is a full copy of the function I'm working with:

<?php
function iheartmodule_letter_form_submit($form, &$form_state) {
	global $user;
	$letter = $form_state['clicked_button']['#post']['files']['letter'];
	
	// Create the directory if it doesn't exist
	$root = file_directory_path();
  	$dirpath = $root .'/pdf/'. $user->uid;
	file_create_path($dirpath);

	// Change the permissions	
	chmod($dirpath, 0775);

	// Upload the file and rename
	file_save_upload('letter', array(), $dirpath, FILE_EXISTS_REPLACE);
	$file_original = $dirpath .'/'. $letter;
	$file_new = $dirpath .'/'. $user->uid .'.pdf';
	file_move(&$file_original, $file_new, FILE_EXISTS_REPLACE);
	
} ?>

Thanks for any help!
- Ryan

Comments

rschwab’s picture

Strange, I went back to using file_check_directory and now its creating the directory as expected. Still working on why the file isn't ending up in the directory though....

Here's the revised code segment:

<?php
// Create the directory if it doesn't exist
  $root = file_directory_path();
  $dirpath = $root .'/pdf/'. $user->uid;
  file_check_directory(&$dirpath, FILE_CREATE_DIRECTORY);
?>

I will post an update if/when I solve this. Any help much appreciated!

- Ryan

pobster’s picture

It's because you're not giving the correct filename/ filepath for your file_move, use $file = file_save_upload(...); then use the information in the $file object for your move function.

Here's a tip for future debugging, install the devel module then use dsm() (eg. dsm($file);) in your code to reveal the contents of variables, objects or arrays. It'll make life so much simpler to be able to see what it is you're actually passing into functions to see why they're failing. If you'd been able to see what $file_original contained, you'd easily have been able to spot that it doesn't contain what you assumed it would... Anyways, now you can use $file->filepath rather than try to build it yourself.

edit: BTW, coding practise file_move(&$file_original... this is deprecated, you no longer need to 'pass' the referenced variable; as long as the function being called has the ampersand, php knows to use the variable as a call-by-reference. This will cause a warning in most installations of php. (Just to be clear, instead use file_move($file_original...)

Pobster

rschwab’s picture

Thank you for the response pobster!

I'm confused because it doesn't seem like file_save_upload is doing anything at all. I changed the code to:

<?php 
$validators = array(
  'file_validate_size' => array(1024 * 1024 * 10), // 10 MB
  'file_validate_extensions' => array ('pdf'),
);

$file = file_save_upload('letter', $validators, $dirpath, FILE_EXISTS_REPLACE);
print_r($file);
?>

But what prints out is just "0". Is 'letter' the correct string to use if my form is built like so:

<?php
function iheartmodule_letter_form() {
	$form = array();
	
	$form['letter'] = array(
     '#type' => 'file',
     '#title' => t('File'),
     '#size' => 30,
	 '#weight' => 0,
	 );
  
	$form['submit_button'] = array(
		'#type' => 'submit',
		'#value' => t('Upload'),
		'#weight' => 1,
		'#prefix' => '<p>',
		'#suffix' => '</p>',
		);

	return $form;
}?>

Thanks again.
- Ryan

pobster’s picture

Hmmm... Well it *is* well documented (honest) but you're missing this;

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

From your form function... You should be good to go, although if you like... I can show you how to do the validation in the form validation step so if the upload fails you get a red warning around the box using form_set_error...?

Edit: http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.... (for reference)

Pobster

pobster’s picture

File handling in Drupal 6.x has been (sort of) broken for this type of thing but there are workarounds. Try to understand what is happening here;

function iheartmodule_letter_form() {
    $form = array();

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

    $form['letter'] = array(
     '#type' => 'file',
     '#title' => t('File'),
     '#size' => 30,
     '#weight' => 0,
     );
  
    $form['submit_button'] = array(
        '#type' => 'submit',
        '#value' => t('Upload'),
        '#weight' => 1,
        '#prefix' => '<p>',
        '#suffix' => '</p>',
        );
    $form['file_placeholder'] = array(
        '#type' => 'hidden',
        '#value' => '',
        );

    return $form;
}

function iheartmodule_letter_form_validate(&$form, &$form_state) {
    global $user;

    // Create the directory if it doesn't exist
    $dirpath = file_directory_path() ."/pdf/$user->uid";
    file_create_path($dirpath);
    // Change the permissions    
    chmod($dirpath, 0775);

    switch ($form_state['clicked_button']['#value']) {
    case t('Upload'):
      $validators = array(
        'file_validate_size' => array(1024 * 1024 * 10), // 10 MB
        'file_validate_extensions' => array('pdf'),
      );
      if (!($file = file_save_upload('letter', $validators, $dirpath, FILE_EXISTS_REPLACE))) {
        // return an error on failure
        form_set_error('letter', t('File upload failed, please contact your system administrator.'));
      }
      else {
        // fill in placeholder variable so we get to pass our file object to the submit function
        form_set_value(array('#parents' => array('file_placeholder')), $file, $form_state);
      }
      break;
  } // end switch
}

function iheartmodule_letter_form_submit($form, &$form_state) {
    // access the file object like this;
    $file = $form_state['values']['file_placeholder'];
//... rest of function...
}

I didn't realise there was a bounty on this thread, please could you send the $20 here;

http://www.make-a-wish.org.uk/donate

Thanks,

Pobster