Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FRAMEWORK method addFlash definition in AbstractController differs from underlying FlashBag->add #34645

Closed
crayner opened this issue Nov 27, 2019 · 2 comments · Fixed by #36913

Comments

@crayner
Copy link

crayner commented Nov 27, 2019

Symfony version(s) affected: 4.4.0 - 5.0

Description
The addFlash method in the AbstractController (5.0) and the ControllerTrait (4.4) limit the definition of a message to a string, but the Flashbag itself does not limit the message by type at all.

The addFlash in the controller method is:

 
    /**
     * Adds a flash message to the current session for type.
     *
     * @throws \LogicException
     */
    protected function addFlash(string $type, string $message): void
    {
        if (!$this->container->has('session')) {
            throw new \LogicException('You can not use the addFlash method if sessions are disabled. Enable them in "config/packages/framework.yaml".');
        }
        $this->container->get('session')->getFlashBag()->add($type, $message);
    }

and the Flashbag method is

    /**
     * {@inheritdoc}
     */
    public function add(string $type, $message)
    {
        $this->flashes[$type][] = $message;
    }

I have been using the Flashbag with a Message as an array [message, params, domain] and twig just looks for an iterable message and renders appropriately with translation.

How to reproduce
Any controller code that uses addFlash must use a string ONLY for the message.

Possible Solution
Remove the restriction on the addFlash so that addFlash and FlashBag->add are defined equally.

    /**
     * Adds a flash message to the current session for type.
     *
     * @throws \LogicException
     */
    protected function addFlash(string $type, $message): void
    {
        if (!$this->container->has('session')) {
            throw new \LogicException('You can not use the addFlash method if sessions are disabled. Enable them in "config/packages/framework.yaml".');
        }
        $this->container->get('session')->getFlashBag()->add($type, $message);
    }

Additional context
I would vote for allowing the addFlash to not be limited to only strings. An example of my current flash renderer in TWIG is:

{% trans_default_domain 'messages' %}
{% for label, messages in app.flashes %}
    {% for message in messages %}
        <div class="{{ label }}" id="message{{ label ~ loop.index0 }}">
            {% if message is iterable %}
                {{ message[0]|trans(message[1]|default({}), message[2]|default('messages')) }}
            {% else %}
                {{ message|trans }}
            {% endif %}
            {% if close_message is not defined or close_message %}
                <button class="button close {{ label }}" title="Close Message" type="button" onclick="closeMessage('message{{ label ~ loop.index0 }}')">
                    <span class="fas fa-times-circle fa-fw {{ label }}"></span>
                </button>
            {% endif %}
        </div>
        <script>
            function closeMessage(id){
                var element = document.getElementById(id)
                element.classList.toggle("hidden");
            }
        </script>
    {% endfor %}
{% endfor %}

Appreciate any feedback!

Craig

@crayner crayner changed the title FRAMEWORK addFlash definition in AbstractController Limits the message to a string. FRAMEWORK method addFlash definition in AbstractController differs from underlying FlashBag->add Nov 27, 2019
@ro0NL
Copy link
Contributor

ro0NL commented Nov 29, 2019

more or less duplicates #28991 :)

AFAIK we should loosen ControllerTrait, as per https://github.com/symfony/symfony/issues/28991#issuecomment-441358703`, for consistency.

Ultimately users are in control, and responsible if e.g messages are valid payload/serializable/etc.

Perhaps, given the type is mixed at the API level, simply renaming $message to $payload (or $data) would clarify 🤔 nowhere we refer e.g. a FlashMessageBag.. it's just a FlashBag.

fabpot added a commit that referenced this issue Jun 10, 2020
…addFlash() (ThomasLandauer)

This PR was merged into the 3.4 branch.

Discussion
----------

[FrameworkBundle] fix type annotation on ControllerTrait::addFlash()

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | no
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #28991 Fix #34645
| License       | MIT
| Doc PR        | not yet, see below

Removing `string` type-hint of $message at addFlash()

Closes #28991 and #34645

Reasons:

* `addFlash()` is just a convenience shortcut for `FlashBagInterface::add()` which doesn't have the type hint: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/Session/Flash/FlashBagInterface.php#L28 . So removing it here improves consistency.

* #28991 (comment) is a valid use case for having an object as `$message`.

* Twig doesn't have any rendering helpers for the `message`, see https://symfony.com/doc/current/controller.html#flash-messages . And since users have to take care of displaying the `message` themselves, there's no reason to force a string upon them.

* This isn't a real new feature, but it isn't a bugfix either ;-)
* I didn't update `src/**/CHANGELOG.md` yet.
* I'm not sure if it's necessary to update the docs. Maybe a short note https://symfony.com/doc/current/controller.html#flash-messages ?

Commits
-------

dfb4614 Update AbstractController.php
symfony-splitter pushed a commit to symfony/framework-bundle that referenced this issue Jun 10, 2020
Removing `string` type-hint of $message at addFlash()

Closes symfony/symfony#28991 and symfony/symfony#34645

Reasons:

* `addFlash()` is just a convenience shortcut for `FlashBagInterface::add()` which doesn't have the type hint: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/Session/Flash/FlashBagInterface.php#L28 . So removing it here improves consistency.

* symfony/symfony#28991 (comment) is a valid use case for having an object as `$message`.

* Twig doesn't have any rendering helpers for the `message`, see https://symfony.com/doc/current/controller.html#flash-messages . And since users have to take care of displaying the `message` themselves, there's no reason to force a string upon them.
@fabpot fabpot closed this as completed Jun 10, 2020
@crayner
Copy link
Author

crayner commented Jun 10, 2020

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants