Last updated August 31, 2012. Created on August 31, 2012.
Edited by NancyDru. Log in to edit this page.

I recently was tasked with creating a report of how many people signed up for the site by date. The query was simple, but creating the file was a bit of a challenge.

<?php
/**
 * User sign up report, output as a CSV.
 */
function mymodule_signups_csv() {
 
// Prevent Devel from messing us up.
 
$GLOBALS['devel_shutdown'] = TRUE;
 
 
// Set the headers to indicate this is a CSV file.
 
header('Content-type: text/csv; charset=UTF-8');
 
header('Content-Disposition: attachment; filename=user_signups.csv');
 
header('Pragma: no-cache');
 
header('Expires: 0');

 
// Create a file.
 
$output = fopen('php://output', 'w');

 
// Column names.
 
fputcsv ($output, array('Date', 'Count'));

 
$query = "SELECT DATE(FROM_UNIXTIME(created)) AS joined, COUNT(*) AS number FROM {users} "
   
. "WHERE status = 1 "
   
. "GROUP BY DATE(FROM_UNIXTIME(created)) "
   
. "ORDER BY created DESC ";
 
$result = db_query($query);

 
// Loop through the rows.
 
foreach ($result as $row) {
   
fputcsv($output, (array) $row);
  }

 
fclose($output);
}
?>

To get to this code was just a matter of creating a MENU_CALLBACK and adding a link to an existing page.

Note the 3rd line. Devel outputs its stuff after the </html> tag, so Excel saw that as data. That simple statement just turns Devel off for this single page load.

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

leenyx’s picture

Hi, this looks very helpful but please can you explain how to get to this code? Can you give us an example of the MENU_CALLBACK and the link to the existing page?

Thanks!

Making the Internet a better place.

Jose Blas, UX Consultant

NancyDru’s picture

<?php
function mymodule_reporting_permission() {
  return array(
   
'access mymodule reports' => array(
     
'title' => t('Access reporting section'),
     
'description' => t('View reports on mymodule activity.'),
      ),
    );
}

function
mymodule_reporting_menu() {
 
$items = array();

 
$items['mymodule-reporting/signups_csv'] = array(
   
'page callback' => 'mymodule_reporting_signups_csv',
   
'access arguments' => array('access mymodule reports'),
   
'type' => MENU_CALLBACK,
    );

  return
$items;
}
/**
 * Downloadable reports.
 */
function mymodule_reporting_downloads() {
 
$output = '<div id="mymodule-reporting">';
 
$output .= '<div id="mymodule-reporting-downloads"><br />';
 
$links = array();

 
// Add a link to download sign up stats.
 
$links['signup-download'] = array(
   
'title' => t('Download registration statistics'),
   
'href' => 'mymodule-reporting/signups_csv',
    );

 
$output .= theme('links', array('links' => $links));

 
$output .= '</div>  <!-- /mymodule-reporting-downloads -->';
 
$output .= '</div>  <!-- /mymodule-reporting -->';
  return
$output;
}
?>

There is, of course, a lot of other stuff missing from our actual implementation.