cakephp edit form with file type not overidding http with put and post occurs twice with empty data - forms

First off I'm new to cakephp.... I'm pulling survey questions from a database and building a form of type=file.
echo $this->Form->create('PersonalDetail', array('type' => 'file', 'id' => 'editProfileForm', 'class' => 'form-horizontal'));
echo $this->Form->hidden('id');
echo $this->Form->hidden('PersonalDetail.id');
echo $this->Form->input('PersonalDetail.field_name', array('label' => false, 'div' => false, 'readonly' => false));
echo $this->Form->submit('Update Profile', array('class' => 'btn btn-primary', 'id' => 'editProfileSubmitBtn'));
echo $this->Form->end();
According to cakephp docs "Since this is an edit form, a hidden input field is generated to override the default HTTP method." But I can't seem to figure out how to tell cake this is an edit form. It always inserts a hidden POST not PUT method:
<form action="/editForm" id="editProfileForm" class="form-horizontal" enctype="multipart/form-data" method="post" accept-charset="utf-8">
<div style="display:none;">
<input type="hidden" name="_method" value="POST"/>
<input type="hidden" name="data[_Token][key]" value="ff8b198e82d800a35581" id="Token836"/></div>
<input type="hidden" name="data[id]" id="id"/>
<input type="hidden" name="data[PersonalDetail][id]" id="PersonalDetailsId"/>
<label class="control-label required">Username</label>
<input name="data[PersonalDetail][field_name]" maxlength="255" type="text" id="PersonalDetailsFieldName"/>
<input class="btn btn-primary" id="editProfileSubmitBtn" type="submit" value="Update Profile"/>
<div style="display:none;">
<input type="hidden" name="data[_Token][fields]" value="a2f722badf82c0d8991ab8%3APersonalDetail.id%7Cid" id="TokenField020"/> <input type="hidden" name="data[_Token][unlocked]" value="" id="TokenUnlocked1562820470"/> </div></form>
The problem is when I submit the form and watch with Firefox's Tamper Data the form posts the data fine, but then it posts again immediately again with all the data missing.
On a working form example, I see the same behaviour, except the hidden input field is "PUT" and when the form submits, it is first a PUT with data, then the immediate second submission is with the POST with data instead of begin blank.
I assume I'm missing something basic here, but I'm really confused.
Here's the controller where PersonalForm is a database of questions passed to an element that builds the forms. PersonalDetail is supposed contain the answers but for this first time this is run the user won't have any answers.
public function editForm() {
$userId = $this->UserAuth->getUserId();
if (!empty($userId)) {
$user_account_type = $this->UserDetail->read('account_type', $userId);
$user_account_type = $user_account_type['UserDetail']['account_type'];
$this->set('user_acct_type', $user_account_type);
$this->loadModel('Usermgmt.PersonalForm');
$forms = $this->PersonalForm->find('all');
$this->set('forms', $forms);
if ($this->request->isPut() || $this->request->isPost()) {
//put in ajax verification
//$this->PersonalDetail->saveAssociated($this->request->data);
$this->Session->setFlash(__('Your answers have been successfully updated'));
$this->redirect('/dashboard');
} else {
// read user's original responses and populate form
$this->loadModel('Usermgmt.PersonalDetail');
$answers = $this->PersonalDetail->read(null, $userId);
$this->request->data = null;
if (!empty($answers)) {
$this->request->data = $answers;
}
}
} else {
$this->redirect('/dashboard');
}
}
I'm using cakephp 2.3.7 and I'm running the debugKit plugin (maybe causing more than one submission? I don't know.) Edit: Also I'm using UserAuth and Security modules.
EDIT: I oversimplified the example when I removed the hidden id fields. Now I included the two hidden input elements. However the first time this form is loaded there is no edit data so it is a create instead of add case. So I don't understand why it is posting twice and losing the data on the second post. Perhaps that is the real problem and not that it should be PUT vs POST? I'm obviously missing something fundamental in how cake is processing the post data.
Perhaps I should mention this is form is part of a plugin. Could the routing have something to do with the loss of data and the second post?

You are missing the vital part of an edit form, the id:
echo $this->Form->input('id');
Without its presence cake assumes that this is not an update (edit), but a create (add).
Also mind your casing, its not $this->Form->Submit() but $this->Form->submit().
EDIT:
At second look: I also guess that you violated more than 5 other conventions, including the most important one: Models are singular, Controllers plural. Meaning:
$this->Form->create('PersonalDetail');
If your model is PersonalDetail (which from your controller code it looks like).
This would explain why the data doesnt end up where it is supposed to.
Again my recommendation: Bake your code to see how its done.

It appears this is related to a security module problem.
I was able to prevent the double empty data posts by adding the following to the beforeFilter:
if (isset($this->Security) && ($this->RequestHandler->isAjax() || $this->action == 'editForm')) {
$this->Security->csrfCheck = false;
$this->Security->validatePost = false;
}
Now I need to research the reasons for this security problem with my form to fix it.

Related

How can I do automatic validation email laravel?

I use laravel 5.3
My view blade like this :
<form id="form-register" role="form" method="POST" action="{{ url('/register') }}">
...
<div class="{{$errors->has('email')?'form-group has-error': 'form-group'}}">
{{Form::label('email', 'Email'), ['class' => 'control-label'])}}
{{Form::email('email', old('email'), ['class' => 'form-control', 'id' => 'email')}}
#if ($errors->has('email'))
<span class="error error-server help-block">Please Enter Your Valid Email</span>
#endif
</div>
...
</form>
My validation like this :
public function rules()
{
return [
...
'email' => 'required|email|max:255|unique:users'
];
}
It works
If I enter an email that is already in the database table, then I submit, it will appear message validation email invalid
But I want to change it to automatic validation
So if the user inputs an existing email in the database table, it will automatically appear message validation email invalid
How can I do that?
on your input changes, you need to send an Ajax request to the backend, this request will reach an API that will check the existing of the requested email.
If I understand you correctly you want to display the exact error message returned by Validator for email field
You can get the first error message returned for email by call this $errors->first('email')
Here is an example
#if ($errors->has('email'))
<span class="error error-server help-block">{{$errors->first('email')}}</span>
#endif

Symfony 2 This form should not contain extra fields

I created a form using formBuilder in Symfony. I add some basic styling to the form inputs using an external stylesheet and referencing the tag id. The form renders correctly and processes information correctly.
However, it outputs an unwanted unordered list with a list item containing the following text: This form should not contain extra fields.
I am having a really hard time getting rid of this notice. I was wondering if someone can help me understand why it being rendered with my form and how to remove it?
Many thanks in advance!
Controller
$form = $this->createFormBuilder($search)
->add('searchinput', 'text', array('label'=>false, 'required' =>false))
->add('search', 'submit')
->getForm();
$form->handleRequest($request);
Twig Output (form is outputted and processed correctly
This form should not contain extra fields.
Rendered HTML
<form method="post" action="">
<div id="form">
<ul>
<li>This form should not contain extra fields.</li>
</ul>
<div>
<input type="text" id="form_searchinput" name="form[searchinput]" />
</div>
<div>
<button type="submit" id="form_search" name="form[search]">Search</button>
</div>
<input type="hidden" id="form__token" name="form[_token]" value="bb342d7ef928e984713d8cf3eda9a63440f973f2" />
</div>
</form>
It seems to me that you have the problem because of the token field. If it is so, try to add options to createFormBuilder():
$this->createFormBuilder($search, array(
'csrf_protection' => true,
'csrf_field_name' => '_token',
))
->add('searchinput', 'text', array('label'=>false, 'required' =>false))
->add('search', 'submit')
->getForm();
To find out the extra field use this code in controller, where you get the request:
$data = $request->request->all();
print("REQUEST DATA<br/>");
foreach ($data as $k => $d) {
print("$k: <pre>"); print_r($d); print("</pre>");
}
$children = $form->all();
print("<br/>FORM CHILDREN<br/>");
foreach ($children as $ch) {
print($ch->getName() . "<br/>");
}
$data = array_diff_key($data, $children);
//$data contains now extra fields
print("<br/>DIFF DATA<br/>");
foreach ($data as $k => $d) {
print("$k: <pre>"); print_r($d); print("</pre>");
}
$form->bind($data);
This message is also possible if you added/changed fields in your createFormBuilder() and press refresh in your browser...
In this case it's ok after sending the form again ;-)
I got the same message while having multiple forms on the same page. Turns out, symfony defaults to the name 'form' for all of them. Instead of using createFormBuilder, you can change the name of the form to avoid conflicts using
public FormBuilderInterface createNamedBuilder(string $name, string|FormTypeInterface $type = 'form', mixed $data = null, array $options = array(), FormBuilderInterface $parent = null)
See https://stackoverflow.com/a/13366086/1025437 for an example.
I ran into this error when creating a multi-step form.
When the step 1 form is submitted, $request->request contains acme_mybundle_myform array. This created a validation error and stopped the back, forward and form fields from populating correctly. Not to mention "this-form-should-not-contain-extra-fields"
I discovered this thanks to the code by nni6.
The solution in my case was inside the controller:
if ($form->isValid())
{
if($form->has('nextStep') && $form->get('nextStep')->isClicked())
{
$session->getFlashBag()->set('notice', 'Next clicked');
$registerType->incrementStep();
$request->request->remove('acme_mybundle_myform');
return $this->forward("AcmeMyBundle:Default:register", array($request));
}
....
}
I had the same error.
It was because I had a form which, by mistake, had a NULL name.
In the HTML, the name attribute would look like this:
<form name href="..." action"..."></form>
As simple as that.
Might not be the case for everyone, but worth to check.

Why is CakePHP 2.3.0 adding a '1' to my Form Post Values?

I'm using cakephp 2.3.0. I searched in the manual for quite awhile, but I haven't found the answer. Also, I've searched the Internet, but still haven't found what I'm looking for. SO, I'm posting my question here. Note, I'm fairly new to cakephp.
Scenario:
I have a simple form with two fields: activity and zip code.
I'm using POST on the form.
When I type in some value in those fields and submit, I echo those 'post' values/parameters and display in the browser screen. What I typed in, I can see on the screen, but the number '1' is added to the end of what I typed in the form.
Here is an example. I type in these values in the form, 'walk' and '44555'. Then I click 'Submit'. The post goes to my controller's action, which then calls my view. My view is displayed on the browser screen and I echo out those 'post' values. The results on screen are 'walk1' and '445551'.
Example #2: If I follow the steps above and don't enter any values in my form (I'll add error checking later), what I see on the browser screen is '1' and '1'.
I am unable to figure out why I am getting the value of '1' added to my form's POST values?
I'll be glad to include any other additional php code to this posting, if requested by someone trying to help.
Here is my FORM code (from my view)...I know there are DIV helpers, but I'll get to that later:
echo $this->Form->create(null, array('url' => array('controller'=>'activities', 'action'=>'results'))); ?>
<div class="box1" style="position:relative; top:10px; left:10px; float: left;">
Search here.... <br>
<hr>
<?php echo $this->Form->input('activityName', array('size'=>'30',
'label'=>'Activity Name:', 'value'=>'i.e. walking, etc.'));?>
<br>
<?php echo $this->Form->input('zip', array('size'=>'7', 'label'=>'Postal Code:')); ?>
<br>
</div>
<div class="box1" align="right">
<?php echo $this->Form->end('Go Search');?>
</div>
Here is my controller code:
<?php
class ActivitiesController extends AppController {
public $helpers = array('Html', 'Form');
public function index() {
//other code....
}
public function results() {
$this->layout = 'second';
$name = $this->request->data['Activity']['activityName'];
$pCode = $this->request->data['Activity']['zip'];
$this->set('theName', $name);
$this->set('theZip', $pCode);
$this->set('results', $this->Activity->
find('all', array('conditions' => array('name' => $name, 'postal_code' => $pCode))));
$this->set('title_for_layout', 'Results');
$this->render();
}
}
?>
My final view code. I left off some of the code...just showing the part that matters:
<div style="position:relative; top:10px; left:5px; ">
<?php echo print_r($theName); ?>
<br>
<?php echo print_r($theZip); ?>
Thanks
The 1 comes from printing the return value of print_r() which is true (i.e. 1).
In other words: you shouldn't do echo print_r(), just do print_r(). The function handles the printing by itself, you don't have to print the results manually.
(Also, print_r() is almost never the best choice to print out values except when debugging and even then CakePHP's debug() is much more suitable.)

CakePHP: allowing database update with button click

I have a product search page with the form below. The search result is displayed on the same page with search bar at the top.
echo $this->Form->create('Searches', array('action'=>'products', 'type' => 'get', 'name' => 'textbox1'));
echo $form->input($varName1, array('label' => false));
echo $form->end('Locate');
I also have a little box next to the search result that allows (it doesn't work yet) the user to flag using checkboxes a product and accordingly update its database (table products and using model Product) with a button click. Note that I have a Searches controller for this search page.
<form method="link" action="/myapp/product/test_update_db>
<label><input type="checkbox" name="flag1" <?php echo $preCheckBox1; ?>>Flag 1</input></label>
<label><input type="checkbox" name="flag2" <?php echo $preCheckBox2; ?>>Flag 2</input></label>
<input type="submit" value="Update">
</form>
I'm having difficulty with this approach figuring out how to perform this check-box-and-DB-update routine. I'm getting to the link I'd like to go (/myapp/product/test_update_db), but I don't know how to take variables flag1 and flag2, along with row ID of this result ($results['Product']['id'])) to the new page.
Could someone guide me on how to perform this neatly? Is this general approach correct? If not, what route should I be taking? I'd prefer not to use javascript at this time, if possible.
EDIT: I think I can make this work if I use the URL for passing data.. but I'd still like to know how this could be done "under the hood" or in MVC. I feel like I'm hacking at the CakePHP platform.
UPDATE: So, I ended up using the URL parameters for retrieving information pieces like flag1 and flag2. I'm still looking for an alternative method.
To see where your is-checkbox-checked data is located, do the following in your controller:
// Cake 2.0+
debug($this->request->data);
// previous versions
debug($this->data);
If you want to pass data to your search controller from the current page, you can always add the data to your form:
$this->input
(
'Product.id',
array
(
'type' => 'hidden',
'value' => $yourProductId
)
);
I ended up using information embedded in the URL for getting submission data. Something like below..
In Products controller, when the form with flag1 and flag2 are submitted:
public function test_update_db() {
// Get variables from URL, if any, and save accordingly
$result = $this->Product->updateProduct($this->params['url'], 'url');
if ($result) {
$this->Session->setFlash('Successfully updated!', 'default', array('class' => 'success'));
$this->redirect($this->referer());
}
else {
$this->Session->setFlash('Update was unsuccessful!', 'default', array('class' => 'error'));
$this->redirect($this->referer());
}
}
This works for doing what I needed to do. I feel like there's a more proper way to do this though.
if ($result) {
$this->Session->setFlash('Successfully updated!', 'default', array('class' => 'success'));
$this->redirect($this->referer());
}

Joomla 2.5 - component development - using form

I am trying to add some form to my component, but I am not shure what naming conventions must be applied to work it correctly.
Currently I have a working form - it displays fields stored in XML file and loads data from database to it. However, when i try to submit this form (edit or add new records), it doesn't work. After pressing submit (save() method) it just redirects me and displays that record was edited successfuly but it wasn't. When I try to edit existing record, after pressing submit nothing happens and when I try to add new record, it just adds empty/blank record.
So I was doing a little debug and discovered, that problem is in the JController::checkEditId() method. It always returns false which means that JControllerForm::save() returns false as well and that's why it doesn't save it correctly. HTML code of form is correct and I can access the data by using global array $_POST.
I suspect that this problem is because of naming conventions in methods loadFormData, getForm of JModelAdmin class. I am not sure how to name that form.
So here is my code related to this problem:
Subcontroller for displaying the form - controllers/slideshowform.php
class SlideshowModelSlideshowForm extends JModelAdmin{
public function getForm($data = array(), $loadData = true){
return $this->loadForm('com_slideshow.slideshowform', 'editform', array('load_data' => $loadData, 'control' => 'jform'));
}
protected function loadFormData(){
$data = JFactory::getApplication()->getUserState('com_slideshow.edit.slideshowform.data', array());
if (empty($data))
{
$data = $this->getItem();
}
return $data;
}
public function getTable($table = "biometricslideshow"){
return parent::getTable($table);
}
}
views/slideshowform/view.html.php
class SlideshowViewSlideshowForm extends JView{
public function display($tmpl = null){
if (count($errors = $this->get('Errors')))
{
JError::raiseError(500, implode('<br />', $errors));
return false;
}
$this->form = $this->get('form');
$this->item = $this->get('item');
JToolBarHelper::save('slideshowform.save');
parent::display();
}
}
views/slideshowform/tmpl/default.php
<?php
defined('_JEXEC') or die('Restricted access');
JHtml::_('behavior.tooltip');
?>
<form method="post" action="<?php echo JRoute::_("index.php?option=com_slideshow&id=".(int) $this->item->id)?>" name="adminForm" id="slideshow-form">
<fieldset class="adminform">
<legend>Edit slide</legend>
<table>
<input type="hidden" name="task" value="">
<?php echo JHtml::_('form.token'); ?>
<?php
foreach($this->form->getFieldset() as $field){
?>
<tr><td><?php echo $field->label ?></td><td><?php echo $field->input ?></td></tr>
<?php
}
?>
</table>
</fieldset>
</form>
Can someone take o look, please?
you have to add controller SlideshowControllerSlideshowForm and code save method. In there you have to validate the form data and call SlideshowModelSlideshowForm->save event, then redirect with success/failure message.