How to create and submit Webform programmatically in Drupal 7

There is a debate going on for years in the Drupal world — what module is the best for building survey-like forms for the website — Webform or Entityform.

Each approach has its own positive and negative sides depending on what are you going to achieve, however very often the argument against Webform is that Webforms are not deployable. Or, they are «sort of» deployable, but it takes more effort to create them programmatically.

To debunk this myth I will demonstrate how to create a simple Webform and submit it without a single mouse click. You can use the code in your hook_update_N or any other deployment or migration script.

The code was tested against the Webform version 7.x-4.12, so I guess it’ll work on any 4.x release.

We will create four popular element types:

  • Single choice select
  • Multiple choice select
  • Free text input
  • Matrix (grid) question

The code is not ready for production and should be adapted to your needs first.

Create a Webform node and attach a form to it

<?php

// Create a node to hold the webform.
$node = new stdClass();
$node->type = 'webform';
node_object_prepare($node);  
$node->title = 'Contact Us';
$node->uid = 1;
$node->status = 1;
$node->promote = 0;
$node->comment = 0;
$node->path = array('alias' => 'sample-form', 'pathauto' => FALSE);

// Save the node in the database.
$node = node_submit($node);
node_save($node);

// Create the webform components.
$components = array(
  array(
    'name' => 'Single choice',
    'form_key' => 'single_choice',
    'type' => 'select',
    'required' => 1,
    'weight' => 0,
    'pid' => 0,
    'extra' => array(
      'multiple' => 0,
      'private' => 0,
      'items' => "first|first\nsecond|second\nthird|third",
      'aslist' => 1,
      'analysis' => TRUE,
    ),
  ),
  array(
    'name' => 'Multiple choice',
    'form_key' => 'multiple_choice',
    'type' => 'select',
    'required' => 1,
    'weight' => 1,
    'pid' => 0,
    'extra' => array(
      'multiple' => 1,
      'private' => 0,
      'items' => "first|first\nsecond|second\nthird|third",
      'aslist' => 0,
      'analysis' => TRUE,
    ),
  ),
  array(
    'name' => 'Free text',
    'form_key' => 'free_text',
    'type' => 'textarea',
    'required' => 1,
    'weight' => 2,
    'pid' => 0,
    'extra' => array(
      'resizable' => 1,
      'private' => 0,
      'items' => "first|first\nsecond|second\nthird|third",
      'analysis' => FALSE,
    ),
  ),
  array(
    'name' => 'Matrix question',
    'form_key' => 'matrix',
    'type' => 'grid',
    'required' => 0,
    'weight' => 3,
    'pid' => 0,
    'extra' => array(
      'description' => t('Choose one of the options'),
      'private' => 0,
      'sticky' => 1,
      'unique' => 0,
      'options' => "bad|bad\ngood|good\nexcellent|excellent",
      'questions' => "quality|quality\nspeed|speed\nprice|price",
      'analysis' => TRUE,
    ),
  ),
);

if (webform_ensure_record($node)) {

  // Set up a few webform defaults and attach components.
  $node->webform['redirect_url'] = '<front>';
  $node->webform['components'] = $components;
}

node_save($node);  

Create a Webform submission

<?php

// Get the node ID of the created Webform and load the node.
$node = node_load($nid);
$uid = 1;

// Include files.
module_load_include('inc', 'webform', 'webform.module');  
module_load_include('inc', 'webform', 'includes/webform.submissions');

// Prepare the data for submission.
$data = array(
  'single_choice' => array('first' => 'first'),
  'free_text' => 'Some random text,
);

// Arrange $data in the way Webform expects it.
$data = _webform_client_form_submit_flatten($node, $data);
$data = webform_submission_data($node, $data);

$submission = (object) array(
  'nid' => $nid,
  'uid' => $uid,
  'submitted' => REQUEST_TIME,
  'remote_addr' => ip_address(),
  'is_draft' => FALSE,
  'data' => $data,
);

webform_submission_insert($node, $submission);

For more elements or advanced usage install Devel module and use its output to adjust the snippets above.

That’s it. Have fun with Webforms!