To stop form submit on every refresh after one submit in codeigniter - forms

After form submission , any number of refresh is storing the data that many times in the db.
ie. !empty($_POST) is always true after on submission.
How can I stop the submission without redirecting the page/url. As I want to stay in the same page.
I am using form_open() and form_submit() i codeigniter.
in view
<?php echo form_open("",array('method' => 'POST'));?>
/* form fields */
'Send', 'value' => 'Send Notifications',"name"=>"send_notification")); ?>
in controller
`if (!empty($_POST['send_notification'])) {
/* validation rules & data*/
if ($this->form_validation->run() == TRUE){
$this->model->insert($data);
}
}`
How can I stop the duplicate record insertion, I have tried , unset($_POST) , isset() , if($this->input->post()) , nothing seems to work.

Just do a redirect(); to the same age after the insert function.

This worked for me. It may help someone
Controller file :
public function success()
{
$_SESSION['txnid'] = $this->input->post('txnid');
$this->bind->set_order();
$this->load->view('success');
}
Model file :
public function set_order()
{
$txnid = $_SESSION['txnid'];
$qry = $this->db->query("SELECT * from orders where transaction_id = '$txnid'");
$result = $qry->result_array();
if($qry->num_rows() == 0 )
{
//add to database here
}
else
{
// do nothing
}
}
I am adding txnid to database on submit. So if it tries to resubmit, it checks if txnid already exist or not.

Related

Symfony2 form submit invalid boolean value

I have a strange problem with Symfony (v 2.3.2) form. It's very simple form without relations. I should also noted that this form is used in REST API only.
So I have a published field (boolean). On the entity it's set to false by default.
On update, the REST API client sends PUT request which is correct aka ...&[entity]published=0&.... This value is also shown in Symfony profiler in the form parameters.
However I've noticed that the actual value in database is set to true (or 1 as it's tinyint).
So, to find out what's the problem, I added throw statement after $form->submit($request);
throw new \Exception(sprintf('Request: %s, form: %s', $request->get('entity')['published'], $form->get('published')->getData()));
or
throw new \Exception(sprintf('Request: %s, form: %s', $request->get('entity')['published'], $form->getData()->getPublished()));
The exception message says: Request: 0, form: 1. It means that somewhere in submit method the string value '0' is converted to 1.
The field is constructed with $builder->add('published', 'checkbox', [ 'required' => false ])
Also I've noticed strange thing, which may be related. On the Symfony profiler, panel request, I'm getting error: Warning: json_encode(): Invalid UTF-8 sequence in classes.php line 3758, I'm not sending any strange characters - just word "test".
You shouldn't use a checkbox form type in your API, 0 doesn't mean false.
You should implement a new boolean form type which transform 1, '1' and true to true, and everything else to false (for example).
Here is an example: https://gist.github.com/fsevestre/abfefe0b66e5f5b24c60
Further investigation revealed that typical HTML form checkbox is only sent to server when it's checked. So I presume that sending value set to 0|false|off would make it work as if it would be set to true.
Therefore, if you set your form widget to type checkbox, do not send checkbox in your request if you want it to be set to false. In my case it would look like this:
Array
(
[entity] => Array
(
[id] => 73
[_token] => d63dad39ea458f7d3c7ae5dbea10c325cb9ee93d
)
)
otherwise send anything, 0, false, off will work too
Array
(
[entity] => Array
(
[id] => 73
[published] => 1|0|false|on|off
[_token] => d63dad39ea458f7d3c7ae5dbea10c325cb9ee93d
)
)
When using PUT this happened to be a bit problematic...
I solved it by adding a subscriber to all of my forms that solve this issue(this code is also solving the issue of using PUT without filling all the data):
class RestFormSubscriber implements EventSubscriberInterface {
/**
* {#inheritdoc}
*/
public static function getSubscribedEvents()
{
return array(FormEvents::PRE_SUBMIT => "preSubmit");
}
/**
* Remove null fields on update
* Fixes boolean value
* #param FormEvent $event
*/
public function preSubmit(FormEvent $event)
{
$form = $event->getForm();
$data = $event->getData();
$isPUT = strtoupper($form->getConfig()->getMethod()) == "PUT";
$accessor = PropertyAccess::createPropertyAccessor();
foreach ($form->all() as $name => $child) {
if ($isPUT && !isset($data[$name])) {
$form->remove($name);
continue;
}
if(is_bool($accessor->getValue($form->getData(), $name))) {
$val = $data[$name];
$data[$name] = ($val=="true")||($val=="1")||($val=="on");
}
}
$event->setData($data);
}
}

symfony 1.4 forms - how to set value of one field while submiting the form?

how can I do this?
I'm trying:
$this->form->getObject()->setWebsiteid($website);
$this->form->setDefault('websiteid', $website);
$request->setParameter('websiteid', $website);
none from above doesn't work
my code:
$this->form = new sfGuardRegisterForm();
if ($request->isMethod('post'))
{
$website=new Website();
$website->save();
$this->form->bind($request->getParameter($this->form->getName()));
if ($this->form->isValid())
{
/* here I try do that */
$this->form->getObject()->setWebsiteid($website);
/* here I try do that end */
$user = $this->form->save();
$this->getUser()->signIn($user);
$this->redirect('#homepage');
}
}
Is websiteid part of your User model ?
Do you use the widget of websiteid in your form ?
You can add the value after the save:
$user = $this->form->save();
$user->setWebsiteid($website);
$user->save();
But the first solution seems ok to me..

Need Help with Zend Form dropdown menu validation

I'm working on a zend framework project and I needed the user to select school and then it goes to the next form then select the grade.
Eg User select ABC High School and then select "Grade 8"
Both School and Grade dropdown menu is soft coded fetching the data from the database.
My problem is that when the user selected a school and then on the next grade form if they don't select any values and click onto "submit" it return a validation error "Value is required and can't be empty" which is correct but the dropdown menu then goes empty.
I wanted to know how to repopulate the values back to the grade dropdown menu if the form doesn't validate.
Thanks so much
Here is my code
Here is the function i generate the grade values (Fetching from the database)
public function processSchoolSelectionAction()
{
$form = $this->getSchoolSelectionForm();
if ($form->isValid($_POST))
{
// getting the values
$schoolId = $form->getValue('school');
$schoolYear = new Application_Model_DbTable_SchoolYear();
$schoolYearValues = $schoolYear->getYearValues($schoolId);
array_unshift($schoolYearValues, array ('key' =>'' , 'value' =>'Please Specify'));
$form = $this->getYearSelectionForm();
$form->year->addMultiOptions($schoolYearValues);
$form->schoolId->setValue($schoolId);
$this->view->form = $form;
}
else
{
$data = $form->getValues();
$form->populate($data);
$this->view->form = $form;
}
}
Code processing the year selection form
public function processYearSelectionAction()
{
$form = $this->getYearSelectionForm();
if ($form->isValid($_POST))
{
// getting the values
$schoolId = $form->getValue('schoolId');
$yearId = $form->getValue('year');
$textbookList = new Application_Model_DbTable_TextbookList();
if ($textbookList->checkTextbookExist($schoolId, $yearId))
{ // check if textbookExist
}
else
{
$this->view->message = "Sorry, But the list you requested is currently not available for ordering online.";
}
}
else
{
$data = $form->getValues();
$form->populate($data);
$this->view->form = $form;
}
}
School selection form
<?php
class Application_Form_SchoolSelection extends ZendX_JQuery_Form
{
public function init()
{
$this->setName('schoolSelection');
$school = new Application_Model_DbTable_School;
$schoolValues = $school->getSchoolValues();
array_unshift($schoolValues, array ('key' =>'' , 'value' =>'Please Specify'));
$schoolElement = new Zend_Form_Element_Select('school');
$schoolElement->addMultiOptions($schoolValues);
$schoolElement->setLabel('School');
$schoolElement->setRequired(true);
$schoolElement->setRegisterInArrayValidator(false);
$submitElement = new Zend_Form_Element_Submit('submit');
$submitElement->setLabel("Next");
$this->addElements(array(
$schoolElement,
$submitElement
));
}
}
?>
Grade (Year) selection form
<?php
class Application_Form_YearSelection extends ZendX_JQuery_Form
{
public function init()
{
$this->setName('yearSelection');
$yearElement = new Zend_Form_Element_Select('year');
$yearElement->setLabel('Year');
$yearElement->setRequired(true);
$yearElement->setRegisterInArrayValidator(false);
$schoolIdElement = new Zend_Form_Element_Hidden('schoolId');
$submitElement = new Zend_Form_Element_Submit('submit');
$submitElement->setLabel("Next");
$this->addElements(array(
$yearElement,
$schoolIdElement,
$submitElement
));
}
}
?>
This is how I done that:
In Controller when form is creating, pass data from request:
$some_selected_data = $this->_getParam('param_from_request'); // you need to validate this
$form = new Application_Form_SchoolSelection( array('some_data' => $some_selected_data) );
Then, in Form Class get that value like this:
$data = $this->getAttrib('some_data'); // the key value of array above
and just ask
if($data) {
// get value from DB and
//SET VALUE TO Zend_Form_Element
}
Obviously, you need to repopulate the options of your Select field.
In your processYearSelectionAction, on the validation failure part just grab the schoolId you stored in the hidden field and use it the same way as you did in your processSchoolSelectionAction to populate your field options.

Symfony: question about the form filters

In the frontend I have a page with a list and a form filter next to it
that shows all the users of a social network.
I would like to hide the user of the session in that list. How can I
do it?
My first thought is creating a function, addXXXXColumnQuery(), for each
field of the form, and in each one add a line like this:
->andWhere("u.id <> ?", $id)
$id being the ID of the user of the current session. But in that way I
find I'm repeating myself.
What should I do?
First, you need to get the user into the filter. You have two options:
Pass the user_id in as an option when you instantiate the form, inside the action:
public function executeList(sfWebRequest $request)
{
$user_id = $this->getUser()->getUserId();
$filter = new ModelFormFilter(array(), array('user_id' => $user_id));
...
Get the user id from the context inside of the form:
sfContext::getInstance()->getUser()->getUserId();
I prefer the former method because it's cleaner and less WTFy.
Once you have the user id, override doBuildQuery to exclude the current user id inside of your FormFilter:
protected function doBuildQuery(array $values)
{
$query = parent::doBuildQuery($values);
$user_id = $this->getOption('user_id'); //or off the context here
if ($user_id)
{
$query->addWhere('r.user_id != ?', $user_id);
}
return $query;
}

Drupal 6: Modifying uid of a submitted node

I have a situation where I want a set of users (employees) to be able to create a node, but to replace the uid (user ID) with that of the users profile currently displayed.
In other words, I have a block that that calls a form for a content type. If an employee (uid = 20) goes to a clients page (uid =105), and fills out the form, I want the uid associated with the form to be the client's(105), not the employee's.
I'm using arg(1) to grab the Client's uid - here is what I have..
<?php
function addSR_form_service_request_node_form_alter(&$form, $form_state) {
if (arg(0) == 'user' && is_numeric(arg(1))) {
$form['#submit'][] = 'addSR_submit_function';
}
}
function addSR_submit_function($form, $form_state) {
$account = user_load(arg(1));
$form_state['values']['uid'] = $account->uid;
$form_state['values']['name'] = $account->name;
}
?>
The form is loading in the block, but when submitted, is still showing the employee uid. I don't want to use hook_form_alter because I don't want to modify the actual form, because clients can fill out the form directly, in this case, I don't want to modify the form at all.
I'm also ashamed that I'm putting this in a block, but I couldn't think of a way to put this in a module, so any suggestions on that would also be appreciated...
To create your form in a block, you could use the formblock module. Especially if you are not used to use the Drupal API. Then all that's left if to add your own submit handler to the form. This is a piece of code that is run, when the form is submitted. You only want to do this on clients pages so you would do that using the hook_form_alter function.
/**
* Hooks are placed in your module and are named modulename_hookname().
* So if a made a module that I called pony (the folder would then be called
* pony and it would need a pony.info and pony.module file I would create this function
*/
function pony_form_service_request_node_form_alter(&$form, $form_state) {
// Only affect the form, if it is submitted on the client/id url
if (arg(0) == 'client' && is_numeric(arg(1))) {
$form['#submit'][] = 'pony_my_own_submit_function';
}
}
function pony_my_own_submit_function($form, &$form_state) {
$account = user_load(arg(1));
$form_state['values']['uid'] = $account->uid;
$form_state['values']['name'] = $account->name;
}
The idea behind this code, is to only alter the form when the condition is met - that it is submitted on a client page. I guessed that the arg(0) would be client so if it's something else you would need to change that of cause. We only need to add a submit function, since what we want is to change the values if the form has passed validation.
Then if that is the case our 2nd function is run, which does that actual alteration of the values.
PHP blocks are bad. You can put them in a module.
function hook_block($op, $delta = 0) {
// Fill in $op = 'list';
if ($op == 'view' && $delta = 'whatever') {
$account = user_load(arg(1));
$node = array('uid' => $account->uid, 'name' => $account->name, 'type' => 'service_request', 'language' => '', '_service_request_client' => $account->uid);
$output = drupal_get_form('service_request_node_form', $node);
// Return properly formatted array.
}
}
Additionally, you want a form_alter just to enforce the values. It's ugly but it works.
function hook_form_service_request_node_form_alter(&$form, $form_state) {
if (isset($form_state['node']['_service_request_client'])) {
$form['buttons']['submit']['#submit'] = array('yourmodule_node_form_submit', 'node_form_submit');
}
}
function yourmodule_node_form_submit($form, &$form_state) {
$account = user_load($form_state['node']['_service_request_cilent'])l
$form_state['values']['uid'] = $account->uid;
$form_state['values']['name'] = $account->name;
}