Sorry for open another post to ask the same question!
I have been confused by this question for several weeks.
'validators' => [
'factories' => [
RecordExists::class => DbValidatorAbstractFactory::class,
NoRecordExists::class => DbValidatorAbstractFactory::class,
],
],
the above configuration is useless, why?
It would not execute even I wrote “exit(‘hello factory!’);” in the DbValidatorAbstractFactory’s __construction function. It obvious not run into the factory logic.
===================================================
step 1. create a factory for the validator named DbValidatorAbstractFactory, it is beyond the module/Application/src/Validator/Factory folder.
namespace Application\Validator\Factory;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Stdlib\ArrayUtils;
use Zend\Validator\Db\RecordExists;
class DbValidatorAbstractFactory implements FactoryInterface
{
private $options;
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
//exit('test whether it run this function'); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! nothing happened!!!
if (isset($options['adapter'])) {
return new $requestedName(ArrayUtils::merge(
$options,
['adapter' => $container->get($options['adapter'])]
));
}
return new $requestedName($options);
}
public function setCreationOptions(array $options)
{
$this->options = $options;
}
}
step 2 config the new validator factory in the module.config.php like:
'validators' => [
'factories' => [
RecordExists::class => DbValidatorAbstractFactory::class,
NoRecordExists::class => DbValidatorAbstractFactory::class,
],
],
step 3 according the vendor\zendframework\zend-db\src\Adapter\AdapterServiceFactory.php, I made a customer dbadatper named ExpressAdapterServiceFactory in the folder module/Application/src/Db/Factory
namespace Application\Db\Factory;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
class ExpressAdapterServiceFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$config = $container->get('config');
return new Adapter($config['express']);
}
}
step 4, My problem is step 4, I wanna to config this new customer db adatper in the top level global.php, how to config it? Can you teach me?
'service_manager' => [
'factories' => [
'adapter.express' => Application\Db\Factory\ExpressAdapterServiceFactory::class, //I dont think it is correct!
],
],
step 5, my Logistics.php model file is a combination of entity and inputfilter the same way as the official tutorial way as following:
namespace Application\Model\Main;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Filter\StringToUpper;
use Zend\Filter\StringTrim;
use Zend\Filter\StripTags;
use Zend\Filter\ToFloat;
use Zend\Filter\ToInt;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
use Zend\Validator\Between;
use Zend\Validator\Db\NoRecordExists;
use Zend\Validator\Db\RecordExists;
use Zend\Validator\InArray;
use Zend\Validator\NotEmpty;
use Zend\Validator\Regex;
use Zend\Validator\StringLength;
class Logistics implements InputFilterAwareInterface
{
public $id;
public $customer; //customer need to check whether the input coustomerid is exist
...
private $inputFilter;
public function exchangeArray(array $data)
{
$this->id = !empty($data['id']) ? $data['id'] : null;
$this->customer = !empty($data['customer']) ? $data['customer'] : null;
...
}
public function getArrayCopy()
{
return [
'id' => $this->id,
'customer' => $this->customer,
...
];
}
public function setInputFilter(InputFilterInterface $inputFilter)
{
throw new \DomainException(sprintf(
'%s does not allow injection of an alternate input filter',
__CLASS__
));
}
public function getInputFilter()
{
if ($this->inputFilter) return $this->inputFilter;
$inputFilter = new InputFilter();
$inputFilter->add([
'name' => 'id',
'required' => true,
'filters' => [
['name' => ToInt::class],
],
]);
$inputFilter->add([
'name' => 'customer',
'required' => true,
'filters' => [
['name' => ToInt::class],
],
'validators' => [
[
'name' => RecordExists::class,
'options' => [
'table' => 'main_customers',
'field' => 'id',
'message' => 'customer id input is not exist in the customer table',
'adapter' => 'adapter.express',
],
],
],
]);
....
$this->inputFilter = $inputFilter;
return $this->inputFilter;
}
}