Swiftmailer to Symfonymailer timeout expansion / yii2 log email target

In my development server, I was setting up the recommended way of extending Symfony Mailer with the timeout feature, but when in use, I run into:

Cannot assign string to property yii\symfonymailer\Mailer::$transportFactory of type ?Symfony\Component\Mailer\Transport

I followed the instructions from https://github.com/yiisoft/yii2-symfonymailer#migrating-from-yiisoftyii2-swiftmailer. Any thoughts and/or suggestions would be appreciated.

With knowing this, I attempted to setup Symfony Mailer in a live production. And ran into issues with the logging feature from Yii2:

PHP Warning: Attempt to read property “enabled” on array in /vendor/yiisoft/yii2/log/Dispatcher.php on line 190

Does anyone know how to setup Symfony Mailer with Yii2 - Logger? that won’t cause errors?

Geez thanks!

Geez thanks…

Furthermore, the explanation given for setting timeout feature migrating-from-yiisoftyii2-swiftmailer shows:

namespace app\utils; //file is in utils folder of your application
use Symfony\Component\Messenger\Transport\TransportFactoryInterface;

which gives the impression that SymfonyMessager might be needed, (but is not mentioned in the documentation) so as a precautionary I installed SymfonyMesanger, see if it would change the error message occurring. Same error as before:

TypeError Cannot assign string to property yii\symfonymailer\Mailer::$transportFactory of type ?Symfony\Component\Mailer\Transport

On my live production, I’m sending logs via email with Yii-Log-Emailtarget. Disabling this option stops the error message:

PHP Warning: Attempt to read property “enabled” on array in /vendor/yiisoft/yii2/log/Dispatcher.php on line 190

I’m interested in updating and knowing how to expand on adding features I was already using with SwiftMailer.

Both development and live are running on PHP 8.1. If anyone has thoughts on this, or having similar problem. I’m interested in hearing from you.

I ended up doing a fresh install of Yii on my development machine. Adding only what was from the readme for yii2-sympfonymailer.

namespace app\utils; //file is in utils folder of your application
use Symfony\Component\Messenger\Transport\TransportFactoryInterface;

class CustomSmtpFactory implements TransportFactoryInterface
{
	public function __construct(private TransportFactoryInterface $factory, private float $timeout)
	{
		$this->timeout = 120;
	}
	
	public function create(Dsn $dsn): TransportInterface
	{
		$result = $this->factory->create($dsn);
		if ($result instanceof SmtpTransport) {
		
			//Setup timeout to this or 
			$result->getStream()->setTimeout($this->timeout);
		}
		
		return $result;
	}
	
	public function supports(Dsn $dsn): bool
	{
		return $this->factory->supports($dsn);
	}
}

And configured it as suggested.

'mailer' => [
       'class' => yii\symfonymailer\Mailer::class,
       'transportFactory' => app\utils\CustomSmtpFactory::class,
        'transport' => [
            'scheme' => 'smtp',
            //other settings
        ],
],

and I get…

Setting unknown property: yii\symfonymailer\Mailer::transportFactory

Newest version of Yii2 running on php 8.1.
I don’t know if I should be writing a bug report, or I’m just misunderstanding something.

you should post your code and config removing sensitive info

I’ve installed two fresh, nothing altered, versions of Yii2, usinging the following:

composer create-project --prefer-dist --stability=dev yiisoft/yii2-app-basic yii2-bugA

Thats installed:

  • yiisoft/yii2 (dev-master 94e83d3)
  • symfony/mailer (6.0.x-dev cd60799)

and
composer create-project --prefer-dist yiisoft/yii2-app-basic yii2-bugB

Thats installed:

  • yiisoft/yii2 (2.0.49.3)
  • yiisoft/yii2-symfonymailer (2.0.4)

Taking from https://github.com/yiisoft/yii2-symfonymailer example code in the readme.

Copying and pasting the timeout example code into my two test apps… “app/utils/CustomSmtpFactory.php” and adding the recommended configuration. I still receive the error:

Unknown Property – yii\base\UnknownPropertyException Setting unknown property: yii\symfonymailer\Mailer::transportFactory

I’ve attempted different configurations, tried digging into Symfony and its documentation. I’m convinced this is a bug and at this point in time wrote a bug report @ github regarding it. That can be seen here.

Thanks

This one should not work with Examples shown in the docs, which are for mailer 3.0.x
Please install latest Yii stable with mailer v3.x as shown in documentation.

One more reminder, you have to share your code and configuration to get further help. Unless of course you expect no help.

Good eye, appreciate that. Checked and updated SymfonyMailer to version 3. The two yii2 bug/test applications I installed for this purpose only. With all this said the error that continues is:

Cannot assign string to property yii\symfonymailer\Mailer::$transportFactory of type ?Symfony\Component\Mailer\Transport

All code is from a freshly downloaded yii2 basic application, installed and updated using composer. I’ll stick with SwiftMailer for time being.

Thank you @evstevemd for the suggestions.

Sorry cannot help with further information

Application ‘A’ is running:

  • minimum-stability": “dev”
  • yiisoft/yii2": ~2.0.45
  • yiisoft/yii2-symfonymailer": "3.0.x-dev

Application ‘B’ is running:

  • minimum-stability": “stable”
  • yiisoft/yii2: “~2.0.45”
  • yiisoft/yii2-symfonymailer": “^3.0”

Both applications are running on freshly installed yii2-app-basic, using composer to install and update. Both applications are using the same configuration, shown below:

        'mailer' => [
            'class' => \yii\symfonymailer\Mailer::class,
            'transportFactory' => app\utils\CustomSmtpFactory::class,// causes the type error.
            'viewPath' => '@app/mail',
            // send all mails to a file by default.
            'useFileTransport' => true,
            'transport' => [
            	'scheme' => 'smtp',
            	//other settings
            	'dsn' => 'native://default',
            ],
        ],

The error:

TypeError
	Cannot assign string to property yii\symfonymailer\Mailer::$transportFactory of type ?Symfony\Component\Mailer\Transport

Both yii2-SynfonyMailer work until I try the transportFactory, and only use the code given as a example from the readme for the timeout option. The CustomSmtpFactory.php code that is saved in ‘app/utils’

<?php
namespace app\utils; //file is in utils folder of your application

use Symfony\Component\Messenger\Transport\TransportFactoryInterface;

class CustomSmtpFactory implements TransportFactoryInterface {
    public function __construct(private TransportFactoryInterface $factory, private float $timeout)
    {
        $this->timeout = 120;
    }

    public function create(Dsn $dsn): TransportInterface
    {
        $result = $this->factory->create($dsn);
        if ($result instanceof SmtpTransport) {
            //Setup timeout to this or 
            $result->getStream()->setTimeout($this->timeout);
        }
        return $result;
    }

    public function supports(Dsn $dsn): bool {
        return $this->factory->supports($dsn);
    }
}

SiteController.php

    public function actionContact()
    {
        $model = new ContactForm();
        if ($model->load(Yii::$app->request->post()) && $model->contact(Yii::$app->params['adminEmail'])) {
            Yii::$app->session->setFlash('contactFormSubmitted');

            return $this->refresh();
        }
        return $this->render('contact', [
            'model' => $model,
        ]);
    }

ContactFoam.php

<?php

namespace app\models;

use Yii;
use yii\base\Model;

/**
 * ContactForm is the model behind the contact form.
 */
class ContactForm extends Model
{
    public $name;
    public $email;
    public $subject;
    public $body;
    public $verifyCode;


    /**
     * @return array the validation rules.
     */
    public function rules()
    {
        return [
            // name, email, subject and body are required
            [['name', 'email', 'subject', 'body'], 'required'],
            // email has to be a valid email address
            ['email', 'email'],
            // verifyCode needs to be entered correctly
            ['verifyCode', 'captcha'],
        ];
    }

    /**
     * @return array customized attribute labels
     */
    public function attributeLabels()
    {
        return [
            'verifyCode' => 'Verification Code',
        ];
    }

    /**
     * Sends an email to the specified email address using the information collected by this model.
     * @param string $email the target email address
     * @return bool whether the model passes validation
     */
    public function contact($email)
    {
        if ($this->validate()) {
            Yii::$app->mailer->compose()
                ->setTo($email)
                ->setFrom([Yii::$app->params['senderEmail'] => Yii::$app->params['senderName']])
                ->setReplyTo([$this->email => $this->name])
                ->setSubject($this->subject)
                ->setTextBody($this->body)
                ->send();

            return true;
        }
        return false;
    }
}

At which time do you get the error?
Tried to create same config and app loads fine.
Do you get it during sending?

I’ve been using the contact foam for testing, so yes when sending the error comes up.

OK, I will test it later and see the issue and possibly fix it