Symfony Api平台:在删除操作上使用验证组

Symfony Api平台:在删除操作上使用验证组,symfony,api-platform.com,Symfony,Api Platform.com,我试图阻止在实体包含某些特定内容时删除该实体。 因此,我添加了一个验证规则,它与使用表单验证的常规控件完美配合 //entity /** * @Assert\IsTrue(message="Delete not allowed", groups="delete") * * @return bool */ public function isDeleteAllowed(): bool {

我试图阻止在实体包含某些特定内容时删除该实体。 因此,我添加了一个验证规则,它与使用表单验证的常规控件完美配合

//entity
    /**
     * @Assert\IsTrue(message="Delete not allowed", groups="delete")
     *
     * @return bool
     */
    public function isDeleteAllowed(): bool
    {
        //some logic here...
        return false;
    }
现在,我想为api平台部分重用相同的逻辑。 我已为实体的删除操作设置了验证组

//entity
/**
 * @ApiResource(
 *     itemOperations={
 *         "delete"={
 *              "validation_groups"={"delete"}
 *          }
 *     })
 */
但是,api平台删除操作正在跳过验证。 我如何执行它


供您参考,我找到了api平台源代码中无法工作的原因,他们故意忽略删除操作的验证。因此,我打开了一张罚单,看看它是否可以被修复。下面是我们用来解决ApiPlatform中这种硬编码行为的解决方案,方法是在事件订阅服务器中反转它:

<?php
//src\EventSubscriber\DeleteValidationSubscriber.php

namespace App\EventSubscriber;

use ApiPlatform\Core\Exception\ResourceClassNotFoundException;
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
use ApiPlatform\Core\Util\RequestAttributesExtractor;
use ApiPlatform\Core\Validator\ValidatorInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class DeleteValidationSubscriber implements EventSubscriberInterface
{
    private $validator;
    private $resourceMetadataFactory;

    /**
     * @param ValidatorInterface $validator
     * @param ResourceMetadataFactoryInterface $resourceMetadataFactory
     */
    public function __construct(ValidatorInterface $validator, ResourceMetadataFactoryInterface $resourceMetadataFactory)
    {
        $this->validator = $validator;
        $this->resourceMetadataFactory = $resourceMetadataFactory;
    }

    /**
     * Validates data returned by the controller for DELETE action because api-platform is ignoring it
     *
     * @param ViewEvent $event
     * @throws ResourceClassNotFoundException
     */
    public function onKernelView(ViewEvent $event)
    {
        $controllerResult = $event->getControllerResult();
        $request = $event->getRequest();

        if (
            $controllerResult instanceof Response
            || !$request->isMethod('DELETE')
            || $request->isMethodSafe()
            || !($attributes = RequestAttributesExtractor::extractAttributes($request))
            || !$attributes['receive']
        ) {
            return;
        }

        $resourceMetadata = $this->resourceMetadataFactory->create($attributes['resource_class']);

        $validationGroups = $resourceMetadata->getOperationAttribute($attributes, 'validation_groups', null, true);
        if (!is_null($validationGroups)) {
            $this->validator->validate($controllerResult, ['groups' => $validationGroups]);
        }
    }

    /**
     * @return array|string[]
     */
    public static function getSubscribedEvents()
    {
        return [
            KernelEvents::VIEW => ['onKernelView', 64],
        ];
    }
}

请显示实体代码。@Eugene什么的完整代码?拥有“更多代码”如何帮助您回答这个问题?@yivi只是为了检查回答者是否正确配置了它。为什么不使用自定义DataPersisters类并在remove()方法中进行删除?@eugenruban配置很好,我添加一条注释来解释问题的根本原因