Add support for image thumbnails
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / file / processor / AttachmentFileProcessor.class.php
CommitLineData
fcd2196c
AE
1<?php
2
3namespace wcf\system\file\processor;
4
7ec674c0 5use wcf\data\attachment\Attachment;
014ed6ba
AE
6use wcf\data\attachment\AttachmentEditor;
7use wcf\data\file\File;
e2fadded 8use wcf\data\file\thumbnail\FileThumbnail;
50fb8d56 9use wcf\system\attachment\AttachmentHandler;
e2fadded 10use wcf\system\exception\NotImplementedException;
50fb8d56 11
fcd2196c
AE
12/**
13 * @author Alexander Ebert
14 * @copyright 2001-2024 WoltLab GmbH
15 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
16 * @since 6.1
17 */
18final class AttachmentFileProcessor implements IFileProcessor
19{
ee0274de 20 #[\Override]
fcd2196c
AE
21 public function getTypeName(): string
22 {
23 return 'com.woltlab.wcf.attachment';
24 }
25
ee0274de 26 #[\Override]
919e4264
AE
27 public function getAllowedFileExtensions(array $context): array
28 {
29 // TODO: Properly validate the shape of `$context`.
30 $objectType = $context['objectType'] ?? '';
31 $objectID = \intval($context['objectID'] ?? 0);
32 $parentObjectID = \intval($context['parentObjectID'] ?? 0);
33 $tmpHash = $context['tmpHash'] ?? '';
34
35 $attachmentHandler = new AttachmentHandler($objectType, $objectID, $tmpHash, $parentObjectID);
36
37 return $attachmentHandler->getAllowedExtensions();
38 }
39
ee0274de 40 #[\Override]
014ed6ba
AE
41 public function adopt(File $file, array $context): void
42 {
43 // TODO: Properly validate the shape of `$context`.
44 $objectType = $context['objectType'] ?? '';
45 $objectID = \intval($context['objectID'] ?? 0);
46 $parentObjectID = \intval($context['parentObjectID'] ?? 0);
47 $tmpHash = $context['tmpHash'] ?? '';
48
49 $attachmentHandler = new AttachmentHandler($objectType, $objectID, $tmpHash, $parentObjectID);
50
51 // TODO: How do we want to create the attachments? Do we really want to
52 // keep using the existing attachment table though?
53 AttachmentEditor::fastCreate([
54 'objectTypeID' => $attachmentHandler->getObjectType()->objectTypeID,
55 'objectID' => $attachmentHandler->getObjectID(),
56 'tmpHash' => $tmpHash,
57 'fileID' => $file->fileID,
58 ]);
59 }
60
ee0274de 61 #[\Override]
baca3027 62 public function acceptUpload(string $filename, int $fileSize, array $context): FileProcessorPreflightResult
fcd2196c 63 {
baca3027 64 // TODO: Properly validate the shape of `$context`.
50fb8d56
AE
65 $objectType = $context['objectType'] ?? '';
66 $objectID = \intval($context['objectID'] ?? 0);
67 $parentObjectID = \intval($context['parentObjectID'] ?? 0);
baca3027 68 $tmpHash = $context['tmpHash'] ?? '';
50fb8d56 69
baca3027 70 $attachmentHandler = new AttachmentHandler($objectType, $objectID, $tmpHash, $parentObjectID);
50fb8d56 71 if (!$attachmentHandler->canUpload()) {
baca3027 72 return FileProcessorPreflightResult::InsufficientPermissions;
50fb8d56
AE
73 }
74
75 if ($fileSize > $attachmentHandler->getMaxSize()) {
baca3027 76 return FileProcessorPreflightResult::FileSizeTooLarge;
50fb8d56
AE
77 }
78
baca3027
AE
79 // TODO: This is a typical use case and should be provided through a helper function.
80 $extensions = \implode(
81 "|",
82 \array_map(
83 static function (string $extension) {
84 $extension = \preg_quote($extension, '/');
85 $extension = \str_replace('\*', '.*', $extension);
86
87 return $extension;
88 },
89 $attachmentHandler->getAllowedExtensions()
90 )
91 );
50fb8d56
AE
92 $extensionsPattern = '/(' . $extensions . ')$/i';
93 if (!\preg_match($extensionsPattern, \mb_strtolower($filename))) {
baca3027 94 return FileProcessorPreflightResult::FileExtensionNotPermitted;
50fb8d56
AE
95 }
96
baca3027 97 return FileProcessorPreflightResult::Passed;
fcd2196c 98 }
50fb8d56 99
ee0274de 100 #[\Override]
7ec674c0
AE
101 public function canDownload(File $file): bool
102 {
103 $attachment = Attachment::findByFileID($file->fileID);
104 if ($attachment === null) {
105 return false;
106 }
107
108 return $attachment->canDownload();
109 }
110
ee0274de 111 #[\Override]
624a427c
AE
112 public function getUploadResponse(File $file): array
113 {
114 $attachment = Attachment::findByFileID($file->fileID);
115 if ($attachment === null) {
116 return [];
117 }
118
119 return [
120 'attachmentID' => $attachment->attachmentID,
121 ];
122 }
123
baca3027 124 public function toHtmlElement(string $objectType, int $objectID, string $tmpHash, int $parentObjectID): string
50fb8d56
AE
125 {
126 return FileProcessor::getInstance()->getHtmlElement(
127 $this,
128 [
129 'objectType' => $objectType,
130 'objectID' => $objectID,
131 'parentObjectID' => $parentObjectID,
baca3027 132 'tmpHash' => $tmpHash,
50fb8d56
AE
133 ],
134 );
135 }
ee0274de
AE
136
137 #[\Override]
138 public function getThumbnailFormats(): array
139 {
140 return [
e2fadded
AE
141 new ThumbnailFormat(
142 '',
143 \ATTACHMENT_THUMBNAIL_HEIGHT,
144 \ATTACHMENT_THUMBNAIL_WIDTH,
145 !!\ATTACHMENT_RETAIN_DIMENSIONS,
146 ),
ee0274de
AE
147 new ThumbnailFormat(
148 'tiny',
149 144,
150 144,
151 false,
152 ),
ee0274de
AE
153 ];
154 }
e2fadded
AE
155
156 #[\Override]
157 public function adoptThumbnail(FileThumbnail $thumbnail): void
158 {
159 $attachment = Attachment::findByFileID($thumbnail->fileID);
160 if ($attachment === null) {
161 // TODO: How to handle this case?
162 return;
163 }
164
165 $columnName = match ($thumbnail->identifier) {
166 '' => 'thumbnailID',
167 'tiny'=>'tinyThumbnailID',
168 'default'=>throw new \RuntimeException('TODO'), // TODO
169 };
170
171 $attachmentEditor = new AttachmentEditor($attachment);
172 $attachmentEditor->update([
173 $columnName => $thumbnail->thumbnailID,
174 ]);
175 }
fcd2196c 176}