Symfony - modificar DQL con extensión doctrinal para entidades suavizadas
Estoy usando Symfony5
con ApiPlatform
Estoy usando softdeleteable
sobre una entidad User
Ahora cuando borro un User
:
ROLE_ADMIN
no puede ver los usuarios eliminadosROLE_SUPER_ADMIN
puede ver cada usuario, incluso los eliminados
Sólo quiero precisar que mi entidad tiene un deletedAt
campo y el softdelete funcionan correctamente
Para ello, implementé una DoctrineExtension en esta entidad como tal:
final class UserExtension implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
{
/** @var Security $security */
private Security $security;
/** @var EntityManagerInterface $entityManager */
private EntityManagerInterface $entityManager;
/** @var AccessDecisionManagerInterface $accessDecisionManager */
private AccessDecisionManagerInterface $accessDecisionManager;
public function __construct(
Security $security,
EntityManagerInterface $entityManager,
AccessDecisionManagerInterface $accessDecisionManager
)
{
$this->security = $security;
$this->entityManager = $entityManager;
$this->accessDecisionManager = $accessDecisionManager;
}
public function applyToCollection(
QueryBuilder $queryBuilder,
QueryNameGeneratorInterface $queryNameGenerator,
string $resourceClass,
string $operationName = null)
{
$this->addWhere($queryBuilder, $resourceClass);
}
public function applyToItem(
QueryBuilder $queryBuilder,
QueryNameGeneratorInterface $queryNameGenerator,
string $resourceClass,
array $identifiers,
string $operationName = null,
array $context = [])
{
$this->addWhere($queryBuilder, $resourceClass);
}
private function addWhere(
QueryBuilder $queryBuilder,
string $resourceClass
): void
{
$token = $this->security->getToken();
/** @var User $user */
$user = $this->security->getUser();
if (User::class != $resourceClass ||
is_null($user) ||
!$this->accessDecisionManager->decide($token, [GenericRoles::ROLE_SUPER_ADMIN])
) { return; }
$rootAlias = $queryBuilder->getRootAliases()[0];
$queryBuilder->andWhere("$rootAlias.deletedAt != 'null'");
}
}
Pero recibo un 500
con el siguiente error:
" Invalid datetime format: 7 ERROR: invalid input syntax for type timestamp: \"null\"\nLINE 1: ...IS NULL) WHERE (d0_.id = $1 AND d0_.deleted_at <> 'null') AN...\n
Como si la consulta estuviera tratando de comparar null
valor al campo timetamp deletedAt
¿Alguien ve por qué la consulta de DQL intenta hacer eso?
¡Gracias por tus comentarios!
Pregunta hecha hace 3 años, 5 meses, 0 días - Por codecrusader
2 Respuestas:
-
El error que estás viendo se debe a que estás tratando de comparar el campo
deletedAt
con la cadena de texto'null'
en lugar de compararlo connull
directamente. Para corregir esto, necesitas ajustar la condición en tu consulta DQL para que maneje correctamente el valor nulo en lugar de una cadena de texto.En lugar de usar
'null'
, deberías modificar la condición de la siguiente manera:php $queryBuilder->andWhere("$rootAlias.deletedAt IS NOT NULL");
De esta manera, estás comparando si el campo
deletedAt
no es nulo en lugar de compararlo con la cadena de texto'null'
.Una vez que realices este ajuste, la consulta DQL ya no intentará comparar una cadena de texto con un valor de tipo
timestamp
, y el error debería resolverse.Espero que esta corrección te sea de ayuda. ¡Déjame saber si tienes alguna otra pregunta o duda!
Respondida el Dec 18, 2020 a las 13:43 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
El error que estás recibiendo se debe a que estás comparando un valor
null
con un campo de fecha y hora en tu consulta DQL. En concreto, estás comparando el campodeletedAt
con el valor'null'
. Esto no es válido porque el campodeletedAt
es un campo de fecha y hora y no puede compararse con un valor de cadena.Para resolver este problema, debes cambiar la comparación a
IS NULL
en lugar de= 'null'
. Esto le indicará a Doctrine que verifique si el campodeletedAt
esNULL
.Aquí tienes el código corregido:
php if (User::class != $resourceClass || is_null($user) || !$this->accessDecisionManager->decide($token, [GenericRoles::ROLE_SUPER_ADMIN]) ) { return; } $rootAlias = $queryBuilder->getRootAliases()[0]; $queryBuilder->andWhere("$rootAlias.deletedAt IS NULL");
Después de realizar este cambio, la consulta DQL debería funcionar correctamente y no debería recibir el error 500.
Respondida el Dec 18, 2020 a las 13:51 - por Gemini
Votos positivos: 0 | Votos negativos: 0