directory pairs, most specific first. * * Uploads before wp-content (uploads may live elsewhere), wp-content * before the site root (wp-content may be relocated), the site root last. * * @since 1.21.16 * @return array */ private static function roots(): array { $pairs = array(); $uploads = wp_upload_dir( null, false ); if ( is_array( $uploads ) && empty( $uploads['error'] ) && ! empty( $uploads['baseurl'] ) && ! empty( $uploads['basedir'] ) ) { $pairs[] = array( self::url_path( (string) $uploads['baseurl'] ), self::dir( (string) $uploads['basedir'] ) ); } $pairs[] = array( self::url_path( content_url() ), self::dir( WP_CONTENT_DIR ) ); $site_prefix = self::url_path( site_url() ); $home_prefix = self::url_path( home_url() ); $pairs[] = array( $site_prefix, self::dir( ABSPATH ) ); if ( $home_prefix !== $site_prefix ) { // WordPress in a subdirectory, site at the root (or the reverse): // a root-relative URL may carry either prefix. $pairs[] = array( $home_prefix, self::dir( ABSPATH ) ); } // Longest prefix first, so /wp-content/uploads wins over /wp-content // and both win over the site root. usort( $pairs, static function ( $a, $b ) { return strlen( $b[0] ) <=> strlen( $a[0] ); } ); return $pairs; } /** * The path component of a URL root, without a trailing slash ('' for * the host root). * * @since 1.21.16 * * @param string $url A root URL such as content_url(). * @return string */ private static function url_path( string $url ): string { $path = wp_parse_url( $url, PHP_URL_PATH ); return is_string( $path ) ? rtrim( $path, '/' ) : ''; } /** * A directory root with forward slashes and no trailing slash. * * @since 1.21.16 * * @param string $dir Directory. * @return string */ private static function dir( string $dir ): string { return rtrim( wp_normalize_path( $dir ), '/' ); } /** * Whether a URL host is this site's. * * @since 1.21.16 * * @param string $host Host from the URL. * @return bool */ private static function same_host( string $host ): bool { $host = strtolower( $host ); foreach ( array( home_url(), site_url(), content_url() ) as $root ) { $site_host = wp_parse_url( $root, PHP_URL_HOST ); if ( is_string( $site_host ) && strtolower( $site_host ) === $host ) { return true; } } return false; } /** * Whether a real path sits inside a root the site serves from. * * @since 1.21.16 * * @param string $real Normalised real path. * @return bool */ private static function is_contained( string $real ): bool { $roots = array( ABSPATH, WP_CONTENT_DIR ); $uploads = wp_upload_dir( null, false ); if ( is_array( $uploads ) && ! empty( $uploads['basedir'] ) ) { $roots[] = (string) $uploads['basedir']; } foreach ( $roots as $root ) { $root_real = realpath( $root ); if ( false === $root_real ) { continue; } $root_real = rtrim( wp_normalize_path( $root_real ), '/' ) . '/'; if ( 0 === strpos( $real, $root_real ) ) { return true; } } return false; } }