Skip to content

Commit f65b90f

Browse files
committed
AttachmentDownloadService
1 parent d0ba222 commit f65b90f

5 files changed

Lines changed: 86 additions & 3 deletions

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\Core\Domain\Messaging\Exception;
6+
7+
class AttachmentFileNotFoundException extends \RuntimeException
8+
{
9+
public function __construct()
10+
{
11+
parent::__construct('Attachment file not available');
12+
}
13+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\Core\Domain\Messaging\Model\Dto;
6+
7+
use Psr\Http\Message\StreamInterface;
8+
9+
final class DownloadableAttachment
10+
{
11+
public function __construct(
12+
public readonly string $filename,
13+
public readonly string $mimeType,
14+
public readonly int $size,
15+
public readonly StreamInterface $content,
16+
) {
17+
}
18+
}

src/Domain/Messaging/Service/AttachmentAdder.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ public function add(Email $email, int $campaignId, OutputFormat $format, bool $f
5858

5959
case OutputFormat::Text:
6060
$hash = $forwarded ? 'forwarded' : $email->getTo()[0]->getAddress();
61-
// todo: add endpoint in rest-api project
62-
$viewUrl = $this->attachmentDownloadUrl . '/?id=' . $att->getId() . '&uid=' . $hash;
61+
$viewUrl = $this->attachmentDownloadUrl . '/' . $att->getId() . '/?uid=' . $hash;
6362

6463
$email->text(
6564
$email->getTextBody()
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\Core\Domain\Messaging\Service;
6+
7+
use GuzzleHttp\Psr7\Utils;
8+
use PhpList\Core\Domain\Messaging\Exception\AttachmentFileNotFoundException;
9+
use PhpList\Core\Domain\Messaging\Model\Attachment;
10+
use PhpList\Core\Domain\Messaging\Model\Dto\DownloadableAttachment;
11+
use Psr\Http\Message\StreamInterface;
12+
use Symfony\Component\DependencyInjection\Attribute\Autowire;
13+
use Symfony\Component\Mime\MimeTypes;
14+
15+
class AttachmentDownloadService
16+
{
17+
public function __construct(
18+
#[Autowire('%phplist.attachment_repository_path%')] private readonly string $attachmentRepositoryPath = '/tmp',
19+
) {
20+
}
21+
22+
public function getDownloadable(Attachment $attachment): DownloadableAttachment
23+
{
24+
$filename = $attachment->getFilename();
25+
if ($filename === null || $filename === '') {
26+
throw new AttachmentFileNotFoundException();
27+
}
28+
29+
$path = rtrim($this->attachmentRepositoryPath, '/');
30+
$filePath = $path . '/' . $filename;
31+
32+
if (!is_file($filePath) || !is_readable($filePath)) {
33+
throw new AttachmentFileNotFoundException();
34+
}
35+
36+
$mimeType = $attachment->getMimeType()
37+
?? MimeTypes::getDefault()->guessMimeType($filePath)
38+
?? 'application/octet-stream';
39+
40+
$size = filesize($filePath);
41+
$size = $size === false ? null : $size;
42+
43+
/** @var StreamInterface $stream */
44+
$stream = Utils::streamFor(Utils::tryFopen($filePath, 'rb'));
45+
46+
return new DownloadableAttachment(
47+
filename: $filename,
48+
mimeType: $mimeType,
49+
size: $size,
50+
content: $stream,
51+
);
52+
}
53+
}

tests/Unit/Domain/Messaging/Service/AttachmentAdderTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public function testTextModePrependsNoticeAndLinks(): void
9191
);
9292
$this->assertStringContainsString('Doc description', $body);
9393
$this->assertStringContainsString('Location', $body);
94-
$this->assertStringContainsString('https://dl.example/?id=42&uid=user@example.com', $body);
94+
$this->assertStringContainsString('https://dl.example/42/?uid=user@example.com', $body);
9595
}
9696

9797
public function testHtmlUsesRepositoryFileIfExists(): void

0 commit comments

Comments
 (0)