first
This commit is contained in:
231
wp-content/plugins/debloat/inc/file-system.php
Normal file
231
wp-content/plugins/debloat/inc/file-system.php
Normal file
@ -0,0 +1,231 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat;
|
||||
|
||||
/**
|
||||
* Filesystem that mainly wraps the WP_File_System
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @mixin \WP_Filesystem_Base
|
||||
*/
|
||||
class FileSystem
|
||||
{
|
||||
/**
|
||||
* Pattern to remove protocol and www
|
||||
*/
|
||||
const PROTO_REMOVE_PATTERN = '#^(https?)?:?//(|www\.)#i';
|
||||
|
||||
/**
|
||||
* @var WP_Filesystem_Base
|
||||
*/
|
||||
public $filesystem;
|
||||
|
||||
protected $valid_hosts;
|
||||
protected $paths_urls;
|
||||
|
||||
/**
|
||||
* Setup file system
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
global $wp_filesystem;
|
||||
|
||||
if (empty($wp_filesystem)) {
|
||||
|
||||
require_once wp_normalize_path(ABSPATH . '/wp-admin/includes/file.php');
|
||||
|
||||
// At shutdown is usually a ob_start callback which doesn't permit calling ob_*
|
||||
if (did_action('shutdown') && ob_get_level() > 0) {
|
||||
$creds = request_filesystem_credentials('');
|
||||
}
|
||||
else {
|
||||
ob_start();
|
||||
$creds = request_filesystem_credentials('');
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
if (!$creds) {
|
||||
$creds = array();
|
||||
}
|
||||
|
||||
$filesystem = WP_Filesystem($creds);
|
||||
|
||||
if (!$filesystem) {
|
||||
|
||||
// Fallback to lax permissions
|
||||
$upload = wp_upload_dir();
|
||||
WP_Filesystem(false, $upload['basedir'], true);
|
||||
}
|
||||
}
|
||||
|
||||
$this->filesystem = $wp_filesystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively make parent directories for a path.
|
||||
*
|
||||
* Note: Adapted a bit from wp_mkdir_p().
|
||||
*
|
||||
* @param string $path
|
||||
* @return boolean true on success, false or failure.
|
||||
*/
|
||||
public function mkdir_p($path)
|
||||
{
|
||||
if ($this->is_dir($path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$path = str_replace('//', '/', $path);
|
||||
|
||||
// Safe mode safety.
|
||||
$path = rtrim($path, '/');
|
||||
$path = $path ?: '/';
|
||||
|
||||
$created = $this->mkdir($path, FS_CHMOD_DIR);
|
||||
if ($created) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If it failed above, try again by creating the parent first, recursively.
|
||||
$parent = dirname($path);
|
||||
if ($parent !== '/' && $this->mkdir_p($parent)) {
|
||||
return $this->mkdir($path, FS_CHMOD_DIR);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a local file by the provided URL, if possible.
|
||||
*
|
||||
* @see wp_normalize_path()
|
||||
*
|
||||
* @return bool|string Either the path or false on failure.
|
||||
*/
|
||||
public function url_to_local($url)
|
||||
{
|
||||
$url = trim($url);
|
||||
|
||||
// Not a URL, just return the path.
|
||||
if (substr($url, 0, 4) !== 'http' && substr($url, 0, 2) !== '//') {
|
||||
return $url;
|
||||
}
|
||||
|
||||
$url = explode('?', trim($url));
|
||||
$url = trim($url[0]);
|
||||
|
||||
// We're not working with encoded URLs.
|
||||
if (strpos($url, '%') !== false) {
|
||||
$url = urldecode($url);
|
||||
}
|
||||
|
||||
// Add https:// for parse_url() or it fails.
|
||||
$url_no_proto = preg_replace(self::PROTO_REMOVE_PATTERN, '', $url);
|
||||
$url_host = parse_url('https://' . $url_no_proto, PHP_URL_HOST);
|
||||
|
||||
// Not a known host / URL.
|
||||
if (!in_array($url_host, $this->get_valid_hosts())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Go through each known path url map and stop at first matched.
|
||||
*/
|
||||
$valid_urls = $this->get_paths_urls();
|
||||
$url_dirname = dirname($url_no_proto);
|
||||
$matched = [];
|
||||
|
||||
foreach ($valid_urls as $path_url) {
|
||||
|
||||
if (strpos($url_dirname, untrailingslashit($path_url['url'])) !== false) {
|
||||
$matched = $path_url;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We have a matched path.
|
||||
if (!empty($matched['path'])) {
|
||||
$path = wp_normalize_path(
|
||||
$matched['path'] . str_replace($matched['url'], '', $url_dirname)
|
||||
);
|
||||
|
||||
$file = trailingslashit($path) . wp_basename($url_no_proto);
|
||||
|
||||
if (file_exists($file) && is_file($file) && is_readable($file)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get recognized hostnames for stylesheet URLs.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_valid_hosts()
|
||||
{
|
||||
if (!$this->valid_hosts) {
|
||||
$this->valid_hosts = wp_list_pluck(
|
||||
$this->get_paths_urls(),
|
||||
'host'
|
||||
);
|
||||
}
|
||||
|
||||
return apply_filters('debloat/file_system/valid_hosts', $this->valid_hosts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map of known path URLs, associated local path, and host.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_paths_urls()
|
||||
{
|
||||
if (!$this->paths_urls) {
|
||||
|
||||
// We add https:// back for parse_url() to prevent it from failing
|
||||
$site_url = preg_replace(self::PROTO_REMOVE_PATTERN, '', site_url());
|
||||
$site_host = parse_url('https://' . $site_url, PHP_URL_HOST);
|
||||
|
||||
$content_url = preg_replace(self::PROTO_REMOVE_PATTERN, '', content_url());
|
||||
$content_host = parse_url('https://' . $content_url, PHP_URL_HOST);
|
||||
|
||||
/**
|
||||
* This array will be processed in order it's defined to find the matching host and URL.
|
||||
*/
|
||||
$hosts = [
|
||||
|
||||
// First priority to use content_host and content_url()
|
||||
'content' => [
|
||||
'url' => $content_url,
|
||||
'path' => WP_CONTENT_DIR,
|
||||
'host' => $content_host
|
||||
],
|
||||
|
||||
// Fallback to using site URL with ABSPATH
|
||||
'site' => [
|
||||
'url' => $site_url,
|
||||
'path' => ABSPATH,
|
||||
'host' => $site_host
|
||||
],
|
||||
];
|
||||
|
||||
$this->paths_urls = apply_filters('debloat/file_system/paths_urls', $hosts);
|
||||
}
|
||||
|
||||
return $this->paths_urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxies to WP_Filesystem_Base
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
return call_user_func_array([$this->filesystem, $name], $arguments);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user