Laravel validation date2 not bigger than the year of date1 - laravel

I am looking for an solution for a (custom) Validation Rule, that depends on an other array value.
simplified it looks like this (using livewire):
...
'positions.*.date_from' => 'required|date',
'positions.*.date_to' => ['required','date','after_or_equal:positions.*.date_from'],
...
I now want to add a validation that date_to must not be next year from date_from. something like before_or_equal:positions.*.date_from->endOfYear()
or
same_year_as:positions.*.date_from
how can I make a custom data aware rule with arrays? the docs don't show any examples with that.
since this case is in a livewire component, a possible workarround would be, that I set an additional array value positions.*.max_year on update of date_from, but this feels "dirty", and I would be interested in how to make such a rule.

Related

Vuetify default rules implementation

I am using Vuetify and use its default way of adding rules to input fields.
I know there is this rule:
v => !!v
This checks if the the form input isn't empty. But how can I make it in such a way that it only accepts alphabetical letters, numbers or even apply a regex to it? I can't find anything in the docs. Can someone with any experience help me out?
So I assume that you've probably sorted this now but for anyone finding this from google etc.
To add a new rule, you need to add it to your vue component, either through an import or just adding it straight to your data object. You name it as you would any other data property and it's an array of the tests like the v => !!v one you mentioned. You then add the OR operator followed by the text to show on a failed validation.
So to add a regex that only allows letters you would have this:
data () {
return {
alphaRule: [
v => /[a-zA-Z]+$/.test(v) || 'Field must only contain letters'
]
}
}
then on your form field you would have <v-text-field :rules="alphaRule"></v-text-field>
That said, I would highly recommend adding all of your rules to a Rules.js file and binding the rules globally so that you can access them anywhere, have a centralised repository for them, and it helps keeps your code DRY too.
I have just made a big ol list of rules inspired by Laravel's Validation rules and will edit my answer to include them oncce I have finished testing them.
EDIT
Here are all the rules I'm currently using in production. Hopefully they'll help someone else! You'll need to import them into your component to use them, or you can globally include them through a vue mixin.

Laravels syncWithoutDetaching and additional data

I have Googled my fingers sore, and I can't see anyone discussing this, but I have a suspicion that Laravels syncWithoutDetaching() method doesn't take any parameters for extra data like save(), sync() and attach() does?
Does anybody know this? In the API documentation the method has the following parameters:
array syncWithoutDetaching(Collection|Model|array $ids)
I have trouble adding existing data to a relationship between a Guest and an Event. I need to add status for the guests and what event they are attending, maybe attending or declined.
sync() and syncWithoutDetaching() both don't have a parameter for additional values, you have to pass the additional values as an array with the ids.
According to the docs:
You may also pass additional intermediate table values with the IDs:
$user->roles()->sync([
1 => ['expires' => true],
2,
3
]);
If you look here you can see that syncWithoutDetaching() just calls sync() but passes false as the second argument.
In your case it would be something like this:
$event->guests()->syncWithoutDetaching([
1 => ['attending' => true],
2 => ['attending' => false]
])
I think #remul answer is the best, but it requires additions for people like me who get to this page.
syncWithoutDetaching() - is just an abbreviation for sync() - here. This corresponds to sync($data, false)
The documentation talks about another great method:
If you would like to insert the same intermediate table values with
each of the synced model IDs, you may use the syncWithPivotValues
method
But the documentation does not say that the method accepts the third argument, which just corresponds to the logic of syncWithoutDetaching().
Look here.
If you pass false, the IDs not passed will not be detaching.
I think this is what the question was about.

How to add / remove elements from array that is in Request

My request looks like this
Array
(
[name] => Eugene A
[address] => Array
(
[billing] => Array
(
[address] => aaa
)
[shipping] => Array
(
[address] => bbb
)
)
)
I need to delete the shipping address. But how?
I can only delete both addresses,
$request->request->remove('address');
but I don't want it.
I want to delete only shipping address, like so
$request->request->remove('address.shipping');
But it is not working for me
Laravel 5.6
Update
Why do I need it?
Easy. I have abstracted out my Form Request validation into a class that is a child to Illuminate\Foundation\Http\FormRequest.
I actually have few classes for validation. I call them one by one in a controller like so:
app()->make(CustomerPostRequest::class); // validate Customer information
app()->make(AddressSaveRequest::class); // validate Addresses
Why?
Now I can Mock this requests in unit-tests, and I can have my validation abstracted out. And I can use Address validation in many places.
But Now I need more flexibility. Why?
Because AddressSaveRequest rule looks like this
public function rules(): array
{
return [
'address.*.address' => [
'bail',
'required',
'string',
],
...
It validates all addresses.
But sometimes I don't want to validate shipping address, if the the chech_box - ship_to_the_same_address is ticked.
But I have my Address validator abstracted in separate file and it is used in many places. There are places where ship_to_the_same_address tick box is not presented.
Thus I cannot use 'required_unless:ship_to_same_address,yes',
And I cannot use
app()->makeWith(AddressSaveRequest::class, ['ship_to_the_same_address ' => 'yes']);
Because Taylor said ...when calling makeWith. In my opinion it should make a new instance each time this method is called because the given parameter array is dynamic.. And it does, and it does not work correctly with app()->instance(AddressSaveRequest::class, $addressSaveRequest); and cannot be mocked in unit tests.
Why Taylor decided it - I seriously don't know.
PS
And yes, I know that mocking requests is not recommended.
If you were trying to add or remove inputs from the Request itself:
You can add data to the request pretty easily by merging it in and letting Laravel handle which data source is being used:
$request->merge(['input' => 'value']);
That will merge in the input named input into the input source for the Request.
For removing inputs you could try to replace all the inputs without that particular input in the replacement:
$request->replace($request->except('address.shipping'));
Just one idea to try.
Try this:
$request->except(['address.shipping']);
Details: Laravel Request
Laravel has a helper method called array_forget, which does exactly what it sounds like:
$requestArray = $request->all();
$newArray = array_forget($requestArray, 'address.shipping')
Documentation
After the edit to the main question with why some inputs of the request are to be deleted, my main answer isn't correct anymore. User Lagbox has the correct answer for the question that was asked.
However, I would like to note that another solution would be to have seperate Request classes with validation. One for placing an order (assuming it is a system where someone can order stuff) where ship_to_same_address is present and another one for things like updating your account, like PlaceOrderRequest and UpdateAccountRequest classes.

kendo mvc declare grid filters in a different class

here's a small block of grid filter code
.ForString(str => str
.Clear()
.Contains("Contains")
.DoesNotContain("Does not contain")
.StartsWith("Starts with")
.EndsWith("Ends with")
.IsEqualTo("Is equal to")
.IsNotEqualTo("Is not equal to")
.IsNull("Is null")
.IsNotNull("Is not null")
)
str in this case is a kendo.mvc.ui.fluent.stringoperationsbuilder
since we have over 150 pages, i have come up with a way to set up most mvc grids in a separate file and have filters i that. However we have maybe 10 grids that, due to heavy customization are done in javascript directly and the method also doesn't seem to work on pages we have set up to server-process vs client. What i would like to do is have a class return this so i can use it and i don't have to make changes all over the project. This same method could also be used to help us in many other places with other shared properties. In my experiments i was getting problems with "can not implicitly convert to action<>" etc and i am not good enough at this to even understand that part. Can someone give me a headstart?
more info: i'm trying to do something like this:
me.something1
me.something2
me.forString(str =>
str
.name
.date
.age)
I either need to be able to somehow (in this simple example) pass in str all at once from a variable OR somehow replace the forstring part from a variable or function commonly located somewhere else. I've tried a few different things, in the above str is a
kendo.mvc.ui.fluent.stringoperationsbuilder
but the forstring part expects an action<> of that type and we've had zero luck making an object of that type.

Laravel validation required rule not working

I need to add required rule if one field is available. Also need to check if it is an integer and 10 digit. So I added the rule like below.
'id_number' => 'sometimes|required|digits:10|integer'
Validations works only when the field is available. But here required rule is not working. It directly shows integer error even if the field is empty.
I use Laravel 5.1
Finally I figured it!
You need to change the order of required rule to last. It works when I add rule like this,
'id_number' => 'sometimes|digits:10|integer|required'

Resources