responsiv / campaign-plugin

[PREMIUM] Send professional campaign messages to your subscribers.
http://octobercms.com/plugin/responsiv-campaign
5 stars 2 forks source link

Can't send test email: mkdir error #49

Closed smartscripts-nl closed 3 years ago

smartscripts-nl commented 6 years ago

When trying to send a test email, online I get an error message: "mkdir(): no such file or directory." All directories on my site are writable (because I run PHP in FPM mode).

Locally, in my development installation of October, I don't have this problem.

Nowhere in error logs has been stored additional information about this error. Does anyone have a clue what may have caused this?

daftspunk commented 6 years ago

This may be related to the file based caching driver that is used. We'd need to see the full stack trace to be sure. Does it give the destination path for mkdir or is it empty?

smartscripts-nl commented 6 years ago

It does not give a destination path, it is empty. I am now trying to debug this error remotely. If I find the cause I'll report back.

smartscripts-nl commented 6 years ago

The error is thrown in \Swift_KeyCache_DiskKeyCache::prepareCache(). $this->path there is /tmp. The temporary directory Swift tries to write there it is not being recognized as a directory (is_dir) and also creating the dir (mkdir) doesn't succeed. Hence the error.

Probably caused by wrong permissions?

smartscripts-nl commented 6 years ago

The strange fact is that a simple test script with only this statement causes no problems:

echo is_dir(sys_get_temp_dir());

So the /tmp directory is accessible. But appently the tempory dir that Swift needs to write inside this dir can't be written?

smartscripts-nl commented 6 years ago

I've tested this: my server doesn't allow the creation of directories inside /tmp. I think this is a very reasonable restriction.

smartscripts-nl commented 6 years ago

For now I've solved this problem by modifying vendor/swiftmailer/swiftmailer/lib/preferences.php:

I've commented out this block of code: if (@is_writable($tmpDir = sys_get_temp_dir())) { $preferences->setTempDir($tmpDir)->setCacheType('disk'); }

and I've replaced it by this:

$preferences->setTempDir($_SERVER['DOCUMENT_ROOT'] . '/[OctoberInstallationDir]/storage/temp')->setCacheType('disk');

After that my test mail was being sent correctly.

smartscripts-nl commented 6 years ago

But now I have still the same problem for sending campaigns via a cron job. It seems I have to add some hard coded statements to vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php to not try to write a directory to /tmp anymore.

smartscripts-nl commented 6 years ago

My hunch turned out to be correct: in the contructor of DiskKeyCache.php I had to replace:

$this->path = $path;

with:

$this->path = dirname(__DIR__, 7) . '/storage/temp';

to make sending campaigns via the scheduler work. So this code in fact points to the directory [OctoberInstallationDir]/storage/temp.

The many dirname calls are needed because $_SERVER['DOCUMENT_ROOT'] is not available when running PHP via a cronjob.

elzix commented 5 years ago

Finally found a permanent fix: swiftmailer/lib/preferences.php looks for tmp dir on line 18 $tmp = getenv('TMPDIR');

So you just need to set the environment tmp dir in your index or config file putenv("TMPDIR=/your/path/to/tmp");