Laravel send query string with optional parameters - laravel

I have my route set as
Route::any('/{brand?}/{type?}/{city?}', 'SearchController#index')->name('search');
I want to send from my controller query strings (Form GET params)
After searching I ended up with this but it does not work properly
return redirect()->route('search', [$brand->name, $type->name, 'search_model_from' => $request->search_model_from, 'search_model_to' => $request->search_model_to]);
which returns back
localhost:8000/toyota/avalon/2018?search_model_to=2019
I want to return
localhost:8000/toyota/avalon/?search_model_from=2018&search_model_to=2019
What I am trying to achieve in general is SEO friendly search functionality

Maybe you should try to assign city as null like that :
return redirect()->route('search', [
'brand' => $brand->name, 'type' => $type->name,
'city' => '', 'search_model_from' => $request->search_model_from,
'search_model_to' => $request->search_model_to
]);

I'm not sure but this could happen because you have defined 3 optional parameters in the route and as you are sending just two of them, this might takes the next (in this case 'search_model_from') as the third parameter for url.
Maybe if you cast and set a default value to the optional parameters in your Controller, you won't have that trouble, like this:
public function index(string $brand='', string $type='', string $city='' , $other_parameters)

Related

Overwrite Laravel Http Faker

Is there a way to overwrite values of Http::fake([]) in Laravel during testing. I've noticed that if I set a value during a faker, eg. Http::fake(['url1.com' => Http::response('OK'), 'url2.com' => Http::response('Not Found', 404),]), if for some reason I need to change the value of say url1.com to something else such as ['message' => 'Success'], if I "update" the value by calling Http::fake(['url1.com' => Http::response(['message' => 'Success']) again at a later point, I'd expect the response when I call Http::get('url1.com') to return ['message' => 'Success'] but it instead always returns OK which was the original value set.
Same way if I later call Http::fake(['url2.com' => Http::response(['message' => 'Object found.'])]), I would expect the response when I call Http::get('url2.com') to be ['message' => 'Object found.'] but it'll always return Not found which was the original value set.
You can use achieve this by swapping the Http client
Http::fake(['https://potato.com' => Http::response('Yummy!', 200)]);
dump(Http::get('https://potato.com')->body()); // Yummy!
at some point in your test, you can reset the Http Facade using Facade Swap
Http::swap(app(\Illuminate\Http\Client\Factory::class));
now you can change the fake value to whatever you want
Http::fake(['https://potato.com' => Http::response("That's what the dcotor ordered.", 200)]);
dump(Http::get('https://potato.com')->body()); // That's what the doctor orderd.

Laravel validate request filter field with dot (period) in field name

Here is to validate form request in laravel, request contains filter and field name in the filter has period(dot) present.
Sample Request url
...?filter[entity.abc][]='value'
Here entity.abc is actually a string, but laravel considers it to be array of object, when rule is given for 'filter.entity.abc'
filter:[
[entity]: [ {abc:'value'}]
]
which is actually
filter:[
[entity.abc]:['value']
]
So we need to make regex for second dot, which equivalents to:
public function rules()
{
return [
'filter.entity\.abc' => ['bail', 'sometimes', 'array'],
'filter.entity\.abc' => ['uuid']
];
}
Above always retuns true,even when invalid uuid is present
why not modify your request like this?
...?filter[entity][abc][]='value'
Edit:
You can use custom validation in laravel where you can deconstruct the parameters and check the values manually
Laravel Custom Validation
https://laravel.com/docs/8.x/validation

How can I validate GET controller params in CakePHP 2?

Given this on the model:
public $validate = [
'amount' => array(
'rule' => array('comparison', '>=', 0),
'message' => 'You must buy over 0 of this item!'
)
];
How can I validate param #2 of the below?
public function buy(int $item, int $amount) {
Validation seems to be built only for POST, which I'd like to opt out of here.
First things first, modifying the database with GET requests is an anti-pattern for many different reasons. Even if you assume a friendly user agent (which you never should!), browsers can behave quirky and do unexpected stuff like for example sending GET request multiple times (that is perfectly valid as GET is not ment to modify data), which they usually won't for POST/PUT/DELETE.
I would strongly suggest to change your endpoint to handle POST requests instead.
That being said, you can generally validate whatever you want, the validation mechanisms first and foremost just validate data, they don't know or care where it stems from. You can hand over whatever data you want to your model, and let it validate it:
$data = array(
'item' => $item,
'amount' => $amount,
);
$this->ModelName->set($data);
if ($this->ModelName->validates()) {
// data is valid
} else {
// data is invalid
$errors = $this->ModelName->validationErrors;
}
Moreover you can use CakePHP's validation methods completely manually too:
App::uses('Utility', 'Validation');
$isValid = Validation::comparison($amount, '>' 0);
This example of course doesn't make too much sense, given that $isValid = $amount > 0 would do the same, however it should just show that you can validate anything everywhere without models being involved.
See also
Cookbook > Models > Data Validation > Validating Data from the Controller
Cookbook > Models > Data Validation > Core Validation Rules

laravel validation Array to string conversion error

if I check min|max before exist
laravel validation will return Array to string conversion error.
(laravel version 5.5)
return [
// 'nick_name' => 'exists:users|max:150|min:6|regex:/\A[0-9a-zA-Z_]{6,150}\z/',
'nick_name' => ['max:150', 'min:6', 'exists:users', 'regex:/\A[0-9a-zA-Z_]{6,150}\z/'],//return Array to string conversion error
// 'nick_name' => ['exists:users', 'max:150', 'min:6', 'regex:/\A[0-9a-zA-Z_]{6,150}\z/'],//success
'ref_code' => 'exists:users',
]
Do you change your application language? If you have translation and translation is missing you can get this error. Just change app language to en and try again.
Make sure nick_name is string. Not an array
Make sure input field name is like shown below
<input type='text' name='nick_name' /> //if name='nick_name[]' then it will be an array
//and below procedure will be used to validate it.
If it is array then validate it like shown below
nick_name.* => 'validation rule here'

Model rule variable required without scenario (Yii2)

How can I create a model rule that's only required when a certain value from the Database is 1?
I tried using a 'required', 'when' rule but that doesn't seem to update the client-side JavaScript.
I also tried a custom inline validator but that doesn't seem to post an empty field.
Scenario's aren't an option I think as I have 6 fields and can have any combination of required/not required.
EDIT
At the moment I just never add the required rules, instead of directly returning the rules I store them in a variable. $rules = []
Then before I return the variable I add the required options to the array.
if($x->x_required)
$rules[] = ['your-field', 'required', 'on' => 'your-scenario'];
This is a quickfix and I don't really like it, but it works. I'm not sure if there is a better way of doing this.
You need to use combination required with when, but for client side validation you need additionally specify whenClient property.
Example (add this to your rules()):
[
'attributeName',
'required',
'when' => function ($model) {
return $model->country == Country::USA;
},
'whenClient' => function (attribute, value) {
return $('#country').value == 'USA';
},
],
Official docs:
RequiredValidator
Validator $when
Validator $whenClient

Resources