I cant seem to figure out why my form is not applying validation defined in my model. Any assistance?
\app\View\Enquiries\view.ctp:
<?php
echo $this->Form->create('Enquiry', array('action'=>'email','novalidate' => true));
echo $this->Form->input('message', array ('type' => 'textarea', 'class'=>'form-control'));
echo $this->Form->hidden('email', array ('value'=> $enquiry['Enquiry']['email']));
?>
\app\Model\Enquiry.php
<?php
App::uses('AppModel', 'Model');
class Enquiry extends AppModel {
public $actsAs = array('Acl' => array('type' => 'requester'));
public function parentNode() {
return null;
}
public $validate = array(
'message' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Please enter your enquiry',
'allowEmpty' => false,
)
),
);
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
}
\app\Controller\EnquiriesController.php
<?php
App::uses('AppController', 'Controller', 'Network/Email');
class EnquiriesController extends AppController {
public $helpers = array('GoogleMap','Html','Form','Session'); //Adding the helper
public $components = array('Paginator','Email','Session');
public function email($id, $dest=null){
if ($this->request->data) {
//Admin reply enquiry email
$Email = new CakeEmail('default');
$Email->config('default');
$Email->template('replyenq');
$Email->from(array('xxxx#gmail' => 'xxxx'))
->to($this->request->data['Enquiry']['email'])
->subject('xxxx has sent you a reply!')
->send();
//after sending, display a notification
$this->Session->setFlash(__('Reply enquiry has been successful.' , true), 'alert-box', array('class'=>'alert-success'));
//Redirect after email has been successful
return $this->redirect(array('action' => '../enquiries'));
}
else {
$this->Session->setFlash(__('Message was empty. Please ensure you enter a message'), 'alert-box', array('class'=>'alert-warning'));
return $this->redirect(array('action' => '../enquiries/view/'.$id));
}
}
}
Data is only normally validated when calling the save() method of a model. Your controller takes the submitted data and puts it straight into an e-mail so there is no interaction with the Enquiry model.
You will need to manually call $this->Enquiry->validates() from the controller and add logic to deal with the result.
See also: Validating Data from the Controller
Related
I don't know why am still getting invalid username or password while I have all the codes and my database. Also the user is already registered but cannot login.
AppController.php
class AppController extends Controller{
public $components = array(
/*'DebugKit.Toolbar',*/
'Session',
'Auth' => array(
'loginRedirect' => array('controller' => 'jobs', 'action' => 'index'),
'logoutRedirect' => array(
'controller' => 'users',
'action' => 'login'
)
)
);
}
Model: User.php
App::uses('AppModel', 'Model');
App::uses('SimplePasswordHasher', 'Controller/Component/Auth');
class User extends AppModel {
public $validate = array(
'Username' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
),
'The username already exists'=>array(
'rule'=>array('isUnique'),
'message'=>'The username already exists!'
),
),
'Password' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
),
'Match passwords'=>array(
'rule'=>'matchPasswords',
'message'=>'The password does not match'
),
),
'Confirm_Password' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
),
),
);
function matchPasswords($data){
if ($data['Password'] == $this->data['User']['Confirm_Password']) {
return TRUE;
}
$this->invalidate('Confirm_Password', 'The password does not match');
return FALSE;
}
public function beforeSave($options = array()) {
if (!parent::beforeSave($options)) {
return false;
}
if (isset($this->data[$this->alias]['Password'])) {
$hasher = new SimplePasswordHasher();
$this->data[$this->alias]['Password'] = $hasher->hash($this->data[$this->alias]['Password']);
}
return true;
}
}
Controller: UsersController.php
class UsersController extends AppController {
public $components = array('Session');
var $name = 'Users';
var $helpers = array('Form');
// Placeholder for login_form, required by CakePHP to see the login_form view
function login_form() { }
public function beforeFilter () {
parent::beforeFilter();
$this->Auth->allow('user', 'login');
}
public function login(){
if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirectUrl());
}
$this->Session->setFlash(__('Incorrect username or password'));
}
}
public function logout() {
return $this->redirect($this->Auth->logout());
}
public function done() {
$this->set('framework', 'CakePHP');
}
public function user(){
if($this->request->is('post')) {
$this->User->create();
if($this->User->save($this->request->data)) {
$this->Session->setFlash('The information has been sent successfully!');
return $this->redirect(array('action' => 'login'));
$this->redirect('done');
}
}
}
}
View: login.ctp
<h4>LOGIN HERE</h4>
<?php
echo $this->Session->flash('auth');
echo $this->Form->create('User');
echo $this->Form->input('Username');
echo $this->Form->input('Password',array('type' => 'password'));
echo $this->Form->end('Login');
?>
You are not using the default field names CakePHP is expecting. Therefore, you have to include them in your AuthComponent configuration.
Try the following:
class AppController extends Controller
{
public $components = array(
/*'DebugKit.Toolbar',*/
'Session',
'Auth' => array(
'loginRedirect' => array('controller' => 'jobs', 'action' => 'index'),
'logoutRedirect' => array(
'controller' => 'users',
'action' => 'login'
),
'authenticate' => array(
'Form' => array(
'fields' => array(
'username' => 'Username',
'password'=>'Password'
),
),
)
)
);
}
These should match the field names in your users table and in your views.
EDIT
Also, make sure your password field in the database is long enough to store the hashed password. The default algorithm used by CakePHP is SHA1, which produces a 160 bit (40 character) hash. A VARCHAR 255 should be more than enough to store this string.
See:
Configuring Authentication handlers in Cookbook 2.x | Authentication
So, I'm trying to make an authentication in CakePHP that is using email instead of username, which field I don't even have in my users table in database. first i was trying to google that, and i already have tried these:
Cakephp 2.0 Authentication using email instead of username
Using email instead of username in CakePHP Auth Component
and few others, but nothing seems to work - still i get the "incorrect data" error. below is my code
AppController.php
class AppController extends Controller {
public $components = array(
'Session',
'Auth' => array(
'userModel' => 'User',
'loginRedirect' => array(
'controller' => 'pages',
'action' => 'display'
),
'logoutRedirect' => array(
'controller' => 'pages',
'action' => 'display',
'home'
),
'authenticate' => array(
'Form' => array(
'fields' => array(
'username' => 'email',
'password' => 'password'
),
'passwordHasher' => 'Blowfish'
)
)
)
);
public function beforeFilter(){
$this->Auth->allow('index', 'view');
}
UsersController.php
public function add() {
if ($this->request->is('post')) {
$this->User->create();
$this->request->data['User']['role'] = "user";
if(strcmp($this->request->data['User']['password'], $this->request->data['User']['repeat']) == 0){
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__('Użytkownik zarejestrowany.'));
return $this->redirect(array('controller' => 'Pages', 'action' => 'display'));
}
else $this->Session->setFlash(__('Wystąpił błąd, spróbuj ponownie.'));
}
else $this->Session->setFlash(__('Wpisane hasła się nie zgadzają'));
}
}
public function login(){
if($this->request->is('post')){
if($this->Auth->login()){
return $this->redirect($this->Auth->redirectUrl());
}
$this->Session->setFlash(__('Nieprawidłowe dane, spróbuj ponownie'.$this->Auth->login()));
}
}
login.ctp
<div class="users form">
<?php echo $this->Session->flash('auth'); ?>
<?php echo $this->Form->create('User'); ?>
<fieldset>
<legend>
<?php echo __('Zaloguj się'); ?>
</legend>
<?php
echo $this->Form->input('email' /*I also tried with username instead of email here*/, array('label' => 'Email'));
echo $this->Form->input('password', array('label' => 'Hasło'));
?>
</fieldset>
<?php echo $this->Form->end(__('Zaloguj')); ?>
</div>
EDIT: Here is User.php
App::uses('AppModel', 'Model');
App::uses('BlowfishPasswordHasher', 'Controller/Component/Auth');
class User extends AppModel {
public $validate = array(
'email' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'Email jest wymagany'
)
),
'password' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'Hasło jest wymagane'
)
),
'repeat' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'Powtórz hasło'
)
),
'identicalFieldValues' => array(
'rule' => 'identicalFieldValues',
'message' => 'Wpisane hasła się nie zgadzają'
)
);
public function identicalFieldValues(){
return $this->data['User']['password'] === $this->data['User']['repeat'];
}
public function beforeSave($options = array()){
if(isset($this->data[$this->alias]['password'])){
$passwordHasher = new BlowfishPasswordHasher();
$this->data[$this->alias]['password'] = $passwordHasher->hash(
$this->data[$this->alias]['password']
);
}
return true;
}
}
2nd EDIT: I read that the problem can be in size of the varchar in sql, so I changed it from 50 to 130, deleted users, made a new one, but still I cannot log in.
3rd EDIT: I made a completly new, clean cake project, without password hashing, but still with login via email and still im getting "incorrect data" -.-
I just started using cakephp 2.5, and i am trying to validate form data using the $validate in the model.
The validation is always wrong even if i enter good data in the fields.
Can someone check what is wrong with my code??
The view file
adduser.ctp
<?php
echo $this->Form->create('user');
echo $this->Form->input('username');
echo $this->Form->input('email');
echo $this->Form->input('password');
echo $this->Form->end('Add User');
the controller file
UsersController.php
<?php
class UsersController extends AppController {
public $helpers = array('Html', 'Form', 'Session');
public $components = array('Session');
public function adduser(){
if ($this->request->is('post')){
$this->User->create();
$this->User->save($this->request->data);
}
}
}
The Model file
User.php
<?php
class User extends AppModel {
public $validate = array(
'username' => array(
'alphaNumeric' => array(
'rule' => 'alphaNumeric',
'required' => true,
'message' => 'The username must be letters and numbers'
)
),
'email' => array(
'rule' => 'email',
'message' => 'The email address must be valid',
'required' => true
),
'password' => array(
'rule' => array('minLength', 6),
'message' => 'The password must be at least 6 characters long',
'required' => true
)
);
}
Thanks for everyone in advance
Mind your casing, naming conventions are very important in CakePHP in order for all the automagical stuff to work properly.
In your form, the model name should be User, not user
echo $this->Form->create('User');
While making login feature in my application, i found a problem i cannot solve..
I created login() action inside IndexController, and i am trying verify given data. Main problem is that i cannot to connect them with User Model which holds all data needed to login , such a nickname (username) and password. The code is below:
IndexController.php
App::uses('AppController', 'Controller');
App::import('Controller', 'Users');
class IndexController extends AppController{
public $helpers = array('Html','Form', 'Session');
public $uses = array('User', 'Registration');
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow();
}
public function index(){
$menu = $this->menu();
$this->set('menu', $menu);
}
public function login(){
if ($this->request->is('post')) {
$this->Auth->authenticate = array('Form' => array('userModel' => 'User' ));
var_dump($this->Auth->login());
exit();
if ($this->Auth->login($this->request->data)) {
return $this->redirect($this->Auth->redirectUrl());
}else{
$this->Session->setFlash(__('Invalid username or password, try again'));
$this->redirect(array('controller' => 'index', 'action' => 'login'));
}
if ($this->Session->read('Auth.User')) {
$this->Session->setFlash('You are logged in!');
return $this->redirect(array('controller' => 'index', 'action' => 'index'));
}
}
}
User.php
App::uses('AppModel', 'Model');
App::uses('SimplePasswordHasher', 'Controller/Component/Auth');
class User extends AppModel {
public $displayField = 'name';
//public $belongsTo = array('Role');
//public $actsAs = array('Acl' => array('type' => 'requester'));
public $validate = array(
'name' => array(
'maxLength' => array(
'rule' => array('maxLength', 20),
'message' => 'Name field is too long'
)
),
'nickname' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Field cannot be empty'
),
'maxLength' => array(
'rule' => array('maxLength', 20),
'message' => 'Nickname field is too long'
),
),
'password' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Field cannot be empty',
),
),
'role_id' => array(
'numeric' => array(
'rule' => array('numeric')
),
),
'email' => array(
'email' => array(
'rule' => array('email'),
'message' => 'Wrong email address format'
),
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Field cannot be empty',
),
'maxLength' => array(
'rule' => array('maxLength', 30),
'message' => 'Your custom message here'
),
),
'avatar' => array(
'maxLength' => array(
'rule' => array('maxLength', 50),
),
),
'points' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
);
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
$passwordHasher = new SimplePasswordHasher();
$this->data[$this->alias]['password'] = $passwordHasher->hash(
$this->data[$this->alias]['password']
);
}
return true;
}
}
And UserController.php
App::uses('AppController', 'Controller');
class UsersController extends AppController {
public $helpers = array('Html', 'Form', 'Session', 'Paginator');
public $components = array('Auth', 'Session');
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('');
}
public function index(){
$this->User->recursive = 0;
$this->set('users', $this->paginate());
}
public function view($id = null){
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('Invalid user'));
}
$this->set('user', $this->User->read(null, $id));
}
public function edit($id = null){
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('Invalid user'));
}
if ($this->request->is('post','put')) {
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__('The user has been saved'));
return $this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(
__('The user could not be saved. Please, try again.')
);
} else {
$this->request->data = $this->User->read(null, $id);
unset($this->request->data['User']['password']);
}
$roles = $this->User->Role->find('list');
$this->set(compact('roles'));
}
public function add(){
if($this->request->is('post')){
$this->User->create();
if($this->User->save($this->request->data)){
$this->Session->setFlash('User has been registered');
return $this->redirect(array('controller' => 'index', 'action' => 'index'));
}
$this->Session->setFlash('Unable to register now, try again');
}
$roles = $this->User->Role->find('list');
$this->set(compact('roles'));
}
public function delete($id = null) {
$this->request->onlyAllow('post');
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('Invalid user'));
}
if ($this->User->delete()) {
$this->Session->setFlash(__('User deleted'));
return $this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('User was not deleted'));
return $this->redirect(array('action' => 'index'));
}
public function login() {
}
}
Login.ctp
<div class="users form">
<?php echo $this->Session->flash('auth'); ?>
<?php echo $this->Form->create('User'); ?>
<fieldset>
<legend>
<?php echo __('Please enter your username and password'); ?>
</legend>
<?php echo $this->Form->input('User.nickname');
echo $this->Form->input('User.password');
?>
</fieldset>
<?php echo $this->Form->end(__('Login')); ?>
</div>
And here is a question: is it even possible to make it like that?
EDIT
Forgive me, but i forgot to add that all Auth rules i set in AppController:
AppController.php
App::uses('Controller', 'Controller');
class AppController extends Controller {
public $components = array(
'Session',
'Acl',
'Auth' => array(
'authorize' => array(
'Actions' => array('actionPath' => 'controllers')
),
'authenticate' => array(
'Form' => array('username' => 'nickname'),
'Basic'
),
'loginAction' => array(
'controller' => 'index',
'action' => 'login'
),
'loginRedirect' => array(
'controller' => 'users',
'action' => 'index'
),
'logoutRedirect' => array(
'controller' => 'index',
'action' => 'index',
)
)
);
}
First of all this line is definitly wrong:
echo $this->Form->input('Userpassword');
change it to
echo $this->Form->input('password');
also Cakes Auth by default is looking for field called "username" so you have 2 options
instead of User.nickname use
echo $this->Form->input('username');
(and remember about changing validiation from nickname to username)
Or
To configure different field then username for user auth in $components array:
Pass settings in $components array
public $components = array(
'Auth' => array(
'authenticate' => array(
'Form' => array(
'fields' => array('username' => 'nickname')
)
)
)
);
I highly recommend you to read about Cake's Auth Component so you will avoid mistakes like this.
I'm new to CakePHP and I'm trying to implement the Simple Acl Controlled Application tutorial, and I've reached the part where you try to add new users and groups..
I successfully added the groups but when i try and add new users I receive the "The user could not be saved. Please, try again." Part of the function.
public function add() {
if ($this->request->is('post')) {
$this->User->create();
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__('The user has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
}
}
}
I noticed that the form tries to create a drop down box of all the different groups that I created but the drop box is empty and I have created three different groups (Admin, Responder and Volunteer).
Here is a copy of the add user view..
<div class="users form">
<?php echo $this->Form->create('User'); ?>
<fieldset>
<legend><?php echo __('Add User'); ?></legend>
<?php
echo $this->Form->input('id');
echo $this->Form->input('username');
echo $this->Form->input('password');
echo $this->Form->input('group_id');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>
<div class="actions">
<h3><?php echo __('Actions'); ?></h3>
<ul>
<li><?php echo $this->Html->link(__('List Users'), array('action' => 'index')); ?></li>
</ul>
</div>
Model as requested:
<?php
App::uses('AppModel', 'Model');
App::uses('AuthComponent', 'Controller/Component');
class User extends AppModel {
public $belongsTo = array('Group');
public $actsAs = array('Acl' => array('type' => 'requester'));
public function parentNode() {
if (!$this->id && empty($this->data)) {
return null;
}
if (isset($this->data['User']['group_id'])) {
$groupId = $this->data['User']['group_id'];
} else {
$groupId = $this->field('group_id');
}
if (!$groupId) {
return null;
} else {
return array('Group' => array('id' => $groupId));
}
}
public $primaryKey = 'id';
public $validate = array(
'id' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
'username' => array(
'notempty' => array(
'rule' => array('notempty'),
),
),
'password' => array(
'notempty' => array(
'rule' => array('notempty'),
),
),
'group_id' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
//old belongs to
// public $belongsTo = array(
// 'Group' => array(
// 'className' => 'Group',
// 'foreignKey' => 'group_id',
// 'conditions' => '',
// 'fields' => '',
// 'order' => ''
// )
// );
public $hasMany = array(
'Post' => array(
'className' => 'Post',
'foreignKey' => 'user_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
public function beforeSave($options = array()) {
$this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
return true;
}
}
Debug message:
array(
'User' => array(
'password' => '*****',
'id' => '',
'username' => 'iwanjones'
)
)
Any help would be appreciated.
Thanks
In the form within your view, you create the id field as an input field (although through Cake's automagic it should convert it to a hidden input). When creating a new user, there is no id yet. It will be determined upon saving (creating) the record. In most applications this will be done by the MySQL backend's AUTO_INCREMENT functionality, which picks the first available "free" id.
In case of adding a new user, the id field is therefor not necessary. You only need it when you want to edit an existing user and make sure Cake edits the proper user, by setting it's id.
At this moment you set the id field in your view, but it gets no value, since it's a new user. In your Model you have added a validation rule that requires the id field to be numeric. But, the value is actually empty. You should do two things to get this working:
Drop the echo $this->Form->input('id'); line from the add view.
Remove the validation rule for the id field from your model (it's pretty uncommon to validate your primary key field, as Cake already handles this the proper way).
This should allow for the user to be saved successfully.