Jump to content
Larry Ullman's Book Forums

Insert Php Generated Table Into An Email


Recommended Posts

I've generated a table of data using form data and the table needs to be emailed. How do you insert a php generated table into an email? I have a feeling that this could be achieved using javascript but I've never got comfortable with js so if it could be done with php, I would prefer to go that route.

 

If you go to this link and fill in the form, you'll see the resulting table that needs to be included in an email.  (There is validation on the form but if you input invalid data, you'll just get a blank screen as I'm working on the core functionality at the moment. )

 

I found these functions online

function extract_id($content, $id) {
	// use mb_string if available
	if (function_exists('mb_convert_encoding')) {
		$content = mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8');
	}
	$dom= new DOMDocument();
	$dom->loadHTML($content);
	$dom->preserveWhiteSpace = false;	
	$element = $dom->getElementById($id);
	$innerHTML = innerHTML($element);
	return($innerHTML); 
}

/**	 
 * Helper, returns the innerHTML of an element
 *
 * @param object DOMElement
 *
 * @return string one element's HTML content
 */

function innerHTML($contentdiv) {
	$r = '';
	$elements = $contentdiv->childNodes; //line 77
	foreach( $elements as $element ) {  // line 78
		if ( $element->nodeType == XML_TEXT_NODE ) {
			$text = $element->nodeValue;
			// IIRC the next line was for working around a
			// WordPress bug
			//$text = str_replace( '<', '<', $text );
			$r .= $text;
		}	 
		// FIXME we should return comments as well
		elseif ( $element->nodeType == XML_COMMENT_NODE ) {
			$r .= '';
		}	 
		else {
			$r .= '<';
			$r .= $element->nodeName;
			if ( $element->hasAttributes() ) { 
				$attributes = $element->attributes;
				foreach ( $attributes as $attribute )
					$r .= " {$attribute->nodeName}='{$attribute->nodeValue}'" ;
			}	 
			$r .= '>';
			$r .= innerHTML( $element );
			$r .= "</{$element->nodeName}>";
		}	 
	}	 
	return $r;
}

When I tried using them, I received these error messages, but I am uncertain what to pass as the argument. Would appreciate any help, thanks.

Notice:  Trying to get property of non-object in /Applications/MAMP/htdocs/circuit/circuit.inc.php on line 77

Warning:  Invalid argument supplied for foreach() in /Applications/MAMP/htdocs/circuit/circuit.inc.php on line 78
Link to comment
Share on other sites

Thanks HartleySan for the reply but the link does not address what I'm trying to do. The table is generated via some server side processing using input from a form and involves some nested loops, so to generate that table within an HTML email is not possible.

 

I amended the first function as follows.

function extract_id($url, $id) {

	$content = file_get_contents($url);
	$content = mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8');
	$dom= new DOMDocument();
	$dom->loadHTML($content);
	$dom->preserveWhiteSpace = false;	
	$element = $dom->getElementById($id);
	$innerHTML = innerHTML($element);
	return($innerHTML); 
}

but got a bunch of warnings, here are just a few.

Warning: DOMDocument::loadHTML() [domdocument.loadhtml]: htmlParseStartTag: misplaced <head> tag in Entity, line: 4 in /Applications/MAMP/htdocs/circuit/get_circuit_cost.php on line 25

Warning: DOMDocument::loadHTML() [domdocument.loadhtml]: htmlParseStartTag: invalid element name in Entity, line: 51 in /Applications/MAMP/htdocs/circuit/get_circuit_cost.php on line 25

Warning: DOMDocument::loadHTML() [domdocument.loadhtml]: htmlParseStartTag: invalid element name in Entity, line: 59 in /Applications/MAMP/htdocs/circuit/get_circuit_cost.php on line 25

Warning: DOMDocument::loadHTML() [domdocument.loadhtml]: htmlParseEntityRef: no name in Entity, line: 75 in /Applications/MAMP/htdocs/circuit/get_circuit_cost.php on line 25

Warning: DOMDocument::loadHTML() [domdocument.loadhtml]: htmlParseEntityRef: no name in Entity, line: 75 in /Applications/MAMP/htdocs/circuit/get_circuit_cost.php on line 25

Not sure if this is even the way to go about getting the table in the email.Any other suggestions?

Link to comment
Share on other sites

Thanks HartleySan for the reply but the link does not address what I'm trying to do. The table is generated via some server side processing using input from a form and involves some nested loops, so to generate that table within an HTML email is not possible.

 

 

I don't understand why this is a problem. Wouldn't you just generate the HTML table using PHP, and then embed it in the email using the PHP mail function?

 

Also, I ran the example script at the following link on multiple HTML documents, and it worked fine:

http://php.net/manual/en/domdocument.loadhtml.php

 

Could you please provide the HTML your using? Thanks.

Link to comment
Share on other sites

Wouldn't you just generate the HTML table using PHP, and then embed it in the email using the PHP mail function?

um, isn't this what I asked in the first post, the subject of this thread? Here's the code to generate the table ( not including the pre-defined functions, of which there are at least 10).

<table id="data_table"><thead><tr><td></td>
	<?php
	setlocale(LC_MONETARY, 'en_GB');
	foreach ($qty_array as $qty){
		echo '<td align="center">' . $qty . '</td>';
	}
	echo '</tr></thead>' ."\r\n";
		foreach ($awd_total_multiple as $row=>$awd_multiple) {
			echo '<tr><td>' . $row . '</td>';
			foreach ($qty_array as $qty) {
				$qty = ($qty == 1) ? 2 : $qty;
				$subtotal = get_awd_subtotal($qty, $total_components_per_circuit, $num_circuit_components);
				
				// calculate cost adder per BGA QFN placement
				$total_BGAs = get_total_BGAs($qty,$num_BGA_circuit);
				$cost_adder = get_cost_adder($qty,$total_BGAs);

				//calculate total
				$awd_total = $subtotal + $cost_adder;
			
				//calculate working days to do
				$working_days = get_working_days($qty, $total_components_per_circuit, $total_BGAs);
				
				$total_multiplier = ($working_days < number_format($row)) ? $awd_multiple : 0;
				if ($row == 15) {$total_multiplier = 1;}
				$tot_to_display = ($total_multiplier == 0) ? ' ' : money_format("%= #5.0n", $awd_total * $total_multiplier);
				echo '<td>'.  $tot_to_display . '</td>'."\r\n";
			}
			echo '</tr>';
		}
		echo '</table>

Are you suggesting I assign all of the above to a variable?

 

I had previously looked at the link you posted but I'm obviously doing something wrong as when I passed a string of a subset of the table,

$content ='<table id="data_table"><thead><tr><td></td>
	<td align="center">1</td><td align="center">2</td><td align="center">3</td><td align="center">5</td><td align="center">10</td><td align="center">20</td><td align="center">30</td><td align="center">50</td><td align="center">100</td></tr></thead>
<tr><td>2</td><td> £  1,788</td>
<td> £  1,788</td>
<td> £  2,285</td>
<td> £  2,919</td>
<td> £  2,886</td>
<td> £  3,421</td>
<td> £  3,872</td>
<td> £  5,237</td>
<td> </td>
</tr>
</tr></table>';

I got these errors

Notice: Trying to get property of non-object in /Applications/MAMP/htdocs/circuit/test_ceil.php on line 23

Warning: Invalid argument supplied for foreach() in /Applications/MAMP/htdocs/circuit/test_ceil.php on line 24

I appreciate you're taking the time to look at this and I have a feeling that I may be overcomplicating things but I don't know how to get the html to pass to mail().

Link to comment
Share on other sites

Are you suggesting I assign all of the above to a variable?

 

Yes, I am. You basically build up your email body one line at a time, storing each line in a variable, and then use the variable that contains the entire HTML string as the $message argument in the PHP mail function. In other words, don't echo the table; assign it to a variable. I'd start out with a simple HTML string for testing purposes, and once you know it works, make it more complex, little by little.

 

As for the errors, I can't comment without seeing more of your code and knowing what lines 23 and 24 are. Could you please explain exactly what you want to do and where your HTML is coming from? I'm still confused as your code seems to be changing a lot.

  • Upvote 1
Link to comment
Share on other sites

The goal is to take data from a form and generate costs using some fairly complicated formula and the form data. Then present a table of results on screen and email the table to the user.

 

You basically build up your email body one line at a time, storing each line in a variable

So I took your suggestion

<?php
	$content = '<table id="data_table"><thead><tr><td></td>';
	setlocale(LC_MONETARY, 'en_GB');
	foreach ($qty_array as $qty){
		echo '<td align="center">' . $qty . '</td>';
	}
	echo '</tr></thead>' ."\r\n";
	$content .= '</tr></thead>' ."\r\n";
		foreach ($awd_total_multiple as $row=>$awd_multiple) {
			echo '<tr><td>' . $row . '</td>';
			foreach ($qty_array as $qty) {
				$qty = ($qty == 1) ? 2 : $qty;
				$subtotal = get_awd_subtotal($qty, $total_components_per_circuit, $num_circuit_components);
				
				// calculate cost adder per BGA QFN placement
				$total_BGAs = get_total_BGAs($qty,$num_BGA_circuit);
				$cost_adder = get_cost_adder($qty,$total_BGAs);

				//calculate total
				$awd_total = $subtotal + $cost_adder;
			
				//calculate working days to do
				$working_days = get_working_days($qty, $total_components_per_circuit, $total_BGAs);
				
				$total_multiplier = ($working_days < number_format($row)) ? $awd_multiple : 0;
				if ($row == 15) {$total_multiplier = 1;}
				$tot_to_display = ($total_multiplier == 0) ? ' ' : money_format("%= #5.0n", $awd_total * $total_multiplier);
				echo '<td>'.  $tot_to_display . '</td>'."\r\n";
				$content .= '<td>'.  $tot_to_display . '</td>';
				
			}
			echo '</tr>';
			$content .='</tr>';
		}
		echo '</table></div>';
		$content .= '</table></div>';
		email_table($em, $content); // this function sends the email

And I'm nearly there! Unfortunately all the html tags were displayed as literals in the email.

<table id="data_table"><thead><tr><td></td></tr></thead>
<td> £  1,788</td><td> £  1,788</td><td> £  2,285</td><td> £  2,919</td><td> £  2,886</td><td> £  3,421</td><td> £  3,872</td><td> £  5,237</td><td> </td></tr><td> £    715</td><td> £    715</td><td> £    914</td><td> £  1,168</td><td> £  1,154</td><td> £  1,368</td><td> £  1,549</td><td> £  2,095</td><td> £  3,179</td></tr><td> £    615</td><td> £    615</td><td> £    786</td><td> £  1,004</td><td> £    993</td><td> £  1,177</td><td> £  1,332</td><td> £  1,802</td><td> £  2,734</td></tr><td> £    476</td><td> £    476</td><td> £    608</td><td> £    777</td><td> £    768</td><td> £    910</td><td> £  1,030</td><td> £  1,393</td><td> £  2,114</td></tr><td> £    436</td><td> £    436</td><td> £    558</td><td> £    712</td><td> £    704</td><td> £    835</td><td> £    945</td><td> £  1,278</td><td> £  1,939</td></tr><td> £    397</td><td> £    397</td><td> £    507</td><td> £    648</td><td> £    641</td><td> £    760</td><td>
 £    860</td><td> £  1,163</td><td> £  1,764</td></tr><td> £    358</td><td> £    358</td><td> £    457</td><td> £    584</td><td> £    577</td><td> £    684</td><td> £    774</td><td> £  1,047</td><td> £  1,590</td></tr></table>

I'll read up on html emails to sort that one out, but I may be back ;)

 

The previous code I posted for the function extract_id was to try to read in the html page on which the table was displayed and grab the inner html to use as the $message for the mail() function. Not sure if that would have worked but maybe I'll try to get that working another day. Thanks again for your help.

 

Link to comment
Share on other sites

Yeah, I'll be honest, I've never really messed with HTML in emails, so I'm not familiar with all the caveats. With that said, the first link I provided you with seemed to explain all the details. As I suggested, start out simple, and then work your way up.

Link to comment
Share on other sites

Hi HartleySan,

 

The link you provided is a good starting place to understand how to style html emails and I've read something similar in the past. To send an html email so the html tags are interpreted as opposed to displaying as literals, one needs to send the email via an email client, such as Thunderbird. So I think I need to speak to my hosting provider to see if/how they support this functionality.

 

Other options are MailChimp and Campaign Monitor, but I need to find a way to automate the process.

 

I've googled this loads and it comes up with lots of helpful links for styling html emails but not the next step of actually getting the html tags to be recognised as html tags and not literal text. Just thought I'd post this in case it helps anyone else.

 

Thanks again for replying!

 

UPDATE: my hosting provider told me to include the appropriate headers in the mail function so all is good.

$to = 'info@example.com';
$subject = 'example';
$message = 'ipsem lorem etc.';
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
mail ($to, $subject, $message, $headers);
Link to comment
Share on other sites

 Share

×
×
  • Create New...