diff --git a/feeds.api.php b/feeds.api.php index 7b81be834f9b9bb69700a957efc52653a5bd2b52..6c611311ff6d4e5e526f8f0f37dd5dc0cc3a28f2 100644 --- a/feeds.api.php +++ b/feeds.api.php @@ -97,6 +97,21 @@ function hook_feeds_after_parse(FeedsSource $source, FeedsParserResult $result) $result->title = 'Import number ' . my_module_import_id(); } +/** + * Invoked before a feed item is saved. + * + * @param $source + * FeedsSource object that describes the source that is being imported. + * @param $entity + * The entity object. + */ +function hook_feeds_presave(FeedsSource $source, $entity) { + if ($entity->feeds_item->entity_type == 'node') { + // Skip saving this entity. + $entity->feeds_item->skip = TRUE; + } +} + /** * Invoked after a feed source has been imported. * diff --git a/feeds.rules.inc b/feeds.rules.inc new file mode 100644 index 0000000000000000000000000000000000000000..4dd583ac0876da608bed2060b891c5966b7cda37 --- /dev/null +++ b/feeds.rules.inc @@ -0,0 +1,79 @@ +<?php + +/** + * @file + * Rules integration. + */ + +/** + * Implements hook_rules_event_info(). + */ +function feeds_rules_event_info() { + $info = array(); + $entity_info = entity_get_info(); + foreach (feeds_importer_load_all() as $importer) { + $config = $importer->getConfig(); + $processor = feeds_plugin($config['processor']['plugin_key'], $importer->id); + $entity_type = $processor->entityType(); + $info['feeds_import_'. $importer->id] = array( + 'label' => t('Before saving an item imported via @name.', array('@name' => $importer->config['name'])), + 'group' => t('Feeds'), + 'variables' => array( + $entity_type => array( + 'label' => t('Imported @label', array('@label' => $entity_info[$entity_type]['label'])), + 'type' => $entity_type, + // Saving is handled by feeds anyway (unless the skip action is used). + 'skip save' => TRUE, + ), + ), + 'access callback' => 'feeds_rules_access_callback', + ); + // Add bundle information if the node processor is used. + if ($processor instanceof FeedsNodeProcessor) { + $config = $processor->getConfig(); + $info['feeds_import_'. $importer->id]['variables'][$entity_type]['bundle'] = $config['content_type']; + } + } + return $info; +} + +/** + * Implements of hook_rules_action_info(). + */ +function feeds_rules_action_info() { + return array( + 'feeds_skip_item' => array( + 'base' => 'feeds_action_skip_item', + 'label' => t('Skip import of feeds item'), + 'group' => t('Feeds'), + 'parameter' => array( + 'entity' => array('type' => 'entity', 'label' => t('The feeds import item to be marked as skipped')), + ), + 'access callback' => 'feeds_rules_access_callback', + ), + ); +} + +/** + * Mark feeds import item as skipped. + */ +function feeds_action_skip_item($entity_wrapper) { + $entity = $entity_wrapper->value(); + if(isset($entity->feeds_item)) { + $entity->feeds_item->skip = TRUE; + } +} + +/** + * Help callback for the skip action. + */ +function feeds_action_skip_item_help() { + return t("This action allows skipping certain feed items during feeds processing, i.e. before an imported item is saved. Once this action is used on a item, the changes to the entity of the feed item are not saved."); +} + +/** + * Access callback for the feeds rules integration. + */ +function feeds_rules_access_callback() { + return user_access('administer feeds'); +} diff --git a/includes/FeedsSource.inc b/includes/FeedsSource.inc index 47230d9e1dae39a8eaf257bbb376d1dc906595da..19ea00246220c6ac1b2e79cf0b3a425d629ac0d0 100644 --- a/includes/FeedsSource.inc +++ b/includes/FeedsSource.inc @@ -201,6 +201,13 @@ class FeedsSource extends FeedsConfigurable { $this->load(); } + /** + * Returns the FeedsImporter object that this source is expected to be used with. + */ + public function importer() { + return $this->importer; + } + /** * Preview = fetch and parse a feed. * diff --git a/plugins/FeedsProcessor.inc b/plugins/FeedsProcessor.inc index 97b6269229b192b203ed6a9edb62b9e7780e7ccf..49404c2a7edea9f0c1ef5b7023f0867807d46a39 100644 --- a/plugins/FeedsProcessor.inc +++ b/plugins/FeedsProcessor.inc @@ -126,14 +126,23 @@ abstract class FeedsProcessor extends FeedsPlugin { } $this->map($source, $parser_result, $entity); $this->entityValidate($entity); - $this->entitySave($entity); - // Track progress. - if (empty($entity_id)) { - $state->created++; + // Allow modules to alter the entity before saving. + module_invoke_all('feeds_presave', $source, $entity); + if (module_exists('rules')) { + rules_invoke_event('feeds_import_'. $source->importer()->id, $entity); } - else { - $state->updated++; + + // Enable modules to skip saving at all. + if (empty($entity->feeds_item->skip)) { + $this->entitySave($entity); + // Track progress. + if (empty($entity_id)) { + $state->created++; + } + else { + $state->updated++; + } } } catch (Exception $e) {