'image/jpeg', 'png' => 'image/png', 'webp' => 'image/webp', 'pdf' => 'application/pdf', ); } public static function max_upload_size() { return (int) wp_max_upload_size(); } private static function upload_data() { // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Calling form handlers verify their nonce; file metadata must remain raw for WordPress upload handling. if ( ! isset( $_FILES[ self::FIELD_NAME ] ) || ! is_array( $_FILES[ self::FIELD_NAME ] ) ) { return array(); } // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Raw upload metadata is validated below and by WordPress upload handling. return $_FILES[ self::FIELD_NAME ]; } public static function has_upload() { $file = self::upload_data(); return ! empty( $file['name'] ); } public static function handle( $ticket_id, $message_id, DPSUPPORT_Attachment_Repository $attachments ) { if ( ! self::has_upload() ) { return true; } $file = self::upload_data(); if ( ! empty( $file['error'] ) ) { return false; } $tmp_name = isset( $file['tmp_name'] ) ? (string) $file['tmp_name'] : ''; $safe_name = sanitize_file_name( $file['name'] ?? '' ); if ( ! $tmp_name || ! is_readable( $tmp_name ) || ! $safe_name ) { return false; } $max_size = self::max_upload_size(); $size = isset( $file['size'] ) ? absint( $file['size'] ) : 0; if ( $max_size > 0 && $size > $max_size ) { return false; } $allowed_mimes = self::allowed_mimes(); $checked = wp_check_filetype_and_ext( $tmp_name, $safe_name, $allowed_mimes ); $checked_type = isset( $checked['type'] ) ? sanitize_mime_type( (string) $checked['type'] ) : ''; $checked_ext = isset( $checked['ext'] ) ? sanitize_key( (string) $checked['ext'] ) : ''; if ( ! $checked_type || ! $checked_ext || ! in_array( $checked_type, array_values( $allowed_mimes ), true ) ) { return false; } require_once ABSPATH . 'wp-admin/includes/file.php'; require_once ABSPATH . 'wp-admin/includes/media.php'; require_once ABSPATH . 'wp-admin/includes/image.php'; $attachment_id = media_handle_upload( self::FIELD_NAME, 0, array(), array( 'test_form' => false, 'mimes' => $allowed_mimes, ) ); if ( is_wp_error( $attachment_id ) ) { return false; } if ( ! $attachments->add( $ticket_id, $message_id, $attachment_id ) ) { wp_delete_attachment( $attachment_id, true ); return false; } return true; } }