diff --git a/feeds.rules.inc b/feeds.rules.inc index a95585f..b1a41f9 100644 --- a/feeds.rules.inc +++ b/feeds.rules.inc @@ -60,15 +60,6 @@ function feeds_rules_event_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', - ), 'feeds_import_feed' => array( 'base' => 'feeds_action_import_feed', 'label' => t('Execute feeds importer'), @@ -79,10 +70,24 @@ function feeds_rules_action_info() { 'options list' => 'feeds_importer_list', 'default mode' => 'input', ), + 'feed_nid' => array( + 'type' => 'node', + 'label' => t('Feed node'), + 'default mode' => 'input', + ), ), 'group' => t('Feeds'), 'access callback' => 'feeds_rules_access_callback', ), + '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', + ), ); } @@ -113,6 +118,37 @@ function feeds_rules_data_info() { } /** + * Rules action callback for "feeds_import_feed" action. + * + * @param string $importer_id + * ID of the importer. + * @param object|null $feed_node + * The feed node, if found. Null otherwise. + * @param array $params + * The raw parameters. + */ +function feeds_action_import_feed($importer_id, $feed_node, array $params) { + $source = feeds_source($importer_id, $params['feed_nid']); + try { + $source->existing()->startImport(); + + // Execute batch, if there is any. Set 'progressive' to false to prevent + // batch from triggering a drupal_goto(). + $batch =& batch_get(); + if (!empty($batch)) { + $batch['progressive'] = FALSE; + batch_process(); + } + } + catch (FeedsNotExistingException $e) { + // Ignore this kind of exception. + } + catch (Exception $e) { + $source->log('import', $e->getMessage(), array(), WATCHDOG_ERROR); + } +} + +/** * Mark feeds import item as skipped. */ function feeds_action_skip_item($entity_wrapper) { @@ -123,22 +159,6 @@ function feeds_action_skip_item($entity_wrapper) { } /** - * Rules action callback for "feeds_import_feed" action. - */ -function feeds_action_import_feed($feeds_importer_id) { - batch_set(array( - 'title' => t('Importing'), - 'operations' => array( - array('feeds_batch', array('import', $feeds_importer_id, 0)) - ), - 'progress_message' => '', - )); - $batch =& batch_get(); - $batch['progressive'] = FALSE; - batch_process(''); -} - -/** * Help callback for the skip action. */ function feeds_action_skip_item_help() { @@ -146,7 +166,7 @@ function feeds_action_skip_item_help() { } /** - * List callback for selecting Feeds importer. + * List callback for selecting a Feeds importer. */ function feeds_importer_list() { $list = array(); diff --git a/tests/feeds_rules.test b/tests/feeds_rules.test index 5e8031e..b6bf3ab 100644 --- a/tests/feeds_rules.test +++ b/tests/feeds_rules.test @@ -182,4 +182,106 @@ class FeedsRulesTest extends FeedsWebTestCase { $node = node_load(1); $this->assertEqual('Ut wisi enim ad minim veniam', $node->title); } + + /** + * Tests the Rules action 'feeds_import_feed'. + */ + public function testFeedsImportAction() { + // Attach importer to content type and set to not import on submission. + $this->setSettings('node', NULL, array( + 'content_type' => 'page', + 'import_period' => FEEDS_SCHEDULE_NEVER, + 'import_on_create' => FALSE, + )); + + // Create a feed node. + $source_url = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/content.csv'; + $this->createFeedNode('node', $source_url, 'Feed node 1', 'page'); + + // Assert that nothing has been imported yet. + $this->assertNodeCount(1); + + // Create rule with import action. + $rule = $this->createTestRule('cron', FALSE); + $rule->action('feeds_import_feed', array( + 'importer' => 'node', + 'feed_nid' => 1, + )); + $rule->integrityCheck()->save(); + + // Trigger rules event. + $this->cronRun(); + + // Assert that 2 items have been imported (three nodes exist in total). + $this->assertNodeCount(3); + } + + /** + * Tests the Rules action 'feeds_import_feed' with standalone form. + */ + public function testFeedsImportActionUsingStandaloneForm() { + $this->setSettings('node', NULL, array( + 'import_period' => FEEDS_SCHEDULE_NEVER, + 'import_on_create' => FALSE, + )); + + // Save data on import form. + $edit = array( + 'feeds[FeedsHTTPFetcher][source]' => $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/content.csv', + ); + $this->drupalPost('import/node', $edit, 'Save'); + + // Create rule with import action. + $rule = $this->createTestRule('cron', FALSE); + $rule->action('feeds_import_feed', array( + 'importer' => 'node', + 'feed_nid' => 0, + )); + $rule->integrityCheck()->save(); + + // Trigger rules event. + $this->cronRun(); + + // Assert that 2 items have been imported. + $this->assertNodeCount(2); + } + + /** + * Tests the Rules action 'feeds_import_feed' with process in background option. + */ + public function testFeedsImportActionWithProcessInBackgroundOption() { + // Attach importer to content type, set to not import on submission and set + // to run in background. + $this->setSettings('node', NULL, array( + 'content_type' => 'page', + 'import_period' => FEEDS_SCHEDULE_NEVER, + 'import_on_create' => FALSE, + 'process_in_background' => TRUE, + )); + + // Create a feed node. + $source_url = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/content.csv'; + $this->createFeedNode('node', $source_url, 'Feed node 1', 'page'); + + // Assert that nothing has been imported yet. + $this->assertNodeCount(1); + + // Create rule with import action. + $rule = $this->createTestRule('feeds_tests_rules_event', FALSE); + $rule->action('feeds_import_feed', array( + 'importer' => 'node', + 'feed_nid' => 1, + )); + $rule->integrityCheck()->save(); + + // Trigger rules event. + $this->drupalGet('testing/feeds/trigger-rules-event'); + + // Run cron to run background task. + $this->cronRun(); + + // Assert that 2 items have been imported (three nodes exist in total). + $this->assertNodeCount(3); + } + } diff --git a/tests/feeds_tests.module b/tests/feeds_tests.module index fd83c5b..d1b54c1 100644 --- a/tests/feeds_tests.module +++ b/tests/feeds_tests.module @@ -39,6 +39,13 @@ function feeds_tests_menu() { 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); + if (module_exists('rules')) { + $items['testing/feeds/trigger-rules-event'] = array( + 'page callback' => 'feeds_tests_trigger_rules_event', + 'access arguments' => array('access content'), + 'type' => MENU_CALLBACK, + ); + } return $items; } @@ -234,6 +241,16 @@ function feeds_tests_nodes() { } /** + * Page callback. Triggers the rules event 'feeds_tests_rules_event'. + */ +function feeds_tests_trigger_rules_event() { + rules_invoke_event('feeds_tests_rules_event'); + return array( + '#markup' => 'Rules event "feeds_tests_rules_event" triggered.', + ); +} + +/** * Implements hook_feeds_processor_targets(). */ function feeds_tests_feeds_processor_targets($entity_type, $bundle) { diff --git a/tests/feeds_tests.rules.inc b/tests/feeds_tests.rules.inc index ca3cf4e..34851bf 100644 --- a/tests/feeds_tests.rules.inc +++ b/tests/feeds_tests.rules.inc @@ -6,6 +6,16 @@ */ /** + * Implements hook_rules_event_info(). + */ +function feeds_tests_rules_event_info() { + return array('feeds_tests_rules_event' => array( + 'label' => t('Test event'), + 'group' => t('Feeds'), + )); +} + +/** * Implements hook_rules_action_info(). */ function feeds_tests_rules_action_info() {