Trying to create a custom validator, I need to use a service from its isValid
method.
How to inject that service ?
As an alternative, I could try to instantiate the service from within the validator method, but the service constructor requires a controller object, which I don't have at that point.
Here is the validator:
class OrderNumber extends AbstractValidator
{
const EXIST = 'exist';
/**
* @var array
*
*/
protected $messageTemplates = array();
/**
* @var element name
*
*/
private $element = null;
/**
* Options for this validator
*
* @var array
*/
protected $options = array(
'manager' => null, // set entity manager to find if value already exist
);
/**
* Constructor
*
* @param array|Traversable|int $options OPTIONAL
*/
public function __construct($options)
{
$this->messageTemplates = array(
self::INVALID => \Application\Util\Translator::translate("This value is required"),
);
if (!isset($options['element']) || empty($options['element'])) {
throw new \Exception('Element name is not defined');
}
$this->element = $options['element'];
parent::__construct();
}
/**
* Returns true if and only if no record where found in Autoself for the value.
*
* @param string $value
* @return bool
*/
public function isValid($value, array $context = null) {
$isAvailable = $vehiculeService->orderNumberIsAvailable($value);
if ($vehiculeService->orderNumberIsAvailable($value)) {
return true;
} else {
return false;
}
}
}
I needed to pass the service manager in a validator for one of my projects. Confronted with the same problem as you, I decided to pass the service manager as a parameter in the options array. Here is may code :
public function __construct(array $options)
{
$this->db_manager = $options['db_manager'];
parent::__construct($options);
}
Here, db_manager is a service manager containing only what I need. As a matter of principle, I never get the full service manager.
This validator is then used in a form. To do this, in the class of the form I define a method getInputFilterSpecification containing the following array :
'recordSource' => [
'name' => 'recordSource',
'required' => true,
'filters' => [
[
'name' => 'StripTags'
],
[
'name' => 'StringTrim'
],
[
'name' => 'SbmPdf\Model\Filter\NomTable',
'options' => [
'db_manager' => $this->db_manager
]
]
],
'validators' => [
[
'name' => 'SbmPdf\Model\Validator\RecordSource',
'options' => [
'db_manager' => $this->db_manager,
'auth_userId' => $this->auth_userId
]
]
]
],
The form itself being built by a factory :
class DocumentPdfFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$db_manager = $serviceLocator->get('Sbm\DbManager');
$pdf = $serviceLocator->get(Tcpdf::class);
return new DocumentPdf($db_manager, ...);
}