Im folgenden wird ein Grundgerüst für ein Drupal-Report-Modul vorgestellt. Zwar benötigt man für viele Reports in Drupal nicht unbedingt ein selbstentwickeltes Modul, weil man sich Reports mit dem Modul Views konfigurieren kann. Allerdings gelangt man mit diesem Modul manchmal an seine Grenzen vor allem, wenn komplexe User-Interaktionen von dem Report erwartet werden. In einem solchen Fall ist es einfacher, seine Anstrengung auf die Modulentwicklung zu konzentrieren. Einen Report zu entwickeln gehört dabei nicht unbedingt zu den schwierigsten Problemstellungen.
Hier wird zunächst ein einfaches Grundgerüst vorgestellt, das man mittels Copy&Paste als Ausgangspunkt für ein Report-Modul verwenden kann.
name = Report Simple description = A simple way to display a report core = 7.x package = whr-nrw php = 5.3 version = 7.x-0.1(alpha) ;dependencies[] = ;files[] = ;configure =
<?php /** * reportsimple module file * * Contains all hooks for this module. * The module shows report infos in a simple way. * * @author Wolfgang Hauertmann <info@hauertmann.com> * @copyright (c) 2014 Wolfgang Hauertmann * @license http://www.gnu.org/licenses/gpl-2.0.html GPL-2.0 * */ /** * Implements hook_menu(); * * @return array page items */ function reportsimple_menu() { /* PAGE: REPORT SIMPLE */ $items['admin/reports/reportsimple'] = array( 'title' => 'Report simple', 'description' => 'View report in a simple way.', 'page callback' => '_reportsimple_report', 'access arguments' => array('report test'), ); /* SETTINGS */ $items['admin/config/development/reportsimple'] = array( 'title' => 'Report simple settings', 'description' => 'Configuration for the reportsimple module', 'page callback' => 'drupal_get_form', 'page arguments' => array('reportsimple_form'), 'access arguments' => array('report administration pages'), 'type' => MENU_NORMAL_ITEM, ); return $items; } /** * Page callback: Displays reportsimple page elements * * @param string $action * Actual action, e.g. delete, clearall, title, path, ref, .... * @param string $param1 * First parameter, e.g.: 134.23.32.7, 'home', 340, ... * @param string $param2 * Second parameter, e.g.: 'include', 'exclude', ... * * @return array Page elements */ function _reportsimple_report($action='', $param1='', $param2='') { return "<h1> I am a simple report</h1>"; } /** * Implements hook_help(); * * @param $path * The paths on which hook_help displays help infos * * @return string Helptext */ function reportsimple_help($path/*, $arg*/) { switch($path){ case 'admin/reports/report_simple': return t('Simple output of the report'); // break; case 'admin/help#reportsimple'; $helpTxt='<p>'.t('Module generates a simple output of the report table').'<p>'; return $helpTxt; // break; } } /** * Report simple settings * * @param $form * A structured array containing the elements and properties of the form. * @param $form_state * An array that stores information about the form's current state * during processing. * * @return array form * */ function reportsimple_form($form, &$form_state) { $form['default_report_simple_pager_count'] = array( '#type' => 'textfield', '#title' => t('Maximum number of report list items per page'), '#default_value' => variable_get('default_report_simple_pager_count', 10), '#size' => 3, '#maxlength' => 3, '#description' => t('The maximum number of report list items per page.'), '#required' => TRUE, ); return system_settings_form($form); } /** * Validation of the settings * * @param $form * A structured array containing the elements and properties of the form. * @param $form_state * An array that stores information about the form's current state * during processing. * * @return void */ function reportsimple_form_validate($form, &$form_state){ $max_num = $form_state['values']['default_report_simple_pager_count']; if (!is_numeric($max_num)){ form_set_error('Maximum number of report list items per page', t('You must enter a number.')); } else if ($max_num <= 0){ form_set_error('Maximum number of report list items per page', t('Maximum number of items to display per page must be positive.')); } }
Es handelt sich um ein funktionsfähiges Modul mit dem Namen "Report Simple", welches aus nur zwei Dateien besteht und das man ohne weiteres schon installieren kann.
Nach der Installation erscheint neben der Modulspalte ein "Hilfe"-Link über den man die Integration des Moduls in Drupal erforschen kann. Ohne das im einzelnen hier zu dokumentieren, sei auf folgende neue Drupal-Seiten verwiesen, die nach der Installation erreichbar sind:
- ein Hilfetext: admin/help/reportsimple,
- die Reportseite: admin/reports/reportsimple,
- die Reporteinstellungen: admin/config/development/reportsimple,
- "Report Simple" wird in der Hilfe aufgelistet: admin/help,
- "Report Simple" wird in den Reports aufgelistet: admin/reports,
- "Report Simple" wird in der Konfiguration aufgelistet: admin/config/development.
Auf der Reportseite (admin/reports/reportsimple) wird vorerst nichts anderes ausgegeben als eine Überschrift: "I am a simple report".
Selbstverständlich kann man dieses Grundgerüst in diesem Zustand auch als Start für andere Module verwenden, nicht nur für Reports. Bisher besitzt das Modul außer einigen austauschbaren Bezeichnern noch keinen Bezug zu einem Reportmodul.
Ausbau des Grundgerüsts zu einem einfachen Report-Modul
Zur Demonstration wird hier die Aufgabe gestellt, den Inhalt der "accesslog"-Tabelle als Report auszugeben.
Abb 1: Ausgabe der Tabelle "accesslog" als "Report Simple"
Dafür muss die Funktion "reportsimple_report" mit Leben gefüllt werden:
/** * Page callback: Displays reportsimple page elements * * @param string $action * Actual action, e.g. delete, clearall, title, path, ref, .... * @param string $param1 * First parameter, e.g.: 134.23.32.7, 'home', 340, ... * @param string $param2 * Second parameter, e.g.: 'include', 'exclude', ... * * @return array Page elements */ function _reportsimple_report($action='', $param1='', $param2='') { #-- Get logaccess data #-- depending on user actions and the local filter database // needed here for building the query (orderByHeader) $header = array( array('data' => t('timestamp'), 'field' => 'h.timestamp', 'sort' => 'desc'), array('data' => t('hostname'), 'field' => 'h.hostname'), array('data' => t('title'), 'field' => 'h.title'), array('data' => t('path'), 'field' => 'h.path'), array('data' => t('referrer'), 'field' => 'h.url'), array('data' => t('timer'), 'field' => 'h.timer'), array('data' => t('id'), 'field' => 'h.aid'), array('data' => t('session'), 'field' => 'h.sid'), array('data' => t('user'), 'field' => 'h.uid'), ); // Build the query for accessing table 'accesslog' $query= db_select('accesslog', 'h')->extend('TableSort'); $query->join('users', 'u', 'h.uid = u.uid'); $query->fields('h', array('hostname', 'title', 'path', 'url', 'timestamp', 'timer', 'aid', 'sid', 'uid')) ->fields('u', array('name')); // Execute the query $result = $query ->extend('PagerDefault') ->orderByHeader($header) ->limit(variable_get('default_accesslog_simple_pager_count', 20)) ->execute(); // Display accesslog table (header: see abouve database query) $rows = array(); foreach ($result as $record) { $rows[] = array( $record->timestamp, $record->hostname, $record->title, $record->path, $record->url, $record->timer, $record->aid, $record->sid, $record->name, ); } $build['table'] = array( '#caption' => t('Access log'), '#theme' => 'table', '#header' => $header, '#rows' => $rows, '#attributes' => array('id' => 'accesslog_simple'), '#empty' => 'Accesslog or filter result is empty!', ); $build['pager'] = array( '#theme' => 'pager', ); return $build; }
Die Funktion besteht aus zwei großen Abschnitten.
Im ersten Abschnitt wird die Datenbankabfrage ("Query") zusammengebaut und ausgeführt.
Im zweiten Abschnitt wird ein $build-Array erstellt, das auf der Basis eines Standard-Themes, das für jedes darzustellende Element (hier unsere Tabelle) über den Schlüssel "#theme" ausgewählt wird, die Ausgabe steuert.
Die Übernahme dieses Code-Snippets lohnt sich ebenfalls, da die vorbereitete Lösung schon die Sortierung einzelner Spalten ermöglicht und eine Paginierung zur Verfügung stellt, wobei die Anzahl der ausgebaren Zeilen pro Seite in der Konfiguration eingestellt werden kann (admin/config/development/reportsimple).
Das Beispiel soll hier nicht ausführlich erläutert werden, sondern zum Ausprobieren und Experimentieren anregen und als Ausgangspunkt für die Entwicklung von komplexeren Reports dienen.