Upload PDFs to the library, link them from any link target, show them in a viewer
PDFs go through the same upload field as images, are checked by their content and kept unchanged in their own table. Every link field can pick one, and a page that links a PDF opens it in a dialog with the browser's own viewer; touch devices and browsers without a viewer get a new tab instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
04927b9563
commit
e8a9dcdf5c
20 files changed
+667
-30
No files matched your search
@@ -738,6 +738,47 @@ final class EditorSecurityTest extends WebTestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function testPdfsGoThroughTheMediaUploadAndTheEditorPicker(): void
|
||||
{
|
||||
$client = $this->login('editor');
|
||||
$crawler = $client->request('GET', '/admin/media');
|
||||
$token = $crawler->filter('form[action="/admin/media/upload"] input[name="_csrf_token"]')->attr('value');
|
||||
$path = tempnam(sys_get_temp_dir(), 'kant-form-pdf-');
|
||||
try {
|
||||
file_put_contents($path, "%PDF-1.7\n%%EOF\n");
|
||||
// Dasselbe Feld wie für Bilder: der Inhalt entscheidet, wohin die Datei geht.
|
||||
$client->request('POST', '/admin/media/upload', ['_csrf_token' => $token], ['files' => [new UploadedFile($path, 'Flyer.pdf', test: true)]]);
|
||||
self::assertResponseRedirects('/admin/media');
|
||||
self::assertSame(0, (int) $this->db->fetchOne('SELECT COUNT(*) FROM media'));
|
||||
self::assertSame('Flyer', $this->db->fetchOne('SELECT title FROM document'));
|
||||
$crawler = $client->followRedirect();
|
||||
self::assertStringContainsString('1 Datei(en) hochgeladen', $crawler->filter('.notice.ok')->text());
|
||||
self::assertCount(1, $crawler->filter('section[aria-labelledby="documents-heading"] .row'));
|
||||
|
||||
// Die Auswahl im Editor: Liste mit Token, Hochladen nur mit Token.
|
||||
$client->request('GET', '/admin/api/dokumente');
|
||||
self::assertResponseIsSuccessful();
|
||||
$data = json_decode($client->getResponse()->getContent(), true);
|
||||
self::assertSame('Flyer', $data['items'][0]['title']);
|
||||
$client->request('POST', '/admin/api/dokumente/upload', files: ['file' => new UploadedFile($path, 'zweites.pdf', test: true)]);
|
||||
self::assertResponseStatusCodeSame(403);
|
||||
file_put_contents($path, '<?php echo 1;');
|
||||
$client->request('POST', '/admin/api/dokumente/upload', files: ['file' => new UploadedFile($path, 'getarnt.pdf', test: true)], server: ['HTTP_X_CSRF_TOKEN' => $data['csrfToken']]);
|
||||
self::assertResponseStatusCodeSame(422);
|
||||
self::assertSame(1, (int) $this->db->fetchOne('SELECT COUNT(*) FROM document'));
|
||||
|
||||
// Archivieren nimmt es aus der Auswahl-Übersicht, die Datei bleibt erreichbar.
|
||||
$id = $data['items'][0]['id'];
|
||||
$client->request('POST', '/admin/api/dokumente/'.$id, server: ['CONTENT_TYPE' => 'application/json', 'HTTP_X_CSRF_TOKEN' => $data['csrfToken']], content: json_encode(['title' => 'Flyer 2026', 'archived' => true, 'version' => 1]));
|
||||
self::assertResponseIsSuccessful();
|
||||
self::assertCount(0, $client->request('GET', '/admin/media')->filter('section[aria-labelledby="documents-heading"] .row'));
|
||||
$client->request('GET', '/media/'.$id.'.pdf');
|
||||
self::assertResponseIsSuccessful();
|
||||
} finally {
|
||||
unlink($path);
|
||||
}
|
||||
}
|
||||
|
||||
public function testMediaPreviewReadsSmallAndArchivedImagesWithoutListingTheLibrary(): void
|
||||
{
|
||||
$id = str_repeat('a', 32);
|
||||
@@ -785,7 +826,7 @@ final class EditorSecurityTest extends WebTestCase
|
||||
$crawler = $client->followRedirect();
|
||||
self::assertCount(2, $crawler->filter('.library-tile'));
|
||||
self::assertCount(1, $crawler->filter('.notice.ok'));
|
||||
self::assertStringContainsString('2 Bild(er) hochgeladen', $crawler->filter('.notice.ok')->text());
|
||||
self::assertStringContainsString('2 Datei(en) hochgeladen', $crawler->filter('.notice.ok')->text());
|
||||
|
||||
$id = (string) $this->db->fetchOne('SELECT id FROM media LIMIT 1');
|
||||
$client->request('POST', '/admin/media/'.$id, ['_csrf_token' => $token, 'title' => 'Bergblick', 'alt' => 'Grüne Berglandschaft', 'archived' => '1', 'version' => 1]);
|
||||
|
||||
Reference in new issue
Block a user