Skip to content

Commit

Permalink
fix: copy email attachment in uploads directory to tmp directory
Browse files Browse the repository at this point in the history
fixes #14
  • Loading branch information
carlalexander committed Aug 3, 2023
1 parent fd56884 commit 101f971
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/Configuration/EmailConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function modify(Container $container)
return new SesClient($container['ymir_http_client'], $container['cloud_provider_key'], $container['cloud_provider_region'], $container['cloud_provider_secret']);
});
$container['email'] = function (Container $container) {
return new Email($container['event_manager'], $container['default_email_from'], $container['phpmailer'], $container['blog_charset']);
return new Email($container['event_manager'], $container['default_email_from'], $container['file_manager'], $container['phpmailer'], $container['blog_charset']);
};
}
}
22 changes: 19 additions & 3 deletions src/Email/Email.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@

namespace Ymir\Plugin\Email;

use Ymir\Plugin\Attachment\AttachmentFileManager;
use Ymir\Plugin\EventManagement\EventManager;
use Ymir\Plugin\Support\Collection;

class Email
{
Expand Down Expand Up @@ -45,6 +47,13 @@ class Email
*/
private $eventManager;

/**
* The attachment file manager.
*
* @var AttachmentFileManager
*/
private $fileManager;

/**
* WordPress PHPMailer object.
*
Expand All @@ -55,12 +64,13 @@ class Email
/**
* Constructor.
*/
public function __construct(EventManager $eventManager, string $defaultFromAddress, \PHPMailer $mailer, string $defaultCharset = 'UTF-8', string $defaultContentType = 'text/plain')
public function __construct(EventManager $eventManager, string $defaultFromAddress, AttachmentFileManager $fileManager, \PHPMailer $mailer, string $defaultCharset = 'UTF-8', string $defaultContentType = 'text/plain')
{
$this->defaultCharset = $defaultCharset;
$this->defaultContentType = $defaultContentType;
$this->defaultFromAddress = $defaultFromAddress;
$this->eventManager = $eventManager;
$this->fileManager = $fileManager;
$this->mailer = $mailer;

// Remove some of the default values so we can check if they were set and passed through the WordPress filters
Expand All @@ -80,9 +90,15 @@ public function attachments($attachments)
throw new \InvalidArgumentException('"attachments" argument must be an array or a string');
}

foreach ($attachments as $attachment) {
(new Collection($attachments))->map(function (string $attachment) {
if ($this->fileManager->isInUploadsDirectory($attachment)) {
$attachment = $this->fileManager->copyToTempDirectory($attachment);
}

return $attachment;
})->each(function (string $attachment) {
$this->mailer->addAttachment($attachment);
}
});
}

/**
Expand Down
80 changes: 56 additions & 24 deletions tests/Unit/Email/EmailTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace Ymir\Plugin\Tests\Unit\Email;

use Ymir\Plugin\Email\Email;
use Ymir\Plugin\Tests\Mock\AttachmentFileManagerMockTrait;
use Ymir\Plugin\Tests\Mock\EventManagerMockTrait;
use Ymir\Plugin\Tests\Mock\PHPMailerMockTrait;
use Ymir\Plugin\Tests\Unit\TestCase;
Expand All @@ -23,9 +24,40 @@
*/
class EmailTest extends TestCase
{
use AttachmentFileManagerMockTrait;
use EventManagerMockTrait;
use PHPMailerMockTrait;

public function testAttachmentsCopiesUploadFilesToTmpDirectory()
{
$fileManager = $this->getAttachmentFileManagerMock();
$phpmailer = $this->getPHPMailerMock();

$fileManager->expects($this->exactly(2))
->method('isInUploadsDirectory')
->withConsecutive(
[$this->identicalTo('attachment1')],
[$this->identicalTo('attachment2')]
)
->willReturnOnConsecutiveCalls(false, true);

$fileManager->expects($this->once())
->method('copyToTempDirectory')
->with($this->identicalTo('attachment2'))
->willReturn('/tmp/attachment2');

$phpmailer->expects($this->exactly(2))
->method('addAttachment')
->withConsecutive(
[$this->identicalTo('attachment1')],
[$this->identicalTo('/tmp/attachment2')]
);

$email = new Email($this->getEventManagerMock(), 'from_address', $fileManager, $phpmailer);

$email->attachments(['attachment1', 'attachment2']);
}

public function testAttachmentsWithArray()
{
$phpmailer = $this->getPHPMailerMock();
Expand All @@ -37,7 +69,7 @@ public function testAttachmentsWithArray()
[$this->identicalTo('attachment2')]
);

$email = new Email($this->getEventManagerMock(), 'from_address', $phpmailer);
$email = new Email($this->getEventManagerMock(), 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer);

$email->attachments(['attachment1', 'attachment2']);
}
Expand All @@ -47,7 +79,7 @@ public function testAttachmentsWithInvalidArgument()
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('"attachments" argument must be an array or a string');

$email = new Email($this->getEventManagerMock(), 'from_address', $this->getPHPMailerMock());
$email = new Email($this->getEventManagerMock(), 'from_address', $this->getAttachmentFileManagerMock(), $this->getPHPMailerMock());

$email->attachments(new \stdClass());
}
Expand All @@ -63,7 +95,7 @@ public function testAttachmentsWithString()
[$this->identicalTo('attachment2')]
);

$email = new Email($this->getEventManagerMock(), 'from_address', $phpmailer);
$email = new Email($this->getEventManagerMock(), 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer);

$email->attachments("attachment1\r\nattachment2");
}
Expand All @@ -79,7 +111,7 @@ public function testBccWithArray()
[$this->identicalTo('[email protected]'), $this->identicalTo('Foo')]
);

$email = new Email($this->getEventManagerMock(), 'from_address', $phpmailer);
$email = new Email($this->getEventManagerMock(), 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer);

$email->bcc(['[email protected]', 'Foo <[email protected]>']);
}
Expand All @@ -89,7 +121,7 @@ public function testBccWithInvalidArgument()
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('"addresses" argument must be an array or a string');

$email = new Email($this->getEventManagerMock(), 'from_address', $this->getPHPMailerMock());
$email = new Email($this->getEventManagerMock(), 'from_address', $this->getAttachmentFileManagerMock(), $this->getPHPMailerMock());

$email->bcc(new \stdClass());
}
Expand All @@ -105,7 +137,7 @@ public function testBccWithString()
[$this->identicalTo('[email protected]'), $this->identicalTo('Foo')]
);

$email = new Email($this->getEventManagerMock(), 'from_address', $phpmailer);
$email = new Email($this->getEventManagerMock(), 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer);

$email->bcc('[email protected], Foo <[email protected]>');
}
Expand All @@ -120,7 +152,7 @@ public function testCharset()
->with($this->identicalTo('wp_mail_charset'), $this->identicalTo('UTF-8'))
->willReturn('filtered_UTF-8');

(new Email($eventManager, 'from_address', $phpmailer))->charset('UTF-8');
(new Email($eventManager, 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer))->charset('UTF-8');

$this->assertSame('filtered_UTF-8', $phpmailer->CharSet);
}
Expand All @@ -132,7 +164,7 @@ public function testConstructorRemovesValues()
$this->assertNotSame('', $phpmailer->CharSet);
$this->assertNotSame('', $phpmailer->ContentType);

$email = new Email($this->getEventManagerMock(), 'from_address', $phpmailer);
$email = new Email($this->getEventManagerMock(), 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer);

$this->assertSame('', $phpmailer->CharSet);
$this->assertSame('', $phpmailer->ContentType);
Expand All @@ -152,7 +184,7 @@ public function testContentTypeHtml()
->with($this->identicalTo('wp_mail_content_type'), $this->identicalTo('text/html'))
->willReturn('text/html');

(new Email($eventManager, 'from_address', $phpmailer))->contentType('text/html');
(new Email($eventManager, 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer))->contentType('text/html');

$this->assertSame('text/html', $phpmailer->ContentType);
}
Expand All @@ -171,7 +203,7 @@ public function testContentTypeNotHtml()
->with($this->identicalTo('wp_mail_content_type'), $this->identicalTo('content_type'))
->willReturn('filtered_content_type');

(new Email($eventManager, 'from_address', $phpmailer))->contentType('content_type');
(new Email($eventManager, 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer))->contentType('content_type');

$this->assertSame('filtered_content_type', $phpmailer->ContentType);
}
Expand All @@ -193,7 +225,7 @@ public function testFromWithDefaultNAme()
->method('setFrom')
->with($this->identicalTo('[email protected]'), $this->identicalTo('filtered_WordPress'), $this->identicalTo(false));

(new Email($eventManager, 'from_address', $phpmailer))->from('[email protected]');
(new Email($eventManager, 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer))->from('[email protected]');
}

public function testHeadersWithArray()
Expand Down Expand Up @@ -222,7 +254,7 @@ public function testHeadersWithArray()
->method('isHtml')
->with($this->identicalTo(false));

(new Email($eventManager, 'from_address', $phpmailer))->headers([
(new Email($eventManager, 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer))->headers([
'From: [email protected]',
'Cc: Foo <[email protected]>',
'Content-Type: content_type',
Expand All @@ -248,7 +280,7 @@ public function testHeadersWithContentTypeAndCharset()
->method('isHtml')
->with($this->identicalTo(false));

(new Email($eventManager, 'from_address', $phpmailer))->headers([
(new Email($eventManager, 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer))->headers([
'Content-Type: content_type;charset=foo_charset',
]);
}
Expand All @@ -258,7 +290,7 @@ public function testHeadersWithInvalidArgument()
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('"headers" argument must be an array or a string');

$email = new Email($this->getEventManagerMock(), 'from_address', $this->getPHPMailerMock());
$email = new Email($this->getEventManagerMock(), 'from_address', $this->getAttachmentFileManagerMock(), $this->getPHPMailerMock());

$email->headers(new \stdClass());
}
Expand All @@ -280,7 +312,7 @@ public function testHeadersWithMultipartContentType()
->method('isHtml')
->with($this->identicalTo(false));

(new Email($eventManager, 'from_address', $phpmailer))->headers([
(new Email($eventManager, 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer))->headers([
'Content-Type: multipart/mixed; boundary="----=_Part_4892_25692638.1192452070893"',
]);
}
Expand Down Expand Up @@ -311,7 +343,7 @@ public function testHeadersWithString()
->method('isHtml')
->with($this->identicalTo(false));

(new Email($eventManager, 'from_address', $phpmailer))->headers("From: [email protected]\r\nCc: Foo <[email protected]>\r\nContent-Type: content_type\r\nHeader: Value\r\nX-Mailer: foo");
(new Email($eventManager, 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer))->headers("From: [email protected]\r\nCc: Foo <[email protected]>\r\nContent-Type: content_type\r\nHeader: Value\r\nX-Mailer: foo");
}

public function testReplyToWithArray()
Expand All @@ -325,7 +357,7 @@ public function testReplyToWithArray()
[$this->identicalTo('[email protected]'), $this->identicalTo('Foo')]
);

$email = new Email($this->getEventManagerMock(), 'from_address', $phpmailer);
$email = new Email($this->getEventManagerMock(), 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer);

$email->replyTo(['[email protected]', 'Foo <[email protected]>']);
}
Expand All @@ -335,7 +367,7 @@ public function testReplyToWithInvalidArgument()
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('"addresses" argument must be an array or a string');

$email = new Email($this->getEventManagerMock(), 'from_address', $this->getPHPMailerMock());
$email = new Email($this->getEventManagerMock(), 'from_address', $this->getAttachmentFileManagerMock(), $this->getPHPMailerMock());

$email->replyTo(new \stdClass());
}
Expand All @@ -351,7 +383,7 @@ public function testReplyToWithString()
[$this->identicalTo('[email protected]'), $this->identicalTo('Foo')]
);

$email = new Email($this->getEventManagerMock(), 'from_address', $phpmailer);
$email = new Email($this->getEventManagerMock(), 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer);

$email->replyTo('[email protected], Foo <[email protected]>');
}
Expand All @@ -360,7 +392,7 @@ public function testSubject()
{
$phpmailer = $this->getPHPMailerMock();

(new Email($this->getEventManagerMock(), 'from_address', $phpmailer))->subject('Foo subject');
(new Email($this->getEventManagerMock(), 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer))->subject('Foo subject');

$this->assertSame('Foo subject', $phpmailer->Subject);
}
Expand Down Expand Up @@ -390,7 +422,7 @@ public function testToStringSetsDefaultValues()
->method('getSentMIMEMessage')
->willReturn('email');

$this->assertSame('email', (new Email($eventManager, 'from_address', $phpmailer))->toString());
$this->assertSame('email', (new Email($eventManager, 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer))->toString());
}

public function testToWithArray()
Expand All @@ -404,7 +436,7 @@ public function testToWithArray()
[$this->identicalTo('[email protected]'), $this->identicalTo('Foo')]
);

$email = new Email($this->getEventManagerMock(), 'from_address', $phpmailer);
$email = new Email($this->getEventManagerMock(), 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer);

$email->to(['[email protected]', 'Foo <[email protected]>']);
}
Expand All @@ -414,7 +446,7 @@ public function testToWithInvalidArgument()
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('"addresses" argument must be an array or a string');

$email = new Email($this->getEventManagerMock(), 'from_address', $this->getPHPMailerMock());
$email = new Email($this->getEventManagerMock(), 'from_address', $this->getAttachmentFileManagerMock(), $this->getPHPMailerMock());

$email->to(new \stdClass());
}
Expand All @@ -430,7 +462,7 @@ public function testToWithString()
[$this->identicalTo('[email protected]'), $this->identicalTo('Foo')]
);

$email = new Email($this->getEventManagerMock(), 'from_address', $phpmailer);
$email = new Email($this->getEventManagerMock(), 'from_address', $this->getAttachmentFileManagerMock(), $phpmailer);

$email->to('[email protected], Foo <[email protected]>');
}
Expand Down

0 comments on commit 101f971

Please sign in to comment.