Skip to content

Commit c8e6612

Browse files
author
jona
committed
Split attachment path into internal and external path, so the external source URL can be retained after a file is downloaded
1 parent 5bb79b5 commit c8e6612

File tree

21 files changed

+395
-299
lines changed

21 files changed

+395
-299
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php /** @noinspection SqlNoDataSourceInspection */
2+
3+
declare(strict_types=1);
4+
5+
namespace DoctrineMigrations;
6+
7+
use Doctrine\DBAL\Schema\Schema;
8+
use Doctrine\Migrations\AbstractMigration;
9+
10+
/**
11+
* Auto-generated Migration: Please modify to your needs!
12+
*/
13+
final class Version20250112051523 extends AbstractMigration
14+
{
15+
public function getDescription(): string
16+
{
17+
return 'Split $path property for attachments into $internal_path and $external_path';
18+
}
19+
20+
public function up(Schema $schema): void
21+
{ $this->addSql('ALTER TABLE attachments ADD internal_path VARCHAR(255) DEFAULT \'\' NOT NULL');
22+
$this->addSql('ALTER TABLE attachments RENAME `path` TO external_path');
23+
24+
$this->addSql('UPDATE attachments SET internal_path=external_path WHERE external_path LIKE \'#%MEDIA#%%\' ESCAPE \'#\'');
25+
$this->addSql('UPDATE attachments SET internal_path=external_path WHERE external_path LIKE \'#%BASE#%%\' ESCAPE \'#\'');
26+
$this->addSql('UPDATE attachments SET internal_path=external_path WHERE external_path LIKE \'#%SECURE#%%\' ESCAPE \'#\'');
27+
$this->addSql('UPDATE attachments SET internal_path=external_path WHERE external_path LIKE \'#%FOOTPRINTS#%%\' ESCAPE \'#\'');
28+
$this->addSql('UPDATE attachments SET internal_path=external_path WHERE external_path LIKE \'#%FOOTPRINTS3D#%%\' ESCAPE \'#\'');
29+
$this->addSql('UPDATE attachments SET external_path=\'\' WHERE internal_path <> \'\'');
30+
}
31+
32+
public function down(Schema $schema): void
33+
{
34+
$this->addSql('UPDATE attachments SET external_path=internal_path WHERE internal_path <> \'\'');
35+
36+
$this->addSql('ALTER TABLE attachments DROP internal_path');
37+
$this->addSql('ALTER TABLE attachments RENAME external_path TO `path`');
38+
}
39+
}

src/Controller/AttachmentFileController.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,15 @@ public function download(Attachment $attachment, AttachmentManager $helper): Bin
5151
$this->denyAccessUnlessGranted('show_private', $attachment);
5252
}
5353

54-
if ($attachment->isExternal()) {
55-
throw $this->createNotFoundException('The file for this attachment is external and can not stored locally!');
54+
if (!$attachment->hasInternal()) {
55+
throw $this->createNotFoundException('The file for this attachment is external and not stored locally!');
5656
}
5757

58-
if (!$helper->isFileExisting($attachment)) {
58+
if (!$helper->isInternalFileExisting($attachment)) {
5959
throw $this->createNotFoundException('The file associated with the attachment is not existing!');
6060
}
6161

62-
$file_path = $helper->toAbsoluteFilePath($attachment);
62+
$file_path = $helper->toAbsoluteInternalFilePath($attachment);
6363
$response = new BinaryFileResponse($file_path);
6464

6565
//Set header content disposition, so that the file will be downloaded
@@ -80,15 +80,15 @@ public function view(Attachment $attachment, AttachmentManager $helper): BinaryF
8080
$this->denyAccessUnlessGranted('show_private', $attachment);
8181
}
8282

83-
if ($attachment->isExternal()) {
84-
throw $this->createNotFoundException('The file for this attachment is external and can not stored locally!');
83+
if (!$attachment->hasInternal()) {
84+
throw $this->createNotFoundException('The file for this attachment is external and not stored locally!');
8585
}
8686

87-
if (!$helper->isFileExisting($attachment)) {
87+
if (!$helper->isInternalFileExisting($attachment)) {
8888
throw $this->createNotFoundException('The file associated with the attachment is not existing!');
8989
}
9090

91-
$file_path = $helper->toAbsoluteFilePath($attachment);
91+
$file_path = $helper->toAbsoluteInternalFilePath($attachment);
9292
$response = new BinaryFileResponse($file_path);
9393

9494
//Set header content disposition, so that the file will be downloaded

src/DataFixtures/PartFixtures.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public function load(ObjectManager $manager): void
131131

132132
$attachment = new PartAttachment();
133133
$attachment->setName('Test2');
134-
$attachment->setPath('invalid');
134+
$attachment->setInternalPath('invalid');
135135
$attachment->setShowInTable(true);
136136
$attachment->setAttachmentType($manager->find(AttachmentType::class, 1));
137137
$part->addAttachment($attachment);

src/DataTables/AttachmentDataTable.php

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ public function configure(DataTable $dataTable, array $options): void
5050
{
5151
$dataTable->add('dont_matter', RowClassColumn::class, [
5252
'render' => function ($value, Attachment $context): string {
53-
//Mark attachments with missing files yellow
54-
if(!$this->attachmentHelper->isFileExisting($context)){
53+
//Mark attachments yellow which have an internal file linked that doesn't exist
54+
if($context->hasInternal() && !$this->attachmentHelper->isInternalFileExisting($context)){
5555
return 'table-warning';
5656
}
5757

@@ -64,8 +64,8 @@ public function configure(DataTable $dataTable, array $options): void
6464
'className' => 'no-colvis',
6565
'render' => function ($value, Attachment $context): string {
6666
if ($context->isPicture()
67-
&& !$context->isExternal()
68-
&& $this->attachmentHelper->isFileExisting($context)) {
67+
&& $this->attachmentHelper->isInternalFileExisting($context)) {
68+
6969
$title = htmlspecialchars($context->getName());
7070
if ($context->getFilename()) {
7171
$title .= ' ('.htmlspecialchars($context->getFilename()).')';
@@ -93,26 +93,6 @@ public function configure(DataTable $dataTable, array $options): void
9393
$dataTable->add('name', TextColumn::class, [
9494
'label' => 'attachment.edit.name',
9595
'orderField' => 'NATSORT(attachment.name)',
96-
'render' => function ($value, Attachment $context) {
97-
//Link to external source
98-
if ($context->isExternal()) {
99-
return sprintf(
100-
'<a href="%s" class="link-external">%s</a>',
101-
htmlspecialchars((string) $context->getURL()),
102-
htmlspecialchars($value)
103-
);
104-
}
105-
106-
if ($this->attachmentHelper->isFileExisting($context)) {
107-
return sprintf(
108-
'<a href="%s" target="_blank" data-no-ajax>%s</a>',
109-
$this->entityURLGenerator->viewURL($context),
110-
htmlspecialchars($value)
111-
);
112-
}
113-
114-
return $value;
115-
},
11696
]);
11797

11898
$dataTable->add('attachment_type', TextColumn::class, [
@@ -136,15 +116,42 @@ public function configure(DataTable $dataTable, array $options): void
136116
),
137117
]);
138118

139-
$dataTable->add('filename', TextColumn::class, [
140-
'label' => $this->translator->trans('attachment.table.filename'),
119+
$dataTable->add('internal_link', TextColumn::class, [
120+
'label' => 'Internal copy', #TODO: translation
141121
'propertyPath' => 'filename',
122+
'render' => function ($value, Attachment $context) {
123+
if ($this->attachmentHelper->isInternalFileExisting($context)) {
124+
return sprintf(
125+
'<a href="%s" target="_blank" data-no-ajax>%s</a>',
126+
$this->entityURLGenerator->viewURL($context),
127+
htmlspecialchars($value)
128+
);
129+
}
130+
131+
return $value;
132+
}
133+
]);
134+
135+
$dataTable->add('external_link', TextColumn::class, [
136+
'label' => 'External copy', #TODO: translation
137+
'propertyPath' => 'host',
138+
'render' => function ($value, Attachment $context) {
139+
if ($context->hasExternal()) {
140+
return sprintf(
141+
'<a href="%s" class="link-external">%s</a>',
142+
htmlspecialchars((string) $context->getExternalPath()),
143+
htmlspecialchars($value)
144+
);
145+
}
146+
147+
return $value;
148+
}
142149
]);
143150

144151
$dataTable->add('filesize', TextColumn::class, [
145152
'label' => $this->translator->trans('attachment.table.filesize'),
146153
'render' => function ($value, Attachment $context) {
147-
if ($context->isExternal()) {
154+
if (!$context->hasInternal()) {
148155
return sprintf(
149156
'<span class="badge bg-primary">
150157
<i class="fas fa-globe fa-fw"></i>%s
@@ -153,8 +160,13 @@ public function configure(DataTable $dataTable, array $options): void
153160
);
154161
}
155162

156-
if ($this->attachmentHelper->isFileExisting($context)) {
157-
return $this->attachmentHelper->getHumanFileSize($context);
163+
if ($this->attachmentHelper->isInternalFileExisting($context)) {
164+
return sprintf(
165+
'<span class="badge bg-secondary">
166+
<i class="fas fa-hdd fa-fw"></i> %s
167+
</span>',
168+
$this->attachmentHelper->getHumanFileSize($context)
169+
);
158170
}
159171

160172
return sprintf(

0 commit comments

Comments
 (0)