/[drupal]/contributions/modules/hof/hof.module
ViewVC logotype

Contents of /contributions/modules/hof/hof.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.17 - (show annotations) (download) (as text)
Mon Feb 2 22:42:25 2009 UTC (9 months, 3 weeks ago) by syscrusher
Branch: MAIN
CVS Tags: HEAD
Changes since 1.16: +14 -10 lines
File MIME type: text/x-php
Initial port to Drupal 7, still alpha-quality.
1 <?php
2 /*
3 * $Id: hof.module,v 1.16 2008/12/19 02:43:40 syscrusher Exp $
4 *
5 * Hall-Of-Fame is a module that reports summary statistics for a Drupal
6 * web site, with an emphasis on reports that are of interest to visitors
7 * rather than just administrators, and which bring credit to those who
8 * have contributed to a site's success.
9 *
10 * This version has been tested with Drupal 4.5 and Drupal 4.6. It will
11 * not work with earlier versions of Drupal.
12 *
13 * Author: Scott Courtney ("syscrusher" on drupal.org) scott@4th.com
14 *
15 * License: GNU General Public License (GPL)
16 */
17
18 /**
19 * Returns help text for various aspects of this module
20 */
21 function hof_help($section) {
22 switch ($section) {
23 case 'admin/modules#description':
24 return t('Displays a Hall of Fame page for the site');
25 case 'admin/help#hof':
26 $html = '<h2>'. t('Introduction') .'</h2>';
27 $html .= '<p>'. t('Hall of Fame (HOF) offers a concise summary of site statistics on a read-only basis. Unlike the built-in statistical features of Drupal itself, HOF is intended for public consumption rather than [mostly] for administrators. The module can display its output in sections such as &quot;Most Popular Content&quot;, &quot;Most Active Contributors&quot;, etc., or it can make a single large page with the combined output of all sections, or it can produce a sparse table-of-contents page with links to each section.');
28 $html .= '</p><p>'. t('Administrators can determine what roles have permission to view the HOF pages, who can change the module\'s settings, and some behaviors of the module (such as which output section is the default).');
29 $html .= '</p><p>'. t('HOF is aware of the weblink and scheduler modules, and if they are installed, it adds specific reporting features related to these, as explained below.');
30 $html .= '</p><h2>'. t('Statistical Computations') .'</h2>';
31 $html .= '<p>'. t('Overall statistics include, among others:') .'<dl>';
32 $html .= '<dt>'. t('Date of first publication, and time since that date') .'<dd>'. t('Computed by looking for the earliest creation date of any node');
33 $html .= '</dd><dt>'. t('Number of active user accounts') .'</dt><dd>'. t('Computed by looking for an update date greater than the creation date of the account, an attempt to ignore accounts which are created but never used.');
34 $html .= '</dd><dt>'. t('Weblinks in directory') .'</dt><dd>'. t('If the weblink module is installed, this statistic reports how many weblinks have been published.');
35 $html .= '</dd><dt>'. t('Items in queue awaiting approval') .'</dt><dd>'. t('Tallies all unpublished nodes. If the scheduler module is installe, nodes that have been scheduled for future publication are not counted in this number.');
36 $html .= '</dd><dt>'. t('Items awaiting scheduled release') .'</dt><dd>'. t('If the scheduler module is installed, this statistic indicates how many nodes have been scheduled for release in the future.');
37 $html .= '</dd></dl></p><p>'. t('Other statistics are computed for the past week, the past month, the past year, and for all time since the site\'s creation. These include:') .'<dl>';
38 $html .= '<dt>'. t('Most active contributors') .'</dt><dd>'. t('Computed by looking at the user who created each node.');
39 $html .= '</dd><dt>'. t('Most popular content') .'</dt><dd>'. t('Computed by tallying the number of reads for each node.');
40 $html .= '</dd><dt>'. t('Stories published') .'</dt><dd>'. t('In this context, &quot;stories&quot; really means &quot;promoted nodes&quot;, the concept being intended as &quot;things that are announced on the default main page as newsworthy&quot; as opposed to regular pages that may include static-ish content, terms of service, privacy policy, and so on.');
41 $html .= '</dd><dt>'. t('Total articles published') .'</dt><dd>'. t('This is simply a count of all published nodes on the site, regardless of type.');
42 $html .= '</dd></dl></p>';
43 return $html;
44 }
45 }
46
47 /**
48 * Reports the permissions exposed by this module
49 */
50 function hof_perm() {
51 $sections = hof_get_sections();
52 $enabled = variable_get('hof_enable_sections', $sections);
53 unset($sections['toc']);
54 unset($sections['all']);
55 $perms = array('access hof', 'administer hof');
56 foreach ($sections as $section=>$title) {
57 if (array_search($section, $enabled) !== FALSE) {
58 $menu_title = strtolower(preg_replace('/\W+/', ' ', $title));
59 $perm = 'access hof '. $menu_title;
60 $perms[$perm] = array('title'=>$title, 'description'=>t('View this page of the Hall of Fame'));
61 }
62 }
63 return $perms;
64 }
65
66 /**
67 * Builds the HOF settings form
68 */
69 function hof_settings_form() {
70 $sections = hof_get_sections();
71 unset($sections['toc']); // These two are always enabled
72 unset($sections['all']);
73 $sections2 = hof_get_sections(); // For selecting default display, do not remove toc and all
74
75 $form = array();
76
77 $form['hof_sections'] = array(
78 '#type' => 'fieldset',
79 '#tree' => false,
80 '#title' => t('Hall of Fame Sections'),
81 '#collapsible' => true,
82 );
83 $form['hof_sections']['hof_enable_sections'] = array(
84 '#type' => 'checkboxes',
85 '#title' => t('Enable HOF sections'),
86 '#description' => t('Check or uncheck each option to enable or disable that section of the Hall of Fame'),
87 '#default_value' => variable_get('hof_enable_sections', $sections),
88 '#options' => $sections,
89 );
90 $sections = hof_get_sections();
91 unset($sections['default']); // Not applicable here
92 $form['hof_sections']['hof_default_section'] = array(
93 '#type' => 'select',
94 '#title' => t('Default HOF section'),
95 '#description' => t('Select the page that will display at the top-level Hall of Fame URL'),
96 '#default_value' => variable_get('hof_default_section', 'all'),
97 '#options' => $sections2,
98 '#multiple' => false,
99 );
100
101 $form['hof_toc'] = array(
102 '#type' => 'fieldset',
103 '#tree' => false,
104 '#title' => t('Table of Contents (TOC) Settings'),
105 '#collapsible' => true,
106 );
107 $form['hof_toc']['hof_toc_position'] = array(
108 '#type' => 'select',
109 '#title' => t('TOC position'),
110 '#description' => t('Select the position of a table-of-contents, or link to the table of contents, to display on all pages except for the TOC page itself.'),
111 '#default_value' => variable_get('hof_toc_position', 'bottom'),
112 '#options' => array('top' => t('Above report'), 'bottom' => t('Below report'), 'none' => t('No automatic TOC')),
113 '#multiple' => false,
114 );
115 $form['hof_toc']['hof_toc_mode'] = array(
116 '#type' => 'select',
117 '#title' => t('TOC mode'),
118 '#description' => t('Should the embedded table-of-contents be just a link to the TOC page, or should all the links to individual pages be listed? This affects only the TOC embedded in other pages, not the TOC on its own dedicated page.'),
119 '#default_value' => variable_get('hof_toc_mode', 'link'),
120 '#options' => array('link' => t('Link to TOC page'), 'full' => t('Show full TOC in pages')),
121 '#multiple' => false,
122 );
123 $form['hof_toc']['hof_toc_in_toc'] = array(
124 '#type' => 'checkbox',
125 '#title' => t('Include HOF TOC in embedded TOC'),
126 '#description' => t('If the embedded table-of-contents is enabled, this setting controls whether that TOC will include a link to the full-page TOC. You can disable that link if it is redundant because of your choice of theme and other Hall of Fame settings.'),
127 '#default_value' => variable_get('hof_toc_in_toc', TRUE),
128 '#return_value' => 1,
129 );
130
131 $form['hof_reports'] = array(
132 '#type' => 'fieldset',
133 '#tree' => false,
134 '#title' => t('Report Settings'),
135 '#collapsible' => true,
136 );
137 $numbers = array('3' => 3, '5' => 5, '10' => 10, '15' => 15, '20' => 20);
138 $form['hof_reports']['hof_active_user_count'] = array(
139 '#type' => 'select',
140 '#title' => t('Users Per Activity Period'),
141 '#description' => t('For reports where the most-active users are listed for given time periods, this setting determines how many users will be listed (maximum) for each time period. The actual displayed list may be shorter if not enough users qualify to be listed.'),
142 '#default_value' => variable_get('hof_active_user_count', 5),
143 '#options' => $numbers,
144 '#multiple' => false,
145 );
146 $form['hof_reports']['hof_item_count'] = array(
147 '#type' => 'select',
148 '#title' => t('Items Per Activity Period'),
149 '#description' => t('For reports where items are ranked (such as by popularity) for given time periods, this setting determines how many items will be listed (maximum) for each time period. The actual displayed list may be shorter if not enough items qualify to be listed.'),
150 '#default_value' => variable_get('hof_item_count', 5),
151 '#options' => $numbers,
152 '#multiple' => false,
153 );
154 $form['hof_reports']['hof_promoted_label'] = array(
155 '#type' => 'textfield',
156 '#title' => t('Label for promoted articles'),
157 '#description' => t('When reporting statistics for promoted nodes (articles), this is the user-friendly title that will be used to describe these nodes. It should be plural and should be formatted with appropriate capitalization for use as a title. Suggested examples would be &quot;Promoted Articles&quot; (the default), &quot;News Items&quot;, and so forth. This option should be decided based on your site\'s policy for promoting content.'),
158 '#default_value' => variable_get('hof_promoted_label', t('Promoted Articles')),
159 '#size' => 30,
160 '#maxlength' => 40,
161 '#required' => true,
162 );
163 $form['hof_reports']['hof_node_label'] = array(
164 '#type' => 'textfield',
165 '#title' => t('Alternative for &quot;nodes&quot;'),
166 '#description' => t('When reporting statistics for all nodes, this is the user-friendly term that is used in place of Drupal\'s internal term, &quot;nodes&quot;. It should be plural and lower-case. Suggested examples would be &quot;articles&quot; (the default), &quot;pages&quot;, &quot;content items&quot;, and so forth.'),
167 '#default_value' => variable_get('hof_node_label', t('articles')),
168 '#size' => 20,
169 '#maxlength' => 20,
170 '#required' => true,
171 );
172 $form['hof_reports']['hof_nodes_include_images'] = array(
173 '#type' => 'checkbox',
174 '#title' => t('Count images as regular content'),
175 '#description' => t('Images are usually uploaded into collections or albums, and many site administrators do not think of each image as a content page in its own right. Technically, however, images are &quot;nodes&quot; within Drupal just like any other content. This setting controls whether they are counted as such in the Hall of Fame statistics for articles. If enabled, images are counted as articles; if disabled, they are counted only in their own separate tally.'),
176 '#default_value' => variable_get('hof_nodes_include_images', 0),
177 '#return_value' => 1,
178 );
179 $form['hof_reports']['hof_site_create_date_manual'] = array(
180 '#type' => 'checkbox',
181 '#title' => t('Set first online date manually'),
182 '#description' => t('If you set this option, the date below will display as the site\'s initial online date in the Site Statistics section. If this option is disabled, then the first published content will establish the site\'s starting date.'),
183 '#default_value' => variable_get('hof_site_create_date_manual', FALSE),
184 );
185 $form['hof_reports']['hof_site_create_date'] = array(
186 '#type' => 'date',
187 '#title' => t('Site first online date'),
188 '#default_value' => variable_get('hof_site_create_date', null),
189 '#description' => t('This date is used only if the checkbox above is set. <strong>This is interpreted as your site\'s default timezone.</strong>'),
190 );
191
192 return system_settings_form($form);
193 }
194
195 /**
196 * Adds appropriate entries to the Drupal menu
197 */
198 function hof_menu() {
199 $items = array();
200 $items['hof'] = array(
201 'title' => t('Hall of Fame'),
202 'page callback' => 'hof_page',
203 'access' => 'user_access',
204 'access arguments' => array('access hof'),
205 'type' => MENU_CALLBACK,
206 );
207 $sections = hof_get_sections();
208 foreach ($sections as $section=>$title) {
209 $weight = ($section == 'all') ? 10 : 0;
210 $items['hof/'. $section] = array(
211 'title' => $title,
212 'page callback' => 'hof_page',
213 'type' => MENU_CALLBACK,
214 'access callback' => 'hof_access',
215 'access arguments' => array($section),
216 'weight' => $weight,
217 );
218 }
219 $items['admin/settings/hof'] = array(
220 'title' => t('Hall of Fame'),
221 'description' => t('Control the display of the Hall of Fame'),
222 'page callback' => 'drupal_get_form',
223 'page arguments' => array('hof_settings_form'),
224 'access callback' => 'user_access',
225 'access arguments' => array('administer hof'),
226 'type' => MENU_NORMAL_ITEM,
227 );
228 return $items;
229 }
230
231 function hof_access($section) {
232 $sections = hof_get_sections();
233 if ($section == 'default' || $section == 'all' || $section == 'toc') {
234 $acc = user_access('access hof');
235 }
236 else {
237 $title = $sections[$section];
238 $section_access_key = 'access hof '. strtolower(preg_replace('/\W+/', ' ', $title));
239 $acc1 = user_access('access hof');
240 $acc2 = user_access($section_access_key);
241 $acc = $acc1 && $acc2;
242 }
243 return $acc;
244 }
245
246
247 /**
248 * Enumerates, as an associative array, the sections and their (translatable) titles
249 */
250 function hof_get_sections() {
251 $sections = array(
252 'site' => t('Site Statistics'),
253 'bytype' => t('Content Published by Type'),
254 'contrib' => t('Most Active Contributors'),
255 'node' => t('Most Popular Content'),
256 'comment' => t('Most Active Commentors'),
257 'files' => t('Uploaded Files'),
258 'all' => t('All Statistics'),
259 'toc' => t('HOF Table of Contents')
260 );
261 return $sections;
262 }
263
264 /**
265 * Enumerates sections as an associative array, but only those that are enabled by
266 * the site administrator and which are accessible to the current user. The sections
267 * 'default', 'toc', and 'all' are enabled for anyone who has access to the HOF
268 * module at all.
269 */
270 function hof_get_allowed_sections() {
271 // Trivial rejection if user has no access at all
272 if (! user_access('access hof')) {
273 return array();
274 }
275 $sections = hof_get_sections();
276 $enabled = variable_get('hof_enable_sections', $sections);
277 foreach ($sections as $section=>$title) {
278 if ($section != 'toc' && $section != 'all' && $section != 'default') {
279 /*
280 $title = strtolower(preg_replace('/\W+/', ' ', $title));
281 $perm = 'access hof '. $title;
282 if (! $enabled[$section]) {
283 unset($sections[$section]);
284 }
285 if (! user_access($perm)) {
286 unset($sections[$section]);
287 }
288 */
289 if (! $enabled[$section] || ! hof_access($section)) {
290 unset($sections[$section]);
291 }
292 }
293 }
294 return $sections;
295 }
296
297 /**
298 * Builds some global arrays for time interval handling
299 */
300 function _hof_constants() {
301 // Compute some time intervals (seconds before now)
302 $GLOBALS['hof_last_week'] = strtotime("-1 week");
303 $GLOBALS['hof_last_month'] = strtotime("-1 month");
304 $GLOBALS['hof_last_year'] = strtotime("-1 year");
305 $GLOBALS['hof_intervals'] = array(
306 t('week') => $GLOBALS['hof_last_week'],
307 t('month') => $GLOBALS['hof_last_month'],
308 t('year') => $GLOBALS['hof_last_year'],
309 t('epoch') => 0
310 );
311 }
312
313
314 /**
315 * Handle the display of pages
316 */
317 function hof_page() {
318 _hof_constants();
319 $toc_position = variable_get('hof_toc_position', 'none');
320 $default_section = variable_get('hof_default_section', 'toc');
321 $html = '<div class="hof">';
322 $section = arg(1);
323 $section = empty($section) ? 'default' : $section;
324 if ($section == 'toc' || ($default_section == 'toc' && $section == 'default')) {
325 $need_toc = FALSE;
326 }
327 else {
328 $need_toc = TRUE;
329 }
330 $function = '_hof_page_section_'. $section;
331 if (function_exists($function)) {
332 if ($need_toc) {
333 $sections = hof_get_sections();
334 if (isset($sections[$section])) {
335 drupal_set_title(t('Hall of Fame: '). $sections[$section]);
336 } else {
337 drupal_set_title(t('Hall of Fame'));
338 }
339 if ($toc_position == 'top') {
340 $html .= _hof_embedded_toc();
341 }
342 }
343 $args = func_get_args();
344 if (is_array($args)) {
345 $args = array_shift($args);
346 }
347 $html .= "<p><strong>". t('Statistics for ') . variable_get('site_name', t('this site')) . t(' as of ') . format_date(REQUEST_TIME, "long") ."</strong></p>\n";
348 $html .= call_user_func_array($function, $args);
349 if ($need_toc) {
350 if ($toc_position == 'bottom') {
351 $html .= _hof_embedded_toc();
352 }
353 }
354 $html .= '</div>';
355 return $html;
356 }
357 else {
358 drupal_not_found();
359 }
360 }
361
362 /**
363 * Default HOF page, depending on admin settings
364 */
365 function _hof_page_section_default() {
366 $default_section = variable_get('hof_default_section', 'toc');
367 $function = '_hof_page_section_'. $default_section;
368 if (function_exists($function)) {
369 $args = func_get_args();
370 return call_user_func_array($function, $args);
371 }
372 else {
373 drupal_set_message('Internal error: HOF tried to call function '. $function);
374 return "Internal error";
375 }
376 }
377
378 /**
379 * TOC only, providing a list of the other pages.
380 * This is the full TOC, not the embedded one.
381 */
382 function _hof_page_section_toc() {
383 $html = "";
384 $sections = hof_get_allowed_sections();
385 unset($sections['toc']);
386 foreach ($sections as $section=>$title) {
387 $function = '_hof_page_section_'. $section;
388 if ($section != 'toc' && $section != 'default' && function_exists($function)) {
389 $html .= "\n<h2 class=\"title\">". l($title, 'hof/'. $section) ."</h2>\n";
390 }
391 }
392 return $html;
393 }
394
395 /**
396 * TOC for embedding in pages, format depending
397 * on the administrative settings of the module.
398 */
399 function _hof_embedded_toc() {
400 $sections = hof_get_allowed_sections();
401 if (! variable_get('hof_toc_in_toc', TRUE)) {
402 unset($sections['toc']);
403 }
404 $mode = variable_get('hof_toc_mode', 'link');
405 $html = '<div class="hof_embedded_toc"><p>';
406 switch ($mode) {
407 case 'full':
408 $links = array();
409 foreach ($sections as $section=>$title) {
410 $links[] = l($title, 'hof/'. $section);
411 }
412 $html .= '[&nbsp;'. implode('&nbsp;|&nbsp;', $links) .'&nbsp;]';
413 break;
414 default:
415 $html .= '[&nbsp;'. l(t('Hall of Fame Table of Contents'), 'hof/toc') .'&nbsp;]';
416 }
417 $html .= "</p></div>\n";
418 return $html;
419 }
420
421 /**
422 * All statistics (combines all others)
423 */
424 function _hof_page_section_all() {
425 $html = "";
426 $sections = hof_get_allowed_sections();
427 unset($sections['toc']); // Don't display the TOC as part of the "all" display
428 foreach ($sections as $section=>$title) {
429 $function = '_hof_page_section_'. $section;
430 if ($section != 'all' && $section != 'default' && function_exists($function)) {
431 $html .= "\n<h2 class=\"title\">". l($title, 'hof/'. $section) ."</h2>\n";
432 $html .= call_user_func($function);
433 }
434 }
435 return $html;
436 }
437
438 /**
439 * Site statistics (general summary)
440 */
441 function _hof_page_section_site() {
442 if (variable_get('hof_site_create_date_manual', FALSE)) {
443 // Get the manually-set date
444 $ymd = variable_get('hof_site_create_date', array());
445 $first_tstmp = gmmktime(0, 0, 0, $ymd['month'], $ymd['day'], $ymd['year'], FALSE) - variable_get('date_default_timezone', 0);
446 } else {
447 $sql="SELECT MIN(created) AS began FROM {node} WHERE status=1 AND moderate=0";
448 $first_tstmp = db_result(db_query($sql));
449 }
450 $founded = format_date($first_tstmp, "long");
451 $duration = format_interval(REQUEST_TIME - $first_tstmp, 3);
452 $html = "<p><ul>\n";
453 $html .= "<li>" . t("This site's first publication was ") . $founded . ".</li>\n";
454 $html .= "<li>" . t("We have been online for ") . $duration . ".</li>\n";
455 $sql="SELECT COUNT(*) FROM {users} WHERE status=1 AND access>created";
456 $count = db_result(db_query($sql));
457 $html .= "<li>" . t("Active registered user accounts: ") . $count . "</li>\n";
458 $sql="SELECT COUNT(*) FROM {users} WHERE status=1 AND access=0 AND uid!=0";
459 $count = db_result(db_query($sql));
460 $html .= "<li>" . t("User accounts never activated: ") . $count . "</li>\n";
461 $sql="SELECT COUNT(*) FROM {users} WHERE status=0 AND uid!=0";
462 $count = db_result(db_query($sql));
463 $html .= "<li>" . t("Disabled user accounts: ") . $count . "</li>\n";
464 // Do the interval calculations
465 $items = array();
466 $intervals = $GLOBALS['hof_intervals'];
467 reset($intervals);
468 $friendly_promoted_nodes = variable_get('hof_promoted_label', t('Promoted Nodes'));
469 $friendly_nodes = variable_get('hof_node_label', t('articles'));
470 if (variable_get('hof_nodes_include_images', 0)) {
471 $image_exclude = '';
472 $image_text = t('Totals for %frnodes include images', array('%frnodes'=>$friendly_nodes));
473 } else {
474 $image_exclude = " AND type!='image'";
475 $image_text = t('Totals for %frnodes do not include images', array('%frnodes'=>$friendly_nodes));
476 }
477 while (list($interval, $tstmp) = each($intervals)) {
478 $sql = "SELECT count(*) FROM {node} WHERE promote=1 AND status=1 AND moderate=0 AND created>=%d " . $image_exclude;
479 $count = db_result(db_query($sql, $intervals[$interval]));
480 if ($interval == t('epoch')) {
481 $items[$interval] = $friendly_promoted_nodes . ' ' .t("published since this site was founded: ") . $count;
482 } else {
483 $items[$interval] = $friendly_promoted_nodes . ' ' .t("published in the last ") . $interval . ": " . $count;
484 }
485 }
486 foreach ($items as $line) {
487 $html .= "<li>" . $line . "</li>\n";
488 }
489 reset($intervals);
490 while (list($interval, $tstmp) = each($intervals)) {
491 $sql = "SELECT count(*) FROM {node} WHERE status=1 AND moderate=0 AND created>=%d " . $image_exclude;
492 $count = db_result(db_query($sql, $intervals[$interval]));
493 if ($interval == t('epoch')) {
494 $items[$interval] = t("Total") . ' ' . $friendly_nodes . ' '. t("published since this site was founded: ") . $count;
495 } else {
496 $items[$interval] = t("Total") . ' ' . $friendly_nodes . ' '. t("published in the last ") . $interval . ": " . $count;
497 }
498 }
499 foreach ($items as $line) {
500 $html .= "<li>" . $line . "</li>\n";
501 }
502 if (module_exists('links_weblink')) {
503 $sql="select count(*) FROM {node} where type = 'weblink' and status=1 and moderate=0";
504 $count = db_result(db_query($sql));
505 $html .= "<li>" . t("Web links in directory: ") . $count . "</li>\n";
506 }
507 if (module_exists('scheduler')) {
508 $sql="SELECT COUNT(*) FROM {node} n LEFT JOIN {scheduler} s ON n.nid=s.nid WHERE (n.status=0 OR n.moderate=1) AND s.nid IS NULL";
509 } else {
510 $sql="SELECT COUNT(*) FROM {node} n WHERE n.status=0 OR n.moderate=1";
511 }
512 $count = db_result(db_query($sql));
513 $html .= "<li>" . t("Items in editorial queue, awaiting approval: ") . $count . "</li>\n";
514 if (module_exists('scheduler')) {
515 $sql="select count(*) FROM {scheduler}";
516 $count = db_result(db_query($sql));
517 $html .= "<li>" . t("Items approved for automatic publication in the future: ") . $count . "</li>\n";
518 }
519 $html .= "</ul>\n";
520 $html .= '<p>' . $image_text . '</p>';
521 return $html;
522 }
523
524 /**
525 * Node statistics by type
526 */
527 function _hof_page_section_bytype() {
528 $html = '';
529 $intervals = $GLOBALS['hof_intervals'];
530 $sql = "SELECT DISTINCT n.type, nt.name, count(*) AS quantity, sum(totalcount) AS total_reads FROM {node} n LEFT JOIN {node_type} nt ON n.type=nt.type LEFT JOIN {node_counter} nc ON (n.nid=nc.nid OR nc.nid IS NULL) WHERE n.status=1 AND n.changed>=%d GROUP BY type ORDER BY type";
531 foreach ($intervals as $interval=>$tstmp) {
532 if ($interval == t('epoch')) {
533 $label = t("For All Time");
534 } else {
535 $label = t("For the past ") . $interval;
536 }
537 $html .= '<h3>' . $label . '</h3>';
538 $rows = array();
539 $result = db_query($sql, $tstmp);
540 if ($result) {
541 while ($row = db_fetch_array($result)) {
542 $type_name = empty($row['name']) ? $row['type'] : $row['name'];
543 $rows[] = array('data'=>array(t($type_name), intval($row['quantity']), intval($row['total_reads'])), 'align'=>'right');
544 }
545 $headers = array(t('Content Type'),t('Total Published'),t('Total Reads'));
546 // In the near future, will make this themeable, but need to do the whole
547 // module at once for aesthetic reasons.
548 // $html .= theme('table',$headers,$rows, array('width'=>'80%', 'class'=>'hof'));
549 // For now, use the legacy approach.
550 $html .= '<table width="80%"><tr>';
551 foreach ($headers as $hdr) {
552 $html .= '<th>' . htmlspecialchars($hdr) . '</th>';
553 }
554 $html .= '</tr>';
555 foreach ($rows as $row) {
556 $html .= '<tr><td>' . htmlspecialchars($row['data'][0]) . '</td><td>' . $row['data'][1] . '</td><td>' . $row['data'][2] . '</td></tr>';
557 }
558 $html .= '</table>';
559 }
560 }
561 $html .= '<p>&nbsp;</p>';
562 return $html;
563 }
564
565 /**
566 * Contributor statistics (most active)
567 */
568 function _hof_page_section_contrib() {
569 $sql = "SELECT count(*) contribs, name, n.uid FROM {node} n left join {users} u on n.uid=u.uid where n.uid>0 and n.status=1 and n.moderate=0 and n.created>=%d";
570 return _hof_most_active($sql);
571 }
572
573 /**
574 * Comment statistics (most active)
575 */
576 function _hof_page_section_comment() {
577 $sql = "SELECT count(*) contribs, u.name, u.uid FROM {comment} c left join {users} u on c.uid=u.uid where u.uid is not null and c.uid>0 and c.timestamp>=%d";
578 return _hof_most_active($sql);
579 }
580
581 /**
582 * Analyzes the "most active (something)" and creates HTML with the results.
583 * The parameter is an SQL statement that must return exactly three columns,
584 * in this order and with these aliases or names:
585 * contribs The integer count of activities for the given user
586 * name The name of the user being reported
587 * uid The uid of the user being reported
588 *
589 * The SQL must also contain a decimal placeholder %d which will be replaced with
590 * the timestamp (integer seconds-past-epoch) for the earliest applicable time
591 * for each iteration of the query.
592 *
593 * The SQL will be appended with appropriate GROUP BY, HAVING, ORDER, and LIMIT
594 * clauses based on administrative settings.
595 */
596 function _hof_most_active($sql) {
597 $active_limit = variable_get('hof_active_user_count', 5);
598 $sql_append = " GROUP BY name HAVING contribs>1 ORDER BY contribs DESC ";
599 $sql_full = $sql . $sql_append;
600 $tops = array();
601 // Do the interval calculations
602 $tops = array();
603 $intervals = $GLOBALS['hof_intervals'];
604 reset($intervals);
605 while (list($interval, $tstmp) = each($intervals)) {
606 $tops[$interval] = array();
607 $result = db_query_range($sql_full, $intervals[$interval], 0,$active_limit);
608 while ($row = db_fetch_array($result)) {
609 $tops[$interval][] = $row;
610 }
611 }
612 $html = "<p><table width=\"60%\">\n";
613 reset($intervals);
614 while (list($interval, $tstmp) = each($intervals)) {
615 $html .= "<tr><td colspan=\"2\">&nbsp;</td></tr>\n";
616 if ($interval == t('epoch')) {
617 $html .= "<tr align=\"left\"><th colspan=\"2\">" . t("For All Time") . "</th></tr>\n";
618 } else {
619 $html .= "<tr align=\"left\"><th colspan=\"2\">" . t("For the past ") . $interval . "</th></tr>\n";
620 }
621 foreach ($tops[$interval] as $list) {
622 $userlink = l($list['name'], 'user/'.$list['uid']);
623 $html .= "<tr align=\"left\"><td>" . $userlink . "</td><td>" . $list['contribs'] . t(" items") . "</td></tr>\n";
624 }
625 }
626 $html .= "</table>\n";
627 return $html;
628 }
629
630 /**
631 * Node statistics for uploaded files
632 */
633 function _hof_page_section_files() {
634 if (! module_exists('upload')) {
635 return "<p>" . t('The upload module is not enabled, so this Hall of Fame section is not applicable to this site.') . '</p>';
636 }
637 $html = "<p><table width=\"100%\">\n";
638 $intervals = $GLOBALS['hof_intervals'];
639 reset($intervals);
640 if (variable_get('hof_nodes_include_images', 0)) {
641 $sql_cond = '';
642 $message = '%filecount files and images uploaded';
643 } else {
644 $sql_cond = ' AND f.filemime NOT LIKE \'image/%\'';
645 $message = '%filecount files uploaded';
646 }
647 while (list($interval, $tstmp) = each($intervals)) {
648 $sql = "SELECT COUNT(DISTINCT u.fid, u.nid) AS filecount FROM {node} n, {upload} u, {files} f WHERE n.nid=u.nid AND n.vid=u.vid AND f.fid=u.fid AND n.created>=" . $tstmp . " AND n.status=1 AND moderate=0";
649 $sql .= $sql_cond;
650 $result = db_query($sql);
651 if ($row = db_fetch_array($result)) {
652 if ($interval == t('epoch')) {
653 $html .= "<tr align=\"left\"><th>" . t("For All Time") . "</th></tr>\n";
654 } else {
655 $html .= "<tr align=\"left\"><th>" . t("For the past ") . $interval . "</th></tr>\n";
656 }
657 $html .= "<tr align=\"left\"><td>" . t($message, array('%filecount'=>$row['filecount'])) . "</td></tr>\n";
658 }
659 }
660 $html .= "</table>\n";
661 return $html;
662 }
663
664 /**
665 * Node statistics (most popular)
666 */
667 function _hof_page_section_node() {
668 if (! module_exists('statistics')) {
669 $html = t('<p>The <code>statistics</code> module is not installed or is disabled. Read counts are not available unless this is corrected.</p>');
670 return $html;
671 }
672 if (! variable_get('statistics_count_content_views', FALSE)) {
673 $html = t('<p>The <code>statistics</code> module is installed, but read counts are not enabled. Correct this in the Access Log Settings page.</p>');
674 return $html;
675 }
676 $popular_limit = variable_get('hof_item_count', 5);
677 // Do the interval calculations
678 $pops = array();
679 $intervals = $GLOBALS['hof_intervals'];
680 reset($intervals);
681 while (list($interval, $tstmp) = each($intervals)) {
682 $pops[$interval] = array();
683 $sql = "SELECT n.nid, n.title, c.totalcount FROM {node} n left join {node_counter} c on n.nid=c.nid where n.status=1 and n.moderate=0 and n.created>=" . $intervals[$interval] . " and c.totalcount>1 and title not like '%page not found%' order by c.totalcount desc, n.created desc limit " . $popular_limit;
684 $result = db_query($sql);
685 while ($row = db_fetch_array($result)) {
686 $pops[$interval][] = $row;
687 }
688 }
689 $html = "<p><table width=\"100%\">\n";
690 reset($intervals);
691 while (list($interval, $tstmp) = each($intervals)) {
692 $html .= "<tr><td colspan=\"2\">&nbsp;</td></tr>\n";
693 if ($interval == t('epoch')) {
694 $html .= "<tr align=\"left\"><th colspan=\"2\">" . t("For All Time") . "</th></tr>\n";
695 } else {
696 $html .= "<tr align=\"left\"><th colspan=\"2\">" . t("For the past ") . $interval . "</th></tr>\n";
697 }
698 foreach ($pops[$interval] as $list) {
699 $nodelink = l($list['title'], 'node/' . $list['nid']);
700 $html .= "<tr align=\"left\"><td>" . $nodelink . "</td><td>" . $list['totalcount'] . "&nbsp;" . t("reads") . "</td></tr>\n";
701 }
702 }
703 $html .= "</table>\n";
704 return $html;
705 }

  ViewVC Help
Powered by ViewVC 1.1.2