WordPress Version: 6.2
/**
* Determines which method to use for reading, writing, modifying, or deleting
* files on the filesystem.
*
* The priority of the transports are: Direct, SSH2, FTP PHP Extension, FTP Sockets
* (Via Sockets class, or `fsockopen()`). Valid values for these are: 'direct', 'ssh2',
* 'ftpext' or 'ftpsockets'.
*
* The return value can be overridden by defining the `FS_METHOD` constant in `wp-config.php`,
* or filtering via {@see 'filesystem_method'}.
*
* @link https://wordpress.org/documentation/article/editing-wp-config-php/#wordpress-upgrade-constants
*
* Plugins may define a custom transport handler, See WP_Filesystem().
*
* @since 2.5.0
*
* @global callable $_wp_filesystem_direct_method
*
* @param array $args Optional. Connection details. Default empty array.
* @param string $context Optional. Full path to the directory that is tested
* for being writable. Default empty.
* @param bool $allow_relaxed_file_ownership Optional. Whether to allow Group/World writable.
* Default false.
* @return string The transport to use, see description for valid return values.
*/
function get_filesystem_method($args = array(), $context = '', $allow_relaxed_file_ownership = false)
{
// Please ensure that this is either 'direct', 'ssh2', 'ftpext', or 'ftpsockets'.
$method = defined('FS_METHOD') ? FS_METHOD : false;
if (!$context) {
$context = WP_CONTENT_DIR;
}
// If the directory doesn't exist (wp-content/languages) then use the parent directory as we'll create it.
if (WP_LANG_DIR === $context && !is_dir($context)) {
$context = dirname($context);
}
$context = trailingslashit($context);
if (!$method) {
$temp_file_name = $context . 'temp-write-test-' . str_replace('.', '-', uniqid('', true));
$temp_handle = @fopen($temp_file_name, 'w');
if ($temp_handle) {
// Attempt to determine the file owner of the WordPress files, and that of newly created files.
$wp_file_owner = false;
$temp_file_owner = false;
if (function_exists('fileowner')) {
$wp_file_owner = @fileowner(__FILE__);
$temp_file_owner = @fileowner($temp_file_name);
}
if (false !== $wp_file_owner && $wp_file_owner === $temp_file_owner) {
/*
* WordPress is creating files as the same owner as the WordPress files,
* this means it's safe to modify & create new files via PHP.
*/
$method = 'direct';
$GLOBALS['_wp_filesystem_direct_method'] = 'file_owner';
} elseif ($allow_relaxed_file_ownership) {
/*
* The $context directory is writable, and $allow_relaxed_file_ownership is set,
* this means we can modify files safely in this directory.
* This mode doesn't create new files, only alter existing ones.
*/
$method = 'direct';
$GLOBALS['_wp_filesystem_direct_method'] = 'relaxed_ownership';
}
fclose($temp_handle);
@unlink($temp_file_name);
}
}
if (!$method && isset($args['connection_type']) && 'ssh' === $args['connection_type'] && extension_loaded('ssh2')) {
$method = 'ssh2';
}
if (!$method && extension_loaded('ftp')) {
$method = 'ftpext';
}
if (!$method && (extension_loaded('sockets') || function_exists('fsockopen'))) {
$method = 'ftpsockets';
// Sockets: Socket extension; PHP Mode: FSockopen / fwrite / fread.
}
/**
* Filters the filesystem method to use.
*
* @since 2.6.0
*
* @param string $method Filesystem method to return.
* @param array $args An array of connection details for the method.
* @param string $context Full path to the directory that is tested for being writable.
* @param bool $allow_relaxed_file_ownership Whether to allow Group/World writable.
*/
return apply_filters('filesystem_method', $method, $args, $context, $allow_relaxed_file_ownership);
}