src/EventSubscriber/RegistryEntryCreator.php line 52
<?php
namespace App\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface,
Symfony\Component\HttpKernel\Event\ViewEvent,
Symfony\Component\HttpKernel\KernelEvents,
Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface,
Symfony\Component\HttpFoundation\Request;
use ApiPlatform\Symfony\EventListener\EventPriorities,
ApiPlatform\Api\IriConverterInterface;
use App\Entity\Admin,
App\Entity\RegistryEntry,
App\Repository\AdminRepository,
App\Repository\RegistryEntryRepository;
final class RegistryEntryCreator implements EventSubscriberInterface
{
const ATTRIBUTE_API_RESOURCE_CLASS = '_api_resource_class';
const ATTRIBUTE_API_OPERATION_NAME = '_api_operation_name';
const ATTRIBUTE_API_WRITE_ITEM_IRI = '_api_write_item_iri';
const ATTRIBUTE_UUID = 'uuid';
const ATTRIBUTE_DATA = 'data';
private AdminRepository $adminRepository;
private RegistryEntryRepository $registryEntryRepository;
private TokenStorageInterface $tokenStorage;
private IriConverterInterface $iriConverter;
public function __construct(
AdminRepository $adminRepository,
RegistryEntryRepository $registryEntryRepository,
TokenStorageInterface $tokenStorage,
IriConverterInterface $iriConverter
) {
$this->adminRepository = $adminRepository;
$this->registryEntryRepository = $registryEntryRepository;
$this->tokenStorage = $tokenStorage;
$this->iriConverter = $iriConverter;
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::VIEW => [
['create', EventPriorities::POST_WRITE]
]
];
}
public function create(ViewEvent $event): void
{
if (! $event->isMainRequest()) {
return;
}
$admin = $this->tokenStorage->getToken()?->getUser();
if (! $admin instanceof Admin) {
return;
}
$admin->setLastActivityAt(new \DateTimeImmutable());
$this->adminRepository->persist($admin, true);
$request = $event->getRequest();
$resourceClass = $request->attributes->get(self::ATTRIBUTE_API_RESOURCE_CLASS);
if (! $resourceClass || $request->isMethod(Request::METHOD_GET)) {
return;
}
$registryEntry = new RegistryEntry(
admin: $admin,
username: $admin->getUserIdentifier(),
operationName: $request->attributes->get(self::ATTRIBUTE_API_OPERATION_NAME),
resourceClass: $request->attributes->get(self::ATTRIBUTE_API_RESOURCE_CLASS),
resourceUuid: $this->getResourceUuid($request),
inputData: $request->attributes->get(self::ATTRIBUTE_DATA),
requestMethod: $request->getMethod(),
requestUri: $request->getPathInfo(),
ip: $request->getClientIp() ?? 'unknown',
);
$this->registryEntryRepository->persist($registryEntry, true);
return;
}
private function getResourceUuid(Request $request): ?string
{
if ($request->attributes->get(self::ATTRIBUTE_UUID)) {
return $request->attributes->get(self::ATTRIBUTE_UUID);
}
$data = $request->attributes->get(self::ATTRIBUTE_DATA);
if (is_object($data) && property_exists($data, self::ATTRIBUTE_UUID)) {
return $data->{'get' . ucfirst(self::ATTRIBUTE_UUID)}()->toString();
}
return $this->getIri($request);
}
private function getIri(Request $request): ?string
{
if (! $iri = $request->attributes->get(self::ATTRIBUTE_API_WRITE_ITEM_IRI)) {
return null;
}
try {
$data = $this->iriConverter->getResourceFromIri($iri);
return $data->getUuid()->toString();
} catch (\Exception $e) {
return $iri;
}
}
}