В Symfony для работы с Doctrine ORM и поиска записей с софт-удалением (soft delete) можно использовать фильтры (filters) и аннотацию @DoctrineORMMappingFilter
.
Для начала, вам необходимо создать фильтр, который будет применяться к вашей сущности при выполнении запросов к базе данных. Этот фильтр будет искать записи, которые не были удалены с помощью флага "soft delete".
1. Создайте класс фильтра, например SoftDeleteFilter
:
use DoctrineORMMappingClassMetadata; use DoctrineORMQueryFilterSQLFilter; class SoftDeleteFilter extends SQLFilter { public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias) { // Получаем имя поля, которое содержит информацию о флаге "soft delete" $fieldName = 'deleted'; // Проверяем, имеет ли сущность аннотацию "SoftDelete" if (!$targetEntity->hasField($fieldName)) { return ''; } // Проверяем, активирован ли фильтр для конкретного типа сущности if ($this->hasParameter($fieldName)) { $enabled = $this->getParameter($fieldName); return $enabled ? '' : sprintf('%s.%s IS NULL', $targetTableAlias, $fieldName); } // Если фильтр не активирован, пропускаем запись return ''; } }
2. Затем, также как и любой другой сервис, вам необходимо зарегистрировать фильтр в вашем контейнере сервисов Symfony. Это можно сделать в файле services.yaml
:
services: AppDoctrineFilterSoftDeleteFilter: arguments: [] tags: - { name: doctrine.event_listener, event: postLoad, connection: default }
3. После этого, вы можете применять фильтр к запросам Doctrine ORM, чтобы получить только непомеченные на удаление записи. Например, в репозитории или контроллере Symfony:
$em = $this->getDoctrine()->getManager(); $em->getFilters()->enable('soft_delete'); $em->getFilters()->setParameter('deleted', false); $repository = $em->getRepository(YourEntity::class); $entities = $repository->findAll(); // Результатом будут записи, которые не помечены на удаление
4. Обратите внимание, что вы также можете использовать фильтр для других типов запросов, таких как findOneBy
, createQueryBuilder
, createQuery
и т.д. Примеры использования фильтра при поиске с помощью QueryBuilder:
$em = $this->getDoctrine()->getManager(); $repository = $em->getRepository(YourEntity::class); $qb = $repository->createQueryBuilder('e'); $qb->addSelect('e') ->andWhere('e.field = :value') ->setParameter('value', $value); $qb->getQuery()->setHint( DoctrineORMQuery::HINT_CUSTOM_OUTPUT_WALKER, 'DoctrineORMQueryFilterSQLFilterWalker' ); $qb->getQuery()->enableResultCache(300); // Если используется кэширование. $em->getFilters()->enable('soft_delete'); $em->getFilters()->setParameter('deleted', false); $entities = $qb->getQuery() ->useResultCache(true, 300) ->getResult(); // Получаем записи, которые удовлетворяют условии и не помечены на удаление
Теперь вы можете использовать фильтр для поиска только непомеченных на удаление записей в Symfony с помощью Doctrine ORM.