diff --git a/feeds_ui/feeds_ui.admin.inc b/feeds_ui/feeds_ui.admin.inc index f975ffe..c12cb3a 100644 --- a/feeds_ui/feeds_ui.admin.inc +++ b/feeds_ui/feeds_ui.admin.inc @@ -401,6 +401,15 @@ function feeds_ui_edit_page(FeedsImporter $importer, $active = 'help', $plugin_k $info['actions'] = array(l(t('Change'), $path . '/processor')); $config_info[] = $info; + // Validate configuration. + $errors = $importer->validateConfig(); + if (count($errors)) { + $message = t('There are some issues with the importer configuration: !errors', array( + '!errors' => theme('item_list', array('items' => $errors)), + )); + drupal_set_message($message, 'warning'); + } + return theme('feeds_ui_edit_page', array( 'info' => $config_info, 'active' => $active_container, @@ -1186,12 +1195,28 @@ function feeds_ui_importer_import_validate($form, &$form_state) { } if (!$form_state['values']['bypass_validation']) { + $errors = array(); + + // @todo Move to FeedsImporter::validateConfig()? foreach (array('fetcher', 'parser', 'processor') as $type) { $plugin = feeds_plugin($feeds_importer->config[$type]['plugin_key'], $feeds_importer->id); if (get_class($plugin) == 'FeedsMissingPlugin') { - form_error($form['importer'], t('The plugin %plugin is unavailable.', array('%plugin' => $feeds_importer->config[$type]['plugin_key']))); + $errors[] = t('The plugin %plugin is unavailable.', array('%plugin' => $feeds_importer->config[$type]['plugin_key'])); + } + } + + // Other validation rules. + $importer = feeds_importer($feeds_importer->id); + $importer->setConfig($feeds_importer->config); + foreach (array('fetcher', 'parser', 'processor') as $type) { + $plugin = feeds_plugin($feeds_importer->config[$type]['plugin_key'], $feeds_importer->id); + if (get_class($plugin) != 'FeedsMissingPlugin') { + $importer->setPlugin($feeds_importer->config[$type]['plugin_key']); + $importer->$type->setConfig($feeds_importer->config[$type]['config']); } } + $errors = array_merge($errors, $importer->validateConfig()); + form_error($form['importer'], theme('item_list', array('items' => $errors))); } $form_state['importer'] = $feeds_importer; diff --git a/includes/FeedsConfigurable.inc b/includes/FeedsConfigurable.inc index d809c20..19a4e06 100644 --- a/includes/FeedsConfigurable.inc +++ b/includes/FeedsConfigurable.inc @@ -173,6 +173,43 @@ abstract class FeedsConfigurable { } /** + * Gives the allowed values for each configuration key that allows a limit set + * of values. + * + * @return array + * Per configuration key, the allowed values. + */ + public function getConfigAllowedValues() { + return array(); + } + + /** + * Validates the configuration. + * + * @return array + * A list of errors. + */ + public function validateConfig() { + $config = $this->getConfig(); + $errors = array(); + + // Check allowed values. + $allowed_values = $this->getConfigAllowedValues(); + foreach ($allowed_values as $key => $values) { + if (isset($config[$key])) { + if (!in_array($config[$key], $values)) { + $errors[] = t('Invalid value %value for config option %key.', array( + '%value' => $config[$key], + '%key' => $key, + )); + } + } + } + + return $errors; + } + + /** * Returns whether or not the configurable has a config form. * * @return bool diff --git a/includes/FeedsImporter.inc b/includes/FeedsImporter.inc index 5286b1d..30591c9 100644 --- a/includes/FeedsImporter.inc +++ b/includes/FeedsImporter.inc @@ -177,6 +177,31 @@ class FeedsImporter extends FeedsConfigurable { } /** + * Validates the configuration. + */ + public function validateConfig() { + $errors = parent::validateConfig(); + + // Validate errors of each plugin as well. + $plugin_types = array( + 'fetcher' => t('Fetcher'), + 'parser' => t('Parser'), + 'processor' => t('Processor'), + ); + foreach ($plugin_types as $type => $plugin_label) { + $plugin_errors = $this->$type->validateConfig(); + foreach ($plugin_errors as $key => $error) { + $errors[] = t('@plugin: !error', array( + '@plugin' => $plugin_label, + '!error' => $error, + )); + } + } + + return $errors; + } + + /** * Return defaults for feed configuration. */ public function configDefaults() { diff --git a/plugins/FeedsProcessor.inc b/plugins/FeedsProcessor.inc index 932b994..39820da 100644 --- a/plugins/FeedsProcessor.inc +++ b/plugins/FeedsProcessor.inc @@ -768,6 +768,19 @@ abstract class FeedsProcessor extends FeedsPlugin { } /** + * Overrides parent::getConfigAllowedValues(). + */ + public function getConfigAllowedValues() { + $allowed_values = parent::getConfigAllowedValues(); + + // Bundle. + $bundles = $this->bundleOptions(); + $allowed_values['bundle'] = array_keys($bundles); + + return $allowed_values; + } + + /** * Overrides parent::configForm(). */ public function configForm(&$form_state) { @@ -775,13 +788,19 @@ abstract class FeedsProcessor extends FeedsPlugin { $form = array(); if (!empty($info['entity keys']['bundle'])) { + $default_bundle = $this->bundle(); $form['bundle'] = array( '#type' => 'select', '#options' => $this->bundleOptions(), '#title' => !empty($info['bundle name']) ? $info['bundle name'] : t('Bundle'), '#required' => TRUE, - '#default_value' => $this->bundle(), + '#default_value' => $default_bundle, ); + if (!isset($form['bundle']['#options'][$default_bundle])) { + $form['bundle']['#options'][$default_bundle] = t('Unknown bundle: @bundle', array( + '@bundle' => $default_bundle, + )); + } } else { $form['bundle'] = array(