How are the month (and year) folders automatically added to the uploads directory? The plugin that I am writing keeps track of the folders in uploads and I want to be able to add the new folder(s) each month as they are created. Is there a filter or action related to his process?

1 Answer 1


This is how I understand the process:

The wp_upload_dir() function is the main control room for the upload folder creation process and the wp_mkdir_p() function is the helpful assistant.

Everytime wp_upload_dir() is called, it's actually running a file_exists() check on the current upload folder, through the wp_mkdir_p() function. If the folder doesn't exists it's created with mkdir(), but not $wp_filesystem->mkdir() as one would expect.

The wp_upload_dir() function checks if the uploads_use_yearmonth_folders option is set. In that case the year/month folders are created, by default, from the current time of current_time( 'mysql' ):

// ... cut ...

if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
    // Generate the yearly and monthly dirs
    if ( !$time )
         $time = current_time( 'mysql' );
    $y = substr( $time, 0, 4 );
    $m = substr( $time, 5, 2 );
    $subdir = "/$y/$m";

$dir .= $subdir;
$url .= $subdir;

// ... cut ...

// Make sure we have an uploads directory.
if ( ! wp_mkdir_p( $uploads['path'] ) ) {

// ... cut ...

where $uploads['path'] is assigned to $dir.

The wp_upload_dir() function is called within the _wp_handle_upload() function that's implicitly applied during uploads. We also note that the media_handle_{upload,sideload}() functions are wrappers for the wp_handle_{upload,sideload}() functions, that are again wrappers for the _wp_handle_upload() function.

So I wonder if you might want to hook into these upload processes, using for example the wp_handle_upload filter within the _wp_handle_upload() function:

 * Hook into the upload/sideload processes and check out the upload path.

add_filter( 'wp_handle_upload', function( $args, $action )
    if( isset( $args['file'] ) && file_exists( $args['file'] ) )
        // Upload path of the new file:
        $path = dirname( $args['file'] )

        // ... do stuff here ...
    return $args;
}, 99, 2 );

where $args['file'] contains the local path of the uploaded file and $action can be 'upload' or 'sideload'.

  • This is a great answer!
    – AlanP
    Apr 4, 2015 at 15:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.