symfony / swiftmailer-bundle

Symfony Swiftmailer Bundle
https://symfony.com/swiftmailer-bundle
MIT License
1.56k stars 151 forks source link

Multiple delivery addresses from .env #245

Closed spasat closed 4 years ago

spasat commented 6 years ago

I would like to have delivery addresses on different environments. ex: .env DELIVERY_ADDRESSES='["email1@test.com", "email2@test.com"]' and in config/swiftmailer.yaml swiftmailer: delivery_addresses: '%env(json:DELIVERY_ADDRESSES)%'

Currently this fails because delivery_addresses expect an array but symfony transform %env(json:DELIVERY_ADDRESSES)% into a token that is parsed lately.

Is somehow a possibility to make this work?

nicoschoenmaker commented 6 years ago

We're also having problems with this.

The problem is basically that the array_filter introduced in #171 does not work because at that point the values are still represented as env_somehash_MAILER_DELIVERY_ADDRESS_somehash. Thus they are not filtered out, causing the Swift_Plugins_RedirectingPlugin to be activated.

Did manage to work around the issue (bit of a hack though). Configure swift like this:

swiftmailer:
    delivery_addresses:
        - '%env(MAILER_DELIVERY_ADDRESS)%'

That works around the initial error.

Add this class somewhere

namespace App\EventListener;

class DeliveryAddressesPlugin implements \Swift_Events_SendListener
{
    private $plugin;
    private $delivery_addresses;

    /**
     * @param \Swift_Events_SendListener $plugin
     * @param string[] $delivery_addresses
     */
    public function __construct(\Swift_Events_SendListener $plugin, array $delivery_addresses)
    {
        $this->plugin             = $plugin;
        $this->delivery_addresses = array_filter($delivery_addresses);
    }

    /**
     * {@inheritdoc}
     */
    public function beforeSendPerformed(\Swift_Events_SendEvent $evt)
    {
        if (empty($this->delivery_addresses)) {
            return;
        }
        $this->plugin->beforeSendPerformed($evt);
    }

    /**
     * {@inheritdoc}
     */
    public function sendPerformed(\Swift_Events_SendEvent $evt)
    {
        if (empty($this->delivery_addresses)) {
            return;
        }
        $this->plugin->sendPerformed($evt);
    }
}

And this to a services.yaml

services:
    App\EventListener\DeliveryAddressesPlugin:
        decorates: swiftmailer.mailer.default.plugin.redirecting
        arguments:
            - '@App\EventListener\DeliveryAddressesPlugin.inner'
            - "%swiftmailer.mailer.default.delivery_addresses%"
uwej711 commented 6 years ago

Wouldn't it be just simpler to extend the bundle configuration with a boolean that could be set with an environment variable that enables the redirecting plugin when there are delivery_addresses defined? That way you could define delivery addresses but enable and disable redirecting. But this does not solve the problem when you want to have a different number of delivery addresses in different environments. The more general solution would be to set array nodes from environment variables in symfony

jbdelhommeau commented 5 years ago

To complete this issue.

An other use case is when you want config via env var if you want to delivery_addresses or not.

Currently delivery_addresses parameter accept only array or null value.

swiftmailer:
    delivery_addresses:
        - '%env(MAILER_DELIVERY_ADDRESS)%'

In this case if %env(MAILER_DELIVERY_ADDRESS)% is null because I want to disable delivery adresses isn't possible.

With deprected parameter delivery_address it was possible to do that.

fabpot commented 4 years ago

Closing as this bundle does not accept new features anymore (Symfony Mailer is now the preferred email solution over Swiftmailer).