Forms and scrapbook
Permalink 1 user found helpful
I am trying to save a form to a scrapbook and use that in the template. Here is what I have tried:
1. Created a simple form - 1 question, text box, Reply - "Thanks"
2. Tested it and it updates the form page in the dashboard and sends out an email notification.
3. Saved it to the dashboard 'Default Page stuff'.
4. Added it to the template with the following:
[code]<?php
$b = Block::getByName('Default Page stuff 331');
$bv = new BlockView();
echo $bv->render($b, 'view');
?> [\code]
When I use the form this way, the page refreshes when pressing the submit button, but I get no submission. Is this possible? Or is there another way to easily put a form on many pages? Thanks.
1. Created a simple form - 1 question, text box, Reply - "Thanks"
2. Tested it and it updates the form page in the dashboard and sends out an email notification.
3. Saved it to the dashboard 'Default Page stuff'.
4. Added it to the template with the following:
[code]<?php
$b = Block::getByName('Default Page stuff 331');
$bv = new BlockView();
echo $bv->render($b, 'view');
?> [\code]
When I use the form this way, the page refreshes when pressing the submit button, but I get no submission. Is this possible? Or is there another way to easily put a form on many pages? Thanks.
Have you tried creating an external form?
This way you could select it from the add block function.
This way you could select it from the add block function.
I'm sure you already thought of this, but just for the sake of completeness -- you could add the block to the page defaults for the relevant page types.
I was able to repeat the issue you're seeing. Comparing the <form> tags:
When added to a page area (works):
When coded into template (broken):
The only difference I see is in the 'arHandle' param which is 'Main' in the first case and null in the second.
I'll take a look at the form block and see if there's a good reason the area can't be null...
When added to a page area (works):
<form enctype="multipart/form-data" id="miniSurveyView208" class="miniSurveyView" method="post" action="/NewCadbury/index.php?cID=1&bID=208&arHandle=Main&ccm_token=1280085922:cbca029cfc3b3bcd464f3f3fdb059cca&btask=passthru&method=submit_form#1280085409">
When coded into template (broken):
<form enctype="multipart/form-data" id="miniSurveyView209" class="miniSurveyView" method="post" action="/NewCadbury/index.php?cID=1&bID=209&arHandle=&ccm_token=1280085922:cbca029cfc3b3bcd464f3f3fdb059cca&btask=passthru&method=submit_form#1280085409">
The only difference I see is in the 'arHandle' param which is 'Main' in the first case and null in the second.
I'll take a look at the form block and see if there's a good reason the area can't be null...
John - I started looking into external forms, but don't see much good info in the forums or docs...
aged - Thanks, let me know if you find something!
aged - Thanks, let me know if you find something!
No solution, but here's what I've tried so far:
The crux of the problem is that when the form is submitted, the function action_submit_form() in concrete/blocks/form/controller.php is not getting called. The <form> action url is mainly getting constructed by a call to the action() function in concrete/libraries/block_view.php. That function calls getBlockPassThruAction() in concrete/libraries/block.php which in turn calls _getBlockAction() in the same class. _getBlockAction() is expecting the block to have an areaHandle.
So I tried the meathead approach of giving the block an area in the template like this:That resulted in a <form> tag like this: Notice that the arHandle param is set to 'Sidebar2'. But something's still wrong. The controller function action_submit_form() is still not getting called when the button is clicked. I haven't been able to figure out what code is responsible for the actual routing to the function action_submit_form().
The crux of the problem is that when the form is submitted, the function action_submit_form() in concrete/blocks/form/controller.php is not getting called. The <form> action url is mainly getting constructed by a call to the action() function in concrete/libraries/block_view.php. That function calls getBlockPassThruAction() in concrete/libraries/block.php which in turn calls _getBlockAction() in the same class. _getBlockAction() is expecting the block to have an areaHandle.
So I tried the meathead approach of giving the block an area in the template like this:
<?php $as2 = new Area('Sidebar2'); $b = Block::getByName('Default Page stuff'); $b->setBlockAreaObject($as2); $bv = new BlockView(); echo $bv->render($b,'view'); ?>
<form enctype="multipart/form-data" id="miniSurveyView209" class="miniSurveyView" method="post" action="/NewCadbury/index.php?cID=1&bID=209&arHandle=Sidebar2&ccm_token=1280092334:9287666fcb4a5ce88f65514efe2bfa3f&btask=passthru&method=submit_form#1280085409">
OK, I've got a solution -- if you don't mind hacking the core a bit.
First of all, don't do what I tried in the last post -- creating an area in the template and assigning the block to it. Just leave the template like you originally had it.
Next go to line 206 in concrete\startup\process.php. The hack is just to handle the case of an empty 'arHandle' there. Change the code to this:
Maybe one of the core developers could have a look at this as a possible core modification. It seems reasonable to me that passThru calls should work from hard-coded blocks as well as blocks added to page areas.
First of all, don't do what I tried in the last post -- creating an area in the template and assigning the block to it. Just leave the template like you originally had it.
Next go to line 206 in concrete\startup\process.php. The hack is just to handle the case of an empty 'arHandle' there. Change the code to this:
case 'passthru': if (isset($_GET['bID']) && isset($_GET['arHandle'])) { if (empty($_GET['arHandle'])) { $b = Block::getByID($_GET['bID']); } else { $a = Area::get($c, $_GET['arHandle']); $b = Block::getByID($_GET['bID'], $c, $a); } // basically, we hand off the current request to the block // which handles permissions and everything $p = new Permissions($b); if ($p->canRead()) { $action = $b->passThruBlock($_REQUEST['method']); } }
Viewing 15 lines of 16 lines. View entire code block.
Maybe one of the core developers could have a look at this as a possible core modification. It seems reasonable to me that passThru calls should work from hard-coded blocks as well as blocks added to page areas.
The only issue I have in changing the core is I have to remember to do it again if I update (I think this is correct?) C5 to a newer version.
I have made 3 sites with C5 and am not a php programmer, although I am comfortable with modifying code. So I really appreciate your looking into this. It would have taken me many days to figure this out.
I have made 3 sites with C5 and am not a php programmer, although I am comfortable with modifying code. So I really appreciate your looking into this. It would have taken me many days to figure this out.
I just made the changes to process.php as you suggested and it is working perfectly.
Thanks again.
Thanks again.
I spoke too soon. It is only working if I am logged in. If I log out of the website I get no results...
I should have tried that too.. my bad!
I don't see why it's necessary to have the permissions checked for a hard-coded block (i.e. empty arHandle) -- so it could be done like this instead:
It works now, whether you're logged in or not. I can't say whether it's a security risk or not.
I don't see why it's necessary to have the permissions checked for a hard-coded block (i.e. empty arHandle) -- so it could be done like this instead:
case 'passthru': if (isset($_GET['bID']) && isset($_GET['arHandle'])) { // Assuming if arHandle is empty the block is hard-coded // so permissions check not necessary. Security risk? if (empty($_GET['arHandle'])) { $b = Block::getByID($_GET['bID']); $action = $b->passThruBlock($_REQUEST['method']); } else { $a = Area::get($c, $_GET['arHandle']); $b = Block::getByID($_GET['bID'], $c, $a); // basically, we hand off the current request to the block // which handles permissions and everything $p = new Permissions($b); if ($p->canRead()) { $action = $b->passThruBlock($_REQUEST['method']);
Viewing 15 lines of 18 lines. View entire code block.
It works now, whether you're logged in or not. I can't say whether it's a security risk or not.
I forgot to follow up - the code works! I think next time I will just put a link in the template that takes the visitor to a signup page so I will bypass the problem, and I can provide more information. I wanted to do it like this to make it quick and simple.
Thanks.
Thanks.
Unfortunately that doesn't work in conjunction with the Ajax Forms addon :(
I'd rather avoid modifying the core so I have another solution. You can request the block from any page id to be used in an area, so you can make a pseudo global block like so:
With this you can add the form to your root page in working condition, and it will remain updated on all other pages.
<?php $pseudo_global_block = Page::getByID(1, "ACTIVE"); $gArea = new Area('Pseudo Global Area'); $gArea->display($pseudo_global_block); ?>
With this you can add the form to your root page in working condition, and it will remain updated on all other pages.
I created a bug entry for this.
http://www.concrete5.org/developers/bugs/5-4-1-1/forms-in-global-sc...
Please confirm the bug, so that this issue get's fixed very soon in concrete5's core.
http://www.concrete5.org/developers/bugs/5-4-1-1/forms-in-global-sc...
Please confirm the bug, so that this issue get's fixed very soon in concrete5's core.
Thanks.