Validating File Paths & Permissions in Drupal Forms

Since Drupal stashes just about everything in the database, dealing with file i/o stuff is pretty uncommon. While it may not come up often, every now and again you run across a Drupal coding task that involves creating files on the server.

Example: I'm currently tinkering with a possible contrib module that will create theme files. One of the fields (textfield) in the module's settings form expects a valid file path to an active theme directory. I want robust validation on this form that verifies the folder in question actually exists and that Drupal can write to this folder.

The code

We'll start by creating the validation function and doing the initial check to see if the folder even exists.

/**
 *  admin form validation
 */

function mymodule_admin_form_validate(&$form, $form_state) {
  $target_dir = $form_state['values']['target_dir'];
  if(!file_exists($target_dir)) {
    form_set_error('themes_path', 'Directory doesn\'t exist');
    return 0;
  }
  ...
}

Pretty straightforward. PHP has a built in function, file_exists(), that will tell us if the directory exists. If not we throw an error on that form element and bail out.

Next item on the agenda is finding out if Drupal can write files to the directory. For that we're going to tap into the power of PHP's lone error control operator, @ and fopen().


  ...
  $fid = $target_dir . '/test.file'; 
  $file = @fopen($fid, 'w');
  if(!$file) {
    form_set_error('themes_path', 'Mymodule can\'t write to the directory ' 
. $target_dir . '. Please check the folder permissions.');
    return 0;
  }
  else  {
    unlink($fid);
  } 
  ...

Let's take a closer look at what's going on here. $fid is set up with the directory path and a temp filename (could be anything). This is just setting the stage for fopen(). But wait, what's up with that @?

@ tells PHP to suppress any error messages generated by the function call it's attached to. fopen() throws php warning errors if it can't open a file, which is fine but we're doing our own error handling with form_set_error() so we want to suppress the normal PHP errors to cut down on confusion. Well that and, let's face it, nothing says n00b quite like your module throwing php errors.

Last but not least, if everything has worked correctly to this point (directory exists and can be written to) we need to clean up after fopen and get rid of the temp file it created, which unlink() does for us.

Full code

/**
 *  admin form validation
 */
function mymodule_admin_form_validate(&$form, $form_state) {
  $themes_dir = $form_state['values']['themes_dir'];
  if(!file_exists($themes_dir) {
    form_set_error('themes_dir',''Directory ' . $themes_dir . ' doesn't exist');
    return 0;
  }
  $fid = $themes_dir . '/test.file';
  $file = @fopen($fid, 'w');
  if(!file) {
    form_set_error('themes_path', 'Mymodule can't write to the directory ' .
 $themes_dir . '. Please check the folder permissions');
    return 0;
  }
  else {
    unlink($fid);
  }

}

Freeman on web stuff

If it's wrong, bad or
stupid, let me just say that
I am not surprised.

- author unknown

User login

Navigation

More Drupal hotness

Powered by Drupal, an open source content management system