2

A module I've written implements hooks defined by the Field API to provide a custom field for defining references to specific node revisions by storing vids. (The module borrows functionality from the Entity Reference, Node Reference and Node Revision Reference modules.)

I have a requirement for "parent" nodes to reference a specific version of one or more "child" nodes. The child node(s) may be modified (i.e. new revisions created) after a reference to it is stored against a parent node. It's essential that the reference on the parent node continues to refer to the same revision of the child node unless the reference is manually updated to a newer revision by a user with sufficient permissions.

I'm currently working on Views integration for the field defined by my module. When creating displays containing one or more parent nodes, I'd also like to be able to display field data for any referenced revisions of child nodes. I've defined the following relationship in my module:

/**
 * Implements hook_field_views_data().
 */
function mymodule_field_views_data($field) {
  $data = field_views_field_default_views_data($field);

  // Get database table info for $field.
  $storage = $field['storage']['details']['sql'];

  foreach ($storage as $table_data) {
    $table = key($table_data);
    $columns = current($table_data);
    $id_column = $columns['vid'];

    if (isset($data[$table])) {
      // Relationship: node revision referenced from $field.
      $data[$table][$id_column]['relationship'] = array(
        'title' => t('Referenced node revision'),
        'label' => t('Node revision referenced from !field_name', array(
          '!field_name' => $field['field_name'],
        )),
        'help' => t('A bridge to the node revision that is referenced via !field_name.', array(
          '!field_name' => $field['field_name'],
        )),
        'group' => t('Node revision reference'),
        'handler' => 'views_handler_relationship',
        'base' => 'node',
        'base field' => 'vid',
      );
    }
  }

  return $data;
}

This relationship allows me to display field content for child nodes where the referenced revision is the current revision. However, if an old revision is being referenced by a parent node, the field data is empty. This behaviour occurs when I create a view displaying either content or content revisions.

Does anyone know of a way of accessing field data for a specific node revision via a relationship in Views regardless of whether it's the current revision or not?

Thanks in advance to anyone who can offer any suggestions!

0

One thing you could try is creating a class that extends views_handler_relationship and override it's query() method using logic that's specific to your use case rather than the generalised logic that's in views_handler_relationship->query(). Then change the "handler" in your relationship declaration to point at your subclass.

Hope it helps.

  • Thanks, Paul! Fancy seeing you here! I think extending views_handler_relationship is the way to go, and I'd already started creating a class before I posted the question above. I still feel like I'm missing something obvious in Views that'll give me what I'm after, but perhaps not... It seems as though Drupal handles revisions in a bit of an unusual way, so perhaps what I'm experiencing is a symptom of that. – Matt Elkins Aug 12 '15 at 8:57
  • Yep, it's a crazy old world alright! I've just been looking at the code of some of some of the moderation modules (like workbench moderation) to see if I can see a silver bullet for this. No luck so far. One thing though, could we be over-thinking it... do you think a simpler approach using a view of revisions manipulated with hook_views_query_alter to pick out the correct revision could be the way to go? – Paul Querol Aug 12 '15 at 10:02
  • I think altering the query one way or the other will need to be done, as Views simply isn't including the necessary tables in the query its generating for some reason. Extending views_handler_relationship to alter the query feels a bit "cleaner" to me, so that could still be the way to go. I've parked this feature for the time being, but I'll be coming back to it soon... – Matt Elkins Aug 19 '15 at 15:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.