<?php
/**
Plugin Name: Bug test case.
Plugin URI: http://kccricket.net/
Description: Demonstrates a bug.
Version: 1.0
Author: Keith "kccricket" Constable
Author URI: http://kccricket.net/
*/

function inject_panel() {
global $user_ID, $wpdb;

$testarray = array("This is one", "This is 'two'", "This is \"Three'");
$testkey = 'kccricket_bugtest_20060220';

?>

<div class="wrap">

<p>Dataset that contains some quotes:<br/>
<pre><?php var_dump($testarray) ?></pre></p>

<hr/>

<p>Add that array to the current user's metadata:<br/>
<pre>update_usermeta($user_ID, $testkey, $testarray)</pre></p>

<?php update_usermeta($user_ID, $testkey, $testarray); ?>

<p>That should have just triggered a DB error.</p>

<hr/>

<p>Okay, that's fine.  I can just escape the data before it's used:<br/>
<pre><?php $testarray = array("This is one", "This is \'two\'", "This is \\\"Three\'");
var_dump($testarray); ?></pre></p>

<hr/>

<p>Add the new array to the current user's metadata:<br/>
<pre>update_usermeta($user_ID, $testkey, $testarray)

<?php var_dump( update_usermeta($user_ID, $testkey, $testarray) ); ?></pre></p>

<hr/>

<p>Attempt to retrieve the array from the usermeta:<br/>
<pre>get_usermeta($user_ID, $testkey)

<?php var_dump( get_usermeta($user_ID, $testkey) ); ?></pre></p>

<p>What the heck?  A string?  I gave it an array!  That's a problem.</p>

<hr/>

<p>Delete the testkey:<br/>
<pre><?php var_dump( $wpdb->query("DELETE FROM $wpdb->usermeta WHERE user_id = '$user_ID' AND meta_key = '$testkey'") ) ?></pre></p>

</div>

<?php
}

function add_inject_panel() {
	add_submenu_page('plugins.php', 'Bug Test', 'Bug Test', 1, 'bug-test', 'inject_panel');
}
add_action('admin_menu', 'add_inject_panel');


function kccricket_update_usermeta( $user_id, $meta_key, $meta_value ) {
	global $wpdb;
	if ( !is_numeric( $user_id ) )
		return false;
	$meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);

	if ( is_array($meta_value) || is_object($meta_value) )
		$meta_value = serialize($meta_value);
	$meta_value = trim( $meta_value );

	if (empty($meta_value)) {
		delete_usermeta($user_id, $meta_key);
	}

	// This is the only change:
	$meta_value = $wpdb->escape($meta_value);

	$cur = $wpdb->get_row("SELECT * FROM $wpdb->usermeta WHERE user_id = '$user_id' AND meta_key = '$meta_key'");
	if ( !$cur ) {
		$wpdb->query("INSERT INTO $wpdb->usermeta ( user_id, meta_key, meta_value )
		VALUES
		( '$user_id', '$meta_key', '$meta_value' )");
	} else if ( $cur->meta_value != $meta_value ) {
		$wpdb->query("UPDATE $wpdb->usermeta SET meta_value = '$meta_value' WHERE user_id = '$user_id' AND meta_key = '$meta_key'");
	} else {
		return false;
	}

	$user = get_userdata($user_id);
	wp_cache_delete($user_id, 'users');
	wp_cache_delete($user->user_login, 'userlogins');

	return true;
}


/** PART TWO **/


function inject_panel2() {
global $wpdb;

$testarray = array("This is one", "This is 'two'", "This is \"Three'");
$testkey = 'kccricket_bugtest2_20060220';

?>

<div class="wrap">

<p>Dataset that contains some quotes:<br/>
<pre><?php var_dump($testarray); ?></pre></p>

<hr/>

<p>Add that array to the options:<br/>
<pre>update_option($testkey, $testarray)

<?php var_dump( update_option($testkey, $testarray) ); ?></pre></p>

<hr/>

<p>Delete the dataset from the cache:<br/>
<pre>wp_cache_delete($testkey, 'options')

<?php var_dump( wp_cache_delete($testkey, 'options') ); ?></pre>

<hr/>

<p>Attempt to retrieve the array from the options:<br/>
<pre>get_option($testkey)

<?php var_dump( get_option($testkey) ); ?></pre></p>

<p>Works as expected.</p>

<hr/>

<p>Delete the testkey:<br/>
<pre>delete_option($testkey)

<?php var_dump( delete_option($testkey) ) ?></pre></p>
<?php }

function add_inject_panel2() {
	add_submenu_page('plugins.php', 'Bug Test 2', 'Bug Test 2', 1, 'bug-test2', 'inject_panel2');
}
add_action('admin_menu', 'add_inject_panel2');
?>
