ife.module in Inline Form Errors 7
Same filename and directory in other branches
Drupal hooks
@author Stijn De Meyere
File
ife.moduleView source
<?php
// $Id$
/**
* @file
* Drupal hooks
*
* @author Stijn De Meyere
*/
/**
* Implements hook_menu().
*/
function ife_menu() {
$items = array();
$items['admin/config/user-interface/ife'] = array(
'title' => 'Inline Form Errors',
'description' => 'Administer which forms to use with field messages.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'ife_settings_form',
),
'access arguments' => array(
'administer inline form errors',
),
'type' => MENU_NORMAL_ITEM,
'file' => 'ife.settings.inc',
);
$items['admin/config/user-interface/ife/%ife_form_id/delete'] = array(
'title' => 'Delete form_id',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'ife_form_id_delete_form',
3,
),
'access arguments' => array(
'administer inline form errors',
),
'type' => MENU_CALLBACK,
'file' => 'ife.settings.inc',
);
return $items;
}
/**
* Implements hook_permission().
*/
function ife_permission() {
return array(
'administer inline form errors' => array(
'title' => t('administer inline form errors'),
'description' => t('TODO Add a description for \'administer inline form errors\''),
),
);
}
/**
* Implements hook_help().
*/
function ife_help($path, $arg) {
switch ($path) {
case 'admin/help#ife':
$output = '<p>' . t('IFE or Inline Form Errors allows you to place form submission error inline with the form elements. Three options are provided for setting your inline error behaviour. You can configure the default behaviour or override the behaviour on a per form basis. You can add as many forms as you like.') . '</p>';
$output .= '<p>' . t('IFE provides three behaviours for the configured forms') . '</p>';
$output .= '<ul>';
$output .= '<li>' . t('<strong>Leave the messages in place</strong>, this option will copy the error messages and place them inline. The original error messages set by Drupal will remain in place') . '</li>';
$output .= '<li>' . t("<strong>Show an alternate message</strong>, this option will replace the original messages with a generic error message such as 'Please correct all errors.'. This message can be set in the IFE configuration page. The original error messages are placed inline with the form elements") . '</li>';
$output .= '<li>' . t('<strong>Remove all messages</strong>, this option will remove all error messages and place them inline with the form element') . '</li>';
$output .= '</ul>';
$output .= '<p>' . t('In all cases only the messages related to the form will be touched. All other messages will remain in tact.') . '</p>';
return $output;
case 'admin/config/user-interface/ife':
return '<p>' . t('This page provides the interface for adding new forms to use inline errors. Just add the form_id of the forms you wish to alter. An * can be used as a wildcard. The default settings can be overridden on a per form basis.') . '</p>';
}
}
/**
* Menu loader function to fetch a form id.
*/
function ife_form_id_load($form_id) {
$form_ids = ife_load_form_ids();
foreach ((array) $form_ids as $form_id_pattern => $form_settings) {
if (ife_match_form_id($form_id, $form_id_pattern)) {
return $form_settings;
}
}
return FALSE;
}
/**
* Check if a form ID pattern matches a given form ID.
*
* @param string $form_id
* The form ID to compare the pattern to.
* @param string $form_id_pattern
* A form ID pattern. Ex. webform_*.
*
* @return boolean
* TRUE if the pattern matches the form_id, FALSE otherwise.
*/
function ife_match_form_id($form_id, $form_id_pattern) {
// Convert form_id_pattern to a regular expression: replace /* with asterisks.
$to_replace = array(
'/\\\\\\*/',
);
$replacements = array(
'.*',
);
// Quote regular expression characters.
$form_id_pattern_quoted = preg_quote($form_id_pattern, '/');
// Create regular expression.
$form_id_pattern_regex = '/^(' . preg_replace($to_replace, $replacements, $form_id_pattern_quoted) . ')$/';
return (bool) preg_match($form_id_pattern_regex, $form_id);
}
/**
* Implements hook_theme().
*/
function ife_theme() {
return array(
'ife_settings_form_ids' => array(
'render element' => 'form',
'file' => 'ife.theme.inc',
),
'ife_form_element' => array(
'render element' => 'element',
'file' => 'ife.theme.inc',
'path' => drupal_get_path('module', 'ife'),
),
);
}
/**
* Load all form ids from the data base
*/
function ife_load_form_ids() {
static $ife_form_ids;
if ($ife_form_ids) {
$form_ids = $ife_form_ids;
}
else {
$cache = cache_get('ife_form_ids', 'cache');
if ($cache) {
$form_ids = $cache->data;
}
}
if (empty($form_ids)) {
$result = db_select('ife')
->fields('ife', array(
'form_id',
'field_types',
'status',
'display',
))
->orderBy('form_id')
->execute();
$form_ids = array();
foreach ($result as $row) {
$form_ids[$row->form_id] = $row;
}
cache_set('ife_form_ids', $form_ids, 'cache');
}
$ife_form_ids = $form_ids;
return $ife_form_ids;
}
/**
* Helper function to determine the display settings of a form
*/
function ife_form_id_display($form_id) {
if ($form_id->display == -1) {
$display = variable_get('ife_display', 1);
}
else {
$display = $form_id->display;
}
return $display;
}
/**
* Implements hook_form_alter().
*/
function ife_form_alter(&$form, $form_state, $form_id) {
$ife_options = ife_form_id_load($form_id);
if ($ife_options && $ife_options->status) {
$display = ife_form_id_display($ife_options);
ife_filter_form($form, $display);
$form['#ife_display'] = $display;
$form['#validate'][] = 'ife_form_validator';
$form['#post_render'][] = 'ife_session_cleanup';
}
//print form_ids
if (variable_get('ife_show_form_ids', 0)) {
$form['ife_form_id'] = array(
'#markup' => t('Form ID: @form_id', array(
'@form_id' => $form_id,
)),
'#weight' => -1000,
'#access' => user_access('administer inline form errors'),
);
}
}
/**
* Function to set the general error mesage if set
*/
function ife_form_validator($form, &$form_state) {
$form_errors = form_get_errors();
if (!empty($form_errors)) {
ife_element_get_error($form);
if ($form['#ife_display'] == 1) {
$message = filter_xss_admin(variable_get('ife_general_message', 'Please correct all highlighted errors and try again.'));
drupal_set_message($message, 'error');
}
}
}
/**
* Function to recursivly go through a form and alter all valid field type elements
*/
function ife_filter_form(&$form, $display) {
//get all possible children
$keys = element_children($form);
$field_types = ife_field_types();
foreach ($keys as $key) {
$element_type = isset($form[$key]['#type']) ? $form[$key]['#type'] : FALSE;
if (in_array($element_type, $field_types)) {
ife_alter_form_element($form[$key], $display);
}
ife_filter_form($form[$key], $display);
}
}
/**
* Function to add our custom theme to the element
*/
function ife_alter_form_element(&$element, $display) {
// Adding any theme wrappers here will mean the default ones don't get added-
// so we get the default ones and add them first.
$defaults = element_info_property($element['#type'], '#theme_wrappers');
if (empty($element['#theme_wrappers']) && !empty($defaults)) {
$element['#theme_wrappers'] = $defaults;
}
$element['#theme_wrappers'][] = 'ife_form_element';
//resend the element type, drupal sets the #type marker to markup
$element['#field_type'] = $element['#type'];
//add display type to element to avoid extra queries
$element['#display_type'] = $display;
// These elements need special attention. Make sure that default pre-render
// functions are included.
switch ($element['#type']) {
case 'text_format':
case 'date_popup':
case 'date_select':
case 'date_text':
$defaults = element_info_property($element['#type'], '#pre_render', array());
if (empty($element['#pre_render'])) {
$element['#pre_render'] = $defaults;
}
$element['#pre_render'] = array_merge($element['#pre_render'], array(
'ife_text_format_prerender',
));
break;
}
}
/**
* Pre render function for any elements that need special attention.
*/
function ife_text_format_prerender($element) {
switch ($element['#type']) {
case 'text_format':
// Make sure that text_format sub-elements get filtered.
ife_filter_form($element, $element['#display_type']);
break;
case 'date_popup':
case 'date_select':
case 'date_text':
// Date's process functions unhelpfully replace the #theme_wrappers.
$element['#theme_wrappers'][] = 'ife_form_element';
}
return $element;
}
/**
* Function to determine all element errors on a given element.
*/
function ife_element_get_error($element, $debug = FALSE) {
if (!isset($_SESSION['messages'])) {
return;
}
// Recurse through all children.
foreach (element_children($element) as $key) {
if (isset($element[$key]) && $element[$key]) {
ife_element_get_error($element[$key]);
}
}
//check for errors and settings
$errors = form_get_errors();
$element_id = implode('][', $element['#parents']);
if (!empty($errors[$element_id])) {
$error_message = $errors[$element_id];
//get error id
$error_id = array_search($error_message, $_SESSION['messages']['error']);
if ($error_id !== FALSE) {
if (isset($element['#display_type']) && $element['#display_type'] != 0) {
unset($_SESSION['messages']['error'][$error_id]);
$_SESSION['messages']['error'] = array_values($_SESSION['messages']['error']);
}
if (count($_SESSION['messages']['error']) <= 0) {
unset($_SESSION['messages']['error']);
}
// Set error message in session, so it can be used in our theming.
$_SESSION['ife'][$element['#id']] = $error_message;
}
}
}
/**
* Clear the session after the form has been build.
*/
function ife_session_cleanup($form, $form_state) {
if (isset($_SESSION['ife'])) {
unset($_SESSION['ife']);
}
return $form;
}
/**
* Helper function that identifies the different field types default in drupal
*/
function ife_field_types() {
$expandable = ife_expandable_field_types();
$extra = array(
'checkbox',
'file',
'link',
'machine_name',
'managed_file',
'password',
'radio',
'select',
'textarea',
'textfield',
'weight',
);
return array_merge($expandable, $extra);
}
/**
* Helper function that identifies the different expandable field types default in drupal
*/
function ife_expandable_field_types() {
$core = array(
'checkboxes',
'date',
'password_confirm',
'radios',
'text_format',
);
$contrib = array(
// Date
'date_combo',
'date_popup',
'date_repeat_rrule',
'date_select',
'date_text',
'date_timezone',
// Link
'link_field',
// Webform
'webform_time',
'webform_grid',
);
return array_merge($core, $contrib);
}
Functions
Name![]() |
Description |
---|---|
ife_alter_form_element | Function to add our custom theme to the element |
ife_element_get_error | Function to determine all element errors on a given element. |
ife_expandable_field_types | Helper function that identifies the different expandable field types default in drupal |
ife_field_types | Helper function that identifies the different field types default in drupal |
ife_filter_form | Function to recursivly go through a form and alter all valid field type elements |
ife_form_alter | Implements hook_form_alter(). |
ife_form_id_display | Helper function to determine the display settings of a form |
ife_form_id_load | Menu loader function to fetch a form id. |
ife_form_validator | Function to set the general error mesage if set |
ife_help | Implements hook_help(). |
ife_load_form_ids | Load all form ids from the data base |
ife_match_form_id | Check if a form ID pattern matches a given form ID. |
ife_menu | Implements hook_menu(). |
ife_permission | Implements hook_permission(). |
ife_session_cleanup | Clear the session after the form has been build. |
ife_text_format_prerender | Pre render function for any elements that need special attention. |
ife_theme | Implements hook_theme(). |