11 static function registerActivityTracker()
13 trace(
"Registering Redirect Log Callback", 1);
14 registerRedirectLogCallback(array(ActivityTracker, logActivity));
17 static function logActivity()
23 $entryPoint = basename($_SERVER[
'SCRIPT_NAME']);
25 if (!
$enabled || ($entryPoint !=
'page.php' && $entryPoint !=
'action.php'))
return;
32 trace(
"Request completed in {$response_time}s", 3);
34 $activity->method = $_SERVER[
'REQUEST_METHOD'];
35 $activity->referer = $_SERVER[
'HTTP_REFERER'];
38 $activity->response_time = $response_time;
39 $activity->memory_usage = memory_get_peak_usage();
48 $log = ActivityTracker::getLogFile(session_id(),
$start);
50 $sessionLogID =
$_SESSION[
"ActivityTracker::tracking"];
56 $sessionLog->session_id = $sessionLogID;
58 $update =
"SET user_id=".$activity->user_id.
", session_end = ".
$activity->quoteFieldValue(
'activity_time', DateTime).
", request_count = request_count + 1";
59 if (startsWith(
$activity->uri,
"/action/activity_tracker/save"))
61 $update .=
", feedback_count = feedback_count + 1";
64 if (startsWith(
$activity->uri,
"/action/"))
66 $update .=
", action_count = action_count + 1";
70 $update .=
", page_views = page_views + 1";
73 $sessionLog->updateExplicit($update);
79 if (!$sessionLog->tableExists())
return;
81 $sessionLog->session_identifier = session_id();
82 $sessionLog->user_id =
$activity->user_id;
83 $sessionLog->session_start =
$activity->activity_time;
84 $sessionLog->session_end =
$activity->activity_time;
85 $sessionLog->request_count = 1;
86 $sessionLog->action_count = (startsWith(
$activity->uri,
"/action/")) ? 1 : 0;
87 $sessionLog->page_views = (startsWith(
$activity->uri,
"/action/")) ? 0 : 1;
88 $sessionLog->ip_address = $_SERVER[
"REMOTE_ADDR"];
89 $sessionLog->user_agent = $_SERVER[
"HTTP_USER_AGENT"];
92 $_SESSION[
"ActivityTracker::tracking"] = $sessionLog->session_id;
98 static function getLogFile($session_identifier,
$start)
101 if (!file_exists(
$dir)) mkdir(
$dir);
103 return $dir.DIRECTORY_SEPARATOR.$session_identifier.
".json";
106 static function formatMemoryUsage(
$activity)
108 return getScaledSize(
$activity->memory_usage, 2);
118 static function deleteUser(
$user)
123 trace(
"Component activity_tracker is deleting objects dependent on user_id {$user_id}", 3);
125 $tx =
new DataTransaction();
131 $feedback->delete(
"WHERE user_id={$user_id}");
134 $userActivity->joinTransaction(
$tx);
135 $userActivity->delete(
"WHERE user_id={$user_id}");
147 static function setDefaults()
151 $base =
$config[
'uploadbase'].DIRECTORY_SEPARATOR.
"user_activity_logs";
153 Settings::setDefaultValue(
"activity_tracker",
"track_activity",
"", Boolean,
"Track user activity. Use this for usage statistics and troubleshooting. For better performance, disable this on sites with heavy traffic.",
"Activity Tracking");
154 Settings::setDefaultValue(
"activity_tracker",
"enable_feedback",
"", Boolean,
"Enable the user feedback feature. You will also need to assign the feedback module to a position in your template.",
"User Feedback",
null, 1);
155 Settings::setDefaultValue(
"activity_tracker",
"feedback_title",
"Provide Feedback", String,
"Title text for the user feedback module",
"User Feedback",
null, 3);
156 Settings::setDefaultValue(
"activity_tracker",
"require_login",
false, Boolean,
"Whether the feedback feature is available to guest users (those who haven't yet logged in)",
"User Feedback",
null, 2);
157 Settings::setDefaultValue(
"activity_tracker",
"confirmation_message",
"Thank you, your feedback is appreciated!", String,
"The message to display after the user submits feedback",
"User Feedback",
null, 4);
159 Settings::setDefaultValue(
"activity_tracker",
"send_email",
false, Boolean,
"Send a notification email when feedback is submitted. If you set this to true, configure recipient and message via the 'feedback_notification' email template",
"User Feedback",
null, 5);
161 Settings::setDefaultValue(
"activity_tracker",
"google_analytics_tracking_id",
"", String,
"Leave blank if tracking is not desired.",
"Google Analytics");
162 Settings::setDefaultValue(
"activity_tracker",
"google_analytics_version",
"Classic", String,
"Specifies the API Version of Google Analytics to use. Select this based on your site's analytics configuration on google.com",
"Google Analytics",
"Classic\nUniversal");
164 Settings::setDefaultValue(
"activity_tracker",
"logging_directory",
$base, String,
"Specifies the directory to which user activity logs will be written",
"Activity Tracking");
166 ActivityTracker::createLogDirectory();
169 static function isEnabled()
174 static function createLogDirectory()
176 if (ActivityTracker::isEnabled())
180 if (!file_exists($logDirectory))
182 mkdir($logDirectory);
187 static function upgradeComponent($version)
190 $mgr->upgrade($version);
197 static function getGoogleAnalyticsScript(
$id)
205 if ($trackingMode ==
"Classic")
208 <script type=
"text/javascript">
210 var _gaq = _gaq || [];
211 _gaq.push([
'_setAccount',
'<?php echo $id ?>']);
212 _gaq.push([
'_trackPageview']);
216 var ga = document.createElement(
'script'); ga.type =
'text/javascript'; ga.async =
true;
217 ga.src = (
'https:' == document.location.protocol ?
'https://ssl' :
'http://www') +
'.google-analytics.com/ga.js';
218 var s = document.getElementsByTagName(
'script')[0]; s.parentNode.insertBefore(ga, s);
224 else if ($trackingMode ==
"Universal")
227 <script type=
"text/javascript">
229 (
function(i,s,o,g,r,a,m){i[
'GoogleAnalyticsObject']=r;i[r]=i[r]||
function(){
230 (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*
new Date();a=s.createElement(o),
231 m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
232 })(window,document,
'script',
'//www.google-analytics.com/analytics.js',
'ga');
234 ga(
'create',
'<?php echo $id ?>',
'auto');
235 ga(
'send',
'pageview');
255 static function postProcessContent(
$content)
263 $script .= ActivityTracker::getGoogleAnalyticsScript(
$id);
270 static function getBrowser($session)
272 $browser = get_browser($session->user_agent);
273 return $browser ?
"{$browser->parent} ({$browser->platform})" :
"N/A";
281 static function loadSession($session)
283 $log = ActivityTracker::getLogFile($session->session_identifier, date(
"Y-m-d", strtotime($session->session_start)));
285 trace(
"Opening session log $log", 3);
287 $fp = fopen(
$log,
"r");
291 while($json = fgets($fp))
305 static function migrateData($session)
307 $records = Query::create(
UserActivity,
"WHERE user_id=:u AND session_id=:s ORDER BY activity_id")
308 ->bind(
":u", $session->user_id,
":s", $session->session_id)
309 ->filter(
new ExclusionFilter(
"response_time"))
312 $start = date(
"Y-m-d", strtotime($session->session_start));
314 $log = ActivityTracker::getLogFile($session->session_id,
$start);
316 if (file_exists(
$log))
return;
319 $userSession->session_identifier = $session->session_id;
320 $userSession->user_id = $session->user_id;
321 $userSession->session_start = $session->session_start;
322 $userSession->session_end = $session->session_end;
323 $userSession->feedback_count = $session->num_feedback;
329 foreach($records as $record)
331 error_log($record->toJSON().
"\n", 3,
$log);
334 if (startsWith(
"/action", $record->uri))
344 $userSession->page_views = $pageViews;
345 $userSession->action_count = $actionCount;
346 $userSession->requestCount = $requestCount;
347 $userSession->save();
351 class ActivityReportFilterHelper
353 function __construct()
361 $session->filter =
new InclusionFilter(
"session_start",
"feedback_user");
362 $session->overrideFieldType(
"feedback_user", Boolean);
368 $userCheckBox =
new BooleanFilterFieldRenderer(
$filterForm,
"feedback_user",
"Show only users that provided feedback", 1);
369 $filterForm->setHandler(
"feedback_user", array($this, getFeedbackUserClause));
381 static function getFeedbackUserClause(
$name, $value)
384 return "feedback_count > 0";
388 class SessionDetailsHelper
392 function __construct()
394 $this->showImages = checkNumeric($_GET[
"showImages"]);
397 function filterImages($record)
399 if (!$this->showImages && startsWith($record->uri,
"/action/image/"))
return false;
if(! $showImages) if($session_id) else if($sessionIdentifier) $activity
static $requestStartTime
Start of request in DateTime format.
static $timestamp
Microsecond Timestamp for start of request.
static $requestURI
The initial request URI.
static using()
Import the datamodels, views and manifest for the specified component(s).
static getValue($component, $name)
Retrieve the value of the specified Setting.
static setDefaultValue($component, $name, $value, $field_type="String", $annotation="", $category="", $options="", $weight=0)
Sets the default value of the given component setting.
if(array_key_exists("HTTP_IF_MODIFIED_SINCE", $_SERVER)) $content