Last active
May 29, 2021 15:16
-
-
Save earth3300/b339f4911ced0022a7d195264c417f5d to your computer and use it in GitHub Desktop.
The _wp_upload_dir function that tries to do too much (and fails when you need it most).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A non-filtered, non-cached version of wp_upload_dir() that doesn't check the path. | |
* | |
* @since 4.5.0 | |
* @access private | |
* | |
* @param string $time Optional. Time formatted in 'yyyy/mm'. Default null. | |
* @return array See wp_upload_dir() | |
*/ | |
function _wp_upload_dir( $time = null ) { | |
$siteurl = get_option( 'siteurl' ); | |
$upload_path = trim( get_option( 'upload_path' ) ); | |
if ( empty( $upload_path ) || 'wp-content/uploads' == $upload_path ) { | |
$dir = WP_CONTENT_DIR . '/uploads'; | |
} elseif ( 0 !== strpos( $upload_path, ABSPATH ) ) { | |
// $dir is absolute, $upload_path is (maybe) relative to ABSPATH | |
$dir = path_join( ABSPATH, $upload_path ); | |
} else { | |
$dir = $upload_path; | |
} | |
echo $upload_path; | |
if ( ! $url = get_option( 'upload_url_path' ) ) { | |
if ( empty( $upload_path ) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) ) { | |
$url = WP_CONTENT_URL . '/uploads'; | |
} else { | |
$url = trailingslashit( $siteurl ) . $upload_path; | |
} | |
} | |
/* | |
* Honor the value of UPLOADS. This happens as long as ms-files rewriting is disabled. | |
* We also sometimes obey UPLOADS when rewriting is enabled -- see the next block. | |
*/ | |
if ( defined( 'UPLOADS' ) && ! ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) ) { | |
$dir = ABSPATH . UPLOADS; | |
$url = trailingslashit( $siteurl ) . UPLOADS; | |
} | |
// If multisite (and if not the main site in a post-MU network) | |
if ( is_multisite() && ! ( is_main_network() && is_main_site() && defined( 'MULTISITE' ) ) ) { | |
if ( ! get_site_option( 'ms_files_rewriting' ) ) { | |
/* | |
* If ms-files rewriting is disabled (networks created post-3.5), it is fairly | |
* straightforward: Append sites/%d if we're not on the main site (for post-MU | |
* networks). (The extra directory prevents a four-digit ID from conflicting with | |
* a year-based directory for the main site. But if a MU-era network has disabled | |
* ms-files rewriting manually, they don't need the extra directory, as they never | |
* had wp-content/uploads for the main site.) | |
*/ | |
if ( defined( 'MULTISITE' ) ) { | |
$ms_dir = '/sites/' . get_current_blog_id(); | |
} else { | |
$ms_dir = '/' . get_current_blog_id(); | |
} | |
$dir .= $ms_dir; | |
$url .= $ms_dir; | |
} elseif ( defined( 'UPLOADS' ) && ! ms_is_switched() ) { | |
/* | |
* Handle the old-form ms-files.php rewriting if the network still has that enabled. | |
* When ms-files rewriting is enabled, then we only listen to UPLOADS when: | |
* 1) We are not on the main site in a post-MU network, as wp-content/uploads is used | |
* there, and | |
* 2) We are not switched, as ms_upload_constants() hardcodes these constants to reflect | |
* the original blog ID. | |
* | |
* Rather than UPLOADS, we actually use BLOGUPLOADDIR if it is set, as it is absolute. | |
* (And it will be set, see ms_upload_constants().) Otherwise, UPLOADS can be used, as | |
* as it is relative to ABSPATH. For the final piece: when UPLOADS is used with ms-files | |
* rewriting in multisite, the resulting URL is /files. (#WP22702 for background.) | |
*/ | |
if ( defined( 'BLOGUPLOADDIR' ) ) { | |
$dir = untrailingslashit( BLOGUPLOADDIR ); | |
} else { | |
$dir = ABSPATH . UPLOADS; | |
} | |
$url = trailingslashit( $siteurl ) . 'files'; | |
} | |
} | |
$basedir = $dir; | |
$baseurl = $url; | |
$subdir = ''; | |
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; | |
$arr = array( | |
'path' => $dir, | |
'url' => $url, | |
'subdir' => $subdir, | |
'basedir' => $basedir, | |
'baseurl' => $baseurl, | |
'error' => false, | |
); | |
echo '<pre>'; | |
var_dump( $arr ); | |
echo '</pre>'; | |
return $arr; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* A non-filtered, non-cached version of wp_upload_dir() that doesn't check the path. | |
* | |
* @since 4.5.0 | |
* @access private | |
* | |
* @param string $time Optional. Time formatted in 'yyyy/mm'. Default null. | |
* @return array See wp_upload_dir() | |
*/ | |
function _wp_upload_dir( $time = null ) { | |
// Define the path to the root of the site ($site_root_path goes to the core). | |
if ( ! defined( 'SITE_ROOT_PATH' ) ) | |
{ | |
define( 'SITE_ROOT_PATH', rtrim( ABSPATH, '/e' ) ); | |
} | |
// Define the site media directory here, if not already defined in config. | |
if ( ! defined( 'SITE_MEDIA_DIR' ) ) | |
{ | |
// replaces the hard coded "uploads". | |
define( 'SITE_MEDIA_DIR', '/media' ); | |
} | |
// replace ABSPATH with $site_root_path in this function. | |
// The media url is reference to the "root" directory | |
$siteurl = get_option( 'siteurl' ); | |
$siteurl = rtrim( $siteurl, '/e' ); | |
$upload_path = trim( get_option( 'upload_path' ) ); | |
if ( empty( $upload_path ) || 'wp-content/uploads' == $upload_path ) { | |
$dir = WP_CONTENT_DIR . SITE_MEDIA_DIR; | |
} elseif ( 0 !== strpos( $upload_path, SITE_ROOT_PATH ) ) { | |
// $dir is absolute, $upload_path is (maybe) relative to ABSPATH | |
$dir = path_join( SITE_ROOT_PATH, $upload_path ); | |
} else { | |
$dir = $upload_path; | |
} | |
if ( ! $url = get_option( 'upload_url_path' ) ) { | |
if ( empty( $upload_path ) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) ) { | |
$url = WP_CONTENT_URL . SITE_MEDIA_DIR; | |
} else { | |
$url = trailingslashit( $siteurl ) . $upload_path; | |
} | |
} | |
/* | |
* Honor the value of UPLOADS. This happens as long as ms-files rewriting is disabled. | |
* We also sometimes obey UPLOADS when rewriting is enabled -- see the next block. | |
*/ | |
if ( defined( 'UPLOADS' ) && ! ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) ) { | |
$dir = SITE_ROOT_PATH . UPLOADS; | |
$url = trailingslashit( $siteurl ) . UPLOADS; | |
} | |
// If multisite (and if not the main site in a post-MU network) | |
if ( is_multisite() && ! ( is_main_network() && is_main_site() && defined( 'MULTISITE' ) ) ) { | |
if ( ! get_site_option( 'ms_files_rewriting' ) ) { | |
/* | |
* If ms-files rewriting is disabled (networks created post-3.5), it is fairly | |
* straightforward: Append sites/%d if we're not on the main site (for post-MU | |
* networks). (The extra directory prevents a four-digit ID from conflicting with | |
* a year-based directory for the main site. But if a MU-era network has disabled | |
* ms-files rewriting manually, they don't need the extra directory, as they never | |
* had wp-content/uploads for the main site.) | |
*/ | |
if ( defined( 'MULTISITE' ) ) { | |
$ms_dir = '/sites/' . get_current_blog_id(); | |
} else { | |
$ms_dir = '/' . get_current_blog_id(); | |
} | |
$dir .= $ms_dir; | |
$url .= $ms_dir; | |
} elseif ( defined( 'UPLOADS' ) && ! ms_is_switched() ) { | |
/* | |
* Handle the old-form ms-files.php rewriting if the network still has that enabled. | |
* When ms-files rewriting is enabled, then we only listen to UPLOADS when: | |
* 1) We are not on the main site in a post-MU network, as wp-content/uploads is used | |
* there, and | |
* 2) We are not switched, as ms_upload_constants() hardcodes these constants to reflect | |
* the original blog ID. | |
* | |
* Rather than UPLOADS, we actually use BLOGUPLOADDIR if it is set, as it is absolute. | |
* (And it will be set, see ms_upload_constants().) Otherwise, UPLOADS can be used, as | |
* as it is relative to ABSPATH. For the final piece: when UPLOADS is used with ms-files | |
* rewriting in multisite, the resulting URL is /files. (#WP22702 for background.) | |
*/ | |
if ( defined( 'BLOGUPLOADDIR' ) ) { | |
$dir = untrailingslashit( BLOGUPLOADDIR ); | |
} else { | |
$dir = $site_root_path . UPLOADS; | |
} | |
$url = trailingslashit( $siteurl ) . 'files'; | |
} | |
} | |
$basedir = $dir; | |
$baseurl = $url; | |
$subdir = ''; | |
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; | |
$url = str_replace( '//b/', '/b/', $url ); | |
$baseurl = str_replace( '//b/', '/b/', $baseurl ); | |
$arr = array( | |
'path' => $dir, | |
'url' => $url, | |
'subdir' => $subdir, | |
'basedir' => $basedir, | |
'baseurl' => $baseurl, | |
'error' => false, | |
); | |
return $arr; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Get an array containing the current upload directory's path and url. | |
* | |
* Checks the 'upload_path' option, which should be from the web root folder, | |
* and if it isn't empty it will be used. If it is empty, then the path will be | |
* 'WP_CONTENT_DIR/uploads'. If the 'UPLOADS' constant is defined, then it will | |
* override the 'upload_path' option and 'WP_CONTENT_DIR/uploads' path. | |
* | |
* The upload URL path is set either by the 'upload_url_path' option or by using | |
* the 'WP_CONTENT_URL' constant and appending '/uploads' to the path. | |
* | |
* If the 'uploads_use_yearmonth_folders' is set to true (checkbox if checked in | |
* the administration settings panel), then the time will be used. The format | |
* will be year first and then month. | |
* | |
* If the path couldn't be created, then an error will be returned with the key | |
* 'error' containing the error message. The error suggests that the parent | |
* directory is not writable by the server. | |
* | |
* On success, the returned array will have many indices: | |
* 'path' - base directory and sub directory or full path to upload directory. | |
* 'url' - base url and sub directory or absolute URL to upload directory. | |
* 'subdir' - sub directory if uploads use year/month folders option is on. | |
* 'basedir' - path without subdir. | |
* 'baseurl' - URL path without subdir. | |
* 'error' - false or error message. | |
* | |
* @since 2.0.0 | |
* @uses _wp_upload_dir() | |
* | |
* @staticvar array $cache | |
* @staticvar array $tested_paths | |
* | |
* @param string $time Optional. Time formatted in 'yyyy/mm'. Default null. | |
* @param bool $create_dir Optional. Whether to check and create the uploads directory. | |
* Default true for backward compatibility. | |
* @param bool $refresh_cache Optional. Whether to refresh the cache. Default false. | |
* @return array See above for description. | |
*/ | |
function wp_upload_dir( $time = null, $create_dir = true, $refresh_cache = false ) { | |
// Define the path to the root of the site (Note the WordPress core files). | |
if ( ! defined( 'SITE_ROOT_PATH' ) ) | |
{ | |
define( 'SITE_ROOT_PATH', rtrim( ABSPATH, '/e' ) ); | |
} | |
// Define the site media directory, if not already defined in the config file. | |
if ( ! defined( 'SITE_MEDIA_DIR' ) ) | |
{ | |
// replace the hard coded "uploads" with the more neutral word, "media". | |
define( 'SITE_MEDIA_DIR', '/media' ); | |
} | |
static $cache = array(), $tested_paths = array(); | |
$key = sprintf( '%d-%s', get_current_blog_id(), (string) $time ); | |
if ( $refresh_cache || empty( $cache[ $key ] ) ) { | |
$cache[ $key ] = _wp_upload_dir( $time ); | |
} | |
/** | |
* Filters the uploads directory data. | |
* | |
* @since 2.0.0 | |
* | |
* @param array $uploads Array of upload directory data with keys of 'path', | |
* 'url', 'subdir, 'basedir', and 'error'. | |
*/ | |
$uploads = apply_filters( 'upload_dir', $cache[ $key ] ); | |
if ( $create_dir ) { | |
$path = $uploads['path']; | |
if ( array_key_exists( $path, $tested_paths ) ) { | |
$uploads['error'] = $tested_paths[ $path ]; | |
} else { | |
if ( ! wp_mkdir_p( $path ) ) { | |
if ( 0 === strpos( $uploads['basedir'], SITE_ROOT_PATH ) ) { | |
$error_path = str_replace( SITE_ROOT_PATH, '', $uploads['basedir'] ) . $uploads['subdir']; | |
} else { | |
$error_path = basename( $uploads['basedir'] ) . $uploads['subdir']; | |
} | |
$uploads['error'] = sprintf( | |
/* translators: %s: directory path */ | |
__( 'Unable to create directory %s. Is its parent directory writable by the server?' ), | |
esc_html( $error_path ) | |
); | |
} | |
$tested_paths[ $path ] = $uploads['error']; | |
} | |
} | |
return $uploads; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Get an array containing the current upload directory's path and url. | |
* | |
* Checks the 'upload_path' option, which should be from the web root folder, | |
* and if it isn't empty it will be used. If it is empty, then the path will be | |
* 'WP_CONTENT_DIR/uploads'. If the 'UPLOADS' constant is defined, then it will | |
* override the 'upload_path' option and 'WP_CONTENT_DIR/uploads' path. | |
* | |
* The upload URL path is set either by the 'upload_url_path' option or by using | |
* the 'WP_CONTENT_URL' constant and appending '/uploads' to the path. | |
* | |
* If the 'uploads_use_yearmonth_folders' is set to true (checkbox if checked in | |
* the administration settings panel), then the time will be used. The format | |
* will be year first and then month. | |
* | |
* If the path couldn't be created, then an error will be returned with the key | |
* 'error' containing the error message. The error suggests that the parent | |
* directory is not writable by the server. | |
* | |
* On success, the returned array will have many indices: | |
* 'path' - base directory and sub directory or full path to upload directory. | |
* 'url' - base url and sub directory or absolute URL to upload directory. | |
* 'subdir' - sub directory if uploads use year/month folders option is on. | |
* 'basedir' - path without subdir. | |
* 'baseurl' - URL path without subdir. | |
* 'error' - false or error message. | |
* | |
* @since 2.0.0 | |
* @uses _wp_upload_dir() | |
* | |
* @staticvar array $cache | |
* @staticvar array $tested_paths | |
* | |
* @param string $time Optional. Time formatted in 'yyyy/mm'. Default null. | |
* @param bool $create_dir Optional. Whether to check and create the uploads directory. | |
* Default true for backward compatibility. | |
* @param bool $refresh_cache Optional. Whether to refresh the cache. Default false. | |
* @return array See above for description. | |
*/ | |
function wp_upload_dir( $time = null, $create_dir = true, $refresh_cache = false ) { | |
static $cache = array(), $tested_paths = array(); | |
$key = sprintf( '%d-%s', get_current_blog_id(), (string) $time ); | |
if ( $refresh_cache || empty( $cache[ $key ] ) ) { | |
$cache[ $key ] = _wp_upload_dir( $time ); | |
} | |
/** | |
* Filters the uploads directory data. | |
* | |
* @since 2.0.0 | |
* | |
* @param array $uploads Array of upload directory data with keys of 'path', | |
* 'url', 'subdir, 'basedir', and 'error'. | |
*/ | |
$uploads = apply_filters( 'upload_dir', $cache[ $key ] ); | |
if ( $create_dir ) { | |
$path = $uploads['path']; | |
if ( array_key_exists( $path, $tested_paths ) ) { | |
$uploads['error'] = $tested_paths[ $path ]; | |
} else { | |
if ( ! wp_mkdir_p( $path ) ) { | |
if ( 0 === strpos( $uploads['basedir'], ABSPATH ) ) { | |
$error_path = str_replace( ABSPATH, '', $uploads['basedir'] ) . $uploads['subdir']; | |
} else { | |
$error_path = basename( $uploads['basedir'] ) . $uploads['subdir']; | |
} | |
$uploads['error'] = sprintf( | |
/* translators: %s: directory path */ | |
__( 'Unable to create directory %s. Is its parent directory writable by the server?' ), | |
esc_html( $error_path ) | |
); | |
} | |
$tested_paths[ $path ] = $uploads['error']; | |
} | |
} | |
return $uploads; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment