Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use of WP_Filesystem #23

Open
KBurkholder opened this issue Oct 26, 2023 · 0 comments
Open

Use of WP_Filesystem #23

KBurkholder opened this issue Oct 26, 2023 · 0 comments

Comments

@KBurkholder
Copy link

KBurkholder commented Oct 26, 2023

I'm using a WordPress theme that incorporates this library. Nice work, but there are some inherent issues with it that cause a hard crash.

Here's the code causing issues:

protected function get_filesystem() {
	global $wp_filesystem;

	// If the filesystem has not been instantiated yet, do it here.
	if ( ! $wp_filesystem ) {
		if ( ! function_exists( 'WP_Filesystem' ) ) {
			require_once wp_normalize_path( ABSPATH . '/wp-admin/includes/file.php' );
		}
		WP_Filesystem();
	}
	return $wp_filesystem;
}

WP_Filesystem is not intended to be used on the front-end - and shouldn't be. But I managed some hacks to get it working, at least in my environment...

First, the global $wp_filesystem may be set but not valid. So this:

if ( ! $wp_filesystem ) {

Should be:

if ( ! $wp_filesystem
or ( is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->has_errors() )
) {

Second, calling WP_Filesystem() with no arguments will fail on any system that actually needs to use WP_Filesystem - those that require FTP/SSH to access files.

What should be passed to WP_Filesystem() is an array of connection parameters. Those parameters should be retrieved by using request_filesystem_credentials() but that has the potential of displaying the "Connection Information" form, which we certainly don't want on the front end.

So, I added this:

if (! WP_Filesystem( get_option('ftp_credentials') ) ) {

which attempts to get the saved credentials - assuming that the administrator has saved credentials previously, and that those credentials are complete (WordPress doesn't save password or keys).

Lastly, since the above doesn't ensure that we actually have a valid $wp_filesystem, we need a fall-back...

if (!class_exists('WP_Filesystem_Direct')) {
	require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
	require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php';
}
$wp_filesystem = new WP_Filesystem_Direct([]);

This at least gives us 'direct' access, which may fail on some systems.

So here's my version of the get_filesystem method. It's far from perfect, and won't work correctly in some cases, but it works in my environment. I do recommend that the administrator set all appropriate FS_* constants in wp-config.php.

protected function get_filesystem() {
	global $wp_filesystem;

	// If the filesystem has not been instantiated yet, do it here.
	if ( ! $wp_filesystem
	or ( is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->has_errors() )
	) {
		if ( ! function_exists( 'WP_Filesystem' ) ) {
			require_once wp_normalize_path( ABSPATH . '/wp-admin/includes/file.php' );
		}
		if (! WP_Filesystem( get_option('ftp_credentials') ) ) {
			if (!class_exists('WP_Filesystem_Direct')) {
				require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
				require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php';
			}
			$wp_filesystem = new WP_Filesystem_Direct([]);
		}
	}
	return $wp_filesystem;
}

I hope this is helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant