laravel how to add validation rule based on custom database query - laravel

I want the user to input postal code then in register controller I want to validate that postal code against postal code database I have so if the user provided postal code is in my database it will success despite of the formatting he/she used and what I mean by that is I want the validation to success whether he/she use spaces or no spaces at all.
the query I would like to use:
$postalcode=$data['postal_code'];
zipcodes::whereRaw('replace(POSTAL_CODE,\' \',\'\')=? ',[str_replace(' ','',$postal_code)
I tried to use the following in my validation:
Rule::exists('zipcodes','POSTAL_CODE')->where(function ($query) use($postalcode) {
// die($postalcode);
$query->whereRaw('replace(POSTAL_CODE,\' \',\'\')=? ',[str_replace(' ','',$postalcode)]);
})
but it does not do what I want and it seems to already try to find if postal code exist in zipcodes table before performing mysql replace or php str_replace.
so please any suggestions?

The easiest way to do this is use Laravel's validate() method.
https://laravel.com/docs/5.7/validation
You can use the Exists validation rule. It will check the database you tell it to and if the record exists, if it does then it will show as valid.
If you need to trim the spaces before validation, first just do $request->postal_code = str_replace(' ', '', $request->postal_code); before you call the validate method.
Here is a complete example:
$request->postal_code = str_replace(' ', '', $request->postal_code);
$request->validate([
'postal_code' => 'required|exists:zipcodes',
]);

Related

Laravel Validation - Individual rule and individual field problem

i have a field in Laravel with the name "company_url". and its stored like this.
$post['company_url'] = "http://example.org";
and then i have a rule string which i have stored for validation which must be applied on this individual field. which is stored like this
$post['rule'] = "required|max:24";
now i am trying this code to get validation errors. which is not working.
$validator = Validator::make([$post['name']], [$post['rules']]);
tell me what is the way to get errors on this validation?
The data you're passing to make() is in incorrect format. It should be in key-value pair format.
Also I don't know where the $post['name'] coming from. I assume it is company_url not name.
$post['rules'] is also undefined. It should be $post['rule']
The following should work:
$validator = Validator::make(['company_url' => $post['company_url']], ['company_url' => $post['rule']]);

What do "except" and "idColumn" refers in "unique:table,column,except,idColumn"? from Laravel docs

To validate the update of the e-mail of a user already registered I have the next function to exclude the "unique" rule for the current User:
public function updateRules() {
return [
'name' => 'required',
'email' => 'required|unique:users,email,'.$this->id,
];
}
In the Laravel docs https://laravel.com/docs/5.7/validation#rule-unique I found the syntax unique:table,column,except,idColumn with 4 parameters:
table: refers to the table name "users"
column: refers the column name "email"
except: I'm taking it as the id of the Model instance I want to exclude from the "unique" verification
idColumn: I have no idea about this
Someone could clarify what do except and idColumn refers to?
Note for those obsessed with duplicate questions: I'm not asking how to do the rule exclusion for the update, because it seems to work just fine, I've read those questions and answers. I'm making helper functions and I need to know exactly what those two parameters means.
So you are right about the except parameter, it is the id that you want to be excluded from the check.
And idColumn is optional in case your column is not called id but user_id for example. So you will use:
'required|unique:users,email,'.$this->id . ',user_id';

Laravel validation: unique with multiple columns and soft_delete

I am trying to do a Laravel validation rules as follow:
"permalink" => "required|unique:posts,permalink,hotel_id,deleted_at,NULL|alpha_dash|max:255",
The explanation to the rules is:
I have a table "Posts" in my system with the following fields (among others): hotel_id, permalink, deleted_at. If MySQL would allow make an unique index with null values, the sql would be:
ALTER TABLE `posts`
ADD UNIQUE `unique_index`(`hotel_id`, `permalink`, `deleted_at`);
So: I just add a new row IF: the combination of hotel_id, permalink and deleted_atfield (witch must be NULL) are unique.
If there is already a row where the permalink and hotel_id field are the same and 'deleted_at' field is NULL, the validation would return FALSE and the row wouldnt be inserted in the database.
Well. I don't know why, but the query Laravel is building looks like:
SELECT count(*) AS AGGREGATE FROM `posts`
WHERE `hotel_id` = the-permalink-value AND `NULL` <> deleted_at)
What the heck...
The query I was hoping Laravel build to validation is:
SELECT count(*) AS AGGREGATE FROM `posts`
WHERE `permalink` = 'the-permalink-value' AND `hotel_id` = ? AND `deleted_at` IS NULL
Could someone explain me how this effectively works? Because everywhere I look it looks like this:
$rules = array(
'field_to_validate' =>
'unique:table_name,field,anotherField,aFieldDifferentThanNull,NULL',
);
Does anyone could help me?
Thank you
all.
Finally, I got a proper understanding of the validation (at least, I think so), and I have a solution that, if it is not beautiful, it can helps someone.
My problem, as I said before, was validate if a certain column (permalink) is unique ONLY IF other columns values had some specific values. The problem is the way Laravel validation string rules works. Lets get to it:
First I wrote this:
"permalink" => "required|unique:posts,permalink,hotel_id,deleted_at,NULL|alpha_dash|max:255",
And it was generating bad queries. Now look at this:
'column_to_validate' => 'unique:table_name,column_to_validate,id_to_ignore,other_column,value,other_column_2,value_2,other_column_N,value_N',
So. The unique string has 3 parameters at first:
1) The table name of the validation
2) The name of the column to validate the unique value
3) The ID of the column you want to avoid (in case you are editing a row, not creating a new one).
After this point, all you have to do is put the other columns in sequence like "key,value" to use in your unique rule.
Oh, easy, an? Not so quickly, paw. If you're using a STATIC array, how the heck you will get your "currently" ID to avoid? Because $rules array in Laravel Model is a static array. So, I had to came up with this:
public static function getPermalinkValidationStr() {
$all = Input::all();
# If you are just building the frozenNode page, just a simple validation string to the permalink field:
if(!array_key_exists('hotel', $all)) {
return 'required|alpha_dash|max:255';
}
/* Now the game got real: are you saving a new record or editing a field?
If it is new, use 'NULL', otherwise, use the current id to edit a row.
*/
$hasId = isset($all['id']) ? $all['id'] : 'NULL';
# Also, check if the new record with the same permalink belongs to the same hotel and the 'deleted_at' field is NULL:
$result = 'required|alpha_dash|max:255|unique:posts,permalink,' . $hasId . ',id,hotel_id,' . $all['hotel'] . ',deleted_at,NULL';
return $result;
}
And, in the FrozenNode rules configuration:
'rules' => array(
'hotel_id' => 'required',
'permalink' => Post::getPermalinkValidationStr()
),
Well. I dont know if there is a easiest way of doing this (or a much better approach). If you know something wrong on this solution, please, make a comment, I will be glad to hear a better solution. I already tried Ardent and Observer but I had some problems with FrozenNode Administrator.
Thank you.

Laravel - validation localization doesn't work

Whenever I use the trans() function to return a specific translation from the validation.php file, it works just perfectly. I have two languages in my application and the translations get returned for both of them.
However, whenever I use the Laravel validator, it returns messages in the default locale only. Is there something I need to specify in the validator? How do I make it work for both languages?
You need to pass as 3rd parameters your translations. Let's assume you have defined your fields, rules and validator like in the following code:
$data = Input::only('title');
$rules['title'] = 'required|min:20|max:80',
$validator = Validator::make($data, $rules,
Lang::get('forms.validation.entry'));
Now you need to define your translations. Let's assume you need translation for fr lang so you need co create lang/fr/forms.php file and put the following content into it:
<?php
return
array (
'validation' => array (
'entry' => array (
'title.required' => 'Your translation for title required',
'title.min' => 'Your translation for title min',
'title.max' => 'Your translation for title max',
)
)
);
Of course you can create file with simpler array but it's just example - instead of forms.validation.entry it could be for example just forms or validation.
The problem originated from my localization implementation. I've added App::setLocale(Session::get('lang')); to the App::before() method in the filters.php file and it all works now.
in resources/lang/en folder laravel have validation.php. When you create new language so you can copy this file to new created language folder and then edit it to this language.
for example you wanna create fr language
.
/resources/lang/fr/validation.php and translate it to this language

Laravel 4: making a combination of values/columns unique

I'm importing a bunch of csv entries in my database with Laravel 4.
I can't really point at one column that has to be unique, it's a combination of 5 columns that makes it unique. However: how does one define this in Laravel?
Option 1: schema builder
You can use the $table->unique('email') method, but that only seems to allow one column, not a combination of columns.
Option 2: Validation
Less preferable, but I could validate the model before inserting it. However, again, using 'unique:[table]' validation rules, it will return an error when just one of the column values isn't unique, not a combination of them.
Can anyone tell me how I should go about this?
I'm sure I'm missing something, but I could use a push in the right direction :-)
Thanks,
Dieter
You can combine:
$table->unique( array('email','name') );
And pretty much everything in Laravel will accept arrays to do whatever you need to with 'more than one'.
Use Schema Builder's unique() method to define your data model, as Antonio mentioned.
Additionally, if you want to use validation on your model, consider my custom Validator rule for multiple UNIQUE indexes: https://github.com/felixkiss/uniquewith-validator
You can also do this;
$table->unique(["column1", "column2"], 'uq_columns');
Which means that you will have a unique column combination of all the columns i.e. column1 and column2
I know this question is for Laravel 4, but I just came across this on searches and found a solution for Laravel >= 5.3
Here it is:
Of course, the migration may look something like
$table->unique( array('email','name') );
Then to validate this, you do not need to use custom rules, just advanced rules:
'email' => Rule::unique('users')->where(function ($query) use ($request) {
return $query->where('name', $request->name);
}),
Of course, you may want to validate name before of this. The name should be required so that you may finish with something like this:
'name' => 'required|max:255',
'email' => Rule::unique('users')->where(function ($query) use ($request) {
return $query->where('name', $request->name);
}),
I hope it helps.
You can try this
$table->string("name");
$table->string("email")->unique("name")

Resources