query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'xspeed_scores' ); delete_option( 'xspeed_score_schema' ); delete_option( 'xspeed_score_history' ); if ( ! function_exists( 'WP_Filesystem' ) ) { require_once ABSPATH . 'wp-admin/includes/file.php'; } WP_Filesystem(); global $wp_filesystem; if ( ! $wp_filesystem ) { return; } $cache_dir = WP_CONTENT_DIR . '/cache/xspeed'; if ( $wp_filesystem->is_dir( $cache_dir ) ) { $wp_filesystem->delete( $cache_dir, true ); } // nginx hit log (FBS-82478). It lives under uploads/xspeed/, NOT the // cache dir, precisely so that a pasted nginx `access_log` directive // pointing at it does NOT get its parent directory deleted here — if it // did, `nginx -t` would fail [emerg] and refuse to (re)start, taking // down EVERY vhost on the host until someone manually finds the orphaned // directive. We therefore EMPTY the log file but DELIBERATELY LEAVE THE // DIRECTORY in place, so any still-pasted directive keeps a valid, // openable target after the plugin is gone. (A stray empty dir is // harmless; a broken nginx is not.) Users are also warned in the admin // UI to remove the snippet before uninstalling. $hits_log = WP_CONTENT_DIR . '/uploads/xspeed/hits.log'; if ( function_exists( 'wp_upload_dir' ) ) { $uploads = wp_upload_dir( null, false ); if ( is_array( $uploads ) && empty( $uploads['error'] ) && ! empty( $uploads['basedir'] ) ) { $hits_log = rtrim( (string) $uploads['basedir'], '/' ) . '/xspeed/hits.log'; } } if ( $wp_filesystem->exists( $hits_log ) ) { // Truncate, don't delete the dir — keep the access_log target openable. $wp_filesystem->put_contents( $hits_log, '', FS_CHMOD_FILE ); } // Static-cache tree — separate from the flat-hash cache dir, holds // the {host}/{path}/index.html files the .htaccess rewrite block // serves directly. Same teardown rules as XSPEED_CACHE_DIR. $static_dir = WP_CONTENT_DIR . '/cache/xspeed-static'; if ( $wp_filesystem->is_dir( $static_dir ) ) { $wp_filesystem->delete( $static_dir, true ); } // Rewrite block in site-root .htaccess. WP's marker helpers handle // the "remove only our block" semantics — passing an empty array // strips the markers in place. $htaccess = ABSPATH . '.htaccess'; if ( $wp_filesystem->exists( $htaccess ) && $wp_filesystem->is_writable( $htaccess ) ) { if ( ! function_exists( 'insert_with_markers' ) ) { require_once ABSPATH . 'wp-admin/includes/misc.php'; } insert_with_markers( $htaccess, 'xSpeed Static Cache', array() ); } $drop_in = WP_CONTENT_DIR . '/advanced-cache.php'; if ( $wp_filesystem->exists( $drop_in ) ) { $contents = $wp_filesystem->get_contents( $drop_in ); if ( is_string( $contents ) && false !== strpos( $contents, 'XSPEED_DROPIN' ) ) { $wp_filesystem->delete( $drop_in ); } } $wp_config = ABSPATH . 'wp-config.php'; if ( defined( 'WP_CACHE' ) && WP_CACHE && $wp_filesystem->is_writable( $wp_config ) ) { $config = $wp_filesystem->get_contents( $wp_config ); if ( is_string( $config ) ) { $config = preg_replace( "/define\\(\\s*['\"]WP_CACHE['\"]\\s*,\\s*true\\s*\\);\\s*\\n?/", '', $config ); $wp_filesystem->put_contents( $wp_config, $config, FS_CHMOD_FILE ); } } }