Inserting data from forms -- So simple?

#1

Hello, I am a hobbist who has been struggling for a week on this code. I am making an rpg where users can create multiple characters per account. This code should allow them to do this through the UCP.

Goal: Have users input data from forms which is inserted into the database. Sounds simple?

Problem: My function to insert the form data is inserting blank data/not working.

Overview of database and files:

The form fields are taken from another table in the database, and are numbered and can be added/deleted from the admin panel. Table name mybb_characterfields, columns include cfid (primary key), name, description, type, etc.

The table where data is inserted is called mybb_characters, where the columns are cid (primary), ucid (equal to user’s ID or uid from another table), and then all the cfids from _characterfields. e.g. cfid4, cfid6, etc.

In the userCP I have generated the forms from _characterfields as such:

[php]if($mybb->input[‘action’] == “addcharacter”)
{
$plugins->run_hooks(“usercp_profile_start”);

$altbg = "trow1";
$requiredfields2 = '';
$customfields2 = '';
$query = $db->simple_select("characterfields", "*", "editable=1", array('order_by' => 'disporder'));
while($characterfield = $db->fetch_array($query))
{
	// Does this field have a minimum post count?
	if($characterfield['postnum'] && $characterfield['postnum'] > $user['postnum'])
	{
		continue;
	}

	$characterfield['type'] = htmlspecialchars_uni($characterfield['type']);
	$characterfield['name'] = htmlspecialchars_uni($characterfield['name']);
	$characterfield['description'] = htmlspecialchars_uni($characterfield['description']);
	$thing = explode("\n", $characterfield['type'], "2");
	$type = $thing[0];
	$options = $thing[1];
	$field = "cfid{$characterfield['cfid']}";
	$select = '';
	if($errors)
	{
		$usercharacterfield = $mybb->input['character_fields'][$field];
	}
	else
	{
		$usercharacterfield = $user[$field];
	}
	if($type == "multiselect")
	{
		if($errors)
		{
			$useropts = $usercharacterfield;
		}
		else
		{
			$useropts = explode("\n", $usercharacterfield);
		}
		if(is_array($useropts))
		{
			foreach($useropts as $key => $val)
			{
				$val = htmlspecialchars_uni($val);
				$seloptions[$val] = $val;
			}
		}
		$expoptions = explode("\n", $options);
		if(is_array($expoptions))
		{
			foreach($expoptions as $key => $val)
			{
				$val = trim($val);
				$val = str_replace("\n", "\\n", $val);

				$sel = "";
				if($val == $seloptions[$val])
				{
					$sel = " selected=\"selected\"";
				}
				$select .= "<option value=\"$val\"$sel>$val</option>\n";
			}
			if(!$characterfield['length'])
			{
				$characterfield['length'] = 3;
			}
			$code = "<select name=\"character_fields[$field][]\" size=\"{$characterfield['length']}\" multiple=\"multiple\">$select</select>";
		}
	}
	elseif($type == "select")
	{
		$expoptions = explode("\n", $options);
		if(is_array($expoptions))
		{
			foreach($expoptions as $key => $val)
			{
				$val = trim($val);
				$val = str_replace("\n", "\\n", $val);
				$sel = "";
				if($val == htmlspecialchars_uni($usercharacterfield))
				{
					$sel = " selected=\"selected\"";
				}
				$select .= "<option value=\"$val\"$sel>$val</option>";
			}
			if(!$characterfield['length'])
			{
				$characterfield['length'] = 1;
			}
			$code = "<select name=\"character_fields[$field]\" size=\"{$characterfield['length']}\">$select</select>";
		}
	}
	elseif($type == "radio")
	{
		$expoptions = explode("\n", $options);
		if(is_array($expoptions))
		{
			foreach($expoptions as $key => $val)
			{
				$checked = "";
				if($val == $usercharacterfield)
				{
					$checked = " checked=\"checked\"";
				}
				$code .= "<input type=\"radio\" class=\"radio\" name=\"character_fields[$field]\" value=\"$val\"$checked /> <span class=\"smalltext\">$val</span><br />";
			}
		}
	}
	elseif($type == "checkbox")
	{
		if($errors)
		{
			$useropts = $usercharacterfield;
		}
		else
		{
			$useropts = explode("\n", $usercharacterfield);
		}
		if(is_array($useropts))
		{
			foreach($useropts as $key => $val)
			{
				$seloptions[$val] = $val;
			}
		}
		$expoptions = explode("\n", $options);
		if(is_array($expoptions))
		{
			foreach($expoptions as $key => $val)
			{
				$checked = "";
				if($val == $seloptions[$val])
				{
					$checked = " checked=\"checked\"";
				}
				$code .= "<input type=\"checkbox\" class=\"checkbox\" name=\"character_fields[$field][]\" value=\"$val\"$checked /> <span class=\"smalltext\">$val</span><br />";
			}
		}
	}
	elseif($type == "textarea")
	{
		$value = htmlspecialchars_uni($usercharacterfield);
		$code = "<textarea name=\"character_fields[$field]\" rows=\"6\" cols=\"30\" style=\"width: 95%\">$value</textarea>";
	}
	else
	{
		$value = htmlspecialchars_uni($usercharacterfield);
		$maxlength = "";
		if($characterfield['maxlength'] > 0)
		{
			$maxlength = " maxlength=\"{$characterfield['maxlength']}\"";
		}
		$code = "<input type=\"text\" name=\"character_fields[$field]\" class=\"textbox\" size=\"{$characterfield['length']}\"{$maxlength} value=\"$value\" />";
	}
	if($characterfield['required'] == 1)
	{
		eval("\$requiredfields2 .= \"".$templates->get("usercp_character_customfield")."\";");
	}
	else
	{
		eval("\$customfields2 .= \"".$templates->get("usercp_character_customfield")."\";");
	}
	$altbg = alt_trow();
	$code = "";
	$select = "";
	$val = "";
	$options = "";
	$expoptions = "";
	$useropts = "";
	$seloptions = "";
}
if($customfields2)
{
	eval("\$customfields2 = \"".$templates->get("usercp_character_profilefields")."\";");
}

$plugins->run_hooks("usercp_profile_end");

eval("\$editprofile = \"".$templates->get("usercp_addcharacter")."\";");
output_page($editprofile);

}[/php]

When they fill out the form and click the button is does this:

[php]if($mybb->input[‘action’] == “do_addcharacter” && $mybb->request_method == “post”)
{
// Verify incoming POST request
verify_post_check($mybb->input[‘my_post_key’]);

$plugins->run_hooks("usercp_do_profile_start");

// Set up user handler.
require_once "inc/datahandlers/user.php";
$userhandler = new UserDataHandler("update");

$user = array(
	"character_fields" => $mybb->input['character_fields']
);

$userhandler->set_data($user);

if(!$userhandler->validate_user())
{
	$errors = $userhandler->get_friendly_errors();
	$errors = inline_error($errors);
	$mybb->input['action'] = "addcharacter";
}
else
{
	$userhandler->insert_character();

	$plugins->run_hooks("usercp_do_profile_end");
	redirect("usercp.php", $lang->redirect_characteradded);
}

}[/php]

Now we go over to user.php for my broken function…

[php]function insert_character()
{
global $db, $cache, $plugins;

	// Yes, validating is required.
	if(!$this->get_validated())
	{
		die("The user needs to be validated before inserting it into the DB.");
	}
	if(count($this->get_errors()) > 0)
	{
		die("The user is not valid.");
	}		
	
	$user['usercharacter_fields']['ucid'] = $this->uid;
	
	$query = $db->simple_select("characterfields", "cfid");
	while($character_field = $db->fetch_array($query))
	{
		if(array_key_exists("cfid{$character_field['cfid']}", $user['usercharacter_fields']))
		{
			continue;
		}
		$user['usercharacter_fields']["cfid{$character_field['cfid']}"] = '';
	}

	$db->insert_query("characters", $user['usercharacter_fields'], false);

}[/php]

This inserts a blank into _characters, with a new cid, but all other fields are blank. I can’t seem to figure out which character_field, usercharacter_fields, etc. go where, and I think that is what is messing me up.

Any help offered is greatly appreciated! Thank you for your time!

#2

I believe this line is not doing what you want it to do (or expect it to do):

[php]if(array_key_exists(“cfid{$character_field[‘cfid’]}”, $user[‘usercharacter_fields’]))[/php]

This checks if there is a key going by the name “cfid”.$character_field[‘cfid’] in $user[‘usercharacter_fields’]. You’ve told us that your characterfields table includes the keys: cfid, name, description,t ype, etc… However, no cfidcfid, no cfidname, no cfiddescription etc. As such, the if is not matched and $user[‘usercharacter_fields’][“cfid{$character_field[‘cfid’]}”] is therefore set to null.

To provide a worthwhile alternative, I’ll need to see the content of the two variables, though.

#3

I think I am following you, though I am not sure what the content OF the two variables are. I have no idea where $usercharacter_fields goes, but isn’t $user defined somewhere in my code? Would they be hidden somewhere in the user.php file you think?

#4

var_dump() allows you to see the content of any variable you like. This is your go-to debugging tool. Can you run both arrays through it and paste the output?

#5

I’ve never used a debugger properly because I can’t get PHP installed on my computer to save my life. I’ve just been making modifications online via FTP (super inefficient, I know).

I’m not sure where to put it…

#6

m’kay, $user is array(1) { [“character_fields”]=> array(2) { [“cfid4”]=> string(0) “” [“cfid6”]=> string(0) “” } }

$character_field is NULL.

I used usercp.php, so I’m not sure it’s applicable when the function lives in user.php?

#7

Straight before the code you want to debug. In your case:

[php]var_dump($user);
var_dump($character_field);[/php]

Watch the output - it throws straight as an echo would.

#8

So it’s these two lines that are failing:

[php] $query = $db->simple_select(“characterfields”, “cfid”);
while($character_field = $db->fetch_array($query))[/php]

You’ll need to look up the doc on whatever framework you are using to figure out what simple_select() takes as parameters. This is the key problem, by the looks of it - $character_field ends up null. Can’t be more specific, though. And if fetch_array returns null rather than false, the loop will run.

#9

Okay, I shall investigate… Thank you!

#10

Keep me posted - always good to know where a bug was. One never stops learning :slight_smile: