I want to validate Bank Account number(123456789) and Routing number(434344343),
with custom message=>Please enter 12 digit valid account number.(000123456789)
I used number validator, integer but not working as I expecting.
Validator should checks values are numbers and also numbers length.
I check this documentation here tutorial-core-validators
public function rules()
{
return [
[['accountnumber'], 'number', 'min' => 12, 'max'=>12],// not wokred
[['routingnumber'], 'number', 'min' => 9, 'max'=>9], // not wokred
// then I used
[['accountnumber', 'routingnumber', ], 'integer']
]
}
Any suggession?
The min and max parameters are for the value, not the lenght, maybe you should save as a string.
['accountnumber', 'string', 'length' => [12, 12]
And also add a regular expression:
['accountnumber', 'match', 'pattern' => '/^[0-9]*$/i']
Try this:
public function rules()
{
return [
[['accountnumber'], 'string', 'min' => 12, 'max'=>12, 'message' => "Please enter 12 digit valid account number"],
[['routingnumber'], 'string', 'min' => 9, 'max'=>9],
[['accountnumber', 'routingnumber', ], 'integer'],
]
}
Minimum, Maximum Number Validation
public function rules(){
return [
[['accountnumber'],'number','min'=>10],
[['accountnumber'],'number','max'=>100],
[['accountnumber'],'number','min'=>10,'max'=>100],
];
}
Minimum, Maximum String Validation
public function rules(){
return [
[['min_string'],'string','min'=>10],
[['max_string'],'string','max'=>10],
[['min_max_string'],'string','min'=>5,'max'=>10],
['min_max_string2', 'string', 'length' => [4, 10]],
];
}
Custom Validation
public function rules(){
return [
['custom_validation','custom_function_validation', 'values'=>['One', 'Two']],
];
}
public function custom_function_validation($attribute, $params){
// add custom validation
if (!in_array($this->$attribute, $params['values']))
$this->addError($attribute,'Custom Validation Error');
}
Related
In model I have defined multiple scenarios:
public function rules() {
return [
[['in_quantity'], 'required','on'=>['stockIn']],
[['out_quantity'], 'required','on'=>['stockOut']],
];
}
Is it possible to use both scenario stockIn and stockOut for single model validation?
$StockModel->scenario[] = 'stockOut';
$StockModel->scenario[] = 'stockIn';
or
$StockModel->scenario = ['stockOut','stockIn'];
You can't have multiple scenarios for model. But you can have multiple scenarios for rule:
public function rules() {
return [
[['in_quantity'], 'required', 'on' => ['stockIn', 'stockOut']],
[['out_quantity'], 'required', 'on' => ['stockIn', 'stockOut']],
];
}
If you need multiple scenarios for model, it means that you're overusing scenarios feature.
Also note that it is not recommended to use too many scenarios in one model - scenarios work fine for simple cases, but more complicated cases should be handled by separate models for each scenario.
You can create multiple scenarios this way in model
class MyModel extends \yii\db\ActiveRecord {
const SCENARIO_CREATE = 'scenario_create';
const SCENARIO_UPDATE = 'scenario_update';
// get scenarios
public function scenarios()
{
return [
self::SCENARIO_CREATE => ['user_id', 'name', 'desc', 'published','date_create'],
self::SCENARIO_UPDATE => ['user_id', 'name', 'desc', 'date_update'],
];
}
public function rules()
{
[['user_id'], 'integer'],
[['name','desc'], 'string', 'max' => 70],
[['date_create', 'date_update'], 'date', 'format' => 'php:Y-m-d H:i:s'],
];
}
}
and you can use this way anywhere
public function actionIndex() {
$model = new MyModel;
$model->scenario = MyModel::SCENARIO_CREATE;
if ($model->load(\Yii::$app->request->post())){
if($model->save()){
// some operations
}
}
}
You could if you extend the rule with when for server validation:
[
['in_quantity'],
'required',
'when' => function ($model) {
return $model->scenario === 'stockIn' || $model->scenario === 'stockOut';
}
]
Also if you want to validate in the form (aka client side validation) you could also use the whenClient that expect a js function:
'whenClient' => "function (attribute, value) {
const scenario = $('#stock-scenario').val()
return scenario === 'stockIn' || scenario = 'stockOut';
}"
It's the first time i am using validation in laravel. I am trying to apply validation rule on below json object. The json object name is payload and example is given below.
payload = {
"name": "jason123",
"email": "email#xyz.com",
"password": "password",
"gender": "male",
"age": 21,
"mobile_number": "0322 8075833",
"company_name": "xyz",
"verification_status": 0,
"image_url": "image.png",
"address": "main address",
"lattitude": 0,
"longitude": 0,
"message": "my message",
"profession_id": 1,
"designation_id": 1,
"skills": [
{
"id": 1,
"custom" : "new custom1"
}
]
}
And the validation code is like below, for testing purpose i am validating name as a digits. When i executed the below code, the above json object is approved and inserted into my database. Instead, it should give me an exception because i am passing name with alpha numeric value, am i doing something wrong:
public function store(Request $request)
{
$this->validate($request, [
'name' => 'digits',
'age' => 'digits',
]);
}
Please try this way
use Validator;
public function store(Request $request)
{
//$data = $request->all();
$data = json_decode($request->payload, true);
$rules = [
'name' => 'digits:8', //Must be a number and length of value is 8
'age' => 'digits:8'
];
$validator = Validator::make($data, $rules);
if ($validator->passes()) {
//TODO Handle your data
} else {
//TODO Handle your error
dd($validator->errors()->all());
}
}
digits:value
The field under validation must be numeric and must have an exact length of value.
I see some helpful answers here, just want to add - my preference is that controller functions only deal with valid requests. So I keep all validation in the request. Laravel injects the request into the controller function after validating all the rules within the request. With one small tweak (or better yet a trait) the standard FormRequest works great for validating json posts.
Client example.js
var data = {first: "Joe", last: "Dohn"};
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST",'//laravel.test/api/endpoint');
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp.send(JSON.stringify(data));
project/routes/api.php
Route::any('endpoint', function (\App\Http\Requests\MyJsonRequest $request){
dd($request->all());
});
app/Http/Requests/MyJsonRequest.php (as generated by php artisan make:request MyJsonRequest)
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class MyJsonRequest extends FormRequest{
public function authorize(){
return true;//you'll want to secure this
}
public function rules(){
return [
'first' => 'required',
'last' => 'required|max:69',
];
}
//All normal laravel request/validation stuff until here
//We want the JSON...
//so we overload one critical function with SOMETHING LIKE this
public function all($keys = null){
if(empty($keys)){
return parent::json()->all();
}
return collect(parent::json()->all())->only($keys)->toArray();
}
}
Your payload should be payload: { then you can do
$this->validate($request->payload, [
'name' => 'required|digits:5',
'age' => 'required|digits:5',
]);
or if you are not sending the payload key you can just use $request->all()
$request->merge([
'meta_data' => !is_null($request->meta_data) ? json_encode($request->meta_data) : null
]);
validator = Validator::make($request->all(), [
'meta_data' => 'nullable|json'
]);
Use the Validator factory class instead using validate method derived from controller's trait. It accepts array for the payload, so you need to decode it first
\Validator::make(json_decode($request->payload, true), [
'name' => 'digits',
'age' => 'digits',
]);
Following the example of #tarek-adam, in Laravel 9 it would be:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class MyJsonRequest extends FormRequest{
public function authorize(){
return true;//you'll want to secure this
}
public function rules(){
return [
'first' => 'required',
'last' => 'required|max:69',
];
}
//All normal laravel request/validation stuff until here
//We want the JSON...
//so we overload one critical function with SOMETHING LIKE this
public function validationData()
{
if(empty($this->all())){
$res = [
'success' => false,
'message' => 'Check your request',
];
throw new HttpResponseException(
response()->json($res, 422)
);
}
return $this->all();
}
}
I am trying to create make a two-step form in yii2.
This is my SiteController.php
public function actionCreateCharacter()
{
$model = new Character();
var_dump(Yii::$app->request->post('Character'));
if ($model->load(Yii::$app->request->post())) {
$attributes=['imie','nazwisko','plec','wyznanie_id'];
if ($step1 = $model->validate($attributes)) {
//var_dump($step1);
// form inputs are valid, do something here
//var_dump(Yii::$app->request->post('Character');
return $this->render('createCharacterStep2', [
'model' => $model,
]);;
}
else {
// validation failed: $errors is an array containing error messages
$errors = $model->errors;
}
}
return $this->render('createCharacter', [
'model' => $model,
]);
}
public function actionCreateCharacterStep2()
{
$model2 = new Character();
var_dump($model);
if ($model2->load(Yii::$app->request->post())) {
var_dump(Yii::$app->request->post('Character'));
if ($model2->validate()) {
// form inputs are valid, do something here
return;
}
}
/*return $this->render('createCharacter2', [
'model' => $model,
]);*/
}
... and this is my Character.php (model + attributeLabels and tableName)
public function rules()
{
return [
[['user_id', 'imie', 'nazwisko', 'plec', 'wyznanie_id', 'avatar_src', 'avatar_svg'], 'required'],
[['user_id', 'wyznanie_id'], 'integer'],
[['avatar_svg'], 'string'],
[['imie'], 'string', 'max' => 15],
[['nazwisko'], 'string', 'max' => 20],
[['plec'], 'string', 'max' => 1],
[['avatar_src'], 'string', 'max' => 30]
];
}
I have access to $_POST by Yii::$app->request->post() in createCharacter - I get imie, nazwisko, plec and wyznanie_id.
But when I send the form in step 2 I have only post data from step 2.
How can I set the post data from step1+step2?
Sorry for my english and thanks in advance.
While rendering step2 from step1 action, you can always pass additional data to controller's action. So I added "STEPONEPOSTS" post variable which contains all posts of step 1. Check below.
public function actionCreateCharacter()
{
$model = new Character();
var_dump(Yii::$app->request->post('Character'));
if ($model->load(Yii::$app->request->post())) {
$attributes=['imie','nazwisko','plec','wyznanie_id'];
if ($step1 = $model->validate($attributes)) {
//var_dump($step1);
// form inputs are valid, do something here
//var_dump(Yii::$app->request->post('Character');
return $this->render('createCharacterStep2', [
'model' => $model,
'STEPONEPOSTS' => Yii::$app->request->post(),
]);;
}
else {
// validation failed: $errors is an array containing error messages
$errors = $model->errors;
}
}
return $this->render('createCharacter', [
'model' => $model,
]);
}
And now in step 2 view, you can get step 1 posts variable as
$STEPONEPOSTS
There is another way , if you have to table for step 1 and step 2. then save the data of step 1 first then step2 data. if you are not using two tables then you can create two form each form for each step and also create scenarios for each step according to the fields.I think this may help . You can use session also as per discussion in comments or you can use the extension array wizard but array wizard extension is not well documented , so i suggest you try my way i will help you.
Being trying to sort this out but going nowhere with it. I have got an array as attribute for a model and I am trying to create custom validation for some of the keys in the array as required. Or even can't figure out how the attribute labels will work? Here is my code:
MODEL
...
public $company = [
'name' => '',
'trading_name' => '',
'type' => '',
];
public function attributeLabels(){
return [
'company[name]' => 'Company Name',
];
}
public function rules(){
return [
[['company[name]','company[trading_name'], 'safe'],
[['company[name]'], 'return_check','skipOnEmpty'=> false],
];
}
public function return_check($attribute, $params){
$this->addError($attribute ,'Required ');
return false;
}
...
I have even tried to pass the whole array and check in the validator method for the keys and values but the custom validator is not even triggered.
I think you need separated model for company.
I've used custom rule functions, and they all worked. Try removing the return clause at the end of the return_check function.
Here's what has worked for me:
class Essid extends ActiveRecord {
public function rules() {
return [
['network_name', 'checkNetworkName']
]
}
public function checkNetworkName($attribute, $params){
if (!$this->hasErrors()) {
if ( !ctype_alnum($this->network_name) )
$this->addError($attribute, Yii::t('app', 'Not a valid Network Name'));
}
}
}
Hope it helps
Why is it that when I retrieve a record from model, it returns the variable that I declared instead of the fields in the table.
This is my controller function
public function actionGetsp()
{
//$sp_id=$_POST['sp_id'];
$model = TblSubProject::find()->select('sp_title, brgy_code')->all();
return json_encode($model);
}
and here is a part of my model.
class TblSubProject extends \yii\db\ActiveRecord
{
public $province;
public $region;
public $city_code;
/**
* #inheritdoc
*/
public static function tableName()
{
return 'tbl_sub_project';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['city_code','brgy_code', 'sp_id', 'sp_title', 'sp_grant', 'lcc', 'modality'], 'required'],
[['sp_id'], 'integer'],
[['sp_grant', 'lcc'], 'number'],
[['brgy_code'], 'string', 'max' => 9],
[['sp_title'], 'string', 'max' => 500],
[['modality'], 'string', 'max' => 50],
[['sp_id'], 'unique']
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'brgy_code' => 'Brgy Code',
'sp_id' => 'Sp ID',
'sp_title' => 'Sp Title',
'sp_grant' => 'Sp Grant',
'lcc' => 'Lcc',
'modality' => 'Modality',
'city_code' => 'City / Municipality',
'brgy_code' => 'Barangay',
'brgyCode.cityCode.province.prov_name' => 'Province',
'brgyCode.cityCode.city_name' => 'City / Municipality',
'brgyCode.brgy_name' => 'Barangay',
];
}
}
And here is sample output..
As you can say, it returns the province, region, and the city_code which is not an attribute in the table but just a declared variable. I want to retrieve like the si_title.
It's a normal Yii ActiveRecord behaviour - it replaces table attributes with declared ones. You don't have do declare them: all table fields are already available as $model->$field.