I'm writing a contact form and want to add some simple validation routines. The action for this page looks like this:
public function contact() {
$this->loadModel('Contact');
$this->set('pageTitle', 'Contact me');
}
and the Contact model is this:
<?php
class Contact extends AppModel {
public $useTable = false;
public $validate = array(
'name' => array(
'between' => array(
'rule' => array('between', 1, 60),
'message' => 'Between 1 and 60 characters in length'
)
),
'email' => array(
'kosher' => array(
'rule' => 'email',
'message' => 'Please make sure your email is entered correctly'
),
),
'message' => array(
'between' => array(
'rule' => array('between', 1, 65000),
'message' => 'Between 1 and 65000 characters in length'
)
)
);
}
and finally my view page:
<?php echo $this->Form->create('Contact'); ?>
<?php echo $this->Form->input('name'); ?>
<?php echo $this->Form->input('email'); ?>
<?php echo $this->Form->input('message', array('type' => 'textarea')); ?>
<?php echo $this->Form->end(array('label' => 'Send', 'class' => 'btn btn-primary')); ?>
However, when I submit the form with incorrect values the validation routines aren't called and no error messages are shown.
How can I get Cake to validate the form?
In your contact action all you are doing is loading the Contact model. You have to explicitly call the relevant model method to perform validation. Read the manual properly for how to do that.
Look in the documentation for how to insert/update data from a form in the controller. You'll see something like this:
if ($this->request->is('post')) {
if ($this->Contact->save($this->request->data)) {
// handle the success.
} else {
$this->Session->setFlash(__('The Contact could not be saved. Please, try again.'));
}
}
Related
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');
I have a very simple model User, and it's associated table users with fields 'id', 'username', 'password', 'role', 'created', 'modified'.
The view add.ctp contains:
<div class="users form">
<?= $this->Form->create('user'); ?>
<fieldset>
<legend><?= __('Add user');?></legend>
<?= $this->Form->input('user.username'); ?>
<?= $this->Form->input('password'); ?>
<?= $this->Form->input('role', array('options' => array('admin' => 'Admin', 'customer' => 'Customer'))); ?>
</fieldset>
<?= $this->Form->end(__('Submit')); ?>
</div>
The model is set up according to http://book.cakephp.org/2.0/en/tutorials-and-examples/blog-auth-example/auth.html:
class User extends AppModel {
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'You must specify a username'
)
),
'password' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'You must specify a password'
)
),
'role' => array(
'valid' => array(
'rule' => array('inList', array('admin','customer')),
'message' => 'You must specify a valid role',
'allowEmpty'=> false
)
)
);
}
And lastly, the controller simply has:
public function add() {
if($this->request->is('post')) {
$this->User->create();
if ($this->User->save($this->request->data)) {
$this->set('stuff', $this->User->data);
$this->Session->setFlash(__('The user has been saved.'));
//return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The user could not be saved. Please try again.'));
}
}
}
I've commented out the redirect on success to be able to show the INSERT query on submit (if I allow the redirect, the only query being shown is SELECT's)
So, quite simple, the problem is, when the form is submitted, it generates this query:
INSERT INTO `mytable`.`users` (`modified`, `created`) VALUES ('2014-02-21 13:03:11', '2014-02-21 13:03:11')
How can I determine why it won't insert the submitted fields? And how can I make it?
use this <?= $this->Form->create('User'); ?> instead of <?= $this->Form->create('user'); ?>
and use this <?= $this->Form->input('User.username'); ?> instead of <?= $this->Form->input('user.username'); ?>
CakePHP is case sensitive model name must be in CamalCase
I have created a Controller, a model and a view for this. I want to make a form in CakePHP. But this is not working and till now I cannot understand the reason why is this happening...
My code for the controller is:
class MlistsController extends AppController {
public $helpers = array('Html','Form');
public function create() {
if ($this->request->is('post')) {
if ($this->Mlist->save($this->request->data)) {
$this->Session->setFlash(__('okay..'));
$this->redirect('action' => 'index');
}
}
}
}
My Model is:
App::uses('AuthComponent', 'Controller/Component');
class MList extends AppModel {
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
$this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
}
return true;
}
public $validate = array(
'listname' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A listname '
)
),
'replyto' => array(
'required' => array(
'rule' => array('notEmpty'),
'email' => 'email'
)
),
'fromName' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'Your name'
)
),
'subject' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A subject '
)
),
'reminder' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A reminder '
)
),
'contactsfile' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'custom message'
)
));
}
And my view file create.ctp is:
<h2>Create new list</h2>
<?php
$this->Form->create('Mlist');
echo $this->Form->input('listname',array('label' => 'Your ListName:'));;
echo $this->Form->input('replyto',array('label' => 'Reply To email:'));
echo $this->Form->input('fromName',array('label' => 'From Name:'));
echo $this->Form->input('subject',array('label' => 'mail subject:'));
echo $this->Form->input('reminder',array('label' => 'Reminder'));
echo $this->Form->input('contactsfile',array('label' => 'Upload your file','type' => 'file'));
echo '<br />';
echo $this->Form->end('submit');
Finally, the Submit button of the form is not even green, but grey and does not function when I click it. Also the star symbol (*) is not showing apart the form labels where the fields are required...
Can you help me with this issue?
You're kind of bypassing Cake's 'Convention over configuration' paradigm.
In order for these conventions to work Cake uses the Inflector Class which handles the plural forms of English words.
So when you use an appropriate (to this convention) naming policy it will work for you "out of the box". Otherwise you will have to configure the Model, Controller and any Helpers/Components/Behaviours you're using. They all have configuration parameters for this, but there is not a big point in doing this static configuration with Cake since you will also have to go through it again if you rename a DB table for example.
I's just against the idea of Cake. If you need to do this just use some other configuration based framework.
I believe the problem is in your view. You also have to echo the starting of the form:
echo $this->Form->create('Mlist');
The naming convention is ok. Cake doesn't have any database of real english words, only few irregularities (see arrays in http://api.cakephp.org/2.3/source-class-Inflector.html) so anything like Mlist is just pluralized with adding "s" at the end.
I have built a simple CakePHP app with a users login system and have hooked up the Cake Form plugin by Milesj.me (not sure if that's causing the problems).
However my validation seems to have applied itself to the login form as well as the signup form. So when I try and login, I am getting errors like 'Username already in use'.
Any ideas what would cause this? Has something changed in CakePHP that adds the validation to authentication forms as well?
Also why am I having to hash the password in the model? I was under the impression that CakePHP hashed passwords automatically? And I've not needed to do it before. However If I don't do it, then it was saving the password in the DB as in and not hashed...
Here is my view, controller and model:
<?php echo $this->Form->create(); ?>
<?php echo $this->Form->input('User.username',
array('tabindex'=>1, 'autofocus',
'label'=>array('class'=>'placeholder','text'=>'Username'))); ?>
<?php echo $this->Form->input('User.password',
array('tabindex'=>2, 'type'=>'password',
'label'=>array('class'=>'placeholder','text' =>'Password' ))); ?>
<div class="input button">
<button class="orangeButton" tabindex="3" type="submit"><span class="icon login">Log in</span></button>
</div>
<?php echo $this->Form->end(); ?>
controller:
public function login() {
if ($this->request->data) {
$this->User->set($this->request->data);
if ($this->User->validates() && $this->Auth->login()) {
if ($user = $this->Auth->user()) {
$this->User->Profile->login($user['id']);
$this->Session->delete('Forum');
$this->redirect($this->referer());
}
}
}
}
Note: the calls to Profile model for login just saves some data for when last logged in and other stuff and doesn't actually do anything regarding authentication!
and the model:
class User extends AppModel {
public $name = 'User';
public $hasOne = array(
'Profile' => array('className' => 'Forum.Profile')
);
public $hasMany = array(
'Access' => array('className' => 'Forum.Access'),
'Moderator' => array('className' => 'Forum.Moderator')
);
public $validate = array(
'email' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A valid email address is required'
),
'email' => array(
'rule' => array('email'),
'message' => 'This is not a valid email address'
),
'unique' => array(
'rule' => array('isUnique'),
'message' => 'This email is already in use'
)
),
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A username is required'
),
'unique' => array(
'rule' => array('isUnique'),
'message' => 'This username is already in use'
),
'alphaNumeric' => array(
'rule' => array('alphaNumeric'),
'message' => 'Usernames must only contain letters and numbers'
),
'between' => array(
'rule' => array('between', 4, 20),
'message' => 'Usernames must be between 4 and 20 characters long'
)
),
'password' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A password is required'
)
)
);
public function beforeSave()
{
if (isset($this->data[$this->alias]['password']))
{
$this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
}
return true;
}
Just add to your validation rules 'on' => 'create'
http://book.cakephp.org/2.0/en/models/data-validation.html#on
As per cakephp
In case of multiple rules per field by default if a particular rule
fails error message for that rule is returned and the following rules
for that field are not processed.
But if first rule doesn't fail, then it continue to evaluate second
rule.
You can remove particular validation by following way
$this->validator()->remove('username', 'unique');
I am new to CakePHP. When I am using Model Field Validations then it is showing error message infront of each required form field. I want to show it in a div at the top of the form. How I can implement it. Thanks in advance.
Here is my Code:
Model:
<?php
class User extends AppModel {
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A username is required'
),
array(
'rule' => array('minLength', 8),
'message' => 'Username must be at least 6 characters long'
)
),
'password' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A password is required'
)
),
'city' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A City is required'
)
),
'state' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A State is required'
)
),
'role' => array(
'valid' => array(
'rule' => array('inList', array('admin', 'author')),
'message' => 'Please enter a valid role',
'allowEmpty' => false
)
)
);
}
UsersController.php
public function add() {
$this->set('states_options', $this->State->find('list', array('fields' =>array('id','name') )));
$this->set('cities_options', array());
if ($this->request->is('post')) {
$this->User->set($this->request->data);
if($this->User->validates())
{
$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.'));
}
}
else {
$errors = $this->User->validationErrors;
$this->set('ValidateAjay',$errors);
//pr($errors);die;
}
}
}
User View:
<!--<script src="http://code.jquery.com/jquery-1.7.2.js"></script>-->
<script>
$(document).ready(function(){
$('#UserState').change(function(){
var stateid=$(this).val();
$.ajax({
type: "POST",
url: "checkcity",
data:'stateid='+stateid+'&part=checkcity',
success: function(data) {
$("#city_div").html(data);
}
});
});
});
</script>
<div class="users form">
<?php
if(!empty($ValidateAjay)){
pr($ValidateAjay);
}
echo $this->Form->create('User'); ?>
<fieldset>
<legend><?php echo __('Add User'); ?></legend>
<?php
echo $this->Form->input('username');
echo $this->Form->input('password');
echo $this->Form->input('state', array('options' => $states_options , 'empty' => 'Select State' ));
?>
<div id="city_div">
<?php
echo $this->Form->input('city', array('options' => $cities_options, 'empty' => 'Select City' ));
?>
</div>
<?php
echo $this->Form->input('role', array(
'options' => array('admin' => 'Admin', 'author' => 'Author')
));
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>
You can get all validation errors from the $this->validationErrors variable on the view. Then feel free to iterate through them and display as you like. They will be organized by model, like so:
array(
'User' => array(
'username' => 'This field cannot be empty.',
'password' => 'This field cannot be empty.'
)
);
Then you can iterate through them on the view and display them as such. This example displays them as an unordered list:
$errors = '';
foreach ($this->validationErrors['User'] as $validationError) {
$errors .= $this->Html->tag('li', $validationError);
}
echo $this->Html->tag('ul', $errors);
Lastly, you can hide the form helper's automatic error messages by hiding them with CSS or setting the FormHelper defaults to not show them.
CSS
.input.error {
display: none;
}
or
in the view
$this->Form->inputDefaults(array(
'error' => false
));
jeremyharris example makes a lot of sense, however if you don't want to manually set loop for every form field, you can try this:
$errors = '';
foreach($this->validationErrors as $assoc) {
foreach ($assoc as $k => $v) {
$errors .= $this->Html->tag('li', $v);
}
}
echo $this->Html->tag('ul', $errors);
So if your validation returns multiple errors, the output will looks like this:
- A username is required
- A password is required
Though this is a very old post, I'd like to answer my solution here as well.
To get Errors of Model Validations, just use the $model->getErrors();. This will return an array of errors with field key.
Example
$errors = $user->getErrors();