WordPress.org

Make WordPress Core

Opened 3 years ago

Closed 2 years ago

#38907 closed feature request (duplicate)

Add `path_is_absolute` filter.

Reported by: tmatsuo Owned by:
Milestone: Priority: normal
Severity: normal Version: 4.6.1
Component: Media Keywords:
Focuses: Cc:
PR Number:

Description

so that plugin developers can easily add media functionalities with stream wrappers.

The path_is_absolute function will be updated to:

<?php
function path_is_absolute( $path ) {
    /*
     * First apply a filter and see the result
     */
    if ( apply_filters('path_is_absolute', $path) == true )
        return true;

    /*
     * This is definitive if true but fails if $path does not exist or contains
     * a symbolic link.
     */
    if ( realpath($path) == $path )
        return true;
 
    if ( strlen($path) == 0 || $path[0] == '.' )
        return false;
 
    // Windows allows absolute paths like this.
    if ( preg_match('#^[a-zA-Z]:\\\\#', $path) )
        return true;
 
    // A path starting with / or \ is absolute; anything else is relative.
    return ( $path[0] == '/' || $path[0] == '\\' );
}

Background:

I'm developing a plugin for uploading media files to Google Cloud Storage, using Google Cloud Storage stream wrapper (gs:// path).

It's easy to use the upload_dir to achieve it, but when it comes to deleting media files, there is a problem.

In wp-includes/post.php, there are some code to delete related files when you delete an uploaded media file:

<?php
        // Remove intermediate and backup images if there are any.
        if ( isset( $meta['sizes'] ) && is_array( $meta['sizes'] ) ) {
                foreach ( $meta['sizes'] as $size => $sizeinfo ) {
                        $intermediate_file = str_replace( basename( $file ), $sizeinfo['file'], $file );
                        /** This filter is documented in wp-includes/functions.php */
                        $intermediate_file = apply_filters( 'wp_delete_file', $intermediate_file );
                        @ unlink( path_join( $uploadpath['basedir'], $intermediate_file ) );
                }
        }

When we replace directories with upload_dir filter, the values of $uploadpath['basedir'] and $intermediate_file are:

<?php
$uploadpath['basedir']; // gs://bucket_name/1/
$intermediate_file; // gs://bucket_name/1/2016/11/old-electrical-panel-150x150.jpg

So the path_join now returns something like: gs://bucket_name/1/gs://bucket_name/1/2016/11/old-electrical-panel-150x150.jpg because the file path is not considered as absolute. If we can customize the return value of path_is_absolute, then the return value of path_join will be something like gs://bucket_name/1/2016/11/old-electrical-panel-150x150.jpg and the media editor correctly unlink the files.

I'd appreciate it if you could consider adding this filter.
Of course, let me know if there are better solutions.

Thanks,

Change History (3)

#1 @tmatsuo
3 years ago

Or, even, if the path starts with one of the registered stream wrappers, can path_is_absolute just return true? You can use stream_get_wrappers to get the registered protocols.

This ticket was mentioned in Slack in #core-media by desrosj. View the logs.


2 years ago

#3 @joemcgill
2 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to duplicate
  • Status changed from new to closed

Hi @tmatsuo,

Thanks for the request, and detailed description. I think this may be a duplicate of #39476. Can you take a look at that ticket and see if the proposed solution would address your concerns?

Thanks,
Joe

Note: See TracTickets for help on using tickets.