bug #30718 [Mime] Fix serialization of Message instances (fabpot)

This PR was merged into the 4.3-dev branch.

Discussion
----------

[Mime] Fix serialization of Message instances

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | yes
| New feature?  | no <!-- don't forget to update src/**/CHANGELOG.md files -->
| BC breaks?    | no     <!-- see https://symfony.com/bc -->
| Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tests pass?   | yes    <!-- please add some, will be required by reviewers -->
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | n/a

Commits
-------

f5386ffb2a [Mime] fixed serialization of Message instances
This commit is contained in:
Fabien Potencier 2019-03-27 08:00:39 +01:00
commit 19c6639452
5 changed files with 92 additions and 27 deletions

View File

@ -84,4 +84,22 @@ class TemplatedEmail extends Email
{
return $this->context;
}
/**
* @internal
*/
public function __serialize(): array
{
return [$this->template, $this->htmlTemplate, $this->textTemplate, $this->context, parent::__serialize()];
}
/**
* @internal
*/
public function __unserialize(array $data): void
{
[$this->template, $this->htmlTemplate, $this->textTemplate, $this->context, $parentData] = $data;
parent::__unserialize($parentData);
}
}

View File

@ -22,4 +22,18 @@ class TemplatedEmailTest extends TestCase
$email->htmlTemplate($template = 'html');
$this->assertEquals($template, $email->getHtmlTemplate());
}
public function testSerialize()
{
$email = (new TemplatedEmail())
->textTemplate('text.txt.twig')
->htmlTemplate('text.html.twig')
->context($context = ['a' => 'b'])
;
$email = unserialize(serialize($email));
$this->assertEquals('text.txt.twig', $email->getTextTemplate());
$this->assertEquals('text.html.twig', $email->getHtmlTemplate());
$this->assertEquals($context, $email->getContext());
}
}

View File

@ -543,20 +543,11 @@ class Email extends Message
return $this;
}
public function __sleep()
/**
* @internal
*/
public function __serialize(): array
{
$this->_headers = $this->getHeaders();
$this->_raw = false;
if (null !== $body = parent::getBody()) {
$r = new \ReflectionProperty(Message::class, 'body');
$r->setAccessible(true);
$this->_body = $r->getValue($this);
$this->_raw = true;
return ['_raw', '_headers', '_body'];
}
if (\is_resource($this->text)) {
if (stream_get_meta_data($this->text)['seekable'] ?? false) {
rewind($this->text);
@ -583,22 +574,16 @@ class Email extends Message
}
}
return ['_raw', '_headers', 'text', 'textCharset', 'html', 'htmlCharset', 'attachments'];
return [$this->text, $this->textCharset, $this->html, $this->htmlCharset, $this->attachments, parent::__serialize()];
}
public function __wakeup()
/**
* @internal
*/
public function __unserialize(array $data): void
{
$r = new \ReflectionProperty(Message::class, 'headers');
$r->setAccessible(true);
$r->setValue($this, $this->_headers);
unset($this->_headers);
[$this->text, $this->textCharset, $this->html, $this->htmlCharset, $this->attachments, $parentData] = $data;
if ($this->_raw) {
$r = new \ReflectionProperty(Message::class, 'body');
$r->setAccessible(true);
$r->setValue($this, $this->_body);
unset($this->_body);
}
unset($this->_raw);
parent::__unserialize($parentData);
}
}

View File

@ -129,4 +129,20 @@ class Message extends RawMessage
{
return bin2hex(random_bytes(16)).strstr($email, '@');
}
/**
* @internal
*/
public function __serialize(): array
{
return [$this->headers, $this->body];
}
/**
* @internal
*/
public function __unserialize(array $data): void
{
[$this->headers, $this->body] = $data;
}
}

View File

@ -16,7 +16,7 @@ namespace Symfony\Component\Mime;
*
* @experimental in 4.3
*/
class RawMessage
class RawMessage implements \Serializable
{
private $message;
@ -52,4 +52,36 @@ class RawMessage
}
$this->message = $message;
}
/**
* @internal
*/
final public function serialize()
{
return serialize($this->__serialize());
}
/**
* @internal
*/
final public function unserialize($serialized)
{
$this->__unserialize(unserialize($serialized));
}
/**
* @internal
*/
public function __serialize(): array
{
return [$this->message];
}
/**
* @internal
*/
public function __unserialize(array $data): void
{
[$this->message] = $data;
}
}