Loading app/Controllers/Analytics.php +26 −89 Original line number Diff line number Diff line Loading @@ -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'; // 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); } /** * 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 player: if (!$session->has('player')) { $playerName = '-unknown-'; $error = ''; /** * 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); try { $useragent = $_SERVER['HTTP_USER_AGENT']; $jsonUserAgents = json_decode( file_get_contents( WRITEPATH . 'uploads/user-agents/src/user-agents.json' ), true ); //-------------------------------------------------------------------- // Preload any models, libraries, etc, here. //-------------------------------------------------------------------- // E.g.: // $this->session = \Config\Services::session(); //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'])) { //It’s a bot! $playerName = '-bot-'; } else { //It isn’t 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))); } } app/Controllers/BaseController.php +5 −47 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ class BaseController extends Controller * * @var array */ protected $helpers = []; protected $helpers = ['analytics']; /** * Constructor. Loading @@ -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); } } app/Helpers/analytics_helper.php 0 → 100644 +191 −0 Original line number Diff line number Diff line <?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'])) { //It’s a bot! $playerName = '- Bot -'; } else { //It isn’t 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 } } } app/Helpers/url_helper.php +20 −0 Original line number Diff line number Diff line Loading @@ -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 ); } app/Views/episodes/view.php +7 −3 Original line number Diff line number Diff line Loading @@ -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() ?> Loading
app/Controllers/Analytics.php +26 −89 Original line number Diff line number Diff line Loading @@ -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'; // 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); } /** * 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 player: if (!$session->has('player')) { $playerName = '-unknown-'; $error = ''; /** * 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); try { $useragent = $_SERVER['HTTP_USER_AGENT']; $jsonUserAgents = json_decode( file_get_contents( WRITEPATH . 'uploads/user-agents/src/user-agents.json' ), true ); //-------------------------------------------------------------------- // Preload any models, libraries, etc, here. //-------------------------------------------------------------------- // E.g.: // $this->session = \Config\Services::session(); //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'])) { //It’s a bot! $playerName = '-bot-'; } else { //It isn’t 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))); } }
app/Controllers/BaseController.php +5 −47 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ class BaseController extends Controller * * @var array */ protected $helpers = []; protected $helpers = ['analytics']; /** * Constructor. Loading @@ -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); } }
app/Helpers/analytics_helper.php 0 → 100644 +191 −0 Original line number Diff line number Diff line <?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'])) { //It’s a bot! $playerName = '- Bot -'; } else { //It isn’t 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 } } }
app/Helpers/url_helper.php +20 −0 Original line number Diff line number Diff line Loading @@ -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 ); }
app/Views/episodes/view.php +7 −3 Original line number Diff line number Diff line Loading @@ -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() ?>