fix: move analytics to helper

This commit is contained in:
Benjamin Bellamy 2020-06-14 15:45:42 +00:00 committed by Yassine Doghri
parent 13be386842
commit d31191732e
6 changed files with 256 additions and 142 deletions

View File

@ -11,103 +11,40 @@ use CodeIgniter\Controller;
class Analytics extends Controller
{
function __construct()
{
$session = \Config\Services::session();
$session->start();
$db = \Config\Database::connect();
$country = 'N/A';
/**
* An array of helpers to be loaded automatically upon
* class instantiation. These helpers will be available
* to all other controllers that extend Analytics.
*
* @var array
*/
protected $helpers = ['analytics'];
// Finds country:
if (!$session->has('country')) {
try {
$reader = new \GeoIp2\Database\Reader(
WRITEPATH . 'uploads/GeoLite2-Country/GeoLite2-Country.mmdb'
);
$geoip = $reader->country($_SERVER['REMOTE_ADDR']);
$country = $geoip->country->isoCode;
} catch (\Exception $e) {
// If things go wrong the show must go on and the user must be able to download the file
}
$session->set('country', $country);
}
/**
* Constructor.
*/
public function initController(
\CodeIgniter\HTTP\RequestInterface $request,
\CodeIgniter\HTTP\ResponseInterface $response,
\Psr\Log\LoggerInterface $logger
) {
// Do Not Edit This Line
parent::initController($request, $response, $logger);
// Finds player:
if (!$session->has('player')) {
$playerName = '-unknown-';
$error = '';
//--------------------------------------------------------------------
// Preload any models, libraries, etc, here.
//--------------------------------------------------------------------
// E.g.:
// $this->session = \Config\Services::session();
try {
$useragent = $_SERVER['HTTP_USER_AGENT'];
$jsonUserAgents = json_decode(
file_get_contents(
WRITEPATH . 'uploads/user-agents/src/user-agents.json'
),
true
);
//Search for current HTTP_USER_AGENT in json file:
foreach ($jsonUserAgents as $player) {
foreach ($player['user_agents'] as $useragentsRegexp) {
//Does the HTTP_USER_AGENT match this regexp:
if (preg_match("#{$useragentsRegexp}#", $useragent)) {
if (isset($player['bot'])) {
//Its a bot!
$playerName = '-bot-';
} else {
//It isnt a bot, we store device/os/app:
$playerName =
(isset($player['device'])
? $player['device'] . '/'
: '') .
(isset($player['os'])
? $player['os'] . '/'
: '') .
(isset($player['app'])
? $player['app']
: '?');
}
//We found it!
break 2;
}
}
}
} catch (\Exception $e) {
// If things go wrong the show must go on and the user must be able to download the file
}
if ($playerName == '-unknown-') {
// Add to unknown list
try {
$procedureNameAUU = $db->prefixTable(
'analytics_unknown_useragents'
);
$db->query("CALL $procedureNameAUU(?)", [$useragent]);
} catch (\Exception $e) {
// If things go wrong the show must go on and the user must be able to download the file
}
}
$session->set('player', $playerName);
}
set_user_session_country();
set_user_session_player();
}
// Add one hit to this episode:
public function hit($p_podcast_id, $p_episode_id, ...$filename)
{
$session = \Config\Services::session();
$db = \Config\Database::connect();
$procedureName = $db->prefixTable('analytics_podcasts');
$p_country_code = $session->get('country');
$p_player = $session->get('player');
try {
$db->query("CALL $procedureName(?,?,?,?);", [
$p_podcast_id,
$p_episode_id,
$p_country_code,
$p_player,
]);
} catch (\Exception $e) {
// If things go wrong the show must go on and the user must be able to download the file
}
podcast_hit($p_podcast_id, $p_episode_id);
return redirect()->to(media_url(implode('/', $filename)));
}
}

View File

@ -26,7 +26,7 @@ class BaseController extends Controller
*
* @var array
*/
protected $helpers = [];
protected $helpers = ['analytics'];
/**
* Constructor.
@ -45,55 +45,13 @@ class BaseController extends Controller
// E.g.:
// $this->session = \Config\Services::session();
$session = \Config\Services::session();
$session->start();
// Defines country
if (!$session->has('country')) {
try {
$reader = new \GeoIp2\Database\Reader(
WRITEPATH . 'uploads/GeoLite2-Country/GeoLite2-Country.mmdb'
);
$geoip = $reader->country($_SERVER['REMOTE_ADDR']);
$session->set('country', $geoip->country->isoCode);
} catch (\Exception $e) {
$session->set('country', 'N/A');
}
}
// Defines browser
if (!$session->has('browser')) {
try {
$whichbrowser = new \WhichBrowser\Parser(getallheaders());
$session->set('browser', $whichbrowser->browser->name);
} catch (\Exception $e) {
$session->set('browser', 'Other');
}
}
// Defines referrer
$newreferer = isset($_SERVER['HTTP_REFERER'])
? parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST)
: '- Direct -';
$newreferer =
$newreferer == parse_url(current_url(false), PHP_URL_HOST)
? '- Direct -'
: $newreferer;
if (!$session->has('referer') or $newreferer != '- Direct -') {
$session->set('referer', $newreferer);
}
set_user_session_country();
set_user_session_browser();
set_user_session_referer();
}
protected function stats($postcast_id)
{
$session = \Config\Services::session();
$session->start();
$db = \Config\Database::connect();
$procedureName = $db->prefixTable('analytics_website');
$db->query("call $procedureName(?,?,?,?)", [
$postcast_id,
$session->get('country'),
$session->get('browser'),
$session->get('referer'),
]);
webpage_hit($postcast_id);
}
}

View File

@ -0,0 +1,191 @@
<?php
/**
* @copyright 2020 Podlibre
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
/**
* Set user country in session variable, for analytics purpose
*/
function set_user_session_country()
{
$session = \Config\Services::session();
$session->start();
$db = \Config\Database::connect();
$country = 'N/A';
// Finds country:
if (!$session->has('country')) {
try {
$reader = new \GeoIp2\Database\Reader(
WRITEPATH . 'uploads/GeoLite2-Country/GeoLite2-Country.mmdb'
);
$geoip = $reader->country($_SERVER['REMOTE_ADDR']);
$country = $geoip->country->isoCode;
} catch (\Exception $e) {
// If things go wrong the show must go on and the user must be able to download the file
}
$session->set('country', $country);
}
}
/**
* Set user player in session variable, for analytics purpose
*/
function set_user_session_player()
{
$session = \Config\Services::session();
$session->start();
if (!$session->has('player')) {
$session = \Config\Services::session();
$session->start();
$playerName = '- Unknown Player -';
$useragent = $_SERVER['HTTP_USER_AGENT'];
try {
$jsonUserAgents = json_decode(
file_get_contents(
WRITEPATH . 'uploads/user-agents/src/user-agents.json'
),
true
);
//Search for current HTTP_USER_AGENT in json file:
foreach ($jsonUserAgents as $player) {
foreach ($player['user_agents'] as $useragentsRegexp) {
//Does the HTTP_USER_AGENT match this regexp:
if (preg_match("#{$useragentsRegexp}#", $useragent)) {
if (isset($player['bot'])) {
//Its a bot!
$playerName = '- Bot -';
} else {
//It isnt a bot, we store device/os/app:
$playerName =
(isset($player['device'])
? $player['device'] . '/'
: '') .
(isset($player['os'])
? $player['os'] . '/'
: '') .
(isset($player['app']) ? $player['app'] : '?');
}
//We found it!
break 2;
}
}
}
} catch (\Exception $e) {
// If things go wrong the show must go on and the user must be able to download the file
}
if ($playerName == '- Unknown Player -') {
// Add to unknown list
try {
$db = \Config\Database::connect();
$procedureNameAUU = $db->prefixTable(
'analytics_unknown_useragents'
);
$db->query("CALL $procedureNameAUU(?)", [$useragent]);
} catch (\Exception $e) {
// If things go wrong the show must go on and the user must be able to download the file
}
}
$session->set('player', $playerName);
}
}
/**
* Set user browser in session variable, for analytics purpose
*/
function set_user_session_browser()
{
$session = \Config\Services::session();
$session->start();
if (!$session->has('browser')) {
$browserName = '- Other -';
try {
$whichbrowser = new \WhichBrowser\Parser(getallheaders());
$browserName = $whichbrowser->browser->name;
} catch (\Exception $e) {
$browserName = '- Could not get browser name -';
}
if ($browserName == null) {
$browserName = '- Could not get browser name -';
}
$session->set('browser', $browserName);
}
}
/**
* Set user referer in session variable, for analytics purpose
*/
function set_user_session_referer()
{
$session = \Config\Services::session();
$session->start();
$newreferer = isset($_SERVER['HTTP_REFERER'])
? parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST)
: '- Direct -';
$newreferer =
$newreferer == parse_url(current_url(false), PHP_URL_HOST)
? '- Direct -'
: $newreferer;
if (!$session->has('referer') or $newreferer != '- Direct -') {
$session->set('referer', $newreferer);
}
}
function webpage_hit($postcast_id)
{
$session = \Config\Services::session();
$session->start();
$db = \Config\Database::connect();
$procedureName = $db->prefixTable('analytics_website');
$db->query("call $procedureName(?,?,?,?)", [
$postcast_id,
$session->get('country'),
$session->get('browser'),
$session->get('referer'),
]);
}
function podcast_hit($p_podcast_id, $p_episode_id)
{
$session = \Config\Services::session();
$session->start();
$first_time_for_this_episode = true;
if ($session->has('episodes')) {
if (in_array($p_episode_id, $session->get('episodes'))) {
$first_time_for_this_episode = false;
} else {
$session->push('episodes', [$p_episode_id]);
}
} else {
$session->set('episodes', [$p_episode_id]);
}
if ($first_time_for_this_episode) {
$db = \Config\Database::connect();
$procedureName = $db->prefixTable('analytics_podcasts');
try {
$db->query("CALL $procedureName(?,?,?,?);", [
$p_podcast_id,
$p_episode_id,
$session->get('country'),
$session->get('player'),
]);
} catch (\Exception $e) {
// If things go wrong the show must go on and the user must be able to download the file
}
}
}

View File

@ -16,3 +16,23 @@ function media_url($uri = '', string $protocol = null): string
{
return base_url(config('App')->mediaRoot . '/' . $uri, $protocol);
}
/**
* Return the podcast URL to use in views
*
* @param mixed $uri URI string or array of URI segments
* @param string $protocol
* @return string
*/
function podcast_url(
$podcast_id = 1,
$episode_id = 1,
$podcast_name = '',
$uri = '',
string $protocol = null
): string {
return base_url(
"/stats/$podcast_id/$episode_id/$podcast_name/$uri",
$protocol
);
}

View File

@ -6,11 +6,15 @@
<img src="<?= media_url(
$episode->image ? $episode->image : $podcast->image
) ?>" alt="Episode cover" class="object-cover w-40 h-40 mb-6" />
<audio controls>
<source src="<?= media_url(
<audio controls preload="none">
<source src="<?= podcast_url(
$episode->podcast_id,
$episode->id,
$podcast->name,
$episode->enclosure_url
) ?>" type="<?= $episode->enclosure_type ?>">
Your browser does not support the audio tag.
</audio>
<?= $this->endSection() ?>
<?= $this->endSection()
?>

View File

@ -34,8 +34,11 @@
</h3>
<p><?= $episode->description ?></p>
</a>
<audio controls class="mt-auto">
<source src="<?= media_url(
<audio controls class="mt-auto" preload="none">
<source src="<?= podcast_url(
$episode->podcast_id,
$episode->id,
$podcast->name,
$episode->enclosure_url
) ?>" type="<?= $episode->enclosure_type ?>">
Your browser does not support the audio tag.
@ -49,4 +52,5 @@
</section>
<?= $this->endSection() ?>
<?= $this->endSection()
?>