<?php
// src/EventSubscriber/FeatureAccessSubscriber.php
namespace App\EventSubscriber;
use App\Attribute\RequireFeature;
use App\Service\ShopManager;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use ReflectionMethod;
class FeatureAccessSubscriber implements EventSubscriberInterface
{
public function __construct(private ShopManager $shopManager)
{
}
public function onKernelController(ControllerEvent $event): void
{
$controller = $event->getController();
// فقط اگر کنترلر یه آرایه باشه یعنی [object, method]
if (!is_array($controller)) {
return; // رد شو، چون ممکنه یه callable باشه یا error controller
}
[$controllerObject, $method] = $controller;
$reflectionClass = new \ReflectionClass($controllerObject);
$classAttributes = $reflectionClass->getAttributes(RequireFeature::class);
$reflectionMethod = new \ReflectionMethod($controllerObject, $method);
$methodAttributes = $reflectionMethod->getAttributes(RequireFeature::class);
$attributes = array_merge($classAttributes, $methodAttributes);
foreach ($attributes as $attribute) {
$instance = $attribute->newInstance();
if (!$this->shopManager->siteAccess($instance->featureKey)) {
throw new AccessDeniedHttpException('شما به این قابلیت دسترسی ندارید.');
}
}
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::CONTROLLER => 'onKernelController',
];
}
}