zend-framework2post-redirect-get

Prevent multiple form submission using PRG?


I need to get rid of the 'Confirm Resubmission' dialog box to prevent multiple form submissions, and also for the form validation errors automatically rendered by ZF2 to be cleared when the user refreshes the page.

I have read on ZF2's Documentation on the PRG plugin but I'm not sure how to implement it when I still want to display form errors.

This is my current code:

public function loginAction()
{
    $sm                 = $this->getServiceLocator();
    $forms              = $this->getForms();
    $viewModel          = new ViewModel();
    $viewModel->setTemplate('customer/customer/view-login-reg-form.phtml');
    $this->layout()->setVariable('title', 'Welcome!');
    $viewModel->setVariables($forms);

    $request            = $this->getRequest();
    if($request->isPost()) {
        $postData       = $request->getPost();
        $forms['formLogin']->setData($postData);
        $forms['formLogin']->setInputFilter($sm->get('Customer\Form\Filter\LoginFilter')->getInputFilter());

        if ($forms['formLogin']->isValid()) {
            $data       = $forms['formLogin']->getData();
            $customer   = $this->getCustomerTable()->getCustomer($data['login-email'], $data['login-password']);

            if (empty($customer)) {
                $viewModel->setVariable('errorMessage', 'Account does not exist');

                return $viewModel;
            }

            $LoginService = $sm->get('Customer\Service\LoginService');
            $LoginService->initLogin($customer);

            $this->handleRedirect();
        }
    }

    return $viewModel;
}

Solution

  • You can write your method as follow :

    public function loginAction()
    {
        $prg = $this->prg();
        if ($prg instanceof Response) {
            return $prg;
        }
        // here, $prg is false if multiple submissions 
        if ($prg === false) {
            // your code for init $prg or redirect to other action
        }
        // here, $prg contains post and get parameters as an array
        // You must distinguish whether this is an entry to display the form 
        // or the return to process the data returned by the submit
        // because $request is no longer available. Example :
        $forms              = $this->getForms();
        if (array_key_exists('submit', $prg) {
            $forms['formLogin']->setData($prg);
            $forms['formLogin']->setInputFilter($sm->get('Customer\Form\Filter\LoginFilter')->getInputFilter());
    
            if ($forms['formLogin']->isValid()) {
                $data       = $forms['formLogin']->getData();
                $customer   = $this->getCustomerTable()->getCustomer($data['login-email'], $data['login-password']);
    
                if (empty($customer)) {
                    $viewModel->setVariable('errorMessage', 'Account does not exist');
    
                    return $viewModel;
                }
    
                $LoginService = $sm->get('Customer\Service\LoginService');
                $LoginService->initLogin($customer);
    
                $this->handleRedirect();
            }
        }
        $viewModel          = new ViewModel();
        $viewModel->setTemplate('customer/customer/view-login-reg-form.phtml');
        $this->layout()->setVariable('title', 'Welcome!');
        $viewModel->setVariables($forms);
        return $viewModel;
    }