true, 'png' => true, 'gif' => true, 'webp' => true, 'avif' => false, // Off by default: encoding needs PHP 8.1+ GD or ImageMagick. 'heic' => true, 'svg' => false, // Disabled by default for security. ); } /** * Convert format settings to MIME type array. * * Converts format configuration (jpeg, png, etc.) to an array of MIME types. * * @param array $formats Format configuration array (e.g., array('jpeg' => true, 'png' => false)). * @return array Array of allowed MIME types. * @since 1.0.0 */ public static function get_mime_types_from_formats( $formats ) { $mime_types = array(); if ( ! empty( $formats['jpeg'] ) ) { $mime_types[] = 'image/jpeg'; } if ( ! empty( $formats['png'] ) ) { $mime_types[] = 'image/png'; } if ( ! empty( $formats['gif'] ) ) { $mime_types[] = 'image/gif'; } if ( ! empty( $formats['webp'] ) ) { $mime_types[] = 'image/webp'; } if ( ! empty( $formats['avif'] ) ) { $mime_types[] = 'image/avif'; } if ( ! empty( $formats['heic'] ) ) { $mime_types[] = 'image/heic'; $mime_types[] = 'image/heif'; } if ( ! empty( $formats['svg'] ) ) { $mime_types[] = 'image/svg+xml'; } return $mime_types; } /** * Get all allowed MIME types based on saved settings. * * Returns the enabled image MIME types. Builds that ship the non-image * upload pipeline extend the list with the other file type categories; in * this build that code is not present and non-image uploads are rejected. * * @return array Array of allowed MIME types. * @since 1.0.0 */ public static function get_allowed_mime_types() { $default_formats = self::get_default_formats(); $allowed_formats = get_option( 'gatewell_allowed_formats', $default_formats ); // Type check and fallback. if ( ! is_array( $allowed_formats ) ) { $allowed_formats = $default_formats; } // Ensure all required keys exist. $allowed_formats = wp_parse_args( $allowed_formats, $default_formats ); // Start with image MIME types (always enabled). $allowed_mime_types = self::get_mime_types_from_formats( $allowed_formats ); return array_unique( $allowed_mime_types ); } /** * Check if a MIME type is allowed. * * @param string $mime_type MIME type to check. * @return bool True if allowed, false otherwise. * @since 1.0.0 */ public static function is_mime_type_allowed( $mime_type ) { $allowed_mime_types = self::get_allowed_mime_types(); return in_array( $mime_type, $allowed_mime_types, true ); } /** * Get file extension from MIME type. * * @param string $mime_type MIME type. * @return string File extension (without dot). * @since 1.0.0 */ public static function get_extension_from_mime( $mime_type ) { $extensions = array( 'image/jpeg' => 'jpg', 'image/png' => 'png', 'image/gif' => 'gif', 'image/webp' => 'webp', 'image/avif' => 'avif', 'image/svg+xml' => 'svg', ); return isset( $extensions[ $mime_type ] ) ? $extensions[ $mime_type ] : 'jpg'; } /** * Check if a MIME type is SVG. * * @param string $mime_type MIME type to check. * @return bool True if SVG, false otherwise. * @since 1.1.0 */ public static function is_svg( $mime_type ) { return 'image/svg+xml' === $mime_type; } /** * Get WordPress default MIME types by category. * * Returns all WordPress-supported file types categorized by type. The * image list drives get_file_type_category(), which routes uploads to the * image processor; the other categories are only reachable in builds that * ship the non-image upload pipeline. * * @return array Categorized MIME types. * @since 1.4.0 */ public static function get_wordpress_mime_types_by_category() { return array( 'image' => array( 'image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/avif', 'image/svg+xml', 'image/heic', 'image/heif', ), 'video' => array( 'video/mp4', 'video/quicktime', 'video/x-msvideo', 'video/x-ms-wmv', 'video/mpeg', 'video/ogg', 'video/3gpp', ), 'audio' => array( 'audio/mpeg', 'audio/ogg', 'audio/wav', 'audio/x-wav', ), 'document' => array( 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.oasis.opendocument.text', ), 'archive' => array( 'application/zip', 'application/x-tar', 'application/x-gzip', ), ); } /** * Get file type category from MIME type. * * Determines which category (image, video, audio, document, archive) * a given MIME type belongs to. * * @param string $mime_type MIME type. * @return string Category (image, video, audio, document, archive, unknown). * @since 1.4.0 */ public static function get_file_type_category( $mime_type ) { $categories = self::get_wordpress_mime_types_by_category(); foreach ( $categories as $category => $mime_types ) { if ( in_array( $mime_type, $mime_types, true ) ) { return $category; } } return 'unknown'; } /** * Get metadata fields applicable to a file type category. * * Returns which metadata fields should be shown/available * for each file type category. * * @param string $category File type category. * @return array Array of field names that should be shown. * @since 1.4.0 */ public static function get_applicable_metadata_fields( $category ) { $field_map = array( 'image' => array( 'filename', 'alt_text', 'title', 'caption', 'description' ), 'video' => array( 'filename', 'title', 'caption', 'description' ), 'audio' => array( 'filename', 'title', 'description' ), 'document' => array( 'filename', 'title', 'description' ), 'archive' => array( 'filename', 'description' ), ); return isset( $field_map[ $category ] ) ? $field_map[ $category ] : array( 'filename' ); } /** * Get file extension from MIME type (extended for all file types). * * Maps MIME types to file extensions for all supported file categories. * * @param string $mime_type MIME type. * @return string File extension (without dot). * @since 1.4.0 */ public static function get_extension_from_mime_extended( $mime_type ) { $extensions = array( // Images. 'image/jpeg' => 'jpg', 'image/png' => 'png', 'image/gif' => 'gif', 'image/webp' => 'webp', 'image/avif' => 'avif', 'image/svg+xml' => 'svg', 'image/heic' => 'heic', 'image/heif' => 'heif', // Videos. 'video/mp4' => 'mp4', 'video/quicktime' => 'mov', 'video/x-msvideo' => 'avi', 'video/x-ms-wmv' => 'wmv', 'video/mpeg' => 'mpg', 'video/ogg' => 'ogv', 'video/3gpp' => '3gp', // Audio. 'audio/mpeg' => 'mp3', 'audio/ogg' => 'ogg', 'audio/wav' => 'wav', 'audio/x-wav' => 'wav', // Documents. 'application/pdf' => 'pdf', 'application/msword' => 'doc', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx', 'application/vnd.ms-powerpoint' => 'ppt', 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx', 'application/vnd.ms-excel' => 'xls', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx', 'application/vnd.oasis.opendocument.text' => 'odt', // Archives. 'application/zip' => 'zip', 'application/x-tar' => 'tar', 'application/x-gzip' => 'gz', ); if ( isset( $extensions[ $mime_type ] ) ) { return $extensions[ $mime_type ]; } // Fallback to original method for backward compatibility. return self::get_extension_from_mime( $mime_type ); } }