Laravel regex validation for price OR empty - php

I am trying to make a regex for price OR empty.
I have the price part (Dutch uses comma instead of point) which actualy works
/^\d+(,\d{1,2})?$/
The regex above validates ok on the value 21,99
Now I try to add the empty part so the field can be... just empty ^$
/(^$|^\d+(,\d{1,2})?$)/
But Laravel starts to complain as soon as I change the regex:
"Method [validate^\d+(,\d{1,2})?$)/] does not exist."
Works ok:
$rules = [
'price' => 'regex:/^\d+(,\d{1,2})?$/'
];
Laravel says no...:
$rules = [
'price' => 'regex:/(^$|^\d+(,\d{1,2})?$)/'
];
Kenken9990 answer - Laravel doesn't break anymore but an empty value is still wrong:
$rules = [
'price' => 'regex:/^(\d+(,\d{1,2})?)?$/'
];

is this work ?
$rules = [
'price' => 'nullable|regex:/^(\d+(,\d{1,2})?)?$/'
];

| is also the separator for multiple validation rules.
For example the following is valid:
$rules = [ "price" => "nullable|numeric|between:0,99" ];
To use it regex you need to switch to using an array:
$rules = [
'price' => [ 'regex:/(^$|^\d+(,\d{1,2})?$)/' ]
];
This is also pointed out in the documentation:
Note: When using the regex / not_regex patterns, it may be necessary to specify rules in an array instead of using pipe delimiters, especially if the regular expression contains a pipe character.
Incidentally the original rule might also do what you want and can also be written as:
$rules [
'price' => [ 'nullable', 'numeric', 'between:0,99' ]
]

Related

Laravel validate array and exclude on specific array value

I have an array of values that I send together with other fields in a form to laravel.
The array contains a role_id field and a status field, the status can be I (Insert) U (update) D (Delete). When I validate the values in the array I want it to skip the ones where the status equals D. Otherwise I want it to validate.
private function checkValuesUpdate($userid = null)
{
return Request::validate(
[
'displayname' => 'required',
'username' => 'required',
'email' => ['nullable', 'unique:contacts,email' . (is_null($userid ) ? '' : (',' . $userid ))],
'roles.*.role_id' => ['exclude_if:roles.*.status,D', 'required']
]
);
}
I can't seem to get it to work. I've been searching all over the place for functional code as well as the Laravel documentation. But no luck so far. Has anybody ever done this?
Your problem comes from a misunderstanding of the exclude_if rule. It doesn't exclude the value from validation, it only excludes the value from the returned data. So it would not be included if you ran request()->validated() to get the validated input values.
According to the documentation, you can use validation rules with array/star notation so using the required_unless rule might be a better approach. (Note there's also more concise code to replace the old unique rule, and I've added a rule to check contents of the role status.)
$rules = [
'displayname' => 'required',
'username' => 'required',
'email' => [
'nullable',
Rule::unique("contacts")->ignore($userid ?? 0)
],
'roles' => 'array',
'roles.*.status' => 'in:I,U,D',
'roles.*.role_id' => ['required_unless:roles.*.status,D']
];

Why regex \pL doesn't works inside laravel validation? [duplicate]

I'm having a small issue with my Laravel rules and regex operation :
Basically a rule is an array as such :
'room'=>'required|alpha_num|min:2|max:10',
The problem i'm having is when using regex and the | (or) operator such as :
'cid'=>'required|regex:/^((comp)|(soen)|(engr)|(elec))\d{3}$/i',
I'm getting a server error saying :
ErrorException
preg_match(): No ending delimiter '/' found
I'm guessing the preg_match is stopping at the first | inside the /.../.
Is there anyway to write the above code to make it work ?
Full code :
public static $rules = array(
'cid' => array('required', 'regex:/^((comp)|(soen)|(engr)|(elec))\d{3}$/i'),
'description'=>'required|regex:/^[A-Za-z \t]*$/i|min:3|unique:courses',
'credits'=>'required|regex:/^\d+(\.\d)?$/'
);
http://laravel.com/docs/validation#rule-regex
regex:pattern
The field under validation must match the given regular expression.
Note: When using the regex pattern, it may be necessary to specify rules in an array instead >of using pipe delimiters, especially if the regular expression contains a pipe character.
To clarify:
You would do something like this
$rules = array('test' => array('size:5', 'regex:foo'));
You should use an array instead of separating rules using |:
'cid' => array('required', 'regex:/^((comp)|(soen)|(engr)|(elec))\d{3}$/i')
The pipe (|) sigh is available in your regular expression pattern so it's conflicting with the separator. Other answer already stated it.
I use this style and save my life :-)
change code from
$validator = Validator::make(
$request->all(),
[
'name' => 'required|string',
'initial_credit' => 'required|integer|between:0,1000000|regex:/[1-9][0-9]*0000$/'
]
]);
to
$validator = Validator::make(
$request->all(),
[
'name' => 'required|string',
'initial_credit' => [ // <=== Convert To Array
'required',
'integer',
'between:0,1000000',
'regex:/([1-9][0-9]*0000$)|([0])/' // <=== Use pipe | in regex
] // <=== End Array
]);

Laravel array object rule

I send an array to a REST API. How can I add a rule for the array?
Also I want to add field_name_id, field_input_type and field_caption as required fields.
I don't know how can I access the array in Laravel rules. Can someone help me?
$rules = [
'name' => 'required',
'forms' => 'array'
]
Laravel uses dot notation to validate arrays and it's nested fields.
$rules = [
'forms.field_name_id' => 'required',
'forms.field_input_type'=> 'required',
'forms.field_caption' => 'required',
]
You can also validate each value within the array. For example, If you want the caption to be unique:
$rules = [
'forms.*.field_caption' => 'unique:captions,caption',
]
Here are the docs for more information on how to use them

Elasticsearch exact match field

I have a field called url that is set to not_analyzed when I index it:
'url' => [
'type' => 'string',
'index' => 'not_analyzed'
]
Here is my method to determine if a URL already exists in the index:
public function urlExists($index, $type, $url) {
$params = [
'index' => $index,
'type' => $type,
'body' => [
'query' => [
'match' => [
'url' => $url
]
]
]
];
$results = $this->client->count($params);
return ($results['count'] > 0);
}
This seems to work fine however I can't be 100% sure this is the correct way to find an exact match, as reading the docs another way to do the search is with the params like:
$params = [
'index' => $index,
'type' => $type,
'body' => [
'query' => [
'filtered' => [
'filter' => [
'term' => [
'url' => $url
]
]
]
]
]
];
My question is would either params work the same way for a not_analyzed field?
The second query is the right approach. term level queries/filters should be used for exact match. Biggest advantage is caching. Elasticsearch uses bitset for this and you will get quicker response time with subsequent calls.
From the Docs
Exclude as many document as you can with a filter, then query just the
documents that remain.
Also if you observe your output, you will find that _score of every document is 1 as scoring is not applied to filters, same goes for highlighting but with match query you will see different _score. Again From the Docs
Keep in mind that once you wrap a query as a filter, it loses query
features like highlighting and scoring because these are not features
supported by filters.
Your first query uses match which is basically used for analyzed fields e.g when you want both Google and google to match all your documents containing google(case insensitive) match queries are used.
Hope this helps!!

Issue with Laravel Rules & Regex (OR) operator

I'm having a small issue with my Laravel rules and regex operation :
Basically a rule is an array as such :
'room'=>'required|alpha_num|min:2|max:10',
The problem i'm having is when using regex and the | (or) operator such as :
'cid'=>'required|regex:/^((comp)|(soen)|(engr)|(elec))\d{3}$/i',
I'm getting a server error saying :
ErrorException
preg_match(): No ending delimiter '/' found
I'm guessing the preg_match is stopping at the first | inside the /.../.
Is there anyway to write the above code to make it work ?
Full code :
public static $rules = array(
'cid' => array('required', 'regex:/^((comp)|(soen)|(engr)|(elec))\d{3}$/i'),
'description'=>'required|regex:/^[A-Za-z \t]*$/i|min:3|unique:courses',
'credits'=>'required|regex:/^\d+(\.\d)?$/'
);
http://laravel.com/docs/validation#rule-regex
regex:pattern
The field under validation must match the given regular expression.
Note: When using the regex pattern, it may be necessary to specify rules in an array instead >of using pipe delimiters, especially if the regular expression contains a pipe character.
To clarify:
You would do something like this
$rules = array('test' => array('size:5', 'regex:foo'));
You should use an array instead of separating rules using |:
'cid' => array('required', 'regex:/^((comp)|(soen)|(engr)|(elec))\d{3}$/i')
The pipe (|) sigh is available in your regular expression pattern so it's conflicting with the separator. Other answer already stated it.
I use this style and save my life :-)
change code from
$validator = Validator::make(
$request->all(),
[
'name' => 'required|string',
'initial_credit' => 'required|integer|between:0,1000000|regex:/[1-9][0-9]*0000$/'
]
]);
to
$validator = Validator::make(
$request->all(),
[
'name' => 'required|string',
'initial_credit' => [ // <=== Convert To Array
'required',
'integer',
'between:0,1000000',
'regex:/([1-9][0-9]*0000$)|([0])/' // <=== Use pipe | in regex
] // <=== End Array
]);

Categories