<?php
namespace App\Package\Admin\Tools\EventSubscriber\RegistrySubscriber;
use Doctrine\ORM\EntityManagerInterface,
Symfony\Component\HttpFoundation\RequestStack,
Symfony\Component\EventDispatcher\EventSubscriberInterface,
Symfony\Component\HttpKernel\KernelEvents,
Symfony\Component\HttpKernel\Event\ControllerEvent,
Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface,
Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use App\Package\Toolkit\ApplicationMode\ApplicationMode,
App\Package\Toolkit\ConfigurationBag\ConfigurationBag,
App\Package\Admin\Tools\AdminUtil\AdminUtil,
App\Package\Admin\Tools\AdminState\AdminState;
use App\Package\Admin\Main\EntityInterface\{ AdminInterface, AdminOnlineInterface, RegistryInterface };
use App\Package\Admin\Base\EntityInterface\AdminLoggableInterface,
App\Package\Admin\Main\RepositoryInterface\AdminOnlineRepositoryInterface;
/**
* RegistrySubscriber
*
* Persists information about parentless request (admin online and registry entities)
*
* @author Daniel Balowski <d.balowski@openform.pl> (_creator)
* @copyright Openform
* @since 03.2019
*/
class RegistrySubscriber implements EventSubscriberInterface
{
/**
* @var ApplicationMode
*/
protected $applicationMode;
/**
* @var ConfigurationBag
*/
protected $configBag;
/**
* @var AdminUtil
*/
protected $adminUtil;
/**
* @var AdminState
*/
protected $adminState;
/**
* @var EntityManagerInterface
*/
protected $em;
/**
* @var AdminInterface
*/
protected $admin;
/**
* @var RequestStack
*/
protected $requestStack;
/**
* @param ApplicationMode $applicationMode
* @param ConfigurationBag $configBag
* @param AdminUtil $adminUtil
* @param AdminState $adminState
* @param EntityManagerInterface $em
* @param TokenStorageInterface $tokenStorage
* @param RequestStack $requestStack
*/
public function __construct(
ApplicationMode $applicationMode,
ConfigurationBag $configBag,
AdminUtil $adminUtil,
AdminState $adminState,
EntityManagerInterface $em,
TokenStorageInterface $tokenStorage,
RequestStack $requestStack
) {
$this->applicationMode = $applicationMode;
$this->configBag = $configBag;
$this->adminUtil = $adminUtil;
$this->adminState = $adminState;
$this->em = $em;
$this->admin =
$tokenStorage->getToken() ?
$tokenStorage->getToken()->getUser() :
null;
$this->requestStack = $requestStack;
}
/**
* @return array
*/
public static function getSubscribedEvents() : array
{
return [
KernelEvents::CONTROLLER => [
[ 'persistRequest', 10 ],
]
];
}
/**
* Persists information about parentless request (admin online and registry entities)
*
* @param ControllerEvent $event
*
* @return void
*/
public function persistRequest(ControllerEvent $event) : void
{
$controller = $event->getController();
if (
$this->requestStack->getParentRequest() ||
$this->applicationMode->getCurrentMode() !== 'admin' ||
! $this->admin ||
gettype($this->admin) === 'string'
) {
return;
}
if (! $this->adminState->getCurrentModule()) {
return;
}
$this->persistAdminOnline($this->admin)
->persistRegistry($this->admin);
$this->admin->setLastSeen(new \DateTime());
$this->em->persist($this->admin);
$this->em->flush();
return;
}
/**
* Persists admin online entity
*
* @param AdminInterface $admin
*
* @return RegistrySubscriber
*/
protected function persistAdminOnline(AdminInterface $admin) : RegistrySubscriber
{
$adminOnline = $this->getAdminOnlineEntity($admin);
$this->fillLoggableEntity(
$adminOnline,
$admin
);
$adminOnline->setUpdatedAt(new \DateTime());
$this->em->persist($adminOnline);
return $this;
}
/**
* Gets admin online entity
* - creates new entity if it does not exist
*
* @param AdminInterface $admin
*
* @return AdminOnlineInterface
*/
protected function getAdminOnlineEntity(AdminInterface $admin) : AdminOnlineInterface
{
$adminOnline = $this->adminUtil->getAdminOnlineRepository()->findOneByAdminId($admin->getId());
if (! $adminOnline) {
$adminOnlineClass = $this->configBag->get('admin:entity:admin_online');
$adminOnline = new $adminOnlineClass();
}
return $adminOnline;
}
/**
* Persists registry entity
*
* @param AdminInterface $admin
*
* @return RegistrySubscriber
*/
protected function persistRegistry(AdminInterface $admin) : RegistrySubscriber
{
$registry = $this->createRegistryEntity();
$this->fillLoggableEntity(
$registry,
$admin
);
if (! empty($_SERVER[ 'HTTP_CLIENT_IP' ])) {
$ip = $_SERVER[ 'HTTP_CLIENT_IP' ];
} elseif (! empty($_SERVER[ 'HTTP_X_FORWARDED_FOR' ])) {
$ip = $_SERVER[ 'HTTP_X_FORWARDED_FOR' ];
} else {
$ip = $_SERVER[ 'REMOTE_ADDR' ];
}
$registry->setIp($ip);
$requestData = "";
if (isset($_GET)) {
$requestData .= "GET: " . var_export($_GET, true) . "\n\n";
} elseif (isset($_POST)) {
$requestData .= "POST: " . var_export($_POST, true) . "\n\n";
}
if (isset($_SESSION)) {
$requestData .= "SESSION: " . var_export($_SESSION, true) . "\n\n";
}
$registry->setRequestData($requestData);
$this->em->persist($registry);
return $this;
}
/**
* Creates registry entity
*
* @return RegistryInterface
*/
protected function createRegistryEntity() : RegistryInterface
{
$registryClass = $this->configBag->get('admin:entity:registry');
return new $registryClass();
}
/**
* Fills loggable entity
*
* @param AdminLoggableInterface $entity
* @param AdminInterface $admin
*
* @return void
*/
protected function fillLoggableEntity(AdminLoggableInterface $entity, AdminInterface $admin) : void
{
$entity->setAdmin($admin);
$entity->setAdminLogin($admin->getLogin());
$entity->setAdminModule(
$this->adminState->getCurrentModule()
);
$entity->setAdminModuleName(
$this->adminState->getCurrentModule()->getName()
);
$entity->setAdminAction(
$this->adminState->getCurrentAction()
);
$entity->setAdminActionName(
$this->adminState->getCurrentAction()->getName()
);
$entity->setObjectId(
$this->adminState->getCurrentObjectId()
);
return;
}
}