| 1 |
<?php
|
| 2 |
// $Id: graphstat.module,v 1.0 2007/06/18 17:04:10 profix898 Exp $
|
| 3 |
|
| 4 |
require_once (drupal_get_path('module', 'graphstat') .'/graphstat_statistics.inc');
|
| 5 |
|
| 6 |
/**
|
| 7 |
* Implementation of hook_perm().
|
| 8 |
*/
|
| 9 |
function graphstat_perm() {
|
| 10 |
return array('access graphs');
|
| 11 |
}
|
| 12 |
|
| 13 |
/**
|
| 14 |
* Implementation of hook_theme().
|
| 15 |
*/
|
| 16 |
function graphstat_theme() {
|
| 17 |
return array(
|
| 18 |
'graphstat_filter_form' => array(
|
| 19 |
'arguments' => array('form' => NULL),
|
| 20 |
),
|
| 21 |
'graphstat_graph' => array(
|
| 22 |
'arguments' => array('url' => NULL, 'title' => '', 'description' => '', 'attributes' => array()),
|
| 23 |
)
|
| 24 |
);
|
| 25 |
}
|
| 26 |
|
| 27 |
/**
|
| 28 |
* Implementation of hook_init().
|
| 29 |
*/
|
| 30 |
function graphstat_init() {
|
| 31 |
drupal_add_css(drupal_get_path('module', 'graphstat') .'/graphstat.css');
|
| 32 |
}
|
| 33 |
|
| 34 |
/**
|
| 35 |
* Implementation of hook_menu().
|
| 36 |
*/
|
| 37 |
function graphstat_menu() {
|
| 38 |
$items = array();
|
| 39 |
$items['admin/reports/graphs'] = array(
|
| 40 |
'title' => 'Graphs',
|
| 41 |
'description' => 'Displays graphs based on site statistics.',
|
| 42 |
'access callback' => 'user_access',
|
| 43 |
'access arguments' => array('access graphs'),
|
| 44 |
'page callback' => 'graphstat_graphs',
|
| 45 |
'page arguments' => array('history'),
|
| 46 |
'weight' => 11
|
| 47 |
);
|
| 48 |
$graphs = module_invoke_all('graphstat');
|
| 49 |
foreach ($graphs as $group => $graph) {
|
| 50 |
$items['admin/reports/graphs/'. strtr($group, ' ', '_')] = array(
|
| 51 |
'title' => check_plain(isset($graph['title']) ? $graph['title'] : drupal_ucfirst($group)),
|
| 52 |
'access callback' => 'user_access',
|
| 53 |
'access arguments' => array('access graphs'),
|
| 54 |
'page callback' => 'graphstat_graphs',
|
| 55 |
'page arguments' => array($group),
|
| 56 |
'type' => ($group == 'history') ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK
|
| 57 |
);
|
| 58 |
foreach (array_keys($graph) as $key) {
|
| 59 |
$items['graphstat/'. strtr($group .'_'. $key, ' ', '_')] = array(
|
| 60 |
'access callback' => 'user_access',
|
| 61 |
'access arguments' => array('access graphs'),
|
| 62 |
'page callback' => 'graphstat_render_graph',
|
| 63 |
'page arguments' => array($group, $key),
|
| 64 |
'type' => MENU_CALLBACK
|
| 65 |
);
|
| 66 |
}
|
| 67 |
}
|
| 68 |
|
| 69 |
return $items;
|
| 70 |
}
|
| 71 |
|
| 72 |
/**
|
| 73 |
* Function graphstat_graphs().
|
| 74 |
* (menu callback: page containing multiple graphs)
|
| 75 |
*/
|
| 76 |
function graphstat_graphs($group = NULL) {
|
| 77 |
$graphs = module_invoke_all('graphstat');
|
| 78 |
|
| 79 |
if ($group && isset($graphs[$group])) {
|
| 80 |
$graphs = $graphs[$group];
|
| 81 |
$output = isset($graphs['pre']) ? $graphs['pre'] : '';
|
| 82 |
// If this graph group defines a filter callback then add the filter form
|
| 83 |
if (isset($graphs['filter'])) {
|
| 84 |
$options = $graphs['filter']['options'];
|
| 85 |
$filter = isset($_SESSION['graphstat_filter'][$group]) ? $_SESSION['graphstat_filter'][$group] : NULL;
|
| 86 |
if (isset($_POST['graphstat_filter_select'])) {
|
| 87 |
$filter = $_POST['graphstat_filter_select'];
|
| 88 |
$_SESSION['graphstat_filter'][$group] = $filter;
|
| 89 |
}
|
| 90 |
$output .= drupal_get_form('graphstat_filter_form', $options, $filter);
|
| 91 |
}
|
| 92 |
// Loop over the graphs for this graph group
|
| 93 |
foreach($graphs as $key => $graph) {
|
| 94 |
if (is_array($graph) && isset($graph['data']) && is_array($graph['data'])) {
|
| 95 |
$url = url('graphstat/'. strtr($group .'_'. $key, ' ', '_'), array('absolute' => TRUE));
|
| 96 |
$title = isset($graph['title']) ? $graph['title'] : drupal_ucfirst($group);
|
| 97 |
$description = isset($graph['description']) ? $graph['description'] : '';
|
| 98 |
$output .= theme('graphstat_graph', $url, $title, $description);
|
| 99 |
}
|
| 100 |
}
|
| 101 |
$output .= isset($graphs['post']) ? $graphs['post'] : '';
|
| 102 |
$output .= drupal_get_form('graphstat_size_form');
|
| 103 |
}
|
| 104 |
else {
|
| 105 |
$output = t('There are no graphs available for this group.');
|
| 106 |
}
|
| 107 |
|
| 108 |
return $output;
|
| 109 |
}
|
| 110 |
|
| 111 |
/**
|
| 112 |
* Function graphstat_filter_form().
|
| 113 |
*/
|
| 114 |
function graphstat_filter_form($form_state, $options, $default = NULL) {
|
| 115 |
$form = array('#attributes' => array('class' => 'graphstat-filter-form'));
|
| 116 |
$form['graphstat_filter_select'] = array(
|
| 117 |
'#type' => 'select',
|
| 118 |
'#default_value' => $default ? $default : $options[0],
|
| 119 |
'#options' => $options
|
| 120 |
);
|
| 121 |
$form['graphstat_filter_submit'] = array('#type' => 'submit', '#value' => t('Show'));
|
| 122 |
|
| 123 |
return $form;
|
| 124 |
}
|
| 125 |
|
| 126 |
/**
|
| 127 |
* Function theme_graphstat_filter_form().
|
| 128 |
*/
|
| 129 |
function theme_graphstat_filter_form($form) {
|
| 130 |
$rows[] = array(
|
| 131 |
drupal_render($form['graphstat_filter_select']),
|
| 132 |
drupal_render($form['graphstat_filter_submit'])
|
| 133 |
);
|
| 134 |
|
| 135 |
return theme('table', array(), $rows, array('width' => '250px'));
|
| 136 |
}
|
| 137 |
|
| 138 |
/**
|
| 139 |
* Function graphstat_size_form().
|
| 140 |
* (add buttons to change (larger/default/smaller) the size of the graphs)
|
| 141 |
*/
|
| 142 |
function graphstat_size_form($form_state) {
|
| 143 |
$form = array('#attributes' => array('class' => 'graphstat-size-form'));
|
| 144 |
$form['graphstat_size_larger'] = array('#type' => 'submit', '#value' => t('Larger graphs'));
|
| 145 |
$form['graphstat_size_default'] = array('#type' => 'submit', '#value' => t('Default'));
|
| 146 |
$form['graphstat_size_smaller'] = array('#type' => 'submit', '#value' => t('Smaller graphs'));
|
| 147 |
|
| 148 |
return $form;
|
| 149 |
}
|
| 150 |
|
| 151 |
/**
|
| 152 |
* Function graphstat_size_form_submit().
|
| 153 |
*/
|
| 154 |
function graphstat_size_form_submit($form, &$form_state) {
|
| 155 |
if (isset($form_state['values']['op'])) {
|
| 156 |
global $user;
|
| 157 |
$cid = 'graphstat:'. $user->uid;
|
| 158 |
$cache = cache_get($cid);
|
| 159 |
$data['width'] = $cache ? $cache->data['width'] : 500;
|
| 160 |
$data['height'] = $cache ? $cache->data['height'] : 300;
|
| 161 |
switch ($form_state['values']['op']) {
|
| 162 |
case t('Larger graphs'):
|
| 163 |
$data['width'] += 100;
|
| 164 |
$data['height'] += 60;
|
| 165 |
break;
|
| 166 |
case t('Smaller graphs'):
|
| 167 |
$data['width'] -= 100;
|
| 168 |
$data['height'] -= 60;
|
| 169 |
break;
|
| 170 |
default:
|
| 171 |
$data['width'] = 500;
|
| 172 |
$data['height'] = 300;
|
| 173 |
}
|
| 174 |
cache_set($cid, $data, 'cache', CACHE_PERMANENT);
|
| 175 |
}
|
| 176 |
}
|
| 177 |
|
| 178 |
/**
|
| 179 |
* Function theme_graphstat_graph().
|
| 180 |
* (format a single graph with title, description, ...)
|
| 181 |
*/
|
| 182 |
function theme_graphstat_graph($url, $title = '', $description = '', $attributes = array()) {
|
| 183 |
global $user;
|
| 184 |
$cache = cache_get('graphstat:'. $user->uid);
|
| 185 |
$attributes['width'] = $cache ? $cache->data['width'] : 500;
|
| 186 |
$attributes['height'] = $cache ? $cache->data['height'] : 300;
|
| 187 |
$attributes['alt'] = isset($attributes['alt']) ? $attributes['alt'] : check_plain($title);
|
| 188 |
|
| 189 |
$output = '<div class="graphstat-container">';
|
| 190 |
$output .= '<div class="graphstat-image">';
|
| 191 |
$output .= '<img src="'. check_url($url) .'" title="'. check_plain($title) .'" '. drupal_attributes($attributes) .' />';
|
| 192 |
$output .= '</div>';
|
| 193 |
if (!empty($description)) {
|
| 194 |
$output .= '<div class="description graphstat-legend">';
|
| 195 |
$output .= check_plain($description);
|
| 196 |
$output .= '</div>';
|
| 197 |
}
|
| 198 |
$output .= '</div>';
|
| 199 |
|
| 200 |
return $output;
|
| 201 |
}
|
| 202 |
|
| 203 |
/**
|
| 204 |
* Function graphstat_render_graph().
|
| 205 |
* (function to render the actual graph .png images)
|
| 206 |
*/
|
| 207 |
function graphstat_render_graph($group, $key) {
|
| 208 |
global $user;
|
| 209 |
drupal_set_header('Content-type: image/png');
|
| 210 |
|
| 211 |
$filter = isset($_SESSION['graphstat_filter'][$group]) ? $_SESSION['graphstat_filter'][$group] : NULL;
|
| 212 |
$cache = cache_get('graphstat:'. $user->uid);
|
| 213 |
$width = $cache ? $cache->data['width'] : 500;
|
| 214 |
$height = $cache ? $cache->data['height'] : 300;
|
| 215 |
$time = format_date(time(), 'custom', 'H');
|
| 216 |
|
| 217 |
$cid = 'graphstat:'. md5($group . $key . $filter) .':'. $width .':'. $time;
|
| 218 |
if ($cache = cache_get($cid)) {
|
| 219 |
$image = $cache->data;
|
| 220 |
}
|
| 221 |
else {
|
| 222 |
// Cache Miss: we need to generate the graphs from scratch
|
| 223 |
$graphs = module_invoke_all('graphstat');
|
| 224 |
$graphs = $graphs[$group];
|
| 225 |
// If a filter is defined then invoke the callback function
|
| 226 |
// to fetch the filtered graph data
|
| 227 |
if (isset($graphs['filter'])) {
|
| 228 |
$function = $graphs['filter']['callback'];
|
| 229 |
if (function_exists($function)) {
|
| 230 |
$function($graphs, $filter);
|
| 231 |
}
|
| 232 |
}
|
| 233 |
$graph = $graphs[$key];
|
| 234 |
// If no graph data available then render a placeholder image
|
| 235 |
if (empty($graph['data'])) {
|
| 236 |
if (function_exists('imagepng')) {
|
| 237 |
$img = imagecreate($width, $height);
|
| 238 |
imagefill($img, 0, 0, imagecolorallocate($img, 240, 240, 240));
|
| 239 |
imageline($img, 0, 0, $width, $height, imagecolorallocate($img, 128, 128, 128));
|
| 240 |
imageline($img, 0, $height, $width, 0, imagecolorallocate($img, 128, 128, 128));
|
| 241 |
imagepng($img);
|
| 242 |
imagedestroy($img);
|
| 243 |
}
|
| 244 |
exit();
|
| 245 |
}
|
| 246 |
// Include the PHPLOT library
|
| 247 |
require_once (drupal_get_path('module', 'graphstat') .'/phplot.php');
|
| 248 |
// Create instance of PHPLOT and configure graph paramters
|
| 249 |
$plot =& new PHPlot($width, $height);
|
| 250 |
$graph['type'] = isset($graph['type']) ? $graph['type'] : 'linepoints';
|
| 251 |
$plot->SetPlotType($graph['type']);
|
| 252 |
$plot->SetTitle(isset($graph['title']) ? $graph['title'] : '');
|
| 253 |
$plot->SetXTitle(isset($graph['xlabel']) ? $graph['xlabel'] : '');
|
| 254 |
$plot->SetXTickLabelPos('none');
|
| 255 |
$plot->SetYTitle(isset($graph['ylabel']) ? $graph['ylabel'] : '');
|
| 256 |
$plot->SetXLabelAngle(90);
|
| 257 |
if (isset($graph['legend'])) {
|
| 258 |
$plot->SetLegend($graph['legend']);
|
| 259 |
}
|
| 260 |
// Push graph data into the plot renderer
|
| 261 |
$data = array();
|
| 262 |
if (is_array(current($graph['data']))) {
|
| 263 |
$data = $graph['data'];
|
| 264 |
}
|
| 265 |
else {
|
| 266 |
foreach ($graph['data'] as $x => $y) {
|
| 267 |
$data[] = array($x, $y);
|
| 268 |
}
|
| 269 |
}
|
| 270 |
$plot->SetDataValues($data);
|
| 271 |
// Draw the graph into a buffer $image
|
| 272 |
ob_start();
|
| 273 |
$plot->DrawGraph();
|
| 274 |
$image = ob_get_contents();
|
| 275 |
ob_end_clean();
|
| 276 |
// Put $image into the cache
|
| 277 |
cache_set($cid, $image, 'cache', CACHE_TEMPORARY);
|
| 278 |
}
|
| 279 |
|
| 280 |
// Print out the image and make sure to exit immediatly
|
| 281 |
print $image;
|
| 282 |
exit();
|
| 283 |
}
|