function drupal_form_submit

You are here

7 form.inc drupal_form_submit($form_id, &$form_state)
8 form.inc drupal_form_submit($form_arg, &$form_state)

Retrieves, populates, and processes a form.

This function allows you to supply values for form elements and submit a form for processing. Compare to drupal_get_form(), which also builds and processes a form, but does not allow you to supply values.

There is no return value, but you can check to see if there are errors by calling form_get_errors().

// register a new user
$form_state = array();
$form_state['values']['name'] = 'robo-user';
$form_state['values']['mail'] = 'robouser@example.com';
$form_state['values']['pass']['pass1'] = 'password';
$form_state['values']['pass']['pass2'] = 'password';
$form_state['values']['op'] = t('Create new account');
drupal_form_submit('user_register_form', $form_state);

Parameters

$form_id: The unique string identifying the desired form. If a function with that name exists, it is called to build the form array. Modules that need to generate the same form (or very similar forms) using different $form_ids can implement hook_forms(), which maps different $form_id values to the proper form constructor function. Examples may be found in node_forms() and search_forms().

$form_state: A keyed array containing the current state of the form. Most important is the $form_state['values'] collection, a tree of data used to simulate the incoming $_POST information from a user's form submission. If a key is not filled in $form_state['values'], then the default value of the respective element is used. To submit an unchecked checkbox or other control that browsers submit by not having a $_POST entry, include the key, but set the value to NULL.

...: Any additional arguments are passed on to the functions called by drupal_form_submit(), including the unique form constructor function. For example, the node_edit form requires that a node object be passed in here when it is called. Arguments that need to be passed by reference should not be included here, but rather placed directly in the $form_state build info array so that the reference can be preserved. For example, a form builder function with the following signature:

  function mymodule_form($form, &$form_state, &$object) {
  }
  

would be called via drupal_form_submit() as follows:

  $form_state['values'] = $my_form_values;
  $form_state['build_info']['args'] = array(&$object);
  drupal_form_submit('mymodule_form', $form_state);
  

For example:

Related topics

6 calls to drupal_form_submit()
aggregator_form_opml_submit in modules/aggregator/aggregator.admin.inc
Form submission handler for aggregator_form_opml().
batch_test_programmatic in modules/simpletest/tests/batch_test.module
Menu callback: programmatically submits the 'Chained' form.
FormsProgrammaticTestCase::submitForm in modules/simpletest/tests/form.test
Helper function used to programmatically submit the form defined in form_test.module with the given values.
install_run_task in includes/install.core.inc
Runs an individual installation task.
openid_authentication in modules/openid/openid.module
Authenticate a user or attempt registration.

... See full list

File

includes/form.inc, line 720
Functions for form and batch generation and processing.

Code

function drupal_form_submit($form_id, &$form_state) {
  if (!isset($form_state['build_info']['args'])) {
    $args = func_get_args();
    array_shift($args);
    array_shift($args);
    $form_state['build_info']['args'] = $args;
  }
  // Merge in default values.
  $form_state += form_state_defaults();

  // Populate $form_state['input'] with the submitted values before retrieving
  // the form, to be consistent with what drupal_build_form() does for
  // non-programmatic submissions (form builder functions may expect it to be
  // there).
  $form_state['input'] = $form_state['values'];

  $form_state['programmed'] = TRUE;
  $form = drupal_retrieve_form($form_id, $form_state);
  // Programmed forms are always submitted.
  $form_state['submitted'] = TRUE;

  // Reset form validation.
  $form_state['must_validate'] = TRUE;
  form_clear_error();

  drupal_prepare_form($form_id, $form, $form_state);
  drupal_process_form($form_id, $form, $form_state);
}

Comments

In Drupal 6, this function was called:
http://api.drupal.org/api/function/drupal_execute/6

Needing a "Create a new node" example, like in the Drupal 6 drupal_execute() documentation.

Could you please post one?!

I use this code to create a new node . but the big problem is that I can't insert data into a custom field ??!! Can anybody help

<?php
define
('DRUPAL_ROOT', getcwd());

include_once

DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

bootstrap_invoke_all('init');
ini_set('memory_limit', '512M');

//Authenticate as user 1
user_authenticate('user', 'password');

module_load_include('inc', 'node', 'node.pages');  // new for Drupal 6

  

$form_state = array();
  
$nodeTmp = array('type' => testimonial); // a variable holding the content type

  

$form_state['values']['type'] = 'testimonial';
  
$form_state['values']['status'] = 1;
  
$form_state['values']['title'] = 'test1';   // the node's title
  
$form_state['values']['body'] = 'just my test node'; // the body, not required
  
$form_state['values']['field_name'] =  t('adham allam');
  
$form_state['values']['status'] = 1; //publish all imported nodes
  
$form_state['values']['promote'] = 1; //promote all imported nodes
  
$form_state['values']['sticky'] = 0; //remove sticky from imported nodes
  
$form_state['values']['image'] = array();
  
$form_state['values']['name'] = 'adham';
  
$form_state['values']['op'] = t('Save');  // this seems to be a required value
 

drupal_form_submit('testimonial_node_form', $form_state, (object)$nodeTmp);
?>

Same as above but you need to copy the $form_state values from the specific node content type with the custom field you want to populate.

$form_state['values']['field_legacy_reference_id'] = array(
  'und' => array(
    array(
      'value' => $key,
    ),
  ),
);

You can get that data structure with hook_node submit in a little 3 line module.

function your_module_name_node_submit($node, $form, &$form_state) {
  var_dump($form_state);
}

Then manually create a piece of content and you'll get the full data structure for that content type, custom fields and all.

e.g. you have the file, and need to tell drupal it's part of a new node you're creating.

Seen exampled for Drupal 6, but not 7.

Couldn't find in drupal 7, got some hint but still not successfull:(

$filename = 'test.jpg';
$image = file_get_contents('http://test.com/images/M/MV5BNjkyOTI5MDA0Ml5BMl5BanBnXkFtZTcwOTU3NzExNw@@._V1._SY0.jpg');
$file = file_save_data($image, 'public://images/poster/' . $filename, FILE_EXISTS_REPLACE);
prd($file);
$temp = $file->fid.$i;

$form_state['values']['field_poster']['und'] = array( 'fid'=>$temp, 'filename'=>$file->filename, 'uri'=>$file->uri, 'filemime'=>$file->filemime, 'filesize'=>$file->filesize, 'display' => '1',
'width' => '743',
'height' => '1100');

a file field can yield multiple files and is always an array:
$form_state['values']['field_poster']['und'][0]=....
$form_state['values']['field_poster']['und'][1]=....

so i guess your code should be like:
$form_state['values']['field_poster']['und'][] = array( 'fid'=>$temp, 'filename'=>$file->filename, 'uri'=>$file->uri, 'filemime'=>$file->filemime, 'filesize'=>$file->filesize, 'display' => '1',
'width' => '743',
'height' => '1100');

Needing a "webform submit" example.

I realize this is old, but it popped up in my search when looking for an answer. Hope this helps someone else!

<?php
$webform_node_id
= [num];

if (

$node = node_load($webform_node_id)){
 
$form_state = array(
   
'values' => array(
      [
value_1_machine_name] => [value_1],
      [
value_2_machine_name] => [value_2],
     
'op' => t('Submit'),
    ),
  );

 

//need to set the submitted key in the values, as this is required by webform
 
$form_state['values']['submitted'] = $form_state['values'];

 

drupal_form_submit('webform_client_form_'. $webform_node_id, $form_state, $node, array());
  if (
form_get_errors() != '') {
    print
'Webform_Error';
    print
'<pre>'.print_r(form_get_errors(), 1).'</pre>';
  }
  else print
'Webform_Success';
}
?>

You can grab the value machine names from the Field Key field when editing form components.
Be sure to check the 'op' variable, as my submission did not succeed without this item
If you do not set a value for a required component you will receive an error explaining this.

This code was used in a custom php script to submit a webform.

Can node_save() be used in place of drupal_form_submit() ?

node_save is somewhat easier to use, but drupal_form_submit (which in the end also calls node_save through node_form_submit) additionally fires up the form hooks, which other modules can listen to and react upon. So by using drupal_form_submit your module is more flexible and can better interact with other modules.

I have a custom module which creates a multi-step user registration form, and am trying to display the validation errors in a more user-friendly way (ie. not lumped together in the error messages output).
I can't get form_get_errors() to return anything, no matter where I put it in my custom module.
I first tried calling it in my _form_alter hook, then in my _submit callback, I then saw (here: http://drupal.stackexchange.com/questions/28355/hook-form-alter-isnt-bei... ) a suggestion to user #after_build, so I've added an #after_build callback function "mi_register_check_errors":

<?php
function mi_register_check_errors($element) {
   
$errors = form_get_errors();
    if (
$errors ) {
       
drupal_set_message(print_r($errors,true));
    } else {
       
drupal_set_message("errors = false");
    }

   

$elemerror = form_get_error($element);
    if (
$elemerror ) {
       
drupal_set_message(print_r($elemerror,true));
    } else {
       
drupal_set_message("elemerror = false");
    }
    return
$element;
}
?>

Now if I load the form, submit it and get validation errors (form reloads with fields given error class), or submit it correctly; the only thing I ever get is that there's no error.

Any ideas how I can get form_get_errors to actually return something if there's an error?
(I'm using #limit_validation on my multi-step form so that only the submitted fields are validated when the user clicks the 'next' button)

It seems form_get_errors() returns false in most places. I think the errors are processed and then cleared so they're not accessible at the point I was checking them.

The solution is to check the errors in a validate callback:
In my MYMODULE_register_form_user_register_form_alter() function:

<?php
$form
['#validate'][] = 'MYMODULE_register_register_validate';
?>

And then the validate handler:

<?php

/**
* Validate handler.
*/
function MYMODULE_register_register_validate(&$form, &$form_state) {
//validate does not actually validate -just prefixes error messages to fields that have errors:
   
$errors = form_get_errors();
    if (
$errors ) {
        foreach (
$errors as $name=>$value ) {
            if ( isset(
$form['account'][$name] ) ) {
               
$form['account'][$name]['#prefix'] = '<div class="pretty error">' . $value . '</div>';
            }
        }
    }
}
?>

We have a form search form with basic criteria (name, id, etc...) and a submit button with say URL /search/invites/<id> where IFF <id> is passed in we would like to set the criteria to the value of <id> and automatically submit the form.

I tried drupal_submit_form HOWEVER to my dismay it does not return the resulting form. So I cloned the method and modified it to have it simply return the form however on any subsequent form submit I get that the form is outdate and needs to be reloaded.

While I see the benefit of programmatic form submit WITHOUT form results HOW does one go about doing programmatic form submit **WITH** corresponding form results?

I find I am going to all sorts of crazy lengths just to get something so simple to work... there MUST be an easier solution that I am simply missing.

After updating with this security patch, I can't retrieve my URL parameter from the query string. I attempted using arg() and nothing there either. The system appears to be preventing access .. is this the case? If so what is the work around. I have data the is pulled into the node from another database - the URL parameter defines the data lookup.