mirror of
https://github.com/Mibew/mibew.git
synced 2025-04-24 23:36:07 +03:00
325 lines
8.8 KiB
PHP
325 lines
8.8 KiB
PHP
<?php
|
|
/*
|
|
* This file is a part of Mibew Messenger.
|
|
*
|
|
* Copyright 2005-2023 the original author or authors.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
// Import namespaces and classes of the core
|
|
use Mibew\EventDispatcher\EventDispatcher;
|
|
use Mibew\EventDispatcher\Events;
|
|
use Mibew\Database;
|
|
use Mibew\ProcessLock;
|
|
use Mibew\Settings;
|
|
use Mibew\Thread;
|
|
|
|
function track_visitor($visitor_id, $entry, $referer)
|
|
{
|
|
$visitor = track_get_visitor_by_id($visitor_id);
|
|
|
|
if (false === $visitor) {
|
|
$visitor = track_visitor_start($entry, $referer);
|
|
|
|
return $visitor;
|
|
} else {
|
|
$db = Database::getInstance();
|
|
$db->query(
|
|
"UPDATE {sitevisitor} SET lasttime = :now WHERE visitorid = :visitorid",
|
|
array(
|
|
':visitorid' => $visitor['visitorid'],
|
|
':now' => time(),
|
|
)
|
|
);
|
|
track_visit_page($visitor['visitorid'], $referer);
|
|
|
|
return $visitor['visitorid'];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initialize visitor tracking.
|
|
*
|
|
* Triggers {@link \Mibew\EventDispatcher\Events::VISITOR_CREATE} event.
|
|
*
|
|
* @param string $entry The page the visitor came from to the page with
|
|
* tracking code.
|
|
* @param string $referer The page where tracking code is placed.
|
|
* @return int ID of the visitor.
|
|
*/
|
|
function track_visitor_start($entry, $referer)
|
|
{
|
|
$visitor = visitor_from_request();
|
|
|
|
$db = Database::getInstance();
|
|
$db->query(
|
|
("INSERT INTO {sitevisitor} ( "
|
|
. "userid, username, firsttime, lasttime, entry, details "
|
|
. ") VALUES ( "
|
|
. ":userid, :username, :now, :now, :entry, :details "
|
|
. ")"),
|
|
array(
|
|
':userid' => $visitor['id'],
|
|
':username' => $visitor['name'],
|
|
':now' => time(),
|
|
':entry' => $entry,
|
|
':details' => track_build_details(),
|
|
)
|
|
);
|
|
|
|
$id = $db->insertedId();
|
|
|
|
if ($id) {
|
|
track_visit_page($id, $referer);
|
|
}
|
|
|
|
$args = array('visitor' => track_get_visitor_by_id($id));
|
|
EventDispatcher::getInstance()->triggerEvent(Events::VISITOR_CREATE, $args);
|
|
|
|
return $id ? $id : 0;
|
|
}
|
|
|
|
function track_get_visitor_by_id($visitor_id)
|
|
{
|
|
$db = Database::getInstance();
|
|
|
|
return $db->query(
|
|
"SELECT * FROM {sitevisitor} WHERE visitorid = ?",
|
|
array($visitor_id),
|
|
array('return_rows' => Database::RETURN_ONE_ROW)
|
|
);
|
|
}
|
|
|
|
function track_get_visitor_by_thread_id($thread_id)
|
|
{
|
|
$db = Database::getInstance();
|
|
|
|
return $db->query(
|
|
"SELECT * FROM {sitevisitor} WHERE threadid = ?",
|
|
array($thread_id),
|
|
array('return_rows' => Database::RETURN_ONE_ROW)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Load visitor info by user id.
|
|
*
|
|
* @param string $user_id User id
|
|
* @return boolean|array Visitor array or boolean false if visitor not exists
|
|
*/
|
|
function track_get_visitor_by_user_id($user_id)
|
|
{
|
|
$db = Database::getInstance();
|
|
|
|
return $db->query(
|
|
"SELECT * FROM {sitevisitor} WHERE userid = ?",
|
|
array($user_id),
|
|
array('return_rows' => Database::RETURN_ONE_ROW)
|
|
);
|
|
}
|
|
|
|
function track_visit_page($visitor_id, $page)
|
|
{
|
|
$db = Database::getInstance();
|
|
|
|
if (empty($page)) {
|
|
return;
|
|
}
|
|
$last_page = $db->query(
|
|
("SELECT address "
|
|
. "FROM {visitedpage} "
|
|
. "WHERE visitorid = ? "
|
|
. "ORDER BY visittime DESC "
|
|
. "LIMIT 1"),
|
|
array($visitor_id),
|
|
array('return_rows' => Database::RETURN_ONE_ROW)
|
|
);
|
|
if (is_bool($last_page) || ($last_page['address'] != $page)) {
|
|
$db->query(
|
|
("INSERT INTO {visitedpage} ("
|
|
. "visitorid, address, visittime "
|
|
. ") VALUES ( "
|
|
. ":visitorid, :page, :now "
|
|
.")"),
|
|
array(
|
|
':visitorid' => $visitor_id,
|
|
':page' => $page,
|
|
':now' => time(),
|
|
)
|
|
);
|
|
|
|
// If the visitor was invited and he goes to another page the invitation
|
|
// should be automatically rejected.
|
|
$invitation_state = invitation_state($visitor_id);
|
|
if ($invitation_state['invited']) {
|
|
invitation_reject($visitor_id);
|
|
}
|
|
}
|
|
}
|
|
|
|
function track_get_path($visitor)
|
|
{
|
|
$db = Database::getInstance();
|
|
$query_result = $db->query(
|
|
"SELECT address, visittime FROM {visitedpage} WHERE visitorid = ?",
|
|
array($visitor['visitorid']),
|
|
array('return_rows' => Database::RETURN_ALL_ROWS)
|
|
);
|
|
$result = array();
|
|
foreach ($query_result as $page) {
|
|
$result[$page['visittime']] = $page['address'];
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
function track_build_details()
|
|
{
|
|
$result = array(
|
|
'user_agent' => (isset($_SERVER['HTTP_USER_AGENT'])
|
|
? $_SERVER['HTTP_USER_AGENT']
|
|
: ''),
|
|
'remote_host' => get_remote_host(),
|
|
);
|
|
|
|
return serialize($result);
|
|
}
|
|
|
|
function track_retrieve_details($visitor)
|
|
{
|
|
return unserialize($visitor['details']);
|
|
}
|
|
|
|
/**
|
|
* Remove old visitors.
|
|
*
|
|
* Triggers {@link \Mibew\EventDispatcher\Events::VISITOR_DELETE_OLD} event.
|
|
*/
|
|
function track_remove_old_visitors()
|
|
{
|
|
$lock = new ProcessLock('visitors_remove_old');
|
|
if ($lock->get()) {
|
|
// Freeze the time for the whole process
|
|
$now = time();
|
|
|
|
$db = Database::getInstance();
|
|
|
|
// Remove associations of visitors with closed threads
|
|
$db->query(
|
|
"UPDATE {sitevisitor} SET threadid = NULL "
|
|
. "WHERE threadid IS NOT NULL AND "
|
|
. "(SELECT count(*) FROM {thread} "
|
|
. "WHERE threadid = {sitevisitor}.threadid "
|
|
. "AND istate <> " . Thread::STATE_CLOSED . " "
|
|
. "AND istate <> " . Thread::STATE_LEFT . ") = 0 "
|
|
);
|
|
|
|
// Get all visitors that will be removed. They will be used in the
|
|
// "delete" event later.
|
|
$rows = $db->query(
|
|
("SELECT visitorid FROM {sitevisitor} "
|
|
. "WHERE (:now - lasttime) > :lifetime "
|
|
. "AND threadid IS NULL"),
|
|
array(
|
|
':lifetime' => Settings::get('tracking_lifetime'),
|
|
':now' => $now,
|
|
),
|
|
array('return_rows' => Database::RETURN_ALL_ROWS)
|
|
);
|
|
$removed_visitors = array();
|
|
foreach ($rows as $row) {
|
|
$removed_visitors[] = $row['visitorid'];
|
|
}
|
|
|
|
// Remove old visitors
|
|
$db->query(
|
|
("DELETE FROM {sitevisitor} "
|
|
. "WHERE (:now - lasttime) > :lifetime "
|
|
. "AND threadid IS NULL"),
|
|
array(
|
|
':lifetime' => Settings::get('tracking_lifetime'),
|
|
':now' => $now,
|
|
)
|
|
);
|
|
|
|
// Trigger the "delete" event only if visitors was removed.
|
|
if (count($removed_visitors) > 0) {
|
|
$args = array('visitors' => $removed_visitors);
|
|
EventDispatcher::getInstance()->triggerEvent(Events::VISITOR_DELETE_OLD, $args);
|
|
}
|
|
|
|
// Release the lock
|
|
$lock->release();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove old tracks
|
|
*/
|
|
function track_remove_old_tracks()
|
|
{
|
|
$db = Database::getInstance();
|
|
|
|
// Remove old visitors' tracks
|
|
$db->query(
|
|
("DELETE FROM {visitedpage} "
|
|
. "WHERE (:now - visittime) > :lifetime "
|
|
// Remove only tracks that are included in statistics
|
|
. "AND calculated = 1 "
|
|
. "AND visitorid NOT IN (SELECT visitorid FROM {sitevisitor}) "),
|
|
array(
|
|
':lifetime' => Settings::get('tracking_lifetime'),
|
|
':now' => time(),
|
|
)
|
|
);
|
|
}
|
|
|
|
/*
|
|
* Return user id by visitor id.
|
|
*
|
|
* @param int $visitor_id Id of the visitor
|
|
* @return string|boolean user id or boolean false if there is no visitor with
|
|
* specified visitor id
|
|
*/
|
|
function track_get_user_id($visitor_id)
|
|
{
|
|
$visitor = track_get_visitor_by_id($visitor_id);
|
|
if (!$visitor) {
|
|
return false;
|
|
}
|
|
|
|
return $visitor['userid'];
|
|
}
|
|
|
|
/**
|
|
* Bind chat thread with visitor
|
|
*
|
|
* @param string $user_id User ID ({sitevisitor}.userid field) of the
|
|
* visitor.
|
|
* @param Thread $thread Chat thread object
|
|
*/
|
|
function track_visitor_bind_thread($user_id, $thread)
|
|
{
|
|
$db = Database::getInstance();
|
|
$db->query(
|
|
('UPDATE {sitevisitor} '
|
|
. 'SET threadid = :thread_id '
|
|
. 'WHERE userid = :user_id'),
|
|
array(
|
|
':thread_id' => $thread->id,
|
|
':user_id' => $user_id,
|
|
)
|
|
);
|
|
}
|