qa-event-logger.php 7.06 KB
Newer Older
Gideon Greenspan committed
1 2 3 4 5 6 7
<?php

/*
	Question2Answer (c) Gideon Greenspan

	http://www.question2answer.org/

8

Gideon Greenspan committed
9 10 11 12 13 14 15 16 17
	File: qa-plugin/event-logger/qa-event-logger.php
	Version: See define()s at top of qa-include/qa-base.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.
18

Gideon Greenspan committed
19 20 21 22 23 24 25 26 27
	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 {
28

29
		public function init_queries($tableslc)
Gideon Greenspan committed
30 31 32
		{
			if (qa_opt('event_logger_to_database')) {
				$tablename=qa_db_add_table_prefix('eventlog');
33

Gideon Greenspan committed
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
				if (!in_array($tablename, $tableslc)) {
					require_once QA_INCLUDE_DIR.'qa-app-users.php';
					require_once QA_INCLUDE_DIR.'qa-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';
				}
			}
		}

55

56
		public function admin_form(&$qa_content)
Gideon Greenspan committed
57 58 59 60 61
		{

		//	Process form input

			$saved=false;
62

Gideon Greenspan committed
63 64 65 66 67 68 69 70
			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;
			}
71

Gideon Greenspan committed
72
		//	Check the validity of the currently entered directory (if any)
73

Gideon Greenspan committed
74
			$directory=qa_opt('event_logger_directory');
75

Gideon Greenspan committed
76 77
			$note=null;
			$error=null;
78

Gideon Greenspan committed
79 80 81 82 83 84 85 86
			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.';
87

Gideon Greenspan committed
88 89 90 91 92 93
		//	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',
			));
94

Gideon Greenspan committed
95 96
			return array(
				'ok' => ($saved && !isset($error)) ? 'Event log settings saved' : null,
97

Gideon Greenspan committed
98 99 100
				'fields' => array(
					array(
						'label' => 'Log events to <code>'.QA_MYSQL_TABLE_PREFIX.'eventlog</code> database table',
Gideon Greenspan committed
101
						'tags' => 'name="event_logger_to_database_field"',
Gideon Greenspan committed
102 103 104 105 106 107
						'value' => qa_opt('event_logger_to_database'),
						'type' => 'checkbox',
					),

					array(
						'label' => 'Log events to daily log files',
Gideon Greenspan committed
108
						'tags' => 'name="event_logger_to_files_field" id="event_logger_to_files_field"',
Gideon Greenspan committed
109 110 111
						'value' => qa_opt('event_logger_to_files'),
						'type' => 'checkbox',
					),
112

Gideon Greenspan committed
113 114 115 116
					array(
						'id' => 'event_logger_directory_display',
						'label' => 'Directory for log files - enter full path:',
						'value' => qa_html($directory),
Gideon Greenspan committed
117
						'tags' => 'name="event_logger_directory_field"',
Gideon Greenspan committed
118 119 120
						'note' => $note,
						'error' => qa_html($error),
					),
121

Gideon Greenspan committed
122 123 124 125
					array(
						'id' => 'event_logger_hide_header_display',
						'label' => 'Include header lines at top of each log file',
						'type' => 'checkbox',
Gideon Greenspan committed
126
						'tags' => 'name="event_logger_hide_header_field"',
Gideon Greenspan committed
127 128 129
						'value' => !qa_opt('event_logger_hide_header'),
					),
				),
130

Gideon Greenspan committed
131 132 133
				'buttons' => array(
					array(
						'label' => 'Save Changes',
Gideon Greenspan committed
134
						'tags' => 'name="event_logger_save_button"',
Gideon Greenspan committed
135 136 137 138 139
					),
				),
			);
		}

140

141
		public function value_to_text($value)
Gideon Greenspan committed
142 143 144 145 146 147 148
		{
			if (is_array($value))
				$text='array('.count($value).')';
			elseif (strlen($value)>40)
				$text=substr($value, 0, 38).'...';
			else
				$text=$value;
149

Gideon Greenspan committed
150 151
			return strtr($text, "\t\n\r", '   ');
		}
152 153


154
		public function process_event($event, $userid, $handle, $cookieid, $params)
Gideon Greenspan committed
155 156 157
		{
			if (qa_opt('event_logger_to_database')) {
				$paramstring='';
158

Gideon Greenspan committed
159 160
				foreach ($params as $key => $value)
					$paramstring.=(strlen($paramstring) ? "\t" : '').$key.'='.$this->value_to_text($value);
161

Gideon Greenspan committed
162 163 164 165
				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
166
				);
Gideon Greenspan committed
167
			}
168

Gideon Greenspan committed
169 170 171
			if (qa_opt('event_logger_to_files')) {

			//	Substitute some placeholders if certain information is missing
172

Gideon Greenspan committed
173 174
				if (!strlen($userid))
					$userid='no_userid';
175

Gideon Greenspan committed
176 177
				if (!strlen($handle))
					$handle='no_handle';
178

Gideon Greenspan committed
179 180
				if (!strlen($cookieid))
					$cookieid='no_cookieid';
181

Gideon Greenspan committed
182 183 184
				$ip=qa_remote_ip_address();
				if (!strlen($ip))
					$ip='no_ipaddress';
185

Gideon Greenspan committed
186
			//	Build the log file line to be written
187

Gideon Greenspan committed
188 189 190 191 192 193 194 195 196
				$fixedfields=array(
					'Date' => date('Y\-m\-d'),
					'Time' => date('H\:i\:s'),
					'IPaddress' => $ip,
					'UserID' => $userid,
					'Username' => $handle,
					'CookieID' => $cookieid,
					'Event' => $event,
				);
197

Gideon Greenspan committed
198
				$fields=$fixedfields;
199

Gideon Greenspan committed
200 201
				foreach ($params as $key => $value)
					$fields['param_'.$key]=$key.'='.$this->value_to_text($value);
202

Gideon Greenspan committed
203
				$string=implode("\t", $fields);
204

Gideon Greenspan committed
205
			//	Build the full path and file name
206

Gideon Greenspan committed
207
				$directory=qa_opt('event_logger_directory');
208

Gideon Greenspan committed
209 210
				if (substr($directory, -1)!='/')
					$directory.='/';
211

Gideon Greenspan committed
212
				$filename=$directory.'q2a-log-'.date('Y\-m\-d').'.txt';
213

Gideon Greenspan committed
214
			//	Open, lock, write, unlock, close (to prevent interference between multiple writes)
215

Gideon Greenspan committed
216 217 218
				$exists=file_exists($filename);

				$file=@fopen($filename, 'a');
219

Gideon Greenspan committed
220 221 222 223 224 225
				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;
226

Gideon Greenspan committed
227 228 229 230 231 232 233 234
						fwrite($file, $string."\n");
						flock($file, LOCK_UN);
					}

					fclose($file);
				}
			}
		}
235

Gideon Greenspan committed
236
	}
237

Gideon Greenspan committed
238 239 240 241

/*
	Omit PHP closing tag to help avoid accidental output
*/