Skip to content

Commit e7dbee2

Browse files
committed
Build a central function for allowed file types
1 parent ff57ca4 commit e7dbee2

6 files changed

Lines changed: 164 additions & 79 deletions

File tree

dt-assets/functions/enqueue-scripts.php

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -444,18 +444,7 @@ function dt_site_scripts() {
444444
wp_localize_script( 'dt-storage', 'storage_settings',
445445
[
446446
'rest_url' => esc_url_raw( rest_url() ),
447-
'accepted_file_types' => [
448-
'image/*',
449-
'application/pdf',
450-
'audio/*',
451-
'video/*',
452-
'application/msword',
453-
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
454-
'application/vnd.ms-excel',
455-
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
456-
'text/plain',
457-
'text/markdown',
458-
],
447+
'accepted_file_types' => dt_get_default_accepted_file_types(),
459448
'translations' => [
460449
'modals' => [
461450
'upload' => [

dt-core/admin/js/dt-settings.js

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,40 +1609,57 @@ jQuery(document).ready(function ($) {
16091609

16101610
// Add file_upload field-specific options
16111611
if (field_type === 'file_upload') {
1612-
let accepted_file_types = field_settings['accepted_file_types'] || [
1613-
'image/*',
1614-
'application/pdf',
1615-
'audio/*',
1616-
'video/*',
1617-
'application/msword',
1618-
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
1619-
'application/vnd.ms-excel',
1620-
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
1621-
'text/plain',
1622-
'text/markdown',
1623-
];
1612+
const fileTypeCategories = all_settings.file_type_categories || {};
1613+
let storedTypes = field_settings['accepted_file_types'] || null;
1614+
let hasStoredTypes = storedTypes !== null;
1615+
16241616
let max_file_size = field_settings['max_file_size'] || '';
16251617
let delete_enabled = field_settings['delete_enabled'] !== false; // default true
16261618
let display_layout = field_settings['display_layout'] || 'grid';
16271619
let auto_upload = field_settings['auto_upload'] !== false; // default true
16281620
let download_enabled = field_settings['download_enabled'] !== false; // default true
16291621
let rename_enabled = field_settings['rename_enabled'] !== false; // default true
16301622

1623+
let categoryCheckboxes = '';
1624+
for (const [catKey, cat] of Object.entries(fileTypeCategories)) {
1625+
let isChecked =
1626+
!hasStoredTypes ||
1627+
cat.types.every((t) => storedTypes.includes(t));
1628+
categoryCheckboxes += `
1629+
<label style="margin-right: 1em;">
1630+
<input type="checkbox" class="accepted-file-category"
1631+
data-types='${JSON.stringify(cat.types)}' ${isChecked ? 'checked' : ''}>
1632+
${cat.label}
1633+
</label>`;
1634+
}
1635+
1636+
// Compute "other" types not covered by any category
1637+
let allCategoryTypes = Object.values(fileTypeCategories).flatMap(
1638+
(c) => c.types,
1639+
);
1640+
let otherTypes = hasStoredTypes
1641+
? storedTypes.filter((t) => !allCategoryTypes.includes(t)).join(', ')
1642+
: '';
1643+
16311644
modal_html_content += `
16321645
<tr>
16331646
<td>
1634-
<label for="accepted_file_types"><b>Accepted File Types</b></label>
1647+
<b>Accepted File Types</b>
16351648
</td>
16361649
<td>
1637-
<input type="text" name="accepted_file_types" id="accepted_file_types"
1638-
value="${accepted_file_types.join(', ')}"
1639-
placeholder="e.g., image/*, audio/*, video/*, application/pdf, .docx"
1640-
style="width: 100%;">
1650+
${categoryCheckboxes}
1651+
<div style="margin-top: 6px;">
1652+
<label for="other_file_types"><b>Other</b></label>
1653+
<input type="text" name="other_file_types" id="other_file_types"
1654+
value="${otherTypes}"
1655+
placeholder="e.g., application/zip, .csv"
1656+
style="width: 100%;">
1657+
<p style="font-size: 11px; color: #666; margin-top: 3px;">
1658+
Comma-separated MIME types or file extensions for additional file types.
1659+
</p>
1660+
</div>
16411661
<p style="font-size: 11px; color: #666; margin-top: 5px;">
1642-
Optional. Comma-separated list of MIME types or file extensions to override the default set (images, PDFs, audio, video, common documents). Leave empty to use the default types.
1643-
<a href="https://developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types" target="_blank" rel="noopener noreferrer">
1644-
View common MIME types.
1645-
</a>
1662+
Select which file type categories are allowed for upload. If none are selected, all types will be accepted.
16461663
</p>
16471664
</td>
16481665
</tr>
@@ -2421,9 +2438,24 @@ jQuery(document).ready(function ($) {
24212438

24222439
// Add file_upload field-specific options to visibility object
24232440
if (field_settings['type'] && field_settings['type'] === 'file_upload') {
2424-
visibility['accepted_file_types'] = $('#accepted_file_types')
2425-
.val()
2426-
.trim();
2441+
let checkedTypes = [];
2442+
let totalCategories = $('.accepted-file-category').length;
2443+
$('.accepted-file-category:checked').each(function () {
2444+
checkedTypes = checkedTypes.concat(
2445+
JSON.parse($(this).attr('data-types')),
2446+
);
2447+
});
2448+
let otherVal = $('#other_file_types').val().trim();
2449+
let otherList = otherVal
2450+
? otherVal.split(',').map((s) => s.trim()).filter(Boolean)
2451+
: [];
2452+
let allTypes = checkedTypes.concat(otherList);
2453+
let allCategoriesChecked =
2454+
$('.accepted-file-category:checked').length === totalCategories;
2455+
visibility['accepted_file_types'] =
2456+
allCategoriesChecked && otherList.length === 0
2457+
? ''
2458+
: allTypes.join(', ');
24272459
visibility['max_file_size'] = $('#max_file_size').val().trim();
24282460
visibility['delete_enabled'] = $('#delete_enabled').is(':checked');
24292461
visibility['display_layout'] = $('#display_layout').val();

dt-core/admin/menu/tabs/tab-custom-fields.php

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -545,18 +545,11 @@ private function edit_field( $field_key, $post_type ){
545545
<?php
546546
$custom_fields = dt_get_option( 'dt_field_customizations' );
547547
$custom_field = $custom_fields[ $post_type ][ $field_key ] ?? [];
548-
$accepted_file_types = $custom_field['accepted_file_types'] ?? [
549-
'image/*',
550-
'application/pdf',
551-
'audio/*',
552-
'video/*',
553-
'application/msword',
554-
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
555-
'application/vnd.ms-excel',
556-
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
557-
'text/plain',
558-
'text/markdown',
559-
];
548+
$file_type_categories = dt_get_file_type_categories();
549+
$has_stored_types = isset( $custom_field['accepted_file_types'] );
550+
$stored_types = $custom_field['accepted_file_types'] ?? [];
551+
$all_category_types = array_merge( ...array_column( $file_type_categories, 'types' ) );
552+
$other_types = $has_stored_types ? array_values( array_diff( $stored_types, $all_category_types ) ) : [];
560553
$max_file_size = $custom_field['max_file_size'] ?? '';
561554
$delete_enabled = isset( $custom_field['delete_enabled'] ) ? $custom_field['delete_enabled'] : true;
562555
$display_layout = $custom_field['display_layout'] ?? 'grid';
@@ -567,19 +560,32 @@ private function edit_field( $field_key, $post_type ){
567560
<h3><?php esc_html_e( 'Field Options', 'disciple_tools' ) ?></h3>
568561
<table id="file_upload_options">
569562
<tr>
570-
<td style="vertical-align: middle">
571-
<label for="accepted_file_types"><b><?php esc_html_e( 'Accepted File Types', 'disciple_tools' ) ?></b></label>
563+
<td style="vertical-align: top">
564+
<b><?php esc_html_e( 'Accepted File Types', 'disciple_tools' ) ?></b>
572565
</td>
573566
<td>
574-
<input type="text" name="accepted_file_types" id="accepted_file_types"
575-
value="<?php echo esc_attr( implode( ', ', $accepted_file_types ) ) ?>"
576-
placeholder="e.g., image/*, audio/*, video/*, application/pdf, .docx"
577-
style="width: 100%;" />
567+
<?php foreach ( $file_type_categories as $cat_key => $cat ) :
568+
$is_checked = ! $has_stored_types || empty( array_diff( $cat['types'], $stored_types ) );
569+
?>
570+
<label style="margin-right: 1em;">
571+
<input type="checkbox" name="accepted_file_categories[]"
572+
value="<?php echo esc_attr( $cat_key ) ?>"
573+
<?php echo $is_checked ? 'checked' : ''; ?>>
574+
<?php echo esc_html( $cat['label'] ) ?>
575+
</label>
576+
<?php endforeach; ?>
577+
<div style="margin-top: 6px;">
578+
<label for="other_file_types"><b><?php esc_html_e( 'Other', 'disciple_tools' ) ?></b></label>
579+
<input type="text" name="other_file_types" id="other_file_types"
580+
value="<?php echo esc_attr( implode( ', ', $other_types ) ) ?>"
581+
placeholder="<?php esc_attr_e( 'e.g., application/zip, .csv', 'disciple_tools' ) ?>"
582+
style="width: 100%;" />
583+
<p style="font-size: 11px; color: #666; margin-top: 3px;">
584+
<?php esc_html_e( 'Comma-separated MIME types or file extensions for additional file types.', 'disciple_tools' ); ?>
585+
</p>
586+
</div>
578587
<p style="font-size: 11px; color: #666; margin-top: 5px;">
579-
<?php esc_html_e( 'Optional. Comma-separated list of MIME types or file extensions to override the default set (images, PDFs, audio, video, common documents). Leave empty to use the default types.', 'disciple_tools' ); ?>
580-
<a href="<?php echo esc_url( 'https://developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types' ); ?>" target="_blank" rel="noopener noreferrer">
581-
<?php esc_html_e( 'View common MIME types.', 'disciple_tools' ); ?>
582-
</a>
588+
<?php esc_html_e( 'Select which file type categories are allowed for upload. If none are selected, all types will be accepted.', 'disciple_tools' ); ?>
583589
</p>
584590
</td>
585591
</tr>
@@ -1045,16 +1051,33 @@ private function process_edit_field( $post_submission ){
10451051

10461052
// file_upload field options
10471053
if ( $field['type'] === 'file_upload' ) {
1048-
// Accepted file types
1049-
if ( isset( $post_submission['accepted_file_types'] ) ) {
1050-
$raw_accepted = trim( $post_submission['accepted_file_types'] );
1051-
if ( $raw_accepted === '' ) {
1052-
// Clear any previously saved override so defaults are used
1053-
unset( $custom_field['accepted_file_types'] );
1054-
} else {
1055-
$types = array_map( 'sanitize_text_field', array_map( 'trim', explode( ',', $raw_accepted ) ) );
1056-
$custom_field['accepted_file_types'] = $types;
1054+
// Accepted file types from category checkboxes
1055+
$category_mime_map = array_map( function ( $cat ) {
1056+
return $cat['types'];
1057+
}, dt_get_file_type_categories() );
1058+
$selected_categories = isset( $post_submission['accepted_file_categories'] )
1059+
? array_map( 'sanitize_text_field', $post_submission['accepted_file_categories'] )
1060+
: [];
1061+
1062+
$raw_other = isset( $post_submission['other_file_types'] ) ? trim( $post_submission['other_file_types'] ) : '';
1063+
$other_types = $raw_other !== ''
1064+
? array_map( 'sanitize_text_field', array_map( 'trim', explode( ',', $raw_other ) ) )
1065+
: [];
1066+
1067+
$all_categories_selected = count( $selected_categories ) === count( $category_mime_map );
1068+
if ( $all_categories_selected && empty( $other_types ) ) {
1069+
unset( $custom_field['accepted_file_types'] );
1070+
} else if ( empty( $selected_categories ) && empty( $other_types ) ) {
1071+
unset( $custom_field['accepted_file_types'] );
1072+
} else {
1073+
$types = [];
1074+
foreach ( $selected_categories as $cat_key ) {
1075+
if ( isset( $category_mime_map[ $cat_key ] ) ) {
1076+
$types = array_merge( $types, $category_mime_map[ $cat_key ] );
1077+
}
10571078
}
1079+
$types = array_merge( $types, $other_types );
1080+
$custom_field['accepted_file_types'] = $types;
10581081
}
10591082

10601083
// Max file size

dt-core/admin/menu/tabs/tab-customizations.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ public function admin_enqueue_scripts() {
121121
'nonce' => wp_create_nonce( 'wp_rest' ),
122122
'site_url' => get_site_url(),
123123
'template_dir' => get_template_directory_uri(),
124+
'file_type_categories' => dt_get_file_type_categories(),
124125
];
125126

126127
if ( !empty( $post_type ) ) {

dt-core/global-functions.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,6 +1556,44 @@ function dt_get_duplicate_fields_defaults( $post_type ) {
15561556
return apply_filters( 'dt_duplicate_fields_defaults', $default_fields, $post_type );
15571557
}
15581558

1559+
function dt_get_file_type_categories() {
1560+
return [
1561+
'images' => [
1562+
'label' => __( 'Images', 'disciple_tools' ),
1563+
'types' => [ 'image/*' ],
1564+
],
1565+
'pdfs' => [
1566+
'label' => __( 'PDFs', 'disciple_tools' ),
1567+
'types' => [ 'application/pdf' ],
1568+
],
1569+
'documents' => [
1570+
'label' => __( 'Documents', 'disciple_tools' ),
1571+
'description' => __( 'Word, Excel, CSV, text, markdown', 'disciple_tools' ),
1572+
'types' => [
1573+
'application/msword',
1574+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
1575+
'application/vnd.ms-excel',
1576+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
1577+
'text/csv',
1578+
'text/plain',
1579+
'text/markdown',
1580+
],
1581+
],
1582+
'audio' => [
1583+
'label' => __( 'Audio', 'disciple_tools' ),
1584+
'types' => [ 'audio/*' ],
1585+
],
1586+
'video' => [
1587+
'label' => __( 'Video', 'disciple_tools' ),
1588+
'types' => [ 'video/*' ],
1589+
],
1590+
];
1591+
}
1592+
1593+
function dt_get_default_accepted_file_types() {
1594+
return array_merge( ...array_column( dt_get_file_type_categories(), 'types' ) );
1595+
}
1596+
15591597
/**
15601598
* All code above here.
15611599
*/

dt-core/utilities/dt-components.php

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -332,18 +332,19 @@ public static function render_file_upload( $field_key, $fields, $post, $params =
332332
}
333333

334334
// Get field settings for configuration
335-
$accepted_file_types = $fields[ $field_key ]['accepted_file_types'] ?? [
336-
'image/*',
337-
'application/pdf',
338-
'audio/*',
339-
'video/*',
340-
'application/msword',
341-
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
342-
'application/vnd.ms-excel',
343-
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
344-
'text/plain',
345-
'text/markdown',
346-
];
335+
$accepted_file_types = $fields[ $field_key ]['accepted_file_types'] ?? dt_get_default_accepted_file_types();
336+
$categories = dt_get_file_type_categories();
337+
$all_category_types = array_merge( ...array_column( $categories, 'types' ) );
338+
$labels = [];
339+
foreach ( $categories as $cat ) {
340+
if ( !empty( array_intersect( $cat['types'], $accepted_file_types ) ) ) {
341+
$labels[] = $cat['label'];
342+
}
343+
}
344+
$other_types = array_diff( $accepted_file_types, $all_category_types );
345+
$labels = array_merge( $labels, array_values( $other_types ) );
346+
$accepted_file_types_label = implode( ', ', $labels );
347+
347348
$max_file_size = $fields[$field_key]['max_file_size'] ?? null;
348349
$delete_enabled = isset( $fields[$field_key]['delete_enabled'] ) ? $fields[$field_key]['delete_enabled'] : true;
349350
$display_layout = $fields[$field_key]['display_layout'] ?? 'grid';
@@ -420,6 +421,7 @@ public static function render_file_upload( $field_key, $fields, $post, $params =
420421
<?php endif; ?>
421422
value="<?php echo esc_attr( json_encode( $enhanced_value ) ) ?>"
422423
accepted-file-types='<?php echo esc_attr( json_encode( $accepted_file_types ) ) ?>'
424+
accepted-file-types-label="<?php echo esc_attr( $accepted_file_types_label ) ?>"
423425
<?php if ( $max_file_size ): ?>
424426
max-file-size="<?php echo esc_attr( $max_file_size ) ?>"
425427
<?php endif; ?>

0 commit comments

Comments
 (0)