View:

Hi. I had the task to create a View, that shows feeds from a specific category, but from different sources. However it turned out that views uses wrong tables during the join. As an result at least one feed source was missing.

I made some changes to the views modules, and it seams to work find for me, so far. So here are my changes. Hopefully these changed will made their way to the code, that we may update without the hase of changing code every time.

Here is an export of my View (after the change).

$view = new view;
$view->name = 'news_view';
$view->description = 'News View';
$view->tag = '';
$view->view_php = '';
$view->base_table = 'aggregator_item';
$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', 'Standards', 'default');
$handler->override_option('fields', array(
  'title' => array(
    'label' => '',
    'alter' => array(
      'alter_text' => 1,
      'text' => '<h1>[title]</h1>',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'strip_tags' => 0,
      'html' => 0,
    ),
    'display_as_link' => 1,
    'exclude' => 0,
    'id' => 'title',
    'table' => 'aggregator_item',
    'field' => 'title',
    'relationship' => 'none',
  ),
  'author' => array(
    'label' => 'Autor',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'strip_tags' => 0,
      'html' => 0,
    ),
    'exclude' => 0,
    'id' => 'author',
    'table' => 'aggregator_item',
    'field' => 'author',
    'relationship' => 'none',
  ),
  'timestamp' => array(
    'label' => 'Zeitstempel',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'strip_tags' => 0,
      'html' => 0,
    ),
    'date_format' => 'small',
    'custom_date_format' => '',
    'exclude' => 0,
    'id' => 'timestamp',
    'table' => 'aggregator_item',
    'field' => 'timestamp',
    'relationship' => 'none',
  ),
  'link' => array(
    'label' => '',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'strip_tags' => 0,
      'html' => 0,
    ),
    'display_as_link' => 1,
    'exclude' => 1,
    'id' => 'link',
    'table' => 'aggregator_item',
    'field' => 'link',
    'relationship' => 'none',
  ),
  'description' => array(
    'label' => '',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'help' => '',
      'trim' => 1,
      'max_length' => '200',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'strip_tags' => 0,
      'html' => 1,
    ),
    'exclude' => 0,
    'id' => 'description',
    'table' => 'aggregator_item',
    'field' => 'description',
    'relationship' => 'none',
  ),
));
$handler->override_option('sorts', array(
  'timestamp' => array(
    'order' => 'DESC',
    'granularity' => 'second',
    'id' => 'timestamp',
    'table' => 'aggregator_item',
    'field' => 'timestamp',
    'relationship' => 'none',
  ),
));
$handler->override_option('filters', array(
  'cid' => array(
    'operator' => 'in',
    'value' => array(
      '1' => '1',
    ),
    'group' => '0',
    'exposed' => FALSE,
    'expose' => array(
      'operator' => FALSE,
      'label' => '',
    ),
    'id' => 'cid',
    'table' => 'aggregator_category',
    'field' => 'cid',
    'relationship' => 'none',
  ),
));
$handler->override_option('access', array(
  'type' => 'none',
));
$handler->override_option('cache', array(
  'type' => 'none',
));
$handler->override_option('items_per_page', 100);
$handler->override_option('distinct', 0);
$handler = $view->new_display('page', 'Seite', 'page_1');
$handler->override_option('path', 'news');
$handler->override_option('menu', array(
  'type' => 'none',
  'title' => '',
  'description' => '',
  'weight' => 0,
  'name' => 'navigation',
));
$handler->override_option('tab_options', array(
  'type' => 'none',
  'title' => '',
  'description' => '',
  'weight' => 0,
));

This is the query created by the views module before the changes.

SELECT aggregator_item.iid AS iid, aggregator_item.title AS aggregator_item_title, aggregator_item.link AS aggregator_item_link, aggregator_item.author AS aggregator_item_author, aggregator_item.timestamp AS aggregator_item_timestamp, aggregator_item.description AS aggregator_item_description FROM aggregator_item aggregator_item  LEFT JOIN aggregator_category_feed aggregator_category_feed ON aggregator_item.fid = aggregator_category_feed.fid LEFT JOIN aggregator_category aggregator_category ON aggregator_category_feed.cid = aggregator_category.cid WHERE aggregator_category.cid in ('1') ORDER BY aggregator_item_timestamp DESC

This is a svn diff containing my source code changes. I hope this fixes the problem, while introducing litte or no side effects.

--- htdocs/sites/all/modules/third_party/views/modules/aggregator.views.inc    (Revision 106)
+++ htdocs/sites/all/modules/third_party/views/modules/aggregator.views.inc    (Arbeitskopie)
@@ -272,13 +272,23 @@
   );

   // ----------------------------------------------------------------------
+  // Aggregator category item table
+
+  $data['aggregator_category_item']['table']['join'] = array(
+    'aggregator_item' => array(
+      'left_field' => 'iid',
+      'field' => 'iid',
+    ),
+  );
+
+  // ----------------------------------------------------------------------
   // Aggregator category table

   $data['aggregator_category']['table']['group'] = t('Aggregator category');

   $data['aggregator_category']['table']['join'] = array(
     'aggregator_item' => array(
-      'left_table' => 'aggregator_category_feed',
+      'left_table' => 'aggregator_category_item',
       'left_field' => 'cid',
       'field' => 'cid',
     ),

This is the query created by the views module after the changes.

SELECT aggregator_item.iid AS iid, aggregator_item.title AS aggregator_item_title, aggregator_item.link AS aggregator_item_link, aggregator_item.author AS aggregator_item_author, aggregator_item.timestamp AS aggregator_item_timestamp, aggregator_item.description AS aggregator_item_description FROM aggregator_item aggregator_item  LEFT JOIN aggregator_category_item aggregator_category_item ON aggregator_item.iid = aggregator_category_item.iid LEFT JOIN aggregator_category aggregator_category ON aggregator_category_item.cid = aggregator_category.cid WHERE aggregator_category.cid in ('1') ORDER BY aggregator_item_timestamp DESC
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dawehner’s picture

Version: 6.x-3.x-dev » 6.x-2.x-dev

Thats also a bug in 2.x, so first fix it there.

There is currently no clean way to display only feeds, not the items, because its not a base table.

From just reading code, your code seams to be more logical, but on my local system i cannot reproduce a bug. Can you try to find out to reproduce it?

esmerel’s picture

Status: Active » Postponed (maintainer needs more info)
esmerel’s picture

Status: Postponed (maintainer needs more info) » Closed (won't fix)

No update for more than 30 days.,

Odd Hill’s picture

Version: 6.x-2.x-dev » 6.x-2.11
Status: Closed (won't fix) » Needs review
FileSize
912 bytes

I wanted to select feed items based on category, and ran into this problem as well.

Made the same changes as suggested above, and it works like intended.

merlinofchaos’s picture

Status: Needs review » Needs work

The problem is that both the patch and the original code here are correct. Unfortunately they can't both exist simultaneously without relationships, which would add significant complexity to the design.

In aggregator, both feeds and aggregator items can have categories, and they both pull from the same category pool. That means that technically, there are two different paths you can use to associate an aggregator category to an aggregator item. You can associate a category directly to an item, through the use of the aggregator_item_category table, like so:

aggregator_category -> aggregator_item_category -> aggregator_item

Or you can associate a category to all items within all feeds with the category:

aggregator_category -> aggregator_feed_category -> aggregator_feed -> aggregator_item

Because aggregator_item, aggregator_feed and aggregator_feed_category all contain fid, you can skip aggregator_feed.

Whoever implemented the Views integration for aggregator assumed that people would more likely want categories related to feeds than categories related to individual items. This may or may not be the case. However, this code has been out there a long time, and applying this patch will change the behavior of sites that want it this way.

That means that the only acceptable solution is going to be to add a relationship from aggregator_item to aggregator_category so that you can use that in place of the implicit relationship Views provides, because we do not want to change behavior out from under existing users.

iamjon’s picture

iamjon’s picture

Assigned: Unassigned » dawehner

Assigning to dereine for review

martysteer’s picture

I realise this is an old issue, but the current D7.15 aggregator still has the join on feed behaviour. Instead of patching the views module, I just altered it in my own module:

function MYMODULE_views_data_alter(&$data) {
	if (module_exists('aggregator')) {
		$data['aggregator_category_item']['table']['join'] = array(
			'aggregator_item' => array(
				'left_field' => 'iid',
				'field' => 'iid',
			),
		);	
		
		// Alter the way aggregator categories join - to join using the item data above.
		$data['aggregator_category']['table']['join']['aggregator_item']['left_table'] ='aggregator_category_item';	
	}
}
Kimitri’s picture

Yup, just ran into the same exact issue in 7.12. I decided it was better to make Views aware of the aggregator_categroy_item table and let the user decide how the feed items should be categorized:

function MYMODULE_views_data_alter(&$data){
	if (module_exists('aggregator')) {
		$data['aggregator_category_item']['table']['group'] = t('Aggregator categories in feed items');
		
		$data['aggregator_category_item']['table']['join']['aggregator_item'] = array(
			'left_field' => 'iid',
			'field' => 'iid'
		);
		
		$data['aggregator_category_item']['cid'] = $data['aggregator_category']['cid'];
	}
}
pjmcghee’s picture

Hi Kimitri,

What file in the Views module did you place this code? i really need to be able to filter on my aggregator categories in views and this solution would really be welcome if I could get a bit more info about where and how to place it.

Thanks!

Never mind, I figured it out. Put the ole big kid pants on. the patch from merlin works as advised. very good.

Chris Matthews’s picture

Status: Needs work » Closed (outdated)

The Drupal 6 branch is no longer supported, please check with the D6LTS project if you need further support. For more information as to why this issue was closed, please see issue #3030347: Plan to clean process issue queue