Search code examples
phpmysqldoctrine-ormzend-framework3laminas

Laminas (Zend Framework 3) Doctrine input filter callback validator - "Call to a member function getId() on null" when isValid false



I have a book management module in my application. When editing a book (in the form) I want to check whether the current reading progress (number of read pages) is not greater than the number of all pages of the book. Form fields are called 'currentprogress' and 'totality'. I'm using Callback Validator and it looks like this:
// Add inputfilter for 'currentprogress' field
$inputFilter->add([
    'name'     => 'currentprogress',
    'required' => false,
    'filters'  => [
    ],
    'validators' => [
        [
           'name'  => 'Callback',
           'options' => [
              'messages' => [
                  \Laminas\Validator\Callback::INVALID_VALUE => 'Current progress cannot be greather than total size.',
               ],
              'callback' => function($value, $context=[]) {
                   $currentprogress = $value;
                   $totality = $context['totality'];
                   $isValid = $currentprogress <= $totality;
                   return $isValid;
               }
           ]
        ],
     ],
]);

I checked in the form 2 cases:

Case 1:
currentprogress = 1
totality = 150

My app successfully updates the book

Case 2:
currentprogress = 160
totality = 150

I got exception

Call to a member function getId() on null


I know values of $currentprogress and $totality are accordingly 160 and 150 (I checked using echo()), so $isValid should be false.

So why is the above exception instead of message from validator under 'currentprogress' field? Any ideas?

I use:

  • php 7.4
  • laminas
  • doctrine-orm-module ^4

Thank you in advance for your support


Solution

  • I found answer in my controller's editAction.
    I marked above the part that was missing in the code (comments //START OF MISSING PART and //END OF MISSING PART).

      public function editAction()
      {
        ...
    
        if ($this->getRequest()->isPost()) {
          ...
    
          if($form->isValid()) {
            ...
    
            return $this->redirect()->toRoute('books',
                        ['action' => 'index']);
    
          }
          //START OF MISSING PART
          else{
              ...
              return new ViewModel(array(
                'publication' => $publication,
                'form' => $form,
              ));
          } 
          //END OF MISSING PART
        } else {
          ...
          return new ViewModel(array(
            'publication' => $publication,
            'form' => $form,
          ));
        }
      }
    

    So when the form failed the $isValid test, it didn't inject the needed variables into the view. It caused exception.

    I feel a bit stupid but I think describing it here helped me find the solution.

    Thanks to everyone who took a look at it.