Adding a custom filter to views in Drupal 7

Per picture Per · Sep 8, 2011 · Viewed 12.1k times · Source

im using Drupal 7 and I want to add a new filter in views.

I have a custom table "clicks" with two fields; nid and clicks_left.

The filter should just contain a checkbox "Only display nodes with clicks left". So the filter should join node and clicks on nid..

I have read like thousands of pages of custom filters but can't get it to work =)

Please, could someone show me a working example so I understand?

I have come so far that the filter is displayed under filters but what do I need to add to do the join and get the checkbox? The relevant code below:

FILE clicks_views.inc:

function clicks_views_data() {
  $data = array();

  $data['clicks']['clicks_filter'] = array(
    'group' => t('Clicks'),
    'title' => t('Clicks left'),
    'help' => t('Filter any Views based on clicks left'),
    'filter' => array(
  'field' => 'clicks_left',
      'handler' => 'clicks_handler_filter',
    ),
  ); 

return $data;
}

FILE clicks_handler_filter.inc:

<?php
  class clicks_handler_filter extends views_handler_filter {

    ???

};

I know both functions are wrong ;)

Answer

Per picture Per · Sep 12, 2011

Ok, I've found a solution. For anyone who needs it:

In clicks.module

function clicks_views_api() {
  return array(
    'api' => 2,
    'path' => drupal_get_path('module', 'clicks') . '/includes'
  );
}

In clicks.views.inc

function clicks_views_handlers() {
  return array(
    'info' => array(
      'path' => drupal_get_path('module', 'clicks') . '/includes', // path to view files
    ),
    'handlers' => array(
      // register our custom filter, with the class/file name and parent class
      'clicks_handler_filter' => array(
        'parent' => 'views_handler_filter',
      )
    ),
);
}

function clicks_views_data() {
  $data = array();

  if(module_exists('clicks')) {
    $data['node']['clicks'] = array(
      'group' => t('Clicks'),
      'title' => t('Clicks left'),
      'help' => t('Filter any Views based on clicks left'),
      'filter' => array(
        'handler' => 'clicks_handler_filter',
      ),
    );
  }
  return $data;
}

In clicks_handler_filter.inc

class clicks_handler_filter extends views_handler_filter {

  function admin_summary() { }
  function operator_form() { }
  function query() {
    $table = $this->ensure_my_table();
    $join = new views_join();
    $join->construct('clicks', $this->table_alias, 'nid', 'nid');
    $this->query->ensure_table('clicks', $this->relationship, $join);
    $this->query->add_where($this->options['group'], "clicks.clicks_left", 0, ">");
 }

}

This gives me a possibility to add a filter "clicks" that if enabled hides all results that doesn't have clicks left (clicks_left > 0)