i'm not able to catch and show validation errors into my CakePHP controller class.
I've this model:
public $validate = array(
'username' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Your custom message here',
'allowEmpty' => false,
'required' => true,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'alphaNumeric' => array(
'rule' => array('alphaNumeric'),
'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'maxLength' => array(
'rule' => array('maxLength', 50),
'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
));
and this is how i try to catch validation message into controller while save a new element into array:
public function add() {
if ($this->request->is('post')) {
$this->Admin->set($this->request->data);
//$this->Admin->create();
if ($this->Admin->validates()) {
// it validated logic
if ($this->Admin->save($this->request->data)) {
$this->Session->setFlash(__('The admin has been saved.'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The admin could not be saved. Please, try again.'));
}
} else {
// didn't validate logic
$errors = $this->Admin->validationErrors;
debug($errors);
}
}
}
but it doesn't work. If i pass an empty field an alert with a default message is showed into add.ctp page. If i insert a duplicate, no message is showed.
You don't need
$this->Admin->set($this->request->data);
$this->Admin->validates(){}
because if you are using "save"
$this->Admin->save($this->request->data)
is validating already. That should do the job.
I need a login/logout system in my project I've done an authorization class but It won't work for me because the login function always returns false
Here is my UserController.php
if ($this->request->is('post')) {
$this->Auth->fields = array("username"=>"username","password"=>"password");
debug($this->Auth->login(),false,true);
if ($this->Auth->login()) {
$this->Session->setFlash(__('You are now logged in.'));
}else{
$this->Session->setFlash(__('Invalid username or password, try again'));
}
Configure::write('debug', 2);
$log = $this->User->getDataSource()->getLog(false, false);
debug($log);
}
Also, my AppController.php have:
public $components = array(
'Session',
'Auth' => array(
'loginAction' => array(
'controller' => 'User',
'action' => 'login'
),
'loginRedirect' => array('controller' => 'User', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'User', 'action' => 'login'),
'authError' => "You can't acces that page",
'authorize' => array('Controller'),
));
public function isAuthorized(){
return TRUE;
}
public function beforeFilter() {
$this->Auth->authenticate = array('Form');
$this->Auth->allow('index', 'view');
}
And finally my model file is:
public $validate = array(
'email' => array(
'required' => array(
'rule' => array("notEmpty"),
'message' => 'A E-mail field is required'
)
),'password' => array(
'required' => array(
'rule' => array("notEmpty"),
'message' => "A Password field is required"
)
)
);
im developing small app and I decided that i will use CakePhp as a framework, i was doint tutorial to make "posts". But when i wanted to use funcionality Simple Authentication and Authorization Application from here i was doing copy and paste and encountered 2 issues
first my User model doesn't see SimplePasswordHasher
App::uses('SimplePasswordHasher', 'Controller/Component/Auth');
class User extends AppModel {
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A username is required'
)
),
'password' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A password is required'
)
),
'role' => array(
'valid' => array(
'rule' => array('inList', array('admin', 'author')),
'message' => 'Please enter a valid role',
'allowEmpty' => false
)
)
);
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
$passwordHasher = new SimplePasswordHasher(); <---- here
$this->data[$this->alias]['password'] = $passwordHasher->hash(
$this->data[$this->alias]['password']
);
}
return true;
}}
maybe App::uses('SimplePasswordHasher', 'Controller/Component/Auth'); doesn't point in right place but i didn't found a way to check it.
second issue is when i try to enter at login page i got Authentication adapter "Form" was not found. Where i can init that adapter. any help would be great.
You must specify the same SimplePasswordHasher in controller as well as follows:
public $components = array(
'Auth' => array(
'loginAction' => array(
'controller' => 'users',
'action' => 'login'
),
'authError' => 'Did you really think you are allowed to see that?',
'authenticate' => array(
'Form' => array(
'passwordHasher' => array(
'className' => 'Simple',
'hashType' => 'sha256'
)
)
),
'loginRedirect' => array(
'controller' => 'users',
'action' => 'index'
)
)
);
Hope it helps
Recently I've been learning AJAX and jQuery, to validate my forms rather than using validations on refresh. I have the form submission with AJAX working correctly - sending the form successfully without a page refresh - however when the form is submitted and passed through the validations within User.php, if any errors are returned these are shown in a separate form, not the original form from which the data was submitted.
EDIT : The errors just keep on coming - The "implode(',', $error)" works, but I've found it doesn't work in chrome. I'm sure there's a quick fix for this but I can't seem to find one that works.
create.ctp
<?php echo $this->Html->script('jquery', FALSE); ?>
<?php echo $this->Html->script('validation', FALSE); ?>
<div id="success"></div>
<div class="users form">
<h2>Create User</h2>
<?php echo $this->Form->create('User'); ?>
<fieldset>
<?php
echo $this->Form->input('username', array('id'=>'username'));
echo $this->Form->input('password', array('id'=>'password'));
echo $this->Form->input('confirmpw', array('label'=>'Confirm Password', 'id'=>'confirmpw', 'type'=>'password'));
echo $this->Form->input('tos', array('type'=>'checkbox', 'id'=>'tos', 'label'
=>__('I confirm I have read the Terms and Conditions', true), 'hidden'=>false, 'value'=>'yes'));
?>
</fieldset>
<?php
echo $this->Js->submit('Send', array(
'before'=>$this->Js->get('#sending')->effect('fadeIn'),
'success'=>$this->Js->get('#sending')->effect('fadeOut'),
'update'=>'#success'
));
echo $this->Form->end();
?>
<div id="sending" style="display: none; background-color: lightblue;">Sending...</div>
<?php
?>
</div>
validation.js
$(document).ready(function() {
$('#username').blur(function(){
$.post(
'/practice/Users/validate_form',
{ field: $('#username').attr('id'), value: $('#username').val() },
handleUsernameValidation
);
});
function handleUsernameValidation(error) {
if (error.length > 0) {
if ($('#username-notEmpty').length == 0) {
$('#username').after('<div id="username-notEmpty" class="error-message">' + error + "</div>");
}
}
else {
$('#username-notEmpty').remove();
}
}
}
)
UsersController.php
public function create() {
if ($this->request->is('post')) {
$this->User->create();
if ($this->User->save($this->request->data)) {
if ($this->RequestHandler->isAjax()) {
$this->render('/Messages/success', 'ajax');
}
else {
$this->Session->setFlash(__('The user has been saved'));
$this->redirect(array('action' => 'index'));
}
}
}
}
public function validate_form() {
if ($this->RequestHandler->isAjax()) {
$field = $this->request->data['field'];
$value = $this->request->data['value'];
$this->request->data['User'][$field] = $value;
$this->User->set($this->request->data);
if ($this->User->validates()) {
$this->autoRender = FALSE;
}
else {
$error = $this->validateErrors($this->User);
$this->set('error', $error[$this->request->data['field']]);
}
}
}
validate_form.ctp
<?php echo implode(',', $error); ?>
User.php
public $validate = array(
'username' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Field cannot be empty.',
'allowEmpty' => false,
'required' => true,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'alphanumeric' => array(
'rule' => array('alphanumeric'),
'message' => 'Only alphanumeric characters allowed.',
'allowEmpty' => false,
'required' => true,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'maxlength' => array(
'rule' => array('maxlength', '15'),
'message' => 'Login name limit is 15 characters.',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'minlength' => array(
'rule' => array('minlength', '6'),
'message' => 'Login name must be more than 6 characters.',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'isUnique' => array(
'rule' => array('isUnique'),
'message' => 'This username is not available, please pick a different name.',
),
),
'password' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Field cannot be empty.',
'allowEmpty' => false,
'required' => true,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'maxlength' => array(
'rule' => array('maxlength', '15'),
'message' => 'Password limit is 15 characters.',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'minlength' => array(
'rule' => array('minlength', '6'),
'message' => 'Password must be more than 6 characters.',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'confirmpw' => array(
'maxlength' => array(
'rule' => array('maxlength', '15'),
'message' => 'Password limit is 15 characters.',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'minlength' => array(
'rule' => array('minlength', '6'),
'message' => 'Password must be more than 6 characters.',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'notEmpty' => array(
'rule' => array('notempty'),
'message' => 'Passwords do not match, please try again.'
),
'equalToField' => array(
'rule' => array('equalToField', 'password'),
'message' => 'Passwords do not match, please try again.',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
'on' => 'create', //Limit validation to 'create' or 'update' operations
)
),
'tos' => array(
'comparison' => array(
'rule' => array('comparison', '==', 'yes'),
'required' => true,
'message' => 'Please agree to the Terms and Conditions.'
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
);
function equalToField($check, $otherfield) {
$fname = '';
foreach ($check as $key => $value) {
$fname = $key;
break;
}
return $this->data[$this->name][$otherfield] === $this->data[$this->name][$fname];
}
Thanks.
As far as I remember validateErrors returned array of error messages for each fields.
Can you please try this in validate_form.ctp
<?php echo implode(',', $error); ?>
Or if it not work, let's try
<?php echo var_export($error); ?>
and see what kind of variable that' the $error contains.
I am creating a message controller that allows the user send messages to other users. Here is my database structure
users
id
username
password
messages
id
to_id
from_id
subject
message
the to_id and from_id both reference the id column in users. Here is my model for messages
message
<?php
class Message extends AppModel {
var $name = 'Message';
var $displayField = 'subject';
var $validate = array(
'id' => array(
'numeric' => array(
'rule' => array('numeric'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'to_id' => array(
'numeric' => array(
'rule' => array('numeric'),
//'message' => 'Your custom message here',
'allowEmpty' => false,
'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'from_id' => array(
'numeric' => array(
'rule' => array('numeric'),
//'message' => 'Your custom message here',
'allowEmpty' => false,
'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
);
var $belongsTo = array(
'Sender' => array(
'className' => 'User',
'foreignKey' => 'to_id'
),
'Recipient' => array(
'className' => 'User',
'foreignKey' => 'from_id'
)
);
}
Then here is my view
<div class="messages form">
<?php echo $this->Form->create('Message');?>
<fieldset>
<legend><?php __('Add Message'); ?></legend>
<?php
echo $this->Form->input('to_id');
echo $this->Form->input('from_id');
echo $this->Form->input('subject');
echo $this->Form->input('message');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit', true));?>
</div>
<div class="actions">
<h3><?php __('Actions'); ?></h3>
<ul>
<li><?php echo $this->Html->link(__('List Messages', true), array('action' => 'index'));?></li>
</ul>
</div>
It displays a drop down box, but no users in it. I have atleast 5 users in the users table
even if i add prefix like so
echo $this->Form->input('Sender.to_id');
echo $this->Form->input('Recipient.from_id');
still doesn't work
Like stated by Mark it doesn't work if you don't stick to convention. Rename the foreignkeys, Sender => sender_id, Recipient => recipient_id
You have to make the lists in the controller first
in the message controller
$senders = $this->Message->Sender->find('list');
$recipients = $this->Message->Recipient->find('list');
$this->set(compact('senders', 'recipients'));
Then in the view
echo $this->Form->input('recipient_id');
echo $this->Form->input('sender_id');