Skip to main content

Programmatic Form Submission in Drupal

Feb 14 '14

For non-coders, GUIs are essential, but as a developer, I abhor them. At Third and Grove we are in a constant cycle of development and releases, adding myriad new features to our client’s websites and web applications. The last thing we want to be doing on launch day is a bunch of manual configuration (prancing around the GUI, creating content types, adding fields etc.). In our development cycle, automation is essential, not just in ensuring the high quality of our products, but also in eliminating human error.

On the exterior Drupal is highly GUI based, but peek beneath the hood, and you will find a very powerful framework in place for configuring Drupal programatically. There is nothing that can’t be done with code alone. Only very rarely is this not practical. Today I would like to discuss an important aspect of this automated approach: programmatically submitting Drupal forms.

The most simple approach to programmatic form submission in drupal would be to find the form, figure out what the submit handler does, and mimic its behavior. This approach can work, but there are often cases where tracing the path of a submission handler is slightly daunting. This is especially true of system forms. Many system forms seem to simply set their values as drupal variables, yet on closer examination contain a web of processes, running only on certain fields or in certain contexts. Tracking all of these down often isn’t practical.

Today I would like to share a small little function, built into Drupal core, that I have found invaluable in the automation of Drupal development, drupal_form_submit.

To illustrate the proper usage, I would like to draw on an actually example that was recently implemented on one of our projects. The client had several .pdf’s that needed to be accessible only to registered users. In order to do this properly, we needed configure Drupal’s private file directory. At first glance, Drupal’s core file system form seems rather simple to submit, there is a field for the file path to the private files directory, and that’s it. Enter a path and you’re done. If you look at the database before and after submitting the form, this path is tracked as a Drupal variable in the variables table.

public file system path

But if you try just setting the variable your private files directory won’t work. This is because this form, on submit, actually winds through core and creates an .htaccess file in the specified private directory for to control access. Trying to program this small carpet ride manually would be cumbersome, and this is where drupal_form_submit comes in.

module_load_include('inc', 'system', 'system.admin');
$form_state = array();
$form_state['values']['file_private_path'] = "YOUR PRIVATE FILE PATH";
$form_state['values']['op'] = 'Save configuration';
drupal_form_submit('system_file_system_settings', $form_state);

You simply include the file that holds the form callback. Then you make the same changes to form state that you would have made if you had submitted the form manually, and voila, you are done! The last part, ‘op’, is important, because some drupal forms have several different operations built into them. In order to discover what the correct op is, just inspect the submit button in any code debugger. You’ll notice that the name of the submit button defaults to ‘op’, hence the ‘value’ attribute is what you need to capture. Drupal uses the value of the submit button on forms with multiple operations in order to determine which operation to perform.

inspect submit

Using drupal_form_submit is by far the best approach to programmatic form submission because it is the functional equivalent of submitting the form manually. Drupal actually uses this function whenever a form is submitted through the GUI.

The possibilities are endless for programmatic form submission, and no more time need be wasted romping around through dense modules or core trying to figure out what is happening with forms, unless (like me) you are so inclined :-).