I don't know why this doesn't work (I am using CakePHP 2.1 and also tried 2.0):
Here is Model
class User extends AppModel
{
public $validate = array('username' => array('rule' => 'email'));
}
Here is Controller
class UsersController extends AppController
{
function index()
{
$this->set('users', $this->User->find('all') );
}
function add()
{
if (!empty($this->request->data))
{
if ($this->User->save($this->request->data))
{
$this->Session->setFlash('User has been registered.');
$this->redirect(array('action' => 'index'));
}
}
}
}
Here is add View
<h1>Add Post</h1>
<?php
echo $this->Form->create('User');
echo $this->Form->input('username');
echo $this->Form->input('password');
echo $this->Form->end('Register');
?>
And it validates whatever I write... And it should check if username is email...
It's impossible! It has to work! - but it doesn't...
I also checked it with cake php 2.0 and it still does't work - please help, it is so simple i has to work...
Maybe something with my db table is wrong???
CREATE TABLE `users` (
`id` int(10) unsigned not null auto_increment,
`username` varchar(50),
`password` varchar(50),
`created` datetime,
`modified` datetime,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=9;
This is very strange - in my app folder I only add 'UserModel.php', 'UserController.php' and 'add.ctp', and a db config - all that I wrote above - and validation doesn't work!!!
I think the $validate array is not declared correctly.
Try this:
$validate = array('username' => array(
'email' => array(
'rule' => array('email')
)));
or this:
$validate = array('username' => 'email');
See http://book.cakephp.org/2.0/en/models/data-validation.html
Ok I know what is wrong:
my model filename was called 'UserModel.php' and it should be 'User.php'
At start of file 'User.php' I had to put 'App::uses('AppModel', 'Model');'
You should write in your controller ( UserController )
($this-User->set($this->request->data)
before the function validates Like you see;
function add()
{
if (!empty($this->request->data))
{ $this->User->set($this->request->data);
if ($this->User->validates())
{ $this->User->save($this->request->data)
$this->Session->setFlash('User has been registered.');
$this->redirect(array('action' => 'index'));
}
}
}
O.k... this is what I do (also changing the username to an email)
$components = array('Auth' => array('authenticate' => array('Form' => array('fields' => array('username' => 'email', 'password' => 'password')))), 'Email');
This works. In CakePHP 1.3 you had to specify both the username (email) and the password. So when I moved to CakePHP 2.1 I continued doing the same thing and had no problems with the validation.
you can see all that you need here: Cookbook
Related
I want to confirm user password then save the new password. I am able to validate username by this code but when i validate password, it doesn't work.
Is something i am missing or i am doing completely wrong. I am using cakephp2.5 Here is my code....
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(40) NOT NULL,
`password` varchar(40) NOT NULL,
`name` varchar(100) NOT NULL,
`email` varchar(100) NOT NULL,
`picture` varchar(100) NOT NULL,
`role_id` int(11) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=18 ;
changepassword.ctp (view)
<div class="row">
<div class="col-lg-6">
<?php echo $this->Form->create('User', array('role'=>'form')); ?>
<fieldset>
<legend><h1>Change Password </h1></legend>
<?php
echo $this->Form->input('oldpassword',array('label'=>'Old Password','type'=>'password','class'=>'form-control'));
echo $this->Form->input('password',array('value'=>'password','label'=>'New Password','class'=>'form-control'));
echo $this->Form->input('password_confirmation',array('type'=>'password','class'=>'form-control','value'=>'password','label'=>'Confirm new Password'));
echo "<br>";
?>
</fieldset>
<?php
$options = array('label' => 'Submit','class' => 'btn btn-default');
echo $this->Form->end($options);
?>
</div>
UsersController.php (controller)
<?php
App::uses('AppController', 'Controller');
class UsersController extends AppController {
public function changepswrd() {
if ($this->request->is('post')) {
$this->User->create();
$data=$this->request->data['User'];
$data['id']=AuthComponent::user('id');
if ($this->User->save($data)) {
$this->Session->setFlash(__('Password changed sucessfully'));
return $this->redirect(array('controller' => 'users', 'action' => 'viewList'));
} else {
$this->Session->setFlash(__('Error!! please try again'));
}
}
}
}
?>
User.php (Model)
<?php
App::uses('AppModel', 'Model');
class User extends AppModel {
public $displayField = 'name';
public $validate = array(
'password' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
),
'matchPasswords'=>array(
'rule'=>array('matchPasswords'),
'message' => 'Both password must be equal',
),
),
'password_confirmation' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
),
),
'oldpassword' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Please Enter old password',
),
'matching'=>array(
'rule'=>array('matching'),
'message' => 'wrong password',
),
),
);
public function matchPasswords($data){
if($data['password']==$this->data['User']['password_confirmation']){
return true;
}
$this->invalidate('password_confirmation','Both password must be equal');
return false;
}
public function matching($data){
$pswrd=AuthComponent::user('password');
if($pswrd==$this->data['User']['oldpassword']){
return true;
}
return false;
}
public function beforeSave($options = array()){
if(isset($this->data['User']['password'])){
$this->data['User']['password']=AuthComponent::password($this->data['User']['password']);
}
}
}
My Way of doing this :
function oldPasswordCheck($check){
$user = $this->find(
'count',
array('conditions' => array(
'User.id' => $this->session_id,
'User.password' => md5($this->data['User']['old_password'])
))
);
if(!$user){
return false;
}else {
return true;
}
}
Other help full link is
Click me
Hope this info helps you.
When I try to edit a user I get a login form, when I try to login it shows me 'The username and/or password is incorrect' from the UsersController. Even though the username and password is correct.
My User Table :
1 user_id bigint(11) AUTO_INCREMENT
2 user_username varchar(45) utf8_general_ci
3 user_email varchar(255) utf8_general_ci
4 user_password varchar(255) utf8_general_ci
5 user_image varchar(255) utf8_general_ci
6 user_created timestamp CURRENT_TIMESTAMP
7 user_modified timestamp
8 user_deleted timestamp
9 user_lastlogin timestamp
10 user_locked timestamp
11 user_confirmed timestamp
12 person_id bigint(20)
This is in my User Model:
public function beforeSave($options=array()){
parent::beforeSave();
if (!empty($this->data['User']['user_password'])){
$this->data['User']['user_password'] = Security::hash($this->data['User']['user_password'], 'sha256', true);
}
return true;
}
This is in my AppController :
public $components = array(
'DebugKit.Toolbar',
'Session',
'Auth' => array(
'authenticate' => array(
'Form' => array(
'fields' => array(
'username' => 'user_username',
'password' => 'user_password'
),
'passwordHasher' => array(
'className' => 'Simple',
'hashType' => 'sha256'
)
)
),
'loginRedirect' => array('controller'=>'users', 'action'=>'index'),
'logoutRedirect' => array('controller'=>'users', 'action'=>'index'),
'AuthError' => 'You cannot access that page',
'authorize'=>array('Controller')
)
);
public function isAuthorized($user){
return true;
}
public function beforeFilter() {
$this->Auth->allow('index', 'view');
}
This is in My login.ctp
echo $this->Form->create();
echo $this->Form->input('user_username');
echo $this->Form->input('user_password', array('type'=>'password'));
echo $this->Form->end('Submit');
This is in my UsersController :
public function beforeFilter(){
parent::beforeFilter();
$this->Auth->allow('add');
}
public function login(){
if ($this->request->is('post')){
if($this->Auth->login()){
$this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash(_('The username and/or password is incorrect'));
}
}
}
public function logout(){
$this->redirect($this->Auth->logout());
}
I've been looking for a while on this. Changing the name of user_password to password, changing the Type, changing the varchar(255) to (40),... Nothing seems to resolve this. Maybe it has something to do with the hashing but I think I've did everything right with that as well.
Maybe something else you should know: I'm working with IIS, do I need to do some sort of configuration?
Can someone help me?
You do not need to use fields 'username' and 'password' arbitrarily. Also AuthComponent::password is deprecated since 2.4. In your AuthComponent configuration, you may add the following parameters:
public $components = array(
'Auth' => array(
'authenticate' => array(
'Form' => array(
'fields' => array(
'username' => 'user_username',
'password' => 'user_password'
),
'passwordHasher' => array(
'className' => 'Simple',
'hashType' => 'sha256'
)
)
)
)
);
In your auth model:
public function beforeSave($options = array()) {
parent::beforeSave();
if (!empty($this->data['Model']['password'])) {
$this->data['Model']['password'] = Security::hash($this->data['Model']['password'], 'sha256', true);
}
return true;
}
Apparently you have to change user_username in the database also to username.
So I changed:
2 user_username varchar(45) utf8_general_ci
4 user_password varchar(255) utf8_general_ci
To:
2 username varchar(45) utf8_general_ci
4 password varchar(255) utf8_general_ci
And also changed those 2 in my cakePHP project.
However I'm wondering if you can change the password and username, that are the default values for using Auth in cakePHP?
I have problems with development of CakePHP2's authentication system, where users are stored in database table participants (not users, like usual).
It simply does not authenticate participant.
Table participants have next structure:
CREATE TABLE IF NOT EXISTS `participants` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`confirmed` tinyint(1) NOT NULL DEFAULT '0',
`name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`password` char(40) COLLATE utf8_unicode_ci DEFAULT NULL,
`token` char(32) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
)
File AppController.php have content like this:
App::uses('Controller', 'Controller');
class AppController extends Controller {
public $components = array('Cookie', 'Session', 'Auth');
function beforeFilter() {
$this->Auth->userModel = 'Participant';
$this->Auth->fields = array('username' => 'name', 'password' => 'password');
$this->Auth->loginAction = array('controller' => 'participants', 'action' => 'login');
//$this->Auth->logoutRedirect = array('controller' => 'participants', 'action' => 'logout'); // i will use this later
//$this->Auth->loginRedirect = array('controller' => 'participants', 'action' => 'index');
}
}
File ParticipantsController.php have content like:
App::uses('AppController', 'Controller');
class ParticipantsController extends AppController {
function beforeFilter() {
parent::beforeFilter();
$this->Auth->allowedActions = array('registration', 'login', 'forgotten', 'recreate', 'confirm');
}
function login() {
if ($this->Auth->login()) {
$this->redirect(array('controller' => 'participants', 'action'=>'view'));
} else {
// it always end-up here
//pr($this->data);
//pr(AuthComponent::password($this->data['Participant']['password']));
//exit;
$this->Session->setFlash( __('Error, please try again.', true) );
}
}
I don't know what is wrong here, can you please help me what I'm missing here?
I think it might be your configuration of fields and userModel
$this->Auth->fields
My working code is closer to :
$this->Auth->authenticate = array(
'Form' => array('userModel' => 'Participant'
, 'fields' => array('username' => 'name', 'password' => 'password')
)
);
Try this:
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow(array('registration', 'login',
'forgotten', 'recreate', 'confirm'));
}
Why your functions is not public in controllers?
New to Cake, and trying to set up model associations. I'm creating an execution planner, to be used by multiple teams, aka 'groups' where the base unit of a plan is an 'event'. Each event is owned by one team, but it can have many supporting teams.
When I use $scaffold in the controllers, the model associations work as expected and when adding a new event I get a select box with all the groups to select who owns an event. However, when I bake the controller using console, the select box for group_id is blank. I've included the baked add() code from the controller, and from the baked add view. I also tried debug($this) in add.ctp, and found that the list of groups is indeed being passed to the view. I'm thus mostly confused about why it works with $scaffold, but not otherwise.
Any advice or pointers in the right direction would be greatly appreciated.
Tables:
CREATE TABLE IF NOT EXISTS `events` (
`id` int(5) NOT NULL AUTO_INCREMENT,
`group_id` int(5) NOT NULL COMMENT 'Group that owns event',
`version` int(5) NOT NULL,
`type` varchar(5) NOT NULL,
`stime` time NOT NULL,
`etime` time NOT NULL,
`description` text NOT NULL,
`comment` text NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE IF NOT EXISTS `events_groups` (
`id` int(5) NOT NULL AUTO_INCREMENT,
`event_id` int(5) NOT NULL,
`group_id` int(5) NOT NULL,
PRIMARY KEY (`id`)
) ;
CREATE TABLE IF NOT EXISTS `groups` (
`id` int(5) NOT NULL AUTO_INCREMENT,
`code` varchar(4) NOT NULL,
`name` varchar(25) NOT NULL,
`liveversion` int(4) NOT NULL,
`lastupdated` date NOT NULL,
PRIMARY KEY (`id`)
);
Models:
Event:
public $belongsTo = array(
'Prigroup' => array(
'className' => 'Group',
'foreignKey' => 'group_id',
)
);
public $hasAndBelongsToMany = array(
'Secgroup' => array(
'className' => 'Group',
'joinTable' => 'events_groups',
'foreignKey' => 'event_id',
'associationForeignKey' => 'group_id',
)
);
Group:
public $hasMany = array(
'Prievent' => array(
'className' => 'Event',
'foreignKey' => 'group_id',
)
);
public $hasAndBelongsToMany = array(
'Secevent' => array(
'className' => 'Event',
'joinTable' => 'events_groups',
'foreignKey' => 'group_id',
'associationForeignKey' => 'event_id',
)
);
EventsController Snippet:
public function add() {
if ($this->request->is('post')) {
$this->Event->create();
if ($this->Event->save($this->request->data)) {
$this->Session->setFlash(__('The event has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The event could not be saved. Please, try again.'));
}
}
$prigroups = $this->Event->Prigroup->find('list');
$secgroups = $this->Event->Secgroup->find('list');
$this->set(compact('prigroups', 'secgroups'));
}
Add view:
<?php echo $this->Form->create('Event'); ?>
<fieldset>
<legend><?php echo __('Add Event'); ?></legend>
<?php
echo $this->Form->input('group_id');
echo $this->Form->input('version');
echo $this->Form->input('type');
echo $this->Form->input('stime');
echo $this->Form->input('etime');
echo $this->Form->input('description');
echo $this->Form->input('comment');
echo $this->Form->input('Secgroup');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
Add HTML Output
<div class="input select"><label for="EventGroupId">Group</label><select name="data[Event][group_id]" id="EventGroupId">
</select></div>
Can u try something for me please? Rename the $prigroups variable to "groups" and pass it to the view. See if this is working. Otherwise use this one with your old code:
echo $this->Form->input(
'group_id',
array(
'options' => $prigroups
)
);
I also recommend you to use camel case for all those PriGroups and SecGroups. Those are two words in english so camel case advisable.
Greetings
func0der
I was wondering if someone could help me out.
I am using cakePHP 1.3 and I am having trouble getting the edit view to update the main Model and a hasOne related Model. I am fairly positive this has to do with my setup of the edit.ctp view. I am using the media plugin which I got working on another model, so I don't believe that has anything to do with that. Specifically I am working on getting the Media Plugin, Monolithic Attachment Model with a hasOne relationship working.
I have checked out the cake docs
http://book.cakephp.org/#!/view/1032/Saving-Related-Model-Data-hasOne-hasMany-belongsTo read the majority of the docs in the Media Plugin this like is the most relevant
https://github.com/davidpersson/media/blob/next/docs/RECIPES
and spent extensive time searching google.
Any help would be appreciated.
Thanks,
James
Model - client.php
<?php
class Client extends AppModel {
var $name = 'Client';
var $displayField = 'name';
var $actsAs = array(
'Media.Transfer',
'Media.Coupler',
'Media.Generator'
);
[...]
var $hasOne = array(
'Logo' => array(
'className' => 'Attachment',
'foreignKey' => 'foreign_key',
'conditions' => array('Logo.model' => 'Client'),
'dependent' => true,
));
[...]
?>
Controller - clients_controller.php
<?php
class ClientsController extends AppController {
var $name = 'Clients';
[...]
function edit($id = null) {
if (!$id && empty($this->data)) {
$this->Session->setFlash(__('Invalid client', true));
$this->redirect(array('action' => 'index'));
}
if (!empty($this->data)) {
if ($this->Client->saveAll($this->data, array('validate'=>'first') )) {
$this->Session->setFlash(__('The client has been saved', true));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The client could not be saved. Please, try again.', true));
}
}
if (empty($this->data)) {
$this->Client->recursive = 0;
$this->data = $this->Client->read(null, $id);
}
$statuses = $this->Client->Status->find('list');
$this->set(compact('statuses'));
}
[...]
?>
View - edit.ctp
<h1><?php __('Edit Clients');?></h1>
<div class="clients form">
<?php echo $this->Form->create('Client', array('type' => 'file'))."\n";?>
<fieldset>
<?php
echo $this->Form->input('Client.id')."\n";
echo $this->Form->input('Client.name')."\n";
echo $this->Form->input('Client.address1')."\n";
echo $this->Form->input('Client.address2')."\n";
[...]
echo $form->input('Logo.id')."\n";
echo $form->input('Logo.file', array('type' => 'file'))."\n";
echo $form->hidden('Logo.foreign_key')."\n";
echo $form->hidden('Logo.model', array('value' => 'Client'))."\n";
?>
</fieldset>
<?php echo $this->Form->end(__('Submit', true));?>
</div>
clients sql
CREATE TABLE `clients` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) NOT NULL,
`address1` varchar(255) NOT NULL,
`address2` varchar(255) NOT NULL,
`created` datetime default NULL,
`modified` datetime default NULL,
PRIMARY KEY (`id`)
)
attachments sql
CREATE TABLE `attachments` (
`id` int(10) NOT NULL auto_increment,
`model` varchar(255) NOT NULL,
`foreign_key` int(10) NOT NULL,
`dirname` varchar(255) default NULL,
`basename` varchar(255) NOT NULL,
`checksum` varchar(255) NOT NULL,
`group` varchar(255) default NULL,
`alternative` varchar(50) default NULL,
`created` datetime default NULL,
`modified` datetime default NULL,
PRIMARY KEY (`id`)
)
var $hasOne = array(
'Logo' => array(
'className' => 'Attachment',
'foreignKey' => 'foreign_key', // 'foreign_key' ? is that a name for your fk?
'conditions' => array('Logo.model' => 'Client'),
'dependent' => true,
));
here you haven't defined the foreign_key which binds your logo to your client. look up in your database for the foreign key and put it's name here.
Thanks for all the responses. I finally got it working. It appears that for some reason the saveAll was causing me grief. When I saved the Client then saved the Logo everything worked.
I posted the code below.
Controller Code
function edit($id = null) {
if (!$id && empty($this->data)) {
$this->Session->setFlash(__('Invalid client', true));
$this->redirect(array('action' => 'index'));
}
if (!empty($this->data)) {
$client = $this->Client->save($this->data);
if (!empty($client)) {
$this->data['Logo']['foreign_key'] = $this->Client->id;
$this->data['Logo']['model'] = 'Client';
$this->Session->setFlash(__('The client has been saved', true));
$this->Client->Logo->save($this->data);
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The client could not be saved. Please, try again.', true));
}
}
if (empty($this->data)) {
$this->Client->recursive = 0;
$this->data = $this->Client->read(null, $id);
}
$statuses = $this->Client->Status->find('list');
$this->set(compact('statuses'));
}