symfony / monolog-bundle

Symfony Monolog Bundle
symfony.com
MIT License
2.89k stars 232 forks source link

SwiftMailer handler's to_email cannot handle %env(json:FOOBAR)% #237

Open marcverney opened 7 years ago

marcverney commented 7 years ago

SwiftMailer handler's to_email config parameter is supposed to accept an array of email addresses. It works ok when the array is given literally, like:

# config.yml
handlers:
    email:
        type: 'swift_mailer'
        to_email:
            - 'foo@a.com'
            - 'bar@a.com'

However, it crashes if the array comes from an environment variable:

# .env
SUBSCRIBERS='["foo@a.com", "bar@a.com"]'

# config.yml
handlers:
    email:
        type: 'swift_mailer'
        to_email: '%env(json:SUBSCRIBERS)%'

The error is:

Array to string conversion in /srv/www/acme/vendor/egulias/email-validator/EmailValidator/Validation/RFCValidation.php:30

I think the cause is that, this parameter being dynamic, its value gets replaced by a string placeholder, something like env_json_SUBSCRIBERS_d4fb785b4f5825b62c36d8476dab783b. This is the value the Config component sees when it parses the bundle's configuration. Since it's a string, it converts it to array('env_json_SUBSCRIBERS_d4fb785b4f5825b62c36d8476dab783b'). When the actual value is finally fetched, the param then equals array(array("foo@a.com", "bar@a.com")) instead of the expected array("foo@a.com", "bar@a.com").

vudaltsov commented 6 years ago

Faced the same issue! Can be reproduced by https://github.com/vudaltsov/symfony-4-monolog-env-config

vudaltsov commented 6 years ago

This issue is going to be fixed by this PR https://github.com/symfony/symfony/pull/23888.

mhujer commented 6 years ago

Looks like it wasn't fixed by the mentioned PR.

In 4.1.0 I'm getting this:

[Symfony\Component\Config\Definition\Exception\InvalidTypeException]
  Invalid type for path "monolog.handlers.swift.to_email.0". 
  Expected one of "bool", "int", "float", "string", but got "array".
ihortymoshenko commented 6 years ago

Any updates on this?

chalasr commented 6 years ago

See https://github.com/symfony/symfony/issues/28599

TheFox commented 6 years ago

When will this be fixed?

dtfafard commented 5 years ago

According to : https://github.com/symfony/symfony/issues/28137

This is by design.

The first error is that the Configuration converts the dynamic variable string into an array :

#In Symfony\Bundle\MonologBundle\DependencyInjection\Configuration
                                ->beforeNormalization()
                                    ->ifString()
                                    ->then(function ($v) { return array($v); })

The second error, is even if it didn't do it, how json handles variables causes, arrayNode does not allow the use of dynamic values.

I've made the code work changing :

// In Symfony\Component\Config\Definition\ArrayNode
    /**
     * {@inheritdoc}
     */
    protected function allowPlaceholders(): bool
    {
        return true;  // was return false;
    }

and

// In Symfony\Bundle\MonologBundle\DependencyInjection\Configuration
->arrayNode('to_email') // swift_mailer and native_mailer
                                ->prototype('scalar')->end()
                                ->beforeNormalization()
                                    ->ifString()
                                    ->then(function ($v) { return $v; }) //Was ->then(function ($v) { return array($v); })
                                ->end()
                            ->end()

It seems that the Symfony build rejects the use of env variables in Array Nodes natively.

Can anyone give more details on this?

Thank you!

Note : Until this is fixed, I would recommend using a mailing list (single email that sends to all recipients tied to it)

shtumi commented 5 years ago

so is there any progress with this issue?

arturslogins commented 4 years ago

Any progress on this?

EmanuelOster commented 1 year ago

I also took a look at this. As a solution, I came up with using a custom email_prototype as a workaround. Example: monolog.yaml:

  symfony_mailer:
      type: symfony_mailer
      email_prototype: 'App\Email\ErrorMailPrototype'
      level: debug
      formatter: monolog.formatter.html
      content_type: text/html

App\Email\ErrorMailPrototype:

class ErrorMailPrototype extends Email
{
    /**
     * @param string[] $toArray
     */
    #[Required]
    public function setDefaults(
        #[Autowire('%env(csv:APP_ERROR_MAIL_RECIPIENTS)%')] array $toArray,
        #[Autowire('%env(APP_ERROR_MAIL_SENDER)%')] string $from,
    ): void {
        $this->to(...$toArray);
        $this->from($from);
        $this->subject('An Error Occurred! %message%');
    }
}