Index: feeds_ui/feeds_ui.admin.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/feeds/feeds_ui/feeds_ui.admin.inc,v retrieving revision 1.30 diff -u -r1.30 feeds_ui.admin.inc --- feeds_ui/feeds_ui.admin.inc 5 May 2010 23:52:48 -0000 1.30 +++ feeds_ui/feeds_ui.admin.inc 5 Jul 2010 10:40:44 -0000 @@ -383,7 +383,6 @@ if (feeds_get_config_form($importer->processor)) { $actions[] = l(t('Settings'), $path .'/settings/'. $config['processor']['plugin_key']); } - $actions[] = l(t('Mapping'), $path .'/mapping'); $info['title'] = t('Processor'); $info['body'] = array( array( @@ -473,174 +472,6 @@ } /** - * Edit mapping. - * - * @todo Completely merge this into config form handling. This is just a - * shared form of configuration, most of the common functionality can live in - * FeedsProcessor, a flag can tell whether mapping is supported or not. - */ -function feeds_ui_mapping_form(&$form_state, $importer) { - drupal_add_js(drupal_get_path('module', 'feeds_ui') .'/feeds_ui.js'); - - $form = array(); - $form['#importer'] = $importer; - $form['help']['#value'] = feeds_ui_mapping_help(); - - // Get mapping sources from parsers and targets from processor, format them - // for output. - // Some parsers do not define mapping sources but let them define on the fly. - if ($sources = $importer->parser->getMappingSources()) { - $source_options = _feeds_ui_format_options($sources); - foreach ($sources as $k => $source) { - $legend['sources'][$k]['name']['#value'] = empty($source['name']) ? $k : $source['name']; - $legend['sources'][$k]['description']['#value'] = empty($source['description']) ? '' : $source['description']; - } - } - else { - $legend['sources']['#value'] = t('This parser supports free source definitions. Enter the name of the source field in lower case into the Source text field above.'); - } - $targets = $importer->processor->getMappingTargets(); - $target_options = _feeds_ui_format_options($targets); - foreach ($targets as $k => $target) { - $legend['targets'][$k]['name']['#value'] = empty($target['name']) ? $k : $target['name']; - $legend['targets'][$k]['description']['#value'] = empty($target['description']) ? '' : $target['description']; - } - - $form['legendset'] = array( - '#type' => 'fieldset', - '#title' => t('Legend'), - '#collapsible' => TRUE, - '#collapsed' => TRUE, - '#tree' => TRUE, - ); - $form['legendset']['legend'] = $legend; - - // Add unique and remove forms to mappings. - $mappings = $importer->processor->getMappings(); - $form['unique_flags'] = $form['remove_flags'] = array( - '#tree' => TRUE, - ); - - if (is_array($mappings)) { - foreach ($mappings as $i => $mapping) { - - $mappings[$i]['source'] = isset($source_options) ? $source_options[$mappings[$i]['source']] : $mappings[$i]['source']; - $mappings[$i]['target'] = $target_options[$mappings[$i]['target']]; - $param = array( - 'processor' => $importer->processor, - 'mapping' => $mapping, - ); - - if (isset($targets[$mapping['target']]['optional_unique']) && $targets[$mapping['target']]['optional_unique'] === TRUE) { - - $form['unique_flags'][$i] = array( - '#type' => 'checkbox', - '#default_value' => !empty($mapping['unique']), - '#attributes' => array('class' => 'feeds-ui-trigger-submit'), - ); - } - $form['remove_flags'][$i] = array( - '#type' => 'checkbox', - '#title' => t('Remove'), - '#prefix' => '', - ); - } - } - - $form['#mappings'] = $mappings; - $form['#targets'] = $targets; - if ($sources) { - $form['source'] = array( - '#type' => 'select', - '#options' => array('' => t('Select a source')) + $source_options, - ); - } - else { - $form['source'] = array( - '#type' => 'textfield', - '#size' => 20, - '#default_value' => t('Name of source field'), - '#attributes' => array('class' => 'hide-text-on-focus'), - ); - } - $form['target'] = array( - '#type' => 'select', - '#options' => array('' => t('Select a target')) + _feeds_ui_format_options($targets), - ); - $form['add'] = array( - '#type' => 'submit', - '#value' => t('Add'), - '#submit' => array('feeds_ui_mapping_form_add_submit'), - ); - $form['save'] = array( - '#type' => 'submit', - '#value' => t('Save'), - '#attributes' => array('class' => 'feeds-ui-hidden-submit'), - ); - return $form; -} - -/** - * Submit handler for add button on feeds_ui_mapping_form(). - */ -function feeds_ui_mapping_form_add_submit($form, &$form_state) { - $importer = $form['#importer']; - try { - $importer->processor->addMapping($form_state['values']['source'], $form_state['values']['target']); - $importer->processor->save(); - drupal_set_message(t('Mapping has been added.')); - } - catch (Exception $e) { - drupal_set_message($e->getMessage(), 'error'); - } -} - -/** - * Submit handler for save button on feeds_ui_mapping_form(). - */ -function feeds_ui_mapping_form_submit($form, &$form_state) { - $processor = $form['#importer']->processor; - $mappings = $processor->config['mappings']; - // We may set some unique flags to mappings that we remove in the subsequent - // step, that's fine. - if (isset($form_state['values']['unique_flags'])) { - foreach ($form_state['values']['unique_flags'] as $k => $v) { - $processor->setUnique($mappings[$k]['source'], $mappings[$k]['target'], $v); - } - } - - foreach ($form_state['values']['remove_flags'] as $k => $v) { - if ($v) { - $processor->removeMapping($mappings[$k]['source'], $mappings[$k]['target']); - } - } - drupal_set_message(t('Your changes have been saved.')); - $processor->save(); -} - -/** - * Walk the result of FeedsParser::getMappingSources() or - * FeedsProcessor::getMappingTargets() and format them into - * a Form API options array. - */ -function _feeds_ui_format_options($options) { - $result = array(); - foreach ($options as $k => $v) { - if (is_array($v) && !empty($v['name'])) { - $result[$k] = $v['name']; - } - elseif (is_array($v)) { - $result[$k] = $k; - } - else { - $result[$k] = $v; - } - } - return $result; -} - -/** * Theme feeds_ui_overview_form(). */ function theme_feeds_ui_overview_form($form) { @@ -753,8 +584,7 @@ /** * Theme function for feeds_ui_mapping_form(). */ -function theme_feeds_ui_mapping_form($form) { - +function theme_feeds_ui_mapping_form($form) { // Build the actual mapping table. $header = array( t('Source'), Index: includes/FeedsConfigurable.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/feeds/includes/FeedsConfigurable.inc,v retrieving revision 1.12 diff -u -r1.12 FeedsConfigurable.inc --- includes/FeedsConfigurable.inc 28 Feb 2010 17:16:25 -0000 1.12 +++ includes/FeedsConfigurable.inc 5 Jul 2010 10:40:44 -0000 @@ -178,6 +178,14 @@ */ public function configFormValidate(&$values) { } + + /** + * Flag whether to render mapping form within the configForm. + * default value is false, override this as necessary. + */ + public function embedMappingForm() { + return FALSE; + } } /** @@ -212,7 +220,17 @@ * The object to perform the save() operation on. */ function feeds_config_form(&$form_state, $configurable) { - $form = $configurable->configForm($form_state); + // Embed mapping form into the config form depend on + // FeedsConfigurable::embedMappingForm() value. + if ($configurable->embedMappingForm()) { + $form = feeds_mapping_form($configurable); + } + else { + $form = array(); + } + + $form = array_merge($form, $configurable->configForm($form_state)); + $form['#configurable'] = $configurable; $form['#validate'] = array('feeds_config_form_validate'); $form['#submit'] = array('feeds_config_form_submit'); @@ -221,6 +239,7 @@ '#value' => t('Save'), '#weight' => 100, ); + return $form; } @@ -234,9 +253,192 @@ /** * Submit handler for feeds_config_form(). */ -function feeds_config_form_submit($form, &$form_state) { +function feeds_config_form_submit($form, &$form_state) { $form['#configurable']->addConfig($form_state['values']); $form['#configurable']->save(); + + // Add special submit handling only if there mappingForm is embedded + // Assumption: Only FeedsProcessor set embedMappingForm() into TRUE + if ($form['#configurable']->embedMappingForm()) { + $processor = $form['#configurable']; + + $mappings = $processor->config['mappings']; + // We may set some unique flags to mappings that we remove in the subsequent + // step, that's fine. + if (isset($form_state['values']['unique_flags'])) { + foreach ($form_state['values']['unique_flags'] as $k => $v) { + $processor->setUnique($mappings[$k]['source'], $mappings[$k]['target'], $v); + } + } + + if (isset($form_state['values']['remove_flags'])) { + foreach ($form_state['values']['remove_flags'] as $k => $v) { + if ($v) { + $processor->removeMapping($mappings[$k]['source'], $mappings[$k]['target']); + } + } + } + $processor->save(); + } + drupal_set_message(t('Your changes have been saved.')); feeds_cache_clear(FALSE); } + +/** + * Definition of the mapping form. + * All FeedsProcessor must call this before adding items into the form. + */ +function feeds_mapping_form($configurable) { + drupal_add_js(drupal_get_path('module', 'feeds_ui') .'/feeds_ui.js'); + + // Get the FeedsImporter object + $importer = feeds_importer($configurable->id); + + $form = array(); + + // Mapping on Import checkbox + $form['mapping_on_import'] = array( + '#type' => 'checkbox', + '#title' => 'Mapping on Import', + '#description' => 'If this is checked, the mapping form here will be disabled and instead user will be asked for the mapping configuration after the first import.', + '#attributes' => array('class' => 'feeds-ui-trigger-submit'), + '#weight' => -100, + '#default_value' => $importer->processor->config['mapping_on_import'], + ); + + if (!$importer->processor->config['mapping_on_import']) { + $form['#theme'] = 'feeds_ui_mapping_form'; + $form['help']['#value'] = feeds_ui_mapping_help(); + + // Get mapping sources from parsers and targets from processor, format them + // for output. + // Some parsers do not define mapping sources but let them define on the fly. + if ($sources = $importer->parser->getMappingSources()) { + $source_options = _feeds_processor_format_options($sources); + foreach ($sources as $k => $source) { + $legend['sources'][$k]['name']['#value'] = empty($source['name']) ? $k : $source['name']; + $legend['sources'][$k]['description']['#value'] = empty($source['description']) ? '' : $source['description']; + } + } + else { + $legend['sources']['#value'] = t('This parser supports free source definitions. Enter the name of the source field in lower case into the Source text field above.'); + } + $targets = $importer->processor->getMappingTargets(); + $target_options = _feeds_mapping_form_format_options($targets); + foreach ($targets as $k => $target) { + $legend['targets'][$k]['name']['#value'] = empty($target['name']) ? $k : $target['name']; + $legend['targets'][$k]['description']['#value'] = empty($target['description']) ? '' : $target['description']; + } + + $form['legendset'] = array( + '#type' => 'fieldset', + '#title' => t('Legend'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#tree' => TRUE, + ); + $form['legendset']['legend'] = $legend; + + // Add unique and remove forms to mappings. + $mappings = $importer->processor->getMappings(); + $form['unique_flags'] = $form['remove_flags'] = array( + '#tree' => TRUE, + ); + + if (is_array($mappings)) { + foreach ($mappings as $i => $mapping) { + + $mappings[$i]['source'] = isset($source_options) ? $source_options[$mappings[$i]['source']] : $mappings[$i]['source']; + $mappings[$i]['target'] = $target_options[$mappings[$i]['target']]; + $param = array( + 'processor' => $importer->processor, + 'mapping' => $mapping, + ); + + if (isset($targets[$mapping['target']]['optional_unique']) && $targets[$mapping['target']]['optional_unique'] === TRUE) { + + $form['unique_flags'][$i] = array( + '#type' => 'checkbox', + '#default_value' => !empty($mapping['unique']), + '#attributes' => array('class' => 'feeds-ui-trigger-submit'), + ); + } + $form['remove_flags'][$i] = array( + '#type' => 'checkbox', + '#title' => t('Remove'), + '#prefix' => '', + ); + } + } + + $form['#mappings'] = $mappings; + $form['#targets'] = $targets; + if ($sources) { + $form['source'] = array( + '#type' => 'select', + '#options' => array('' => t('Select a source')) + $source_options, + ); + } + else { + $form['source'] = array( + '#type' => 'textfield', + '#size' => 20, + '#default_value' => t('Name of source field'), + '#attributes' => array('class' => 'hide-text-on-focus'), + ); + } + $form['target'] = array( + '#type' => 'select', + '#options' => array('' => t('Select a target')) + _feeds_mapping_form_format_options($targets), + ); + $form['add'] = array( + '#type' => 'submit', + '#value' => t('Add'), + '#submit' => array('feeds_mapping_form_add_submit'), + ); + } + $form['save'] = array( + '#type' => 'submit', + '#value' => t('Save'), + '#attributes' => array('class' => 'feeds-ui-hidden-submit'), + ); + + return $form; +} + +/** + * Submit handler for add button on feeds_ui_mapping_form(). + */ +function feeds_mapping_form_add_submit($form, &$form_state) { + try { + $form['#configurable']->addMapping($form_state['values']['source'], $form_state['values']['target']); + $form['#configurable']->save(); + drupal_set_message(t('Mapping has been added.')); + } + catch (Exception $e) { + drupal_set_message($e->getMessage(), 'error'); + } +} + +/** + * Walk the result of FeedsParser::getMappingSources() or + * FeedsProcessor::getMappingTargets() and format them into + * a Form API options array. + */ +function _feeds_mapping_form_format_options($options) { + $result = array(); + foreach ($options as $k => $v) { + if (is_array($v) && !empty($v['name'])) { + $result[$k] = $v['name']; + } + elseif (is_array($v)) { + $result[$k] = $k; + } + else { + $result[$k] = $v; + } + } + return $result; +} \ No newline at end of file Index: plugins/FeedsDataProcessor.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/feeds/plugins/FeedsDataProcessor.inc,v retrieving revision 1.13 diff -u -r1.13 FeedsDataProcessor.inc --- plugins/FeedsDataProcessor.inc 16 May 2010 21:51:58 -0000 1.13 +++ plugins/FeedsDataProcessor.inc 5 Jul 2010 10:45:10 -0000 @@ -255,6 +255,7 @@ 'update_existing' => 0, 'expire' => FEEDS_EXPIRE_NEVER, // Don't expire items by default. 'mappings' => array(), + 'mapping_on_import' => 0, ); } Index: plugins/FeedsFeedNodeProcessor.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/feeds/plugins/FeedsFeedNodeProcessor.inc,v retrieving revision 1.12 diff -u -r1.12 FeedsFeedNodeProcessor.inc --- plugins/FeedsFeedNodeProcessor.inc 28 Apr 2010 22:18:30 -0000 1.12 +++ plugins/FeedsFeedNodeProcessor.inc 5 Jul 2010 10:45:20 -0000 @@ -107,6 +107,7 @@ 'content_type' => '', 'update_existing' => 0, 'mappings' => array(), + 'mapping_on_import' => 0, ); } Index: plugins/FeedsNodeProcessor.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/feeds/plugins/FeedsNodeProcessor.inc,v retrieving revision 1.38 diff -u -r1.38 FeedsNodeProcessor.inc --- plugins/FeedsNodeProcessor.inc 19 Jun 2010 18:03:41 -0000 1.38 +++ plugins/FeedsNodeProcessor.inc 5 Jul 2010 10:45:31 -0000 @@ -146,6 +146,7 @@ 'expire' => FEEDS_EXPIRE_NEVER, 'mappings' => array(), 'author' => 0, + 'mapping_on_import' => 0, ); } Index: plugins/FeedsProcessor.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/feeds/plugins/FeedsProcessor.inc,v retrieving revision 1.11 diff -u -r1.11 FeedsProcessor.inc --- plugins/FeedsProcessor.inc 19 Jun 2010 15:57:13 -0000 1.11 +++ plugins/FeedsProcessor.inc 5 Jul 2010 10:45:38 -0000 @@ -130,7 +130,10 @@ * Declare default configuration. */ public function configDefaults() { - return array('mappings' => array()); + return array( + 'mappings' => array(), + 'mapping_on_import' => 0, + ); } /** @@ -272,5 +275,11 @@ module_implements('', FALSE, TRUE); } $loaded = TRUE; - } + } + + /** + * Override FeedsConfigurable::embedMappingForm() + * Embed mapping form in the FeedsProcessor configuration form + */ + public function embedMappingForm() { return TRUE; } } Index: plugins/FeedsTermProcessor.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/feeds/plugins/FeedsTermProcessor.inc,v retrieving revision 1.9 diff -u -r1.9 FeedsTermProcessor.inc --- plugins/FeedsTermProcessor.inc 28 Apr 2010 22:18:30 -0000 1.9 +++ plugins/FeedsTermProcessor.inc 5 Jul 2010 10:45:45 -0000 @@ -126,6 +126,7 @@ 'vocabulary' => 0, 'update_existing' => 0, 'mappings' => array(), + 'mapping_on_import' => 0, ); } Index: plugins/FeedsUserProcessor.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/feeds/plugins/FeedsUserProcessor.inc,v retrieving revision 1.12 diff -u -r1.12 FeedsUserProcessor.inc --- plugins/FeedsUserProcessor.inc 19 Jun 2010 15:57:13 -0000 1.12 +++ plugins/FeedsUserProcessor.inc 5 Jul 2010 10:45:52 -0000 @@ -117,6 +117,7 @@ 'update_existing' => FALSE, 'status' => 1, 'mappings' => array(), + 'mapping_on_import' => 0, ); }