You are here

form_builder.module in Form Builder 6

Same filename and directory in other branches
  1. 7.2 form_builder.module
  2. 7 form_builder.module

form_builder.module Generic form building framework and user interface.

File

form_builder.module
View source
<?php

/**
 * @file form_builder.module
 * Generic form building framework and user interface.
 */
define('FORM_BUILDER_ROOT', 0);

/**
 * Implementation of hook_menu().
 */
function form_builder_menu() {
  $items = array();
  $items['admin/build/form-builder/add'] = array(
    'title' => 'Add field',
    'description' => 'Add a field to a form.',
    'page callback' => 'form_builder_add_page',
    'access callback' => 'form_builder_menu_field_access',
    'access arguments' => array(
      'add',
      4,
      5,
      6,
    ),
    'file' => 'includes/form_builder.admin.inc',
    'type' => MENU_CALLBACK,
  );
  $items['admin/build/form-builder/clone'] = array(
    'title' => 'Clone field',
    'description' => 'Clone a field within a form.',
    'page callback' => 'form_builder_clone_page',
    'access callback' => 'form_builder_menu_field_access',
    'access arguments' => array(
      'clone',
      4,
      5,
      6,
    ),
    'type' => MENU_CALLBACK,
    'file' => 'form_builder.admin.inc',
    'file path' => drupal_get_path('module', 'form_builder') . '/includes',
  );
  $items['admin/build/form-builder/configure'] = array(
    'title' => 'Configure field',
    'description' => 'Configure a field within a form.',
    'page callback' => 'form_builder_configure_page',
    'access callback' => 'form_builder_menu_field_access',
    'access arguments' => array(
      'configure',
      4,
      5,
      6,
    ),
    'file' => 'includes/form_builder.admin.inc',
    'type' => MENU_CALLBACK,
  );
  $items['admin/build/form-builder/remove'] = array(
    'title' => 'Remove field',
    'description' => 'Remove a field from a form.',
    'page callback' => 'form_builder_remove_page',
    'access callback' => 'form_builder_menu_field_access',
    'access arguments' => array(
      'remove',
      4,
      5,
      6,
    ),
    'file' => 'includes/form_builder.admin.inc',
    'type' => MENU_CALLBACK,
  );
  $items['admin/build/form-builder/json'] = array(
    'title' => 'JSON representation',
    'description' => 'Display a form field as a JSON string.',
    'page callback' => 'form_builder_field_json',
    'access callback' => 'form_builder_menu_field_access',
    'access arguments' => array(
      'view',
      4,
      5,
      6,
    ),
    'file' => 'includes/form_builder.admin.inc',
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/**
 * Implements hook_theme().
 */
function form_builder_theme() {
  return array(
    'form_builder_wrapper' => array(
      'arguments' => array(
        'element' => NULL,
        'content' => NULL,
      ),
      'file' => 'includes/form_builder.admin.inc',
    ),
    'form_builder_element_wrapper' => array(
      'arguments' => array(
        'element' => NULL,
        'content' => NULL,
      ),
      'file' => 'includes/form_builder.admin.inc',
    ),
    'form_builder_empty_form' => array(
      'arguments' => array(),
      'file' => 'includes/form_builder.admin.inc',
    ),
    'form_builder_empty_fieldset' => array(
      'arguments' => array(),
      'file' => 'includes/form_builder.admin.inc',
    ),
    'form_builder_no_field_selected' => array(
      'variables' => array(),
      'file' => 'includes/form_builder.admin.inc',
    ),
    'form_builder_field_loading' => array(
      'variables' => array(),
      'file' => 'includes/form_builder.admin.inc',
    ),
    'form_builder_field_palette' => array(
      'arguments' => array(
        'fields' => NULL,
        'groups' => NULL,
        'form_type' => NULL,
        'form_id' => NULL,
      ),
      'file' => 'includes/form_builder.admin.inc',
    ),
  );
}

/**
 * Implements hook_block_info().
 */
function form_builder_block_info() {
  $blocks = array();
  $blocks['fields'] = array(
    'info' => t('Form builder fields'),
    'weight' => 0,
  );
  return $blocks;
}

/**
 * Implements hook_block().
 */
function form_builder_block($op = 'list', $delta = 0, $edit = array()) {
  if ($op == 'list') {
    return form_builder_block_info();
  }
  if ($op == 'view') {
    return form_builder_block_view($delta);
  }
}

/**
 * Implements hook_block_view().
 */
function form_builder_block_view($delta = '') {
  $block = array();
  if ($delta == 'fields' && form_builder_active_form()) {
    module_load_include('inc', 'form_builder', 'includes/form_builder.admin');
    $block['content'] = form_builder_field_palette();
  }
  return $block;
}

/**
 * Access callback for field configuration, viewing, addition, and deletion.
 */
function form_builder_menu_field_access($op, $form_type, $form_id, $element_id) {
  module_load_include('inc', 'form_builder', 'includes/form_builder.api');
  module_load_include('inc', 'form_builder', 'includes/form_builder.cache');
  $element = form_builder_cache_field_load($form_type, $form_id, $element_id);
  $access = FALSE;
  if ($op == 'add' || $op == 'view') {
    $access = TRUE;
  }
  if ($op == 'clone') {

    // Unique fields cannot be cloned (or otherwise they would not be unique).
    // Cloning fieldsets is also not currently supported.
    $fields = form_builder_get_form_type($form_type);
    $access = !empty($element['#form_builder']['element_type']) && empty($fields[$element['#form_builder']['element_type']]['unique']) && $element['#form_builder']['element_type'] != 'fieldset';
  }
  if ($op == 'configure' && !empty($element['#form_builder']['configurable'])) {
    $access = TRUE;
  }
  if ($op == 'remove' && !empty($element['#form_builder']['removable'])) {
    $access = TRUE;
  }
  $module_accesses = module_invoke_all('form_builder_field_access', $op, $form_type, $form_id, $element);
  if (!empty($module_accesses)) {
    $access = array_pop($module_accesses);
  }
  return $access;
}

/**
 * Implementation of hook_form_builder_properties().
 */
function form_builder_form_builder_properties($form_type) {
  module_load_include('inc', 'form_builder', 'includes/form_builder.properties');
  return array(
    'key' => array(
      'form' => 'form_builder_property_key_form',
    ),
    'title' => array(
      'form' => 'form_builder_property_title_form',
    ),
    'title_display' => array(
      'form' => 'form_builder_property_title_display_form',
    ),
    'description' => array(
      'form' => 'form_builder_property_description_form',
    ),
    'disabled' => array(
      'form' => 'form_builder_property_disabled_form',
    ),
    'weight' => array(
      'form' => 'form_builder_property_weight_form',
    ),
    'default_value' => array(
      'form' => 'form_builder_property_default_value_form',
    ),
    'markup' => array(
      'form' => 'form_builder_property_markup_form',
    ),
    'input_format' => array(
      'form' => 'form_builder_property_input_format_form',
    ),
    'maxlength' => array(
      'form' => 'form_builder_property_maxlength_form',
    ),
    'required' => array(
      'form' => 'form_builder_property_required_form',
    ),
    'options' => array(
      'form' => 'form_builder_property_options_form',
      'submit' => array(
        'form_builder_property_options_form_submit',
      ),
    ),
    'size' => array(
      'form' => 'form_builder_property_size_form',
    ),
    'rows' => array(
      'form' => 'form_builder_property_rows_form',
    ),
    'cols' => array(
      'form' => 'form_builder_property_cols_form',
    ),
    'field_prefix' => array(
      'form' => 'form_builder_property_field_prefix_form',
    ),
    'field_suffix' => array(
      'form' => 'form_builder_property_field_suffix_form',
    ),
    'collapsible' => array(
      'form' => 'form_builder_property_collapsible_form',
    ),
    'collapsed' => array(
      'form' => 'form_builder_property_collapsed_form',
    ),
  );
}

/**
 * Implementation of hook_form_builder_property_groups().
 */
function form_builder_form_builder_property_groups($form_type) {
  return array(
    'default' => array(
      'weight' => 0,
      'title' => t('Properties'),
    ),
    'hidden' => array(
      'weight' => 100,
      'title' => t('Advanced'),
      'collapsed' => TRUE,
      'collapsible' => TRUE,
    ),
    'display' => array(
      'weight' => 1,
      'title' => t('Display'),
    ),
    'options' => array(
      'weight' => 2,
      'title' => t('Options'),
    ),
    'validation' => array(
      'weight' => 3,
      'title' => t('Validation'),
    ),
  );
}

/**
 * Implementation of hook_form_builder_palette_groups().
 */
function form_builder_form_builder_palette_groups() {
  return array(
    'default' => array(
      'weight' => 0,
      'title' => t('Standard'),
    ),
    'special' => array(
      'weight' => 5,
      'title' => t('Special'),
    ),
  );
}

/**
 * Implementation of hook_form_builder_validators().
 */
function form_builder_form_builder_validators($form_type) {
  return array(
    'form_validate_integer' => array(
      'form' => 'form_builder_validate_integer',
    ),
    'form_validate_decimal' => array(
      'form' => 'form_builder_validate_decimal',
    ),
    'form_validate_email' => array(
      'form' => 'form_builder_validate_email',
    ),
    'form_validate_url' => array(
      'form' => 'form_builder_validate_url',
    ),
  );
}

/**
 * Static storage of the current type of form being edited (if any).
 *
 * @param $new_type_name
 *   The name of the type being edited. If this value is passed in, the static
 *   variable is set. If this parameter is ommited, the current type is
 *   returned. Pass in FALSE to reset current type.
 */
function form_builder_active_form($new_type = NULL, $new_id = NULL) {
  static $active_form = FALSE;
  if (isset($new_type) && isset($new_id)) {
    if (!$new_type && !$new_id) {
      $active_form = FALSE;
    }
    else {
      $active_form['form_type'] = $new_type;
      $active_form['form_id'] = $new_id;
    }
  }
  return $active_form;
}

/**
 * A #post_render callback to backport Drupal 7's #theme_wrappers.
 *
 * This #after_build function can be added to any form element to make it
 * process #form_builder_wrappers functions which act in the same way as
 * Drupal 7's #theme_wrappers functions.
 */
function form_builder_wrappers($content, $elements) {
  if (isset($elements['#form_builder_wrappers'])) {
    foreach ($elements['#form_builder_wrappers'] as $theme_wrapper) {
      $content = theme($theme_wrapper, $elements, $content);
    }
  }
  return $content;
}

/**
 * Generic validation function to check that an element has a integer value.
 */
function form_validate_integer(&$element, &$form_state) {
  $value = $element['#value'];
  if (empty($value)) {
    return;
  }

  // Remove thousands separators from numbers.
  $locale_info = localeconv();
  $separator = empty($locale_info['thousands_sep']) ? ',' : $locale_info['thousands_sep'];
  $new_value = str_replace(array(
    ' ',
    $separator,
  ), '', $value);
  $int_value = $new_value * 1;
  $new_value = (string) $int_value;
  if (!is_int($int_value) || $int_value === 0) {
    form_error($element, t('The %title field value must be an integer.', array(
      '%title' => $element['#title'],
    )));
  }
  elseif ($new_value !== $value) {
    form_set_value($element, $new_value, $form_state);
  }
}

/**
 * Generic validation function to check that an element has a decimal value.
 */
function form_validate_decimal(&$element, &$form_state) {
  $value = $element['#value'];
  if (empty($value)) {
    return;
  }

  // Remove thousands separators from numbers.
  $locale_info = localeconv();
  $separator = empty($locale_info['thousands_sep']) ? ',' : $locale_info['thousands_sep'];
  $new_value = str_replace(array(
    ' ',
    $separator,
  ), '', $value);
  $float_value = $new_value * 1.0;
  $new_value = (string) $float_value;
  if (!is_float($float_value) || $float_value === 0.0) {
    form_error($element, t('The %title field value must be a decimal.', array(
      '%title' => $element['#title'],
    )));
  }
  elseif ($new_value !== $value) {
    form_set_value($element, $new_value, $form_state);
  }
}

/**
 * Generic validation function to check for a valid e-mail value.
 */
function form_validate_email(&$element, &$form_state) {
  if (empty($element['#value'])) {
    return;
  }
  if (valid_email_address($element['#value'])) {
    form_error($element, t('The %title field value must be a valid e-mail address.', array(
      '%title' => $element['#title'],
    )));
  }
}

/**
 * Generic validation function to check for a valid url value.
 */
function form_validate_url(&$element, &$form_state) {
  if (empty($element['#value'])) {
    return;
  }
  if (valid_url($element['#value'], isset($element['#absolute_url']) ? $element['#absolute_url'] : TRUE)) {
    form_error($element, t('The %title field value must be a valid URL.', array(
      '%title' => $element['#title'],
    )));
  }
}

Functions

Namesort descending Description
form_builder_active_form Static storage of the current type of form being edited (if any).
form_builder_block Implements hook_block().
form_builder_block_info Implements hook_block_info().
form_builder_block_view Implements hook_block_view().
form_builder_form_builder_palette_groups Implementation of hook_form_builder_palette_groups().
form_builder_form_builder_properties Implementation of hook_form_builder_properties().
form_builder_form_builder_property_groups Implementation of hook_form_builder_property_groups().
form_builder_form_builder_validators Implementation of hook_form_builder_validators().
form_builder_menu Implementation of hook_menu().
form_builder_menu_field_access Access callback for field configuration, viewing, addition, and deletion.
form_builder_theme Implements hook_theme().
form_builder_wrappers A #post_render callback to backport Drupal 7's #theme_wrappers.
form_validate_decimal Generic validation function to check that an element has a decimal value.
form_validate_email Generic validation function to check for a valid e-mail value.
form_validate_integer Generic validation function to check that an element has a integer value.
form_validate_url Generic validation function to check for a valid url value.

Constants

Namesort descending Description
FORM_BUILDER_ROOT @file form_builder.module Generic form building framework and user interface.