Automattic\WooCommerce\Internal\TransientFiles
TransientFilesEngine::delete_expired_files
Delete expired transient files from the filesystem.
Method of the class: TransientFilesEngine{}
No Hooks.
Returns
array. "deleted_count" with the number of files actually deleted, "files_remain" that will be true if there are still files left to delete.
Usage
$TransientFilesEngine = new TransientFilesEngine(); $TransientFilesEngine->delete_expired_files( $limit ): array;
- $limit(int)
- Maximum number of files to delete.
Default:1000
TransientFilesEngine::delete_expired_files() TransientFilesEngine::delete expired files code WC 11.1.2
public function delete_expired_files( int $limit = 1000 ): array {
$expiration_date_gmt = $this->legacy_proxy->call_function( 'gmdate', 'Y-m-d' );
$base_dir = $this->get_transient_files_directory();
/*
* scandir, not glob: glob doesn't support stream wrappers (it always goes to the local filesystem)
* and returns an empty array for paths like "s3://bucket/uploads", which would silently turn the
* cleanup into a no-op on those sites. scandir returns bare names rather than full paths.
*/
$entries = scandir( $base_dir );
if ( false === $entries ) {
// phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Not rendered as output, and consistent with the other throws in this class.
throw new Exception( "Error when getting the list of subdirectories of $base_dir" );
}
$subdirs = array_values(
array_filter(
$entries,
fn( $name ) => 1 === preg_match( self::EXPIRATION_DATE_DIRECTORY_REGEX, $name ) && is_dir( $base_dir . '/' . $name )
)
);
$expired_subdirs = array_filter( $subdirs, fn( $name ) => $name < $expiration_date_gmt );
asort( $subdirs ); // We want to delete files starting with the oldest expiration month.
$remaining_limit = $limit;
$limit_reached = false;
foreach ( $expired_subdirs as $subdir ) {
$full_dir_path = $base_dir . '/' . $subdir;
$dir_entries = scandir( $full_dir_path );
if ( false === $dir_entries ) {
// phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Not rendered as output, and consistent with the other throws in this class.
throw new Exception( "Error when getting the list of files in $full_dir_path" );
}
$files_to_delete = array_values(
array_map(
fn( $name ) => $full_dir_path . '/' . $name,
// Skip dot files, matching what the "*" glob pattern used to do. This also drops "." and "..".
array_filter( $dir_entries, fn( $name ) => '.' !== $name[0] )
)
);
if ( count( $files_to_delete ) > $remaining_limit ) {
$limit_reached = true;
$files_to_delete = array_slice( $files_to_delete, 0, $remaining_limit );
}
array_map( 'wp_delete_file', $files_to_delete );
$remaining_limit -= count( $files_to_delete );
$this->delete_directory_if_not_empty( $full_dir_path );
if ( $limit_reached ) {
break;
}
}
return array(
'deleted_count' => $limit - $remaining_limit,
'files_remain' => $limit_reached,
);
}