Views Audit

(Submitted Sun, 2007-12-30 20:52) | |

Owing to a long development period, and several changes of the core development team, we have a lot of leftover Views that are no longer being used. However, with pages upon pages of them and quite a large site, it isn't always immediately apparent which Views are still needed and which aren't.

Here is a very small module I quickly threw together yesterday to track when Views are called/rendered and generate a report at /admin/views_audit. I doubt that there is enough general need for this to put it in contrib, but someone out there might get some use of it.

It should be just as happy running on 4.7 as 5.

Keep in mind that this will add one additional DB query per View access, so it isn't the sort of thing you would want to enable and forget about on a production server. Rather, you'd want to turn it on for about a week or so to collect the data. Myself, I only have it enabled on our development server.

Full tarball with module, install file, and info file is here, module code is pasted below. (The formatting may look a little off because of linewrap and such)

<?php
function views_audit_menu($may_cache) {
  if (
$may_cache) {
   
$items[] = array('path'               => 'admin/views_audit',
                     
'title'              => t('Views Audit'),
                     
'callback'           => 'views_audit_admin_page',
                     
'access'             => user_access('administer views'),
                     
'type'               => MENU_CALLBACK,
               );
  }

  return 
$items;
}

function 
views_audit_views_pre_query($view) {
 
// this function will be called for each view
 
$sql "INSERT INTO {views_audit} (vid, timestamp)
          VALUES (%d, %d)
          ON DUPLICATE KEY UPDATE timestamp = %d;"


 
$result db_query($sql$view->vidtime(), time());
}

function 
views_audit_admin_page() {
 
$output '';

  if (isset(
$_REQUEST['days'])) {
   
$days_stamp $_REQUEST['days'] * 86400;
  }
  else {
   
$days_stamp 0;
  }

 
// 4.7 and 5 have different drupal_get_form behaviour, so compensate
 
if (strncmp(VERSION'5'1) == 0)
   
$output .= drupal_get_form('views_audit_admin_form');
  else
   
$output .= drupal_get_form('views_audit_admin_form'views_audit_admin_form());



 
$header = array(
                   array(
'data'  => t('View ID'),
                         
'field' => 'vid',
                   ),
                   array(
'data'  =>  t('View Name'),
                         
'field' => 'name',
                   ),
                   array(
'data'  =>  t('Last Updated'),
                         
'field' => 'changed',
                   ),
                   array(
'data'  =>  t('Last Accessed'),
                         
'sort'  => 'desc',
                         
'field' => 'timestamp',
                   )
            );

 
$sql "SELECT v.vid, a.timestamp, v.changed, v.name
          FROM {view_view} v
          LEFT OUTER JOIN {views_audit} a
          ON v.vid = a.vid"
;

 
$result db_query($sql tablesort_sql($header));

  while (
$sql_row db_fetch_object($result)) {
    if (empty(
$sql_row->timestamp)) {
     
$timestamp $sql_row->timestamp "no record";
    }
    else {
     
$timestamp format_date($sql_row->timestamp'small') .
                   
' (' round( (time() - $sql_row->timestamp)/86400 ) .
                   
' ' t('days ago') . ')';
    }

   
$updated format_date($sql_row->changed'small') .
               
' (' round( (time() - $sql_row->changed)/86400 ) .
               
' ' t('days ago') . ')';   

 
   
// the Views admin paths are different in 4.7 and 5, so build the appropriate
    // destination path
   
if (strncmp(VERSION'5'1) == 0)
     
$destination 'admin/build/views/' $sql_row->name '/edit';
    else
     
$destination 'admin/views/edit/' $sql_row->vid;

   
$table_row = array($sql_row->vid,
                       
l($sql_row->name$destination),
                       
$updated,
                       
$timestamp,
                 );

    if ( (
$sql_row->timestamp <= time() - $days_stamp) ||
         (
$sql_row->timestamp == 'no record') ) {
     
$rows[] = $table_row;
    }

  }
 
$output .= theme('table'$header$rows);

  return 
$output;
}

function 
views_audit_admin_form() {
 
$form['days'] = array(
   
'#type' => 'select',
   
'#title' => t('Show Views which have not been used in at least the following number of days'),
   
'#default_value' => $_REQUEST['days'],
   
'#options' =>  drupal_map_assoc(array(0123456789101520253060120240365)),
   
'#required' => FALSE,
  );

 
$form['submit'] = array(
   
'#type' => 'submit',
   
'#value' => 'filter',
  );

  return 
$form;
}

function 
views_audit_admin_form_submit($form_id$form_values) {
 
drupal_goto('admin/views_audit''days='.$form_values['days']);
}
?>

Submitted by Benjamin Melançon (not verified) on Sun, 2007-12-30 21:51.

+1 on putting this in contrib! Thanks for sharing in any case.

Submitted by Amitai (not verified) on Mon, 2007-12-31 08:08.

A use case can be for example integration with Workflow-ng as a condition - If View is rendered X do action Y.

Submitted by catch (not verified) on Mon, 2007-12-31 11:28.

Another +1 for me. Even with my three pages worth of views, I still get confused between what's being used and what isn't. Seems like a great candidate for views bonus pack to me if you didn't want to make a new project for it.

Submitted by Moshe Weitzman (not verified) on Thu, 2008-01-24 21:59.

With permission, I cleaned this up and contributed it on drupal.org. see http://drupal.org/project/views_audit. please use the issue queue there.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote>
  • Lines and paragraphs break automatically.
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.
More information about formatting options

Hosted By Dreamhost.com


Did you know?

You don't need to register at WWDD to post comments.

Isn't it annoying when you want to comment on an article, but don't want to go through the hassle of creating yet-another-user account at yet-another-website?

Feel free to comment anonymously, or log in with your username@drupal.org account.

We won't mind a bit.