Override Backpack validation roles - php

What I did:
I am trying to override backpack form validation roles (update request).
UserUpdateCrudRequest.php
use App\Http\Requests\Backpack\PermissionManager\UserUpdateCrudRequest as UpdateRequest;
class UserUpdateCrudRequest extends \Backpack\PermissionManager\app\Http\Requests\UserUpdateCrudRequest
{
function __construct()
{
parent::__construct();
}
public function authorize()
{
// only allow updates if the user is logged in
return \Auth::check();
}
public function rules()
{
$rules = [
'name' => 'required',
'password' => 'confirmed',
];
return $rules;
}
}
app/Http/Controllers/Admin/Backpack/PermissionManager/UserCrudController.php
public function update(UpdateRequest $request)
{
//code
}
What I expected to happen:
The email field is mandatory on create , and not mandatory on update.
What happened:
ErrorException in UserCrudController.php line 18:
Declaration of App\Http\Controllers\Admin\Backpack\PermissionManager\UserCrudController::update() should be compatible with Backpack\PermissionManager\app\Http\Controllers\UserCrudController::update(Backpack\PermissionManager\app\Http\Requests\UserUpdateCrudRequest $request)

If I'm right,
inside UserCrudController you have,
use Backpack\PermissionManager\app\Http\Requests\UserStoreCrudRequest as StoreRequest;
use Backpack\PermissionManager\app\Http\Requests\UserUpdateCrudRequest as UpdateRequest;
If you want to make the email field not mandatory on update you have to edit the UserUpdateCrudRequest.php inside your-project/vendor/backpack/permissionmanager/src/app/Http/Requests and remove the line
'email' => 'required',

Related

Validation for form

Please help with setting rules (). The thing is, I have a form. Where 2 fields are present. If all fields are empty, the form cannot be submitted, but if at least ONE is not empty, then the form can be submitted. Can you help me please, I'm new at it?
Here's my form
<?php $form = ActiveForm::begin() ?>
$form->field($model, 'field1')->textInput();
$form->field($model, 'field2')->textInput();
<?php $form = ActiveForm::end() ?>
And this's my model, but this rule does not quite suit me. Because the rules require you to fill in all the fields. And the main thing for me is that at least one, but was filled, so i could send the form. If ALL fields are empty, then validation fails.
public function rules()
{
return [
[['field1', 'field1'], 'require'] ]}
Should I add something in controller maybe?
You have TYPO in rules: use required
public function rules()
{
return [
[['field1', 'field1'], 'required']
];
}
You can use yii\validators\Validator::when property to decide whether the rule should or shouldn't be applied.
public function rules()
{
return [
[['field1'], 'required', 'when' => function ($model) {
return empty($model->field2);
}]
[['field2'], 'required', 'when' => function ($model) {
return empty($model->field1);
}]
];
}
The when property is expecting a callable that returns true if the rule should be applied. If you are using a client side validation you might also need to set up the yii\validators\Validator::whenClient property.
You can use standalone validation:
public function rules()
{
return [
[['field1', 'field2'], MyValidator::className()],
];
}
And create a new class like follows:
namespace app\components;
use yii\validators\Validator;
class MyValidator extends Validator
{
public function validateAttribute($model, $attribute)
{
if (empty($model->filed1) and empty($model->field2)) {
$this->addError($model, $attribute, 'some message');
}
}
}

Insert record after Laravel form validation

I'm trying a Laravel 5.8 request validation. I managed to return errors and display them to my view. The problem is when I try to not trigger any validation rule, for whatever reason I cannot insert records into my table.
Error
Too few arguments to function
App\Http\Requests\FieldRequest::Illuminate\Foundation\Providers{closure}(),
0 passed and exactly 1 expected
Controller
class FormController extends Controller
{
public function create()
{
return view('create');
}
public function store(FieldRequest $req)
{
$validate_data = $req->validate();
Form::create($validate_data);
return redirect()->back()->with('message', 'Success!');
}
}
FormRequest
class FieldRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'item_name' => 'bail|required|max:255',
'sku_no' => 'required|alpha_num',
'price' => 'required|numeric',
];
}
public function messages()
{
return [
'item_name.required' => 'An Item Name is required',
'sku_no.required' => 'An SKU NO is required',
'price.required' => 'The price is required',
];
}
}
I'm expecting something to be inserted in my table. Do I need to perform the validation in my controller or not to achieve this? Thanks in advance!
public function store(FieldRequest $req)
{
$data = $req->all();
Form::create($data);
return redirect()->back()->with('message', 'Success!');
}
when you are working with form request you no need to use validate() function because your request goes in form request to validate your data then it will store records

array_map(): Argument #2 should be an array

I'm getting this errorarray_map(): Argument #2 should be an array when a user trying to create a product
I changed my code from this solutions How to make each authenticated user only see their own product, and now it gives me that error.
ProductController
class productController extends Controller
{
public function index(Request $request)
{
$userId = $request->user()->id;
$products = products_model::where('user_id', $userId)->get();
return view('seller.product.index',compact('products'));
}
public function create()
{
return view('seller.product.create');
}
public function seller()
{
$products=products_model::all();
return view('seller.product.index',compact('products'));
}
public function store(Request $request)
{
$formInput=$request->except('image');
$this->validate($request, [
'pro_name'=> 'required',
'pro_price'=> 'required',
'pro_info'=> 'required',
'user_id' => \Auth::id(),
'image'=>'image|mimes:png,jpg,jpeg|max:10000'
]);
$image=$request->image;
if($image){
$imageName=$image->getClientOriginalName();
$image->move('images', $imageName);
$formInput['image']=$imageName;
}
products_model::create($formInput);
return redirect()->back();
}
public function show($id)
{
//
}
public function edit($id)
{
//
}
public function update(Request $request, $id)
{
//
}
public function destroy($id)
{
$userId = $request->user()->id();
$deleteData=products_model::where('user_id', $userId)->findOrFail($id);
$deleteData->delete();
return redirect()->back();
}
}
Products_model
class products_model extends Model
{
protected $table='products';
protected $primaryKey='id';
protected $fillable= ['user_id','pro_name','pro_price','pro_info','image','stock','category_ id'];
}
Products table
class CreateProductsTable extends Migration
{
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('pro_name');
$table->integer('pro_price');
$table->text('pro_info');
$table->integer('stock');
$table->string('image')->nullable();
$table->timestamps();
$table->bigInteger('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
public function down()
{
Schema::dropIfExists('products');
}
}
After updating my code now am getting this errorSQLSTATE[HY000]: General error: 1364 Field 'user_id' doesn't have a default value (SQL: insert intoproducts(pro_name,pro_price,stock,pro_info,i`
Change your validate function. Instead of use $this->validate(),
use $request->validate() method:
$request->validate([
'pro_name'=> 'required',
'pro_price'=> 'required',
'pro_info'=> 'required',
'user_id' => 'required|integer',
'image'=>'image|mimes:png,jpg,jpeg|max:10000'
]);
If the validation rules pass, your code will keep executing normally; however, if validation fails, an exception will be thrown and the proper error response will automatically be sent back to the user.
Another solution:
Add
use Validator;
to your class.
$validator = Validator::make($request->all(), [
'pro_name'=> 'required',
'pro_price'=> 'required',
'pro_info'=> 'required',
'user_id' => 'required|integer',
'image'=>'image|mimes:png,jpg,jpeg|max:10000'
]);
if($validator->fails()){
//Validation does not pass logic here
}else{
//
}
One more:
Create a form request, with
php artisan make:request RequestName
The file will be created in app\Http\Requests directory.
Within the file, add your rules to the rules method:
public function rules()
{
return [
'pro_name'=> 'required',
'pro_price'=> 'required',
'pro_info'=> 'required',
'user_id' => 'required|integer',
];
}
Change the authorize method, to return true:
public function authorize()
{
return true;
}
In your store method, swap the Request $request with RequestName $request.
Now you don't need to validate the $request inside store method. It will go to store only if the validation succeed;
Your store method now should looks like
public function store(RequestName $request)
{
$formInput=$request->except('image');
$image=$request->image;
if($image){
$imageName=$image->getClientOriginalName();
$image->move('images', $imageName);
$formInput['image']=$imageName;
}
products_model::create(array_merge(
$formInput, ['user_id' => Auth::user()->id]
));
return redirect()->back();
}
Dont forget to use App\Http\Requests\RequestName
If validation fails, a redirect response will be generated to send the user back to their previous location. The errors will also be flashed to the session so they are available for display. If the request was an AJAX request, a HTTP response with a 422 status code will be returned to the user including a JSON representation of the validation errors.
You can learn more about request validation here.
[EDIT]
I change the users_id rule to user_id, to match with your foreign key name.
I think you made a typo here when you asked the question.
Hope it helps.

How to add user_id to login parameter in Laravel?

Below is some method in a trait AuthenticatesUsers where Illuminate\Foundation\Auth, Laravel.
...
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->username() => 'required|string',
'password' => 'required|string',
]);
}
...
public function username()
{
return 'email';
}
Originally, my goal is to make another login form with user_id and password in mobile device, so this will check Auth() and if success, it will work some method and automatically logout after then. could you tell me detailed advice?
Additional question.
as Jaskaran Singh's advice I added it also as below.
protected function authenticated(Request $request, $user)
{
if($request->Inn == 'Inn') {
return redirect()->route('mobiles_start', ['Inn' => 'Inn']);
}
elseif($request->Ut == 'Ut') {
return redirect()->route('mobiles_destroy', ['Ut' => 'Ut']);
}
return view('welcome');
}
but if login failed, then it is redirected back to the /login page instead of expected view page that pre defined in the route(mobiles_start and mobiles_destroy) above.
How could I do?
You can login with User ID like this:
if(Auth::loginUsingId($user->id)){
return response()->json(['success' => $user], $this->successStatus);
}
You don't have to extend the core trait or any core Laravel code.
in app/Http/Controllers/Auth/LoginController.php add the following functions, this will override the default functions in AuthenticatesUsers trait.
add username() function
public function username()
{
if(request('id')){
return 'id'; // if request contains id then return it
}
return 'email'; // else return email
}
add validateLogin() function
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->username() => 'required', //remove |string
'password' => 'required|string',
]);
}
that's it.

How to use Custom and Default Validation Together?

I have custom validation for validating data. The custom validation doesn't have unique rule as I need to ignore this on update, therefore I am using unique rule on store() method. But this is ignored, and it only works if I change the custom validation with default validation.
It works if I have the following:
public function store(Request $request)
{
if (!$this->user instanceof Employee) {
return response()->json(['error' => 'Unauthorized'], 401);
}
$request->validate([
'name' => 'required|max:50|unique:centers'
]);
$center = Center::create($request->all());
return response()->json($center, 201);
}
But this doesn't work if I change the method signature to the following:
public function store(CustomValidation $request)
How can I use both together? I do not want to move the custom validation code inside the method as I have to repeat msyelf for update method then.
I think it will help you
use Illuminate\Contracts\Validation\Rule;
class CowbellValidationRule implements Rule
{
public function passes($attribute, $value)
{
return $value > 10;
}
public function message()
{
return ':attribute needs more cowbell!';
}
}
and
public function store()
{
// Validation message would be "song needs more cowbell!"
$this->validate(request(), [
'song' => [new CowbellValidationRule]
]);
}
or
public function store()
{
$this->validate(request(), [
'song' => [function ($attribute, $value, $fail) {
if ($value <= 10) {
$fail(':attribute needs more cowbell!');
}
}]
]);
}

Categories