In my crud controller, There is one field called "roles (Multiple checklist)", While before saving the roles, I am converting array into string like 1,2,3 using implode.
Ex: CrudController
setUp() method
$options = [
'name' => 'roles',
'label' => 'Roles',
'type' => 'checklist',
'entity' => 'roles',
'attribute' => 'name',
'model' => "Backpack\PermissionManager\app\Models\Role",
];
$this->crud->addField($options);
In Store method,
public function store(StoreRequest $request)
{
$sel_roles = $request->input("roles");
$roles = !empty($sel_roles) ? implode(",",$sel_roles) : "";
$request->request->set("roles",$roles);
//dd($request);
return parent::storeCrud($request);
}
Edit Method looks like this,
public function edit($id) {
$this->crud->hasAccessOrFail('update');
// get the info for that entry
$this->data['entry']= $this->crud->getEntry($id);
$options = [
'name' => 'roles',
'label' => 'Roles',
'type' => 'checklist',
'entity' => 'roles',
'attribute' => 'name',
'model' => "Backpack\PermissionManager\app\Models\Role",
];
$this->crud->addField($options);
$this->data['crud'] = $this->crud;
$this->data['fields'] = $this->crud->getUpdateFields($id);
$this->data['id'] = $id;
return view('crud::edit', $this->data);
}
If am trying to access, Edit page, I am getting below error,
ErrorException in line 15:
Call to a member function pluck() on string (View: /var/www/html/app/vendor/backpack/crud/src/resources/views/fields/checklist.blade.php)
checklist.blade.php page looks like below
<div #include('crud::inc.field_wrapper_attributes') >
<label>{!! $field['label'] !!}</label>
<?php $entity_model = $crud->getModel(); ?>
<div class="row">
#foreach ($field['model']::all() as $connected_entity_entry)
<div class="col-sm-4">
<div class="checkbox">
<label>
<input type="checkbox"
name="{{ $field['name'] }}[]"
value="{{ $connected_entity_entry->id }}"
#if( ( old( $field["name"] ) && in_array($connected_entity_entry->id, old( $field["name"])) ) || (isset($field['value']) && in_array($connected_entity_entry->id, $field['value']->pluck('id', 'id')->toArray())))
checked = "checked"
#endif > {!! $connected_entity_entry->{$field['attribute']} !!}
</label>
</div>
</div>
#endforeach
</div>
{{-- HINT --}}
#if (isset($field['hint']))
<p class="help-block">{!! $field['hint'] !!}</p>
#endif
</div>
How do I display the roles with selected values in the edit page.
Thanks
After hours of debug and verified,
Send the edit values in the collection format,
$options = [
'name' => 'role_id',
'label' => 'Roles',
'type' => 'checklist',
'entity' => 'roles',
'attribute' => 'name',
'model' => "Backpack\PermissionManager\app\Models\Role",
"value" => collect([$edit_value_array])
];
Please help me, I'm trying to validate each row of the row that was highlighted with red in the form using the validate([]). If a user filled one of the columns in a row, and try to submit it with the other fields left unfilled, then it will prompt the user that the remaining fields are required to be filled. I have come up with various conditions but sadly none on them worked out,
this is my store function
public function store(Request $request){
$currentStatus = 0;
$data = $request->validate([
'to' => 'required',
'date' => 'date',
'address' => 'required',
'reference' => 'required',
'attention' => 'required',
'area' => 'required',
'project' => 'required',
'salesman' => 'required',
'location' => 'required'
]);
\App\Contract::create($data + ['status' => $currentStatus]);
return redirect('contracts/pendings');
first u need to create a FormRequest php artisan make:request MyControllerNameRequest
Then in MyControllerNameRequest define your rules
public function rules(): array
{
return [
'firstField' => ['required', 'int'],
'secondField' => ['required', 'int'],
'thirdFied' => ['required', 'int'],
'fourthField' => ['required', 'int'],
];
}
after go in to your controller and add MyControllerNameRequest like attribute in action
public function store(MyControllerNameRequest $request)
{
$model = Model::create($request->validated());
return redirect()->route('route.name');
}
or in some_name.blade.php add required
<input type="text" name="name" value="{{ old('value') }}" required>
I'm assuming that the names in HTML look like this:
<form method="post" action="{{ route('test') }}">
#csrf
<input type="text" name="data[0][quantity]">
<input type="text" name="data[0][unit]">
<input type="text" name="data[1][quantity]">
<input type="text" name="data[1][unit]">
<input type="submit">
</form>
You could try something like this in your controller.
$this->validate($request, [
'data.*.quantity' => 'sometimes|required_with:data.*.unit',
'data.*.unit' => 'sometimes|required_with:data.*.quantity',
]);
The required_with params accept multiples fields separated per comma, so you may have to pass all your fields in the validation. The sometimes validates only when it's passed values, so this may do the trick.
I have some problem where the validation is failing for my blade template with dropdown select on related table. I tried to searched for an answer but cannot found it.
To temporarily comment out the the field 'business_unit_id' inside the array in validate function to avoid the error.
In controller update function:
$item = CostCenter::findOrFail($id);
$validatedData = $request->validate([
'code' => 'bail|min:4|required|max:6',
'descr' => 'bail|min:4|required|max:50',
'business_unit_id' => 'required|integer',
]);
$item->fill($validatedData);
$item->business_unit_id = $request->businessUnit;
$item->save();
$request->session()->flash('status', 'Cost centers record was updated!');
return redirect()->route('costCenters.show', ['cost_centers' => $item->id]);
In blade template:
<label for="businessUnit" class="col-sm-2 col-form-label">Business Unit</label>
<select name="businessUnit" class="form-control">
#foreach (App\Models\BusinessUnit::all() as $data)
<option value="{{ $data->id }}"
{{ old('business_unit_id', $cost_centers->business_unit_id ?? '1')
!= $data->id ?: 'selected' }}>
{{ $data->code }} - {{ $data->descr }}
</option>
#endforeach
</select>
The notification received is "The business unit id field is required." with my error helper.
$validatedData = $request->validate([
'code' => 'bail|min:4|required|max:6',
'descr' => 'bail|min:4|required|max:50',
'businessUnit' => 'required|integer',
]);
Use businessUnit instead of business_unit_id
as we have to use the name of select tag...
don't use the id of options tag..
you can try this code...and use use keyword to of the code like use Validator;
$rules = [
'code' => 'bail|min:4|required|max:6',
'descr' => 'bail|min:4|required|max:50',
'businessUnit' => 'required|integer|exists:business_unit,id',
];
$message = [
'code.required' => 'code is required.',
'descr.required' => 'description field is required.',
'businessUnit.required' => 'The business unit id field is required.',
];
$validator = Validator::make($request->all(), $rules,$message);
if ($validator->fails()) {
$arr = array("status"=>400,"msg"=>$validator->errors()-
>first(),"result"=>array());
}
else
{
your code write in this section
}
For any request data validation in controller You can try like this:
$rule=array(
'code' => 'bail|min:4|required|max:6',
'descr' => 'bail|min:4|required|max:50',
'business_unit_id' => 'required|integer',
);
$validator= Validator::make($request->all(),$rule);
I already asked this question but there are a few things different this time. Last time the problem was fixed pretty well so now i just need a hand to tell me how to change the code so it works properly.
The thing i have changed is that i have implemented a way to successfully lend more then one book at once. So now i have an array which works perfectly.
So this is my View imagine this code 3 times one for every book you want to lend:
<div class="form-group row">
<label for="serialnumber" class="col-md-4 col-form-label text-md-right">{{ __('Gerät 1 (serialnumber) :') }}</label>
<div class="col-md-6">
<input id="serialnumber" type="text" class="form-control{{ $errors->has('serialnumber') ? ' is-invalid' : '' }}" name="serialnumber[]" value="{{ old('serialnumber') }}" required #if (Session::has('autofocus')) autofocus #endif>
#if ($errors->any())
<div class="alert alert-danger">The book with this serialnumber is already lend by antoher person
<ul>
</ul>
</div>
#endif
</div>
</div>
This is my Controller Code now:
public function store(BookRequest $request)
{
//if( !Book::find($request->get('serialnumber'))->exists() ) {
$this->middleware('guest');
request()->validate([
'serialnumber' => 'required',
'ma_id' => 'required'
]);
$requestData = $request->all();
$data = [
[
'serialnumber' => $requestData['serialnumber'][0],
'comment' => $requestData['comment'],
'ma_id' => $requestData['ma_id'],
],
[
'serialnumber' => $requestData['serialnumber'][1],
'comment' => $requestData['comment'],
'ma_id' => $requestData['ma_id'],
],
[
'serialnumber' => $requestData['serialnumber'][2],
'comment' => $requestData['comment'],
'ma_id' => $requestData['ma_id'],
]
];
Book::insert($data);
return redirect()->route('borrow.index')
->with('success','Successfully lend the book');
}
And the last is my Request.php page:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class BookRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'serialnumber[0]' => 'required|unique:borrowed,serialnumber,null',
'serialnumber[1]' => 'required|unique:borrowed,serialnumber,null',
'serialnumber[2]' => 'required|unique:borrowed,serialnumber,null',
'ma_id' => 'required',
];
}
public function messages()
{
return [
'serialnumber' => 'Seems like you have added the same book more than once!',
];
}
}
And this is my error message which i got after i tried to lend a book which is already lend by another person. Before i implemented the array thing this code worked perfect. Another question that i have is how could i implement a way which shows an error message which says "Sorry but this book is currently not in our database please press the info button and get some administraive help" so that basically an error message appears when the book is not in our database we have a lot of books so it is possible that we forget to scan one. Every help is much appreciated!!
EDIT:
Forgot the error message
htmlspecialchars() expects parameter 1 to be string, array given
Change your view:
#if(!empty(old('serialnumber')))
#foreach(old('serialnumber') as $i=>$value)
<input id="serialnumber" type="text" class="form-control{{ $errors->has('serialnumber') ? ' is-invalid' : '' }}" name="serialnumber[]" value="{{ old('serialnumber.'.$i) }}" required #if (Session::has('autofocus')) autofocus #endif>
#endforeach
#endif
where $i is your array index
aslo you can modify your rules and message like:
public function rules(){
return [
'serialnumber.0' => 'required|unique:borrowed,serialnumber,null',
'serialnumber.1' => 'required|unique:borrowed,serialnumber,null',
'serialnumber.2' => 'required|unique:borrowed,serialnumber,null',
'ma_id' => 'required',
];
}
or
public function rules(){
return [
'serialnumber.*' => 'required|unique:borrowed,serialnumber,null',
'ma_id' => 'required',
];
}
and
public function messages()
{
return [
'serialnumber.*' => 'Seems like you have added the same book more than once!',
];
}
I have created the password route, view and method in UserController#getProfilePassword and UserController#postProfilePassword
At the moment, if I fill out the new_password field, it gets hashed and submitted to the database correctly, then I can login with the new password.
But I need to be able to validate the new_password and new_password_confirm to make sure they're the same and validate the user's current password as well.
How can I do that?
EDIT: I added $this->validate to the method, but now I keep getting the error The password confirmation confirmation does not match. even though they do match as I am using a simple password. Also I think I need to check against the current password manually as validator won't do it for me.
public function getProfilePassword(Request $request) {
return view('profile/password', ['user' => Auth::user()]);
}
public function postProfilePassword(Request $request) {
$user = Auth::user();
$this->validate($request, [
'old_password' => 'required',
'password' => 'required|min:4',
'password_confirmation' => 'required|confirmed'
]);
$user->password = Hash::make(Input::get('new_password'));
$user->save();
}
And this is the view
<form action="{{ route('profile/updatepassword') }}" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="name">Current Password</label>
<input type="password" name="old_password" class="form-control" id="old_password">
</div>
<div class="form-group">
<label for="name">Password</label>
<input type="password" name="password" class="form-control" id="password">
</div>
<div class="form-group">
<label for="name">New Password</label>
<input type="password" name="password_confirmation" class="form-control" id="password_confirmation">
</div>
<button type="submit" class="btn btn-primary">Change Password</button>
<input type="hidden" value="{{ Session::token() }}" name="_token">
</form>
There's a Hash::check() function which allows you to check whether the old password entered by user is correct or not.
usage
if (Hash::check("param1", "param2")) {
//add logic here
}
param1 - user password that has been entered on the form
param2 - old password hash stored in database
it will return true if old password has been entered correctly and you can add your logic accordingly
for new_password and new_confirm_password to be same, you can add your validation in form request like
'new_password' => 'required',
'new_confirm_password' => 'required|same:new_password'
If you only need the functionality of a custom rule once throughout your application, you may use a Closure instead of a rule object. The Closure receives the attribute's name, the attribute's value, and a $fail callback that should be called if validation fails
$request->validate([
'new_password' => 'required|confirmed|min:4',
'current_password' => ['required', function ($attribute, $value, $fail) use ($user) {
if (!\Hash::check($value, $user->password)) {
return $fail(__('The current password is incorrect.'));
}
}],
]);
https://laravel.com/docs/5.6/validation#using-closures
In Laravel 6 there is a new rule called password ,according to docs
The field under validation must match the authenticated user's password. You may specify an authentication guard using the rule's first parameter:
'password' => 'password:api'
so the validation rules can be as simple as :
'current_password' => 'required|password',
'password' => 'required|string|min:8|confirmed',
You can do this by creating a custom validation rule (for this example I'm using current_password and new_password as the input names).
Put this in AppServiceProvider::boot():
Validator::extend('current_password', function ($attribute, $value, $parameters, $validator) {
$user = User::find($parameters[0]);
return $user && Hash::check($value, $user->password);
});
Now you can use the following in your controller:
$user = auth()->user(); // or pass an actual user here
$this->validate($request, [
'current_password' => 'required_with:new_password|current_password,'.$user->id,
]);
Using laravel 5.8/6.0, here is what i do(without much additional code)
Step 1: Validate
$data = request()->validate([
'firstname' => ['required', 'string', 'max:255'],
'lastname' => ['required', 'string', 'max:255'],
'username' => ['bail', 'nullable', 'string', 'max:255', 'unique:users'],
'email' => ['bail', 'nullable', 'string', 'email:rfc,strict,dns,spoof,filter', 'max:255', 'unique:users'],
'new_password' => ['nullable', 'string', 'min:8'],
'confirm_new_password' => ['nullable', 'required_with:new_password', 'same:new_password'],
'current_password' => ['required', function ($attribute, $value, $fail) {
if (!\Hash::check($value, Auth::user()->password)) {
return $fail(__('The current password is incorrect.'));
}
}]
]);
Step 2: If validation is passed
Create array , checking each input value (but not the ones with the required tag in validation) for presence or null OR do something that you want.
For example:
if(request(input)){
$data += ['input' => request(input)];
}
Update database using the created array
For example:
Auth::user()->account->update($data);
A complete function which will check everything. You just need to send old_password, new_password and confirm_password.
public function changePassword(Request $request) {
try {
$valid = validator($request->only('old_password', 'new_password', 'confirm_password'), [
'old_password' => 'required|string|min:6',
'new_password' => 'required|string|min:6|different:old_password',
'confirm_password' => 'required_with:new_password|same:new_password|string|min:6',
], [
'confirm_password.required_with' => 'Confirm password is required.'
]);
if ($valid->fails()) {
return response()->json([
'errors' => $valid->errors(),
'message' => 'Faild to update password.',
'status' => false
], 200);
}
// Hash::check("param1", "param2")
// param1 - user password that has been entered on the form
// param2 - old password hash stored in database
if (Hash::check($request->get('old_password'), Auth::user()->password)) {
$user = User::find(Auth::user()->id);
$user->password = (new BcryptHasher)->make($request->get('new_password'));
if ($user->save()) {
return response()->json([
'data' => [],
'message' => 'Your password has been updated',
'status' => true
], 200);
}
} else {
return response()->json([
'errors' => [],
'message' => 'Wrong password entered.',
'status' => false
], 200);
}
} catch (Exception $e) {
return response()->json([
'errors' => $e->getMessage(),
'message' => 'Please try again',
'status' => false
], 200);
}
}
Laravel Check Old Password and Updating a New Password | More
public function updatePassword(Request $request)
{
$this->validate($request, [
'old_password' => 'required',
'new_password' => 'required|min:6',
'confirm_password' => 'required|same:new_password',
]);
$data = $request->all();
if(!\Hash::check($data['old_password'], auth()->user()->password)){
return back()->with('error','You have entered wrong password');
}else{
here you will write password update code
}
}
Validation rules for laravel 8.*
Default
'current_password' => 'required|current_password',
'password' => 'required|min:8|confirmed',
Custom
php artisan make:rule MatchOldPassword
//inside MatchOldPassword
public function passes($attribute, $value)
{
return Hash::check($value, auth()->user()->password);
}
'current_password' => ['required', new MatchOldPassword()],
'password' => 'required|min:8|confirmed',
Validation rules for Laravel 8.*
use default available validation rules:
[
'current_password' => ['required', 'string', 'current_password'],
'password' => ['required', 'string', 'min:4', 'confirmed']
]
current_password based on Laravel Document check parameter to be equaled to authenticated user password
confirmed based on Laravel
Document check parameter to equaled with new parameter named:
{parameter}_confirmation
You can add confirmed as it's to confirm old password.
And 'required|confirmed' you change to 'required|same:password' to compare password and password confirmation
'old_password' => 'required|confirmed',
'password' => 'required|min:4',
'password_confirmation' => 'required|same:password'
Good luck!
In Laravel 8.x you can use this method in UserController.php:
public function ChangePasswordStore(Request $request, $user_id)
{
$user = User::findOrFail($user_id);
$request->validate([
'password' => 'required|confirmed|string|min:8',
'current_password' => ['required', function ($attr, $password, $validation) use ($user) {
if (!\Hash::check($password, $user->password)) {
return $validation(__('The current password is incorrect.'));
}
}],
]);
User::where('id', $user_id)->update([
'password' => Hash::make($request->input('password')),
]);
return redirect()->back();
}
In web.php:
Route::post('/user/{user_id}/changepassword', [
App\Http\Controllers\Admin\UserController::class,
'changepasswordStore'
])->name('users.changepassword.store');