src/Jobs/Analytics.php
<?php
/*
* This file is part of SeAT
*
* Copyright (C) 2015 to present Leon Jacobs
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
namespace Seat\Services\Jobs;
use GuzzleHttp\Client;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Seat\Services\AbstractSeatPlugin;
use Seat\Services\Helpers\AnalyticsContainer;
use Seat\Services\Settings\Seat;
use Seat\Services\Traits\VersionsManagementTrait;
/**
* Class Analytics.
*
* @package Seat\Services\Jobs
*/
class Analytics implements ShouldQueue
{
use InteractsWithQueue, Queueable, SerializesModels, VersionsManagementTrait;
/**
* The number of times the job may be attempted.
*
* @var int
*/
public $tries = 1;
/**
* @var \Seat\Services\Helpers\AnalyticsContainer
*/
private $hit;
/**
* @var string
*/
private $tracking_id = 'UA-80887494-1';
/**
* @var bool
*/
private $debug;
/**
* Create a new job instance.
*
* @param \Seat\Services\Helpers\AnalyticsContainer $hit
* @param bool $debug
*/
public function __construct(AnalyticsContainer $hit, $debug = false)
{
$this->hit = $hit;
$this->debug = $debug;
}
/**
* Execute the job, keeping in mind that if tracking
* is disabled, nothing should be sent and the
* job should just return.
*
* @return void
*
* @throws \Seat\Services\Exceptions\SettingException
*/
public function handle()
{
// Do nothing if tracking is disabled
if (! $this->allowTracking())
return;
// Send the hit based on the hit type
switch ($this->hit->type) {
case 'event':
$this->sendEvent();
break;
case 'exception':
$this->sendException();
break;
default:
break;
}
}
/**
* Check if tracking is allowed.
*
* @return bool
*
* @throws \Seat\Services\Exceptions\SettingException
*/
public function allowTracking()
{
if (Seat::get('allow_tracking') === 'no')
return false;
return true;
}
/**
* Send an 'event' type hit to GA.
*/
public function sendEvent()
{
$this->send('event', [
'ec' => $this->hit->ec, // Event Category
'ea' => $this->hit->ea, // Event Action
'el' => $this->hit->el, // Event Label
'ev' => $this->hit->ev, // Event Value
]);
}
/**
* Send the GA Hit.
*
* @param $type
* @param array $query
*
* @throws \Seat\Services\Exceptions\SettingException
*/
private function send($type, array $query)
{
$versions = $this->getPluginsMetadataList()->core->map(function (AbstractSeatPlugin $package) {
return sprintf('%s/%s', $package->getPackagistPackageName(), $package->getVersion());
});
$client = new Client([
'base_uri' => 'https://www.google-analytics.com/',
'timeout' => 5.0,
]);
// Check if we are in debug mode
$uri = $this->debug ? '/debug/collect' : '/collect';
// Submit the hit
$client->get($uri, [
'query' => array_merge([
// Fields referenced from:
// https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters
// Required Fields
// https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide#required
'v' => 1, // Protocol Version
'tid' => $this->tracking_id, // Google Tracking-ID
'cid' => $this->getClientID(), // Unique Client-ID
't' => $type, // Event
// Optional Fields
'aip' => 1, // Anonymize the IP of the calling client
'an' => 'SeAT', // App Name
// Versions of the currently installed packages.
'av' => $versions->implode(', '),
// User Agent is comprised of OS Name(s), Release(r)
// and Machine Type(m). Examples:
// Darwin/15.6.0/x86_64
// Linux/2.6.32-642.el6.x86_64/x86_64
//
// See:
// http://php.net/manual/en/function.php-uname.php
'ua' => 'SeAT/' . php_uname('s') .
'/' . php_uname('r') .
'/' . php_uname('m'),
'z' => rand(1, 10000), // Cache Busting Random Value
], $query),
]);
}
/**
* Query the eveseat/resources repository for SDE
* related information.
*
* @return mixed|string
*
* @throws \Seat\Services\Exceptions\SettingException
*/
private function getClientID()
{
$id = Seat::get('analytics_id');
if (! $id) {
// Generate a V4 random UUID
// https://gist.github.com/dahnielson/508447#file-uuid-php-L74
$id = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand(0, 0xFFFF), mt_rand(0, 0xFFFF),
mt_rand(0, 0xFFFF),
mt_rand(0, 0x0FFF) | 0x4000,
mt_rand(0, 0x3FFF) | 0x8000,
mt_rand(0, 0xFFFF), mt_rand(0, 0xFFFF), mt_rand(0, 0xFFFF)
);
// Set the generated UUID in the applications config
Seat::set('analytics_id', $id);
}
return $id;
}
/**
* Send an 'exception' type hit to GA.
*/
public function sendException()
{
$this->send('exception', [
'exd' => $this->hit->exd, // Exception Description
'exf' => $this->hit->exf, // Is Fatal Exception?
]);
}
}