ApiPaltform - восстановление мягко удаленного элемента

Я использую ApiPlatform и Symfony5

Я реализовал softdelete на объекте User

Этот объект удален правильно, я все еще хочу отображать удаленных пользователей для некоторых ролей, поэтому я пытаюсь DoctrineExtension динамически изменить запрос.

Вот мой UserExtension.php:

    public function applyToItem(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, array $identifiers, string $operationName = null, array $context = []): void
    {
        $this->addWhere($queryBuilder, $resourceClass);
    }

    private function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
    {

        if (User::class == $resourceClass &&
            $this->security->isGranted(GenericRoles::ROLE_ADMIN)
        ) {
            $rootAlias = $queryBuilder->getRootAliases()[0];

            $queryBuilder->andWhere("$rootAlias.deletedAt > '2019-01-01'");
        }
    }

Я проверил, что вхожу в условие if.

Но я все еще получаю 404 за предмет, который пытаюсь восстановить (который все еще находится в базе)

Тот же запрос, введенный в командной строке в базе данных, возвращает мне элемент, который я хочу восстановить.

Я также пытался отключить softdelete следующим образом:

$this->entityManager->getFilters()->disable('softdeleteable');

Но при этом отключите его для всего приложения, и я не могу снова включить его в UserExtension

Кто-нибудь знает, что я делаю неправильно? Или если есть другой способ восстановить обратимо удаленные элементы

Или, если у вас есть больше документов по этому вопросу, я был бы признателен, потому что у меня заканчиваются варианты.

Спасибо!

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
1
0
808
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Да, это не просто, так как ваш запрос выполняется вне расширения. Я бы, вероятно, попытался отключить мягко удаляемый фильтр для объекта пользователя только в том случае, если аутентифицированный пользователь имеет роль администратора. Он по-прежнему будет отключен после выполнения запроса, но это не должно вызывать слишком много побочных эффектов, поскольку пользователь с правами администратора должен иметь возможность видеть удаленные объекты пользователя. Что-то вроде этого.

public function applyToItem(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, array $identifiers, string $operationName = null, array $context = []): void
{
    $this->addWhere($queryBuilder, $resourceClass);
}

private function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
{
    if (User::class === $resourceClass &&
        $this->security->isGranted(GenericRoles::ROLE_ADMIN)
    ) {
        $filter = $this->entityManager->getFilters()->enable('softdeleteable');
        $filter->disableForEntity(User::class);

        $rootAlias = $queryBuilder->getRootAliases()[0];
        $queryBuilder->andWhere("$rootAlias.deletedAt > '2019-01-01'");
    }
}

Спасибо за ваш комментарий! Я не пробовал это решение, но с помощью DataProvider я могу disable фильтр запросить объект, который я хочу запросить, а затем снова enable фильтр, возвращая интересующий объект.

baronbrn 23.12.2020 14:30
Ответ принят как подходящий

Это решение сработало для меня, я надеюсь, что оно сработает для тех, кто попадется на это:

С помощью DataProvider можно disable фильтровать, запрашивать мягко удаленный объект, который вы хотите запросить, и сохранять его в переменной, затем enable снова фильтровать и возвращать ваш объект.

Я не знаю, является ли использование DataProvider таким образом хорошей практикой, но это не создало побочных эффектов в моем приложении.

Вот пример:

    public function getItem(string $resourceClass, $id, string $operationName = null, array $context = [])
    {
        if ($this->security->isGranted(GenericRoles::ROLE_ADMIN))
        ) {
            $this->entityManager->getFilters()->disable('softdeleteable');
        }

        $softDeletedObject = $this->itemDataProvider->getItem($resourceClass, $id, $operationName, $context);

        $this->entityManager->getFilters()->enable('softdeleteable');

        return $softDeletedObject;
    }

Другие вопросы по теме