laravel validation rule does not accept first index of array - php

/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request) {
$rules = [
'translations' => 'required|array',
'translations.*.language_code' => 'required|exists:app_languages,code',
'translations.*.name' => 'required'
];
$this->validate($request, $rules);
dd("OK");
}
I am using PostMan to test it. Everything is ok for array's second parameter. But it does not accept name 0 index or array.
When i didn't send first index :
UPDATE
It is Postman's bug. I added same parameter then replace it, it works.

It is Postman's bug. I added same parameter then replace it, it works.
I do not know, why it didn't accept and now it accept lol.

I think this helps you .
$rules = [];
if($request->has('translations'))
{
$translations = $request->input('translations');
foreach($translations as $key => $value)
{
$rules["translations.$key.$value"] = 'required';
}
}

Related

The PUT method is not supported for this route. Supported methods: GET, HEAD, POST. while i use #method('PUT')

I've used the #method('PUT') in my blade, but it still says the PUT Method is not supported, does someone know what's wrong?
My routes are:
routes
This is my workshops controller edit parameter and storage.
public function edit(Workshops $workshops)
{
$result = compact('workshops');
Json::dump($result);
return view('admin.workshops.edit', $result);
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param \App\Workshops $workshops
* #return \Illuminate\Http\Response
*/
public function update(Request $request, Workshops $workshops)
{
$this->validate($request,[
'name' => 'required|unique:workshops' . $workshops->id,
'datum' => 'required'. $workshops->id,
'plaatsen' => 'required' . $workshops->id,
'price' => 'required'
]);
$workshops->name = $request->name;
$workshops->datum = $request->datum;
$workshops->plaatsen = $request->plaatsen;
$workshops->price = $request->price;
$workshops->save();
session()->flash('success', 'The workshop has been updated');
return redirect('admin/workshops');
}
Look in your routes file, you need Route::put() for the route you are trying to use. https://laravel.com/docs/7.x/routing#basic-routing
You need to define your route with PUT as shown below
Route::put('/admin/workshops/{id}', 'ControllerName#methodName');
Official Laravel Documentation
W3Schools
You have to use like this
Route::post('/admin/workshops/{id}', 'ControllerNameController#methodName');

Laravel - old inputs on create method

I have a small project with laravel and I stuck on my create method inputs. So this is happening:
When I click on my input to type something it is showing my old values. How can I get rid of that?
Here is my Controller#store function:
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
if(Auth::user()->name == 'Optika Podgorica/Delta'){
$this->validate($request, [
'br_kesice' => 'required',
'klijent' => 'required',
'datum_preuz' => 'required',
//'datum_izdav' => 'required',
]);
$storeone = new Storeone;
$storeone->br_kesice = $request->input('br_kesice');
$storeone->klijent = $request->input('klijent');
$storeone->br_telefona = $request->input('br_telefona');
$storeone->posao = $request->input('posao');
$storeone->cijena = $request->input('cijena');
$storeone->placanje = $request->input('placanje');
$storeone->popust = $request->input('popust');
$storeone->datum_preuz = $request->input('datum_preuz');
$storeone->datum_izdav = $request->input('datum_izdav');
$storeone->smjena = $request->input('smjena');
$storeone->radnik = $request->input('radnik');
$storeone->status = $request->input('status');
$storeone->user_id = auth()->user()->id;
$storeone->save();
return redirect('/storeones');
}else{
return redirect()->back();
}
}
And I use Laravel Collective forms. Can anybody help me?
I think it's coming form browser auto fill. Add autocomplete="false" to your input it will not show previous entry.

Validator, what's wrong?

I'm going a little be crazy with my simple validator.
$data = ['dam' => 1, 'sir' => 2];
$v = Validator::make(
$data,
['dam' => 'exists:individuals,id'],
['dam.exists' => 'Object not found']
);
$validateLab = $v->validate();
dd($validateLab);
In the table individuals, there is an entry for id=1, but not id=2. If I run the code as it is, I get "true". If I change 'dam' => 1 to 'dam' => 2, I get
"The given data was invalid." on line 306 of
/Applications/MAMP/htdocs/mysamples/vendor/laravel/framework/src/Illuminate/Validation/Validator.php :
...
/**
* Run the validator's rules against its data.
*
* #return void
*
* #throws \Illuminate\Validation\ValidationException
*/
public function validate()
{
if ($this->fails()) {
throw new ValidationException($this);
}
}
...
Why? Why it does not return "Object not found"?

laravel 5.4 modify data before validation in request [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I have my custom Request, which extends the Backpack CrudController.
Now I would like to override the prepareForValidation of the ValidatesWhenResolvedTrait since it looks like the right place to modify my incoming data, but I can't figure out how ...
So my first question is, can I override this method? Its protected ...
protected function prepareForValidation()
And my second question, how can I modify my input on the Request or FormRreuqest objects?
Here is my RequestClass
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
use Config;
class DonationsRequest extends \Backpack\CRUD\app\Http\Requests\CrudRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
// only allow updates if the user is logged in
return \Auth::check();
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'name' => 'required|max:255',
'email' => 'required|email',
'dob' => 'required|date',
'newsletter' => 'required|boolean',
'country' => 'sometimes|required|in:'.implode(',', Config::get('validation.countries')),
'street' => 'sometimes|required|string|max:255',
'zip' => 'sometimes|required|string|between:4,5',
'city' => 'sometimes|required|string|between:4,255',
'amount' => 'required|numeric|between:1,'.Config::get('donations.max'),
'type' => 'required|in:oo,monthly',
'provider' => 'sometimes|string|nullable',
'product_id' => 'sometimes|exists:products,id|nullable',
'campaign_id' => 'required|exists:campaigns,id',
'status' => 'sometimes|required|in:pending,canceled,success,error',
'profile' => 'sometimes|string|regex:/^profile[0-9]+$/|nullable',
];
}
/**
* Get the validation attributes that apply to the request.
*
* #return array
*/
public function attributes()
{
return [
//
];
}
/**
* Get the validation messages that apply to the request.
*
* #return array
*/
public function messages()
{
return [
//
];
}
private function prepareForValidation()
{
dd('getValidatorInstance custom');
$this->sanitizeInput();
return parent::getValidatorInstance();
}
private function sanitizeInput()
{
dd('sanitizeInput custom');
$data = $this->all();
dd($data);
// overwrite the newsletter field value to match boolean validation
$data['newsletter'] = ($data['newsletter'] == 'true' || $data['newsletter'] == '1' || $data['newsletter'] == true) ? true : false;
return $data;
}
private function validate() {
dd('validate');
}
}
As you can see, I first tried to override the getValidatorInstance method, since this looked like the common aproach to this, but it is not executed (so not overridden - protected?).
Although I didn't tried but it seems it should work you can override validationData from Illuminate\Foundation\Http\FormRequest class like.
/**
* Get data to be validated from the request.
*
* #return array
*/
protected function validationData()
{
$all = parent::validationData();
//e.g you have a field which may be json string or array
if (is_string($playerIDs = array_get($all, 'player_id')))
$playerIDs = json_decode($playerIDs, true);
$all['player_id'] = $playerIDs
return $all;
}
or you can override all method in Illuminate\Http\Concerns\InteractsWithInput trait
/**
* Get all of the input and files for the request.
*
* #return array
*/
public function all()
{
$all = parent::all();
//then do your operation
if (is_string($playerIDs = array_get($all, 'player_id')))
$playerIDs = json_decode($playerIDs, true);
$all['player_id'] = $playerIDs
return $all;
}
Could you modify the request?
$request->merge(['field' => 'new value']);
Well I am sure,this can help in modifying The input, it worked for me.[laravel 5.4]
place this
$input['url'] = $url;
$this->replace($input);
dd($input);
in listFormRequest. (use $all instead of $input, if you follow above used answer).
This only changes input,which is available even in controller. You still need to find a way to insert it into DB, or do something else to use modified input for using it in blade.
Ok I found out where the error was. I did split the Frontend Request and the Backend Request Call. Since I was working on the Backend Request the Frontend Request was not overwriting anything ... so it was my bad, no bug there, sry for the waste of time, but a big thanks to the community!

How to include fractal transformed objects directly to collection meta without data key

I'm using league/fractal with JsonApiSerializer,
I've got users collection for json output.
Now I want to add some filters data to this json response (like users count for current filters).
I got this:
$resource = new Collection($dataProvider->getData(), new UserTransformer());
//the only way to include some not directly linked data i found is using setMeta():
$resource->setMetaValue('projects', $dataProvider->getProjects());
$resource->setMetaValue('somes', $dataProvider->getTasks());
But! 'projects' & 'somes' collections (yes, they are collection too) also included with 'data' key in it.
So, I've got this structure:
{
'data' => [
{//user1},{//user2},...
],
'meta' => {
'projects' => {
'data' => {...}
},
'somes' => {
'data' => {...}
}
}
}
but I want something like:
{
'data' => [
{//user1},{//user2},...
],
'meta' => {
'projects' => {...}, //there is no 'data' key
'somes' => {...} //there is no 'data' key
}
}
What should I do?
This is kinda hack but works fine without refactor Scope class which hardcoded in fractal's League\Fractal\Manager::createData() and is only way to use your own Scope class realization is to overload this method in Manager's extension.
<?php
use League\Fractal\Serializer\JsonApiSerializer;
/**
* Class EmbedSerializer
*/
class EmbedSerializer extends JsonApiSerializer
{
const RESOURCE_EMBEDDED_KEY = 'embedded';
/**
* Serialize a collection.
*
* #param string $resourceKey
* #param array $data
* #return array
*/
public function collection($resourceKey, array $data)
{
return $resourceKey === self::RESOURCE_EMBEDDED_KEY ? $data : [$resourceKey ?: 'data' => $data];
}
/**
* Serialize an item.
*
* #param string $resourceKey
* #param array $data
* #return array
*/
public function item($resourceKey, array $data)
{
return $resourceKey === self::RESOURCE_EMBEDDED_KEY ? $data : [$resourceKey ?: 'data' => [$data]];
}
}
So, now i could use it like:
/** #var $this->fractal League\Fractal\Manager */
$this->fractal->setSerializer(new EmbedSerializer());
$projectsCollection = $this->fractal->createData(
new Collection($projects, new UserProjectTransformer(), 'embedded')
)->toArray();
$resource = new Collection($users, new UserTransformer());
$resource->setMetaValue('projects', $projectsCollection);
That's all u need. Hope this will be helpful.

Categories