Event View does not work with Views API 6

rmetcalf9 - August 23, 2009 - 13:27
Project:Event Views
Version:6.x-2.x-dev
Component:Code
Category:bug report
Priority:critical
Assigned:Unassigned
Status:active
Description

Hi,
I have spent about 6 hours yesterday working through getting Event Start Date into a view in drupal 6.13 and I would like to share my experences.

The Views 2.x API is here: http://views.doc.logrus.com/
This lists all the hooks and it is clear from this that hook_views_data must be implemented to add fields, etc. to the views module.

I have downloaded the event views module (6.x-2.x-dev) and this does not implement this hook. Instead it implements a hook called hook_views_tables which dosn't even exist in version 2.x API. My guess is that it is still written for a previous version of the views API. Despite this it reports itself as a drupal 6 module. Since drupal 6 must use views 2.x API it's basically faking it and I don't see how it has ever worked.

My solution for this is something that worked for me and people can use it as a start. (Although not a professional quality fix)

Important things to note if you are following this to do a views 2.x API

  • Some views hooks are in the module file, other views hooks are in special inc files. Watch which goes where
  • You must include hook_views_api () in your module file
  • You have to use the right file names for the inc file
  • You must goto Adminster -> Site Building -> Views -> Tools and press the Clear Views Cache button to see any of this

I devloped a site custom module called xxx_custom and created the following directory:
/sites/all/modules/xxx_custom

Create a file called xxx_custom.info and fill in the following

; $Id$
name = xxx_custom
description = Custom module for GKR15 Website
version = "0.0.0.2"

core = "6.x"

Create a file called xxx_custom.module and fill in the following
<?PHP
/**
* Implementation of hook_views_api().
*/
function xxx_custom_views_api() {
  return array(
'api' => 2,
  );
}

Create a file called xxx_custom.views.inc and fill it with:

<?PHP
/**
*  Implementation of hook_views_data().
*  Expose event fields and filters to the views module.
*/
function xxx_custom_views_data() {
   $data['event']['table']['group'] = t('Event (RJM)');

   $data['event']['table']['join'] = array(
     'node' => array(
       'left_field' => 'nid',
       'field' => 'nid',
     ),
);


   // Node ID field.
   $data['event']['nid'] = array(
     'title' => t('Event Data'),
     'help' => t('Event data linked to the node'),
     'relationship' => array(
       'base' => 'node',
       'field' => 'nid',
       'handler' => 'views_handler_relationship',
       'label' => t('Event Node'),
     ),
   );

   // Example numeric text field.
   $data['event']['timezone'] = array(
     'title' => t('timezone'),
     'help' => t('Just a numeric field.'),
     'field' => array(
       'handler' => 'views_handler_field_numeric',
       'click sortable' => TRUE,
      ),
     'filter' => array(
       'handler' => 'views_handler_filter_numeric',
     ),
     'sort' => array(
       'handler' => 'views_handler_sort',
     ),
   );

   // Example timestamp field.
   $data['event']['event_start'] = array(
     'title' => t('Event Start'),
     'help' => t('Event Start Date and Time'),
     'field' => array(
       'handler' => 'views_handler_field_rjm_date',
       'click sortable' => TRUE,
     ),
     'sort' => array(
       'handler' => 'views_handler_sort_date',
     ),
     'filter' => array(
       'handler' => 'views_handler_filter_date',
     ),
   );
   return $data;
}

?>

Finally create a file called views_handler_field_rjm_date.inc and fill it with:
<?PHP

class views_handler_field_rjm_date extends views_handler_field_date {
  function render($values) {
    $value = $values->{$this->field_alias};
    $format = $this->options['date_format'];
    if (in_array($format, array('custom', 'raw time ago', 'time ago', 'raw time span', 'time span'))) {
      $custom_format = $this->options['custom_date_format'];
    }

//our format 2008-03-30 10:00:00
$old_value = $value;

//$value = date("Y-m-d H:i:s",$old_value);
$hr = (int) substr($old_value,11,2);
$min = (int) substr($old_value,14,2);
$sec = (int) substr($old_value,17,2);

$day = (int) substr($old_value,8,2);
$mon = (int) substr($old_value,5,2);
$year = (int) substr($old_value,0,4);

$value = mktime($hr,$min,$sec,$mon,$day,$year, -1);

//$custom_format = "Y-m-d H:i:s";

    if (!$value) {
      return theme('views_nodate');
    } else {
      $time_diff = time() - $value; // will be positive for a datetime in the past (ago), and negative for a datetime in the future (hence)
      switch ($format) {
        case 'raw time ago':
          return format_interval($time_diff, is_numeric($custom_format) ? $custom_format : 2);
        case 'time ago':
          return t('%time ago', array('%time' => format_interval($time_diff, is_numeric($custom_format) ? $custom_format : 2)));
        case 'raw time span':
          return ($time_diff < 0 ? '-' : '') . format_interval(abs($time_diff), is_numeric($custom_format) ? $custom_format : 2);
        case 'time span':
          return t(($time_diff < 0 ? '%time hence' : '%time ago'), array('%time' => format_interval(abs($time_diff), is_numeric($custom_format) ? $custom_format : 2)));
        case 'custom':
          return date($custom_format, $value); //format_date($value, $format, $custom_format);
        default:
          return date($format, $value);
      }
    }
  }
}

?>

Now goto Adminster -> Site Building -> Views -> Tools and press the Clear Views Cache. When you create a view you will now see the event start field. You should use this with a custom format and put in a PHP style format string to view the date.

As you can see I have used the API documentation example to produce the result. When this worked I found that the default date handler didn't work. I have had to create my own but I don't understand how Drupal handles dates so I have written the code in a way that works for me, but I think there is a proper way to do it which isn't this way!

Hopefully this post will stop others having to spend 6 hours figuring this out.

#1

rmetcalf9 - August 23, 2009 - 14:11

Two things I forgot to mention
Firstly, this won't work until you activate the custom module.
The second thing is I have only put in the event start date code because that was all I needed.
To get event end date you need to adjsut xxx_custom.views.inc
and add something like

   // Example timestamp field.
   $data['event']['event_end'] = array(
     'title' => t('Event End'),
     'help' => t('Event End Date and Time'),
     'field' => array(
       'handler' => 'views_handler_field_rjm_date',
       'click sortable' => TRUE,
     ),
     'sort' => array(
       'handler' => 'views_handler_sort_date',
     ),
     'filter' => array(
       'handler' => 'views_handler_filter_date',
     ),

This is untested
Add this after where the event start code is. (It's just copied and pasted) Don't forget to clear the views cache or you won't see it.

I don't know if there are other event fields that could be added because I don't use the events module (doing this to help out a friend on his site.)
You should add these by looking at the example code in views 2.0 api for the spercific type and putting it into xxx_custom.views.inc

#4

dark_religion - November 14, 2009 - 08:26

Thank you)))

#5

savedario - November 22, 2009 - 16:00

When I use the above i get:

Error: handler for event > event_start doesn't exist!

After I try to add the start date field in my view.

Aren't handlers supposed to be declared ?
(Asks the newbie)

 
 

Drupal is a registered trademark of Dries Buytaert.