Jump to content

Convert Grouped Array to JSON - streamline code


jarvis

Recommended Posts

Hi all,

I've got a database returning specific data. I'm looping this information and creating an array as follows (this helps grab only the info I need and format any data):

	$bookings[] = array(
		'booking_id'	=> $post->ID,
		'name'			=> $all_meta_for_user['first_name'][0].' '.$all_meta_for_user['last_name'][0],
		'telephone'		=> $all_meta_for_user['billing_phone'][0],
		'email'			=> $all_meta_for_user['billing_email'][0],
		'suite'			=> get_the_title( $bookingMeta['_booking_product_id'][0] ),
		'animal'		=> get_the_title( $bookingMeta['_booking_resource_id'][0] ),
		'quantity'		=> unserialize($bookingMeta['_booking_persons'][0]),
		'order_id'		=> $order_id_number,
		'start_date'	=> date_format($start_date,"d-m-Y"),
		'end_date'		=> date_format($end_date,"d-m-Y"),
	);

I'm then grouping the array by suite:

// group data by suite (pen)
$result = array();
foreach ($bookings as $booking) :
	$result[$booking['suite']][] = $booking;
endforeach;

This allows me to display the information in a tabulated format. This is handled by the following code:

$json = array();		
$count = 0;	
foreach ($result as $itemName => $rows) :
$count++;		
	echo '<tr>';
	echo '<td colspan="7"><strong>', $itemName, '</strong></td>';
	echo '</tr>';
		
	$customClass = ($count % 2 == 1) ? "ganttRed" : "ganttBlue"; 	

	foreach ($rows as $row) :
		echo '<tr>';
		echo '<td>', $row["booking_id"],$customClass. '</td>';
		echo "<td>".$row['name']."<br/>".$row['telephone']."<br/>".$row['email']."</td>";
		echo "<td>".$row['suite']."<br/>(".$row['animal'].")</td>";
		echo "<td>";
		foreach ($row['quantity'] as $quantity):
			echo $quantity;
		endforeach;		
		echo "</td>";
		echo '<td>', $row["order_id"], '</td>';
		echo '<td>', $row["start_date"], '</td>';
		echo '<td>', $row["end_date"], '</td>';
		echo '</tr>';
		
		$json_data = [
			'from'	=> $row["start_date"],
			'to'	=> $row["end_date"],
			'label'	=> $row['suite']." (".$row['animal'].")",
			'desc'	=> $row['name']."<br/>".$row['telephone']."<br/>".$row['email'],
			'customClass' => $customClass
		];	
		
		$json[] = array(
			'name' => $itemName,
			'desc' => $row["booking_id"],
			'values' => $json_data
		);		
		
	endforeach;
		
endforeach;

The final part is creating JSON from the above as this is then used to construct a jQuery Gantt chart. I'm using the following:

$i = 0;
$len = count($json);
foreach( $json as $data ):
	echo '{';
		echo 'name: "'.$data["name"].'",';
		echo 'desc: "'.$data["desc"].'",';
		echo "values: [{";
			echo 'from: "'.$data['values']['from'].'",';
			echo 'to: "'.$data['values']['to'].'",';
			echo 'label: "'.$data['values']['label'].'",';
			echo 'desc: "'.$data['values']['desc'].'",';
			echo 'customClass: "'.$data['values']['customClass'].'"';
		echo '},]';

	if( $i == $len - 1 ):
		echo '}';
	else:
		echo '},';
	endif;	
endforeach;

My question is whether I've massively over complicated this and whether I can achieve what's required with a more streamlined approach?

Thanks

Link to comment
Share on other sites

Thanks @Barand

I did try that but it returned no results, hence going the manually route.

On closer inspection I think it may be to do with the comma when calling it:

$(".gantt").gantt({
    source: [
	<?php
	$json_data = json_encode($json);
	echo $json_data;
	?>
    ],
    navigate: "buttons",
    scale: "days"
});

Also tried:

$(".gantt").gantt({
    source: 
	<?php
	$json_data = json_encode($json);
	echo $json_data;
	?>
    ,
    navigate: "buttons",
    scale: "days"
});

 

Link to comment
Share on other sites

Hmm, it's odd. This works:

<script>
$(".gantt").gantt({
    source: [
	<?php
	$i = 0;
	$len = count($json);
	foreach( $json as $data ):
		echo '{';
			echo 'name: "'.$data["name"].'",';
			echo 'desc: "'.$data["desc"].'",';
			echo "values: [{";
				echo 'from: "'.$data['values']['from'].'",';
				echo 'to: "'.$data['values']['to'].'",';
				echo 'label: "'.$data['values']['label'].'",';
				echo 'desc: "'.$data['values']['desc'].'",';
				echo 'customClass: "'.$data['values']['customClass'].'"';
			echo '},]';

		if( $i == $len - 1 ):
			echo '}';
		else:
			echo '},';
		endif;	
	endforeach;
	?>
    ],
    navigate: "buttons",
    scale: "days"
});
</script>

But this doesn't:

<script>
$(".gantt").gantt({
   navigate: "buttons",
    scale: "days",	
    source: 
<?php
$json_data = json_encode($json);
echo $json_data;	
?>
});
</script>	

I've moved the navigate and scale above source to prevent an issue with the commas but can see why it won't work?

Link to comment
Share on other sites

My 0.02 worth...

Don't mix your JS and PHP code like that. I f you need to send php data to JS (and you're not using AJAX) put the data into a hidden input field.

<?php
$jsonstr = json_encode($json);
echo "<input type='hidden', id='jsondata' value='$jsonstr'>";
?>

<script>
$(".gantt").gantt({
   navigate: "buttons",
    scale: "days",	
    source: $("#jsondata").val()

});
</script>	

 

Link to comment
Share on other sites

Thanks @Barand

Oddly, that didn't work at all and didn't produce any output

This code, partially works. It outputs the table of the chart but no data:

<script>
$(".gantt").gantt({
    navigate: "buttons",
    scale: "days",	
    source: 
<?php
$json_data = json_encode($json);
echo $json_data; ?>
});
</script>	

Checking the source code, I can see (truncated a lot of the inner stuff):

<script>
$(".gantt").gantt({
    navigate: "buttons",
    scale: "days",	
    source: 
[{"name":"Ducks Suite 2","desc":119,"values":{"from":"29-03-2022","to":"02-04-2022","label":"Small ducks (6)"...."customClass":"ganttBlue"}}]    
});
</script>	

This code works:

<script>
$(".gantt").gantt({
    navigate: "buttons",
    scale: "days",	
    source: [
<?php
$json_data = json_encode($json);
#echo $json_data;	
$i = 0;
$len = count($json);
foreach( $json as $data ):
	echo '{';
		echo 'name: "'.$data["name"].'",';
		echo 'desc: "'.$data["desc"].'",';
		echo "values: [{";
			echo 'from: "'.$data['values']['from'].'",';
			echo 'to: "'.$data['values']['to'].'",';
			echo 'label: "'.$data['values']['label'].'",';
			echo 'desc: "'.$data['values']['desc'].'",';
			echo 'customClass: "'.$data['values']['customClass'].'"';
		echo '},]';

	if( $i == $len - 1 ):
		echo '}';
	else:
		echo '},';
	endif;	
endforeach;
?>
    ],

});
</script>	

This outputs:

<script>
$(".gantt").gantt({
    navigate: "buttons",
    scale: "days",	
    source: [
{name: "Ducks Suite 2",desc: "119",values: [{from: "29-03-2022",to: "02-04-2022",label: "Small ducks (6)"...,customClass: "ganttBlue"},]},    ],

});
</script>

It looks like the part values requires the content to be wrapped in [] which the manual code does. The json_encode seems to exclude these - hence the content not fully loading!

Link to comment
Share on other sites

Thanks again @Barand for your help.

Sadly that still doesn't work:

<script>
$(".gantt").gantt({
    navigate: "buttons",
    scale: "days",	
    source: 
[[{"name":"Ducks Suite 2","desc":119,"values":{"from":"29-03-2022","to":"02-04-2022","label":"Small ducks (6)"...,"customClass":"ganttBlue"}}]]	
});
</script>	

It seems to double wrap the who source with []

However (penny drop moment!), if I revert back to your first snippet:

$json_data = json_encode($json);

Then amend the code to create the json array:

		$json_data = [[
			'from'	=> $row["start_date"],
			'to'	=> $row["end_date"],
			'label'	=> $row['animal']." (".$quantity.")",
			'desc'	=> $row['name']."<br/>".$row['telephone']."<br/>".$row['email'],
			'customClass' => $customClass
		]];	
		
		$json[] = array(
			'name' => $itemName,
			'desc' => $row["booking_id"],
			'values' => $json_data
		);	

That works!!! 😃

I hope that's the correct way to fix it!?

Thank you for taking the time to help, it's always very much appreciated!

Link to comment
Share on other sites

My advice is don't do this:

$data = [[
  ...
  'desc'	=> $row['name']."<br/>".$row['telephone']."<br/>".$row['email'],
]];	

Use separate elements for these 3 values.  This maintains the separation of concerns:  your data is your data in json form, and you use your View code to display that data in whatever way you need.   It is trivial to output that markup if you really want a string that has that format, but later if you want to improve that, you will have to rewrite your code to do anything different.  Don't mix data with markup.

$data = [[
  'from' => $row["start_date"],
  'to' => $row["end_date"],
  'label' => $row['animal']." (".$quantity.")",
  'name' => $row['name'],
  'telephone' => $row['telephone'],
  'email' => $row['email'],
  'customClass' => $customClass
]];

$items[] = array(
  'name' => $itemName,
  'desc' => $row["booking_id"],
  'values' => $data
);

I also renamed the $json_data variable.  It's not json data, it's just the data.  Use $json_data or better yet $jsonData as the name of the variable to use when you have json_encode'd the array data.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.