<?php
/**
* @license SILK SOFTWARE HOUSE SP Z O O
*/
namespace App\EventSubscriber;
use App\Annotation\ApplySettings;
use App\Entity\Device;
use App\Entity\Measurement;
use App\Entity\MeasurementSetting;
use App\Factory\MeasurementViewFactory;
use App\Model\View\MeasurementView;
use Doctrine\ORM\EntityManagerInterface as EntityManager;
use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Doctrine\Common\Annotations\Reader;
use ReflectionClass;
use ReflectionException;
/**
* Class ParamSettingsSubscriber.
*/
class ParamSettingsSubscriber implements EventSubscriberInterface
{
/**
* Entity manager.
*
* @var EntityManager
*/
private $entityManager;
/**
* Annotation reader.
*
* @var Reader
*/
private $annotationReader;
/**
* Factory.
*
* @var MeasurementViewFactory
*/
private $factory;
/**
* CacheSubscriber constructor.
*
* @param EntityManager $entityManager
* @param Reader $reader
* @param MeasurementViewFactory $factory
*/
public function __construct(EntityManager $entityManager, Reader $reader, MeasurementViewFactory $factory)
{
$this->annotationReader = $reader;
$this->entityManager = $entityManager;
$this->factory = $factory;
}
/**
* Get subscribed events.
*
* @return array
*/
public static function getSubscribedEvents()
{
// return the subscribed events, their methods and priorities
return [
KernelEvents::CONTROLLER_ARGUMENTS => [
['onControllerArguments', 2],
],
];
}
/**
* On kernel controller.
*
* @param ControllerArgumentsEvent $event
*/
public function onControllerArguments(ControllerArgumentsEvent $event)
{
if (!$event->isMasterRequest()) {
return;
}
$annotation = $this->getSettingAnnotation($event->getController());
if (null === $annotation) {
return;
}
$view = null;
foreach ($event->getArguments() as $argument) {
if ($argument instanceof Measurement) {
$this->applySettingsOnMeasurements($argument);
}
if ($argument instanceof Device && $argument->getLastMeasurement()) {
$this->applySettingsOnMeasurements($argument->getLastMeasurement());
}
}
}
/**
* Apply settings on measurements.
*
* @param Measurement $measurement
*/
private function applySettingsOnMeasurements(Measurement $measurement)
{
$this->entityManager->getRepository(MeasurementSetting::class)->create($measurement);
}
/**
* Does controller have idempotent annotation.
*
* @param callable $controllerData
*
* @return ApplySettings|null
*/
private function getSettingAnnotation($controllerData)
{
$annotation = null;
if (!is_array($controllerData)) {
return null;
}
list($controllerObject, $methodName) = $controllerData;
try {
$controller = new ReflectionClass($controllerObject);
$method = $controller->getMethod($methodName);
$annotation = $this->annotationReader->getMethodAnnotation($method, ApplySettings::class);
} catch (ReflectionException $e) {
return null;
}
return $annotation instanceof ApplySettings ? $annotation : null;
}
}