<?php /* Question2Answer by Gideon Greenspan and contributors http://www.question2answer.org/ File: qa-plugin/event-logger/qa-event-logger.php Description: Event module class for event logger plugin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. More about this license: http://www.question2answer.org/license.php */ class qa_event_logger { public function init_queries($table_list) { if (qa_opt('event_logger_to_database')) { $tablename=qa_db_add_table_prefix('eventlog'); if (!in_array($tablename, $table_list)) { require_once QA_INCLUDE_DIR.'app/users.php'; require_once QA_INCLUDE_DIR.'db/maxima.php'; return 'CREATE TABLE ^eventlog ('. 'datetime DATETIME NOT NULL,'. 'ipaddress VARCHAR (15) CHARACTER SET ascii,'. 'userid '.qa_get_mysql_user_column_type().','. 'handle VARCHAR('.QA_DB_MAX_HANDLE_LENGTH.'),'. 'cookieid BIGINT UNSIGNED,'. 'event VARCHAR (20) CHARACTER SET ascii NOT NULL,'. 'params VARCHAR (800) NOT NULL,'. 'KEY datetime (datetime),'. 'KEY ipaddress (ipaddress),'. 'KEY userid (userid),'. 'KEY event (event)'. ') ENGINE=MyISAM DEFAULT CHARSET=utf8'; } } } public function admin_form(&$qa_content) { // Process form input $saved=false; if (qa_clicked('event_logger_save_button')) { qa_opt('event_logger_to_database', (int)qa_post_text('event_logger_to_database_field')); qa_opt('event_logger_to_files', qa_post_text('event_logger_to_files_field')); qa_opt('event_logger_directory', qa_post_text('event_logger_directory_field')); qa_opt('event_logger_hide_header', !qa_post_text('event_logger_hide_header_field')); $saved=true; } // Check the validity of the currently entered directory (if any) $directory=qa_opt('event_logger_directory'); $note=null; $error=null; if (!strlen($directory)) $note='Please specify a directory that is writable by the web server.'; elseif (!file_exists($directory)) $error='This directory cannot be found. Please enter the full path.'; elseif (!is_dir($directory)) $error='This is a file. Please enter the full path of a directory.'; elseif (!is_writable($directory)) $error='This directory is not writable by the web server. Please choose a different directory, use chown/chmod to change permissions, or contact your web hosting company for assistance.'; // Create the form for display qa_set_display_rules($qa_content, array( 'event_logger_directory_display' => 'event_logger_to_files_field', 'event_logger_hide_header_display' => 'event_logger_to_files_field', )); return array( 'ok' => ($saved && !isset($error)) ? 'Event log settings saved' : null, 'fields' => array( array( 'label' => 'Log events to <code>'.QA_MYSQL_TABLE_PREFIX.'eventlog</code> database table', 'tags' => 'name="event_logger_to_database_field"', 'value' => qa_opt('event_logger_to_database'), 'type' => 'checkbox', ), array( 'label' => 'Log events to daily log files', 'tags' => 'name="event_logger_to_files_field" id="event_logger_to_files_field"', 'value' => qa_opt('event_logger_to_files'), 'type' => 'checkbox', ), array( 'id' => 'event_logger_directory_display', 'label' => 'Directory for log files - enter full path:', 'value' => qa_html($directory), 'tags' => 'name="event_logger_directory_field"', 'note' => $note, 'error' => qa_html($error), ), array( 'id' => 'event_logger_hide_header_display', 'label' => 'Include header lines at top of each log file', 'type' => 'checkbox', 'tags' => 'name="event_logger_hide_header_field"', 'value' => !qa_opt('event_logger_hide_header'), ), ), 'buttons' => array( array( 'label' => 'Save Changes', 'tags' => 'name="event_logger_save_button"', ), ), ); } public function value_to_text($value) { if (is_array($value)) $text='array('.count($value).')'; elseif (strlen($value)>40) $text=substr($value, 0, 38).'...'; else $text=$value; return strtr($text, "\t\n\r", ' '); } public function process_event($event, $userid, $handle, $cookieid, $params) { if (qa_opt('event_logger_to_database')) { $paramstring=''; foreach ($params as $key => $value) $paramstring.=(strlen($paramstring) ? "\t" : '').$key.'='.$this->value_to_text($value); qa_db_query_sub( 'INSERT INTO ^eventlog (datetime, ipaddress, userid, handle, cookieid, event, params) '. 'VALUES (NOW(), $, $, $, #, $, $)', qa_remote_ip_address(), $userid, $handle, $cookieid, $event, $paramstring ); } if (qa_opt('event_logger_to_files')) { // Substitute some placeholders if certain information is missing if (!strlen($userid)) $userid='no_userid'; if (!strlen($handle)) $handle='no_handle'; if (!strlen($cookieid)) $cookieid='no_cookieid'; $ip=qa_remote_ip_address(); if (!strlen($ip)) $ip='no_ipaddress'; // Build the log file line to be written $fixedfields=array( 'Date' => date('Y\-m\-d'), 'Time' => date('H\:i\:s'), 'IPaddress' => $ip, 'UserID' => $userid, 'Username' => $handle, 'CookieID' => $cookieid, 'Event' => $event, ); $fields=$fixedfields; foreach ($params as $key => $value) $fields['param_'.$key]=$key.'='.$this->value_to_text($value); $string=implode("\t", $fields); // Build the full path and file name $directory=qa_opt('event_logger_directory'); if (substr($directory, -1)!='/') $directory.='/'; $filename=$directory.'q2a-log-'.date('Y\-m\-d').'.txt'; // Open, lock, write, unlock, close (to prevent interference between multiple writes) $exists=file_exists($filename); $file=@fopen($filename, 'a'); if (is_resource($file)) { if (flock($file, LOCK_EX)) { if ( (!$exists) && (filesize($filename)===0) && !qa_opt('event_logger_hide_header') ) $string="Question2Answer ".QA_VERSION." log file generated by Event Logger plugin.\n". "This file is formatted as tab-delimited text with UTF-8 encoding.\n\n". implode("\t", array_keys($fixedfields))."\textras...\n\n".$string; fwrite($file, $string."\n"); flock($file, LOCK_UN); } fclose($file); } } } }