diff --git a/Form/Type/AcbFileType.php b/Form/Type/AcbFileType.php index 2c79360..24b7fde 100644 --- a/Form/Type/AcbFileType.php +++ b/Form/Type/AcbFileType.php @@ -65,6 +65,10 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'label' => 'field_type.file.restriction_type', 'multiple' => true, 'choices' => is_array($mimeTypeChoices) ? $mimeTypeChoices : [], + 'choice_attr' => function ($choice): array { + return ['data-mime-type' => json_encode($this->mimeTypeManager->getMimeTypesByCode($choice))]; + }, + 'attr' => ['data-mime-type-restriction' => ''] ]) ; @@ -160,6 +164,7 @@ private function updateForm(FormInterface $form, $data, $options, $hasFile = fal 'label' => 'field_type.file.file', 'required' => !$isFileUploaded && $options['required'], 'constraints' => $options['file_constraints'], + 'attr' => ['data-mime-type-restriction' => ''] ]) ; diff --git a/Resources/js/index.js b/Resources/js/index.js index aec639e..40ebc31 100644 --- a/Resources/js/index.js +++ b/Resources/js/index.js @@ -247,6 +247,56 @@ jQuery(function ($) { slide.element.on('slideContentUpdated', updateControls); slide.element.on('change', '.simplify-controls', updateControls); + $('body').on('change', '[data-mime-type-restriction]', function (e) { + let inputFile = $(this).closest('.acb-widget-container').find('input[type=file]'); + let errorMessage = $(this).closest('.acb-widget-container').find('.invalid-feedback'); + + if (!inputFile.length) { + return; + } + + inputFile = inputFile[0]; + + if (!inputFile.files.length) { + errorMessage.removeClass('d-block').addClass('d-none'); + + return; + } + + let mimeTypeOption = $(this).closest('.acb-widget-container').find('[data-mime-type-restriction-values]').find(':checked'); + + if (!mimeTypeOption.length) { + return; + } + + + let mimeTypeValues = []; + mimeTypeOption.each(function() { + $(this).data('mime-type').forEach((element) => mimeTypeValues.push(element)); + }); + + let allImageType = mimeTypeValues.length === 1 && mimeTypeValues[0] === 'image/*'; + let hasError = true; + + if (allImageType && inputFile.files[0].type.includes('image/')) { + hasError = false; + } else if (mimeTypeValues.includes(inputFile.files[0].type)) { + hasError = false; + } + + if (hasError) { + let msg = errorMessage.data('error'); + + mimeTypeValues = mimeTypeValues.map(type => `"${type}"`); + msg = msg.replace('%mime%', inputFile.files[0].type).replace('%allowed_mime%', mimeTypeValues.join(', ')); + + errorMessage.html(msg); + errorMessage.removeClass('d-none').addClass('d-block'); + } else { + errorMessage.removeClass('d-block').addClass('d-none'); + } + }); + function updateRowAfterLayoutUpdate(row) { saveExistingField( $('.acb-elements-container').data('edit-url') + '?type=row', diff --git a/Resources/translations/AdvancedContentBundle.en.yml b/Resources/translations/AdvancedContentBundle.en.yml index 9dad42a..bf38064 100644 --- a/Resources/translations/AdvancedContentBundle.en.yml +++ b/Resources/translations/AdvancedContentBundle.en.yml @@ -41,6 +41,7 @@ field_type: file: File label: File restriction_type: File type restriction + restriction_type_error: The mime type of the file is invalid ("%mime%"). Allowed mime types are %allowed_mime%. relative_link: label: Relative Link separator: diff --git a/Resources/translations/AdvancedContentBundle.fr.yml b/Resources/translations/AdvancedContentBundle.fr.yml index 186ffa0..55754e5 100644 --- a/Resources/translations/AdvancedContentBundle.fr.yml +++ b/Resources/translations/AdvancedContentBundle.fr.yml @@ -41,6 +41,7 @@ field_type: file: Fichier label: Fichier restriction_type: Restriction du type de fichier + restriction_type_error: Le type du fichier est invalide ("%mime%"). Les types autorisés sont %allowed_mime%. relative_link: label: Lien relatif separator: diff --git a/Resources/views/Form/content.html.twig b/Resources/views/Form/content.html.twig index f067b30..1644709 100644 --- a/Resources/views/Form/content.html.twig +++ b/Resources/views/Form/content.html.twig @@ -181,85 +181,91 @@ {% endblock %} {% block acb_image_widget %} -