diff --git a/config/services.yaml b/config/services.yaml index 54da499a..1da3682f 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -94,6 +94,7 @@ services: arguments: $allow_attachments_downloads: '%partdb.attachments.allow_downloads%' $mimeTypes: '@mime_types' + $max_upload_size: '%partdb.attachments.max_file_size%' App\EventSubscriber\LogSystem\LogoutLoggerListener: tags: diff --git a/src/Form/AttachmentFormType.php b/src/Form/AttachmentFormType.php index dc23fea2..fbf75b97 100644 --- a/src/Form/AttachmentFormType.php +++ b/src/Form/AttachmentFormType.php @@ -37,6 +37,8 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormError; use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; +use Symfony\Component\Form\FormInterface; +use Symfony\Component\Form\FormView; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; @@ -168,6 +170,11 @@ class AttachmentFormType extends AbstractType ]); } + public function finishView(FormView $view, FormInterface $form, array $options) + { + $view->vars['max_upload_size'] = $this->submitHandler->getMaximumAllowedUploadSize(); + } + public function getBlockPrefix(): string { return 'attachment'; diff --git a/src/Services/Attachments/AttachmentSubmitHandler.php b/src/Services/Attachments/AttachmentSubmitHandler.php index cd3afcac..e3552eed 100644 --- a/src/Services/Attachments/AttachmentSubmitHandler.php +++ b/src/Services/Attachments/AttachmentSubmitHandler.php @@ -61,6 +61,12 @@ class AttachmentSubmitHandler protected HttpClientInterface $httpClient; protected MimeTypesInterface $mimeTypes; protected FileTypeFilterTools $filterTools; + /** + * @var string The user configured maximum upload size. This is a string like "10M" or "1G" and will be converted to + */ + protected string $max_upload_size; + + private ?int $max_upload_size_bytes = null; protected const BLACKLISTED_EXTENSIONS = ['php', 'phtml', 'php3', 'ph3', 'php4', 'ph4', 'php5', 'ph5', 'phtm', 'sh', 'asp', 'cgi', 'py', 'pl', 'exe', 'aspx', 'js', 'mjs', 'jsp', 'css', 'jar', 'html', 'htm', 'shtm', 'shtml', 'htaccess', @@ -68,12 +74,13 @@ class AttachmentSubmitHandler public function __construct(AttachmentPathResolver $pathResolver, bool $allow_attachments_downloads, HttpClientInterface $httpClient, MimeTypesInterface $mimeTypes, - FileTypeFilterTools $filterTools) + FileTypeFilterTools $filterTools, string $max_upload_size) { $this->pathResolver = $pathResolver; $this->allow_attachments_downloads = $allow_attachments_downloads; $this->httpClient = $httpClient; $this->mimeTypes = $mimeTypes; + $this->max_upload_size = $max_upload_size; $this->filterTools = $filterTools; @@ -417,4 +424,48 @@ class AttachmentSubmitHandler return $attachment; } + + /** + * Parses the given file size string and returns the size in bytes. + * Taken from https://github.com/symfony/symfony/blob/6.2/src/Symfony/Component/Validator/Constraints/File.php + * @param string $maxSize + * @return int + */ + private function parseFileSizeString(string $maxSize): int + { + $factors = [ + 'k' => 1000, + 'ki' => 1 << 10, + 'm' => 1000 * 1000, + 'mi' => 1 << 20, + 'g' => 1000 * 1000 * 1000, + 'gi' => 1 << 30, + ]; + if (ctype_digit((string) $maxSize)) { + return (int) $maxSize; + } elseif (preg_match('/^(\d++)('.implode('|', array_keys($factors)).')$/i', $maxSize, $matches)) { + return $matches[1] * $factors[$unit = strtolower($matches[2])]; + } else { + throw new RuntimeException(sprintf('"%s" is not a valid maximum size.', $maxSize)); + } + } + + /* + * Returns the maximum allowed upload size in bytes. + * This is the minimum value of Part-DB max_file_size, and php.ini's post_max_size and upload_max_filesize. + */ + public function getMaximumAllowedUploadSize(): int + { + if ($this->max_upload_size_bytes) { + return $this->max_upload_size_bytes; + } + + $this->max_upload_size_bytes = min( + $this->parseFileSizeString(ini_get('post_max_size')), + $this->parseFileSizeString(ini_get('upload_max_filesize')), + $this->parseFileSizeString($this->max_upload_size), + ); + + return $this->max_upload_size_bytes; + } } diff --git a/templates/parts/edit/edit_form_styles.html.twig b/templates/parts/edit/edit_form_styles.html.twig index cb3f7d24..d41972f5 100644 --- a/templates/parts/edit/edit_form_styles.html.twig +++ b/templates/parts/edit/edit_form_styles.html.twig @@ -106,7 +106,21 @@ - {{ form_widget(form) }} + {{ form_row(form.name) }} + {{ form_row(form.attachment_type) }} + {{ form_row(form.secureFile) }} + {{ form_row(form.showInTable) }} + {{ form_row(form.url) }} + {{ form_row(form.downloadURL) }} + +
+ {{ form_label(form.file) }} +
+ {{ form_widget(form.file) }} + {% trans %}attachment.max_file_size{% endtrans %}: {{ max_upload_size | format_bytes }} +
+
+