As an example of Laravel validation:
$validatedData = $request->validate([
'title' => ['required', 'unique:posts', 'max:255'],
'body' => ['required'],
]);
I want to add path exists or not in storage .
Storage::exists('/path/to/your/directory');
Based on this I want to do something like :
$validatedData = $request->validate([
'title' => ['required', 'unique:posts', 'max:255'],
'body' => ['required'],
'path' => ['storage_file_exists_or_not']
]);
How to achieve that. Thanks.
You can create a custom rule using
php artisan make:rule StorageFileExists
and specify your condition inside the passes function and write your message.
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Facades\Storage;
class StorageFileExists implements Rule
{
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
return (Storage::exists($value)) ? false : true;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'File is present.';
}
}
and write validation rule like this
$request->validate([
'path' => new StorageFileExists(), // your Rulename
]);
Related
I am working with laravel 9.1. I want to validate two request inputs in single column of a table. below is my validation rule in form request.
Basically name = resource_name . permission_type i thought of merging both column before the validation but the problem is both fields needs to be validated first before concatination.
Can anyone please help me how do i validate resource_name and permission_type first and then check for resource_name.permission_type in the name column permission_types table.
Thankyou.
$name = $this->request->input('resource_name') . '.' . $this->request->input('permission_type');
$this->request->merge([
'name' => $name,
]);
return [
'type' => ['required'],
'resource_name' => ['required', 'alpha', 'min:3', 'max:50'],
'permission_type' => ['required'],
'name' => ''
];
Try this
$name = $request->validate([
'type' => ['required'],
'resource_name' => ['required'],
'permission_type' => ['required'],
'name' => [
$request->input('resource_name'). '.' .$request->input('permission_type')
]
]);
Ok, this is what i did. the name field is an actual field in the database but its data is coming from two different inputs i.e resource_name and permission_type if the field is not present in request the rules won't get triggered and applied, so i create a hidden input type with permission_name in view. and created a custom validator which does the job.
<input type="hidden" name="permission_name" value="" />
FORM REQUEST:
$rules = [
'resource_type' => ['required'],
'resource_name' => ['required', 'alpha', 'min:3', 'max:50', new IsPlural],
'permission_type_name_single' => ['required'],
'permission_name' => new UniqueTwoInputsInOneColumn('permissions', 'name', $this->request->get('resource_name'), $this->request->get('permission_type_name_single'))
];
CUSTOM RULE:
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Facades\DB;
class UniqueTwoInputsInOneColumn implements Rule
{
protected $tableName;
protected $columnName;
protected $value1;
protected $value2;
protected $ignoreField;
protected $ignoreFieldValue;
/**
* Create a new rule instance.
*
* #return void
*/
public function __construct($tableName, $columnName, $value1, $value2, $ignoreField = null, $ignoreFieldValue = null)
{
$this->tableName = $tableName;
$this->columnName = $columnName;
$this->value1 = $value1;
$this->value2 = $value2;
$this->ignoreField = $ignoreField;
$this->ignoreFieldValue = $ignoreFieldValue;
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
if (!$this->ignoreField)
{
return DB::table($this->tableName)->where($this->columnName, $this->value1 . '.' . $this->value2)->count() == 0;
}
else
{
return DB::table($this->tableName)->where($this->columnName, $this->value1 . '.' . $this->value2)->where($this->ignoreField, '!=', $this->ignoreFieldValue)->count() == 0;
}
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The Permission name ' . $this->value1 . '.' . $this->value2 . ' already exists.';
}
}
Add this code :
$validatedData = $request->validate([
'resource_name' => ['required', 'alpha','min:3', 'max:255'],
'permission_type' => ['required'],
]);
i want to redirect to a previously accessed page right before accessing the registration page after a user has successfully registered themselves. I edited the registration controller as below although i get the following exception View [http:..127.0.0.1:8000.prices] not found. I cross checked my routes and everything is fine. Here is my register controller.
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* #var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'fname' => ['required', 'string', 'max:255'],
'lname' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'phonenumber' => ['required', 'string', 'min:10', 'max:10'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\User
*/
protected function create(array $data)
{
return User::create([
'fname' => $data['fname'],
'lname' => $data['lname'],
'email' => $data['email'],
'phonenumber' => $data['phonenumber'],
'password' => Hash::make($data['password']),
]);
}
/**
* Show the application's registration form.
*
* #return \Illuminate\Http\Response
*/
public function showRegistrationForm()
{
if(session('link')) {
$myPath = session('link');
$registerPath = url('/register');
$previous = url()->previous();
if($previous = $registerPath) {
session(['link' => $myPath]);
}else{
session(['link' => $previous]);
}
}else{
session(['link' => url()->previous()]);
}
return view('auth.register');
}
protected function redirectTo()
{
if(session('link')){
return view(session('link'));
}
return view('/');
}
}
I think the issue is most likely to be with the function:
protected function redirectTo()
{
if(session('link')){
return view(session('link'));
}
return view('/');
}
I tried replacing return view(session('link')); with return url()->previous(); but there was no luck. I am using laravel 7.
The issue was actually with adding view. Instead of return view(session('link')); use return (session('link')); Same applies to the return outside the if statement.
try to use redirect back
return Redirect::back();
do not forget to import redirect in controller
use Redirect;
I am developing A web Application using Laravel-5.8 framework. I have a Model Class as shown below:
<?php
namespace App;
use App\Model;
class Gradesystem extends Model
{
protected $table = 'grade_systems';
}
Also my Controller is shown below:
public function store(Request $request){
$request->validate([
'grade_system_name' => 'required|string|max:255',
'point' => 'required',
'grade' => 'required',
'from_mark' => 'required',
'to_mark' => 'required',
]);
$gpa = new Gradesystem;
$gpa->grade_system_name = $request->grade_system_name;
$gpa->point = $request->point;
$gpa->grade = $request->grade;
$gpa->from_mark = $request->from_mark;
$gpa->to_mark = $request->to_mark;
$gpa->save();
}
How do I validate, probably from the Model or the Controller between from_mark and to_mark. Also, from_mark should not be greater that or equal to to_mark.
It must not allow a number that falls in the range of already existing value. For example if from_mark is 0 and to_mark is 49 are already in database. So, if a user enters from_mark or to_mark to be 30, it must not allow it.
How do I achieve this?
Thank you.
For custom Validations its better use Rule Objects, where you can implement the logic of your validation.
An Example:
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class Uppercase implements Rule
{
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
return strtoupper($value) === $value;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The :attribute must be uppercase.';
}
}
You can see the info in the Laravel documentation
Hope this can help you
I did not understand entire validation you asked but this will help. With same way you can write any other validation on from_mark and to_mark.
$validator = Validator::make($request->all(), [
'grade_system_name' => 'required|string|max:255',
'point' => 'required',
'grade' => 'required',
'from_mark' => 'required',
'to_mark' => 'required',
]);
if ($validator->fails()) {
return redirect()->back()->withInput()->withErrors();
}
if ($request->get('from_mark') < $request->get('to_mark')) {
return redirect()->back()->withInput()->withErrors();
}
I am begginer, and trying to create a referral system. following is sample url
http://dev.lea.com/register?ref=mh2HPLpVSn
I try to get referral string. how can i get separately? is there need of middleware for getting cookies? if yes then what will be code of middleware? and how can i get referral reference in RegisterController?
Here is my Register Controller.
<?php
namespace Lea\Http\Controllers\Auth;
use DB;
use Lea\User;
use Lea\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Http\Request;
use Cookie;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* #var string
*/
protected $redirectTo = '/';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'fname' => 'required|string|max:255',
'lname' => 'required|string|max:255',
'referral' => 'string|max:255',
'username' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
// 'tracking_id' => 'required',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \Lea\User
*/
protected function create(array $data, Request $request)
{
// printing here referral Link
echo $request()->ref;
// $referred_by = Cookie::get();
// print_r($referred_by);
die;
return User::create([
'fname' => $data['fname'],
'lname' => $data['lname'],
'username' => $data['username'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'affiliate_id' => str_random(10),
// 'referred_by' => $referred_by,
'identity' => $data['identity'],
'dob' => $data['dob'],
'board_id' => $data['board_id'],
'class_id' => $data['class_id'],
'subject_id' => $data['subject_id'],
'institute' => $data['institute'],
'address' => $data['address'],
'city' => $data['city'],
'std_mobile' => $data['std_mobile'],
'father_name' => $data['father_name'],
'father_mobile' => $data['father_mob'],
'ipadress' => \Request::ip(),
]);
}
}
When you have an URI such as /register?ref=mh2HPLpVSn you can retrieve ref like this:
$request()->ref
in your controller! I believe you can also use $request()->has('ref') to determine if it's present in the URI.
Hope this helps you!!
In laravel 6+ inside controller you can use like
$request->get('ResourcePath')
You can get your parameters using Request access.
Here one example for get your ref code:
public function register(Request $request)
{
$allParams = $request->all();
$refParam = $request->ref;
dd($allParams, $refParam);
...
}
public function showRegister(Request $request) {
var_dump(request->ref)
}
then you can do things like validation and so on, another possiblity is to change the template of your register form and add a hidden field with the refcode from the ref param and handle the whole request in your register method.
So I am trying to group all my validation rules into its respective files in folders for easy maintenance. Below is how my folder structures look:
Project
--app
--config
--(more folders)
--domains
----App
--------Entities
--------Repositories
--------Services
--------Validators
----Core
--------Validators
So what I wanted to achieve is under Core\Validators I created a LaravelValidator.php which look like this
<?php namespace Core\Validators;
use Validator;
abstract class LaravelValidator {
/**
* Validator
*
* #var \Illuminate\Validation\Factory
*/
protected $validator;
/**
* Validation data key => value array
*
* #var Array
*/
protected $data = array();
/**
* Validation errors
*
* #var Array
*/
protected $errors = array();
/**
* Validation rules
*
* #var Array
*/
protected $rules = array();
/**
* Custom validation messages
*
* #var Array
*/
protected $messages = array();
public function __construct(Validator $validator)
{
$this->validator = $validator;
}
/**
* Set data to validate
*
* #return \Services\Validations\AbstractLaravelValidator
*/
public function with(array $data)
{
$this->data = $data;
return $this;
}
/**
* Validation passes or fails
*
* #return Boolean
*/
public function passes()
{
$validator = Validator::make(
$this->data,
$this->rules,
$this->messages
);
if ($validator->fails())
{
$this->errors = $validator->messages();
return false;
}
return true;
}
/**
* Return errors, if any
*
* #return array
*/
public function errors()
{
return $this->errors;
}
}
Then in my App\Validators I created a file name RegistrationFormValidator.php which look like this
<?php namespace App\Validators\Profile;
class RegistrationFormValidator extends \Core\Validators\LaravelValidator
{
protected $rules = array(
'first_name' => 'required',
'last_name' => 'required',
'username' => 'required',
'password' => 'required',
'rTPassword' => 'required',
'profile_url' => 'required',
'email' => 'required|email',
'gender' => 'required',
'dob' => 'required',
);
}
so usually in laravel 4.2, to validate something all i do is construct the validation rules and then call it in services which look like this
<?php namespace App\Services\Profile;
/*
|-----------------------------------------------------------
| This section injects the repositories being used
| in this service.
|-----------------------------------------------------------
*/
use App\Repositories\Profile\ProfileRepository;
use Core\ValidationFailedException;
use App\Validators\Profile\RegistrationFormValidator;
use Validator;
class ProfileService implements ProfileServiceInterface
{
protected $_profile;
protected $v;
/*
|-----------------------------------------------------------
| All construsted models variables must carry
| the '_' sign to identify it as a model variable
|-----------------------------------------------------------
*/
public function __construct(ProfileRepository $_profile, RegistrationFormValidator $v)
{
$this->_profile = $_profile;
$this->v = $v;
}
/*
|-----------------------------------------------------------
| 1. All try and catch error handling must be done
| in the respective controllers.
|
| 2. All data formattings must be done in this section
| then pass to repository for storing.
|
| 3. No controller actions allown in this section
|-----------------------------------------------------------
*/
public function createProfile($array)
{
if($this->v->passes())
{
//save into db
}
else
{
throw new ValidationFailedException(
'Validation Fail',
null,
$this->v->errors()
);
}
}
}
But the problem is once i upgraded into laravel 5 i did the same thing and when i try to execute the code it returns me with this error
ErrorException in ProfileService.php line 26:
Argument 2 passed to App\Services\Profile\ProfileService::__construct() must be an instance of App\Validators\Profile\RegistrationFormValidator, none given
My code works absolutely fine in L4.2 but once i upgraded it wont work anymore. I also know that i can do validation like such
public function createProfile($array)
{
$v = Validator::make($array, [
'first_name' => 'required',
'last_name' => 'required',
'username' => 'required',
'password' => 'required',
'rTPassword' => 'required',
'profile_url' => 'required',
'email' => 'required|email',
'gender' => 'required',
'dob' => 'required',
]);
if($v->passes())
{
}
else
{
throw new ValidationFailedException(
'Validation Fail',
null,
$v->errors()
);
}
}
But the problem is if i would have more validation rules or scenario it will flood the whole service file.
Any suggestions or solutions that will guide me? thanks in advance!
In Laravel 5 you have something similar, which handles better the validation and makes validation clean and easy. It is called Form Request Validation. The idea there is the same - to have different classes that handle validation in different scenarios.
So whenever you need a validation you can create new FormRequest, like this:
php artisan make:request RegisterFormRequest
A new class will be generated under app/Http/Requests. There you can see it has two methods authorize and rules. In the first one you can make a check if given user is allwed to make this request. In the second method you can define your rules, just like in the validator.
public functions rules() {
return array(
'first_name' => 'required',
'last_name' => 'required',
'username' => 'required',
'password' => 'required',
'rTPassword' => 'required',
'profile_url' => 'required',
'email' => 'required|email',
'gender' => 'required',
'dob' => 'required',
);
}
Then you can change your controller method like this:
public function postCreateProfile(RegisterFormRequest $request) {
// your code here
}
The are a few cool things here. First one - the class will be automatically constructed in injected in your controller method by the IoC container, you don't need to do something special. The second cool thing is that the validation check is done before the Request object is passed to the controller, so if any validation error occurs you will be redirected back with all errors according to your rules set. This means that writing your code in the postCreateProfile method you can assume if this code get executed the validation is passed at this position and no additional check are needed by you.
I suggest you to migrate your code to use Laravel 5 Form Requests, because what you need is already implemented in the framework, and yes basically this is the point of the migration of one version to another. You can also check the documentation for more examples.