Im new to cakePHP.I just learning the way to validate the data before storing into the database.I just did the following validation to check the birth date given by the user.
class User extends AppModel {
public $name = "Users";
public $validate = array (
'birth_dt' => array ( 'rule' => 'date',
'required' => true,
'allowEmpty' => false,
'message' => 'Please Give valid date' ));
}
I expected a error message when I give wrong data in the birth_dt field.But there is no errors in case of wrong data ,bug the data is not getting store in the database.If I give the valid data also the data is not getting stored.If I remove the validation part then data getting stored in the database.
It not only happen for date ,it happen for other fields like alphaNumeric ,email which I used in my form.Any one please tell what I did wrong.
This is my controller code,
<?php
class UsersController extends AppController{
var $name = 'Users';
var $uses = array('User','Dob');
var $helpers = array('Form');
function index() {
if ($this->request->is('post')) {
if ($this->request->data) {
$this->User->save ( $this->request->data );
$this->Session->setFlash("User Added!");
$this->redirect('/users');
}
}
}
There can be multiple possible issue.Try following.
Before saving user Create new record like this->User->create();
You don't have else part. Write like following in else & check,
else {
$this->Session->setFlash(__('User could not be saved',true));
}
You can check why save() failed by examining the validationErrors array in the User model. From the UsersController it can be access via $this->User->validationErrors.
Furthermore, your controller logic isn't quite right. A was mentioned in some of the comments, you don't check if save() was successful and you always state that a user was added, even when it's not true.
Try something like this:
if($this->request->is('post') && !empty($this->data)) {
if($this->User->save($this->data)) {
$this->Session->setFlash('User added!', 'flash_good');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('Could not add player.', 'flash_bad');
}
}
This way, when save() fails for some reason, the user will remain in that action and the form will still be populated with the data the user entered. Furthermore, if you use $this->Form->input(...) to create you form elements the validation errors will be added to the form automagically.
I think your public $validate is wrongly written
Try this
class User extends AppModel {
public $name = "Users";
//For more strict validation you should have more than one parameter
//submitted to the rule array for date which requires the user to enter
// exactly what you need. for example 01/01/12 instead of 01/01/2012
//Please check the following address
//http://book.cakephp.org/2.0/en/models/data-validation.html#Validation::date
//However, this should work fine.
public $validate = array (
'birth_dt' => array (
'rule' => array('date'),
'required' => true,
'allowEmpty' => false,
'message' => 'Please Give valid date'
)
);
}
I think best way for validation is to integrate server side and client side validation.
form fields should be validated on focus out/blur with ajax call to server side validation rules via your controllers. This will ensure consistency in server side and client side validation.
bla..bla :)
I think validate error message not show
because you use $this->redirect('/users');
when redirect cakephp will be render view that clear message error :)
You can comment line //$this->redirect('/users'); and then try again :)
Related
So i'm working on validating a form's inputs using the following code:
$request->validate([
'title' => 'bail|required|max:255',
'body' => 'required',
]);
So basically, there are two fields in the form, a title and a body and they have the above rules. Now if the validation fails I want to catch the error directly in the controller and before being redirected to the view so that I can send the error message as a response for the Post request. What would be the best way to do it?
I understand that errors are pushed to the session but that's for the view to deal with, but i want to deal with such errors in the controller itself.
Thanks
If you have a look at the official documentation you will see that you can handle the input validation in different ways.
In your case, the best solution is to create the validator manually so you can set your own logic inside the controller.
If you do not want to use the validate method on the request, you may create a validator instance manually using the Validator facade.
Here a little example:
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'bail|required|max:255',
'body' => 'required',
]);
// Check validation failure
if ($validator->fails()) {
// [...]
}
// Check validation success
if ($validator->passes()) {
// [...]
}
// Retrieve errors message bag
$errors = $validator->errors();
}
For someone who wants to know how to get validation errors after page redirection in the controller:
$errors = session()->get('errors');
if ($errors) {
//Check and get the first error of the field "title"
if ($errors->has('title')) {
$titleError = $errors->first('title');
}
//Check and get the first error of the field "body"
if ($errors->has('body')) {
$bodyError = $errors->first('body');
}
}
$errors will contain an instance of Illuminate/Contracts/Support/MessageBag
You can read more on the API here: https://laravel.com/api/8.x/Illuminate/Contracts/Support/MessageBag.html
Note: I have tested it in Laravel 8, it should work on Laravel 6+ if you get the MessageBag from the session
I have a form and after user submits the form and validation goes OK, I want to ask him for his email and nickname in modal window. If user fills and submit an email and nickname, I want to validate it and save it as new record or get id of existing one (in case email was already used in past). If validation is not successful, user should be able to correct values in the same modal. If everything is OK, I want to save the form including create user id.
I already have form saving and user create/find process done. I just do not know, how to put this together, to work in scenario I described above. Could anyone explain, how this should be done in Yii? I am using Yii 1.1.15 and Yii Booster. Thank you.
In Yii the _form.php view file is used both in update.php and create.php views by default.
So, you might need to do smth. similar: insert form with modal in both update.php and create.php views.
Actions and different for these, so you keep logic separate; this is the MVC basic advantage.
public function actionCreate() {
$model = new Users;
if (isset($_POST['Users'])) {
$model->attributes = $_POST['Users'];
if ($model->save()) { // here in the save() method the valadation is included
// ONLY after we validate and successfully saved we go to update action
$this->redirect(array('update', 'id' => $model->id));
}
}
$this->render('create', array(
'model' => $model,
));
}
The main thing is that when you try to save save() method the validation happend automatically.
So if validation is not successful the logic brings back to the same action (create for example) with fields populated in view since model is already having data passed into it: $model->attributes = $_POST['Users'].
If validation is successful we redirect further. Not nessesary ajax form submit, even casual submit fits here.
public function actionUpdate($id) {
$model = $this->loadModel($id);
if (isset($_POST['Users'])) {
$model->attributes = $_POST['Users'];
if ($model->save()) { // after saving EXISTING record we redirect to 'admin' action
$this->redirect(array('admin'));
}
}
$this->render('update', array(
'model' => $model,
));
}
Forms in views(update/create) you keep as originally designed.
Validation for uniqueness is simple in model rules():
array('username, email', 'unique'),
Email valadation for email syntax is seems like this:
array('email', 'email'),
I'm new to Yii framework. Now I'm using two textfields for min size and max size. Now this textfields are supposed to take only integers. But they are taking alphabets also. I used the following rule in model file.
public function rules() {
return array(
array('min_size, max_size', 'numerical', 'integerOnly'=>true));
}
But this seems to be not working, no error is displayed . How can i validate successfully, by displaying error when text is entered. Should I make some changes in main.php
Look for this kind of form in your code
<?php
$form = $this->beginWidget('CActiveForm', array(
'id' => 'trip-form',
'enableAjaxValidation' => true,
'enableClientValidation' => true,
?>
if you want ajax validation to take place then this line must be uncommented in controller
$this->performAjaxValidation($model);
Client validation will automatically take place
Just try Adding this instead of that
if (isset($_POST['ajax']) && $_POST['ajax'] === "your_form_id") {
echo CActiveForm::validate($model);
Yii::app()->end();
}
This will check with the model when the ajax request is received
Is there any way to use Validator on login form from Simple Authentication in Lithium tutorial. I know that it is better to use validation in model, but with login form there's no model, so, as I understand, I need to use Validator in the SessionsController, but I don't know how to do it (
What I am trying to do is in SessionsController:
<?php
namespace app\controllers;
use lithium\security\Auth;
use lithium\storage\Session;
use lithium\util\Validator;
class SessionsController extends \lithium\action\Controller {
private $rules = array(
'password' => array(
array('notEmpty', 'message' => 'password is empty'),
),
'email' => array(
array('notEmpty', 'message' => 'email is empty'),
array('email', 'message' => 'email is not valid')
)
);
public function add() {
if ($this->request->data && Auth::check('default', $this->request)) {
return $this->redirect('/');
}
// Handle failed authentication attempts
$errors = Validator::check($this->request->data, $this->rules);
return compact('errors');
}
public function delete() {
Auth::clear('default');
return $this->redirect('/');
}
/* ... */
}
and I'm expect that after empty form was sent, it will be rendered with errors, like in user creation from tutorial. But there are no errors showed, just login form again. Can I ever validate forms without models and how to do it in Lithium?
Thanks beforehand.
The errors rendered in the form are bound to an entity, which is bound to the form when you create it with $this->form->create($user). In this case only, the errors are displayed thanks to the form helper automatically.
If your need is to check, in the controller, the incoming data, you can check $this->request->data['password'] and return errors that you need to handle by yourself in the form view (with if (!empty($errors)) for example)
Description
I have a simple form on every page of my site - a single input and a submit button. The point is just for the user to enter his/her email address and hit submit.
It works if the data is an email address - but if it's not a valid email address, it submits the form, the page reloads (or whatever), and the flash message comes up instead of my model's more specific "not a valid email" error.
Question:
So, how do I use the model's validation message instead of the controller's generic one?
The form:
echo $this->Form->create('Email', array('class'=>'form1', 'url'=>'/emails/add', 'inputDefaults'=>array('label'=>false)));
echo $this->Form->input('Email.email');
echo $this->Form->end('SIGN-UP');
The email controller "add" function (or method?):
function add() {
if (!empty($this->data)) {
$this->Email->create();
if ($this->Email->save($this->data)) {
$this->Session->setFlash(__('The email address has been saved', true));
$this->redirect($this->referer());
} else {
$this->Session->setFlash(__('The email address could not be saved. Please, try again.', true));
$this->set('error', 'custom error here');
$this->redirect($this->referer());
}
}
}
And the email model:
class Email extends AppModel {
var $name = 'Email';
var $validate = array(
'email' => array(
'is_valid' => array( //named whatever we want
'rule' => 'notEmpty',
'rule' => array('email', true),
'message' => 'Please supply a valid email address.',
'last' => true //causes it to not check the next rule if this one fails
),
'is_unique' => array( //named whatever we want
'rule' => 'isUnique',
'message' => 'That email address is already in our database.'
)
),
);
}
Dave
CakePHP does this for you, you have set the validation correctly, the error is the REDIRECT if your save fails. This loses the post data and hence the validation messages
Simply
if ($this->Email->save($this->data)) {
$this->Session->setFlash(__('The email address has been saved', true));
$this->redirect($this->referer());
} else {
$this->Session->setFlash(__('There were problems saving, please see the messages below.', true));
}
Normally, you would use the $form helper's error options. See the section of the manual on this.
However, if you want to populate the flash message with the validation message, you can use the model method invalidFields(). Here is an example:
if (!$this->User->save($this->data)) {
$validationErrors = $this->User->invalidFields();
$this->Session->setFlash($validationErrors['email']); // named key of the rule
$this->redirect('/somewhere');
}
What this does is to get the messages written in model for the validation rules that failed. While invalidFields() returns an array, you can manipulate the values within it to produce a better error message, like for example, concatenating the different error messages.
Btw, I noticed something bad in your code above. You are naming your model class as 'Email' and there is a core CakePHP class already named Email (which is the famous Email component), so I suggest you name the whole MVC for that differently.