Matthew
Matthew

Reputation: 63

Zend plugin FlashMessenger is delayed one page refresh

I am using ZF3 and FlashMessenger plugin from zend. This plugin not required any configuration. I only override it with my custom class becouse I want to use two methods in other way:

class CustomFlashMessenger extends FlashMessenger
{
public function hasMessages($namespace = null)
{
    if (null !== $namespace) {
        return parent::hasMessages($namespace);
    }

    return parent::hasMessages('default') ||
        parent::hasMessages('error') ||
        parent::hasMessages('warning') ||
        parent::hasMessages('info') ||
        parent::hasMessages('success');
}

public function clearMessages($namespace = null)
{
    if (null !== $namespace) {
        return parent::clearMessages($namespace);
    }

    return parent::clearMessages('default') ||
        parent::clearMessages('error') ||
        parent::clearMessages('warning') ||
        parent::clearMessages('info') ||
        parent::clearMessages('success');
    }
}

It is registered in Module.php and it works fine.

My problem is, when I want to display messages to the screen:

UserController.php

    public function loginAction()
{
    $form = new LoginForm();

    if (null !== $this->identity()) {
        return $this->redirect()->toRoute('home');
    }

    if ($this->getRequest()->isPost()) {
        $data = $this->params()->fromPost();
        $form->setData($data);

        if (!$form->isValid()) {
            foreach ($form->getMessages() as $message) {
                if (is_array($message)) {
                    $message = array_pop($message);
                }
                $this->flashMessenger()->addErrorMessage($message);
            }
        }

        $data = $form->getData();
        $result = $this->authManager->login($data[ 'login' ], $data[ 'password' ], $data[ 'remember_me' ]);

        if ($result->getCode() == Result::SUCCESS) {
            return $this->redirect()->toRoute('home');
        } else {
            $this->flashMessenger()->addErrorMessage('Error');
        }
    }

    $this->layout()->setTemplate('layout/login');

    return new ViewModel(
        [
            'form' => $form,
        ]);
}

layout/login.phtml

<?php if ($this->flashMessenger()->hasMessages()) { ?>
        <div class="message">
            <?php echo $this->partial('partial/messages'); ?>
        </div>
    <?php } ?>

partial/messages.phtml

<?php
echo $this->flashMessenger()->render('info');
echo $this->flashMessenger()->render('success');
echo $this->flashMessenger()->render('warning');
echo $this->flashMessenger()->render('error');
?>

My messages to view are delayed one page refresh. Eg. scenario:

  1. Going to login page
  2. Want to login with bad password and clicking submit
  3. Page refresh and can't find any information
  4. Login with good creditentials and clicking submit
  5. I am logged in and see error message (bad password) on home page.

Upvotes: 1

Views: 627

Answers (1)

complex-space
complex-space

Reputation: 744

The flash messenger plugin is intended to displays message on the next request and is useful with e.g. the post-request-get plugin.

If your code is generating messages in the same request that renders them, then simply pass the messages through to the view model directly, no plugin needed.

return new ViewModel(
    [
        'messages' => $form->getMessages(),
        // ... other variables
    ]
);

Not related to your question, but in the loginAction i nthe code you posted, the method $this->authManager->login is called regardless of whether your form has validated or not. You may wish to put the call to that method in an else after the if (!$form->isValid()) { ...

Upvotes: 2

Related Questions