<?php
namespace App\DataFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractContextAwareFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use App\Request\OrderRequestRequest;
use App\Security\UserSecurityHelper;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
class OrderRequestDeletedDataFilter extends AbstractContextAwareFilter
{
const STATE_DELETED = 'deleted';
const STATE_ALL = 'all';
const STATE_DEFAULT = 'default';
/**
* @var UserSecurityHelper
*/
private $securityHelper;
/**
* @var Security
*/
private $security;
/**
* OrderRequestDeletedDataFilter constructor.
*
* @param UserSecurityHelper $securityHelper
* @param ManagerRegistry $managerRegistry
* @param RequestStack|null $requestStack
* @param LoggerInterface|null $logger
* @param array|null $properties
* @param NameConverterInterface|null $nameConverter
*/
public function __construct(
Security $security,
UserSecurityHelper $securityHelper,
ManagerRegistry $managerRegistry,
?RequestStack $requestStack = null,
LoggerInterface $logger = null,
array $properties = null,
NameConverterInterface $nameConverter = null
) {
parent::__construct($managerRegistry, $requestStack, $logger, $properties, $nameConverter);
$this->securityHelper = $securityHelper;
$this->security = $security;
}
/**
* @inheritDoc
*/
protected function filterProperty(
string $property,
$state,
QueryBuilder $queryBuilder,
QueryNameGeneratorInterface $queryNameGenerator,
string $resourceClass,
string $operationName = null
) {
if (!$this->securityHelper->isGranted('ROLE_GALAB_API_USER')) {
return;
}
if ($property !== 'delete_state') {
return;
}
if ($resourceClass !== OrderRequestRequest::class) {
return;
}
$state = $this->normalizeValue($state);
if ($state === null) {
return;
}
if ($state === self::STATE_DEFAULT) {
return;
}
$parts = $queryBuilder->getDQLPart('where')->getParts();
$queryBuilder->resetDQLPart('where');
$parts = array_filter($parts, fn($part) => 'p.deletedAt IS NULL' !== $part);
foreach ($parts as $part) {
$queryBuilder->andWhere($part);
}
if ($state === self::STATE_ALL) {
return;
}
$queryBuilder->andWhere('p.deletedAt IS NOT NULL');
}
private function normalizeValue($value)
{
switch ($value) {
case self::STATE_DELETED:
case self::STATE_ALL:
case self::STATE_DEFAULT:
return $value;
}
return null;
}
/**
* @inheritDoc
*/
public function getDescription(string $resourceClass): array
{
$description = [
'delete_state' => [
'property' => 'delete_state',
'type' => 'string',
'required' => false,
'schema' => [
'type' => 'string',
'description' => 'Allows the admin user to filter by deleted state',
'enum' => [
self::STATE_DEFAULT => 'Default state, no deleted order requests will be shown',
self::STATE_ALL => 'All order requests will be loaded regardless of delete state',
self::STATE_DELETED => 'Only deleted order requests will be shown',
],
],
],
];
return $description;
}
}