| Current Path : /home/poneycluc/www/plugins/system/bfnetwork/bfnetwork/ |
| Current File : /home/poneycluc/www/plugins/system/bfnetwork/bfnetwork/bfActivitylog.php |
<?php
/*
* @package bfNetwork
* @copyright Copyright (C) 2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022,2023,2024,2025,2026 Blue Flame Digital Solutions Ltd. All rights reserved.
* @license GNU General Public License version 3 or later
*
* @see https://mySites.guru/
* @see https://www.phil-taylor.com/
*
* @author Phil Taylor / Blue Flame Digital Solutions Limited.
*
* bfNetwork 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 3 of the License, or
* (at your option) any later version.
*
* bfNetwork 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.
*
* You should have received a copy of the GNU General Public License
* along with this package. If not, see http://www.gnu.org/licenses/
*
* If you have any questions regarding this code, please contact phil@phil-taylor.com
*/
use Joomla\CMS\Factory;
use Joomla\CMS\Uri\Uri;
require_once 'bfPreferences.php';
class bfActivitylog
{
protected static $instance;
private $db;
private $table_create = 'CREATE TABLE IF NOT EXISTS `bf_activitylog` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`who` varchar(255) DEFAULT NULL,
`who_id` int(11) DEFAULT NULL,
`what` varchar(255) DEFAULT NULL,
`when` datetime DEFAULT NULL,
`where` varchar(255) DEFAULT NULL,
`where_id` int(11) DEFAULT NULL,
`ip` varchar(255) DEFAULT NULL,
`useragent` varchar(255) DEFAULT NULL,
`constkey` varchar(255) DEFAULT NULL,
`meta` text,
`action` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `who` (`who`),
KEY `who_id` (`who_id`),
KEY `when` (`when`)
) DEFAULT CHARSET=utf8';
private $table_insert = 'INSERT INTO `bf_activitylog`
(`id`, `who`, `who_id`, `what`, `when`, `where`, `where_id`, `ip`, `useragent`, `meta`,`action`,`constkey`)
VALUES
(NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)';
private $core_table_insert = 'INSERT INTO `#__action_logs` (`id`, `message_language_key`, `message`, `log_date`, `extension`, `user_id`, `item_id`, `ip_address`)
VALUES (NULL, %s, \'{}\', %s, \'mySites.guru\', 0, 0, %s)';
private $prefs;
/**
* @var \bfPreferences
*/
private $preferences;
public function __construct()
{
try {
$this->preferences = new bfPreferences();
$this->prefs = $this->preferences->getPreferences();
$this->db = Factory::getContainer()->get('DatabaseDriver');
$this->ensureTableCreated();
} catch (Exception $exception) {
//ignore failure as not to output anything to the public website
}
}
public function ensureTableCreated()
{
$this->db->setQuery($this->table_create);
$this->db->execute();
}
/**
* @return bfActivitylog
*/
public static function getInstance()
{
if (! isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
/**
* If we get here we are "inside" the Joomla Application API and so all Joomla functions available.
*
* @param string $who
* @param int $who_id
* @param string $what
* @param string $where
* @param int $where_id
* @param null $ip
* @param null $userAgent
*/
public function log(
$who = 'not me!',
$who_id = 0,
$what = 'dunno',
$where = 'er?',
$where_id = 0,
$ip = null,
$userAgent = null,
$meta = '{}',
$action = '',
$alertName = '',
$constKey = 'legacy',
$when = null
) {
try {
if (null === $when) {
$when = (new DateTime('now', new DateTimeZone('UTC')))->format('Y-m-d H:i:s');
}
if (! (int) $who_id) {
$who_id = 0;
}
if (! (int) $where_id) {
$where_id = 0;
}
if (null == $ip) {
$ip = str_replace('::ffff:', '', (@getenv('HTTP_X_FORWARDED_FOR') ?: @$_SERVER['REMOTE_ADDR']));
}
if ('system' == $ip) {
$ip = '';
}
if (! $userAgent && is_array($_SERVER) && array_key_exists('HTTP_USER_AGENT', $_SERVER)) {
$agent = $_SERVER['HTTP_USER_AGENT'];
if (! $agent) {
$agent = 'Unknown';
}
} else {
$agent = $userAgent;
}
// Use mySites.guru Activity Log
$sql = sprintf(
$this->table_insert,
$this->db->quote($who),
$this->db->quote($who_id),
$this->db->quote($what),
$this->db->quote($when),
$this->db->quote($where),
$this->db->quote($where_id),
$this->db->quote($ip),
$this->db->quote($agent),
$this->db->quote($meta),
$this->db->quote($action),
$this->db->quote($constKey)
);
$this->db->setQuery($sql);
$this->db->execute();
// Use Joomla core Activity Log
$sql = sprintf(
$this->core_table_insert,
$this->db->quote('[mySites.guru] ' . $what),
$this->db->quote($when),
$this->db->quote($ip)
);
$this->db->setQuery($sql);
$this->db->execute();
$host_id = $this->getHostID();
if (! $host_id) {
return;
}
$data = [
'HOST_ID' => $host_id,
'who' => $who,
'who_id' => $who_id,
'what' => $what,
'when' => $when,
'where' => $where,
'where_id' => $where_id,
'ip' => $ip,
'userAgent' => $userAgent,
'meta' => $meta,
'action' => $action,
'alert_name' => $alertName,
];
// Always attempt
$this->sendToSpy($data);
if (property_exists($this->prefs, $alertName) && $this->prefs->$alertName == 1) {
if (! $this->sendLogAlert($data)) {
$this->preferences->updatePreference($alertName, 0);
}
}
} catch (Exception $exception) {
//ignore failure as not to output anything to the public website
}
}
/**
* @param mixed[] $data
* @return string|void
*/
public function sendLogAlert($data)
{
$opts = [
'http' => [
'content' => http_build_query($data),
'method' => 'POST',
'user_agent' => Uri::base(),
'max_redirects' => 1,
'header' => 'Content-type: application/x-www-form-urlencoded',
'proxy' => ('local' === getenv('APPLICATION_ENV') ? 'tcp://host.docker.internal:8888' : ''),
'timeout' => 5, //so we don't destroy live sites if the service is offline
],
];
if ('local' === getenv('APPLICATION_ENV')) {
// Allow bad certs in development mode
$opts = array_merge($opts, [
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
],
]);
// Using @ so we don't destroy live sites if the service is offline
return @file_get_contents('https://dev.mysites.guru/api/log', false, stream_context_create($opts));
}
// Using @ so we don't destroy live sites if the service is offline
return @file_get_contents('https://manage.mysites.guru/api/log', false, stream_context_create($opts));
}
/**
* @return string|bool
*/
public function getHostID()
{
$files = [
str_replace(
['/administrator', '\administrator'],
'',
JPATH_BASE . '/plugins/system/bfnetwork/HOST_ID'
), //Joomla 1.5 gulp
str_replace(['/administrator', '\administrator'], '', JPATH_BASE . '/plugins/system/bfnetwork/bfnetwork/HOST_ID'), //Joomla 2+
];
foreach ($files as $file) {
if (file_exists($file)) {
return file_get_contents($file);
}
}
return false;
}
/**
* Realtime Log Viewer Integration.
*/
private function sendToSpy(array $data): void
{
if (! file_exists(__DIR__ . '/tmp/realtime.php')) {
return;
}
$opts = [
'http' => [
'content' => json_encode($data),
'method' => 'POST',
'user_agent' => Uri::base(),
'max_redirects' => 1,
'header' => 'Content-type: application/x-www-form-urlencoded',
'proxy' => ('local' == getenv('APPLICATION_ENV') ? 'tcp://host.docker.internal:8888' : ''),
'timeout' => 5, //so we don't destroy live sites if the service is offline
],
];
// decode configuration
$realTimeConfig = json_decode(file_get_contents(__DIR__ . '/tmp/realtime.php'));
// check if realtime is still active
if (time() < $realTimeConfig->until) {
// dev mode ignore SSL unsigned
if (strpos($realTimeConfig->endpoint, 'dev')) {
$opts = array_merge($opts, [
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
],
]);
}
/*
* Push data to tmp endpoint for this site
* Using @ so we don't destroy live sites if the service is offline
*/
@file_get_contents($realTimeConfig->endpoint, false, stream_context_create($opts));
} else {
// expired, delete file
@unlink(__DIR__ . '/tmp/realtime.php');
}
}
}