Capturing data from a C5 block form

Permalink
I've created a C5 form (from the Form block type) and want to capture the entered data. Now I know from another post that this is tricky as C5 sticks it in the database.

So, can I just extract this new data back out and then deal with it myself? It appears on the Reports so presumably I can. If so, what tables does it use and whhich PHP files do I need to edit to pick up on the fact the Submit button has been clicked and the data is now in the DBase?

Is this the best way? Or do I need to create a new block type and code the entire form and style and validate it myself in PHP? Sounds like a lot of work. It will have at least 15 fields. At least I'll have my own PHP files under the ROOT override area rather than trying to edit the Core files. Is there a way of using the C5 Form builder in my own block so I have more control?

Thanks for any suggestions

View Replies:
jero replied on at Permalink Reply
jero
I think it rather depends on what you're trying to do and when you're trying to do it. By the sound of it, you want something other than the form submission to happen in real time.

What you probably need to do is to copy
concrete/blocks/form/controller.php to blocks/form/controller.php thereby overriding the controller.

Then make changes in the action_submit_form() function of blocks/form/controller.php to do whatever it is you need.
mnakalay replied on at Permalink Reply
mnakalay
hello,
I agree with jero but you probably don't need to copy the whole thing.
I suggest you look at this add-in and the tutorial that comes with it.
http://www.concrete5.org/marketplace/addons/fancy-forms-template/...
http://www.concrete5.org/documentation/how-tos/developers/change-bl...

in the tutorial he explains how to divert the data towards your own code before sending it back to the normal C5 for process. He uses javascript. It's pretty straightforward and well explained actually.

Good luck
SteveDay replied on at Permalink Reply
Thanks jero and mnakalay.

To explain further, what I want to do is capture a load of user input and store it in a table for searching and displaying later. I don't think I need C5 to process the data after I've dealt with it unless it has to due to the way C5 works behind the scences.

I thought of copying the controller as you suggested jero but there was so much in it I wasn't sure where to start looking to make to changes. I'll check out the routine you suggest and see what I can make of it. This is all very new to me. I assume that if I use this form.php then I can still use the C5 form designer? (which will save me a load of coding I would think).

I'll check out your add-on suggestions as well mnakalay. May save me some time. I am a software guy but I have no skills in js, php, html, css...but some books are on their way!
mkly replied on at Permalink Reply
mkly
When I do this I create a package and a block specific to the form. The built in form is pretty complex to weed through to store stuff in a database if you aren't used to reading messy php.

The process is like this

1. Create a package
2. If you are creating a new table to add the data to create a db.xml file in your packages top level directory with the columns you need.
3. Create a block inside that package.
4. The db.xml file for this block is for the _settings_ of your form not the data you need to store. You do that in the above package db.xml
5. Create a form with the block view.php with the concrete5 form helper or just with html. Whichever you prefer.
6. Direct that form to
<form method="post" action="<?php echo $this->action('save_form') ?>">

7. In controller.php create a method
public function action_save_form() {

8. Inside that method, validate the data you get from post. You can use concrete5's builtin $this->post('name') or php's $_POST['name'] .

9. Save the data in the table you need it in.
$db = Loader::db();
$db->Execute('INSERT INTO some_table VALUES (?,?,?)', array($value_1, $value_2, $value_3);

That's the really brief version to get you started. I'm not sure if there is a good example out there right now, but that's the basics of it.

Good luck.
SteveDay replied on at Permalink Reply
Thanks mkly, this looks as though I might be able to do this, steps look fairly straight forward but still loads there to learn as I go. Books on PHP/SQL and C5 arriving shortly! I've found the package creating help page to get me going.
SteveDay replied on at Permalink Reply
OK, I'm stuck on what to put in the "blocks" db.xml file. I can find nothing in the forums for _settings_ and forms, only stuff to do with adding new attributes. What should go in this file?

Blocks I've looked at seem to have Table structure in them, but as instructed, this is in the package XML.

Also, other blocks I've looked at (and Dev Package creation page) have edit.php and add.php - do I need these as well. I did when I tried an simple example "block" add-on. If so what goes in these?
jero replied on at Permalink Reply
jero
OK, if that's what you want to do, you might want to try writing a block that will do this. Perhaps the easiest way to get started is to install the designer content package, which allows you to generate your own blocks - if you are going to hack code, this is an awesome base to start from.

Assuming you have a block, then you could try this bit of code:

<?php
$db = Loader::db();
$sql='select distinct questionSetId from btForm where surveyName=?';
$rows = $db->getRow($sql,array('Contact Us'));
$id = $rows['questionSetId'];
$answerSets = $db->getAll('select asID from btFormAnswerSet where questionSetId=?',array($id));
foreach ($answerSets as $v) {
        $asID = $v['asID'];
        $answers = $db->getAll('SELECT * FROM btFormAnswers A, btFormQuestions Q WHERE A.asID =? and A.msqID = Q.msqID', array($asID));
        foreach ($answers as $a){
                echo $a['question'].': '.$a['answer'], $a['answerLong']. '<br>';
        }
        echo '<hr>';
}
?>


In the case above, a standard form block on the "Contact Us" page is used as an example to pick out all the questions and answers that users have submitted.