如何在ZendFramework 2 AbstractValidator中包含EntityManager

时间:2018-01-22 11:49:44

标签: zend-framework2 zend-validate zend-servicemanager

我有一个自定义验证器,扩展了Zend AbstractValidator。问题是,我想包括Doctrine EntityManager,但我一直都在失败!我试图为我的验证器制作一个工厂,但它似乎不起作用。救命!!我做错了什么?

验证

$ this-> objectRepository保持为空,而我期待内容。     

namespace Rentals\Validator;

use Rentals\Response;
use Zend\Validator\AbstractValidator;
use Zend\Stdlib\ArrayUtils;

class ExistentialQuantification extends AbstractValidator
{
    const NO_ENTITY_ID = 'noEntityId';
    const ENTITY_NOT_FOUND = 'entityNotFound';
    const INVALID_ID = 'invalidId';

    protected $messageTemplates = [
        self::NO_ENTITY_ID => 'The input does not contain an entity id.',
        self::ENTITY_NOT_FOUND => 'The entity could not be found.',
        self::INVALID_ID => 'The input does not contain an entity id.',
    ];

    protected $objectRepository;

    public function __construct(array $options)
    {
        $this->objectRepository = $options['object_repository'];

        parent::__construct($options);
    }

    public function isValid($value)
    {
        if ($value === null) {
            return true;
        }
        if (! isset($value->id)) {
            $this->error(self::NO_ENTITY_ID);

            return false;
        }

        $entityClass = $this->getOption('entity_class');
        $controller = new Controller();
        $entity = (new FactoryInterface)(EntityManager::class)->find($entityClass, $entity->id);
        if (! $entity instanceof $entityClass) {
            $this->error(self::ENTITY_NOT_FOUND);

            return false;
        }
        if (! $entity->getId()) {
            $this->error(self::NO_ENTITY_ID);

            return false;
        }

        return true;
    }
}

工厂:     

namespace Rentals\Validator;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\MutableCreationOptionsInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Stdlib\ArrayUtils;

class ExistentialQuantificationFactory implements FactoryInterface, MutableCreationOptionsInterface
{
    protected $options = [];

    public function setCreationOptions(array $options)
    {
        $this->options = $options;
    }

    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        if (! isset($this->options['object_manager'])) {
            $this->options['object_manager'] = 'doctrine.entitymanager.orm_default';
        }

        $objectManager = $serviceLocator->get($this->options['object_manager']);
        $objectRepository = $objectManager->getRepository($this->options['entity_class']);

        return new ExistentialQuantification(ArrayUtils::merge(
            $this->options, [
                'objectManager' => $objectManager,
                'objectRepository' => $objectRepository
            ]
        ));
    }
}

模块配置:

<?php
return [
    'service_manager' => [
        'factories' => [
            'Rentals\\Validator\\ExistentialQuantification' => 'Rentals\\Validator\\ExistentialQuantificationFactory'
        ]
    ]
];
?>

1 个答案:

答案 0 :(得分:1)

如果您更改配置条目,如下例所示,该怎么办?

return [
    'validators' => [
        'factories' => [
            ExistentialQuantification::class => ExistentialQuantificationFactory::class,
        ],
    ],
];

此更改将导致您的工厂进一步更改,因为实体管理器的服务定位器与您注入的服务定位器不同。

namespace Application\Validator\Factory;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\MutableCreationOptionsInterface;
use Zend\ServiceManager\MutableCreationOptionsTrait;
use Zend\ServiceManager\ServiceLocatorInterface;

class ExistentialQuantificationFactory implements FactoryInterface, MutableCreationOptionsInterface
{
    use MutableCreatinOptionsTrait;

    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $parentLocator = $serviceLocator->getServiceLocator();

        if (! isset($this->creationOptions['object_manager'])) {
            $this->creationOptions['object_manager'] = 'doctrine.entitymanager.orm_default';
        }

        $objectManager = $parentLocator->get($this->creationOptions['object_manager']);
        $objectRepository = $objectManager->getRepository($this->creationOptions['entity_class']);

        return new ExistentialQuantification(ArrayUtils::merge(
            $this->options, [
                'objectManager' => $objectManager,
                'objectRepository' => $objectRepository
            ]
        ));
    }
}

我在这做了什么?首先,我实现了MutableCreationOptionsTrait类。此特征实现了使用创建选项所需的功能。但这只是避免不必要工作的一点暗示。

由于在配置中将验证器类设置为验证器,我们必须使用父服务定位器来获取实体管理器。继承的服务定位器只提供对验证器的访问。

现在,您可以尝试在控制器中访问验证器,如下面的示例所示。

$validator = $this->getServiceLocator()
    ->get('ValidatorManager')
    ->get(ExistentialQuantification::class, [
        'entity_class' => YourEntityClass::class,
    ]);

\Zend\Debug\Debug::dump($validator, __METHOD__);

验证器管理器应返回验证器,以便您可以对其进行测试。