From 7f33f0c4b5d01a614a000110a7a463c97e7d6ed7 Mon Sep 17 00:00:00 2001 From: Alex Barth <alex_b@53995.no-reply.drupal.org> Date: Tue, 27 Jul 2010 23:01:25 +0000 Subject: [PATCH] #851194: Featurize. Replace feeds_defaults with feeds_fast_news, feeds_import, feeds_news. Needs more testing especially of upgrade path. --- feeds.install | 21 + feeds_defaults/feeds_defaults.defaults.inc | 430 ---------------- feeds_defaults/feeds_defaults.features.inc | 35 -- feeds_defaults/feeds_defaults.info | 8 - feeds_defaults/feeds_defaults.install | 35 -- feeds_defaults/feeds_defaults.module | 51 -- feeds_defaults/tests/feeds_defaults.test | 469 ------------------ .../feeds_fast_news.data_default.inc | 133 +++++ feeds_fast_news/feeds_fast_news.features.inc | 37 ++ ...feeds_fast_news.feeds_importer_default.inc | 65 +++ feeds_fast_news/feeds_fast_news.info | 13 + feeds_fast_news/feeds_fast_news.install | 46 ++ feeds_fast_news/feeds_fast_news.module | 3 + feeds_fast_news/feeds_fast_news.test | 86 ++++ feeds_import/feeds_import.features.inc | 11 + .../feeds_import.feeds_importer_default.inc | 120 +++++ feeds_import/feeds_import.info | 9 + feeds_import/feeds_import.module | 3 + feeds_import/feeds_import.test | 175 +++++++ feeds_news/feeds_news.features.inc | 51 ++ .../feeds_news.feeds_importer_default.inc | 117 +++++ feeds_news/feeds_news.info | 14 + feeds_news/feeds_news.module | 3 + feeds_news/feeds_news.test | 149 ++++++ feeds_news/feeds_news.views_default.inc | 368 ++++++++++++++ 25 files changed, 1424 insertions(+), 1028 deletions(-) delete mode 100644 feeds_defaults/feeds_defaults.defaults.inc delete mode 100644 feeds_defaults/feeds_defaults.features.inc delete mode 100644 feeds_defaults/feeds_defaults.info delete mode 100644 feeds_defaults/feeds_defaults.install delete mode 100644 feeds_defaults/feeds_defaults.module delete mode 100644 feeds_defaults/tests/feeds_defaults.test create mode 100644 feeds_fast_news/feeds_fast_news.data_default.inc create mode 100644 feeds_fast_news/feeds_fast_news.features.inc create mode 100644 feeds_fast_news/feeds_fast_news.feeds_importer_default.inc create mode 100644 feeds_fast_news/feeds_fast_news.info create mode 100644 feeds_fast_news/feeds_fast_news.install create mode 100644 feeds_fast_news/feeds_fast_news.module create mode 100644 feeds_fast_news/feeds_fast_news.test create mode 100644 feeds_import/feeds_import.features.inc create mode 100644 feeds_import/feeds_import.feeds_importer_default.inc create mode 100644 feeds_import/feeds_import.info create mode 100644 feeds_import/feeds_import.module create mode 100644 feeds_import/feeds_import.test create mode 100644 feeds_news/feeds_news.features.inc create mode 100644 feeds_news/feeds_news.feeds_importer_default.inc create mode 100644 feeds_news/feeds_news.info create mode 100644 feeds_news/feeds_news.module create mode 100644 feeds_news/feeds_news.test create mode 100644 feeds_news/feeds_news.views_default.inc diff --git a/feeds.install b/feeds.install index 2771190f..2a585d39 100644 --- a/feeds.install +++ b/feeds.install @@ -492,3 +492,24 @@ function feeds_update_6009() { db_create_table($ret, 'feeds_push_subscriptions', $table); return $ret; } + +/** + * Enable all Feeds News, Feeds Import and Feeds fast news features. + */ +function feeds_update_6010() { + drupal_install_modules(array('feeds_news', 'feeds_import')); + if (module_exist('data')) { + drupal_install_modules(array('feeds_fast_news')); + drupal_set_message(t('Installed Feeds News, Feeds Fast News and Feeds Import as replacement for Feeds Defaults module.')); + } + else { + drupal_set_message(t('Installed Feeds News and Feeds Import as replacement for Feeds Defaults module.')); + } + if (module_exists('features')) { + drupal_set_message(t('Review importer configurations on admin/build/feeds and disable Feeds Features on admin/build/features if undesired configurations show up.')); + } + else { + drupal_set_message(t('Review importer configurations on admin/build/feeds and disable Feeds Feature modules on admin/build/modules if undesired configurations show up.')); + } + return array(); +} diff --git a/feeds_defaults/feeds_defaults.defaults.inc b/feeds_defaults/feeds_defaults.defaults.inc deleted file mode 100644 index 8fadbf11..00000000 --- a/feeds_defaults/feeds_defaults.defaults.inc +++ /dev/null @@ -1,430 +0,0 @@ -<?php -// $Id$ - -/** - * @file - * Actual function bodies for default hook definitions in - * feeds_defaults.features.inc. - */ - -/** - * Helper to implementation of hook_ctools_plugin_api(). - */ -function _feeds_defaults_ctools_plugin_api() { - $args = func_get_args(); - $module = array_shift($args); - $api = array_shift($args); - if ($module == "data" && $api == "data_default") { - return array("version" => 1); - } - else if ($module == "feeds" && $api == "feeds_importer_default") { - return array("version" => 1); - } -} - -/** - * Helper to implementation of hook_data_default(). - */ -function _feeds_defaults_data_default() { - $export = array(); - $data_table = new stdClass; - $data_table->disabled = FALSE; /* Edit this to true to make a default data_table disabled initially */ - $data_table->api_version = 1; - $data_table->title = 'Fast feed'; - $data_table->name = 'feeds_data_feed_fast'; - $data_table->table_schema = array( - 'fields' => array( - 'feed_nid' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - 'id' => array( - 'type' => 'serial', - 'size' => 'normal', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - 'timestamp' => array( - 'description' => 'The Unix timestamp for the data.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => FALSE, - ), - 'title' => array( - 'type' => 'varchar', - 'length' => 255, - 'not null' => FALSE, - ), - 'description' => array( - 'type' => 'text', - 'not null' => FALSE, - ), - 'url' => array( - 'type' => 'text', - 'not null' => FALSE, - ), - 'guid' => array( - 'type' => 'text', - 'not null' => FALSE, - ), - ), - 'indexes' => array( - 'feed_nid' => array( - '0' => 'feed_nid', - ), - 'id' => array( - '0' => 'id', - ), - 'timestamp' => array( - '0' => 'timestamp', - ), - 'url' => array( - '0' => array( - '0' => 'url', - '1' => 255, - ), - ), - 'guid' => array( - '0' => array( - '0' => 'guid', - '1' => 255, - ), - ), - ), - 'primary key' => array( - '0' => 'id', - ), - ); - $data_table->meta = array( - 'fields' => array( - 'feed_nid' => array( - 'label' => '', - 'views_field_handler' => 'views_handler_field_numeric', - 'views_filter_handler' => 'views_handler_filter_numeric', - 'views_argument_handler' => 'views_handler_argument_numeric', - 'views_sort_handler' => 'views_handler_sort', - ), - 'id' => array( - 'label' => '', - 'views_field_handler' => 'views_handler_field_numeric', - 'views_filter_handler' => 'views_handler_filter_numeric', - 'views_argument_handler' => 'views_handler_argument_numeric', - 'views_sort_handler' => 'views_handler_sort', - ), - 'timestamp' => array( - 'label' => '', - 'views_field_handler' => 'views_handler_field_date', - 'views_filter_handler' => 'views_handler_filter_date', - 'views_argument_handler' => 'views_handler_argument_date', - 'views_sort_handler' => 'views_handler_sort_date', - ), - 'title' => array( - 'label' => '', - 'views_field_handler' => 'views_handler_field', - 'views_filter_handler' => 'views_handler_filter_string', - 'views_argument_handler' => 'views_handler_argument_string', - 'views_sort_handler' => 'views_handler_sort', - ), - 'description' => array( - 'label' => '', - 'views_field_handler' => 'views_handler_field', - 'views_filter_handler' => 'views_handler_filter_string', - 'views_argument_handler' => 'views_handler_argument', - 'views_sort_handler' => 'views_handler_sort', - ), - 'url' => array( - 'label' => '', - 'views_field_handler' => 'views_handler_field_url', - 'views_filter_handler' => 'views_handler_filter_string', - 'views_argument_handler' => 'views_handler_argument', - 'views_sort_handler' => 'views_handler_sort', - ), - 'guid' => array( - 'label' => '', - 'views_field_handler' => 'views_handler_field', - 'views_filter_handler' => 'views_handler_filter_string', - 'views_argument_handler' => 'views_handler_argument', - 'views_sort_handler' => 'views_handler_sort', - ), - ), - ); - - $export['feeds_data_feed_fast'] = $data_table; - return $export; -} - -/** - * Helper to implementation of hook_feeds_importer_default(). - */ -function _feeds_defaults_feeds_importer_default() { - $export = array(); - $feeds_importer = new stdClass; - $feeds_importer->disabled = TRUE; /* Edit this to true to make a default feeds_importer disabled initially */ - $feeds_importer->api_version = 1; - $feeds_importer->id = 'feed'; - $feeds_importer->config = array( - 'name' => 'Feed', - 'description' => 'Import RSS or Atom feeds, create nodes from feed items.', - 'fetcher' => array( - 'plugin_key' => 'FeedsHTTPFetcher', - 'config' => array( - 'auto_detect_feeds' => FALSE, - ), - ), - 'parser' => array( - 'plugin_key' => 'FeedsSyndicationParser', - 'config' => array(), - ), - 'processor' => array( - 'plugin_key' => 'FeedsNodeProcessor', - 'config' => array( - 'content_type' => 'feed_item', - 'update_existing' => 0, - 'expire' => '-1', - 'mappings' => array( - '0' => array( - 'source' => 'title', - 'target' => 'title', - 'unique' => FALSE, - ), - '1' => array( - 'source' => 'description', - 'target' => 'body', - 'unique' => FALSE, - ), - '2' => array( - 'source' => 'timestamp', - 'target' => 'created', - 'unique' => FALSE, - ), - '3' => array( - 'source' => 'url', - 'target' => 'url', - 'unique' => TRUE, - ), - '4' => array( - 'source' => 'guid', - 'target' => 'guid', - 'unique' => TRUE, - ), - ), - ), - ), - 'content_type' => 'feed', - 'update' => 0, - 'import_period' => '1800', - 'expire_period' => 3600, - 'import_on_create' => 1, - ); - - $export['feed'] = $feeds_importer; - - // Expose a default configuration for Data if enabled. - if (module_exists('data')) { - - $feeds_importer = new stdClass; - $feeds_importer->disabled = TRUE; /* Edit this to true to make a default feeds_importer disabled initially */ - $feeds_importer->api_version = 1; - $feeds_importer->id = 'feed_fast'; - $feeds_importer->config = array( - 'name' => 'Fast feed', - 'description' => 'Create light weight database records from feed items. Faster than aggregating nodes.', - 'fetcher' => array( - 'plugin_key' => 'FeedsHTTPFetcher', - 'config' => array( - 'auto_detect_feeds' => FALSE, - ), - ), - 'parser' => array( - 'plugin_key' => 'FeedsSyndicationParser', - 'config' => array(), - ), - 'processor' => array( - 'plugin_key' => 'FeedsDataProcessor', - 'config' => array( - 'update_existing' => 0, - 'expire' => '7257600', - 'mappings' => array( - '0' => array( - 'source' => 'title', - 'target' => 'title', - 'unique' => 0, - ), - '1' => array( - 'source' => 'description', - 'target' => 'description', - 'unique' => 0, - ), - '2' => array( - 'source' => 'url', - 'target' => 'url', - 'unique' => 1, - ), - '3' => array( - 'source' => 'guid', - 'target' => 'guid', - 'unique' => 1, - ), - ), - ), - ), - 'content_type' => 'feed_fast', - 'update' => 0, - 'import_period' => '1800', - 'expire_period' => 3600, - 'import_on_create' => 1, - ); - - $export['feed_fast'] = $feeds_importer; - } - - $feeds_importer = new stdClass; - $feeds_importer->disabled = TRUE; /* Edit this to true to make a default feeds_importer disabled initially */ - $feeds_importer->api_version = 1; - $feeds_importer->id = 'node'; - $feeds_importer->config = array( - 'name' => 'Node import', - 'description' => 'Import nodes from CSV file.', - 'fetcher' => array( - 'plugin_key' => 'FeedsFileFetcher', - 'config' => array(), - ), - 'parser' => array( - 'plugin_key' => 'FeedsCSVParser', - 'config' => array( - 'delimiter' => ',', - ), - ), - 'processor' => array( - 'plugin_key' => 'FeedsNodeProcessor', - 'config' => array( - 'content_type' => 'story', - 'update_existing' => 1, - 'expire' => '-1', - 'mappings' => array( - '0' => array( - 'source' => 'title', - 'target' => 'title', - 'unique' => FALSE, - ), - '1' => array( - 'source' => 'body', - 'target' => 'body', - 'unique' => FALSE, - ), - '2' => array( - 'source' => 'published', - 'target' => 'created', - 'unique' => FALSE, - ), - '3' => array( - 'source' => 'guid', - 'target' => 'guid', - 'unique' => 1, - ), - ), - ), - ), - 'content_type' => '', - 'update' => 0, - 'import_period' => '-1', - 'expire_period' => 3600, - 'import_on_create' => 1, - ); - - $export['node'] = $feeds_importer; - $feeds_importer = new stdClass; - $feeds_importer->disabled = TRUE; /* Edit this to true to make a default feeds_importer disabled initially */ - $feeds_importer->api_version = 1; - $feeds_importer->id = 'opml'; - $feeds_importer->config = array( - 'name' => 'OPML import', - 'description' => 'Import subscriptions from OPML files. Use together with "Feed" configuration.', - 'fetcher' => array( - 'plugin_key' => 'FeedsFileFetcher', - 'config' => array(), - ), - 'parser' => array( - 'plugin_key' => 'FeedsOPMLParser', - 'config' => array(), - ), - 'processor' => array( - 'plugin_key' => 'FeedsFeedNodeProcessor', - 'config' => array( - 'content_type' => 'feed', - 'update_existing' => 0, - 'mappings' => array( - '0' => array( - 'source' => 'title', - 'target' => 'title', - 'unique' => FALSE, - ), - '1' => array( - 'source' => 'xmlurl', - 'target' => 'source', - 'unique' => 1, - ), - ), - ), - ), - 'content_type' => '', - 'update' => 0, - 'import_period' => '-1', - 'expire_period' => 3600, - 'import_on_create' => 1, - ); - - $export['opml'] = $feeds_importer; - $feeds_importer = new stdClass; - $feeds_importer->disabled = TRUE; /* Edit this to true to make a default feeds_importer disabled initially */ - $feeds_importer->api_version = 1; - $feeds_importer->id = 'user'; - $feeds_importer->config = array( - 'name' => 'User import', - 'description' => 'Import users from CSV file.', - 'fetcher' => array( - 'plugin_key' => 'FeedsFileFetcher', - 'config' => array(), - ), - 'parser' => array( - 'plugin_key' => 'FeedsCSVParser', - 'config' => array( - 'delimiter' => ',', - ), - ), - 'processor' => array( - 'plugin_key' => 'FeedsUserProcessor', - 'config' => array( - 'roles' => array(), - 'update_existing' => FALSE, - 'status' => 1, - 'mappings' => array( - '0' => array( - 'source' => 'name', - 'target' => 'name', - 'unique' => 0, - ), - '1' => array( - 'source' => 'mail', - 'target' => 'mail', - 'unique' => 1, - ), - '2' => array( - 'source' => 'created', - 'target' => 'created', - 'unique' => FALSE, - ), - ), - ), - ), - 'content_type' => '', - 'update' => 0, - 'import_period' => '-1', - 'expire_period' => 3600, - 'import_on_create' => 1, - ); - - $export['user'] = $feeds_importer; - return $export; -} diff --git a/feeds_defaults/feeds_defaults.features.inc b/feeds_defaults/feeds_defaults.features.inc deleted file mode 100644 index 2247f14f..00000000 --- a/feeds_defaults/feeds_defaults.features.inc +++ /dev/null @@ -1,35 +0,0 @@ -<?php -// $Id$ - -/** - * @file - * Default hook definitions. This code is generated with Features module but it - * has been tweaked manually. Do not attempt to reexport. - */ - -/** - * Implementation of hook_ctools_plugin_api(). - */ -function feeds_defaults_ctools_plugin_api() { - module_load_include('inc', 'feeds_defaults', 'feeds_defaults.defaults'); - $args = func_get_args(); - return call_user_func_array('_feeds_defaults_ctools_plugin_api', $args); -} - -/** - * Implementation of hook_data_default(). - */ -function feeds_defaults_data_default() { - module_load_include('inc', 'feeds_defaults', 'feeds_defaults.defaults'); - $args = func_get_args(); - return call_user_func_array('_feeds_defaults_data_default', $args); -} - -/** - * Implementation of hook_feeds_importer_default(). - */ -function feeds_defaults_feeds_importer_default() { - module_load_include('inc', 'feeds_defaults', 'feeds_defaults.defaults'); - $args = func_get_args(); - return call_user_func_array('_feeds_defaults_feeds_importer_default', $args); -} diff --git a/feeds_defaults/feeds_defaults.info b/feeds_defaults/feeds_defaults.info deleted file mode 100644 index bd333032..00000000 --- a/feeds_defaults/feeds_defaults.info +++ /dev/null @@ -1,8 +0,0 @@ -; $Id$ -core = "6.x" -name = "Feeds Defaults" -package = "Feeds" -description = "Get started: useful default configurations for Feeds: RSS/Atom aggregation, OPML import, node import and user import." -project = "Feeds" -dependencies[] = "feeds" -php = 5.2 diff --git a/feeds_defaults/feeds_defaults.install b/feeds_defaults/feeds_defaults.install deleted file mode 100644 index 93a10600..00000000 --- a/feeds_defaults/feeds_defaults.install +++ /dev/null @@ -1,35 +0,0 @@ -<?php -// $Id$ - -/** - * @file - * Install hooks. - */ - -/** - * Implementation of hook_schema(). - */ -function feeds_defaults_schema() { - // Install data tables. - include_once('feeds_defaults.features.inc'); - $tables = feeds_defaults_data_default(); - $schema = array(); - foreach ($tables as $name => $table) { - $schema[$name] = $table->table_schema; - } - return $schema; -} - -/** - * Implementation of hook_install(). - */ -function feeds_defaults_install() { - drupal_install_schema('feeds_defaults'); -} - -/** - * Implementation of hook_uninstall(); - */ -function feeds_defaults_uninstall() { - drupal_uninstall_schema('feeds_defaults'); -} diff --git a/feeds_defaults/feeds_defaults.module b/feeds_defaults/feeds_defaults.module deleted file mode 100644 index cf03317b..00000000 --- a/feeds_defaults/feeds_defaults.module +++ /dev/null @@ -1,51 +0,0 @@ -<?php -// $Id$ - -/** - * @file - * Default importer configurations for Feeds module. - */ - -require_once(dirname(__FILE__) .'/feeds_defaults.features.inc'); - -/** - * Implementation of hook_node_info(). - */ -function feeds_defaults_node_info() { - $items = array(); - if (in_array('feed', feeds_enabled_importers())) { - $items['feed'] = array( - 'name' => t('Feed'), - 'module' => 'node', - 'description' => t('Subscribe to RSS or Atom feeds. Creates nodes of the content type "Feed item" from feed content.'), - 'has_title' => '1', - 'title_label' => t('Title'), - 'has_body' => '1', - 'body_label' => t('Body'), - 'locked' => TRUE, - ); - $items['feed_item'] = array( - 'name' => t('Feed item'), - 'module' => 'node', - 'description' => t('This content type is being used for automatically aggregated content from feeds.'), - 'has_title' => '1', - 'title_label' => t('Title'), - 'has_body' => '1', - 'body_label' => t('Body'), - 'locked' => TRUE, - ); - } - if (in_array('feed_fast', feeds_enabled_importers())) { - $items['feed_fast'] = array( - 'name' => t('Fast feed'), - 'module' => 'node', - 'description' => t('Subscribe to RSS or Atom feeds. Create light weight database records from feed content.'), - 'has_title' => '1', - 'title_label' => t('Title'), - 'has_body' => '1', - 'body_label' => t('Body'), - 'locked' => TRUE, - ); - } - return $items; -} diff --git a/feeds_defaults/tests/feeds_defaults.test b/feeds_defaults/tests/feeds_defaults.test deleted file mode 100644 index 5f7aac74..00000000 --- a/feeds_defaults/tests/feeds_defaults.test +++ /dev/null @@ -1,469 +0,0 @@ -<?php -// $Id$ - -/** - * @file - * Tests for default configurations. - */ - -// Require FeedsWebTestCase class definition. -require_once(dirname(__FILE__) .'/../../tests/feeds.test.inc'); - -/** - * Base class for default tests. - */ -class FeedsDefaultsTestCase extends FeedsWebTestCase { - - /** - * Enable a default configuration and verify it. - */ - public function enable($ids) { - if (is_string($ids)) { - $ids = array($ids); - } - $edit = array(); - foreach ($ids as $id) { - $edit[$id] = TRUE; - } - $this->drupalPost('admin/build/feeds', $edit, 'Save'); - foreach ($ids as $id) { - $this->assertRaw('admin/build/feeds/edit/'. $id .'">Override', 'Enabled '. $id); - } - } - - /** - * Disable a default configuration and verify it. - */ - public function disable($ids) { - if (is_string($ids)) { - $ids = array($ids); - } - $edit = array(); - foreach ($ids as $id) { - $edit[$id] = FALSE; - } - $this->drupalPost('admin/build/feeds', $edit, 'Save'); - foreach ($ids as $id) { - $this->assertNoRaw('admin/build/feeds/edit/'. $id .'">Override', 'Disabled '. $id); - } - } -} - -/** - * Test Feed configuration. - */ -class FeedsDefaultsFeedTestCase extends FeedsDefaultsTestCase { - - /** - * Set up test. - */ - public function setUp() { - parent::setUp('feeds', 'feeds_ui', 'ctools', 'feeds_defaults'); - - $this->drupalLogin( - $this->drupalCreateUser( - array( - 'administer feeds', 'administer nodes', - ) - ) - ); - } - - /** - * Describe this test. - */ - public function getInfo() { - return array( - 'name' => t('Defaults: Feed'), - 'description' => t('Test "Feed" default configuration.'), - 'group' => t('Feeds'), - ); - } - - /** - * Run tests. - */ - public function test() { - $this->enable('feed'); - $nid = $this->createFeedNode('feed', NULL, '', 'feed'); - - // Assert results. - $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'feed_item'")); - $this->assertEqual($count, 10, 'Found the correct number of feed item nodes in database.'); - - $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); - $this->assertEqual($count, 10, 'Found the correct number of records in feeds_node_item.'); - - $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE title = 'Open Atrium Translation Workflow: Two Way Translation Updates'")); - $this->assertEqual($count, 1, 'Found title.'); - $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE title = 'Week in DC Tech: October 5th Edition'")); - $this->assertEqual($count, 1, 'Found title.'); - $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE title = 'Integrating the Siteminder Access System in an Open Atrium-based Intranet'")); - $this->assertEqual($count, 1, 'Found title.'); - $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE title = 'Scaling the Open Atrium UI'")); - $this->assertEqual($count, 1, 'Found title.'); - - $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item} WHERE url = 'http://developmentseed.org/blog/2009/oct/06/open-atrium-translation-workflow-two-way-updating'")); - $this->assertEqual($count, 1, 'Found feed_node_item record.'); - $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item} WHERE url = 'http://developmentseed.org/blog/2009/oct/05/week-dc-tech-october-5th-edition'")); - $this->assertEqual($count, 1, 'Found feed_node_item record.'); - $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item} WHERE guid = '974 at http://developmentseed.org'")); - $this->assertEqual($count, 1, 'Found feed_node_item record.'); - $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item} WHERE guid = '970 at http://developmentseed.org'")); - $this->assertEqual($count, 1, 'Found feed_node_item record.'); - - // Remove all items - $this->drupalPost('node/'. $nid .'/delete-items', array(), 'Delete'); - $this->assertText('Deleted 10 nodes.'); - - // Import again. - $this->drupalPost('node/'. $nid .'/import', array(), 'Import'); - $this->assertText('Created 10 Feed item nodes.'); - - // Delete and assert all items gone. - $this->drupalPost('node/'. $nid .'/delete-items', array(), 'Delete'); - - $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'feed_item'")); - $this->assertEqual($count, 0, 'Found the correct number of feed item nodes in database.'); - - $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); - $this->assertEqual($count, 0, 'Found the correct number of records in feeds_node_item.'); - - // Create a batch of nodes. - $this->createFeedNodes('feed', 10, 'feed'); - $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'feed_item'")); - $this->assertEqual($count, 100, 'Imported 100 nodes.'); - $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); - $this->assertEqual($count, 100, 'Found 100 records in feeds_node_item.'); - - // Disable the configuration. - $this->disable('feed'); - $this->drupalGet('node/add'); - $this->assertNoRaw('node/add/feed'); - $this->assertNoText('node/add/feed-item'); - } -} - -/** - * Test Feed fast configuration. - */ -class FeedsDefaultsFastFeedTestCase extends FeedsDefaultsTestCase { - - /** - * Set up test. - */ - public function setUp() { - parent::setUp('feeds', 'feeds_ui', 'ctools', 'feeds_defaults', 'data', 'data_ui', 'views', 'views_ui'); - - $this->drupalLogin( - $this->drupalCreateUser( - array( - 'administer feeds', 'administer nodes', 'administer data tables', - ) - ) - ); - } - - /** - * Describe this test. - */ - public function getInfo() { - return array( - 'name' => t('Defaults: Fast feed'), - 'description' => t('Test "Fast feed" default configuration <strong>Requires Data and Views.</strong>'), - 'group' => t('Feeds'), - ); - } - - /** - * Run tests. - */ - public function test() { - - // Enable configuration and assert status. - $this->enable('feed_fast'); - $this->drupalGet('admin/build/data'); - $this->assertText('feeds_data_feed_fast'); - $this->drupalGet('admin/content/data/view/feeds_data_feed_fast'); - $this->assertText('Fast feed'); - $this->assertText('There is no data in this table.'); - - // Create feed node. - $nid = $this->createFeedNode('feed_fast', NULL, '', 'feed_fast'); - $this->assertText('Created 10 items.'); - - // Verify presence of aggregated items. - $this->drupalGet('admin/content/data/view/feeds_data_feed_fast'); - $this->assertText('Open Atrium Translation Workflow: Two Way Translation Updates'); - $this->assertText('n a word, nothing. There has been a major improvement on this front. Now your translation'); - $this->assertLink('http://developmentseed.org/blog/2009/oct/06/open-atrium-translation-workflow-two-way-updating'); - - // Delete and re import. - $this->drupalPost('node/'. $nid .'/delete-items', array(), 'Delete'); - $this->assertText('Deleted 10 items.'); - $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_data_feed_fast}")); - $this->assertEqual($count, 0, 'Found correct number of items.'); - - $this->drupalPost('node/'. $nid .'/delete-items', array(), 'Delete'); - $this->assertText('Deleted 0 items.'); - $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_data_feed_fast}")); - $this->assertEqual($count, 0, 'Found correct number of items.'); - - $this->drupalPost('node/'. $nid .'/import', array(), 'Import'); - $this->assertText('Created 10 items.'); - $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_data_feed_fast}")); - $this->assertEqual($count, 10, 'Found correct number of items.'); - - $this->drupalPost('node/'. $nid .'/import', array(), 'Import'); - $this->assertText('There are no new items.'); - $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_data_feed_fast}")); - $this->assertEqual($count, 10, 'Found correct number of items.'); - - // Disable. - $this->disable('feed_fast'); - $this->drupalGet('node/add'); - $this->assertNoRaw('node/add/feed-fast'); - } -} - -/** - * Test Node import configuration. - */ -class FeedsDefaultsNodeTestCase extends FeedsDefaultsTestCase { - - /** - * Set up test. - */ - public function setUp() { - parent::setUp('feeds', 'feeds_ui', 'ctools', 'feeds_defaults'); - - $this->drupalLogin( - $this->drupalCreateUser( - array( - 'administer feeds', 'administer nodes', - ) - ) - ); - } - - /** - * Describe this test. - */ - public function getInfo() { - return array( - 'name' => t('Defaults: Node import'), - 'description' => t('Test "Node import" default configuration.'), - 'group' => t('Feeds'), - ); - } - - /** - * Run tests. - */ - public function test() { - $this->enable('node'); - - // Import file. - $this->importFile('node', $this->absolutePath() .'/tests/feeds/nodes.csv'); - - // Assert returning page. - $this->assertText('Created 8 Story nodes.'); - $this->assertText('Import CSV files with one or more of these columns: title, body, published, guid.'); - $this->assertText('Column guid is mandatory and considered unique: only one item per guid value will be created.'); - $this->assertRaw('feeds/nodes.csv'); - - // Assert created nodes. - $this->drupalGet('node'); - $this->assertText('Typi non habent'); - $this->assertText('Eodem modo typi'); - $this->assertText('Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.'); - $this->assertText('Lorem ipsum'); - $this->assertText('Ut wisi enim ad minim veniam'); - $this->assertText('1976'); - // Nam liber tempor has the same GUID as Lorem ipsum. - $this->assertNoText('Nam liber tempor'); - - // Click through to one node. - $this->clickLink('Lorem ipsum'); - $this->assertText('Lorem ipsum'); - $this->assertText('Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.'); - $this->assertText('Anonymous'); - - // Assert DB status as is and again after an additional import. - for ($i = 0; $i < 2; $i++) { - $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); - $this->assertEqual($count, 8, 'Found correct number of items.'); - $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'story' AND status = 1 AND uid = 0")); - $this->assertEqual($count, 8, 'Found correct number of items.'); - // Do not filter on type intentionally. There shouldn't be more than 8 nodes total. - $count = db_result(db_query("SELECT COUNT(*) FROM {node_revisions}")); - $this->assertEqual($count, 8, 'Found correct number of items.'); - - // Import again. Feeds only updates items that haven't changed. However, - // there are 2 different items with the same GUID in nodes.csv. - // Therefore, feeds will show updates to 2 nodes. - $this->drupalPost('import/node/import', array(), 'Import'); - $this->assertText('Updated 2 Story nodes.'); - } - - // Remove all nodes. - $this->drupalPost('import/node/delete-items', array(), 'Delete'); - $this->assertText('Deleted 8 nodes.'); - - // Import once again. - $this->drupalPost('import/node/import', array(), 'Import'); - $this->assertText('Created 8 Story nodes.'); - - // Import a similar file with changes in 4 records. Feeds should report 6 - // Updated story nodes (4 changed records, 2 records sharing a GUID - // subsequently being updated). - $this->importFile('node', $this->absolutePath() .'/tests/feeds/nodes_changes.csv'); - $this->assertText('Updated 6 Story nodes.'); - - // Import a larger file with more records. - $this->importFile('node', $this->absolutePath() .'/tests/feeds/many_nodes.csv'); - $this->assertText('Created 71 Story nodes.'); - - // Remove all nodes. - $this->drupalPost('import/node/delete-items', array(), 'Delete'); - $this->assertText('Deleted 79 nodes.'); - - // Import once again. - $this->drupalPost('import/node/import', array(), 'Import'); - $this->assertText('Created 79 Story nodes.'); - - // Disable, nodes should be still present. - $this->disable('node'); - $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); - $this->assertEqual($count, 79, 'Found correct number of items.'); - $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'story' AND status = 1 AND uid = 0")); - $this->assertEqual($count, 79, 'Found correct number of items.'); - // Do not filter on type intentionally. There shouldn't be more than 8 nodes total. - $count = db_result(db_query("SELECT COUNT(*) FROM {node_revisions}")); - $this->assertEqual($count, 79, 'Found correct number of items.'); - - // Import a tab separated file. - $this->enable('node'); - $this->drupalPost('import/node/delete-items', array(), 'Delete'); - $edit = array( - 'files[feeds]' => $this->absolutePath() .'/tests/feeds/nodes.tsv', - 'feeds[FeedsCSVParser][delimiter]' => "TAB", - ); - $this->drupalPost('import/node', $edit, 'Import'); - $this->assertText('Created 8 Story nodes.'); - - // Disable before exiting test. - $this->disable('node'); - } -} - -/** - * Test OPML import configuration. - */ -class FeedsDefaultsOPMLTestCase extends FeedsDefaultsTestCase { - - /** - * Set up test. - */ - public function setUp() { - parent::setUp('feeds', 'feeds_ui', 'ctools', 'feeds_defaults'); - - $this->drupalLogin( - $this->drupalCreateUser( - array( - 'administer feeds', 'administer nodes', - ) - ) - ); - } - - /** - * Describe this test. - */ - public function getInfo() { - return array( - 'name' => t('Defaults: OPML import'), - 'description' => t('Test "OPML import" default configuration.'), - 'group' => t('Feeds'), - ); - } - - /** - * Run tests. - */ - public function test() { - $this->enable('feed'); - $this->enable('opml'); - - // Import OPML and assert. - $file = $this->generateOPML(); - $this->importFile('opml', $file); - $this->assertText('Created 3 feed nodes.'); - $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_source}")); - $this->assertEqual($count, 4, 'Found correct number of items.'); - - // Import a feed and then delete all items from it. - $this->drupalPost('node/1/import', array(), 'Import'); - $this->assertText('Created 10 Feed item nodes.'); - $this->drupalPost('node/1/delete-items', array(), 'Delete'); - $this->assertText('Deleted 10 nodes.'); - - // Disable. - $this->disable('feed'); - $this->disable('opml'); - } -} - -/** - * Test User import configuration. - */ -class FeedsDefaultsUserTestCase extends FeedsDefaultsTestCase { - - /** - * Set up test. - */ - public function setUp() { - parent::setUp('feeds', 'feeds_ui', 'ctools', 'feeds_defaults'); - - $this->drupalLogin( - $this->drupalCreateUser( - array( - 'administer feeds', 'administer users', - ) - ) - ); - } - - /** - * Describe this test. - */ - public function getInfo() { - return array( - 'name' => t('Defaults: User import'), - 'description' => t('Test "User import" default configuration.'), - 'group' => t('Feeds'), - ); - } - - /** - * Run tests. - */ - public function test() { - $this->enable('user'); - - // Import CSV file. - $this->importFile('user', $this->absolutePath() .'/tests/feeds/users.csv'); - - // Assert result. - $this->assertText('Created 4 users.'); - // 1 user has an invalid email address. - $this->assertText('There was 1 user that could not be imported because either their name or their email was empty or not valid. Check import data and mapping settings on User processor.'); - $this->drupalGet('admin/user/user'); - $this->assertText('Morticia'); - $this->assertText('Fester'); - $this->assertText('Gomez'); - $this->assertText('Pugsley'); - - $this->disable('user'); - } -} diff --git a/feeds_fast_news/feeds_fast_news.data_default.inc b/feeds_fast_news/feeds_fast_news.data_default.inc new file mode 100644 index 00000000..758b93d2 --- /dev/null +++ b/feeds_fast_news/feeds_fast_news.data_default.inc @@ -0,0 +1,133 @@ +<?php + +/** + * Implementation of hook_data_default(). + */ +function feeds_fast_news_data_default() { + $export = array(); + $data_table = new stdClass; + $data_table->disabled = FALSE; /* Edit this to true to make a default data_table disabled initially */ + $data_table->api_version = 1; + $data_table->title = 'Fast feed'; + $data_table->name = 'feeds_data_feed_fast'; + $data_table->table_schema = array( + 'fields' => array( + 'feed_nid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'id' => array( + 'type' => 'serial', + 'size' => 'normal', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'timestamp' => array( + 'description' => 'The Unix timestamp for the data.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => FALSE, + ), + 'title' => array( + 'type' => 'varchar', + 'length' => 255, + 'not null' => FALSE, + ), + 'description' => array( + 'type' => 'text', + 'not null' => FALSE, + ), + 'url' => array( + 'type' => 'text', + 'not null' => FALSE, + ), + 'guid' => array( + 'type' => 'text', + 'not null' => FALSE, + ), + ), + 'indexes' => array( + 'feed_nid' => array( + '0' => 'feed_nid', + ), + 'id' => array( + '0' => 'id', + ), + 'timestamp' => array( + '0' => 'timestamp', + ), + 'url' => array( + '0' => array( + '0' => 'url', + '1' => 255, + ), + ), + 'guid' => array( + '0' => array( + '0' => 'guid', + '1' => 255, + ), + ), + ), + 'primary key' => array( + '0' => 'id', + ), + ); + $data_table->meta = array( + 'fields' => array( + 'feed_nid' => array( + 'label' => '', + 'views_field_handler' => 'views_handler_field_numeric', + 'views_filter_handler' => 'views_handler_filter_numeric', + 'views_argument_handler' => 'views_handler_argument_numeric', + 'views_sort_handler' => 'views_handler_sort', + ), + 'id' => array( + 'label' => '', + 'views_field_handler' => 'views_handler_field_numeric', + 'views_filter_handler' => 'views_handler_filter_numeric', + 'views_argument_handler' => 'views_handler_argument_numeric', + 'views_sort_handler' => 'views_handler_sort', + ), + 'timestamp' => array( + 'label' => '', + 'views_field_handler' => 'views_handler_field_date', + 'views_filter_handler' => 'views_handler_filter_date', + 'views_argument_handler' => 'views_handler_argument_date', + 'views_sort_handler' => 'views_handler_sort_date', + ), + 'title' => array( + 'label' => '', + 'views_field_handler' => 'views_handler_field', + 'views_filter_handler' => 'views_handler_filter_string', + 'views_argument_handler' => 'views_handler_argument_string', + 'views_sort_handler' => 'views_handler_sort', + ), + 'description' => array( + 'label' => '', + 'views_field_handler' => 'views_handler_field', + 'views_filter_handler' => 'views_handler_filter_string', + 'views_argument_handler' => 'views_handler_argument', + 'views_sort_handler' => 'views_handler_sort', + ), + 'url' => array( + 'label' => '', + 'views_field_handler' => 'views_handler_field_url', + 'views_filter_handler' => 'views_handler_filter_string', + 'views_argument_handler' => 'views_handler_argument', + 'views_sort_handler' => 'views_handler_sort', + ), + 'guid' => array( + 'label' => '', + 'views_field_handler' => 'views_handler_field', + 'views_filter_handler' => 'views_handler_filter_string', + 'views_argument_handler' => 'views_handler_argument', + 'views_sort_handler' => 'views_handler_sort', + ), + ), + ); + + $export['feeds_data_feed_fast'] = $data_table; + return $export; +} diff --git a/feeds_fast_news/feeds_fast_news.features.inc b/feeds_fast_news/feeds_fast_news.features.inc new file mode 100644 index 00000000..709063ff --- /dev/null +++ b/feeds_fast_news/feeds_fast_news.features.inc @@ -0,0 +1,37 @@ +<?php + +/** + * Implementation of hook_ctools_plugin_api(). + */ +function feeds_fast_news_ctools_plugin_api() { + list($module, $api) = func_get_args(); + if ($module == "data" && $api == "data_default") { + return array("version" => 1); + } + elseif ($module == "data" && $api == "data_table") { + return array("version" => 1); + } + elseif ($module == "feeds" && $api == "feeds_importer_default") { + return array("version" => 1); + } +} + +/** + * Implementation of hook_node_info(). + */ +function feeds_fast_news_node_info() { + $items = array( + 'feed_fast' => array( + 'name' => t('Fast feed'), + 'module' => 'node', + 'description' => t('Subscribe to RSS or Atom feeds. Create light weight database records from feed content.'), + 'has_title' => '1', + 'title_label' => t('Title'), + 'has_body' => '1', + 'body_label' => t('Body'), + 'min_word_count' => '0', + 'help' => '', + ), + ); + return $items; +} diff --git a/feeds_fast_news/feeds_fast_news.feeds_importer_default.inc b/feeds_fast_news/feeds_fast_news.feeds_importer_default.inc new file mode 100644 index 00000000..023cfd02 --- /dev/null +++ b/feeds_fast_news/feeds_fast_news.feeds_importer_default.inc @@ -0,0 +1,65 @@ +<?php + +/** + * Implementation of hook_feeds_importer_default(). + */ +function feeds_fast_news_feeds_importer_default() { + $export = array(); + $feeds_importer = new stdClass; + $feeds_importer->disabled = FALSE; /* Edit this to true to make a default feeds_importer disabled initially */ + $feeds_importer->api_version = 1; + $feeds_importer->id = 'feed_fast'; + $feeds_importer->config = array( + 'name' => 'Fast feed', + 'description' => 'Create light weight database records from feed items. Faster than aggregating nodes.', + 'fetcher' => array( + 'plugin_key' => 'FeedsHTTPFetcher', + 'config' => array( + 'auto_detect_feeds' => FALSE, + 'use_pubsubhubbub' => FALSE, + 'designated_hub' => '', + ), + ), + 'parser' => array( + 'plugin_key' => 'FeedsSyndicationParser', + 'config' => array(), + ), + 'processor' => array( + 'plugin_key' => 'FeedsDataProcessor', + 'config' => array( + 'update_existing' => 0, + 'expire' => '7257600', + 'mappings' => array( + '0' => array( + 'source' => 'title', + 'target' => 'title', + 'unique' => 0, + ), + '1' => array( + 'source' => 'description', + 'target' => 'description', + 'unique' => 0, + ), + '2' => array( + 'source' => 'url', + 'target' => 'url', + 'unique' => 1, + ), + '3' => array( + 'source' => 'guid', + 'target' => 'guid', + 'unique' => 1, + ), + ), + ), + ), + 'content_type' => 'feed_fast', + 'update' => 0, + 'import_period' => '1800', + 'expire_period' => 3600, + 'import_on_create' => 1, + ); + + $export['feed_fast'] = $feeds_importer; + return $export; +} diff --git a/feeds_fast_news/feeds_fast_news.info b/feeds_fast_news/feeds_fast_news.info new file mode 100644 index 00000000..70547f87 --- /dev/null +++ b/feeds_fast_news/feeds_fast_news.info @@ -0,0 +1,13 @@ +core = "6.x" +dependencies[] = "data" +dependencies[] = "feeds" +description = "A fast news aggregator built with feeds, creates flat database records from imported feed items." +features[ctools][] = "data:data_default:1" +features[ctools][] = "data:data_table:1" +features[ctools][] = "feeds:feeds_importer_default:1" +features[data_tables][] = "feeds_data_feed_fast" +features[feeds_importer][] = "feed_fast" +features[node][] = "feed_fast" +name = "Feeds Fast News" +package = "Feeds" +project = "Feeds" diff --git a/feeds_fast_news/feeds_fast_news.install b/feeds_fast_news/feeds_fast_news.install new file mode 100644 index 00000000..ba78a0ab --- /dev/null +++ b/feeds_fast_news/feeds_fast_news.install @@ -0,0 +1,46 @@ +<?php +// $Id$ + +/** + * @file + * Install hooks. + */ + +/** + * Implementation of hook_schema(). + */ +function feeds_fast_news_schema() { + // Install data tables. + include_once('feeds_fast_news.data_default.inc'); + $tables = feeds_fast_news_data_default(); + $schema = array(); + foreach ($tables as $name => $table) { + $schema[$name] = $table->table_schema; + } + return $schema; +} + +/** + * Implementation of hook_install(). + */ +function feeds_fast_news_install() { + // We are replacing feeds_defaults module, taking over its table. + // Hence we cannot use drupal_install_schema('feeds_fast_news'); + $schema = drupal_get_schema_unprocessed('feeds_fast_news'); + _drupal_initialize_schema('feeds_fast_news', $schema); + + $ret = array(); + foreach ($schema as $name => $table) { + // Check whether table exists. + if (!db_table_exists($name)) { + db_create_table($ret, $name, $table); + } + } +} + +/** + * Implementation of hook_uninstall(); + */ +function feeds_defaults_uninstall() { + drupal_uninstall_schema('feeds_fast_news'); +} diff --git a/feeds_fast_news/feeds_fast_news.module b/feeds_fast_news/feeds_fast_news.module new file mode 100644 index 00000000..ead9b390 --- /dev/null +++ b/feeds_fast_news/feeds_fast_news.module @@ -0,0 +1,3 @@ +<?php + +include_once('feeds_fast_news.features.inc'); diff --git a/feeds_fast_news/feeds_fast_news.test b/feeds_fast_news/feeds_fast_news.test new file mode 100644 index 00000000..66b30424 --- /dev/null +++ b/feeds_fast_news/feeds_fast_news.test @@ -0,0 +1,86 @@ +<?php +// $Id$ + +/** + * @file + * Tests for feeds_fast_news feature. + */ + +// Require FeedsWebTestCase class definition. +require_once(dirname(__FILE__) .'/../tests/feeds.test.inc'); + +/** + * Test Feed fast configuration. + */ +class FeedsExamplesFastFeedTestCase extends FeedsWebTestCase { + + /** + * Set up test. + */ + public function setUp() { + parent::setUp('feeds', 'feeds_ui', 'ctools', 'features', 'feeds_fast_news', 'data', 'data_ui', 'views', 'views_ui'); + + $this->drupalLogin( + $this->drupalCreateUser( + array( + 'administer feeds', 'administer nodes', 'administer data tables', + ) + ) + ); + } + + /** + * Describe this test. + */ + public function getInfo() { + return array( + 'name' => t('Feature: Fast feed'), + 'description' => t('Test "Fast feed" default configuration <strong>Requires Data, Features and Views.</strong>'), + 'group' => t('Feeds'), + ); + } + + /** + * Run tests. + */ + public function test() { + + // Enable configuration and assert status. + $this->drupalGet('admin/build/data'); + $this->assertText('feeds_data_feed_fast'); + $this->drupalGet('admin/content/data/view/feeds_data_feed_fast'); + $this->assertText('Fast feed'); + $this->assertText('There is no data in this table.'); + + // Create feed node. + $nid = $this->createFeedNode('feed_fast', NULL, '', 'feed_fast'); + $this->assertText('Created 10 items.'); + + // Verify presence of aggregated items. + $this->drupalGet('admin/content/data/view/feeds_data_feed_fast'); + $this->assertText('Open Atrium Translation Workflow: Two Way Translation Updates'); + $this->assertText('n a word, nothing. There has been a major improvement on this front. Now your translation'); + $this->assertLink('http://developmentseed.org/blog/2009/oct/06/open-atrium-translation-workflow-two-way-updating'); + + // Delete and re import. + $this->drupalPost('node/'. $nid .'/delete-items', array(), 'Delete'); + $this->assertText('Deleted 10 items.'); + $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_data_feed_fast}")); + $this->assertEqual($count, 0, 'Found correct number of items.'); + + $this->drupalPost('node/'. $nid .'/delete-items', array(), 'Delete'); + $this->assertText('Deleted 0 items.'); + $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_data_feed_fast}")); + $this->assertEqual($count, 0, 'Found correct number of items.'); + + $this->drupalPost('node/'. $nid .'/import', array(), 'Import'); + $this->assertText('Created 10 items.'); + $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_data_feed_fast}")); + $this->assertEqual($count, 10, 'Found correct number of items.'); + + $this->drupalPost('node/'. $nid .'/import', array(), 'Import'); + $this->assertText('There are no new items.'); + $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_data_feed_fast}")); + $this->assertEqual($count, 10, 'Found correct number of items.'); + } +} diff --git a/feeds_import/feeds_import.features.inc b/feeds_import/feeds_import.features.inc new file mode 100644 index 00000000..fd84a3af --- /dev/null +++ b/feeds_import/feeds_import.features.inc @@ -0,0 +1,11 @@ +<?php + +/** + * Implementation of hook_ctools_plugin_api(). + */ +function feeds_import_ctools_plugin_api() { + list($module, $api) = func_get_args(); + if ($module == "feeds" && $api == "feeds_importer_default") { + return array("version" => 1); + } +} diff --git a/feeds_import/feeds_import.feeds_importer_default.inc b/feeds_import/feeds_import.feeds_importer_default.inc new file mode 100644 index 00000000..8e4fd92f --- /dev/null +++ b/feeds_import/feeds_import.feeds_importer_default.inc @@ -0,0 +1,120 @@ +<?php + +/** + * Implementation of hook_feeds_importer_default(). + */ +function feeds_import_feeds_importer_default() { + $export = array(); + $feeds_importer = new stdClass; + $feeds_importer->disabled = FALSE; /* Edit this to true to make a default feeds_importer disabled initially */ + $feeds_importer->api_version = 1; + $feeds_importer->id = 'node'; + $feeds_importer->config = array( + 'name' => 'Node import', + 'description' => 'Import nodes from CSV file.', + 'fetcher' => array( + 'plugin_key' => 'FeedsFileFetcher', + 'config' => array( + 'direct' => FALSE, + ), + ), + 'parser' => array( + 'plugin_key' => 'FeedsCSVParser', + 'config' => array( + 'delimiter' => ',', + ), + ), + 'processor' => array( + 'plugin_key' => 'FeedsNodeProcessor', + 'config' => array( + 'content_type' => 'story', + 'update_existing' => 1, + 'expire' => '-1', + 'mappings' => array( + '0' => array( + 'source' => 'title', + 'target' => 'title', + 'unique' => FALSE, + ), + '1' => array( + 'source' => 'body', + 'target' => 'body', + 'unique' => FALSE, + ), + '2' => array( + 'source' => 'published', + 'target' => 'created', + 'unique' => FALSE, + ), + '3' => array( + 'source' => 'guid', + 'target' => 'guid', + 'unique' => 1, + ), + ), + 'input_format' => 0, + 'author' => 0, + ), + ), + 'content_type' => '', + 'update' => 0, + 'import_period' => '-1', + 'expire_period' => 3600, + 'import_on_create' => 1, + ); + + $export['node'] = $feeds_importer; + $feeds_importer = new stdClass; + $feeds_importer->disabled = FALSE; /* Edit this to true to make a default feeds_importer disabled initially */ + $feeds_importer->api_version = 1; + $feeds_importer->id = 'user'; + $feeds_importer->config = array( + 'name' => 'User import', + 'description' => 'Import users from CSV file.', + 'fetcher' => array( + 'plugin_key' => 'FeedsFileFetcher', + 'config' => array( + 'direct' => FALSE, + ), + ), + 'parser' => array( + 'plugin_key' => 'FeedsCSVParser', + 'config' => array( + 'delimiter' => ',', + ), + ), + 'processor' => array( + 'plugin_key' => 'FeedsUserProcessor', + 'config' => array( + 'roles' => array(), + 'update_existing' => FALSE, + 'status' => 1, + 'mappings' => array( + '0' => array( + 'source' => 'name', + 'target' => 'name', + 'unique' => 0, + ), + '1' => array( + 'source' => 'mail', + 'target' => 'mail', + 'unique' => 1, + ), + '2' => array( + 'source' => 'created', + 'target' => 'created', + 'unique' => FALSE, + ), + ), + ), + ), + 'content_type' => '', + 'update' => 0, + 'import_period' => '-1', + 'expire_period' => 3600, + 'import_on_create' => 1, + ); + + $export['user'] = $feeds_importer; + return $export; +} diff --git a/feeds_import/feeds_import.info b/feeds_import/feeds_import.info new file mode 100644 index 00000000..448296d1 --- /dev/null +++ b/feeds_import/feeds_import.info @@ -0,0 +1,9 @@ +core = "6.x" +dependencies[] = "feeds" +description = "An example of a node importer and a user importer." +features[ctools][] = "feeds:feeds_importer_default:1" +features[feeds_importer][] = "node" +features[feeds_importer][] = "user" +name = "Feeds Import" +package = "Feeds" +project = "Feeds" diff --git a/feeds_import/feeds_import.module b/feeds_import/feeds_import.module new file mode 100644 index 00000000..a7b47532 --- /dev/null +++ b/feeds_import/feeds_import.module @@ -0,0 +1,3 @@ +<?php + +include_once('feeds_import.features.inc'); diff --git a/feeds_import/feeds_import.test b/feeds_import/feeds_import.test new file mode 100644 index 00000000..59902a53 --- /dev/null +++ b/feeds_import/feeds_import.test @@ -0,0 +1,175 @@ +<?php +// $Id$ + +/** + * @file + * Tests for feeds_import feature. + */ + +// Require FeedsWebTestCase class definition. +require_once(dirname(__FILE__) .'/../tests/feeds.test.inc'); + +/** + * Test Node import configuration. + */ +class FeedsExamplesNodeTestCase extends FeedsWebTestCase { + + /** + * Set up test. + */ + public function setUp() { + parent::setUp('feeds', 'feeds_ui', 'ctools', 'feeds_import'); + + $this->drupalLogin( + $this->drupalCreateUser( + array( + 'administer feeds', 'administer nodes', + ) + ) + ); + } + + /** + * Describe this test. + */ + public function getInfo() { + return array( + 'name' => t('Feature: Node import'), + 'description' => t('Test "Node import" default configuration.'), + 'group' => t('Feeds'), + ); + } + + /** + * Run tests. + */ + public function test() { + // Import file. + $this->importFile('node', $this->absolutePath() .'/tests/feeds/nodes.csv'); + + // Assert returning page. + $this->assertText('Created 8 Story nodes.'); + $this->assertText('Import CSV files with one or more of these columns: title, body, published, guid.'); + $this->assertText('Column guid is mandatory and considered unique: only one item per guid value will be created.'); + $this->assertRaw('feeds/nodes.csv'); + + // Assert created nodes. + $this->drupalGet('node'); + $this->assertText('Typi non habent'); + $this->assertText('Eodem modo typi'); + $this->assertText('Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.'); + $this->assertText('Lorem ipsum'); + $this->assertText('Ut wisi enim ad minim veniam'); + $this->assertText('1976'); + // Nam liber tempor has the same GUID as Lorem ipsum. + $this->assertNoText('Nam liber tempor'); + + // Click through to one node. + $this->clickLink('Lorem ipsum'); + $this->assertText('Lorem ipsum'); + $this->assertText('Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.'); + $this->assertText('Anonymous'); + + // Assert DB status as is and again after an additional import. + for ($i = 0; $i < 2; $i++) { + $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); + $this->assertEqual($count, 8, 'Found correct number of items.'); + $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'story' AND status = 1 AND uid = 0")); + $this->assertEqual($count, 8, 'Found correct number of items.'); + // Do not filter on type intentionally. There shouldn't be more than 8 nodes total. + $count = db_result(db_query("SELECT COUNT(*) FROM {node_revisions}")); + $this->assertEqual($count, 8, 'Found correct number of items.'); + + // Import again. Feeds only updates items that haven't changed. However, + // there are 2 different items with the same GUID in nodes.csv. + // Therefore, feeds will show updates to 2 nodes. + $this->drupalPost('import/node/import', array(), 'Import'); + $this->assertText('Updated 2 Story nodes.'); + } + + // Remove all nodes. + $this->drupalPost('import/node/delete-items', array(), 'Delete'); + $this->assertText('Deleted 8 nodes.'); + + // Import once again. + $this->drupalPost('import/node/import', array(), 'Import'); + $this->assertText('Created 8 Story nodes.'); + + // Import a similar file with changes in 4 records. Feeds should report 6 + // Updated story nodes (4 changed records, 2 records sharing a GUID + // subsequently being updated). + $this->importFile('node', $this->absolutePath() .'/tests/feeds/nodes_changes.csv'); + $this->assertText('Updated 6 Story nodes.'); + + // Import a larger file with more records. + $this->importFile('node', $this->absolutePath() .'/tests/feeds/many_nodes.csv'); + $this->assertText('Created 71 Story nodes.'); + + // Remove all nodes. + $this->drupalPost('import/node/delete-items', array(), 'Delete'); + $this->assertText('Deleted 79 nodes.'); + + // Import once again. + $this->drupalPost('import/node/import', array(), 'Import'); + $this->assertText('Created 79 Story nodes.'); + + // Import a tab separated file. + $this->drupalPost('import/node/delete-items', array(), 'Delete'); + $edit = array( + 'files[feeds]' => $this->absolutePath() .'/tests/feeds/nodes.tsv', + 'feeds[FeedsCSVParser][delimiter]' => "TAB", + ); + $this->drupalPost('import/node', $edit, 'Import'); + $this->assertText('Created 8 Story nodes.'); + } +} + +/** + * Test User import configuration. + */ +class FeedsExamplesUserTestCase extends FeedsWebTestCase { + + /** + * Set up test. + */ + public function setUp() { + parent::setUp('feeds', 'feeds_ui', 'ctools', 'feeds_import'); + + $this->drupalLogin( + $this->drupalCreateUser( + array( + 'administer feeds', 'administer users', + ) + ) + ); + } + + /** + * Describe this test. + */ + public function getInfo() { + return array( + 'name' => t('Feature: User import'), + 'description' => t('Test "User import" default configuration.'), + 'group' => t('Feeds'), + ); + } + + /** + * Run tests. + */ + public function test() { + // Import CSV file. + $this->importFile('user', $this->absolutePath() .'/tests/feeds/users.csv'); + + // Assert result. + $this->assertText('Created 4 users.'); + // 1 user has an invalid email address. + $this->assertText('There was 1 user that could not be imported because either their name or their email was empty or not valid. Check import data and mapping settings on User processor.'); + $this->drupalGet('admin/user/user'); + $this->assertText('Morticia'); + $this->assertText('Fester'); + $this->assertText('Gomez'); + $this->assertText('Pugsley'); + } +} diff --git a/feeds_news/feeds_news.features.inc b/feeds_news/feeds_news.features.inc new file mode 100644 index 00000000..810c7621 --- /dev/null +++ b/feeds_news/feeds_news.features.inc @@ -0,0 +1,51 @@ +<?php + +/** + * Implementation of hook_ctools_plugin_api(). + */ +function feeds_news_ctools_plugin_api() { + list($module, $api) = func_get_args(); + if ($module == "feeds" && $api == "feeds_importer_default") { + return array("version" => 1); + } +} + +/** + * Implementation of hook_node_info(). + */ +function feeds_news_node_info() { + $items = array( + 'feed' => array( + 'name' => t('Feed'), + 'module' => 'node', + 'description' => t('Subscribe to RSS or Atom feeds. Creates nodes of the content type "Feed item" from feed content.'), + 'has_title' => '1', + 'title_label' => t('Title'), + 'has_body' => '1', + 'body_label' => t('Body'), + 'min_word_count' => '0', + 'help' => '', + ), + 'feed_item' => array( + 'name' => t('Feed item'), + 'module' => 'node', + 'description' => t('This content type is being used for automatically aggregated content from feeds.'), + 'has_title' => '1', + 'title_label' => t('Title'), + 'has_body' => '1', + 'body_label' => t('Body'), + 'min_word_count' => '0', + 'help' => '', + ), + ); + return $items; +} + +/** + * Implementation of hook_views_api(). + */ +function feeds_news_views_api() { + return array( + 'api' => '2', + ); +} diff --git a/feeds_news/feeds_news.feeds_importer_default.inc b/feeds_news/feeds_news.feeds_importer_default.inc new file mode 100644 index 00000000..91642ba4 --- /dev/null +++ b/feeds_news/feeds_news.feeds_importer_default.inc @@ -0,0 +1,117 @@ +<?php + +/** + * Implementation of hook_feeds_importer_default(). + */ +function feeds_news_feeds_importer_default() { + $export = array(); + $feeds_importer = new stdClass; + $feeds_importer->disabled = FALSE; /* Edit this to true to make a default feeds_importer disabled initially */ + $feeds_importer->api_version = 1; + $feeds_importer->id = 'feed'; + $feeds_importer->config = array( + 'name' => 'Feed', + 'description' => 'Import RSS or Atom feeds, create nodes from feed items.', + 'fetcher' => array( + 'plugin_key' => 'FeedsHTTPFetcher', + 'config' => array( + 'auto_detect_feeds' => FALSE, + 'use_pubsubhubbub' => FALSE, + 'designated_hub' => '', + ), + ), + 'parser' => array( + 'plugin_key' => 'FeedsSyndicationParser', + 'config' => array(), + ), + 'processor' => array( + 'plugin_key' => 'FeedsNodeProcessor', + 'config' => array( + 'content_type' => 'feed_item', + 'update_existing' => 0, + 'expire' => '-1', + 'mappings' => array( + '0' => array( + 'source' => 'title', + 'target' => 'title', + 'unique' => FALSE, + ), + '1' => array( + 'source' => 'description', + 'target' => 'body', + 'unique' => FALSE, + ), + '2' => array( + 'source' => 'timestamp', + 'target' => 'created', + 'unique' => FALSE, + ), + '3' => array( + 'source' => 'url', + 'target' => 'url', + 'unique' => TRUE, + ), + '4' => array( + 'source' => 'guid', + 'target' => 'guid', + 'unique' => TRUE, + ), + ), + 'input_format' => 0, + 'author' => 0, + ), + ), + 'content_type' => 'feed', + 'update' => 0, + 'import_period' => '1800', + 'expire_period' => 3600, + 'import_on_create' => 1, + ); + + $export['feed'] = $feeds_importer; + $feeds_importer = new stdClass; + $feeds_importer->disabled = FALSE; /* Edit this to true to make a default feeds_importer disabled initially */ + $feeds_importer->api_version = 1; + $feeds_importer->id = 'opml'; + $feeds_importer->config = array( + 'name' => 'OPML import', + 'description' => 'Import subscriptions from OPML files. Use together with "Feed" configuration.', + 'fetcher' => array( + 'plugin_key' => 'FeedsFileFetcher', + 'config' => array( + 'direct' => FALSE, + ), + ), + 'parser' => array( + 'plugin_key' => 'FeedsOPMLParser', + 'config' => array(), + ), + 'processor' => array( + 'plugin_key' => 'FeedsFeedNodeProcessor', + 'config' => array( + 'content_type' => 'feed', + 'update_existing' => 0, + 'mappings' => array( + '0' => array( + 'source' => 'title', + 'target' => 'title', + 'unique' => FALSE, + ), + '1' => array( + 'source' => 'xmlurl', + 'target' => 'source', + 'unique' => 1, + ), + ), + ), + ), + 'content_type' => '', + 'update' => 0, + 'import_period' => '-1', + 'expire_period' => 3600, + 'import_on_create' => 1, + ); + + $export['opml'] = $feeds_importer; + return $export; +} diff --git a/feeds_news/feeds_news.info b/feeds_news/feeds_news.info new file mode 100644 index 00000000..c6f6d7d6 --- /dev/null +++ b/feeds_news/feeds_news.info @@ -0,0 +1,14 @@ +core = "6.x" +dependencies[] = "feeds" +dependencies[] = "views" +description = "A news aggregator built with feeds, creates nodes from imported feed items. With OPML import." +features[ctools][] = "feeds:feeds_importer_default:1" +features[feeds_importer][] = "feed" +features[feeds_importer][] = "opml" +features[node][] = "feed" +features[node][] = "feed_item" +features[views][] = "feeds_defaults_feed_items" +features[views_api][] = "api:2" +name = "Feeds News" +package = "Feeds" +project = "Feeds" diff --git a/feeds_news/feeds_news.module b/feeds_news/feeds_news.module new file mode 100644 index 00000000..5c4fce3e --- /dev/null +++ b/feeds_news/feeds_news.module @@ -0,0 +1,3 @@ +<?php + +include_once('feeds_news.features.inc'); diff --git a/feeds_news/feeds_news.test b/feeds_news/feeds_news.test new file mode 100644 index 00000000..d5e9486d --- /dev/null +++ b/feeds_news/feeds_news.test @@ -0,0 +1,149 @@ +<?php +// $Id$ + +/** + * @file + * Tests for feeds_news feature. + */ + +// Require FeedsWebTestCase class definition. +require_once(dirname(__FILE__) .'/../tests/feeds.test.inc'); + +/** + * Test Feed configuration. + */ +class FeedsExamplesFeedTestCase extends FeedsWebTestCase { + + /** + * Set up test. + */ + public function setUp() { + parent::setUp('feeds', 'feeds_ui', 'ctools', 'features', 'feeds_news'); + + $this->drupalLogin( + $this->drupalCreateUser( + array( + 'administer feeds', 'administer nodes', + ) + ) + ); + } + + /** + * Describe this test. + */ + public function getInfo() { + return array( + 'name' => t('Feature: Feed'), + 'description' => t('Test "Feed" default configuration. <strong>Requires Features.</strong>'), + 'group' => t('Feeds'), + ); + } + + /** + * Run tests. + */ + public function test() { + $nid = $this->createFeedNode('feed', NULL, '', 'feed'); + + // Assert results. + $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'feed_item'")); + $this->assertEqual($count, 10, 'Found the correct number of feed item nodes in database.'); + + $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); + $this->assertEqual($count, 10, 'Found the correct number of records in feeds_node_item.'); + + $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE title = 'Open Atrium Translation Workflow: Two Way Translation Updates'")); + $this->assertEqual($count, 1, 'Found title.'); + $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE title = 'Week in DC Tech: October 5th Edition'")); + $this->assertEqual($count, 1, 'Found title.'); + $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE title = 'Integrating the Siteminder Access System in an Open Atrium-based Intranet'")); + $this->assertEqual($count, 1, 'Found title.'); + $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE title = 'Scaling the Open Atrium UI'")); + $this->assertEqual($count, 1, 'Found title.'); + + $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item} WHERE url = 'http://developmentseed.org/blog/2009/oct/06/open-atrium-translation-workflow-two-way-updating'")); + $this->assertEqual($count, 1, 'Found feed_node_item record.'); + $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item} WHERE url = 'http://developmentseed.org/blog/2009/oct/05/week-dc-tech-october-5th-edition'")); + $this->assertEqual($count, 1, 'Found feed_node_item record.'); + $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item} WHERE guid = '974 at http://developmentseed.org'")); + $this->assertEqual($count, 1, 'Found feed_node_item record.'); + $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item} WHERE guid = '970 at http://developmentseed.org'")); + $this->assertEqual($count, 1, 'Found feed_node_item record.'); + + // Remove all items + $this->drupalPost('node/'. $nid .'/delete-items', array(), 'Delete'); + $this->assertText('Deleted 10 nodes.'); + + // Import again. + $this->drupalPost('node/'. $nid .'/import', array(), 'Import'); + $this->assertText('Created 10 Feed item nodes.'); + + // Delete and assert all items gone. + $this->drupalPost('node/'. $nid .'/delete-items', array(), 'Delete'); + + $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'feed_item'")); + $this->assertEqual($count, 0, 'Found the correct number of feed item nodes in database.'); + + $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); + $this->assertEqual($count, 0, 'Found the correct number of records in feeds_node_item.'); + + // Create a batch of nodes. + $this->createFeedNodes('feed', 10, 'feed'); + $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'feed_item'")); + $this->assertEqual($count, 100, 'Imported 100 nodes.'); + $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); + $this->assertEqual($count, 100, 'Found 100 records in feeds_node_item.'); + } +} + +/** + * Test OPML import configuration. + */ +class FeedsExamplesOPMLTestCase extends FeedsWebTestCase { + + /** + * Set up test. + */ + public function setUp() { + parent::setUp('feeds', 'feeds_ui', 'ctools', 'feeds_news'); + + $this->drupalLogin( + $this->drupalCreateUser( + array( + 'administer feeds', 'administer nodes', + ) + ) + ); + } + + /** + * Describe this test. + */ + public function getInfo() { + return array( + 'name' => t('Feature: OPML import'), + 'description' => t('Test "OPML import" default configuration.'), + 'group' => t('Feeds'), + ); + } + + /** + * Run tests. + */ + public function test() { + + // Import OPML and assert. + $file = $this->generateOPML(); + $this->importFile('opml', $file); + $this->assertText('Created 3 feed nodes.'); + $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_source}")); + $this->assertEqual($count, 4, 'Found correct number of items.'); + + // Import a feed and then delete all items from it. + $this->drupalPost('node/1/import', array(), 'Import'); + $this->assertText('Created 10 Feed item nodes.'); + $this->drupalPost('node/1/delete-items', array(), 'Delete'); + $this->assertText('Deleted 10 nodes.'); + } +} diff --git a/feeds_news/feeds_news.views_default.inc b/feeds_news/feeds_news.views_default.inc new file mode 100644 index 00000000..f74efb7f --- /dev/null +++ b/feeds_news/feeds_news.views_default.inc @@ -0,0 +1,368 @@ +<?php + +/** + * Implementation of hook_views_default_views(). + */ +function feeds_news_views_default_views() { + $views = array(); + + // Exported view: feeds_defaults_feed_items + $view = new view; + $view->name = 'feeds_defaults_feed_items'; + $view->description = 'Show feed items for a feed node. Use together with default importer configuration "Feed".'; + $view->tag = 'Feeds defaults'; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->override_option('relationships', array( + 'feed_nid' => array( + 'label' => 'Owner feed', + 'required' => 1, + 'id' => 'feed_nid', + 'table' => 'feeds_node_item', + 'field' => 'feed_nid', + 'override' => array( + 'button' => 'Override', + ), + 'relationship' => 'none', + ), + )); + $handler->override_option('fields', array( + 'url' => array( + 'label' => '', + 'alter' => array( + 'alter_text' => 0, + 'text' => '', + 'make_link' => 0, + 'path' => '', + 'link_class' => '', + 'alt' => '', + 'prefix' => '', + 'suffix' => '', + 'target' => '', + 'help' => '', + 'trim' => 0, + 'max_length' => '', + 'word_boundary' => 1, + 'ellipsis' => 1, + 'html' => 0, + 'strip_tags' => 0, + ), + 'empty' => '', + 'hide_empty' => 0, + 'empty_zero' => 0, + 'display_as_link' => 1, + 'exclude' => 1, + 'id' => 'url', + 'table' => 'feeds_node_item', + 'field' => 'url', + 'override' => array( + 'button' => 'Override', + ), + 'relationship' => 'none', + ), + 'title' => array( + 'label' => '', + 'alter' => array( + 'alter_text' => 0, + 'text' => '', + 'make_link' => 1, + 'path' => '[url]', + 'link_class' => '', + 'alt' => '', + 'prefix' => '<h2>', + 'suffix' => '</h2>', + 'target' => '', + 'help' => '', + 'trim' => 0, + 'max_length' => '', + 'word_boundary' => 1, + 'ellipsis' => 1, + 'html' => 0, + 'strip_tags' => 0, + ), + 'empty' => '', + 'hide_empty' => 0, + 'empty_zero' => 0, + 'link_to_node' => 0, + 'exclude' => 0, + 'id' => 'title', + 'table' => 'node', + 'field' => 'title', + 'override' => array( + 'button' => 'Override', + ), + 'relationship' => 'none', + ), + 'title_1' => array( + 'label' => '', + 'alter' => array( + 'alter_text' => 0, + 'text' => '', + 'make_link' => 0, + 'path' => '', + 'link_class' => '', + 'alt' => '', + 'prefix' => '', + 'suffix' => '', + 'target' => '', + 'help' => '', + 'trim' => 0, + 'max_length' => '', + 'word_boundary' => 1, + 'ellipsis' => 1, + 'html' => 0, + 'strip_tags' => 0, + ), + 'empty' => '', + 'hide_empty' => 0, + 'empty_zero' => 0, + 'link_to_node' => 1, + 'exclude' => 1, + 'id' => 'title_1', + 'table' => 'node', + 'field' => 'title', + 'override' => array( + 'button' => 'Override', + ), + 'relationship' => 'feed_nid', + ), + 'nothing' => array( + 'label' => '', + 'alter' => array( + 'text' => 'From [title_1]', + 'make_link' => 0, + 'path' => '', + 'link_class' => '', + 'alt' => '', + 'prefix' => '', + 'suffix' => '', + 'target' => '', + 'help' => '', + 'trim' => 0, + 'max_length' => '', + 'word_boundary' => 1, + 'ellipsis' => 1, + 'html' => 0, + 'strip_tags' => 0, + ), + 'empty' => '', + 'hide_empty' => 0, + 'empty_zero' => 0, + 'exclude' => 0, + 'id' => 'nothing', + 'table' => 'views', + 'field' => 'nothing', + 'override' => array( + 'button' => 'Override', + ), + 'relationship' => 'none', + ), + 'body' => array( + 'label' => '', + 'alter' => array( + 'alter_text' => 0, + 'text' => '', + 'make_link' => 0, + 'path' => '', + 'link_class' => '', + 'alt' => '', + 'prefix' => '', + 'suffix' => '', + 'target' => '', + 'help' => '', + 'trim' => 0, + 'max_length' => '', + 'word_boundary' => 1, + 'ellipsis' => 1, + 'html' => 0, + 'strip_tags' => 0, + ), + 'empty' => '', + 'hide_empty' => 0, + 'empty_zero' => 0, + 'exclude' => 0, + 'id' => 'body', + 'table' => 'node_revisions', + 'field' => 'body', + 'override' => array( + 'button' => 'Override', + ), + 'relationship' => 'none', + ), + 'edit_node' => array( + 'label' => '', + 'alter' => array( + 'alter_text' => 0, + 'text' => '', + 'make_link' => 0, + 'path' => '', + 'link_class' => '', + 'alt' => '', + 'prefix' => '', + 'suffix' => '', + 'target' => '', + 'help' => '', + 'trim' => 0, + 'max_length' => '', + 'word_boundary' => 1, + 'ellipsis' => 1, + 'html' => 0, + 'strip_tags' => 0, + ), + 'empty' => '', + 'hide_empty' => 0, + 'empty_zero' => 0, + 'text' => 'Edit', + 'exclude' => 0, + 'id' => 'edit_node', + 'table' => 'node', + 'field' => 'edit_node', + 'override' => array( + 'button' => 'Override', + ), + 'relationship' => 'none', + ), + )); + $handler->override_option('arguments', array( + 'nid' => array( + 'default_action' => 'empty', + 'style_plugin' => 'default_summary', + 'style_options' => array(), + 'wildcard' => 'all', + 'wildcard_substitution' => 'All', + 'title' => 'Articles from %1', + 'breadcrumb' => '', + 'default_argument_type' => 'fixed', + 'default_argument' => '', + 'validate_type' => 'none', + 'validate_fail' => 'not found', + 'break_phrase' => 0, + 'not' => 0, + 'id' => 'nid', + 'table' => 'node', + 'field' => 'nid', + 'validate_user_argument_type' => 'uid', + 'validate_user_roles' => array( + '2' => 0, + ), + 'relationship' => 'feed_nid', + 'default_options_div_prefix' => '', + 'default_argument_fixed' => '', + 'default_argument_user' => 0, + 'default_argument_php' => '', + 'validate_argument_node_type' => array( + 'feed' => 0, + 'feed_item' => 0, + 'story' => 0, + ), + 'validate_argument_node_access' => 0, + 'validate_argument_nid_type' => 'nid', + 'validate_argument_vocabulary' => array(), + 'validate_argument_type' => 'tid', + 'validate_argument_transform' => 0, + 'validate_user_restrict_roles' => 0, + 'validate_argument_php' => '', + 'override' => array( + 'button' => 'Override', + ), + ), + )); + $handler->override_option('filters', array( + 'type' => array( + 'operator' => 'in', + 'value' => array( + 'feed_item' => 'feed_item', + ), + 'group' => '0', + 'exposed' => FALSE, + 'expose' => array( + 'operator' => FALSE, + 'label' => '', + ), + 'id' => 'type', + 'table' => 'node', + 'field' => 'type', + 'override' => array( + 'button' => 'Override', + ), + 'relationship' => 'none', + ), + )); + $handler->override_option('access', array( + 'type' => 'perm', + 'perm' => 'access content', + )); + $handler->override_option('cache', array( + 'type' => 'none', + )); + $handler->override_option('empty', 'There are no items for this feed at the moment.'); + $handler->override_option('empty_format', '1'); + $handler = $view->new_display('page', 'Page', 'page_1'); + $handler->override_option('arguments', array( + 'nid' => array( + 'default_action' => 'empty', + 'style_plugin' => 'default_summary', + 'style_options' => array(), + 'wildcard' => 'all', + 'wildcard_substitution' => 'All', + 'title' => 'All items from %1', + 'breadcrumb' => '', + 'default_argument_type' => 'fixed', + 'default_argument' => '', + 'validate_type' => 'node', + 'validate_fail' => 'not found', + 'break_phrase' => 0, + 'not' => 0, + 'id' => 'nid', + 'table' => 'node', + 'field' => 'nid', + 'validate_user_argument_type' => 'uid', + 'validate_user_roles' => array( + '2' => 0, + ), + 'relationship' => 'feed_nid', + 'default_options_div_prefix' => '', + 'default_argument_fixed' => '', + 'default_argument_user' => 0, + 'default_argument_php' => '', + 'validate_argument_node_type' => array( + 'feed' => 'feed', + 'feed_item' => 0, + 'story' => 0, + ), + 'validate_argument_node_access' => 0, + 'validate_argument_nid_type' => 'nid', + 'validate_argument_vocabulary' => array(), + 'validate_argument_type' => 'tid', + 'validate_argument_transform' => 0, + 'validate_user_restrict_roles' => 0, + 'validate_argument_php' => '', + 'override' => array( + 'button' => 'Use default', + ), + ), + )); + $handler->override_option('path', 'node/%/feed-items'); + $handler->override_option('menu', array( + 'type' => 'tab', + 'title' => 'View items', + 'description' => '', + 'weight' => '0', + 'name' => 'navigation', + )); + $handler->override_option('tab_options', array( + 'type' => 'none', + 'title' => '', + 'description' => '', + 'weight' => 0, + 'name' => 'navigation', + )); + + $views[$view->name] = $view; + + return $views; +} -- GitLab