Skip to content

Commit

Permalink
Merge pull request #299 from sherlockode/feature/js-mime-type-validation
Browse files Browse the repository at this point in the history
File mime type js validation
  • Loading branch information
Vowow authored Nov 14, 2023
2 parents ff6fa13 + 8b96f12 commit 11b7c2d
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 64 deletions.
5 changes: 5 additions & 0 deletions Form/Type/AcbFileType.php
Original file line number Diff line number Diff line change
Expand Up @@ -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' => '']
])
;

Expand Down Expand Up @@ -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' => '']
])
;

Expand Down
50 changes: 50 additions & 0 deletions Resources/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
1 change: 1 addition & 0 deletions Resources/translations/AdvancedContentBundle.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions Resources/translations/AdvancedContentBundle.fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
134 changes: 70 additions & 64 deletions Resources/views/Form/content.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -181,85 +181,91 @@
{% endblock %}

{% block acb_image_widget %}
<div {{ block('widget_container_attributes') }}>
{{ form_row(form.file) }}

{% set source = '' %}
{% if form.vars.src is not empty %}
{% set source = uploadManager.webPath ~ '/' ~ form.vars.src %}
{% endif %}
{% if source != '' %}
<div class="form-group">
<a href="{{ asset(source) }}">
<img src="{{ asset(source) }}" height="50px" alt="image">
</a>
{%- set attr = attr|merge({ class: attr.class|default('acb-widget-container') }) -%}
<div {{ block('widget_container_attributes') }}>
<div class="mb-3">
{{ form_row(form.file) }}
<div class="invalid-feedback d-none" data-error="{{ 'field_type.file.restriction_type_error'|trans }}"></div>
</div>
{% endif %}

{% if form.delete is defined %}
{{ form_row(form.delete) }}
{% endif %}
{% if form.src is defined %}
{{ form_row(form.src) }}
{% endif %}
{% set source = '' %}
{% if form.vars.src is not empty %}
{% set source = uploadManager.webPath ~ '/' ~ form.vars.src %}
{% endif %}
{% if source != '' %}
<div class="form-group">
<a href="{{ asset(source) }}">
<img src="{{ asset(source) }}" height="50px" alt="image">
</a>
</div>
{% endif %}

{{ form_row(form.alt) }}
{% if form.mime_type is defined %}
{% import "@SherlockodeAdvancedContent/Common/Macros/collapse.html.twig" as macro %}
{% if form.delete is defined %}
{{ form_row(form.delete) }}
{% endif %}
{% if form.src is defined %}
{{ form_row(form.src) }}
{% endif %}

{% set content %}
{{ form_widget(form.mime_type) }}
{{ form_help(form.mime_type) }}
{{ form_errors(form.mime_type) }}
{% endset %}
{{ form_row(form.alt) }}
{% if form.mime_type is defined %}
{% import "@SherlockodeAdvancedContent/Common/Macros/collapse.html.twig" as macro %}

{% set data = [{'title': form_label(form.mime_type), 'content': content }] %}
{% set content %}
{{ form_widget(form.mime_type, {'attr': {'data-mime-type-restriction-values': ''}}) }}
{{ form_help(form.mime_type) }}
{{ form_errors(form.mime_type) }}
{% endset %}

{{ macro.buildAccordion(data) }}
{% endif %}
{{ form_rest(form) }}
</div>
{% set data = [{'title': form_label(form.mime_type), 'content': content }] %}
{{ macro.buildAccordion(data) }}
{% endif %}
{{ form_rest(form) }}
</div>
{% endblock %}

{% block acb_file_widget %}
<div {{ block('widget_container_attributes') }}>
{{ form_row(form.file) }}

{% set source = '' %}
{% if form.vars.src is not empty %}
{% set source = uploadManager.webPath ~ '/' ~ form.vars.src %}
{% endif %}
{% if source != '' %}
<div class="form-group">
<a href="{{ asset(source) }}" download>
{{ form.vars.src }}
</a>
{%- set attr = attr|merge({ class: attr.class|default('acb-widget-container') }) -%}
<div {{ block('widget_container_attributes') }}>
<div class="mb-3">
{{ form_row(form.file) }}
<div class="invalid-feedback d-none" data-error="{{ 'field_type.file.restriction_type_error'|trans }}"></div>
</div>
{% endif %}

{% if form.delete is defined %}
{{ form_row(form.delete) }}
{% endif %}
{% if form.src is defined %}
{{ form_row(form.src) }}
{% endif %}
{% set source = '' %}
{% if form.vars.src is not empty %}
{% set source = uploadManager.webPath ~ '/' ~ form.vars.src %}
{% endif %}
{% if source != '' %}
<div class="form-group">
<a href="{{ asset(source) }}" download>
{{ form.vars.src }}
</a>
</div>
{% endif %}

{{ form_row(form.title) }}
{% if form.mime_type is defined %}
{% import "@SherlockodeAdvancedContent/Common/Macros/collapse.html.twig" as macro %}
{% if form.delete is defined %}
{{ form_row(form.delete) }}
{% endif %}
{% if form.src is defined %}
{{ form_row(form.src) }}
{% endif %}

{% set content %}
{{ form_widget(form.mime_type) }}
{{ form_help(form.mime_type) }}
{{ form_errors(form.mime_type) }}
{% endset %}
{{ form_row(form.title) }}
{% if form.mime_type is defined %}
{% import "@SherlockodeAdvancedContent/Common/Macros/collapse.html.twig" as macro %}

{% set data = [{'title': form_label(form.mime_type), 'content': content }] %}
{% set content %}
{{ form_widget(form.mime_type, {'attr': {'data-mime-type-restriction-values': ''}}) }}
{{ form_help(form.mime_type) }}
{{ form_errors(form.mime_type) }}
{% endset %}

{{ macro.buildAccordion(data) }}
{% endif %}
{{ form_rest(form) }}
</div>
{% set data = [{'title': form_label(form.mime_type), 'content': content }] %}
{{ macro.buildAccordion(data) }}
{% endif %}
{{ form_rest(form) }}
</div>
{% endblock %}

{% block acb_column_config_row %}
Expand Down

0 comments on commit 11b7c2d

Please sign in to comment.