mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
126 lines
3.9 KiB
PHP
126 lines
3.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* Chill is a software for social workers
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Chill\MainBundle\ArgumentResolver;
|
|
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Doctrine\Persistence\ManagerRegistry;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;
|
|
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
|
|
|
/**
|
|
* Resolves entity arguments for controllers.
|
|
*
|
|
* This replaces the functionality previously provided by SensioFrameworkExtraBundle.
|
|
*/
|
|
class EntityValueResolver implements ValueResolverInterface
|
|
{
|
|
public function __construct(
|
|
private readonly ManagerRegistry $doctrine,
|
|
) {}
|
|
|
|
public function resolve(Request $request, ArgumentMetadata $argument): iterable
|
|
{
|
|
$type = $argument->getType();
|
|
if (null === $type || !class_exists($type) || !$this->isEntity($type)) {
|
|
return [];
|
|
}
|
|
|
|
$name = $argument->getName();
|
|
|
|
// If the argument name is 'id', we don't want to resolve it as an entity
|
|
if ('id' === $name) {
|
|
return [];
|
|
}
|
|
|
|
// Try to find the entity ID from various possible parameter names
|
|
$id = $this->findEntityId($request, $name, $type);
|
|
|
|
if (null === $id) {
|
|
return [];
|
|
}
|
|
|
|
$entity = $this->doctrine->getRepository($type)->find($id);
|
|
|
|
if (null === $entity) {
|
|
return [];
|
|
}
|
|
|
|
return [$entity];
|
|
}
|
|
|
|
/**
|
|
* Tries to find the entity ID from various possible parameter names.
|
|
*
|
|
* This method checks for the following parameter names in order:
|
|
* 1. The parameter name specified in the route (e.g., 'id', 'person_id', 'household_id')
|
|
* 2. A parameter named after the entity with 'Id' suffix (e.g., 'personId' for Person entity)
|
|
* 3. A parameter named after the entity with '_id' suffix (e.g., 'person_id' for Person entity)
|
|
* 4. The 'id' parameter as a fallback
|
|
*/
|
|
private function findEntityId(Request $request, string $name, string $type): mixed
|
|
{
|
|
// Common parameter naming patterns
|
|
$possibleNames = [
|
|
$name . 'Id',
|
|
$name . '_id',
|
|
$this->getShortClassName($type) . '_id',
|
|
$this->getShortClassName($type) . 'Id',
|
|
'id',
|
|
];
|
|
|
|
// Special cases based on observed @ParamConverter usage
|
|
$specialCases = [
|
|
'Household' => ['household_id'],
|
|
'AccompanyingCourse' => ['accompanying_period_id'],
|
|
'AccompanyingPeriod' => ['accompanying_period_id'],
|
|
'Event' => ['event_id'],
|
|
'User' => ['userId'],
|
|
'Person' => ['person_id'],
|
|
'Action' => ['action_id'],
|
|
];
|
|
|
|
// Add special cases if applicable
|
|
$shortClassName = $this->getShortClassName($type);
|
|
if (isset($specialCases[$shortClassName])) {
|
|
$possibleNames = array_merge($specialCases[$shortClassName], $possibleNames);
|
|
}
|
|
|
|
// Try each possible parameter name
|
|
foreach ($possibleNames as $paramName) {
|
|
if ($request->attributes->has($paramName)) {
|
|
return $request->attributes->get($paramName);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Gets the short class name (without namespace) from a fully qualified class name.
|
|
*/
|
|
private function getShortClassName(string $class): string
|
|
{
|
|
$parts = explode('\\', $class);
|
|
return end($parts);
|
|
}
|
|
|
|
private function isEntity(string $class): bool
|
|
{
|
|
if (!$this->doctrine->getManagerForClass($class) instanceof EntityManagerInterface) {
|
|
return false;
|
|
}
|
|
|
|
return !$this->doctrine->getManagerForClass($class)->getMetadataFactory()->isTransient($class);
|
|
}
|
|
}
|