background image

Content tagged with: form_state

Eric's picture

In this snippet, I'll show you how you can submit a webform programmatically using drupal_execute(). The first thing you'll need to do is figure out what the $form_state data looks like when the webform is submitted, so you can recreate that structure and pass it into drupal_execute().

One way to accomplish this is to add a validation/submit handler to the form using hook_form_alter() and then output the contents of the submitted data (using krumo, print_r, etc).

The following code will prepend a validation handler to the webform $form, so we can dump the submitted data to the screen:

<?php
function MYMODULE_form_alter(&$form, $form_state, $form_id) {
 
 
// define node id of webform
 
$webform_node_id = 146;
 
 
// check for form id of webform
 
if ($form_id == 'webform_client_form_' . $webform_node_id) {
 
   
// prepend a validation callback to the form
   
array_unshift($form['#validate'],
     
'_MYMODULE_form_alter_webform_' . $webform_node_id . '_validate');
 
  }
 
}
?>

And here is the validation handler which will dump the submitted data to the screen. NOTE: krumo() is available from the devel module; you could use print_r() as well:

<?php
function _MYMODULE_form_alter_webform_146_validate($form, &$form_state) {
 
// debug
 
krumo($form_state);
  die;
}
?>

Now, if I populate the webform with some data:

And submit the form, I will get the following debug output:

You'll need to mirror the structure of the submitted data when creating your $form_state variable, which will be passed into drupal_execute().

In the following function, I show how you can submit a webform programmatically. There is even additional code in there which loads a user's previously submitted data, if you care.

<?php
function MYMODULE_some_function() {

 
// define webform node id
 
$webform_node_id = 146;

 
// define user submitting the webform
 
$user_id = 2;

 
// load webform node
 
if ($node = node_load($webform_node_id)) {

   
// load module include file, per loading previously submitted webform data
   
module_load_include('inc', 'webform', 'webform_report');

   
// get submissions for user
   
$submissions = webform_get_submissions($node->nid, NULL, $user_id);

   
// get submission data ($submission) and submission id ($sid)
   
if (FALSE !== ($sid = key($submissions))) {
     
$submission = $submissions[$sid];
    }
    else {
     
$submission = NULL;
     
$sid = NULL;
    }

   
// create array of $form_state data
    // NOTE: be sure to use the debug output as a guide to make this array match!
   
$form_state = array(
     
'submitted' => true,
     
'values' => array(
       
'submission' => $submission,
       
'submitted' => array(
         
'test_field_1' => 'abc',
         
'test_field_2' => '123',
         
'test_field_3' => 'def',
        ),
       
'details' => array(
         
'email_subject' => $node->webform['email_subject'],
         
'email_from_name' => $node->webform['email_from_name'],
         
'email_from_address' => $node->webform['email_from_address'],
         
'nid' => $webform_node_id,
         
'sid' => $sid,
        ),
       
'op' => t('Submit'),
       
'submit' => t('Submit'),
       
'form_id' => 'webform_client_form_'. $webform_node_id,
      ),
    );

   
// Saves the webform data submited prior to login.
   
drupal_execute('webform_client_form_'. $webform_node_id, $form_state, $node, $submission, TRUE, FALSE);
   
  }

}
?>

Eric's picture

drupal_execute() is great for processing a form and drupal_get_form() is great for generating the html for a form, but what if you'd like to load the $form object to modify or embed it?

<?php
// include drupal's node include file
require("modules/node/node.pages.inc");

// create an empty $form_state array
$form_state = array();

// define the content type of the form you'd like to load
$nodeType = 'MYCCKNODETYPE';

// create a string of the $form_id
$form_id = $nodeType . '_node_form';

// create a basic $node array
$node = array('type' => $nodeType, 'uid' => $GLOBALS['user']->uid, 'name' => $GLOBALS['user']->uid);

// load the $form
$form = drupal_retrieve_form($form_id, $form_state, $node);

// prepare the $form
drupal_prepare_form($form_id, $form, $form_state);

// show the form structure, debug
echo "<PRE>";
print_r($form);
echo
"</PRE>";
?>

Eric's picture

Here are some tips on how to create a node programmatically in a Drupal module. The safest way to create a node is to use the drupal_execute() function which simulates the submission of a form [see API documentation]. This function accepts a variable number of arguments: 1) $form_id; 2) $form_state; and 3) any additional arguments. When creating a new node, the 3rd argument should be a $node object.

The $form_id should be formatted: NODETYPE_node_form. To confirm this, you could use hook_form_alter to show the form IDs for the current page (NOTE: you'll have to be on node/add/NODETYPE to display the node form ID).

<?php
function MYMODULE_form_alter(&$form, $form_state, $form_id) {
  echo
$form_id . "<BR>";
}
?>

For the second argument, you'll have to create an array that contains $form_state values (the data submitted from the node/add/NODETYPE form). Here is a basic $form_state array:

<?php
$form_state
= array();
$form_state['values'] = array(
 
'title' => t('MYTITLE'),
 
'body' => t('MYBODY'),
 
'name' => $GLOBALS['user']->name,
 
'op' => t('Save'),
);
?>

If you are creating a more complex node type, you'll want to include more information in in the $form_state['values'] array. I find it helpful to view the submitted node form data using the following code:

<?php
function MYMODULE_form_alter(&$form, $form_state, $form_id) {
 
// ensure we are modifying the right node type
 
if ($form_id == 'NODETYPE_node_form') {
   
// add an additional validation handler
   
$form['#validate'][] = '_MYMODULE_node_form_validate';
  }
}

function
_MYMODULE_node_form_validate($form, &$form_state) {
 
// display the submitted data and then die
 
echo "<pre>";
 
print_r($form_state['values']);
  echo
"</pre>";
  die;
}
?>

Now, if you create a test node (node/add/NODETYPE), you'll see the data that's being submitted from the form. NOTE: be sure to remove these two functions when you are familiar with the structure of the $form_state variable.

The 3rd argument will be a (mostly) empty $node object containing the node type:

<?php
$node
= (object) NULL;
$node->type = 'NODETYPE';
?>

Here's a code snippet that shows all the pieces together:

<?php
// create $form_state
$form_state = array();
$form_state['values'] = array(
 
'title' => t('MYTITLE'),
 
'body' => t('MYBODY'),
 
'name' => $GLOBALS['user']->name,
 
'op' => t('Save'),
);

// create $node
$node = (object) NULL;
$node->type = 'NODETYPE';

// include node file, necessary for node generation
module_load_include('inc', 'node', 'node.pages');

// create node using drupal_execute
drupal_execute('NODETYPE_node_form', $form_state, $node);
?>