Hello,

I'm using custom tables and implemented hook_views_data() in my module.
I have a table 'items' :

  $schema['items'] = array(
    'fields' => array(
      'id' => array(
	    'type' => 'serial',
		'unsigned' => TRUE,
		'not null' => TRUE,
	  ),
      'label' => array(
	    'type' => 'varchar',
	    'length' => '255',
		'not null' => TRUE,
	  ),
    ),
    'primary key' => array('id'),
  );

Users can be linked to many items through this table :

  $schema['user_items'] = array(
    'fields' => array(
      'uid' => array(
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'item_id' => array(
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE
      ),
    ),
  );
  //Looks like i forgot primary key which should be combination of uid/item_id.

So i guess this is a many-to-many relationship.

Here's what i have in hook_views_data() for the user_items table :

  $data['user_items']['table']['group'] = t('Items');

  $data['user_items']['table']['base'] = array(
    'field' => 'uid',
    'title' => t('User id'),
    'help' => t('User id')
  );

  $data['user_items']['table']['join'] = array(
    'users' => array('left_field' => 'uid', 'field' => 'uid'),
    'items' => array('left_field' => 'id', 'field' => 'item_id'),
  );

  $data['user_items']['item_id'] = array(
    'title' => t("User's items"),
    'help' => t("Items that belong to a user."),
    'field' => array('handler' => 'views_handler_field', 'click sortable' => TRUE),
    'filter' => array('handler' => 'views_handler_filter_numeric'),
    'argument' => array('handler' => 'views_handler_argument_numeric'),
    'sort' => array('handler' => 'views_handler_sort'),
    'relationship' => array(
      'label' => t('Item'),
      'title' => t('Item'),
      'help' => t("Item's relationship"),
      'base' => 'items',
      'base field' => 'id',
      'skip base' => array('items'),
    )
  );

The problem is, when outputing a view, results are duplicated for each item.
Let's say a user has 3 items, then the view shows 3 rows with the same user, with each row showing one item.

I'd like to "group" multiple values, as CCK does.

How can i do this?

Thanks!

Comments

dawehner’s picture

Issue tags: -handler, -Custom table

Before adding tags read the issue tag guidelines. Do NOT use tags for adding random keywords or duplicating any other fields. Separate terms with a comma, not a space.

Hey wow, this is an actual api question.

Okay what you want to do is to write a custom handler which doesn't add the field to the sql query but loads it in an additional query.
As an example see modules/upload/views_handler_field_upload_fid.inc

The important functions you should have a look at is:


  function pre_render($values) {

There you load each item into $this->items.

Additional

extends views_handler_field_prerender_list {

is important.

Do you think with this informations you can fix the issue?

ludo.r’s picture

Ok, sorry for the tags.

I did try this solution :
- set a custom handler for cluster_id field :

  $data['user_items']['item_id'] = array(
    'title' => t("User's items"),
    'help' => t("Items that belong to a user."),
    'field' => array('handler' => "mymodule_handler_field_item", 'click sortable' => TRUE),
    'filter' => array('handler' => 'views_handler_filter_numeric'),
    'argument' => array('handler' => 'views_handler_argument_numeric'),
    'sort' => array('handler' => 'views_handler_sort'),
    'relationship' => array(
      'label' => t('Item'),
      'title' => t('Item'),
      'help' => t("Item's relationship"),
      'base' => 'items',
      'base field' => 'id',
      'skip base' => array('items'),
    )
  );

The handler class

class mymodule_handler_field_item extends views_handler_field_prerender_list {
  function construct() {
    parent::construct();
  }

  function option_definition() {
    $options = parent::option_definition();
    return $options;
  }

  function options_form(&$form, &$form_state) {
    parent::options_form($form, $form_state);
  }

  function pre_render($values) {
    $ids = array();
    $this->items = array();

    foreach ($values as $result) {
      $ids[] = $result->{$this->field_alias};
    }
    if ($ids) {
      $result = db_query("SELECT id, label FROM {items} WHERE id IN (" . implode(', ', $ids) . ")");
      while ($row = db_fetch_object($result)) {
        $this->items[$row->id][$row->id] = $row->label;
      }
      drupal_set_message(print_r($this->items, TRUE));
    }
  }

//  function render_item($count, $item) {
//    return $item['description'];
//  }
}

Do i need the render_item() function?

Now when using this handler, i get a Display type option with choices : Unordered list, Ordered list, Simple separator

But the view still outputs multiple rows.

What am i missing?

Thank you for your help, this is much appreciated!

ludo.r’s picture

Maybe i should put the handler (extends views_handler_field_prerender_list) on the label field of the items table?

  $data['user_items']['table']['group'] = t('Items');

  $data['user_items']['table']['base'] = array(
    'field' => 'uid',
    'title' => t('User id'),
    'help' => t('User id')
  );

  $data['user_items']['table']['join'] = array(
    'users' => array('left_field' => 'uid', 'field' => 'uid'),
    'items' => array('left_field' => 'id', 'field' => 'item_id'),
  );

  $data['user_items']['item_id'] = array(
    'title' => t("User's items"),
    'help' => t("Items that belong to a user."),
    'field' => array('handler' => 'views_handler_field', 'click sortable' => TRUE),
    'filter' => array('handler' => 'views_handler_filter_numeric'),
    'argument' => array('handler' => 'views_handler_argument_numeric'),
    'sort' => array('handler' => 'views_handler_sort'),
    'relationship' => array(
      'label' => t('Item'),
      'title' => t('Item'),
      'help' => t("Item's relationship"),
      'base' => 'items',
      'base field' => 'id',
      'skip base' => array('items'),
    )
  );
  
  //Handler class here
  $data['items']['label'] = array(
    'field' => array('handler' => 'mymodule_handler_field_item', 'click sortable' => TRUE),
  );

Can anyone help?

fourmi4x’s picture

I would like to do exactly the same thing, did you manage to do it?

ludo.r’s picture

I am still looking for a solution, but i didnt have time to go further for now.
I hope to work on it next week.

robynover’s picture

I have the same problem. I'm confused about pre_render and the like. Does anyone have more information on this issue?

ludo.r’s picture

No unfortunately I did not find a solution, and didn't have more time to spend on this issue (which was a minor one on this project).

kars-t’s picture

Status: Active » Closed (won't fix)

Dear fellow Drupal enthusiasts,

This issue is now lasting for a very long time in the issue queue and was unfortunately never solved. As Drupal is a open source project, everyone is helping on a voluntary basis. That this was not solved is nothing personal and means no harm. But perhaps no one had time to deal with this issue, maybe it is too complex, or the problem was not described comprehensibly.

But this issue is not the only one. There are thousands of issues on Drupal.org that have never been worked on or could not be processed. This means that we are building a wave that is unmanageable and it is a problem for the Drupal project as a whole. Please help us keep the issue queue smaller and more manageable.

Please read again, "Making an issue report" and see if you can improve the issue. Test the problem with the current Core and modules. Maybe the problem doesn't exist anymore, is a duplicate or has even been solved within this issue but never closed.

Help can also be found for it on IRC and in the user groups.

In order to close this issue, I have set this issue to "Closed (won't fix)".

If there is new information, please re-open the issue by changing the status to active.

--
This issue was edited with the help of Issue Helper