Commit | Line | Data |
---|---|---|
fcd2196c AE |
1 | <?php |
2 | ||
3 | namespace wcf\system\file\processor; | |
4 | ||
7ec674c0 | 5 | use wcf\data\attachment\Attachment; |
014ed6ba AE |
6 | use wcf\data\attachment\AttachmentEditor; |
7 | use wcf\data\file\File; | |
e2fadded | 8 | use wcf\data\file\thumbnail\FileThumbnail; |
50fb8d56 | 9 | use wcf\system\attachment\AttachmentHandler; |
e2fadded | 10 | use 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 | */ | |
18 | final 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 | } |