Forums

Email after database submit?

balslev 25 Jul, 2009
Hi there,

Is there any neat way I can provide a client with an auto incremented number, a unique support ticket (the cf_id is fine), in the email sent out immidately after submit?

Emails are working fine, I know how to get cf_id from the form table using php and it executes nicely in the On Submit events. But, since the record is not created at the time when an email is generated, I currently only get the last id. I fear I'll have to do tricks, e.g. with a helper table that generate a number which will later be stuffed into the form's table.

But, before I go down that path to what has perhaps been solved 2,000 times over before I arrived, I'll ask here. Obviously I have searched the forum, read the FAQ (especially the "Can I run PHP code when the form is submitted?") and tried tutorials, but no luck.

Thank you for you assistance.

/Balslev
GreyHead 25 Jul, 2009
Hi Balslev,

Change the Flow Order on the Autogenerated tab so that the Database save is run 'Before Email'. The saved data including the cf_id is then available in $MyForm->tablerow["table_name"].

Bob

NB if you set the Autogenerated Code to run Before Email and Emails are turned off then the code will not run!
balslev 26 Jul, 2009
Hi GreyHead,

Thank you very much. I'm sure the path you suggest is the right one but I can't make it work:
1. You advise me to change the flow order on the Autogenerated tab. I assume you either mean "of" instead of "on", or that I should change it on the RunOrder tab. In any event, I can't see any other place where changing the flow order would be more appropriate so I had fun with RunOrder

2. Regardless of the combination of 2 or 3 I set for "Autogenerated block" and "OnSubmit block" I arrive at the same result when emailing is disabled: No emails are sent and nothing is saved to the database

3. With emailing enabled the combination doesn't seem to matter either. At least when I execute a fetch for MAX(cf_id) of the table in the Submit block before email, I consistently get the previous id. It does send an email though, and it does save form data correctly. But I can't verify that RunOrder actually has any effect.

4. I'd better admit that my PHP experience is not really impressive. Hence I'm not able to get from the (assumed) array you refer to with '$MyForm->tablerow["jos_chronoforms_formSuggestions"]' to the value of cf_id... I tried:
- $MyForm->tablerow["jos_chronoforms_formSuggestions"]["cf_id"]
- $MyForm->tablerow["jos_chronoforms_formSuggestions"]["id"]
- $MyForm->tablerow["jos_chronoforms_formSuggestions"][1]
- $MyForm->tablerow["jos_chronoforms_formSuggestions"]->cf_id and a wealth of other equally ineffective notations, all executed in the Submit Before Email block.

Do you have any ideas as to how I should progress?

Thank you for your effort!

/Balslev
GreyHead 26 Jul, 2009
Hi balslev,

Hmmm I did mean 'on' - there used to be an option 'on' the Autogenerated Tab but it looks as though Max has removed it in the latest release and I don't see any alternative option :-(

That's a bit of a nuisance . . . I don't quite know what to suggest now. Let me think about it.

Bob
balslev 26 Jul, 2009
Hi Bob,

If looked into and debugged chronoform.php (line 400 onwards), and as far as I can conclude:
- The file is designed to facilitate three executing blocks on each side of the send email operation, the three blocks being plugins, on submit code and autogenerated code

- Specifications on the RunOder tab only deals with the order of execution AFTER the email is sent. The order of execution before email is sent is non-negotiable: (1) Plugin, (2) On submit and (3) Autogenerated

- The admin UI offer blocks for on submit code to be executed both before and after email is sent. This is NOT the case for the autogenerated blocks. There is only one. This could be argued as a fair design albeit rather strange since chronoform.php offer execution of two

- The autogenerated block persists data to the database and is exactly what the name implies, that is, it cannot be effectively altered by us. Hence, neither the content nor the order of database submit execution can be customized

- The two solutions to the original challenge I see are:
a) I'll rearrange chronoform.php so RunOrder settings are honored both before and after emails are sent. I would assume this to be in line with the thoughts Max have had at some point, but for some reason later disregarded and never got around to clean up
b) I'll add a table maintaining an autoincremented id which is handled in the on submit before email block. The block would also have to transfer the incremented ID to a hidden form variable which will then, vis a vis the autogenerated code, be stored along with the rest of the record

I'll go with b) and so consider this case closed / solved.

Regards,

/Balslev
GreyHead 27 Jul, 2009
Hi Balslev,

A nice piece of work, thank you.

A third solution woudl be to copy the AutoGenerated Code out of the AutoGenerated Code box and paste it into the OnSubmit Before Box where it is editable.

Bob

PS I really don't understadn wehay Max has removed the flow control option from the Autogenerate Code - maybe it was just to complicated controlling all the options - but occasionally it was really useful.
Max_admin 27 Jul, 2009
Hi Balslev,

Thank you for suggestions, I have plans to turn this into events and allow the ability to add/enable/disable/arrange as many of them as possible, many other improvements as well, not sure when I will be able to finish this though!

Regards,
Max
Max
ChronoForms developer...
Did you try ChronoMyAdmin for managing your Joomla database tables ?
za1111az 13 Aug, 2009
Hi Bob, I have the same problem Balslev. Design a product order form and I need that in the e-mail that comes to clint showing the order number.

I saw that to make the row number should I use $ MyForm-> tablerow [ "table_name"] -> cf_id but not where to put.

Thank you very much and sorry for my English.

Tito Soli
GreyHead 13 Aug, 2009
Hi Tito,

It needs to go into the Email template.
<?php
echo "Order Number: ".$MyForm->tablerow["table_name"]->cf_id;
?>
To add php like this into the template you will need to disable the html editor in the Email Setup Properties.

Bob
nml375 13 Aug, 2009
In addition to Bob's reply,
Also make sure that the "Saving Data/Email order" setting under DB Connection is set to "Before Email", so that the data is added to the database (and thus given an unique id) prior sending the email (I believe that setting is still around).

This should save you the hazzle of copying the autogenerated code into the "onsubmit before email" box, as the autogenerated segment would be evaluated right after this. A word of advice though, is that if you disable emails, the db storage would also be disabled just like the "onsubmit before email" would.
/Fredrik
bonsai 25 Aug, 2009
Hi Bob,

first, its a great work of the team. It makes fun to work with this component.

I have similar problems. My form works quite well. The handover of the cf_id through the templates works great. Now I would like to attach a PDF document. This works also great with the data from the form. But now I would like to add the cf_id from the database in the PDF. So i copied the complete code from the tab "auto-generated code" in the "On submit code before sending ...". The only problem I have now is the output in PDF.

The template have the correct ID. Unfortunately, the ID in my PDF is the ID bevor. For Example Template has cf_id 100 and PDF 99.

I attached my code. Unfortunately, my knowledge of PHP is not very large.
But perhaps there is an idea about this.


<?php
error_reporting(E_ALL);
/* Put the AutoGenerated code here */
		$MyForm =& CFChronoForm::getInstance("Pclub");
		if($MyForm->formparams("dbconnection") == "Yes"){
			$user = JFactory::getUser();			
			$row =& JTable::getInstance("chronoforms_pclub", "Table");
			srand((double)microtime()*10000);
			$inum	=	"I" . substr(base64_encode(md5(rand())), 0, 16).md5(uniqid(mt_rand(), true));
			JRequest::setVar( "recordtime", JRequest::getVar( "recordtime", date("Y-m-d")." - ".date("H:i:s"), "post", "string", "" ));
			JRequest::setVar( "ipaddress", JRequest::getVar( "ipaddress", $_SERVER["REMOTE_ADDR"], "post", "string", "" ));
			JRequest::setVar( "uid", JRequest::getVar( "uid", $inum, "post", "string", "" ));
			JRequest::setVar( "cf_user_id", JRequest::getVar( "cf_user_id", $user->id, "post", "int", "" ));
			$post = JRequest::get( "post" , JREQUEST_ALLOWRAW );			
			if (!$row->bind( $post )) {
				JError::raiseWarning(100, $row->getError());
			}				
			if (!$row->store()) {
				JError::raiseWarning(100, $row->getError());
			}
			$MyForm->tablerow["jos_chronoforms_pclub"] = $row;
		}

/* End AutoGenerated code */

require('_fpdf/fpdf.php');
$data = $MyForm->tablerow["jos_chronoforms_pclub"]->cf_id;
$Vorname = utf8_decode($_POST['Vorname']);
$Nachname = utf8_decode($_POST['Nachname']);

$pdf=new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','',16);
$pdf->Cell(0, 7, 'Datum:, '.date("d.m.Y"), 0, 1, 'R');
$pdf->Cell(40,10, 'Hallo');
$pdf->Text(80,50, $Vorname);
$pdf->Cell(90,60,'cf_id.: '.$data);
$pdf->Output('images/stories/pdf/test', 'F');

$MyUploads =& CFUploads::getInstance($MyForm->formrow->id);
$MyUploads->attachments[] = 'images/stories/pdf/test'; // add complete file path here
?>

I forgot: I am using the latest releases of Joomla and of Chronoforms.
Thank you very much. Sorry for my english.
Günter
nml375 25 Aug, 2009
Hi Günther,
Could you verify whether you get one or two entries for each post in your database?

/Fredrik
bonsai 26 Aug, 2009
Hi Fredrik,

ups. You are right. there are two entries. what is the mistake?
Is it because the AutoGenerated code is running after the "on submit before..."
How could i get control of it?

Günter
nml375 26 Aug, 2009
Hi Dave,
It's because you still got the DB Connection enabled, and do the very same job by hand. Thus, the data gets saved twice.

My recommendation is that you stick with the DB Connection only (remove your own db-store code), make sure that the "Saving Data/Email order" setting under DB Connections is set to "Before Email", and make sure the run-order is set as: 1: auto-generated, 2: plugins, 3: OnSubmit.
Then put your pdf-creation code (without the autogenerated code) in the OnSubmit Before Email box.

/Fredrik
bonsai 26 Aug, 2009
Hi Fredrik,

ok.
Your recommendation i had before. only DB Connection, set to "Before Email", same "RunOrder". But then i didn't get the cf_id in the pdf output.

And now i get also an error:
Notice: Undefined index: jos_chronoforms_pclub in ../cms/components/com_chronocontact/libraries/customcode.php(64) : eval()'d code on line 8


Line 8: $data = $MyForm->tablerow["jos_chronoforms_pclub"]->cf_id;

I think there is a RunOrder Problem or maybe the pdf-output comes too early, because in the email-output the cf_id is ok.

This is the code now:

<?php
require('_fpdf/fpdf.php');

//$MyForm =& CFChronoForm::getInstance();
$data = $MyForm->tablerow["jos_chronoforms_pclub"]->cf_id;
echo $data;
$Vorname = utf8_decode($_POST['Vorname']);
$Nachname = utf8_decode($_POST['Nachname']);

$pdf=new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','',16);
$pdf->Cell(0, 7, 'Datum:, '.date("d.m.Y"), 0, 1, 'R');
$pdf->Cell(40,10, 'Hallo');
$pdf->Text(80,50, $Vorname);
$pdf->Cell(90,60,'Club-nr.: '.$data);
$pdf->Output('images/stories/pdf/test', 'F');

$MyUploads =& CFUploads::getInstance($MyForm->formrow->id);
$MyUploads->attachments[] = 'images/stories/pdf/test'; // add complete file path here
$database->getErrorMsg()
?>


Günter
nml375 26 Aug, 2009
Hi Günter,
Sorry I called you Dave in the last reply.. Probably had too much blood in the caffein circulatory system..

Back to the issue, this seems indeed like a run-order issue. Or actually, as I'm digging through the source, it seems the OnSubmit Before Email code does not honor run-order rules, and is always executed first. As such, you'll have to do the storage "by hand". Add the autogenerated code to your "before email" code, and remember to turn off the DB Connection.

/Fredrik
bonsai 27 Aug, 2009
Hi Fredrik,

i add the code and turn off the DB Connection as you told me. But now there is no entry in the database and also an error in the email-template and on the page generating the cf_id output. When i set the DB Connection to Yes the entry comes twice.

Shit,
I don't know what to do.

Günter
nml375 27 Aug, 2009
Hi Günter,
Seems I overlooked a tiny, but yet so important, line in the auto-generated code..
      if($MyForm->formparams("dbconnection") == "Yes"){

This is a failsafe to make sure the data isn't saved when the db connection is disabled even if the auto-generated code would be executed by accident. Unfortunately, that fights against us here, so change your code into something like this (removing the conditional):
<?php
  error_reporting(E_ALL);
/* Put the AutoGenerated code here */
  $MyForm =& CFChronoForm::getInstance("Pclub");
  $user = JFactory::getUser();         
  $row =& JTable::getInstance("chronoforms_pclub", "Table");
  srand((double)microtime()*10000);
  $inum   =   "I" . substr(base64_encode(md5(rand())), 0, 16).md5(uniqid(mt_rand(), true));
  JRequest::setVar( "recordtime", JRequest::getVar( "recordtime", date("Y-m-d")." - ".date("H:i:s"), "post", "string", "" ));
  JRequest::setVar( "ipaddress", JRequest::getVar( "ipaddress", $_SERVER["REMOTE_ADDR"], "post", "string", "" ));
  JRequest::setVar( "uid", JRequest::getVar( "uid", $inum, "post", "string", "" ));
  JRequest::setVar( "cf_user_id", JRequest::getVar( "cf_user_id", $user->id, "post", "int", "" ));
  $post = JRequest::get( "post" , JREQUEST_ALLOWRAW );         
  if (!$row->bind( $post )) {
    JError::raiseWarning(100, $row->getError());
  }            
  if (!$row->store()) {
    JError::raiseWarning(100, $row->getError());
  }
  $MyForm->tablerow["jos_chronoforms_pclub"] = $row;
/* End AutoGenerated code */

require('_fpdf/fpdf.php');
$data = $MyForm->tablerow["jos_chronoforms_pclub"]->cf_id;
$Vorname = utf8_decode($_POST['Vorname']);
$Nachname = utf8_decode($_POST['Nachname']);

$pdf=new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','',16);
$pdf->Cell(0, 7, 'Datum:, '.date("d.m.Y"), 0, 1, 'R');
$pdf->Cell(40,10, 'Hallo');
$pdf->Text(80,50, $Vorname);
$pdf->Cell(90,60,'cf_id.: '.$data);
$pdf->Output('images/stories/pdf/test', 'F');

$MyUploads =& CFUploads::getInstance($MyForm->formrow->id);
$MyUploads->attachments[] = 'images/stories/pdf/test'; // add complete file path here
?>


/Fredrik
bonsai 28 Aug, 2009
Hi Fredrik,

now i get an fatal error?!

Günter

Fatal error: Call to a member function on a non-object in ...com_chronocontact/libraries/customcode.php(64) : eval()'d code on line 14
nml375 28 Aug, 2009
Hi Günter,
Sorry, I forgot that you'll need to load the Class definition of the JTable class used for the DB Storage.
Add this to the beginning of the code:
eval ('?>' . $MyForm->formrow->dbclasses);


/Fredrik
bonsai 29 Aug, 2009
Hi Fredrik,

this looks very good. The pdf-Output is ok.
But now there is an error in the email-output.

Before doing the things you told me the following code was ok.

Email Template:
<?php
//$MyForm =& CFChronoForm::getInstance();
$data = $MyForm->tablerow['jos_chronoforms_pclub']->cf_id;
echo $data;
?>


Do i have to change them yet?

Günter
nml375 29 Aug, 2009
Hi Günter,
That piece of code should still be valid. I am a little tied up at the moment, but I'll have a deeper look at this early next week. I hope this isn't too much of an inconvenience for you.

/Fredrik
nml375 01 Sep, 2009
Hi Günter,
Could you post some details on the new error? Been trying to reproduce the issue, but (unfortunately) everything works just fine here with CF3.1RC5.5.

/Fredrik
bonsai 26 Oct, 2009
Hi Fredrik,
excuse me that I reply so late. But i was sick for awhile and then in the holidays.
Now I'm back. You're right. Your code was o.k.. The error was in the Template.

It must be:
$MyForm =& CFChronoForm::getInstance();

and not
//$MyForm =& CFChronoForm::getInstance();

So thank you very much for your patience.
Günter :-)
nml375 26 Oct, 2009
No worries,
Happy you got it sorted finally.

/Fredrik
This topic is locked and no more replies can be posted.