sfneal /
tracking
| 1 | <?php |
||||
| 2 | |||||
| 3 | namespace Sfneal\Tracking\Actions; |
||||
| 4 | |||||
| 5 | use Illuminate\Http\RedirectResponse; |
||||
| 6 | use Illuminate\Http\Request; |
||||
| 7 | use Illuminate\Http\Response; |
||||
| 8 | use Illuminate\Support\Facades\Cookie; |
||||
| 9 | use Jenssegers\Agent\Agent; |
||||
| 10 | use Sfneal\Actions\Action; |
||||
| 11 | use Sfneal\Helpers\Arrays\ArrayHelpers; |
||||
| 12 | use Sfneal\Helpers\Laravel\AppInfo; |
||||
| 13 | |||||
| 14 | class ParseTraffic extends Action |
||||
| 15 | { |
||||
| 16 | /** |
||||
| 17 | * Array keys to exclude from the 'request_payload' attribute. |
||||
| 18 | * |
||||
| 19 | * @var array |
||||
| 20 | */ |
||||
| 21 | private const REQUEST_PAYLOAD_EXCLUSIONS = [ |
||||
| 22 | '_token', |
||||
| 23 | '_method', |
||||
| 24 | 'password', |
||||
| 25 | ]; |
||||
| 26 | |||||
| 27 | /** |
||||
| 28 | * @var array |
||||
| 29 | */ |
||||
| 30 | private $tracking = []; |
||||
| 31 | |||||
| 32 | /** |
||||
| 33 | * @var Request |
||||
| 34 | */ |
||||
| 35 | private $request; |
||||
| 36 | /** |
||||
| 37 | * @var Response|RedirectResponse |
||||
| 38 | */ |
||||
| 39 | private $response; |
||||
| 40 | |||||
| 41 | /** |
||||
| 42 | * @var string |
||||
| 43 | */ |
||||
| 44 | private $timestamp; |
||||
| 45 | |||||
| 46 | /** |
||||
| 47 | * Create a new event instance. |
||||
| 48 | * |
||||
| 49 | * @param Request $request |
||||
| 50 | * @param Response|RedirectResponse $response |
||||
| 51 | * @param string|null $timestamp |
||||
| 52 | */ |
||||
| 53 | public function __construct(Request $request, $response, string $timestamp = null) |
||||
| 54 | { |
||||
| 55 | $this->request = $request; |
||||
| 56 | $this->response = $response; |
||||
| 57 | $this->timestamp = $timestamp ?? microtime(); |
||||
| 58 | } |
||||
| 59 | |||||
| 60 | /** |
||||
| 61 | * Execute the action. |
||||
| 62 | * |
||||
| 63 | * @return array |
||||
| 64 | */ |
||||
| 65 | public function execute(): array |
||||
| 66 | { |
||||
| 67 | // Initialize event for serialization |
||||
| 68 | $this->tracking['user_id'] = intval(auth()->id()); |
||||
| 69 | $this->tracking['session_id'] = Cookie::get(config('session.cookie')); |
||||
| 70 | $this->tracking['app_version'] = AppInfo::version(); |
||||
| 71 | $this->tracking['time_stamp'] = self::getTimestamp($this->timestamp); |
||||
| 72 | |||||
| 73 | // Request data |
||||
| 74 | $this->tracking['request'] = $this->parseRequest(); |
||||
| 75 | |||||
| 76 | // Response data |
||||
| 77 | $this->tracking['response'] = $this->parseResponse(); |
||||
| 78 | |||||
| 79 | // Request data |
||||
| 80 | $this->tracking['agent'] = $this->parseAgent(); |
||||
| 81 | |||||
| 82 | return $this->tracking; |
||||
| 83 | } |
||||
| 84 | |||||
| 85 | /** |
||||
| 86 | * Parse a Request object to retrieve relevant data. |
||||
| 87 | * |
||||
| 88 | * @return array |
||||
| 89 | */ |
||||
| 90 | public function parseRequest(): array |
||||
| 91 | { |
||||
| 92 | return [ |
||||
| 93 | 'host' => $this->request->getHttpHost(), |
||||
| 94 | 'uri' => $this->request->getRequestUri(), |
||||
| 95 | 'method' => $this->request->getMethod(), |
||||
| 96 | 'payload' => $this->getRequestPayload(), |
||||
| 97 | 'browser' => $_SERVER['HTTP_USER_AGENT'] ?? null, |
||||
| 98 | 'ip' => $this->request->ip(), |
||||
| 99 | 'referrer' => $_SERVER['HTTP_REFERER'] ?? null, |
||||
| 100 | 'token' => $this->request->get('track_traffic_token') ?? uniqid(), |
||||
| 101 | ]; |
||||
| 102 | } |
||||
| 103 | |||||
| 104 | /** |
||||
| 105 | * Parse a Response object to retrieve relevant data. |
||||
| 106 | * |
||||
| 107 | * @return array |
||||
| 108 | */ |
||||
| 109 | public function parseResponse(): array |
||||
| 110 | { |
||||
| 111 | // Status code & response time |
||||
| 112 | $response = [ |
||||
| 113 | 'code' => $this->response->getStatusCode(), |
||||
| 114 | 'time' => self::getResponseTime($this->timestamp), |
||||
| 115 | ]; |
||||
| 116 | |||||
| 117 | // Store response content served if enabled |
||||
| 118 | if (config('tracking.traffic.response_content')) { |
||||
| 119 | $response['content'] = $this->response->getContent(); |
||||
| 120 | } |
||||
| 121 | |||||
| 122 | return $response; |
||||
| 123 | } |
||||
| 124 | |||||
| 125 | /** |
||||
| 126 | * Set user agent data on platform, device & browser. |
||||
| 127 | * |
||||
| 128 | * @return array |
||||
| 129 | */ |
||||
| 130 | public function parseAgent(): array |
||||
| 131 | { |
||||
| 132 | $agent = new Agent(); |
||||
| 133 | |||||
| 134 | return [ |
||||
| 135 | 'platform' => $agent->platform(), |
||||
| 136 | 'device' => $agent->device(), |
||||
| 137 | 'browser' => $agent->browser(), |
||||
| 138 | ]; |
||||
| 139 | } |
||||
| 140 | |||||
| 141 | /** |
||||
| 142 | * Retrieve a request payload with exclusions removed. |
||||
| 143 | * |
||||
| 144 | * @return array |
||||
| 145 | */ |
||||
| 146 | private function getRequestPayload(): array |
||||
| 147 | { |
||||
| 148 | return ArrayHelpers::from($this->request->query()) |
||||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
| 149 | ->merge($this->request->input()) |
||||
| 150 | ->removeKeys(self::REQUEST_PAYLOAD_EXCLUSIONS) |
||||
| 151 | ->get(); |
||||
| 152 | } |
||||
| 153 | |||||
| 154 | /** |
||||
| 155 | * Determine the amount of time taken to return a response. |
||||
| 156 | * |
||||
| 157 | * @param string $timestamp |
||||
| 158 | * @return float |
||||
| 159 | */ |
||||
| 160 | private static function getResponseTime(string $timestamp): float |
||||
| 161 | { |
||||
| 162 | return floatval(number_format($timestamp - LARAVEL_START, 2)); |
||||
| 163 | } |
||||
| 164 | |||||
| 165 | /** |
||||
| 166 | * Retrieve a traffic visit occurred at timestamp. |
||||
| 167 | * |
||||
| 168 | * @param string $timestamp |
||||
| 169 | * @return string |
||||
| 170 | */ |
||||
| 171 | private static function getTimestamp(string $timestamp): string |
||||
| 172 | { |
||||
| 173 | return date('Y-m-d H:i:s', $timestamp); |
||||
|
0 ignored issues
–
show
$timestamp of type string is incompatible with the type integer|null expected by parameter $timestamp of date().
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 174 | } |
||||
| 175 | } |
||||
| 176 |