<?php
/*
Plugin Name: Filesystem Debug Logger
Plugin URI: http://dd32.id.au/wordpress-plugins/?fs-debug-log
Description: This plugin hooks the filesystem abstraction to allow for logging of all calls. <strong>Requires PHP5.1+</strong>. The debug log is stored in wp-content/uploads/debug.txt and assumes that folder is writable.
Version: 1.0
Author: Dion Hulse
Author URI: http://dd32.id.au/
*/

add_filter('filesystem_method', 'fs_debug_log_filter');
function fs_debug_log_filter() {
	return 'Debug_Log';
}
add_filter('filesystem_method_file', 'fs_debug_log_file');
function fs_debug_log_file() {
	return __FILE__;
}

add_filter('request_filesystem_credentials', 'fs_debug_log_form', 10, 4);
function fs_debug_log_form($type, $form_post, $type, $error) {
	remove_filter('filesystem_method', 'fs_debug_log_filter');
	$method = get_filesystem_method( get_option('ftp_credentials') );
	add_filter('filesystem_method', 'fs_debug_log_filter');
	$GLOBALS['debug-log'] = $method;
	if ( 'direct' == $method )
		return ' ';
	else
		return request_filesystem_credentials($form_post, $method, $error) . ' ';
}

class WP_Filesystem_Debug_Log {
	var $a;
	var $handle;
	function __construct($args) {
		
		remove_filter('filesystem_method', 'fs_debug_log_filter');
		$method = isset($GLOBALS['debug-log']) ? $GLOBALS['debug-log'] : get_filesystem_method($args);

		if ( ! class_exists("WP_Filesystem_$method") )
			include_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-' . $method . '.php';

		$method = "WP_Filesystem_$method";
		$this->a = new $method($args);
		
		$this->handle = fopen(ABSPATH . 'wp-content/uploads/debug.txt', 'w+');
		
		if ( isset($GLOBALS['upgrader']) )
			fwrite($this->handle, "==================\r\n" . htmlentities(print_r($GLOBALS['upgrader'], true)) . "\r\n\r\n");
	}
	function __call($name, $args) {
		fwrite($this->handle, 'Calling ' . $name . '(' . implode(', ', $args) . ') = ');
		$res = call_user_func_array( array(&$this->a, $name), $args);
		if ( is_bool($res) )
			$hres = '(bool)' . ($res ? '1' : '0');
		else
			$hres = $res;
		fwrite($this->handle, htmlentities(print_r($hres, true)) . "\r\n\r\n");
		return $res;
	}
	function __get($name) {
		return $this->a->$name;
	}
	function __set($name, $value) {
		return ($this->a->$name = $value);
	}
}