<?php
namespace App\Event;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\HttpFoundation\Session;
//use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use \DateTime as DateTime;
//use App\Utils\UserHelper;
use App\Utils\ContentHelper;
use App\Entity\Content;
use App\Entity\Traffic;
use App\Entity\TrafficData;
use App\Entity\ContentView;
use App\Entity\SiteConfig;
use App\Entity\User;
class RouteListener
{
//protected $userHelper;
protected $entityManager;
protected $contentHelper;
protected $tokenStorage;
public function __construct (
//UserHelper $userHelper,
ContentHelper $contentHelper,
EntityManagerInterface $entityManager,
TokenStorageInterface $tokenStorage
){
//$this->userHelper = $userHelper;
$this->contentHelper = $contentHelper;
$this->entityManager = $entityManager;
$this->tokenStorage = $tokenStorage;
}
public function onKernelRequest (
RequestEvent $event
) {
//Temporary CCS redirect:
/*
//Fix issues with dev bar not showing up (bc vars declared twice?)
$request = $event->getRequest();
$site_host = $request->getHost();
$site = SiteConfig::getSiteIdFromURL($site_host);
$routeName = $request->get("_route");
if ($this->tokenStorage->getToken()) {
$user = $this->tokenStorage->getToken()->getUser();
} else {
$user = null;
}
if (is_string($user)) {
$user = null;
}
if($site == Content::SITE_CCS && $routeName != "sign-in_ccs" && $routeName != "coming-soon_ccs" && (!$user || (!$user->isAdmin()))) {
$event->setResponse(new RedirectResponse("/coming-soon"));
}
elseif($site == Content::SITE_CCS && $routeName == "coming-soon_ccs" && $user && ($user->isAdmin())) {
$event->setResponse(new RedirectResponse("/"));
}
*/
/*
var_dump("event handler");
exit;
*/
//Ran from a cron job now. See Command/UpdatePublishedExpiredContentCommand.php
/*
$this->contentHelper->updatePublished();
$this->contentHelper->updateExpired();
$this->contentHelper->updateExpiredAnnouncements();
*/
//Ran from a cron job now. See Command/UpdatePurchaseItemsCommand.php
//$this->orderHelper->updateExpiredPurchaseItems();
$request = $event->getRequest();
$session = $request->getSession();
if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST ||
strpos($event->getRequest()->getPathInfo(), "_wdt") !== false
) {
return;
}
$routeName = $request->get("_route");
$routeParams = $request->get("_route_params");
$path = $request->getPathInfo();
if ($this->tokenStorage->getToken()) {
$user = $this->tokenStorage->getToken()->getUser();
} else {
$user = null;
}
if (is_string($user)) {
$user = null;
}
// ==================================================
// Log the traffic request
// Should modify and use ContentHelper's addImpression function instead of doing here
// $temp = $request;
$temp = $_REQUEST;
// remove any private payment data ...
if (isset($temp["payment"])) {
unset($temp["payment"]);
}
$last_route = $session->get("last_route", [
"name" => "",
"params" => "",
"path" => "",
]);
$user_token = $session->get("user_token", bin2hex(openssl_random_pseudo_bytes(32)));
//Get the site
$site_host = $request->getHost();
$site = SiteConfig::getSiteIdFromURL($site_host);
//Don't log any traffic from the admin pages
if(substr($path, 0, strlen("/admin/")) !== "/admin/") {
$user_ip = $request->getClientIp();
$user_ua = $request->headers->get("User-Agent");
$user_refer = isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : "";
$user_this_path = $path;
$user_this_route = isset($routeName) ? $routeName : "";
$user_this_route_params = isset($routeParams) ? json_encode($routeParams) : "";
$user_last_path = isset($last_route["path"]) ? $last_route["path"] : "";
$user_last_route = isset($last_route["name"]) ? $last_route["name"] : "";
$user_last_route_params = isset($last_route["params"]) ? json_encode($last_route["params"]) : "";
$user_request_data = json_encode($temp);
$requested_at = new DateTime("now");
$hash = md5(implode("", [
$user_token,
$user_ip,
$user_ua,
($user) ? $user->getId() : "",
$user_refer,
$user_this_path,
$user_this_route,
$user_this_route_params,
$user_last_path,
$user_last_route,
$user_last_route_params,
$user_request_data,
date("Y-m-d H:i:s"),
rand(1,1000),
]));
$traffic_data = new TrafficData();
$traffic_data->setHash($hash);
$traffic_data->setUserToken($user_token);
$traffic_data->setUser($user);
$traffic_data->setUserIp($user_ip);
$traffic_data->setUserUa($user_ua);
$traffic_data->setUserRefer($user_refer);
$traffic_data->setUserThisPath($user_this_path);
$traffic_data->setUserThisRoute($user_this_route);
$traffic_data->setUserThisRouteParams($user_this_route_params);
$traffic_data->setUserLastPath($user_last_path);
$traffic_data->setUserLastRoute($user_last_route);
$traffic_data->setUserLastRouteParams($user_last_route_params);
$traffic_data->setUserRequestData($user_request_data);
$traffic_data->setRequestedAt($requested_at);
if (!$this->entityManager->isOpen()) {
$this->entityManager = $this->entityManager->create(
$this->entityManager->getConnection(),
$this->entityManager->getConfiguration()
);
}
$content = "";
if($path && $path != "/") {
$content = $this->entityManager
->getRepository(Content::class)
->getContentByUrl(
$path, $site
);
}
else {
//Home page. Just store view to content_id 1. (RCS previously was using 48924)
$content = $this->entityManager
->getRepository(Content::class)
->findOneBy(["id" => 1]);
}
if($content) {
$content_view = new ContentView();
$content_view->setTrafficData($traffic_data);
$content_view->setContent($content);
$content_view->setRequestedAt($requested_at);
$content_view->setSiteId($site);
}
try{
//not tracking paging that aren't content w/ new system, do we need to?
//$this->entityManager->persist($traffic);
//$this->entityManager->flush();
if($content) {
//$content->incrementTotalClicks();
$this->entityManager->persist($content);
$this->entityManager->persist($content_view);
$this->entityManager->persist($traffic_data);
$this->entityManager->flush();
}
} catch(\Exception $e) {
try{
//Exception may occur if inserting a duplicate primary key. Should log this somewhere.
$errorlog = fopen(__DIR__ . "/../../var/log/traffic_error.txt", "a") or die("Unable to open file!");
$txt = 'Caught exception (RouteListener.php): '. $e->getMessage() . "\n";
fwrite($errorlog, $txt);
fclose($errorlog);
} catch(\Exception $e) {
// Error writing to file
}
}
}
// store the token in the session
$session->set("user_token", $user_token);
// End log traffic request
// ==================================================
// store the site being used
//$session->set("site_host", $request->getHost());
$session->set("site", $site);
// we should also prevent duplicate pages from get stored back to back ...
// perform any database cleanup - this should probably not remove accounts - just set them to null...
//(Now done in Command/UpdatePublishedExpiredContentCommand.php)
//$this->userHelper->clean();
if ($routeName[0] == "_") {
return;
}
$routeData = array (
"name" => $routeName,
"params" => $routeParams,
"path" => $path,
);
//Temporary redirect for CCS:
/*if($site == Content::SITE_CCS && $routeName != "sign-in_ccs" && $routeName != "coming-soon_ccs" && (!$user || (!$user->isAdmin()))) {
$event->setResponse(new RedirectResponse("/coming-soon"));
}
elseif($site == Content::SITE_CCS && $routeName == "coming-soon_ccs" && $user && ($user->isAdmin())) {
$event->setResponse(new RedirectResponse("/"));
}*/
$thisRoute = $session->get("this_route", array ());
if ($thisRoute == $routeData) {
return;
}
$session->set("last_route", $thisRoute);
$session->set("this_route", $routeData);
if($path != "/sign-in" &&
$path != "/rcs-sign-up" &&
$path != "/forgot-password" &&
$path != "/forgot-username" &&
$path != "/send-activation" &&
//$path != "/sign-in_aar" &&
!(strpos($path, "/rcs-reset-password") !== false) &&
!(strpos($path, "/activate-account") !== false) &&
!(strpos($path, "/rcs.php") !== false) &&
!(strpos($path, "/mfasignin") !== false) &&
!(strpos($path, "/mfa/") !== false) &&
!(strpos($path, "/ajax") !== false)
) {
$session->set("non_sign_in_route", $routeData);
}
}
}