Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save plugin-republic/cf417236fbbcb78716c0143b60266dec to your computer and use it in GitHub Desktop.

Select an option

Save plugin-republic/cf417236fbbcb78716c0143b60266dec to your computer and use it in GitHub Desktop.
<?php
/**
* Snippet: Auto-delete PEWC uploaded files 30 days after an order is completed.
*
* When an order transitions to "completed", a one-time WP-Cron event is scheduled
* for 30 days later. When that event fires, any uploaded files attached to the
* order are deleted from the filesystem and the order is marked accordingly.
*
* Usage: add this file as an mu-plugin, or require it from your theme/child-theme
* functions.php, or use a snippet plugin such as Code Snippets.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Schedule file deletion 30 days after an order is marked completed.
*
* If the order is set to completed more than once (e.g. after being put back to
* processing), duplicate scheduled events are avoided by checking wp_next_scheduled().
*/
add_action( 'woocommerce_order_status_changed', 'pewc_schedule_auto_file_deletion', 10, 3 );
function pewc_schedule_auto_file_deletion( $order_id, $old_status, $new_status ) {
if ( 'completed' !== $new_status ) {
return;
}
// Don't schedule a second event if one is already pending for this order.
if ( wp_next_scheduled( 'pewc_auto_delete_order_files', array( $order_id ) ) ) {
return;
}
$timestamp = time() + ( 30 * DAY_IN_SECONDS );
wp_schedule_single_event( $timestamp, 'pewc_auto_delete_order_files', array( $order_id ) );
}
/**
* Delete uploaded files for the given order.
*
* Mirrors the deletion logic used by the built-in PEWC cleanup tools:
* - Reads file paths from the `pewc_uploaded_files` order meta (set when rename/
* organise uploads is enabled), falling back to scanning order item meta.
* - Validates each file is within the PEWC upload directory before deleting.
* - Sets `pewc_uploaded_files_deleted` on the order so the built-in cleanup
* tools skip it and the admin order page reflects the correct state.
*/
add_action( 'pewc_auto_delete_order_files', 'pewc_auto_delete_order_files_handler' );
function pewc_auto_delete_order_files_handler( $order_id ) {
// Bail if PEWC is not active.
if ( ! function_exists( 'pewc_get_upload_dir' ) ) {
return;
}
$order = wc_get_order( $order_id );
if ( ! $order ) {
return;
}
// Skip if files have already been deleted (e.g. via the admin cleanup tools).
if ( $order->get_meta( 'pewc_uploaded_files_deleted', true ) ) {
return;
}
$upload_dir = pewc_get_upload_dir();
if ( function_exists( 'pewc_replace_backslashes_in_file_paths' ) && pewc_replace_backslashes_in_file_paths() ) {
$upload_dir = str_replace( '\\', '/', $upload_dir );
}
// Prefer the dedicated meta key set when rename/organise uploads is enabled;
// fall back to extracting paths directly from order item meta.
$uploaded_files = $order->get_meta( 'pewc_uploaded_files', true );
if ( empty( $uploaded_files ) && function_exists( 'pewc_get_uploaded_files_from_order_items' ) ) {
$uploaded_files = pewc_get_uploaded_files_from_order_items( $order );
}
if ( empty( $uploaded_files ) ) {
// No files found — mark as processed so future checks are skipped.
$order->update_meta_data( 'pewc_uploaded_files_deleted', true );
$order->save();
return;
}
$all_deleted = true;
foreach ( $uploaded_files as $file ) {
// Only delete files that exist and sit inside the PEWC upload directory.
if ( is_file( $file ) && false !== strpos( $file, $upload_dir ) ) {
if ( ! unlink( $file ) ) {
$all_deleted = false;
if ( function_exists( 'pewc_error_log' ) ) {
pewc_error_log( 'Auto-delete: Order #' . $order_id . ', could not delete file: ' . $file );
}
}
}
}
if ( $all_deleted ) {
$order->update_meta_data( 'pewc_uploaded_files_deleted', true );
$order->delete_meta_data( 'pewc_uploaded_files_not_deleted' );
$order->save();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment