podcast_publisher-1.0.0-alpha3/modules/podcast_publisher_analytics/src/StackMiddleware/DownloadIntentTracker.php
modules/podcast_publisher_analytics/src/StackMiddleware/DownloadIntentTracker.php
<?php
namespace Drupal\podcast_publisher_analytics\StackMiddleware;
use Drupal\Core\Queue\QueueFactory;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\HttpKernelInterface;
/**
* Creates download intent queue item on requests of podcast episodes.
*/
class DownloadIntentTracker implements HttpKernelInterface {
/**
* The wrapped HTTP kernel.
*
* @var \Symfony\Component\HttpKernel\HttpKernelInterface
*/
protected $httpKernel;
/**
* The queue factory.
*
* @var \Drupal\Core\Queue\QueueFactory
*/
protected $queueFactory;
/**
* Constructor.
*
* @param \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel
* The wrapped HTTP kernel.
* @param \Drupal\Core\Queue\QueueFactory $queue_factory
* The queue factory.
*/
public function __construct(HttpKernelInterface $http_kernel, QueueFactory $queue_factory) {
$this->httpKernel = $http_kernel;
$this->queueFactory = $queue_factory;
}
/**
* {@inheritdoc}
*/
public function handle(Request $request, $type = self::MAIN_REQUEST, $catch = TRUE): Response {
$path = $request->getPathInfo();
// Ignore on all other paths.
if (strpos($path, '/podcast-publisher/') !== 0) {
return $this->httpKernel->handle($request, $type, $catch);
}
// /podcast-publisher/{source}/{podcast-episode-id}/{file-id}/path/to/file.
$path_array = explode('/', substr($path, 1));
$redirect_path_array = array_filter($path_array, function ($i) {
return $i > 3;
}, ARRAY_FILTER_USE_KEY);
$redirect_url = '/' . implode('/', $redirect_path_array);
// Check if file exists.
if ($external_host = $request->query->get('external_host')) {
$redirect_url = $request->getScheme() . '://' . $external_host . $redirect_url;
}
elseif (!is_file(\Drupal::root() . urldecode($redirect_url))) {
throw new NotFoundHttpException();
}
// Do not track HEAD request.
if ($request->getMethod() !== 'HEAD') {
$this->trackDownload($request, $path_array[1], $path_array[2], $path_array[3]);
}
$response_code = $request->server->get('SERVER_PROTOCOL') == 'HTTP/1.0' ? 301 : 307;
return new RedirectResponse($redirect_url, $response_code);
}
/**
* Queues the data.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The request.
* @param string $source
* The source.
* @param int $episode_id
* The episode id.
* @param int $file_id
* The file id.
*/
protected function trackDownload(Request $request, $source, $episode_id, $file_id) {
$queue_item = [
'request_method' => $request->getMethod(),
'user_agent' => $request->server->get('HTTP_USER_AGENT'),
'ip' => $request->server->get('HTTP_X_FORWARDED_FOR') ?? $request->server->get('REMOTE_ADDR'),
'source' => $source,
'episode_id' => $episode_id,
'file_id' => $file_id,
'timestamp' => $request->server->get('REQUEST_TIME'),
];
if ($http_range = $request->server->get('HTTP_RANGE')) {
$queue_item['httprange'] = $http_range;
}
$this->queueFactory
->get('podcast_download_intent_tracker')
->createItem($queue_item);
}
}
