I have a problem with Doctrine 2 NoObjectExists validator. For one field it works fine, but with multiple fields I get error:
Provided values count is 1, while expected number of fields to be matched is 2
Entity:
/**
* Message
*
* @ORM\Table(name="messages")
* @ORM\Entity
*/
class Message
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", precision=0, scale=0, nullable=false, unique=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=32, nullable=false)
*/
private $name;
/**
* @var User
*
* @ORM\ManyToOne(targetEntity="User", inversedBy="assignedMessages")
* @ORM\JoinColumn(name="user_id")
*/
private $user;
}
Fieldset class
class MessageFieldset extends Fieldset implements InputFilterProviderInterface
{
protected $objectManager;
public function __construct(ObjectManager $em)
{
parent::__construct('message');
$this->setObjectManager($em);
$this->setHydrator(new DoctrineHydrator($em))
->setObject(new Message());
/* User Field */
$this->add(array(
'name' => 'user',
'attributes' => array(
'type' => 'hidden',
),
));
/* Name Field */
$this->add(array(
'name' => 'name',
'attributes' => array(
'type' => 'text',
'id' => 'name-label',
'class' => 'form-control',
),
'options' => array(
'label' => 'Title',
'label_attributes' => array(
'for' => 'name-label'
),
)
));
}
public function getInputFilterSpecification()
{
return array(
'name' => array(
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'messages' => array(
NotEmpty::IS_EMPTY => 'custom text'
)
)
),
array(
'name' => 'Regex',
'options' => array(
'pattern' => '/[a-zA-Z][a-zA-Z0-9_-]*/'
)
),
array(
'name' => 'DoctrineModule\Validator\NoObjectExists',
'options' => array(
'object_repository' => $this->getObjectManager()->getRepository('Application\Entity\Message'),
'fields' => array('name', 'user'),
//'fields' => 'name', <--- with one field it works fine
'messages' => array(
'objectFound' => 'Custom text'
),
)
)
)
),
)
}
}
Form class
class MessageForm extends Form
{
public function __construct(ObjectManager $em)
{
parent::__construct('message-form');
$this->setAttributes(array(
'method' => 'post',
'role' => 'form'
));
$this->setHydrator(new DoctrineHydrator($em));
$fieldset = new MessageFieldset($em);
$fieldset->setUseAsBaseFieldset(true);
$this->add($fieldset);
$this->add(array(
'type' => 'Zend\Form\Element\Csrf',
'name' => 'csrf',
'options' => array(
'csrf_options' => array(
'timeout' => 600
)
)
));
$submit = new Element\Button('submit');
$submit->setLabel('Add');
$submit->setAttributes(
array(
'type' => 'submit',
'class' =>'btn btn-primary'
));
$this->add($submit);
}
}
my action:
public function messageAction()
{
$form = new MessageForm($this->em);
$message = new Message();
$form->bind($message);
if ($this->request->isPost()) {
$data = $this->request->getPost();
//var_dump($data); <--- it shows all values(name, user)
$form->setData($data);
if ($form->isValid()) {
//...
}else{
//...
}
}
return new ViewModel(array(
'form' => $form
));
}
So if I set only one field(name) everything works fine, but if I pass array with fields(user, name) I get error as above.
Any idea what may be wrong in my code? In my entity user field is relation to another table so I tried set manually like this:
if ($this->request->isPost()) {
$data = $this->request->getPost();
$data->message['user'] = $this->identity() <--- obj of Entity\User
$form->setData($data);
...
}
But it didn't work either.
Try using the DoctrineModule\Validator\UniqueObject
validator like the following:
array(
'name' => 'DoctrineModule\Validator\UniqueObject',
'options' => array(
'object_repository' => $this->getObjectManager()->getRepository('Application\Entity\Message'),
'object_manager' => $this->getObjectManager(),
'fields' => array('name', 'user'),
'messages' => array(
'objectNotUnique' => 'Custom text'
),
)
)
This will validate that there is no object exists with the same name
and user
.
To use multiple fields in your NoObjectExists
validator you also need to bind an array of values to your validator.
Read more details about this issue in the answer from Ocramius in this post on GitHub