Index: components/hidden.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/hidden.inc,v retrieving revision 1.17 diff -u -r1.17 hidden.inc --- components/hidden.inc 12 Jan 2010 02:02:07 -0000 1.17 +++ components/hidden.inc 12 Jan 2010 21:36:41 -0000 @@ -82,10 +82,11 @@ * * Make hidden fields visible while editing. */ -function _webform_form_builder_preview_alter_hidden(&$form_element) { +function _webform_form_builder_preview_alter_hidden($form_element) { $form_element['#field_suffix'] = '(' . t('hidden') . ')'; $form_element['#autocomplete_path'] = NULL; // Needed to avoid notices. $form_element['#type'] = 'textfield'; + return $form_element; } /** @@ -111,19 +112,9 @@ } /** - * Implementation of _webform_help_component(). + * Implementation of _webform_analysis_component(). */ -function _webform_help_hidden($section) { - switch ($section) { - case 'admin/settings/webform#hidden_description': - return t('A field which is not visible to the user, but is recorded with the submission.'); - } -} - -/** - * Implementation of _webform_analysis_rows_component(). - */ -function _webform_analysis_rows_hidden($component, $sids = array()) { +function _webform_analysis_hidden($component, $sids = array()) { $placeholders = count($sids) ? array_fill(0, count($sids), "'%s'") : array(); $sidfilter = count($sids) ? " AND sid in (".implode(",", $placeholders).")" : ""; $query = 'SELECT data '. @@ -153,7 +144,7 @@ /** * Implementation of _webform_csv_data_component(). */ -function _webform_table_data_hidden($component, $value) { +function _webform_table_hidden($component, $value) { return check_plain(empty($value[0]) ? '' : $value[0]); } Index: components/textarea.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/textarea.inc,v retrieving revision 1.16 diff -u -r1.16 textarea.inc --- components/textarea.inc 12 Jan 2010 02:02:07 -0000 1.16 +++ components/textarea.inc 12 Jan 2010 21:36:41 -0000 @@ -147,28 +147,19 @@ /** * Implementation of _webform_form_builder_save_component(). */ -function _webform_form_builder_save_textarea(&$component, $form_element) { +function _webform_form_builder_save_textarea($component, $form_element) { $component['extra']['description'] = $form_element['#description']; $component['extra']['cols'] = $form_element['#cols']; $component['extra']['rows'] = $form_element['#rows']; $component['extra']['disabled'] = empty($form_element['#disabled']) ? NULL : TRUE; $component['extra']['format'] = isset($form_element['#input_format']) ? $form_element['#input_format'] : NULL; + return $component; } /** - * Implementation of _webform_help_component(). + * Implementation of _webform_analysis_component(). */ -function _webform_help_textarea($section) { - switch ($section) { - case 'admin/settings/webform#textarea_description': - return t('A large text area that allows for multiple lines of input.'); - } -} - -/** - * Implementation of _webform_analysis_rows_component(). - */ -function _webform_analysis_rows_textarea($component, $sids = array()) { +function _webform_analysis_textarea($component, $sids = array()) { $placeholders = count($sids) ? array_fill(0, count($sids), "'%s'") : array(); $sidfilter = count($sids) ? " AND sid in (".implode(",", $placeholders).")" : ""; $query = 'SELECT data '. @@ -195,9 +186,9 @@ } /** - * Implementation of _webform_table_data_component(). + * Implementation of _webform_table_component(). */ -function _webform_table_data_textarea($component, $value) { +function _webform_table_textarea($component, $value) { return empty($value[0]) ? '' : check_plain($value[0]); } Index: components/file.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/file.inc,v retrieving revision 1.6 diff -u -r1.6 file.inc --- components/file.inc 12 Jan 2010 02:02:07 -0000 1.6 +++ components/file.inc 12 Jan 2010 21:36:41 -0000 @@ -440,16 +440,6 @@ } /** - * Implementation of _webform_help_component(). - */ -function _webform_help_file($section) { - switch ($section) { - case 'admin/settings/webform#file_description': - return t('Allow users to submit files of the configured types.'); - } -} - -/** * Implementation of _webform_theme_component(). */ function _webform_theme_file() { @@ -464,9 +454,9 @@ } /** - * Implementation of _webform_analysis_rows_component(). + * Implementation of _webform_analysis_component(). */ -function _webform_analysis_rows_file($component, $sids = array()) { +function _webform_analysis_file($component, $sids = array()) { $placeholders = count($sids) ? array_fill(0, count($sids), "'%s'") : array(); $sidfilter = count($sids) ? " AND sid in (".implode(",", $placeholders).")" : ""; $query = 'SELECT data '. @@ -494,9 +484,9 @@ } /** - * Implementation of _webform_table_data_component(). + * Implementation of _webform_table_component(). */ -function _webform_table_data_file($component, $value) { +function _webform_table_file($component, $value) { $output = ''; $file_data = unserialize($value[0]); if (!empty($file_data['filename'])) { Index: components/pagebreak.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/pagebreak.inc,v retrieving revision 1.5 diff -u -r1.5 pagebreak.inc --- components/pagebreak.inc 12 Jan 2010 02:02:07 -0000 1.5 +++ components/pagebreak.inc 12 Jan 2010 21:36:41 -0000 @@ -45,16 +45,6 @@ } /** - * Implementation of _webform_help_component(). - */ -function _webform_help_pagebreak($section) { - switch ($section) { - case 'admin/settings/webform#pagebreak_description': - return t('Break up a multi-page form.'); - } -} - -/** * Implementation of _webform_render_component(). */ function _webform_render_pagebreak($component, $value = NULL, $filter = TRUE) { Index: components/time.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/time.inc,v retrieving revision 1.19 diff -u -r1.19 time.inc --- components/time.inc 12 Jan 2010 02:02:07 -0000 1.19 +++ components/time.inc 12 Jan 2010 21:36:41 -0000 @@ -245,16 +245,6 @@ } /** - * Implementation of _webform_help_component(). - */ -function _webform_help_time($section) { - switch ($section) { - case 'admin/settings/webform#time_description': - return t('Presents the user with hour and minute fields. Optional am/pm fields.'); - } -} - -/** * Implementation of _webform_theme_component(). */ function _webform_theme_time() { @@ -269,9 +259,9 @@ } /** - * Implementation of _webform_analysis_rows_component(). + * Implementation of _webform_analysis_component(). */ -function _webform_analysis_rows_time($component, $sids = array()) { +function _webform_analysis_time($component, $sids = array()) { $placeholders = count($sids) ? array_fill(0, count($sids), "'%s'") : array(); $sidfilter = count($sids) ? " AND sid in (".implode(",", $placeholders).")" : ""; $query = 'SELECT no,data '. @@ -318,9 +308,9 @@ } /** - * Implementation of _webform_table_data_component(). + * Implementation of _webform_table_component(). */ -function _webform_table_data_time($component, $value) { +function _webform_table_time($component, $value) { if (drupal_strlen($value[0]) > 0 && drupal_strlen($value[1]) > 0) { $timestamp = strtotime($value[0] .':'. $value[1] . $value[2]); if ($component['extra']['hourformat'] == '24-hour') { Index: components/fieldset.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/fieldset.inc,v retrieving revision 1.7 diff -u -r1.7 fieldset.inc --- components/fieldset.inc 12 Jan 2010 02:02:07 -0000 1.7 +++ components/fieldset.inc 12 Jan 2010 21:36:41 -0000 @@ -100,18 +100,9 @@ /** * Implementation of _webform_form_builder_save_component(). */ -function _webform_form_builder_save_fieldset(&$component, $form_element) { +function _webform_form_builder_save_fieldset($component, $form_element) { $component['extra']['collapsible'] = isset($form_element['#collapsible']) ? $form_element['#collapsible'] : NULL; $component['extra']['collapsed'] = isset($form_element['#collapsed']) ? $form_element['#collapsed'] : NULL; $component['extra']['description'] = isset($form_element['#description']) ? $form_element['#description'] : ''; -} - -/** - * Implementation of _webform_help_component(). - */ -function _webform_help_fieldset($section) { - switch ($section) { - case 'admin/settings/webform#fieldset_description': - return t('Fieldsets allow you to organize multiple fields into groups.'); - } + return $component; } Index: components/date.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/date.inc,v retrieving revision 1.19 diff -u -r1.19 date.inc --- components/date.inc 12 Jan 2010 02:02:07 -0000 1.19 +++ components/date.inc 12 Jan 2010 21:36:40 -0000 @@ -275,16 +275,6 @@ } /** - * Implementation of _webform_help_component(). - */ -function _webform_help_date($section) { - switch ($section) { - case 'admin/settings/webform#date_description': - return t('Presents month, day, and year fields.'); - } -} - -/** * Implementation of _webform_theme_component(). */ function _webform_theme_date() { @@ -299,9 +289,9 @@ } /** - * Implementation of _webform_analysis_rows_component(). + * Implementation of _webform_analysis_component(). */ -function _webform_analysis_rows_date($component, $sids = array()) { +function _webform_analysis_date($component, $sids = array()) { $placeholders = count($sids) ? array_fill(0, count($sids), "'%s'") : array(); $sidfilter = count($sids) ? " AND sid in (".implode(",", $placeholders).")" : ""; $query = 'SELECT no,data '. @@ -350,9 +340,9 @@ } /** - * Implementation of _webform_table_data_component(). + * Implementation of _webform_table_component(). */ -function _webform_table_data_date($component, $value) { +function _webform_table_date($component, $value) { if (drupal_strlen($value[0]) > 0 && drupal_strlen($value[1]) > 0 && drupal_strlen($value[2]) > 0) { return check_plain($value[0] .'/'. $value[1] .'/'. $value[2]); } Index: components/markup.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/markup.inc,v retrieving revision 1.8 diff -u -r1.8 markup.inc --- components/markup.inc 12 Jan 2010 02:02:07 -0000 1.8 +++ components/markup.inc 12 Jan 2010 21:36:41 -0000 @@ -74,21 +74,23 @@ /** * Implementation of _webform_form_builder_save_component(). */ -function _webform_form_builder_save_markup(&$component, $form_element) { +function _webform_form_builder_save_markup($component, $form_element) { $component['extra']['format'] = $form_element['#input_format']; $component['value'] = $form_element['#markup']; + return $component; } /** * Module specific instance of hook_form_builder_preview_alter(). */ -function _webform_form_builder_preview_alter_markup(&$form_element) { +function _webform_form_builder_preview_alter_markup($form_element) { $form_element['#markup'] = isset($form_element['#markup']) ? $form_element['#markup'] : ''; $form_element['#value'] = check_markup(_webform_filter_values($form_element['#markup'], NULL, NULL, FALSE), $form_element['#input_format'], FALSE); if (strlen(trim($form_element['#value'])) == 0) { $form_element['#value'] = t('This markup element currently does not contain any text.'); } + return $form_element; } /** @@ -119,13 +121,3 @@ return $fields; } - -/** - * Implementation of _webform_help_component(). - */ -function _webform_help_markup($section) { - switch ($section) { - case 'admin/settings/webform#markup_description': - return t('Displays text as HTML in the form; does not render a field.'); - } -} Index: components/grid.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/grid.inc,v retrieving revision 1.6 diff -u -r1.6 grid.inc --- components/grid.inc 12 Jan 2010 02:02:07 -0000 1.6 +++ components/grid.inc 12 Jan 2010 21:36:41 -0000 @@ -142,7 +142,7 @@ /** * Implementation of _webform_submit_component(). */ -function _webform_submit_grid($component, $value) { +function _webform_submit_grid($component, $value) {; $options = drupal_map_assoc(array_flip(_webform_grid_options($component['extra']['options']))); // Questions are a bit more tricky, since quotes were removed from them in @@ -195,16 +195,6 @@ } /** - * Implementation of _webform_help_component(). - */ -function _webform_help_grid($section) { - switch ($section) { - case 'admin/settings/webform#grid_description': - return t('Allows creation of grid questions, denoted by radio buttons.'); - } -} - -/** * Implementation of _webform_help_grid(). */ function _webform_theme_grid() { @@ -219,9 +209,9 @@ } /** - * Implementation of _webform_analysis_rows_component(). + * Implementation of _webform_analysis_component(). */ -function _webform_analysis_rows_grid($component, $sids = array()) { +function _webform_analysis_grid($component, $sids = array()) { // Generate the list of options and questions. $options = _webform_grid_options($component['extra']['options']); $questions = array_values(_webform_grid_options($component['extra']['questions'])); @@ -264,9 +254,9 @@ } /** - * Implementation of _webform_table_data_component(). + * Implementation of _webform_table_component(). */ -function _webform_table_data_grid($component, $value) { +function _webform_table_grid($component, $value) { $questions = array_values(_webform_grid_options($component['extra']['questions'])); $output = ''; // Set the value as a single string. Index: components/select.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/select.inc,v retrieving revision 1.27 diff -u -r1.27 select.inc --- components/select.inc 12 Jan 2010 02:02:07 -0000 1.27 +++ components/select.inc 12 Jan 2010 21:36:41 -0000 @@ -334,19 +334,20 @@ /** * Module specific instance of hook_form_builder_load(). */ -function _webform_form_builder_load_select(&$form_element) { +function _webform_form_builder_load_select($form_element) { if (in_array($form_element['#type'], array('radios', 'checkboxes', 'select'))) { $form_element['#webform']['type'] = 'select'; if ($form_element['#type'] == 'checkboxes') { $form_element['#multiple'] = TRUE; } + return $form_element; } } /** * Implementation of _webform_form_builder_save_component(). */ -function _webform_form_builder_save_select(&$component, $form_element) { +function _webform_form_builder_save_select($component, $form_element) { $options = ''; foreach ($form_element['#options'] as $key => $option_value) { @@ -357,6 +358,7 @@ $component['extra']['multiple'] = empty($form_element['#multiple']) ? 'N' : 'Y'; $component['extra']['aslist'] = $form_element['#type'] == 'select' ? 'Y' : 'N'; $component['extra']['description'] = isset($form_element['#description']) ? $form_element['#description'] : ''; + return $component; } /** @@ -394,16 +396,6 @@ } /** - * Implementation of _webform_help_component(). - */ -function _webform_help_select($section) { - switch ($section) { - case 'admin/settings/webform#select_description': - return t('Allows creation of checkboxes, radio buttons, or select menus.'); - } -} - -/** * Implementation of _webform_theme_component(). */ function _webform_theme_select() { @@ -415,9 +407,9 @@ } /** - * Implementation of _webform_analysis_rows_component(). + * Implementation of _webform_analysis_component(). */ -function _webform_analysis_rows_select($component, $sids = array()) { +function _webform_analysis_select($component, $sids = array()) { $options = _webform_select_options($component['extra']['items'], TRUE); $placeholders = count($sids) ? array_fill(0, count($sids), "'%s'") : array(); $sidfilter = count($sids) ? " AND sid in (".implode(",", $placeholders).")" : ""; @@ -443,9 +435,9 @@ } /** - * Implementation of _webform_table_data_component(). + * Implementation of _webform_table_component(). */ -function _webform_table_data_select($component, $value) { +function _webform_table_select($component, $value) { $output = ''; // Set the value as a single string. if (is_array($value)) { Index: components/textfield.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/textfield.inc,v retrieving revision 1.16 diff -u -r1.16 textfield.inc --- components/textfield.inc 12 Jan 2010 02:02:07 -0000 1.16 +++ components/textfield.inc 12 Jan 2010 21:36:41 -0000 @@ -141,13 +141,14 @@ /** * Implementation of _webform_form_builder_save_component(). */ -function _webform_form_builder_save_textfield(&$component, $form_element) { +function _webform_form_builder_save_textfield($component, $form_element) { $component['extra']['width'] = isset($form_element['#size']) ? $form_element['#size'] : NULL; $component['extra']['maxlength'] = isset($form_element['#maxlength']) ? $form_element['#maxlength'] : NULL; $component['extra']['field_prefix'] = isset($form_element['#field_prefix']) ? $form_element['#field_prefix'] : NULL; $component['extra']['field_suffix'] = isset($form_element['#field_suffix']) ? $form_element['#field_suffix'] : NULL; $component['extra']['description'] = isset($form_element['#description']) ? $form_element['#description'] : NULL; $component['extra']['disabled'] = isset($form_element['#disabled']) ? $form_element['#disabled'] : FALSE; + return $component; } /** @@ -204,19 +205,9 @@ } /** - * Implementation of _webform_help_component(). + * Implementation of _webform_analysis_component(). */ -function _webform_help_textfield($section) { - switch ($section) { - case 'admin/settings/webform#textfield_description': - return t('Basic textfield type.'); - } -} - -/** - * Implementation of _webform_analysis_rows_component(). - */ -function _webform_analysis_rows_textfield($component, $sids = array()) { +function _webform_analysis_textfield($component, $sids = array()) { $placeholders = count($sids) ? array_fill(0, count($sids), "'%s'") : array(); $sidfilter = count($sids) ? " AND sid in (".implode(",", $placeholders).")" : ""; $query = 'SELECT data '. @@ -243,9 +234,9 @@ } /** - * Implementation of _webform_table_data_component(). + * Implementation of _webform_table_component(). */ -function _webform_table_data_textfield($component, $value) { +function _webform_table_textfield($component, $value) { return check_plain(empty($value[0]) ? '' : $value[0]); } Index: components/email.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/email.inc,v retrieving revision 1.23 diff -u -r1.23 email.inc --- components/email.inc 12 Jan 2010 02:02:07 -0000 1.23 +++ components/email.inc 12 Jan 2010 21:36:40 -0000 @@ -146,10 +146,11 @@ /** * Implementation of _webform_form_builder_save_component(). */ -function _webform_form_builder_save_email(&$component, $form_element) { +function _webform_form_builder_save_email($component, $form_element) { $component['extra']['width'] = isset($form_element['#size']) ? $form_element['#size'] : NULL; $component['extra']['description'] = isset($form_element['#description']) ? $form_element['#description'] : NULL; $component['extra']['disabled'] = isset($form_element['#disabled']) ? $form_element['#disabled'] : FALSE; + return $component; } /** @@ -179,19 +180,9 @@ } /** - * Implementation of _webform_help_component(). + * Implementation of _webform_analysis_component(). */ -function _webform_help_email($section) { - switch ($section) { - case 'admin/settings/webform#email_description': - return t("A textfield that automatically fills in a logged-in user's e-mail."); - } -} - -/** - * Implementation of _webform_analysis_rows_component(). - */ -function _webform_analysis_rows_email($component, $sids = array()) { +function _webform_analysis_email($component, $sids = array()) { $placeholders = count($sids) ? array_fill(0, count($sids), "'%s'") : array(); $sidfilter = count($sids) ? " AND sid in (".implode(",", $placeholders).")" : ""; $query = 'SELECT data '. @@ -218,9 +209,9 @@ } /** - * Implementation of _webform_table_data_component(). + * Implementation of _webform_table_component(). */ -function _webform_table_data_email($component, $value) { +function _webform_table_email($component, $value) { return check_plain(empty($value[0]) ? '' : $value[0]); } Index: webform.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/webform.module,v retrieving revision 1.151 diff -u -r1.151 webform.module --- webform.module 12 Jan 2010 02:02:07 -0000 1.151 +++ webform.module 12 Jan 2010 21:36:40 -0000 @@ -45,16 +45,6 @@ $output .= '

'. t('Click on any existing component\'s name to edit its settings.') .'

'; break; } - if (strstr($section, 'admin/settings/webform#')) { - // Call help hooks in plugins: - $components = webform_load_components(TRUE); - foreach ($components as $key => $component) { - $help_function = '_webform_help_'. $key; - if (function_exists($help_function)) { - $output .= $help_function($section); - } - } - } return $output; } @@ -72,6 +62,7 @@ 'access callback' => 'user_access', 'access arguments' => array('access all webform results'), 'description' => 'View and edit all the available webforms on your site.', + 'file' => 'includes/webform.admin.inc', 'type' => MENU_NORMAL_ITEM, ); @@ -83,6 +74,7 @@ 'access callback' => 'user_access', 'access arguments' => array('administer site configuration'), 'description' => 'Global configuration of webform functionality.', + 'file' => 'includes/webform.admin.inc', 'type' => MENU_NORMAL_ITEM, ); @@ -325,14 +317,16 @@ function webform_menu_component_load($cid, $nid, $type) { module_load_include('inc', 'webform', 'includes/webform.components'); if ($cid == 'new') { - $components = webform_load_components(); + $components = webform_components(); $component = in_array($type, array_keys($components)) ? array('type' => $type, 'name' => $_GET['name'], 'mandatory' => $_GET['mandatory'], 'email' => $_GET['email'], 'pid' => $_GET['pid'], 'weight' => $_GET['weight']) : FALSE; } else { $node = node_load($nid); $component = isset($node->webform['components'][$cid]) ? $node->webform['components'][$cid] : FALSE; } - webform_component_defaults($component); + if ($component) { + webform_component_defaults($component); + } return $component; } @@ -448,9 +442,6 @@ 'arguments' => array('form' => NULL), 'file' => 'includes/webform.pages.inc', ), - 'webform_admin_settings' => array( - 'arguments' => array('form' => NULL), - ), 'webform_confirmation' => array( 'arguments' => array('node' => NULL, 'sid' => NULL), 'template' => 'templates/webform-confirmation', @@ -468,12 +459,18 @@ 'arguments' => array('form_values' => NULL, 'node' => NULL, 'sid' => NULL, 'cid' => NULL), 'pattern' => 'webform_mail_headers_[0-9]+', ), - 'webform_admin_content' => array( - 'arguments' => array('nodes' => NULL), - ), 'webform_token_help' => array( 'arguments' => array(), ), + // webform.admin.inc. + 'webform_admin_settings' => array( + 'arguments' => array('form' => NULL), + 'file' => 'includes/webform.admin.inc', + ), + 'webform_admin_content' => array( + 'arguments' => array('nodes' => NULL), + 'file' => 'includes/webform.admin.inc', + ), // webform.emails.inc. 'webform_emails_form' => array( 'arguments' => array('form' => NULL), @@ -511,32 +508,88 @@ 'arguments' => array('node' => NULL, 'components' => NULL, 'submissions' => NULL, 'node' => NULL, 'total_count' => NULL, 'pager_count' => NULL), ), ); + // Theme functions in all components. - $components = webform_load_components(TRUE); - foreach ($components as $key => $component) { - $theme_hook = '_webform_theme_'. $key; - if (function_exists($theme_hook)) { - $theme = array_merge($theme, $theme_hook()); + $components = webform_components(TRUE); + foreach ($components as $type => $component) { + if ($theme_additions = webform_component_invoke($type, 'theme')) { + $theme = array_merge($theme, $theme_additions); } } return $theme; } /** - * Implementation of hook_node_info(). + * Implementation of hook_webform_component_info(). */ -function webform_node_info() { +function webform_webform_component_info() { return array( - 'webform' => array( - 'name' => t('Webform'), - 'module' => 'webform', - 'description' => t('Create a new form or questionnaire accessible to users. Submission results and statistics are recorded and accessible to privileged users.'), - ) + 'date' => array( + 'label' => t('Date'), + 'description' => t('Presents month, day, and year fields.'), + 'file' => 'components/date.inc', + ), + 'email' => array( + 'label' => t('E-mail'), + 'description' => t('A special textfield that accepts e-mail addresses.'), + 'file' => 'components/email.inc', + ), + 'fieldset' => array( + 'label' => t('Fieldset'), + 'description' => t('Fieldsets allow you to organize multiple fields into groups.'), + 'file' => 'components/fieldset.inc', + ), + 'file' => array( + 'label' => t('File'), + 'description' => t('Allow users to upload files of configurable types.'), + 'file' => 'components/file.inc', + ), + 'grid' => array( + 'label' => t('Grid'), + 'description' => t('Allows creation of grid questions, denoted by radio buttons.'), + 'file' => 'components/grid.inc', + ), + 'hidden' => array( + 'label' => t('Hidden'), + 'description' => t('A field which is not visible to the user, but is recorded with the submission.'), + 'file' => 'components/hidden.inc', + ), + 'markup' => array( + 'label' => t('Markup'), + 'description' => t('Displays text as HTML in the form; does not render a field.'), + 'file' => 'components/markup.inc', + ), + 'pagebreak' => array( + 'label' => t('Page break'), + 'description' => t('Organize forms into multiple pages.'), + 'file' => 'components/pagebreak.inc', + ), + 'select' => array( + 'label' => t('Select options'), + 'description' => t('Allows creation of checkboxes, radio buttons, or select menus.'), + 'file' => 'components/select.inc', + ), + 'textarea' => array( + 'label' => t('Textarea'), + 'description' => t('A large text area that allows for multiple lines of input.'), + 'file' => 'components/textarea.inc', + ), + 'textfield' => array( + 'label' => t('Textfield'), + 'description' => t('Basic textfield type.'), + 'file' => 'components/textfield.inc', + ), + 'time' => array( + 'label' => t('Time'), + 'description' => t('Presents the user with hour and minute fields. Optional am/pm fields.'), + 'file' => 'components/time.inc', + ), ); } /** * Implementation of hook_forms(). + * * All webform_client_form forms share the same form handler */ function webform_forms($form_id) { @@ -667,7 +720,7 @@ // Allow components clean up extra data, such as uploaded files. module_load_include('inc', 'webform', 'includes/webform.components'); foreach ($node->webform['components'] as $cid => $component) { - webform_component_delete($node->nid, $cid); + webform_component_delete($node, $component); } // Remove any trace of webform data from the database. @@ -995,175 +1048,6 @@ } /** - * Menu callback for admin/webform/settings. - */ -function webform_admin_settings() { - module_load_include('inc', 'webform', 'includes/webform.export'); - - $node_types = node_get_types('names'); - $form['node_types'] = array( - '#type' => 'checkboxes', - '#title' => t('Webform Node Types'), - '#description' => t('Webform allows you to enable the webform components for any content type. Choose the types on which you would like to associate webform components.'), - '#options' => $node_types, - '#default_value' => webform_variable_get('webform_node_types'), - ); - - $form['components'] = array( - '#type' => 'fieldset', - '#title' => t('Available components'), - '#collapsible' => TRUE, - '#collapsed' => FALSE, - '#description' => t('These are the available field types for your installation of Webform. You may disable any of these components by unchecking its corresponding box. Only checked components will be available in existing or new webforms.'), - ); - - // Add each component to the form: - $component_types = webform_load_components(TRUE); - foreach ($component_types as $key => $component) { - $form['components']['webform_enable_'. $key] = array( - '#title' => $component, - '#description' => module_invoke('webform', 'help', 'admin/settings/webform#'. $key .'_description'), - '#type' => 'checkbox', - '#checked_value' => 1, - '#default_value' => variable_get('webform_enable_'. $key, 1), - ); - } - - $form['email'] = array( - '#type' => 'fieldset', - '#title' => t('Default e-mail values'), - '#collapsible' => TRUE, - '#collapsed' => FALSE, - ); - - $form['email']['webform_default_from_address'] = array( - '#type' => 'textfield', - '#title' => t('From address'), - '#default_value' => variable_get('webform_default_from_address', variable_get('site_mail', ini_get('sendmail_from'))), - '#description' => t('The default sender address for emailed webform results; often the e-mail address of the maintainer of your forms.'), - ); - - $form['email']['webform_default_from_name'] = array( - '#type' => 'textfield', - '#title' => t('From name'), - '#default_value' => variable_get('webform_default_from_name', variable_get('site_name', '')), - '#description' => t('The default sender name which is used along with the default from address.'), - ); - - $form['email']['webform_default_subject'] = array( - '#type' => 'textfield', - '#title' => t('Default subject'), - '#default_value' => variable_get('webform_default_subject', t('Form submission from: %title')), - '#description' => t('The default subject line of any e-mailed results.'), - ); - - $form['advanced'] = array( - '#type' => 'fieldset', - '#title' => t('Advanced options'), - '#collapsible' => TRUE, - '#collapsed' => TRUE, - ); - - $form['advanced']['webform_use_cookies'] = array( - '#type' => 'checkbox', - '#checked_value' => 1, - '#title' => t('Allow cookies for tracking submissions'), - '#default_value' => variable_get('webform_use_cookies', 0), - '#description' => t('Cookies can be used to help prevent the same user from repeatedly submitting a webform. This feature is not needed for limiting submissions per user, though it can increase accuracy in some situations. Besides cookies, Webform also uses IP addresses and site usernames to prevent repeated submissions.'), - ); - - $form['advanced']['webform_email_address_format'] = array( - '#type' => 'radios', - '#title' => t('E-mail address format'), - '#options' => array( - 'long' => t('Long format: "Example Name" <name@example.com>'), - 'short' => t('Short format: name@example.com'), - ), - '#default_value' => variable_get('webform_email_address_format', 'long'), - '#description' => t('Most servers support the "long" format which will allow for more friendly From addresses in e-mails sent. However many Windows-based servers are unable to send in the long format. Change this option if experiencing problems sending e-mails with Webform.'), - ); - - $form['advanced']['webform_export_format'] = array( - '#type' => 'radios', - '#title' => t('Default export format'), - '#options' => webform_export_list(), - '#default_value' => variable_get('webform_export_format', 'delimited'), - ); - - $form['advanced']['webform_csv_delimiter'] = array( - '#type' => 'select', - '#title' => t('Default export delimiter'), - '#description' => t('This is the delimiter used in the CSV/TSV file when downloading Webform results. Using tabs in the export is the most reliable method for preserving non-latin characters. You may want to change this to another character depending on the program with which you anticipate importing results.'), - '#default_value' => variable_get('webform_csv_delimiter', '\t'), - '#options' => array( - ',' => t('Comma (,)'), - '\t' => t('Tab (\t)'), - ';' => t('Semicolon (;)'), - ':' => t('Colon (:)'), - '|' => t('Pipe (|)'), - '.' => t('Period (.)'), - ' ' => t('Space ( )'), - ), - ); - - $form['advanced']['webform_submission_access_control'] = array( - '#type' => 'radios', - '#title' => t('Submission access control'), - '#options' => array( - '1' => t('Select the user roles that may submit each individual webform'), - '0' => t('Disable Webform submission access control'), - ), - '#default_value' => variable_get('webform_submission_access_control', 1), - '#description' => t('By default, the configuration form for each webform allows the administrator to choose which roles may submit the form. You may want to allow users to always submit the form if you are using a separate node access module to control access to webform nodes themselves.'), - ); - - $form['advanced']['webform_debug'] = array( - '#type' => 'select', - '#title' => t('Webforms debug'), - '#default_value' => variable_get('webform_debug', 0), - '#options' => array(0 => t('Off'), 1 => t('Log submissions'), 2 => t('Full debug')), - '#description' => t('Set to "Log submissions" to log all submissions in the watchdog. Set to "Full debug" to print debug info on submission.') - ); - - $form = system_settings_form($form); - $form['#theme'] = 'webform_admin_settings'; - $form['#submit'][] = 'webform_admin_settings_submit'; - - return $form; -} - -function webform_admin_settings_submit($form, &$form_state) { - foreach ($form_state['values']['node_types'] as $type) { - if ($type) { - $types[] = $type; - } - } - variable_set('webform_node_types', $types); -} - -function theme_webform_admin_settings($form) { - // Format the components into a table. - foreach (element_children($form['components']) as $key) { - $row = array(); - $row[] = $form['components'][$key]['#title']; - $row[] = $form['components'][$key]['#description']; - unset($form['components'][$key]['#title']); - unset($form['components'][$key]['#description']); - $row[] = array('data' => drupal_render($form['components'][$key]), 'align' => 'center'); - $rows[] = $row; - } - $header = array(t('Name'), t('Description'), t('Enabled')); - - // Create the table inside the form. - $form['components']['table'] = array( - '#value' => theme('table', $header, $rows) - ); - - $output = drupal_render($form); - return $output; -} - -/** * Menu callback to load the appropriate node form. */ function webform_client_form_load($node, $submission, $enabled) { @@ -1196,7 +1080,6 @@ global $user; module_load_include('inc', 'webform', 'includes/webform.components'); - webform_load_components(); if (isset($submission->sid) && !$is_draft) { drupal_set_title(t('Submission #@sid', array('@sid' => $submission->sid))); @@ -1388,17 +1271,16 @@ if (!$enabled) { // This component is display only. $display_function = '_webform_display_'. $component['type']; - if (function_exists($display_function)) { - $parent_fieldset[$component['form_key']] = $display_function($component, (empty($submission->data[$cid]['value']) ? NULL : $submission->data[$cid]['value'])); + $data = empty($submission->data[$cid]['value']) ? NULL : $submission->data[$cid]['value']; + if ($output = webform_component_invoke($component['type'], 'display', $component, $data)) { + $parent_fieldset[$component['form_key']] = $output; } } elseif ($component['page_num'] == $page_num) { // Add this user-defined field to the form (with all the values that are always available). - $render_function = '_webform_render_'. $component['type']; - if (function_exists($render_function)) { - // Call the component render function. - $data = isset($submission->data[$cid]['value']) ? $submission->data[$cid]['value'] : NULL; - $parent_fieldset[$component['form_key']] = $render_function($component, $data, $filter); + $data = isset($submission->data[$cid]['value']) ? $submission->data[$cid]['value'] : NULL; + if ($element = webform_component_invoke($component['type'], 'render', $component, $data, $filter)) { + $parent_fieldset[$component['form_key']] = $element; // Override the value if one already exists in the form state. if (isset($component_value)) { @@ -1521,7 +1403,6 @@ function webform_client_form_submit($form, &$form_state) { global $user, $base_url; module_load_include('inc', 'webform', 'includes/webform.submissions'); - webform_load_components(); $node = node_load($form_state['values']['details']['nid']); @@ -1651,7 +1532,7 @@ $sid = $form_state['values']['details']['sid']; // Check if this form is sending an email. - if (!$form_state['values']['details']['finished']) { + if (!$is_draft && !$form_state['values']['details']['finished']) { // Create a themed message for mailing. foreach ($node->webform['emails'] as $eid => $email) { $cid = is_numeric($email['email']) && isset($node->webform['components'][$email['email']]) ? $email['email'] : 'custom'; @@ -1799,11 +1680,10 @@ } if (isset($node->webform['components'][$cid])) { + // Call the component process submission function. $component = $node->webform['components'][$cid]; - $submit_function = '_webform_submit_'. $component['type']; - if (function_exists($submit_function) && (!isset($types) || in_array($component['type'], $types))) { - // Call the component process submission function. - $form_values[$component['form_key']] = $submit_function($component, $form_values[$component['form_key']]); + if ((!isset($types) || in_array($component['type'], $types)) && ($new_value = webform_component_invoke($component['type'], 'submit', $component, $form_values[$component['form_key']]))) { + $form_values[$component['form_key']] = $new_value; } } } @@ -1915,7 +1795,7 @@ } // First check for component-level themes. - $themed_output = theme('webform_mail_'. $component['type'], $value, $component); + $themed_output = theme('webform_mail_'. $component['type'], $component, $value); $message = ''; if ($themed_output) { @@ -2009,6 +1889,11 @@ global $user; static $replacements; + // Don't do any filtering if the string is empty. + if (strlen(trim($string)) == 0) { + return; + } + // Setup default token replacements. if (!isset($replacements)) { $replacements['unsafe'] = array(); @@ -2118,47 +2003,7 @@ * Filters all special tokens provided by webform, and allows basic layout in descriptions. */ function _webform_filter_descriptions($string, $node = NULL, $submission = NULL, $strict = TRUE) { - return check_markup(_webform_filter_values($string, $node, $submission, $strict)); -} - -/** - * Menu callback for admin/content/webform. Displays all webforms on the site. - */ -function webform_admin_content() { - $result = db_query(db_rewrite_sql("SELECT n.* FROM {node} n WHERE n.type = 'webform'")); - $nodes = array(); - while ($node = db_fetch_object($result)) { - $nodes[] = $node; - } - - return theme('webform_admin_content', $nodes); -} - - -/** - * Generate a list of all webforms avaliable on this site. - */ -function theme_webform_admin_content($nodes) { - $header = array( - t('Title'), - array('data' => t('View'), 'colspan' => '4'), - array('data' => t('Operations'), 'colspan' => '2') - ); - - $rows = array(); - foreach ($nodes as $node) { - $rows[] = array( - l($node->title, 'node/'. $node->nid), - l(t('Submissions'), 'node/'. $node->nid .'/webform-results'), - l(t('Analysis'), 'node/'. $node->nid .'/webform-results/analysis'), - l(t('Table'), 'node/'. $node->nid .'/webform-results/table'), - l(t('Download'), 'node/'. $node->nid .'/webform-results/download'), - node_access('update', $node) ? l(t('Edit'), 'node/'. $node->nid .'/edit') : '', - user_access('delete all webform submissions') ? l(t('Clear'), 'node/'. $node->nid .'/webform-results/clear') : '', - ); - } - - return theme('table', $header, $rows); + return strlen($string) == 0 ? '' : check_markup(_webform_filter_values($string, $node, $submission, $strict)); } /** @@ -2471,30 +2316,72 @@ } /** - * Load all necessary component.inc files into memory. + * Get a list of all available component definitions. */ -function webform_load_components($return_all = FALSE, $reset = FALSE) { - static $component_list, $enabled_list; +function webform_components($include_disabled = FALSE, $reset = FALSE) { + static $components, $disabled; - if (!isset($component_list) || $reset) { - $component_list = array(); - $enabled_list = array(); - $path = drupal_get_path('module', 'webform') .'/components'; - $files = file_scan_directory($path, '^.*\.inc$'); - foreach ($files as $filename => $file) { - $enabled = variable_get('webform_enable_'. $file->name, 1); - if ($return_all || $enabled) { - module_load_include('inc', 'webform', 'components/'. $file->name); - $component_list[$file->name] = t($file->name); - } - if ($enabled) { - $enabled_list[$file->name] = t($file->name); + if (!isset($components) || $reset) { + $components = array(); + $disabled = array_flip(variable_get('webform_disabled_components', array())); + foreach (module_implements('webform_component_info') as $module) { + $module_components = module_invoke($module, 'webform_component_info'); + foreach ($module_components as $type => $info) { + $module_components[$type]['module'] = $module; + $module_components[$type]['enabled'] = !in_array($type, $disabled); } + $components += $module_components; + } + drupal_alter('webform_component_info', $components); + ksort($components); + } + + return $include_disabled ? $components : array_diff_key($components, $disabled); +} + +/** + * Build a list of components suitable for use as select list options. + */ +function webform_component_options($include_disabled = FALSE) { + $component_info = webform_components($include_disabled); + $options = array(); + foreach ($component_info as $type => $info) { + $options[$type] = $info['label']; + } + return $options; +} + +/** + * Load all necessary component.inc files into memory. + */ +function webform_component_include($component_type) { + static $included = array(); + + // No need to load components that have already been added once. + if (!isset($included[$component_type])) { + $components = webform_components(TRUE); + $included[$component_type] = TRUE; + + if (($info = $components[$component_type]) && isset($info['file'])) { + $pathinfo = pathinfo($info['file']); + $path = (!empty($pathinfo['dirname']) ? $pathinfo['dirname'] . '/' : '') . $pathinfo['filename']; + module_load_include($pathinfo['extension'], $info['module'], $path); } } +} - // Ensure only wanted components are returned, even all are loaded. - return $return_all ? $component_list : array_intersect_assoc($component_list, $enabled_list); +/** + * Invoke a component callback. + */ +function webform_component_invoke($type, $callback) { + $args = func_get_args(); + $type = array_shift($args); + $callback = array_shift($args); + $function = '_webform_' . $callback . '_' . $type; + webform_component_include($type); + if (function_exists($function)) { + return call_user_func_array($function, $args); + } } /** Index: webform_hooks.php =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/webform_hooks.php,v retrieving revision 1.1 diff -u -r1.1 webform_hooks.php --- webform_hooks.php 12 Jan 2010 02:02:07 -0000 1.1 +++ webform_hooks.php 12 Jan 2010 21:36:40 -0000 @@ -9,6 +9,79 @@ /** * @defgroup webform_component Sample Webform Component * @{ + * Webform's hooks enable other modules to intercept events within Webform, such + * as the completion of a submission or adding validation. Webform's hooks also + * allow other modules to provide additional components for use within forms. + */ + +/** + * Define components to Webform. + * + * @return + * An array of components, keyed by machine name. Required properties are + * "label" and "description". An optional "file" may be specified to be loaded + * when the component is needed. A set of callbacks will be established based + * on the name of the component. All components follow the pattern: + * + * _webform_[callback]_[component] + * + * Where [component] is the name of the key of the component and [callback] is + * any of the following: + * + * - defaults + * - theme + * - edit + * - form_builder_types + * - form_builder_save + * - form_builder_preview_alter + * - delete + * - render + * - display + * - analysis + * - table + * - csv_headers + * - csv_data + * + * See the sample component implementation for details on each one of these + * callbacks. + * + * @see webform_component + */ +function hook_webform_component_info() { + $components = array(); + + $components['textfield'] = array( + 'label' => t('Textfield'), + 'description' => t('Basic textfield type.'), + 'file' => 'components/textfield.inc', + ); + + return $components; +} + +/** + * Alter the list of available Webform components. + * + * @param $components + * A list of existing components as defined by hook_webform_component_info(). + * + * @see hook_webform_component_info() + */ +function hook_webform_component_info_alter(&$components) { + // Completely remove a component. + unset($components['grid']); + + // Change the name of a component. + $components['textarea']['label'] = t('Text box'); +} + +/** + * @} + */ + +/** + * @defgroup webform_component Sample Webform Component + * @{ * In each of these examples, the word "component" should be replaced with the, * name of the component type (such as textfield or select). These are not * actual hooks, but instead samples of how Webform integrates with its own @@ -75,21 +148,6 @@ } /** - * Validate the configuration form of _webform_edit_component(). - * - * @param $form - * The complete form array for editing a component. - * @param $form_state - * The form state array containing the submitted values. - */ -function _webform_edit_validate_component($form, $form_state) { - $rows = explode('\n', $form['extra']['options']); - if (count($rows) < 2) { - form_error($form['extra']['options'], t('At least 2 options must be provided.')); - } -} - -/** * Define the component to structure to hook_form_builder_types(). */ function _webform_form_builder_types_email() { @@ -286,7 +344,7 @@ * An array of data rows, each containing a statistic for this component's * submissions. */ -function _webform_analysis_rows_component($component, $sids = array()) { +function _webform_analysis_component($component, $sids = array()) { // Generate the list of options and questions. $options = _webform_component_options($component['extra']['options']); $questions = array_values(_webform_component_options($component['extra']['questions'])); @@ -342,7 +400,7 @@ * @return * Textual output formatted for human reading. */ -function _webform_table_data_component($component, $value) { +function _webform_table_component($component, $value) { $questions = array_values(_webform_component_options($component['extra']['questions'])); $output = ''; // Set the value as a single string. Index: CHANGELOG.txt =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/CHANGELOG.txt,v retrieving revision 1.5 diff -u -r1.5 CHANGELOG.txt --- CHANGELOG.txt 10 Jan 2010 01:59:24 -0000 1.5 +++ CHANGELOG.txt 12 Jan 2010 21:36:39 -0000 @@ -9,6 +9,7 @@ - Conditional fields. - Webform may now be attached to any content type. - Form builder integration for live previews and editing of forms. +- Public API for allowing other modules to provide components. 1.x to 2.0 ---------- Index: includes/webform.form_builder.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/includes/webform.form_builder.inc,v retrieving revision 1.3 diff -u -r1.3 webform.form_builder.inc --- includes/webform.form_builder.inc 11 Jan 2010 01:13:35 -0000 1.3 +++ includes/webform.form_builder.inc 12 Jan 2010 21:36:42 -0000 @@ -78,9 +78,7 @@ } // Populate a new default component. elseif (isset($element['#webform']['is_new'])) { - $defaults_function = '_webform_defaults_'. $type; - if (function_exists($defaults_function)) { - $component = $defaults_function(); + if ($component = webform_component_invoke($type, 'defaults')) { $component['type'] = $type; } } @@ -104,9 +102,8 @@ } // Save any specific settings. - $save_function = '_webform_form_builder_save_'. $type; - if (function_exists($save_function)) { - $save_function($component, $element); + if ($saved_component = webform_component_invoke($type, 'form_builder_save', $component, $element)) { + $component = $saved_component; } if (!isset($component['cid'])) { @@ -133,11 +130,10 @@ function webform_form_builder_types() { $fields = array(); - $components = webform_load_components(); - foreach ($components as $key => $component) { - $function = '_webform_form_builder_types_'. $key; - if (function_exists($function)) { - $fields = array_merge($fields, $function()); + $components = webform_components(); + foreach ($components as $type => $component) { + if ($additional_fields = webform_component_invoke($type, 'form_builder_types')) { + $fields = array_merge($fields, $additional_fields); } } @@ -152,11 +148,10 @@ $properties = array(); if ($form_type == 'webform') { - $components = webform_load_components(); - foreach ($components as $key => $component) { - $function = '_webform_form_builder_properties_'. $key; - if (function_exists($function)) { - $properties = array_merge($properties, $function()); + $components = webform_components(); + foreach ($components as $type => $component) { + if ($additional_properties = webform_component_invoke($type, 'form_builder_properties')) { + $properties = array_merge($properties, $additional_properties); } } } @@ -194,10 +189,9 @@ // Add any component-specific loading. Note that all components are // invoked here because the component type isn't yet known. - foreach (webform_load_components() as $component => $name) { - $load_function = '_webform_form_builder_load_' . $component; - if (function_exists($load_function)) { - $load_function($form[$key]); + foreach (webform_components() as $type => $info) { + if ($element = webform_component_invoke($type, 'form_builder_load', $form[$key])) { + $form[$key] = $element; } } webform_form_builder_load_process($form[$key], $node, $cid); @@ -236,8 +230,8 @@ // Let components do any extra filtering if needed. $type = isset($element['#webform']['type']) ? $element['#webform']['type'] : $element['#form_builder']['element_type']; $function = '_webform_form_builder_preview_alter_' . $type; - if (function_exists($function)) { - $function($element); + if ($new_element = webform_component_invoke($type, 'form_builder_preview_alter', $element)) { + $element = $new_element; } } } Index: includes/webform.submissions.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/includes/webform.submissions.inc,v retrieving revision 1.4 diff -u -r1.4 webform.submissions.inc --- includes/webform.submissions.inc 12 Jan 2010 02:02:07 -0000 1.4 +++ includes/webform.submissions.inc 12 Jan 2010 21:36:42 -0000 @@ -80,12 +80,8 @@ */ function webform_submission_delete($node, $submission) { // Iterate through all components and let each do cleanup if necessary. - webform_load_components(); foreach ($node->webform['components'] as $cid => $component) { - $delete_function = '_webform_delete_'. $component['type']; - if (function_exists($delete_function) && isset($submission->data[$cid])) { - $delete_function($component, $submission->data[$cid]); - } + webform_component_invoke($component['type'], 'delete', $component, $submission->data[$cid]); } db_query('DELETE FROM {webform_submitted_data} WHERE nid = %d AND sid = %d', $node->nid, $submission->sid); Index: includes/webform.components.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/includes/webform.components.inc,v retrieving revision 1.9 diff -u -r1.9 webform.components.inc --- includes/webform.components.inc 12 Jan 2010 02:02:07 -0000 1.9 +++ includes/webform.components.inc 12 Jan 2010 21:36:42 -0000 @@ -113,11 +113,9 @@ '#size' => 24, ); - $component_types = webform_load_components(); - natcasesort($component_types); $form['add']['type'] = array( '#type' => 'select', - '#options' => $component_types, + '#options' => webform_component_options(), '#weight' => 3, '#default_value' => (isset($_GET['cid']) && isset($node->webform['components'][$_GET['cid']])) ? $node->webform['components'][$_GET['cid']]['type'] : 'textfield', ); @@ -480,13 +478,8 @@ } // Add the fields specific to this component type: - webform_load_components(); // Load all component types. - $edit_function = '_webform_edit_'. $component['type']; - $additional_form_elements = array(); - if (function_exists($edit_function)) { - $additional_form_elements = $edit_function($component); - } - else { + $additional_form_elements = (array) webform_component_invoke($component['type'], 'edit', $component); + if (empty($additional_form_elements)) { drupal_set_message(t('The webform component of type @type does not have an edit function defined.', array('@type' => $component['type']))); } @@ -528,13 +521,6 @@ form_set_error('form_key', t('The field key %field_key is already in use by the field labeled %existing_field. Please use a unique key.', array('%field_key' => $form_state['values']['form_key'], '%existing_field' => $component['name']))); } } - - // Let the field do any additional validation. - webform_load_components($form_state['values']['type']); - $validate_function = '_webform_edit_validate_'. $form_state['values']['type']; - if (function_exists($validate_function)) { - $validate_function($form, $form_state); - } } function webform_component_edit_form_submit($form, &$form_state) { @@ -637,13 +623,15 @@ function webform_component_delete($node, $component) { // Check if a delete function is available for this component. If so, // load all submissions and allow the component to delete each one. + + webform_component_include($component['type']); $delete_function = '_webform_delete_'. $component['type']; if (function_exists($delete_function)) { module_load_include('inc', 'webform', 'includes/webform.submissions'); $submissions = webform_get_submissions($node->nid); foreach ($submissions as $submission) { if (isset($submission->data[$component['cid']])) { - $delete_function($component, $submission->data[$component['cid']]); + webform_component_invoke($component['type'], 'delete', $component, $submission->data[$component['cid']]); } } } @@ -686,11 +674,7 @@ * Populate a component with the defaults for that type. */ function webform_component_defaults(&$component) { - webform_load_components(); - - $function = '_webform_defaults_'. $component['type']; - if (function_exists($function)) { - $defaults = $function(); + if ($defaults = webform_component_invoke($component['type'], 'defaults')) { foreach ($defaults as $key => $default) { if (!isset($component[$key])) { $component[$key] = $default; Index: includes/webform.report.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/webform/includes/webform.report.inc,v retrieving revision 1.6 diff -u -r1.6 webform.report.inc --- includes/webform.report.inc 12 Jan 2010 02:02:07 -0000 1.6 +++ includes/webform.report.inc 12 Jan 2010 21:36:42 -0000 @@ -166,9 +166,6 @@ * Create a table containing all submitted values for a webform node. */ function webform_results_table($node, $pager_count = 0) { - // Load Components. - webform_load_components(); - if (isset($_GET['results']) && is_numeric($_GET['results'])) { $pager_count = $_GET['results']; } @@ -229,14 +226,11 @@ // Generate a cell for each component. foreach ($node->webform['components'] as $component) { - $table_function = '_webform_table_data_'. $component['type']; - if (function_exists($table_function)) { - $data = isset($submission->data[$component['cid']]['value']) ? $submission->data[$component['cid']]['value'] : NULL; - $submission_output = $table_function($component, $data); - if ($submission_output !== NULL) { - $component_headers[] = $component['name']; - $cell[] = $submission_output; - } + $data = isset($submission->data[$component['cid']]['value']) ? $submission->data[$component['cid']]['value'] : NULL; + $submission_output = webform_component_invoke($component['type'], 'table', $component, $data); + if ($submission_output !== NULL) { + $component_headers[] = $component['name']; + $cell[] = $submission_output; } } @@ -401,15 +395,12 @@ $header[2] = array(t('Serial'), t('SID'), t('Time'), t('IP Address'), t('UID'), t('Username')); // Compile header information. - webform_load_components(); // Load all components. foreach ($node->webform['components'] as $cid => $component) { - $csv_header_function = '_webform_csv_headers_'. $component['type']; - if (function_exists($csv_header_function)) { - // Let each component determine its headers. - $component_header = $csv_header_function($component); - $header[0] = array_merge($header[0], (array)$component_header[0]); - $header[1] = array_merge($header[1], (array)$component_header[1]); - $header[2] = array_merge($header[2], (array)$component_header[2]); + // Let each component determine its headers. + if ($component_header = webform_component_invoke($component['type'], 'csv_headers', $component)) { + $header[0] = array_merge($header[0], (array) $component_header[0]); + $header[1] = array_merge($header[1], (array) $component_header[1]); + $header[2] = array_merge($header[2], (array) $component_header[2]); } } @@ -432,11 +423,10 @@ $row[] = $submission->uid; $row[] = $submission->name; foreach ($node->webform['components'] as $cid => $component) { - $csv_data_function = '_webform_csv_data_'. $component['type']; - if (function_exists($csv_data_function)) { - // Let each component add its data. - $raw_data = isset($submission->data[$cid]['value']) ? $submission->data[$cid]['value'] : NULL; - $data = $csv_data_function($component, $raw_data); + // Let each component add its data. + $raw_data = isset($submission->data[$cid]['value']) ? $submission->data[$cid]['value'] : NULL; + $data = webform_component_invoke($component['type'], 'csv_data', $component, $raw_data); + if ($data !== NULL) { if (is_array($data)) { $row = array_merge($row, array_values($data)); } @@ -474,14 +464,11 @@ array('data' => t('responses'), 'colspan' => '10') ); - webform_load_components(); // Load all component types. foreach ($node->webform['components'] as $component) { $question_number++; // Do component specific call. - $analysis_function = '_webform_analysis_rows_'. $component['type']; - if (function_exists($analysis_function)) { - $crows = $analysis_function($component, $sids); + if ($crows = webform_component_invoke($component['type'], 'analysis', $component, $sids)) { if (is_array($crows)) { $row[0] = array('data' => ''. $question_number .'', 'rowspan' => count($crows) + 1, 'valign' => 'top'); $row[1] = array('data' => ''. $component['name'] .'', 'colspan' => '10'); Index: includes/webform.admin.inc =================================================================== RCS file: includes/webform.admin.inc diff -N includes/webform.admin.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ includes/webform.admin.inc 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,227 @@ + 'checkboxes', + '#title' => t('Webform Node Types'), + '#description' => t('Webform allows you to enable the webform components for any content type. Choose the types on which you would like to associate webform components.'), + '#options' => $node_types, + '#default_value' => webform_variable_get('webform_node_types'), + ); + + $form['components'] = array( + '#type' => 'fieldset', + '#title' => t('Available components'), + '#collapsible' => TRUE, + '#collapsed' => FALSE, + '#description' => t('These are the available field types for your installation of Webform. You may disable any of these components by unchecking its corresponding box. Only checked components will be available in existing or new webforms.'), + ); + + // Add each component to the form: + $form['components'] = array('#tree' => TRUE); + $component_types = webform_components(TRUE); + foreach ($component_types as $key => $component) { + $form['components'][$key] = array( + '#title' => $component['label'], + '#description' => $component['description'], + '#type' => 'checkbox', + '#return_value' => 1, + '#default_value' => $component['enabled'], + ); + } + + $form['email'] = array( + '#type' => 'fieldset', + '#title' => t('Default e-mail values'), + '#collapsible' => TRUE, + '#collapsed' => FALSE, + ); + + $form['email']['webform_default_from_address'] = array( + '#type' => 'textfield', + '#title' => t('From address'), + '#default_value' => variable_get('webform_default_from_address', variable_get('site_mail', ini_get('sendmail_from'))), + '#description' => t('The default sender address for emailed webform results; often the e-mail address of the maintainer of your forms.'), + ); + + $form['email']['webform_default_from_name'] = array( + '#type' => 'textfield', + '#title' => t('From name'), + '#default_value' => variable_get('webform_default_from_name', variable_get('site_name', '')), + '#description' => t('The default sender name which is used along with the default from address.'), + ); + + $form['email']['webform_default_subject'] = array( + '#type' => 'textfield', + '#title' => t('Default subject'), + '#default_value' => variable_get('webform_default_subject', t('Form submission from: %title')), + '#description' => t('The default subject line of any e-mailed results.'), + ); + + $form['advanced'] = array( + '#type' => 'fieldset', + '#title' => t('Advanced options'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + + $form['advanced']['webform_use_cookies'] = array( + '#type' => 'checkbox', + '#checked_value' => 1, + '#title' => t('Allow cookies for tracking submissions'), + '#default_value' => variable_get('webform_use_cookies', 0), + '#description' => t('Cookies can be used to help prevent the same user from repeatedly submitting a webform. This feature is not needed for limiting submissions per user, though it can increase accuracy in some situations. Besides cookies, Webform also uses IP addresses and site usernames to prevent repeated submissions.'), + ); + + $form['advanced']['webform_email_address_format'] = array( + '#type' => 'radios', + '#title' => t('E-mail address format'), + '#options' => array( + 'long' => t('Long format: "Example Name" <name@example.com>'), + 'short' => t('Short format: name@example.com'), + ), + '#default_value' => variable_get('webform_email_address_format', 'long'), + '#description' => t('Most servers support the "long" format which will allow for more friendly From addresses in e-mails sent. However many Windows-based servers are unable to send in the long format. Change this option if experiencing problems sending e-mails with Webform.'), + ); + + $form['advanced']['webform_export_format'] = array( + '#type' => 'radios', + '#title' => t('Default export format'), + '#options' => webform_export_list(), + '#default_value' => variable_get('webform_export_format', 'delimited'), + ); + + $form['advanced']['webform_csv_delimiter'] = array( + '#type' => 'select', + '#title' => t('Default export delimiter'), + '#description' => t('This is the delimiter used in the CSV/TSV file when downloading Webform results. Using tabs in the export is the most reliable method for preserving non-latin characters. You may want to change this to another character depending on the program with which you anticipate importing results.'), + '#default_value' => variable_get('webform_csv_delimiter', '\t'), + '#options' => array( + ',' => t('Comma (,)'), + '\t' => t('Tab (\t)'), + ';' => t('Semicolon (;)'), + ':' => t('Colon (:)'), + '|' => t('Pipe (|)'), + '.' => t('Period (.)'), + ' ' => t('Space ( )'), + ), + ); + + $form['advanced']['webform_submission_access_control'] = array( + '#type' => 'radios', + '#title' => t('Submission access control'), + '#options' => array( + '1' => t('Select the user roles that may submit each individual webform'), + '0' => t('Disable Webform submission access control'), + ), + '#default_value' => variable_get('webform_submission_access_control', 1), + '#description' => t('By default, the configuration form for each webform allows the administrator to choose which roles may submit the form. You may want to allow users to always submit the form if you are using a separate node access module to control access to webform nodes themselves.'), + ); + + $form['advanced']['webform_debug'] = array( + '#type' => 'select', + '#title' => t('Webforms debug'), + '#default_value' => variable_get('webform_debug', 0), + '#options' => array(0 => t('Off'), 1 => t('Log submissions'), 2 => t('Full debug')), + '#description' => t('Set to "Log submissions" to log all submissions in the watchdog. Set to "Full debug" to print debug info on submission.') + ); + + $form = system_settings_form($form); + $form['#theme'] = 'webform_admin_settings'; + $form['#submit'][] = 'webform_admin_settings_submit'; + + return $form; +} + +function webform_admin_settings_submit($form, &$form_state) { + $disabled_components = array(); + foreach ($form_state['values']['components'] as $name => $enabled) { + if (!$enabled) { + $disabled_components[] = $name; + } + } + variable_set('webform_disabled_components', $disabled_components); + + $webform_types = array(); + foreach ($form_state['values']['node_types'] as $type) { + if ($type) { + $webform_types[] = $type; + } + } + variable_set('webform_node_types', $webform_types); +} + +function theme_webform_admin_settings($form) { + // Format the components into a table. + foreach (element_children($form['components']) as $key) { + $row = array(); + $row[] = $form['components'][$key]['#title']; + $row[] = $form['components'][$key]['#description']; + unset($form['components'][$key]['#title']); + unset($form['components'][$key]['#description']); + $row[] = array('data' => drupal_render($form['components'][$key]), 'align' => 'center'); + $rows[] = $row; + } + $header = array(t('Name'), t('Description'), array('data' => t('Enabled'), 'class' => 'checkbox')); + + // Create the table inside the form. + $form['components']['table'] = array( + '#value' => theme('table', $header, $rows) + ); + + $output = drupal_render($form); + return $output; +} + +/** + * Menu callback for admin/content/webform. Displays all webforms on the site. + */ +function webform_admin_content() { + $webform_types = webform_variable_get('webform_node_types'); + $placeholders = implode(', ', array_fill(0, sizeof($webform_types), '%d')); + $result = db_query(db_rewrite_sql("SELECT n.* FROM {node} n WHERE n.type IN ($placeholders)", $webform_types)); + $nodes = array(); + while ($node = db_fetch_object($result)) { + $nodes[] = $node; + } + + return theme('webform_admin_content', $nodes); +} + +/** + * Generate a list of all webforms avaliable on this site. + */ +function theme_webform_admin_content($nodes) { + $header = array( + t('Title'), + array('data' => t('View'), 'colspan' => '4'), + array('data' => t('Operations'), 'colspan' => '2') + ); + + $rows = array(); + foreach ($nodes as $node) { + $rows[] = array( + l($node->title, 'node/'. $node->nid), + l(t('Submissions'), 'node/'. $node->nid .'/webform-results'), + l(t('Analysis'), 'node/'. $node->nid .'/webform-results/analysis'), + l(t('Table'), 'node/'. $node->nid .'/webform-results/table'), + l(t('Download'), 'node/'. $node->nid .'/webform-results/download'), + node_access('update', $node) ? l(t('Edit'), 'node/'. $node->nid .'/edit') : '', + user_access('delete all webform submissions') ? l(t('Clear'), 'node/'. $node->nid .'/webform-results/clear') : '', + ); + } + + return theme('table', $header, $rows); +}