0
votes

I am using FlashMessenger Controller/Plugin to show error messages, and that works fine. I am trying to show success messages by setting the namespace to success.

$this->flashMessenger()->addSuccessMessage('Success msg!');
$successMessages = $this->flashMessenger()->hasSuccessMessages();
print_r($successMessages);exit;
$view = new ViewModel(array('success' => $successMessages));

When i print $successMessages it shows Array() as there are no messages to show.

Same is if i try to set namespace like this.

$this->flashMessenger()->setNamespace('success')->addSuccessMessage('Success msg!');
$successMessages = $this->flashMessenger()->setNamespace('success')->getMessages();

Is this the propper way to set namespace and how to show the message on view? I am using this to show error messages, but it doesn't work with success messages.

    <?php if (!empty($this->messages)): ?>
    <?php foreach ($this->messages as $msg) : ?>
            <div class="error-box"><?php echo $this->translate($msg) ?></div>
    <?php endforeach; ?>
    <?php endif; ?>

This is my FlashMessenger class.

2

2 Answers

4
votes

It looks like you are writing and reading the messages in the same request. Think that flashMessenger is mainly meant to save messages for later, as you can read in the old but meaningful ZF1 docs:

The FlashMessenger helper allows you to pass messages that the user may need to see on the next request.

For example, you are in a request that comes from a form that is meant to add records to a list, in the controller/action that receives the form you save a record, write the message to the flashmessenger, and redirect the user to the controller/action that show the list of records again. Something that you can see in this example from the ZF2 mvc plugins docs:

public function processAction()
{
    // ... do some work ...
    $this->flashMessenger()->addMessage('You are now logged in.');
    return $this->redirect()->toRoute('user-success');
}

public function successAction()
{
    $return = array('success' => true);
    $flashMessenger = $this->flashMessenger();
    if ($flashMessenger->hasMessages()) {
        $return['messages'] = $flashMessenger->getMessages();
    }
    return $return;
}

If what you need is to read the messages in the same request (something that is also really common) you have to use the "Current Messages" methods of the helper. So, instead of calling

$this->flashMessenger()->hasSuccessMessages()

you should call

$this->flashMessenger()->hasCurrentSuccessMessages()

and instead of calling

$this->flashMessenger()->getSuccessMessages()

you should call

$this->flashMessenger()->getCurrentSuccessMessages()

You can take a look at the full list of functions, if you go to the Zend.Mvc.Controller.Plugin.FlashMessenger API docs and you search for "Current"

UPDATE

To show the messages in the view, you can use 2 approaches:

  1. Retrieve the messages in the controller and send it to the view

    In the controller

    public function yourAction() {
        return array (
          '$successMessages' 
                    => $this->flashMessenger()->getCurrentSuccessMessages()       
        );
    }
    

    In the view

    //note that getCurrentSuccessMessages() returns an array, 
    //so in the vew $successMessages is an array
    foreach ($successMessages as $m) {
       echo $m;
    }
    
  2. Retrieving directly in the view. The first thing that comes to mind is to use the FlashMessenger view helper (Zend\View\Helper \FlashMessenger), but im afraid it doesnt have a function to get the current messages. So, you can extend it, or even more, you can write your own view helper. You have here a good tutorial on how to do exactly this.

1
votes

I just tested the following in a Controller:

$this->flashMessenger()->addSuccessMessage('test');

if ($this->flashMessenger()->hasSuccessMessages()) {
    print_r($this->flashMessenger()->getSuccessMessages());
}

This resulted in Array ( [0] => test )

Based on your question it appears you have not yet called on getSuccessMessages()

To get the messages into your ViewModel you could do something like this:

$viewModel = new ViewModel();
$viewModel->setVariable('messages', ($this->flashMessenger()->hasSuccessMessages()) ? $this->flashMessenger()->getSuccessMessages() : null);

And in your View you could do this:

if (!is_null($this->messages)) {
    foreach ($this->messages as $message) {
        echo $message . "\n";
    }
}

Try reloading the page a few times to ensure that the message is visible. I personally use the EventManager (in my Controller) to check and handle messages stored in the flashMessenger(). For example:

public function setEventManager(EventManagerInterface $events)
{
    parent::setEventManager($events);

    $events->attach('dispatch', function () {
        $this->getServiceLocator()->get('translator')->setLocale('en');

        if ($this->flashMessenger()->hasMessages()) {
            $this->Flash()->Display($this->flashMessenger()->getMessages()); // Custom Controller Plugin
        }
    }, 100);
}

Hope this helps you out!