CakePHP - edit loses URL variable when trying validation fails on save - php

User starts here:
/admin/cuisines/edit/16
User types something in that is against validation rules and clicks Submit. User is taken here:
/admin/cuisines/edit/16
User thinks it IS valid and clicks submit again - they're then taken here:
/admin/cuisines/edit/
User corrects their mistake, clicks submit, and instead of an edit, it saves this as a new item in the table, since there's no id.
My code:
function admin_edit($id = null) { // EDIT ***********
if (!$id && empty($this->data)) {
$this->Session->setFlash(__('Invalid cuisine', true));
$this->redirect(array('action' => 'index'));
}
if (!empty($this->data)) {
if ($this->Cuisine->save($this->data)) {
$this->Session->setFlash(__('The edits to this cuisine have been saved', true));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The edits to this cuisine could not be saved. Please, try again.', true));
}
}
if (empty($this->data)) {
$this->data = $this->Cuisine->read(null, $id);
}
}
Any thoughts on what I'm doing wrong? I thought I did it just like the tutorial, but - I would have to guess Cake is smart enough to not let this happen - ie - my assumption is I'm doing something wrong.

To avoid the saving of new items when the edit form is submitted, make sure that a form field for the id is present.
<?php echo $this->Form->input('id'); ?>
This field will be hidden automatically because it is the models primary key.
Also check the form action attribute in the HTML. I sometimes have to set it manually to avoid it being wrong.
<?php echo $this->Form->create('Cuisine', array(
'url' => array(
'action' => 'edit',
$this->Form->value('id')
)
)); ?>

Related

Update existing record in CakePHP

I want to create the following in CakePHP:
Starting page: User enters a loginname which pre exists in the DB. Table name loginname.
Once the user has entered the right loginname, the user continues to the registration form, where the user can add personal data to the existing record.
When the user saves the form, the record with only the loginname has personal data added.
This is what i have:
Logic for starting page:
public function checkCodeRespondent() {
//set var
$password = $this->data['Respondent']['loginname'];
//set condition for hasAny function
$condition = array('Respondent.loginname'=>$password);
//if password matches continue to registreer
if($this->Respondent->hasAny($condition)){
//find data by password
$respondent = $this->findByPass($password);
//set var for current id
$id= $respondent['Respondent']['id'];
//redirect with current id
$this->redirect(array('action' => 'aanmelden', $id));
} else {
//if password does not match, return to index with errormessage
$this->redirect(array('action' => 'index'));
}
}
public function findByPass($pass) {
$respondent = $this->Respondent->find('first', array('conditions' => array('pass' => $pass)));
return $respondent;
}
And this is the logic for saving the data to the record:
public function registreren() {
if($this->request->isPost()) {
$this->Respondent->id = $id;
if ($this->Respondent->save($this->request->data)){
$this->Flash->success(__('Your post has been saved.'));
return $this->redirect(array('action' => 'index'));
} else {
}
}
I thought i got my id through the function checkCodeRespondent() , but that's not working. What am i forgetting or what am i doing wrong? If i need to give more info, i'm happy to help ofcourse.
Update: I read that i need to add echo $form->input('id');, only when i debug($this->request); the id value is empty. What do i need to change in my code?
If you have added hidden field for id then just replace:
$this->Respondent->id = $id;
By:
$this->Respondent->id = $this->request->data['Respondent']['id'];
And in your view, give name="data[Respondent][id]" in the hidden field of id like:
<input type="hidden" name="data[Respondent][id]" value="value of id">
that should work fine for you if no other issues out there.

CakePHP saving foreignKeys not working

I have 3 tables: Computers hasMany Brands, Brands belongsTo Computers and Parts. Now i have these fields in my Brands description,computer_id,part_id. I have the code below to save my data. It will save the description and part_id....But my computer_id does not save at all.
Usually my URL written http://192.168.6.253/computers/brands/add/1 where 1 is computer_id.
How will I save it? Im still beginner in this framework
Controller
public function add($id = null) {
if (!$id) {
throw new NotFoundException(__('Invalid post'));
}
//Assign value to link computer_id
$data = $this->Brand->Computer->findById($id);
$this->set('computers', $data);
//assign select values to parts select
$this->set('parts', $this->Brand->Part->find('list',
array('fields' => array('description'))));
if ($this->request->is('post')) {
$this->Brand->create();
if ($this->Brand->save($this->request->data)) {
$this->Session->setFlash(__('Your post has been saved.'));
$this->redirect(array('action' => 'table/'.$id));
} else {
$this->Session->setFlash(__('Unable to add your post.'));
}
}
}
View
<?php
echo $this->Form->create('Brand');
echo $this->Form->input('part_id',array('empty'=>' '));
echo $this->Form->input('description');
echo $this->Form->input('computer_id',array('type'=>hidden));
echo $this->Form->end('Save Post');
?>
If you are not requiring to send the computer id through the form since it's a url param... you can adjust your add function like this
if ($this->request->is('post')) {
$this->request->data['Brand']['computer_id'] = $id; //manually add the id to the request data object
$this->Brand->create();
if ($this->Brand->save($this->request->data)) {
$this->Session->setFlash(__('Your post has been saved.'));
$this->redirect(array('action' => 'table/'.$id));
} else {
$this->Session->setFlash(__('Unable to add your post.'));
}
}
That's a very basic way of doing it without checking for data integrity, anyone could easily change the param to a 2, but it conforms with your current setup.

cakephp $this->User->save($this->data) error on edit function of a logged user

I am trying to create the "edit" profile page for a logged user in cakephp. This would be the function to add/edit information about the user.
I get an error during the $this->User->save($this->data) function and I don't understand what is the problem.
public function edit() {
$this->User->id = $this->Auth->User('id');
if ($this->request->is('post')) {
if ($this->User->save($this->data)) {
$this->Session->setFlash(__('The user has been saved'), 'flash_success');
// $this->redirect($this->Auth->redirect());
} else {
var_dump($this->invalidFields());
$this->Session->setFlash(__('The user could not be saved. Please, try again.'), 'flash_failure');
}
} else {
//autocompleto il form
$this->data = $this->User->read(null, $this->Auth->User('id'));
}
}
The view is:
<?php
echo $this->Form->create('User',array('action' => 'edit'));
echo $this->Form->input('name', array('label'=> 'Name'));
echo $this->Form->input('surname', array('label'=> 'Surname'));
echo $this->Form->input('id', array('type'=> 'hidden'));
echo $this->Form->end(__('Submit'));
?>
I see you use Auth component. If your Auth::authorize default value is overridden ensure that you give user proper rights to perform data writing (maybe he only allowed to read).
Another issue could be your $validate declaration in model, where you force user to enter field value (using 'required' = true) but actually this field is not even displayed on View. You could avoid this validation rule on data edit if 'on' => 'create' is defined inside.
Also I would recommend use CakePHP debug() instead of var_dump() for debugging purpose.

CakePHP passing id to edit form

I've noticed that their is many different ways to pass an ID to a form when editing a database entry. So for example for a edit user profile form I have the following code:
function edit($id = null)
{
$this->layout = 'page';
// this line isn't needed?
//$this->User->id = $id;
if (empty($this->data))
{
$this->data = $this->User->read();
}
else
{
if ($this->User->save($this->data))
{
$this->Session->setFlash('Your profile has been updated', 'flash', array('header' => 'Announcement', 'myclass' => 'success'));
$this->redirect(array('controller' => 'users', 'action' => 'view', $id));
}
}
}
Now the function expects an id passing in the url e.g. /users/edit/2 But let's say I wanted it to be something more user friendly like /profile/edit (rewrote by routing) I would no longer be passing in the ID as part of the url. As you can see in my code I have a line I have commented out because it isn't needed?
Also in the form I ALSO Need <?php echo $this->Form->input('id', array('type' => 'hidden')); ?> why?
Basically this is more of what are the options available to me to build various types of edit forms and passing data to the form. And what is the need for the hidden field in the form if the data is being passed either via the URL or some other way
I've also noticed on some sites that they have things like Form Keys and the username stored in meta tags in the page header???
EDIT:
public function beforeFilter()
{
$this->set('authUser', $this->Auth->user());
//
$user = $this->Auth->user();
if (!empty($user))
{
Configure::write('User', $user[$this->Auth->getModel()->alias]);
}
}
public function beforeRender()
{
$user = $this->Auth->user();
if (!empty($user))
{
$user = $user[$this->Auth->getModel()->alias];
}
$this->set(compact('user'));
}
// NEW VERSION
function settings()
{
$this->layout = 'page';
$this->set('title_for_layout', 'Edit Profile');
$this->User->id = $user['id'];
if (empty($this->data))
{
$this->data = $this->User->read();
}
else
{
if ($this->User->save($this->data))
{
$this->Session->setFlash('Your settings have been updated', 'flash', array('myclass' => 'success'));
$this->redirect(array('controller' => 'users', 'action' => 'settings'));
}
}
}
Also in the form I ALSO Need Form->input('id',
array('type' => 'hidden')); ?> why?
Having the id hidden in the form removes the need for your controller action to grab the $id from the uri (aka passed as parameter). When in the form, it will automatically be placed into your $data array.
what is the need for the hidden field
in the form if the data is being
passed either via the URL or some
other way
It's not needed in the form if it's available from the uri. You'd simply grab the $id and assign it to the User model (as the commented out code does).
let's say I wanted it to be something
more user friendly like /profile/edit
I assume that would be when the user is editing his own profile. In that case, your system should be able to retrieve the user's id via the session.

CakePHP Validation Question with Plugin

In my CakePHP application, I have setup the PersistantValidation plugin to validate my forms on the model level thanks to a kind previous suggestion. The plugin essentially makes it so that you can use model validation on a partial without having it redirect to the underlying page (ie. the register.ctp view or the login.ctp view, for example).
The validation works great for the login form, but it's not working properly on the user registration form for some reason.
The controller looks like this:
function register() {
if(!empty($this->data)) {
$name = $this->data['User']['name'];
$email = $this->data['User']['email'];
$password = $this->Password->generatePassword();
$this->data['User']['password'] = $this->Auth->password($password);
$this->User->create();
if($this->User->save($this->data)) {
$this->Session->setFlash(__('Your account has been created!', true));
$this->redirect(array('controller' => 'users', 'action' => 'offers'));
} else {
$this->redirect($this->referer());
}
}
}
The PresistentValidation component is also properly setup and included, since it works just fine in the login() function in the same controller. When I run this code, nothing happens. There is no redirect away from the partial, which is good, but the errors don't show up. Also, the errors do show up going to the register.ctp view, which means it isn't a problem with the validations themselves.
Does anyone have any ideas?
function register() {
if(!empty($this->data)) {
$this->data['User']['password'] = $this->Auth->password($password);
if($this->User->save($this->data)) {
$this->Session->setFlash(__('Your account has been created!', true));
$this->redirect(array('controller' => 'users', 'action' => 'offers'));
} else {
$this->redirect($this->referer());
}
}
}

Categories