Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Added a flashmessage listener
  • Loading branch information
Miliooo committed Oct 17, 2013
commit 9e02547b460068946e804b7a24088d3b81d00800
8 changes: 8 additions & 0 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ public function getConfigTreeBuilder()
->scalarNode('spam_detector')->defaultValue('fos_message.noop_spam_detector')->cannotBeEmpty()->end()
->scalarNode('twig_extension')->defaultValue('fos_message.twig_extension.default')->cannotBeEmpty()->end()
->scalarNode('user_transformer')->defaultValue('fos_user.user_to_username_transformer')->cannotBeEmpty()->end()
->arrayNode('flash_messages')
->addDefaultsIfNotSet()
->children()
->booleanNode('show')->defaultValue(false)->end()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be enabled for consistency with Symfony nodes. As of 2.3, there is even 2 shortcut methods for array nodes: canBeEnabled() and canBeDisabled(), which handle the call to addDefaultsIfNotSet() and setting the enabled with a default value (but you cannot use them yet as the bundle still need to support 2.2)

->scalarNode('flash_key')->defaultNull()->cannotBeEmpty()->end()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cannotBeEmpty looks weird as the code allows using an empty key

->scalarNode('service')->defaultValue('fos_message.flash_listener.default')->cannotBeEmpty()->end()
->end()
->end()
->arrayNode('search')
->addDefaultsIfNotSet()
->children()
Expand Down
11 changes: 11 additions & 0 deletions DependencyInjection/FOSMessageExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,16 @@ public function load(array $configs, ContainerBuilder $container)

$container->getDefinition('fos_message.recipients_data_transformer')
->replaceArgument(0, new Reference($config['user_transformer']));

if($config['flash_messages']['show'])
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this curly brace should be on the previous line

$loader->load('flash.xml');
$container->setAlias('fos_message.flash_listener', $config['flash_messages']['service']);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the alias is useless as we will never reference it (it is an event listener, not a dependency for other services). The event dispatcher will use the service id itself when reading tags

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If @merk agrees I'll undo those changes. I also don't think it's really something users will want to overwrite. Then again there are always strange use cases...

if($config['flash_messages']['flash_key'] !== null)
{
$container->getDefinition('fos_message.flash_listener.default')
->replaceArgument(2, $config['flash_messages']['flash_key']);
}
}
}
}
89 changes: 89 additions & 0 deletions EventListener/FlashListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php
namespace FOS\MessageBundle\EventListener;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use FOS\MessageBundle\Event\FOSMessageEvents;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\EventDispatcher\Event;

/**
* The flash listener adds flash messages when certain message events occur
*
* @author Michiel Boeckaert <[email protected]>
*/
class FlashListener implements EventSubscriberInterface
{
private static $successMessages = array(
FOSMessageEvents::POST_SEND => 'flash_post_send_success',
FOSMessageEvents::POST_DELETE => 'flash_thread_delete_success',
FOSMessageEvents::POST_UNDELETE => 'flash_thread_undelete_success',
);

/**
* Translator
*
* @var TranslatorInterface
*/
protected $translator;

/**
* Session
*
* @var Session
*/
protected $session;

/**
* Constructor.
*
* @param Session $session The current session
* @param TranslatorInterface $translator A translator instance
* @param string $key An optional flashBag key which overwrites the default key
*/
public function __construct(Session $session, TranslatorInterface $translator, $key = '')
{
$this->session = $session;
$this->translator = $translator;
if (empty($key)) {
$this->key = 'success';
} else {
$this->key = $key;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think making the key configurable is really needed. As Symfony 2.1+ supports putting multiple flash messages per type, it is quite logical to use success, error and warning as type IMO instead of inventing weird ones

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or I'm doing something silly but my theme has multiple places where I want to show a flash message.

I'm not sure how I would handle that with only a flash bag that has success, error and warning. How could I know then where to show them? Personally I set the key to 'message_info'. And then in my layout i check for message_info flashes on the messenger pages. So then I can show them in the right place and I know they are 'message flashes' not other ones...

But I agree for most it would be overkill... or again maybe I do something wrong

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can solve this by extending the listener in your own app and overriding the functions that actually add flashes. Maybe move it to a getKey method which can be overridden.

}
}

/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return array(
FOSMessageEvents::POST_SEND => 'addSuccessFlash',
FOSMessageEvents::POST_DELETE => 'addSuccessFlash',
FOSMessageEvents::POST_UNDELETE => 'addSuccessFlash'
);
}

/**
* Adds a flashmessage to the session
*
* @param Event $event The current event
*
* @throws \InvalidArgumentException
*/
public function addSuccessFlash(Event $event)
{
$eventName = $event->getname();

if (!isset(self::$successMessages[$eventName])) {
throw new \InvalidArgumentException('This event does not correspond to a known flash message');
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spacing


$this->session->getFlashBag()->add($this->key, $this->trans(self::$successMessages[$eventName]));
}

private function trans($message, array $params = array())
{
return $this->translator->trans($message, $params, 'FOSMessageBundle');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not enough spaces :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Damn i'm starting to count them by hand till i fix my editor 😢

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can install phpcs as a pear package which will list all these issues
for you if that helps

On Fri, Oct 18, 2013 at 11:47 AM, Miliooo [email protected] wrote:

In EventListener/FlashListener.php:

  • \* @throws \InvalidArgumentException
    
  • */
    
  • public function addSuccessFlash(Event $event)
  • {
  •    $eventName = $event->getname();
    
  •    if (!isset(self::$successMessages[$eventName])) {
    
  •        throw new \InvalidArgumentException('This event does not correspond to a known flash message');
    
  •    }
    
  •    $this->session->getFlashBag()->add($this->key, $this->trans(self::$successMessages[$eventName]));
    
  • }
  • private function trans($message, array $params = array())
  • {
  •   return $this->translator->trans($message, $params, 'FOSMessageBundle');
    

Damn i'm starting to count them by hand till i fix my editor [image:
😢]


Reply to this email directly or view it on GitHubhttps://github.com//pull/183/files#r7052132
.

}
}
18 changes: 18 additions & 0 deletions Resources/config/flash.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>

<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>

<service id="fos_message.flash_listener.default" class="FOS\MessageBundle\EventListener\FlashListener">
<argument type="service" id="session" />
<argument type="service" id="translator" />
<argument></argument>
<tag name="kernel.event_subscriber" />
</service>

</services>

</container>
4 changes: 4 additions & 0 deletions Resources/translations/FOSMessageBundle.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ by: By %sender%
no_thread: There is no thread to show
delete: Delete
undelete: Undelete

flash_post_send_success: Your message has been sent
flash_thread_delete_success: The thread has been deleted
flash_thread_undelete_success: The thread has been restored
4 changes: 4 additions & 0 deletions Resources/translations/FOSMessageBundle.nl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ on: Op %date%
by: Door %sender%
no_thread: Geen onderwerpen gevonden
delete: Verwijder

flash_post_send_success: Jouw bericht werd succesvol verzonden
flash_thread_delete_success: Onderwerp werd verwijderd
flash_thread_undelete_success: Onderwerp niet langer verwijderd
85 changes: 85 additions & 0 deletions Tests/EventListener/FlashListenerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php
namespace FOS\MessageBundle\Tests\EventListener;

use FOS\MessageBundle\EventListener\FlashListener;
use FOS\MessageBundle\Event\FOSMessageEvents;

/**
* Test for the Flash listener
*
* @author Michiel Boeckaert <[email protected]>
*/
class FlashListenerTest extends \PHPUnit_Framework_TestCase
{
private $listener;
private $session;
private $translator;
private $event;

public function setUp()
{
$this->event = $this->getMock('Symfony\Component\EventDispatcher\Event');

//if we use the interface getflashbag returns an error...
$this->session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\Session')->disableOriginalConstructor()->getMock();
$this->translator = $this->getMock('Symfony\Component\Translation\TranslatorInterface');
$this->listener = new FlashListener($this->session, $this->translator);
}

/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage This event does not correspond to a known flash message
*/
public function testAddFlashWithNonSupportedEvent()
{
$this->event->expects($this->once())->method('getName')->will($this->returnValue('foo'));
$this->listener->addSuccessFlash($this->event);
}

public function testAddFlashOnValidEventWithDefaultKey()
{
$flashbagMock = $this->getMock('Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface');

$this->event->expects($this->once())->method('getName')->will($this->returnValue(FOSMessageEvents::POST_SEND));

$this->translator->expects($this->once())
->method('trans')
->with('flash_post_send_success', array(), 'FOSMessageBundle')
->will($this->returnValue('translatedString'));

$this->session->expects($this->once())
->method('getFlashBag')
->will($this->returnValue($flashbagMock));

$flashbagMock->expects($this->once())
->method('add')
->with('success', 'translatedString');

$this->listener->addSuccessFlash($this->event);
}

public function testAddFlashOnValidEventWithCustomKey()
{
$customKey = 'message_info';
$flashbagMock = $this->getMock('Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface');

$this->listener = new FlashListener($this->session, $this->translator, $customKey);

$this->event->expects($this->once())->method('getName')->will($this->returnValue(FOSMessageEvents::POST_SEND));

$this->translator->expects($this->once())
->method('trans')
->with('flash_post_send_success', array(), 'FOSMessageBundle')
->will($this->returnValue('translatedString'));

$this->session->expects($this->once())
->method('getFlashBag')
->will($this->returnValue($flashbagMock));

$flashbagMock->expects($this->once())
->method('add')
->with($customKey, 'translatedString');

$this->listener->addSuccessFlash($this->event);
}
}