Page 1 of 1

Multidimensional Array Advice

Posted: Thu Apr 27, 2006 2:38 pm
by kayers
Hey all,

I'm working on some code where I'm getting values from a db and comparing them to values I've gotten from a web form. It works correctly, but I don't like the format of my array I'm using because later on, I have to instantiate "custom fields" with the values. The problem is that there are "groups" that may have many "fields", but the "fields" can have one and only one "value". Currently, my array is not grouped that way:

Code: Select all

Array 
( 
	[0] => Array (
	 				[0] => 4 (Edit: Group ID)
	 				[1] => 6 
					[2] => General Facilities 
				 ) 
	[1] => Array (
	 				[0] => 4 (Edit: Group ID)
	 				[1] => 5
	 				[2] => DEC
	 			 ) 
	[2] => Array (
	 				[0] => 5 (Edit: Group ID)
	 				[1] => 7
	 				[2] => test
	 			)
)
I'm trying to figure out a way to either check the next group id and compare it to the current value (through nested for loops) or make an associative array that somehow links the group id and all of its fields and field values.

I'm currently just using a foreach loop to simply loop through all of the values:

Code: Select all

function instantiate_custom_fields($custom_fields)
{
	$field_handler = new cer_CustomFieldGroupHandler();	
	$filename = "test_instantiate.txt";
	$fp = fopen($filename, "a");
		
	foreach($custom_fields as $cf_fields)
	{
		if($cf_fields[0] != "")
		{
			fwrite($fp, "group id: $cf_fields[0]\n");
			fwrite($fp, "field id: $cf_fields[1]\n");
			fwrite($fp, "field value: $cf_fields[2]\n");
					
			//$instance_id = $field_handler->addGroupInstance("T", $this->ticket_id, $val[0]);
			//$field_handler->setFieldInstanceValue($val[1], $instance_id, $val[2]);
		}
	}
		
	fclose($fp);
}
Of course, this loop has no way of knowing that the group ids are the same and so adds a new instance of the group for EACH field. But every time I try a for loop, I get Array[0][1] etc, so I know I'm not reaching the right level.

Does anyone have a suggestion about doing this? I'm going to keep working on it, but I was wondering if anyone here had any ideas. I'd rather modify the instantiate_custom_fields code than my find_custom_fields_in_body, since that logic in more involved in the latter (I've included it at the end of this post, in case you want to look at it - it's kind of long), but I'm open to anything. I've Googled it and looked at the manuals, but nothing I've tried has worked. Sorry to be a bother, but I'm not very good at multidimensional arrays.

Thanks! I really appreciate everyone's help! :)

Code: Select all

function find_custom_field_in_body(&$raw_email)
{	
	$custom_field_values = array();

	$sql = "SELECT g.group_id, g.group_name, f.field_id, f.field_name, f.field_type ".
            "FROM field_group g ".
	    "LEFT JOIN `fields_custom` f ON (f.field_group_id = g.group_id) ".
	    "ORDER BY g.group_name";

	$res = $this->db->query($sql);

	preg_match_all("/\[Group\](.*)/i",$raw_email->body,$groups, PREG_SET_ORDER);
	preg_match_all("/\[Field Name\](.*)/i",$raw_email->body,$field_names, PREG_SET_ORDER);
	preg_match_all("/\[Field Value\](.*)/i",$raw_email->body,$field_values, PREG_SET_ORDER);

	if($this->db->num_rows($res) > 0)
	{
		$counter = 0;

		while($row = $this->db->fetch_row($res))
		{			
			if($row["group_id"] != NULL)
			{				
				foreach($groups as $group_name)
				{
					if(strcmp(rtrim($group_name[1]), stripslashes($row["group_name"])) == 0)
					{
						foreach($field_names as $f_name)
						{
							if(strcmp(rtrim($f_name[1]), stripslashes($row["field_name"])) == 0)
							{
								foreach($field_values as $f_val)
								{
									if(strcmp($row["field_type"], "D") == 0)
									{
										$sql2 = sprintf("SELECT o.field_id, o.option_id, o.option_value ".
	 												"FROM fields_options o ".
													"WHERE o.field_id = %d ".
													"ORDER BY o.option_order, o.option_value ASC",
														$row["field_id"]
											);

										$res2 = $this->db->query($sql2);

										if($this->db->num_rows($res2)) 
										{
											while($row2 = $this->db->fetch_row($res2)) 
											{
												if(strcmp(rtrim($f_val[1]), $row2["option_value"]) == 0)
												{
													$custom_field_values[$counter] = array($row["group_id"], $row["field_id"], $row2["option_value"]);
												}
											}
										}										
									}
									else
									{
										$custom_field_values[$counter] = array($row["group_id"], $row["field_id"], $f_name[1]);
									}
								}
							}
						}
					}
				}

				$counter++;	
			}	
		}
	}

	return $custom_field_values;
}
[/b]

Posted: Thu Apr 27, 2006 3:18 pm
by infolock
well, one thing i noticed while going through this was there is an error in your sql...

Code: Select all

$sql2 = "SELECT o.field_id, o.option_id, o.option_value FROM fields_options o  WHERE o.field_id = '{$row['field_id']}' ORDER BY o.option_order, o.option_value ASC";

notice the "o" after the fields_options table name in the FROM clause. is this suposed to be AS like this ?

Code: Select all

$sql2 = "SELECT o.field_id, o.option_id, o.option_value FROM fields_options AS o WHERE o.field_id = '{$row['field_id']}' ORDER BY o.option_order, o.option_value ASC";

Next, I'm not exactly what you are wanting to do with your array. All I can tell is you don't like the format it's in, which I have no idea what you would like it to look like? Could you give an example?


Next, I'd try formatting my arrays like this (as they will be a little more descriptive and will help you out later when you have to debug and print out the array like you did above..)

Code: Select all

if(strcmp(rtrim($f_val[1]), $row2["option_value"]) == 0) { 

                          $custom_field_values[] = array('group_id'     => $row["group_id"], 
                                                         'field_id'     => $row["field_id"], 
                                                         'option_value' => $row2["option_value"],
                                                        ); 
                        } 

//....some other stuff you have above this else statement
                  } else { 

                    $custom_field_values[] = array('group_id' => $row["group_id"], 
                                                   'field_id' => $row["field_id"], 
                                                   'f_name'   => $f_name[1],
                                                  ); 

                  }

Posted: Thu Apr 27, 2006 3:25 pm
by kayers
Hmm, well, I didn't write that SQL statement; I found it elsewhere in the code. I'll try it, though. :) Thanks!

I'm trying to store the group id, field id, and field values together, to establish a relationship between them. Then I send it back, and later one, send it to another function in another class, where I parse it and use that data to create instances of these 'custom fields' (which are groups of dropdown list, textareas, etc).

I guess my problem is I can't figure out how to get the foreach loop to check the next group id and compare it to the current one (because I don't want to create a new group each time if the group ids are the same), and I can't get a for loop to work...

Posted: Thu Apr 27, 2006 3:30 pm
by infolock
you should look up in_array()

Posted: Thu Apr 27, 2006 3:32 pm
by kayers
Yeah, I looked at that, but I don't know the group id value ahead of time... at least, not in that function; the data's all in the array (or am I just not understaning how to use in_array?). I'll play around with it, though. :)

Posted: Thu Apr 27, 2006 3:42 pm
by kayers
Okay, I guess what I'm really wondering is why this

Code: Select all

for($i = 0; $i < count($custom_fields); $i++)
{
	$current = $custom_field[$i];
			
	fwrite($fp, "current_field values:\n");
	fwrite($fp, "group id: $current_field[$i][0]\n");
	fwrite($fp, "field id: $current_field[$i][1]\n");
	fwrite($fp, "field value: $current_field[$i][2]\n\n");

	fwrite($fp, "current values:\n");
	fwrite($fp, "group id: $current[0]\n");
	fwrite($fp, "field id: $current[1]\n");
	fwrite($fp, "field value: $current[2]\n\n");
}
gives me this

Code: Select all

current_field values:
group id: [0]
field id: [1]
field value: [2]

current values:
group id: 
field id: 
field value: 

current_field values:
group id: [0]
field id: [1]
field value: [2]

current values:
group id: 
field id: 
field value: 

current_field values:
group id: [0]
field id: [1]
field value: [2]

current values:
group id: 
field id: 
field value:

Posted: Thu Apr 27, 2006 3:42 pm
by cj5
usort is your friend!