Note that there are some explanatory texts on larger screens.

plurals
  1. PONoRecordExists inputfilter
    primarykey
    data
    text
    <p>I have a fieldset which is used in both an 'add' and 'edit' form. </p> <p>The fieldset implements <code>InputFilterProviderInterface</code> to provide its validation.</p> <p>When validating for an add operation, I need to check a database record with the same value doesn't already exist in the database, so I use the <code>NoRecordExists</code> validator.</p> <p>All good so far. But, when I use the same fieldset in an edit form, the validation will fail, as there is obviously already a record with a specific value, its the record being edited. </p> <p>So I turn to the <code>exclude</code> option of the <code>NoRecordExists</code> validator and exclude the record with the 'id' (this is my primary key field) of the record I'm editing. </p> <p>So I'm nearly there, the only thing I can't work out is how to get the 'id' value which I want to exclude at the point I create the inputfilter in <code>getInputFilterSpecification</code>.</p> <p>Here is my fieldset code. If anyone can tell me how to access other properties of the form (or bound object) from within <code>getInputFilterSpecification</code> I would me much obliged.</p> <p>Maybe I need to implement my imputfilter differently to do this? Or even implement a custom validator? But surely a custom validator would be overkill for what would seem a pretty regular use case...</p> <p>Many thanks in advance. :wq</p> <pre><code>&lt;?php namespace Kickoff\Form\Competition; use Kickoff\Form\AbstractFieldset, Kickoff\Model\Entities\Competition, DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator, Zend\InputFilter\InputFilterProviderInterface; class CompetitionFieldset extends AbstractFieldset implements InputFilterProviderInterface { public function init() { $this-&gt;setName('Competition') -&gt;setHydrator(new DoctrineHydrator($this-&gt;getObjectManager(),'Kickoff\Model\Entities\Competition')) -&gt;setObject(new Competition()) -&gt;setLabel('Competition') -&gt;setAttribute('class','form-collection'); $this-&gt;add(array( 'type' =&gt; 'Zend\Form\Element\Hidden', 'name' =&gt; 'id', )); $this-&gt;add(array( 'name' =&gt; 'name', 'options' =&gt; array( 'label' =&gt; 'Competition name', 'admin_inline' =&gt; true, ), )); $this-&gt;add(array( 'name' =&gt; 'long_name', 'options' =&gt; array( 'label' =&gt; 'Competition long name', 'admin_inline' =&gt; true, ), 'attributes' =&gt; array( 'class' =&gt; 'input-xxlarge', ), )); $this-&gt;add(array( 'type' =&gt; 'Zend\Form\Element\Collection', 'name' =&gt; 'leagues', 'options' =&gt; array( 'label' =&gt; 'Leagues', 'count' =&gt; 0, 'should_create_template' =&gt; true, 'allow_add' =&gt; true, 'target_element' =&gt; array( 'type' =&gt; 'LeagueFieldset', ), ), )); } /** * Implement InputFilterProviderInterface */ public function getInputFilterSpecification() { return array( 'name' =&gt; array( 'filters' =&gt; array( array('name' =&gt; 'Zend\Filter\StringTrim'), ), 'validators' =&gt; array( 'notempty' =&gt; array( 'name' =&gt; 'NotEmpty', 'break_chain_on_failure' =&gt; true, 'options' =&gt; array( 'messages' =&gt; array('isEmpty' =&gt; 'Competition name is required.',), ), ), 'length' =&gt; array( 'name' =&gt; 'StringLength', 'options' =&gt; array( 'max' =&gt; '64', 'messages' =&gt; array( 'stringLengthTooLong' =&gt; 'Competition name must be no more than 64 characters.', ), ), ), 'unique' =&gt; array( 'name' =&gt; 'Db\NoRecordExists', 'options' =&gt; array( 'table' =&gt; 'competition', 'field' =&gt; 'name', 'adapter' =&gt; $this-&gt;serviceManager-&gt;getServiceLocator()-&gt;get('db'), 'exclude' =&gt; array( 'field' =&gt; 'id', 'value' =&gt; '', ), 'messages' =&gt; array( 'recordFound' =&gt; 'A competition already exists with this name', ), ), ), ), ), 'long_name' =&gt; array( 'filters' =&gt; array( array('name' =&gt; 'Zend\Filter\StringTrim'), ), 'validators' =&gt; array( 'length' =&gt; array( 'name' =&gt; 'StringLength', 'options' =&gt; array( 'max' =&gt; '128', 'messages' =&gt; array( 'stringLengthTooLong' =&gt; 'Competition long name must be no more than 128 characters.', ), ), ), ), ), ); } } </code></pre> <p>Edit: adding my 'edit' controller action to this post:</p> <pre><code>public function editCompetitionAction() { $id = $this-&gt;params()-&gt;fromRoute('competition_id'); $repository = $this-&gt;getEntityManager()-&gt;getRepository('Kickoff\Model\Entities\Competition'); $competition = $repository-&gt;find($id); if (null == $competition) { $this-&gt;getResponse()-&gt;setStatusCode(404); return; } $formManager = $this-&gt;serviceLocator-&gt;get('FormElementManager'); $form = $formManager-&gt;get('Kickoff\Form\Competition\CompetitionForm'); $form-&gt;bind($competition); $request = $this-&gt;getRequest(); if ($request-&gt;isPost()) { $form-&gt;setData($request-&gt;getPost()); $this-&gt;logger-&gt;debug("Validator is ".print_r($form-&gt;getValidator(),1)); if ($form-&gt;isValid()) { $this-&gt;getEntityManager()-&gt;persist($competition); $this-&gt;getEntityManager()-&gt;flush(); } } return array( 'form' =&gt; $form, ); } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload