Adarsh Khatri
Adarsh Khatri

Reputation: 358

Doctrine Zend Form not setting data on post

I am very new to Zend and Doctrine

Creating a module for Zend using ORM but while I post, data not being set.

I checked this but no luck.

My module.config.php

<?php

return array(
    'controllers' => array(
        'invokables' => array(
            'Room\Controller\Index' => 'Room\Controller\IndexController',
        ),
    ),
    'router' => array(
                //other stuff
                //
                ),
                'may_terminate' => true,
            ),
        ),
    ),
    'view_manager' => array(
        'display_exceptions' => true,
        'template_path_stack' => array(
            'room' => __DIR__ . '/../view'
        ),
    ),
    'service_manager' => array (
        'factories' => array(
            'room_module_options' => 'Room\Service\Factory\ModuleOptionsFactory',
            'room_error_view' => 'Room\Service\Factory\ErrorViewFactory',
            'room_form' => 'Room\Service\Factory\RoomFormFactory',
        ),
    ),
    'doctrine' => array(
        'configuration' => array(
            'orm_default' => array(
                'generate_proxies' => true,
            ),
        ),
        
        'driver' => array(
            'room_driver' => array(
                'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
                'cache' => 'array',
                'paths' => array(
                    __DIR__ . '/../src/Room/Entity',
                ),
            ),
            'orm_default' => array(
                'drivers' => array(
                    'Room\Entity' => 'room_driver',
                ),
            ),
        ),
    ),
);

I have my Room.php file inside Entity folder and have got all getters/setters method along with ORM settings. Running schema:update also works and adds new table to database.

My Factory/RoomFormFactory.php

<?php

namespace Room\Service\Factory;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

use DoctrineORMModule\Form\Annotation\AnnotationBuilder as DoctrineAnnotationBuilder;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use DoctrineModule\Validator\NoObjectExists as NoObjectExistsValidator;

use Room\Entity\Room;

class RoomFormFactory implements FactoryInterface
{
  
    /**
     * @var Zend\Form\Form
     */
    private $form;
    
    /**
     * @var ServiceLocatorInterface
     */
    private $serviceLocator;
    
    /**
     * @var ModuleOptions
     */
    protected $options;
    
    /**
     * @var Doctrine\ORM\EntityManager
     */
    protected $entityManager;
    
    /**
     * @var Zend\Mvc\I18n\Translator
     */
    protected $translatorHelper;
    
    /**
     * @var Zend\Mvc\I18n\Translator
     */
    protected $url;
    
  
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $this->serviceLocator = $serviceLocator;
        return $this;
    }
    
    /**
     * Add Room
     *
     * Method to create the Doctrine ORM room form for edit/add room 
     *
     * @return Zend\Form\Form
     */
    public function createRoomForm($roomEntity, $formName = 'AddRoom')
    {
        $entityManager = $this->getEntityManager();
        $builder = new DoctrineAnnotationBuilder($entityManager);
        $this->form = $builder->createForm($roomEntity);
        $this->form->setHydrator(new DoctrineHydrator($entityManager));
        $this->form->setAttribute('method', 'post');

        $this->addCommonFields();
        
        switch($formName) {
              
          case 'AddRoom':
              //$this->addRoomFields();
              //$this->addRoomFilters();
              $this->form->setAttributes(array(
                  'action' => $this->getUrlPlugin()->fromRoute('room', array('action' => 'add')),
                  'name' => 'add_room'
              ));
              break;
              
          case 'EditRoom':
              $this->form->setAttributes(array(
                  'name' => 'add_room'
              ));
              break;
              
          default:
              //$this->addRoomFields();
              //$this->addRoomFilters();
              $this->form->setAttributes(array(
                  'action' => $this->getUrlPlugin()->fromRoute('room', array('action' => 'add')),
                  'name' => 'add_room'
              ));
              break;
        }       
        
        $this->form->bind($roomEntity);
    
        return $this->form;
    }
    
    /**
     *
     * Common Fields
     *
     */
    private function addCommonFields()
    {
        $this->form->add(array(
            'name' => 'csrf',
            'type' => 'Zend\Form\Element\Csrf',
            'options' => array(
                'csrf_options' => array(
                    'timeout' => 600
                )
            )
        ));
         

        $this->form->add(array(
            'name' => 'submit',
            'type' => 'Zend\Form\Element\Submit',
            'attributes' => array(
                'type'  => 'submit',
            ),
        ));
    }
    
    
    /**
     * get options
     *
     * @return ModuleOptions
     */
    private function getOptions()
    {
        if(null === $this->options) {
            $this->options = $this->serviceLocator->get('room_module_options');
        }
    
        return $this->options;
    }
    
    /**
     * get entityManager
     *
     * @return Doctrine\ORM\EntityManager
     */
    private function getEntityManager()
    {
        if(null === $this->entityManager) {
            $this->entityManager = $this->serviceLocator->get('doctrine.entitymanager.orm_default');
        }
    
        return $this->entityManager;
    }
    
    /**
     * get translatorHelper
     *
     * @return  Zend\Mvc\I18n\Translator
     */
    private function getTranslatorHelper()
    {
        if(null === $this->translatorHelper) {
            $this->translatorHelper = $this->serviceLocator->get('MvcTranslator');
        }
    
        return $this->translatorHelper;
    }
    
    /**
     * get urlPlugin
     *
     * @return  Zend\Mvc\Controller\Plugin\Url
     */
    private function getUrlPlugin()
    {
        if(null === $this->url) {
            $this->url = $this->serviceLocator->get('ControllerPluginManager')->get('url');
        }
    
        return $this->url;
    }
    
}

My Controller/IndexController.php

<?php

namespace Room\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

use Room\Entity\Room;
use Room\Options\ModuleOptions;
use Room\Service\RoomService as RoomCredentialsService;

/**
 * Index controller
 */
class IndexController extends AbstractActionController
{
    /**
     * @var ModuleOptions
     */
    protected $options;

    /**
     * @var Doctrine\ORM\EntityManager
     */
    protected $entityManager;
    
    /**
     * @var Zend\Mvc\I18n\Translator
     */
    protected $translatorHelper;
    
    /**
     * @var Zend\Form\Form
     */
    protected $roomFormHelper;
    
    /**
     * Index action
     *
     * Method to show an Rooms
     *
     * @return Zend\View\Model\ViewModel
     */
    public function indexAction()
    {
        $rooms = $this->getEntityManager()->getRepository('Room\Entity\Room')->findall();
        return new ViewModel(array('rooms' => $rooms));
    }
    
    /**
     * Add room
     *
     * Method to add room
     *
     * @return Zend\View\Model\ViewModel
     */
    public function addAction()
    {
      
        try {
            $room = new Room;
            $identity = $this->identity();
            
            $form = $this->getRoomFormHelper()->createRoomForm($room, 'AddRoom');
            $request = $this->getRequest();
            if ($request->isPost()) {
                $form->setValidationGroup('room_code', 'room_number', 'program_time', 'room_size', 'csrf');
                $form->setData($request->getPost());
                if ($form->isValid()) {
                    $entityManager = $this->getEntityManager();
                    
                    $room->setCreatedDate(new \DateTime());
                    //var_dump($form->getData()); die(); //gives all NULL value; prob setData() not working
                    $entityManager->persist($room);
                    $entityManager->flush();
                    $this->flashMessenger()->addSuccessMessage($this->getTranslatorHelper()->translate('Room Added Successfully'));
                    return $this->redirect()->toRoute('room');                                        
                }
            }        
        }
        catch (\Exception $e) {
            return $this->getServiceLocator()->get('room_error_view')->createErrorView(
                $this->getTranslatorHelper()->translate('Something went wrong during adding room! Please, try again later.'),
                $e,
                $this->getOptions()->getDisplayExceptions(),
                false
            );
        }
        
        $viewModel = new ViewModel(array('form' => $form));
        $viewModel->setTemplate('room/index/add');
        return $viewModel;
    }
    
    /**
     * get options
     *
     * @return ModuleOptions
     */
    private function getOptions()
    {
        if (null === $this->options) {
           $this->options = $this->getServiceLocator()->get('room_module_options');
        }
            
        return $this->options;
    }

    /**
     * get entityManager
     *
     * @return EntityManager
     */
    private function getEntityManager()
    {
        if (null === $this->entityManager) {
            $this->entityManager = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
        }

        return $this->entityManager;
    }
    
    /**
     * get translatorHelper
     *
     * @return  Zend\Mvc\I18n\Translator
     */
    private function getTranslatorHelper()
    {
        if (null === $this->translatorHelper) {
           $this->translatorHelper = $this->getServiceLocator()->get('MvcTranslator');
        }
      
        return $this->translatorHelper;
    }
    
    /**
     * get roomFormHelper
     *
     * @return  Zend\Form\Form
     */
    private function getRoomFormHelper()
    {
        if (null === $this->roomFormHelper) {
           $this->roomFormHelper = $this->getServiceLocator()->get('room_form');
        }
      
        return $this->roomFormHelper;
    }
}

Now my add.phtml

<?php

$form = $this->form;

/**
 *
 * Set form fields classes and placeholders here
 *
 */

$form->setAttributes(array(
    'class' => 'form'
));

$form->get('room_code')->setAttributes(array(
    'required' => 'true',
    'class' => 'form-control input-lg', 
    'placeholder' => $this->translate('Room Code')
));

$form->get('room_number')->setAttributes(array(
    'required' => 'false',
    'class' => 'form-control input-lg', 
    'placeholder' => $this->translate('Room Number')
));

$form->get('program_time')->setAttributes(array(
    'required' => 'false',
    'class' => 'form-control input-lg', 
    'placeholder' => $this->translate('Program Time')
));

$form->get('room_size')->setAttributes(array(
    'required' => 'true',
    'class' => 'form-control input-lg', 
    'placeholder' => $this->translate('Room Size')
));

$form->get('submit')->setAttributes(array(
    'class' => 'btn btn btn-success btn-lg', 
    'value' => $this->translate('Add Room')
));


$form->prepare();
?>
<div class="">
  <h2><?php echo $this->translate('Add Room')?></h2>
    <div class="containe" id="wrap">
      <div class="row">
        <div class="col-md-12">
            <div class="form-group">
              <?php echo $this->form()->openTag($form); ?>
                <?php
                  $element = $form->get('room_code');
                  echo $this->formElement($element);
                  echo $this->formElementErrors($element);
                ?>
            </div>
            <div class="form-group row">
              <div class="col-xs-4 col-md-4">
                <?php
                  $element = $form->get('room_number');
                  echo $this->formElement($element);
                  echo $this->formElementErrors($element);
                ?>
              </div>
              <div class="col-xs-4 col-md-4">
                <?php
                  $element = $form->get('program_time');
                  echo $this->formElement($element);
                  echo $this->formElementErrors($element);
                ?>
              </div>
            <div class="col-xs-4 col-md-4">
                <?php
                  $element = $form->get('room_size');
                  echo $this->formElement($element);
                  echo $this->formElementErrors($element);
                ?>
            </div>
            </div>
            <div class="form-group row">
              <div class="col-sm-12"> 
                <?php echo $this->formRow($form->get('submit'))?>              
              </div>
            </div>
          <?php 
            echo $this->formRow($form->get('csrf'));
            echo $this->form()->closeTag();
          ?>         
        </div>
      </div>            
    </div>
</div>

Problem

When I submit the form it doesn't update the table as all post data are null. I have also tested to check if it is posting by doing var_dump($request->getPost()), and it returns all passed data. However when I check var_dump($form->getData()); after $form->isValid() it returns all NULL data.

Checked whole day and did whatever I could, but no luck whatsoever. Please help.

My guess is there is something wrong in Form file, but not sure.

Upvotes: 0

Views: 537

Answers (2)

Adarsh Khatri
Adarsh Khatri

Reputation: 358

Alright, finally after few days to narrowing down the problem found the solution.

Basically I had wrong syntax in Entity class. I was declaring my variable with "_", which was causing the problem since it was not called with my getters and setters.

For example, I had variable like $room_code and my getter/setter for this variable were:

public function setRoomCode($room_code)
{
   $this->room_code = $room_code;
   return $this;
}

public function getRoomCode()
{
   return $this->room_code;
}

Doing it Zend's correct way

$roomCode; //declaring variable.

//setter
public function setRoomCode($roomCode)
    {
       $this->roomCode = $roomCode;
       return $this;
    }

//getter
public function getRoomCode()
    {
       return $this->roomCode;
    }

It was really pity of me, but I guess it gave me really good time on learning how zend and orm work together.

I hope this will help someone in near future.

Upvotes: 1

Amit Kriplani
Amit Kriplani

Reputation: 682

Try changing these two lines

$form->setData($request->getPost());
if ($form->isValid()) {

To

//$form->setData($request->getPost());
if ($form->isValid($request->getPost())) {

Upvotes: 0

Related Questions