Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit07a54d2

Browse files
committed
[Mime] Simplify adding Parts to an Email
1 parent0ca5051 commit07a54d2

File tree

13 files changed

+85
-133
lines changed

13 files changed

+85
-133
lines changed

‎src/Symfony/Bridge/Twig/Tests/Mime/TemplatedEmailTest.php‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,16 @@ public function testSymfonySerialize()
7474
"htmlCharset": null,
7575
"attachments": [
7676
{
77+
"filename": "test.txt",
78+
"mediaType": "application",
7779
"body": "Some Text file",
80+
"charset": null,
81+
"subtype": "octet-stream",
82+
"disposition": "attachment",
7883
"name": "test.txt",
79-
"content-type": null,
80-
"inline": false
84+
"encoding": "base64",
85+
"headers": [],
86+
"class": "Symfony\\\Component\\\Mime\\\Part\\\DataPart"
8187
}
8288
],
8389
"headers": {

‎src/Symfony/Bridge/Twig/composer.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
"symfony/security-core":"^5.4|^6.0",
4444
"symfony/security-csrf":"^5.4|^6.0",
4545
"symfony/security-http":"^5.4|^6.0",
46-
"symfony/serializer":"^5.4|^6.0",
46+
"symfony/serializer":"^6.2",
4747
"symfony/stopwatch":"^5.4|^6.0",
4848
"symfony/console":"^5.4|^6.0",
4949
"symfony/expression-language":"^5.4|^6.0",

‎src/Symfony/Component/Mailer/composer.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"psr/event-dispatcher":"^1",
2222
"psr/log":"^1|^2|^3",
2323
"symfony/event-dispatcher":"^5.4|^6.0",
24-
"symfony/mime":"^5.4|^6.0",
24+
"symfony/mime":"^6.2",
2525
"symfony/service-contracts":"^1.1|^2|^3"
2626
},
2727
"require-dev": {

‎src/Symfony/Component/Mime/Email.php‎

Lines changed: 14 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -326,25 +326,15 @@ public function getHtmlCharset(): ?string
326326
*/
327327
publicfunctionattach($body,string$name =null,string$contentType =null):static
328328
{
329-
if (!\is_string($body) && !\is_resource($body)) {
330-
thrownew \TypeError(sprintf('The body must be a string or a resource (got "%s").',get_debug_type($body)));
331-
}
332-
333-
$this->cachedBody =null;
334-
$this->attachments[] = ['body' =>$body,'name' =>$name,'content-type' =>$contentType,'inline' =>false];
335-
336-
return$this;
329+
return$this->attachPart(newDataPart($body,$name,$contentType));
337330
}
338331

339332
/**
340333
* @return $this
341334
*/
342335
publicfunctionattachFromPath(string$path,string$name =null,string$contentType =null):static
343336
{
344-
$this->cachedBody =null;
345-
$this->attachments[] = ['path' =>$path,'name' =>$name,'content-type' =>$contentType,'inline' =>false];
346-
347-
return$this;
337+
return$this->attachPart(newDataPart('file://'.$path,$name,$contentType));
348338
}
349339

350340
/**
@@ -354,25 +344,15 @@ public function attachFromPath(string $path, string $name = null, string $conten
354344
*/
355345
publicfunctionembed($body,string$name =null,string$contentType =null):static
356346
{
357-
if (!\is_string($body) && !\is_resource($body)) {
358-
thrownew \TypeError(sprintf('The body must be a string or a resource (got "%s").',get_debug_type($body)));
359-
}
360-
361-
$this->cachedBody =null;
362-
$this->attachments[] = ['body' =>$body,'name' =>$name,'content-type' =>$contentType,'inline' =>true];
363-
364-
return$this;
347+
return$this->attachPart((newDataPart($body,$name,$contentType))->asInline());
365348
}
366349

367350
/**
368351
* @return $this
369352
*/
370353
publicfunctionembedFromPath(string$path,string$name =null,string$contentType =null):static
371354
{
372-
$this->cachedBody =null;
373-
$this->attachments[] = ['path' =>$path,'name' =>$name,'content-type' =>$contentType,'inline' =>true];
374-
375-
return$this;
355+
return$this->attachPart((newDataPart('file://'.$path,$name,$contentType))->asInline());
376356
}
377357

378358
/**
@@ -381,22 +361,17 @@ public function embedFromPath(string $path, string $name = null, string $content
381361
publicfunctionattachPart(DataPart$part):static
382362
{
383363
$this->cachedBody =null;
384-
$this->attachments[] =['part' =>$part];
364+
$this->attachments[] =$part;
385365

386366
return$this;
387367
}
388368

389369
/**
390-
* @returnarray|DataPart[]
370+
* @return DataPart[]
391371
*/
392372
publicfunctiongetAttachments():array
393373
{
394-
$parts = [];
395-
foreach ($this->attachmentsas$attachment) {
396-
$parts[] =$this->createDataPart($attachment);
397-
}
398-
399-
return$parts;
374+
return$this->attachments;
400375
}
401376

402377
publicfunctiongetBody():AbstractPart
@@ -502,35 +477,23 @@ private function prepareParts(): ?array
502477
}
503478

504479
$otherParts =$relatedParts = [];
505-
foreach ($this->attachmentsas$attachment) {
506-
$part =$this->createDataPart($attachment);
507-
if (isset($attachment['part'])) {
508-
$attachment['name'] =$part->getName();
509-
}
510-
511-
$related =false;
480+
foreach ($this->attachmentsas$part) {
512481
foreach ($namesas$name) {
513-
if ($name !==$attachment['name']) {
482+
if ($name !==$part->getName()) {
514483
continue;
515484
}
516485
if (isset($relatedParts[$name])) {
517486
continue2;
518487
}
519-
$part->setDisposition('inline');
488+
520489
$html =str_replace('cid:'.$name,'cid:'.$part->getContentId(),$html,$count);
521-
if ($count) {
522-
$related =true;
523-
}
524-
$part->setName($part->getContentId());
490+
$relatedParts[$name] =$part;
491+
$part->setName($part->getContentId())->asInline();
525492

526-
break;
493+
continue2;
527494
}
528495

529-
if ($related) {
530-
$relatedParts[$attachment['name']] =$part;
531-
}else {
532-
$otherParts[] =$part;
533-
}
496+
$otherParts[] =$part;
534497
}
535498
if (null !==$htmlPart) {
536499
$htmlPart =newTextPart($html,$this->htmlCharset,'html');
@@ -539,24 +502,6 @@ private function prepareParts(): ?array
539502
return [$htmlPart,$otherParts,array_values($relatedParts)];
540503
}
541504

542-
privatefunctioncreateDataPart(array$attachment):DataPart
543-
{
544-
if (isset($attachment['part'])) {
545-
return$attachment['part'];
546-
}
547-
548-
if (isset($attachment['body'])) {
549-
$part =newDataPart($attachment['body'],$attachment['name'] ??null,$attachment['content-type'] ??null);
550-
}else {
551-
$part = DataPart::fromPath($attachment['path'] ??'',$attachment['name'] ??null,$attachment['content-type'] ??null);
552-
}
553-
if ($attachment['inline']) {
554-
$part->asInline();
555-
}
556-
557-
return$part;
558-
}
559-
560505
/**
561506
* @return $this
562507
*/
@@ -606,12 +551,6 @@ public function __serialize(): array
606551
$this->html = (newTextPart($this->html))->getBody();
607552
}
608553

609-
foreach ($this->attachmentsas$i =>$attachment) {
610-
if (isset($attachment['body']) &&\is_resource($attachment['body'])) {
611-
$this->attachments[$i]['body'] = (newTextPart($attachment['body']))->getBody();
612-
}
613-
}
614-
615554
return [$this->text,$this->textCharset,$this->html,$this->htmlCharset,$this->attachments,parent::__serialize()];
616555
}
617556

‎src/Symfony/Component/Mime/MessageConverter.php‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,7 @@ private static function attachParts(Email $email, array $parts): Email
114114
thrownewRuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.',get_debug_type($email)));
115115
}
116116

117-
$headers =$part->getPreparedHeaders();
118-
$method ='inline' ===$headers->getHeaderBody('Content-Disposition') ?'embed' :'attach';
119-
$name =$headers->getHeaderParameter('Content-Disposition','filename');
120-
$email->$method($part->getBody(),$name,$part->getMediaType().'/'.$part->getMediaSubtype());
117+
$email->attachPart($part);
121118
}
122119

123120
return$email;

‎src/Symfony/Component/Mime/Part/DataPart.php‎

Lines changed: 16 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,28 @@ class DataPart extends TextPart
2828
private$filename;
2929
private$mediaType;
3030
private$cid;
31-
private$handle;
3231

33-
/**
34-
* @param resource|string $body
35-
*/
3632
publicfunction__construct($body,string$filename =null,string$contentType =null,string$encoding =null)
3733
{
3834
unset($this->_parent);
3935

36+
$path =null;
37+
if (\is_string($body) &&str_starts_with($body,'file://')) {
38+
$path =substr($body,\strlen('file://'));
39+
if (!$filename) {
40+
$filename =basename($path);
41+
}
42+
}
43+
4044
if (null ===$contentType) {
4145
$contentType ='application/octet-stream';
46+
if ($path) {
47+
$ext =strtolower(substr($path,strrpos($path,'.') +1));
48+
if (null ===self::$mimeTypes) {
49+
self::$mimeTypes =newMimeTypes();
50+
}
51+
$contentType =self::$mimeTypes->getMimeTypes($ext)[0] ??'application/octet-stream';
52+
}
4253
}
4354
[$this->mediaType,$subtype] =explode('/',$contentType);
4455

@@ -53,32 +64,7 @@ public function __construct($body, string $filename = null, string $contentType
5364

5465
publicstaticfunctionfromPath(string$path,string$name =null,string$contentType =null):self
5566
{
56-
if (null ===$contentType) {
57-
$ext =strtolower(substr($path,strrpos($path,'.') +1));
58-
if (null ===self::$mimeTypes) {
59-
self::$mimeTypes =newMimeTypes();
60-
}
61-
$contentType =self::$mimeTypes->getMimeTypes($ext)[0] ??'application/octet-stream';
62-
}
63-
64-
if ((is_file($path) && !is_readable($path)) ||is_dir($path)) {
65-
thrownewInvalidArgumentException(sprintf('Path "%s" is not readable.',$path));
66-
}
67-
68-
if (false ===$handle = @fopen($path,'r',false)) {
69-
thrownewInvalidArgumentException(sprintf('Unable to open path "%s".',$path));
70-
}
71-
72-
if (!is_file($path)) {
73-
$cache =fopen('php://temp','r+');
74-
stream_copy_to_stream($handle,$cache);
75-
$handle =$cache;
76-
}
77-
78-
$p =newself($handle,$name ?:basename($path),$contentType);
79-
$p->handle =$handle;
80-
81-
return$p;
67+
returnnewself('file://'.$path,$name,$contentType);
8268
}
8369

8470
/**
@@ -158,13 +144,6 @@ private function generateContentId(): string
158144
returnbin2hex(random_bytes(16)).'@symfony';
159145
}
160146

161-
publicfunction__destruct()
162-
{
163-
if (null !==$this->handle &&\is_resource($this->handle)) {
164-
fclose($this->handle);
165-
}
166-
}
167-
168147
publicfunction__sleep():array
169148
{
170149
// converts the body to a string

‎src/Symfony/Component/Mime/Part/TextPart.php‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class TextPart extends AbstractPart
4040
private$seekable;
4141

4242
/**
43-
* @param resource|string $body
43+
* @param resource|string $body Use file:// to defer loading the file until rendering
4444
*/
4545
publicfunction__construct($body, ?string$charset ='utf-8',string$subtype ='plain',string$encoding =null)
4646
{
@@ -52,6 +52,13 @@ public function __construct($body, ?string $charset = 'utf-8', string $subtype =
5252
thrownew \TypeError(sprintf('The body of "%s" must be a string or a resource (got "%s").',self::class,get_debug_type($body)));
5353
}
5454

55+
if (\is_string($body) &&str_starts_with($body,'file://')) {
56+
$path =substr($body,\strlen('file://'));
57+
if ((is_file($path) && !is_readable($path)) ||is_dir($path)) {
58+
thrownewInvalidArgumentException(sprintf('Path "%s" is not readable.',$path));
59+
}
60+
}
61+
5562
$this->body =$body;
5663
$this->charset =$charset;
5764
$this->subtype =$subtype;
@@ -116,6 +123,10 @@ public function getName(): ?string
116123

117124
publicfunctiongetBody():string
118125
{
126+
if (\is_string($this->body) &&str_starts_with($this->body,'file://')) {
127+
returnfile_get_contents(substr($this->body,\strlen('file://')));
128+
}
129+
119130
if (null ===$this->seekable) {
120131
return$this->body;
121132
}
@@ -134,7 +145,14 @@ public function bodyToString(): string
134145

135146
publicfunctionbodyToIterable():iterable
136147
{
137-
if (null !==$this->seekable) {
148+
if (\is_string($this->body) &&str_starts_with($this->body,'file://')) {
149+
$path =substr($this->body,\strlen('file://'));
150+
if (false ===$handle = @fopen($path,'r',false)) {
151+
thrownewInvalidArgumentException(sprintf('Unable to open path "%s".',$path));
152+
}
153+
154+
yieldfrom$this->getEncoder()->encodeByteStream($handle);
155+
}elseif (null !==$this->seekable) {
138156
if ($this->seekable) {
139157
rewind($this->body);
140158
}

‎src/Symfony/Component/Mime/Tests/EmailTest.php‎

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,9 @@ public function testSerialize()
504504
$expected =clone$e;
505505
$n =unserialize(serialize($e));
506506
$this->assertEquals($expected->getHeaders(),$n->getHeaders());
507-
$this->assertEquals($e->getBody(),$n->getBody());
507+
$a =preg_replace(["{boundary=.+\r\n}","{^\-\-.+\r\n}m"], ['boundary=x','--x'],$e->getBody()->toString());
508+
$b =preg_replace(["{boundary=.+\r\n}","{^\-\-.+\r\n}m"], ['boundary=x','--x'],$n->getBody()->toString());
509+
$this->assertEquals($a,$b);
508510
}
509511

510512
publicfunctiontestSymfonySerialize()
@@ -525,10 +527,16 @@ public function testSymfonySerialize()
525527
"htmlCharset": "utf-8",
526528
"attachments": [
527529
{
530+
"filename": "test.txt",
531+
"mediaType": "application",
528532
"body": "Some Text file",
533+
"charset": null,
534+
"subtype": "octet-stream",
535+
"disposition": "attachment",
529536
"name": "test.txt",
530-
"content-type": null,
531-
"inline": false
537+
"encoding": "base64",
538+
"headers": [],
539+
"class": "Symfony\\\Component\\\Mime\\\Part\\\DataPart"
532540
}
533541
],
534542
"headers": {
@@ -587,15 +595,15 @@ public function testMissingHeaderDoesNotThrowError()
587595
publicfunctiontestAttachBodyExpectStringOrResource()
588596
{
589597
$this->expectException(\TypeError::class);
590-
$this->expectExceptionMessage('The body must be a string or a resource (got "bool").');
598+
$this->expectExceptionMessage('The bodyof "Symfony\Component\Mime\Part\TextPart"must be a string or a resource (got "bool").');
591599

592600
(newEmail())->attach(false);
593601
}
594602

595603
publicfunctiontestEmbedBodyExpectStringOrResource()
596604
{
597605
$this->expectException(\TypeError::class);
598-
$this->expectExceptionMessage('The body must be a string or a resource (got "bool").');
606+
$this->expectExceptionMessage('The bodyof "Symfony\Component\Mime\Part\TextPart"must be a string or a resource (got "bool").');
599607

600608
(newEmail())->embed(false);
601609
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
content

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp