diff --git a/includes/webform_template.admin.inc b/includes/webform_template.admin.inc index 6bc9aa9..66ed60f 100644 --- a/includes/webform_template.admin.inc +++ b/includes/webform_template.admin.inc @@ -74,3 +74,106 @@ function webform_template_config_form($form, &$form_state) { return system_settings_form($form); } +/** + * Defaults form + */ +function webform_template_config_defaults_form($form, &$form_state) { + $types = node_type_get_names(); + $tpl_src = array_filter(variable_get('webform_template_src', array())); + $tpl_dest = array_filter(variable_get('webform_template_dest', array())); + $config = array('!config' => l(t('Webform Template settings'), 'admin/config/content/webform_template')); + + if (!empty($tpl_dest) && !empty($tpl_src)) { + $form['map'] = array( + '#type' => 'item', + '#prefix' => t('Select the default and allowed webform template(s) to use for each content type enabled on the !config page:', $config), + '#theme' => 'webform_template_defaults_table' + ); + + // For each Destination webform type specify allowed sources and default one. + foreach ($tpl_dest as $type_dest) { + $tpl_dest_name = "webform_template_default_{$type_dest}"; + $defaults = _webform_template_source_defaults($type_dest); + + $form['map'][$tpl_dest_name] = array( + '#title' => $types[$type_dest], + '#type' => 'item', + '#tree' => TRUE, + ); + + // Allowed sources for each Destination. + foreach ($tpl_src as $type_src) { + $form['map'][$tpl_dest_name]["allowed_{$type_src}"] = array( + '#type' => 'checkbox', + '#title' => $types[$type_src], + '#default_value' => $defaults['allowed'][$type_src], + + // Additional deep level for convinient types data extraction; + // @see _webform_template_conf_defaults(). + '#parents' => array($tpl_dest_name, 'allowed', $type_src), + ); + } + + // Default template for each Destination. + $form['map'][$tpl_dest_name]["default"] = array( + '#type' => 'select', + '#title' => t('Default'), + + // Allow select any Source as default regardless of 'allowed' option. + '#options' => _webform_template_source_options($tpl_src), + '#empty_option' => '- ' . t('none') . ' -', + '#default_value' => $defaults['default'], + ); + } + } + else { + drupal_set_message(t('You need to enable sources and destinations on the !config page first.', $config)); + } + + return system_settings_form($form); +} + +/** + * Returns HTML for a Webform Template 'Defaults' table. + * + * @param $variables + * An associative array containing: + * - element: A render element representing the 'Defaults' map. + * + * @see webform_template_config_defaults_form() + * @ingroup themeable + */ +function theme_webform_template_defaults_table($variables) { + $header = array(t('Destination')); + $rows = array(); + + foreach (element_children($variables['element']) as $row_index => $tpl_dest_name) { + $tpl_dest_element = &$variables['element'][$tpl_dest_name]; + + $row = array($tpl_dest_element['#title']); + + foreach (element_children($tpl_dest_element) as $tpl_src_name) { + $tpl_src_element = &$tpl_dest_element[$tpl_src_name]; + + if (!$row_index) { + $header[] = $tpl_src_element['#title']; + } + + $tpl_src_element['#title'] = t('Use @source for @destination', array( + '@source' => $tpl_src_element['#title'], + '@destination' => $tpl_dest_element['#title'], + )); + $tpl_src_element['#title_display'] = 'invisible'; + $tpl_src_element['#attributes']['title'] = $tpl_src_element['#title']; + + $row[] = drupal_render($tpl_src_element); + } + + $rows[] = $row; + hide($tpl_dest_element); + } + + $output = theme('table', array('header' => $header, 'rows' => $rows)); + + return $output . drupal_render_children($variables['element']); +} diff --git a/webform_template.module b/webform_template.module index afbc587..f42ace0 100644 --- a/webform_template.module +++ b/webform_template.module @@ -23,6 +23,20 @@ function webform_template_menu() { 'file' => 'includes/webform_template.admin.inc', 'type' => MENU_NORMAL_ITEM, ); + $items['admin/config/content/webform_template/settings'] = array( + 'title' => 'Settings', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + ); + $items['admin/config/content/webform_template/defaults'] = array( + 'title' => 'Default Templates', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('webform_template_config_defaults_form'), + 'access arguments' => array('administer site configuration'), + 'description' => 'Configure the default nodes to use', + 'file' => 'includes/webform_template.admin.inc', + 'type' => MENU_LOCAL_TASK, + ); return $items; } @@ -47,6 +61,18 @@ function webform_template_field_extra_fields() { } /** + * Implements hook_theme(). + */ +function webform_template_theme() { + return array( + 'webform_template_defaults_table' => array( + 'render element' => 'element', + 'file' => 'includes/webform_template.admin.inc', + ), + ); +} + +/** * Implements hook_node_form_alter(). */ function webform_template_form_node_form_alter(&$form, &$form_state, $form_id) { @@ -59,27 +85,8 @@ function webform_template_form_node_form_alter(&$form, &$form_state, $form_id) { // Allow other modules to hide the template selection. drupal_alter('webform_template_show_selection', $show, $form); if ($show) { - $show_lang = variable_get('webform_template_lang'); - - $q = db_select('node', 'n') - ->fields('n', array('nid', 'title', 'language')) - ->condition('status', 1) - ->condition('type', $tpl_src, 'IN') - ->orderBy('tnid'); - - if (!variable_get('webform_template_defeat_nodeaccess', FALSE)) { - $q->addTag('node_access'); - } - - $result = $q->execute()->fetchAll(); - - $templates = array(); - foreach ($result as $row) { - $templates[$row->nid] = $row->title; - if (!empty($show_lang)) { - $templates[$row->nid] .= ' [' . $row->language . ']'; - } - } + $source_options = _webform_template_source_options($tpl_src, $form['type']['#value']); + $source_default = _webform_template_source_defaults($form['type']['#value'], 'default'); $form['webform_template'] = array( '#type' => 'fieldset', @@ -87,18 +94,24 @@ function webform_template_form_node_form_alter(&$form, &$form_state, $form_id) { '#weight' => 5, '#collapsible' => variable_get('webform_template_collapsible', FALSE), '#collapsed' => TRUE, + + // Hide from user if there are no options but still process + // default value if set in the admin. + '#access' => !empty($source_options), ); $form['webform_template']['source'] = array( '#type' => 'select', '#title' => t('Available webforms'), - '#options' => $templates, + '#options' => $source_options, '#empty_option' => '- ' . t('none') . ' -', - '#default_value' => '', + '#default_value' => $source_default, '#description' => t('Make a selection to copy the fields of the selected webform to this node.'), ); + if (!empty($form['nid']['#value'])) { $form['webform_template']['source']['#description'] .= '
' . t('Setting this will overwrite any webform you previously defined!') . ''; + unset($form['webform_template']['source']['#default_value']); } // Add a submit function before the usual submit. @@ -120,6 +133,95 @@ function webform_template_form_node_form_alter(&$form, &$form_state, $form_id) { } /** + * Retrieves configuration of Default and allowed source types; + * and populate default values for this config. + * + * @param string $dest_type + * Type of Destination Webform. + * @param string $option + * (optional) Specific option to retrieve. Possible values: + * - 'allowed' - list of all possible sources with 1/0 values + * - 'default' - NID of default Source to use with this Destination. + * + * @return mixed + */ +function _webform_template_source_defaults($dest_type, $option = NULL) { + $info = &drupal_static(__FUNCTION__, array()); + + if (!isset($info[$dest_type])) { + $tpl_src = array_filter(variable_get('webform_template_src', array())); + + $dest_info = variable_get("webform_template_default_{$dest_type}", array( + 'allowed' => array(), + 'default' => NULL, + )); + + $dest_info['allowed'] += array_fill_keys($tpl_src, '1'); + + $info[$dest_type] = $dest_info; + } + + + if (isset($option) && isset($info[$dest_type][$option])) { + return $info[$dest_type][$option]; + } + + return $info[$dest_type]; +} + +/** + * Helper function gets the available templates for the #options attribute. + * + * @param array $types + * Array of node types. + * @param string $dest_type + * (optional) Webform node type to filter only allowed source templates. + * + * @return array + */ +function _webform_template_source_options(array $types, $dest_type = NULL) { + $show_lang = variable_get('webform_template_lang'); + + if (isset($dest_type)) { + $allowed = _webform_template_source_defaults($dest_type, 'allowed'); + $types = array_intersect($types, array_keys(array_filter($allowed))); + } + + if (empty($types)) { + return array(); + } + + $cid = md5(serialize($types)); + $cache = &drupal_static(__FUNCTION__, array()); + if (!isset($cache[$cid])) { + $q = db_select('node', 'n') + ->fields('n', array('nid', 'title', 'language')) + ->condition('status', NODE_PUBLISHED) + ->condition('type', $types, 'IN') + ->orderBy('tnid'); + + if (!variable_get('webform_template_defeat_nodeaccess', FALSE)) { + $q->addTag('node_access'); + } + + $result = $q->execute()->fetchAll(); + + $templates = array(); + foreach ($result as $row) { + $templates[$row->nid] = $row->title; + + if (!empty($show_lang)) { + $templates[$row->nid] .= ' [' . $row->language . ']'; + } + } + + $cache[$cid] = $templates; + } + + return $cache[$cid]; +} + +/** * Form submission handler for node forms. */ function webform_template_submit($form, &$form_state) {