Some questions are asked more often than others. The following I have read a thousand times. Maybe it’s time for some of those to be answered in detail.
Editing own account/profile
If you want users to allow editing their own profile you usually dont want to add the user_id to the url.
Just a simple domain.com/users/edit/
.
You also want to make sure that they can only edit their own account.
Prior to Cake 2.0 (where a post finally defaults to the same url) you need to manually alter the create() method of the edit form:
<?php echo $this->Form->create('User', array('url' => '/' . $this->params['url']['url'])); ?>
This way the form doesn’t add the user_id to the url after the post.
public function edit() {
$uid = $this->Session->read('Auth.User.id');
if (!empty($this->data)) {
$this->data['User']['id'] = $uid;
if ($this->User->save($this->data, true, array('email', 'first_name', 'last_name', 'id', ...))) {
// if you rely on auth session data from the user, make sure to update that here
$this->Session->write('Auth.User.email', $this->data['User']['email']); // etc
...
// OK, redirect
} else {
// ERROR
}
} else {
$this->data = $this->User->get($uid); // this is my shortcut method - use find(first)
}
}
Using the AuthComponent the action itself cannot be accessed by guests. And logged in users have their Session Auth.User.id and can therefore access and edit only their own account. If you don’t use the Security Component you should pass along all allowed fields as third parameter to ensure that nobody can temper with your form.
I also recommend using my behavior for editing passwords in this action. It covers the issue at a central place in code without creating more overhead as absolutely necessary.
Display only the user’s own posts
Paginated:
$this->paginate = array(
'contain' => array('User'),
'conditions' => array('Post.user_id' => $this->Session->read('Auth.User.id'))
);
$posts = $this->paginate();
Normal find(all):
$options = array(
'conditions' => array('Post.user_id' => $this->Session->read('Auth.User.id')
);
$posts = $this->Post->find('all', $options);
Those code examples are from the controller action.
Default Values for forms via link
Disclaimer: Updated to 2.x syntax
When using links use query strings to set default values for forms:
// In your view ctp
$this->Html->link('Add event to this user',
array('action' => add, '?' => array('user_id' => $uid, 'date' => $dateString)));
// add action in your controller
public function add() {
if ($this->request->is('post')) {
// Validate and save
} else {
$this->request->data['Event'] = $this->request->query;
}
}
This way all your query strings are used to populate the form in case the form is requested as GET (after a normal link).
Try to avoid passed or named params for passing default values, as they should not be used in this case.
Read more about handling default values here.
Login Counter
You can use the login method of your users controller to raise the login counter after each successful login or do anything else you want to be done afterwards (setting cookie, custom redirect).
public function login($username = null) {
if (!empty($this->data)) {
if ($this->Auth->user()) {
// adjust Login +1 and LastLogin in users table with your own little method
$this->User->loginUpdate($this->Session->read('Auth.User')); # write it yourself
// maybe set cookie
// redirect if to be forwarded
$nonsense = array('/login', '/home');
$redirect = $this->Session->read('Auth.redirect');
if (!empty($redirect) && !in_array($redirect, $nonsense)) {
$this->redirect($redirect);
} // default:
$this->redirect('/home');
}
}
}
With the nonsense array I make sure that the user is not forwarded to pages where it would not make much sense. If no referrer is available it will simply redirect to the dashboard.
Your approach to edit own profile is an awesome hack. Thanks!
Maybe for version difference reasons your code didnt work. Am on CakePHP 3.0. My solution:
> Controller:
View template:
Thanks!
im currently working on my cakephp app i have database named time and is has to table users and accounts users have EployeeId, Password data fields and accounts has also EmployeeId , Password etc.. now what i want to happen is every time that i will add data to users table it will authenticate if that data to save is present in the accounts table if not it will flash error else it will save how can i do this in cakephp ?? here is may
add.ctp code
public function add()
{
$user = $this->Users->newEntity();
if ($this->request->is(‘post’)) {
$user = $this->Users->patchEntity($user, $this->request->data);
if ($this->Users->save($user)) {
$this->Flash->success((‘Logs has been saved.’));
return $this->redirect([‘action’ => ‘index’]);
} else {
$this->Flash->error((‘The logs could not be saved. Please, try again.’));
}
}
$this->set(compact(‘user’));
$this->set(‘_serialize’, [‘user’]);
}