Description
The deleteuploadedfiles
Class is designed to delete uploaded files subsequent to email notifications. This functionality is particularly useful when entry storage and saving to the Media Library are disabled.
WPForms strongly discourages modifying any parent theme files directly. Any alterations made directly to the parent theme are at risk of being overwritten during theme updates, resulting in the loss of customizations. It is advised to create and use a child theme for making any desired changes.
Methods
- Establish dependencies to support the Class by generating a file named
class-delete-uploaded-files.php
within the root directory of your theme. - After creating this file, open your
functions.php
and insert the following snippet. Save the changes to your functions file.require __DIR__ . '/class-delete-uploaded-files.php'; ( new \WPF\DeleteUploadedFiles() )->hooks();
Source
File: class-delete-uploaded-files.php
/** * Class deleteuploadedfiles to delete uploaded files from the server * * @link https://wpforms.com/developers/class-deleteuploadedfiles/ */ <?php namespace WPF; class DeleteUploadedFiles { /** * Should we delete files from the WordPress Media Library? * Change the constant to true to delete files form the WordPress Media Library. */ const DELETE_MEDIA_FILES = false; /** * Add hooks. */ public function hooks() { add_action( 'wpforms_process_complete', [ $this, 'delete_attached_files' ], 10, 4 ); add_filter( 'wpforms_html_field_value', [ $this, 'replace_html_field_value' ], 100, 4 ); add_filter( 'wpforms_emails_notifications_plaintext_field_value', [ $this, 'replace_plaintext_field_value' ], 100, 3 ); add_filter( 'wpforms_smarttags_process_field_id_value', [ $this, 'replace_field_id_smart_tags_value' ], 10, 5 ); add_filter( 'wpforms_smarttags_process_field_value_id_value', [ $this, 'replace_field_value_id_smart_tags_value' ], 10, 5 ); } /** * Delete attached files after emails are sent if these files aren't stored in entries. * * @param array $fields Fields data. * @param array $entry Form submission raw data ($_POST). * @param array $form_data Form data and settings. * @param int $entry_id Entry ID. */ public function delete_attached_files( $fields, $entry, $form_data, $entry_id ) { if ( ! $this->is_allowed_delete_files_after_sending_email( $form_data ) ) { return; } $delete_files_fields = $this->get_filtered_attached_files_fields( $form_data ); if ( empty( $delete_files_fields ) ) { return; } foreach ( $delete_files_fields as $field_id ) { if ( empty( $fields[ $field_id ] ) ) { continue; } $field = $fields[ $field_id ]; if ( self::DELETE_MEDIA_FILES ) { if ( ! empty( $field[ 'style' ] ) && $field[ 'style' ] === 'modern' ) { $is_media_field = false; foreach ( $field[ 'value_raw' ] as $file ) { if ( ! empty( $file[ 'attachment_id' ] ) ) { wp_delete_attachment( $file[ 'attachment_id' ], true ); $is_media_field = true; } } if ( $is_media_field ) { continue; } } if ( ! empty( $field[ 'attachment_id' ] ) ) { wp_delete_attachment( $field[ 'attachment_id' ], true ); continue; } } $files_paths = \WPForms_Field_File_Upload::get_entry_field_file_paths( $form_data[ 'id' ], $field ); if ( empty( $files_paths ) ) { continue; } foreach ( $files_paths as $path ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.unlink_unlink @unlink( $path ); } } } /** * Replace field value with (attached) text if file is attached * to email and will be deleted after sending HTML email. * * @param string $field_val Field value. * @param array $field The field. * @param array $form_data Form data and settings. * @param string $context Context usage. * * @return string */ public function replace_html_field_value( $field_val, $field, $form_data, $context ) { if ( $context !== 'email-html' ) { return $field_val; } if ( empty( $field[ 'type' ] ) || $field[ 'type' ] !== 'file-upload' ) { return $field_val; } if ( ! $this->is_allowed_delete_files_after_sending_email( $form_data ) ) { return $field_val; } $delete_files_fields = $this->get_filtered_attached_files_fields( $form_data ); if ( empty( $field[ 'id' ] ) || ! in_array( $field[ 'id' ], $delete_files_fields, true ) ) { return $field_val; } if ( ! empty( $field[ 'style' ] ) && $field[ 'style' ] === 'modern' ) { $files = []; foreach ( $field['value_raw'] as $file ) { $file_name = $file['file'] ?? ''; $files[] = sprintf( '%1$s (%2$s)', $file_name, __( 'attached', 'wpforms' ) ); } return implode( "\n", $files ); } $file_name = $field[ 'file' ] ?? ''; return sprintf( '%1$s (%2$s)', $file_name, __( 'attached', 'wpforms' ) ); } /** * Replace field value with (attached) text if file is attached * to email and will be deleted after sending text email. * * @param string $field_val Field value. * @param array $field The field. * @param array $form_data Form data and settings. * * @return string */ public function replace_plaintext_field_value( $field_val, $field, $form_data ) { $replaced_value = $this->replace_html_field_value( $field_val, $field, $form_data, 'email-html' ); if ( $replaced_value !== $field ) { return $replaced_value . "\r\n\r\n"; } return $field_val; } /** * Replace {field_id} smart tag value with (attached) text if file is attached * to email and will be deleted after sending text email. * * @param scalar|null $value Smart Tag value. * @param array $form_data Form data. * @param array $fields List of fields. * @param int $entry_id Entry ID. * @param SmartTag $smart_tag_object The smart tag object or the Generic object for those cases when class unregistered. * * @return string */ public function replace_field_id_smart_tags_value( $value, $form_data, $fields, $entry_id, $smart_tag_object ) { $attributes = $smart_tag_object->get_attributes(); if ( empty( $attributes[ 'field_id' ] ) ) { return $value; } if ( empty( $fields[ $attributes[ 'field_id' ] ] ) ) { return $value; } return $this->replace_html_field_value( $value, $fields[ $attributes[ 'field_id' ] ], $form_data, 'email-html' ); } /** * Replace {field_value_id} smart tag value with (attached) text if file is attached * to email and will be deleted after sending text email. * * @param scalar|null $value Smart Tag value. * @param array $form_data Form data. * @param array $fields List of fields. * @param int $entry_id Entry ID. * @param SmartTag $smart_tag_object The smart tag object or the Generic object for those cases when class unregistered. * * @return string */ public function replace_field_value_id_smart_tags_value( $value, $form_data, $fields, $entry_id, $smart_tag_object ) { $attributes = $smart_tag_object->get_attributes(); if ( empty( $attributes[ 'field_value_id' ] ) ) { return $value; } if ( empty( $fields[ $attributes[ 'field_value_id' ] ] ) ) { return $value; } return $this->replace_html_field_value( $value, $fields[ $attributes[ 'field_value_id' ] ], $form_data, 'email-html' ); } /** * Determine if the files should be deleted after sending email. * * @param array $form_data Form data and settings. * * @return bool */ private function is_allowed_delete_files_after_sending_email( $form_data ) { return ! empty( $form_data[ 'settings' ][ 'disable_entries' ] ) && ! empty( $form_data[ 'settings' ][ 'notifications' ] ); } /** * Get fields IDs that are attached to email and will be deleted after sending email. * * @param array $form_data Form data and settings. * * @return array */ private function get_filtered_attached_files_fields( $form_data ) { if ( empty( $form_data[ 'fields' ] ) || empty( $form_data[ 'settings' ][ 'notifications' ] ) ) { return []; } $fields = $this->get_all_attached_files_fields( $form_data ); foreach ( $fields as $key => $field_id ) { if ( empty( $form_data[ 'fields' ][ $field_id ][ 'type' ] ) || $form_data['fields'][ $field_id ][ 'type' ] !== 'file-upload' ) { unset( $fields[ $key ] ); } if ( ! self::DELETE_MEDIA_FILES && ! empty( $form_data[ 'fields' ][ $field_id ][ 'media_library' ] ) ) { unset( $fields[ $key ] ); } } return $fields; } /** * Get fields IDs that are attached to email. * * @param array $form_data Form data and settings. * * @return array */ private function get_all_attached_files_fields( $form_data ) { $is_first = true; $fields = []; foreach ( $form_data[ 'settings' ][ 'notifications' ] as $notification ) { if ( empty( $notification[ 'file_upload_attachment_enable' ] ) || empty( $notification[ 'file_upload_attachment_fields' ] ) ) { return []; } if ( $is_first ) { $fields = $notification[ 'file_upload_attachment_fields' ]; $is_first = false; continue; } $fields = array_intersect( $fields, $notification[ 'file_upload_attachment_fields' ] ); } return $fields; } }
Usage
To utilize this Class, there are certain setup requirements.
Entries are disabled
To disable storing the entries, select Settings » General. Confirm the Disable storing entry information in WordPress is enabled.
Disable storing uploads to Media Library
Next, be sure the File Upload field has the Store file in WordPress Media Library disabled by clicking on the field and on the Advanced tab, be sure the setting is disabled.
Attach file to email notifications
Finally, the last step is to be sure the file attachements are enabled to the email notification. To complete this step, navigate to Settings » Notifications and under the Advanced options, enable the Enable File Upload Attachments. From the File Upload Fields dropdown select your upload field.
Once these settings are completed, any file upload on your forms will attach the files uploaded but not store them on your server.
Additional (optional)
Moreover, this Class permits the removal of uploaded files from the WP Media Library. This feature is turned off by default since certain users might prefer to retain uploaded files in the WP Media, especially when utilizing Post Submissions addon and requiring file storage for thumbnails. Nevertheless, if users wish to delete both uploaded files and associated files from the WP Media Library, please must modify the DELETE_MEDIA_FILES
constant in the class-delete-uploaded-files.php
file to true
.