laravel validate conditional image field - laravel

i have a field that required, and can be 2 value type : String (path) and Image file
how can write validation rule for this ?
if value is string check file_exist and if is file must be image
thanks

Maybe there's an easier way to do this. However, I think a custom rule as such should work.
$validator = Validator::make($request->all(), [
'image' => [
'required',
function ($attribute, $value, $fail) {
if(is_file($value)) {
if (true !== mb_strpos($value->getMimeType(), "image")) {
return $fail($attribute.' is invalid.');
}
}
if (is_string($value)) {
if(! file_exists($value)) {
return $fail($attribute.' is invalid.');
}
}
},
],
]);

i found my answer with FormRequest
MyTestFormRequest
<?php
use Illuminate\Foundation\Http\FormRequest;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class MyTestFormRequest extends FormRequest
{
public function rules()
{
$rules = [
"image" => ['required']
];
if(is_string($this->image)) {
$rules['image'][] = new FileExistsRule;
} else if($this->image instanceof UploadedFile) {
$rules['image'][] = 'image';
$rules['image'][] = 'dimensions:ratio=1/1';
}
return $rules;
}
}
FileExistsRule
<?php
use Illuminate\Contracts\Validation\Rule;
class FileExistsRule implements Rule
{
public function passes($attribute, $value)
{
return file_exists(public_path($value));
}
public function message()
{
return 'The file not exists';
}
}

Related

Laravel FormRequest: client sends attribute with dots inside

Client sends something like this:
foo.1.bar=hello
in my FormRequest class I have tried:
public function rules()
{
return [
'foo.1.bar' => 'string|nullable' // does not work
'foo' => 'array|nullable' // does not work
'foo' => [ // does not work
'1' => [
'bar' => 'string|nullable'
]
]
Any idea how to handle this?
Try getting the value of the parameter manually and then validating it:
class YourRequest extends FormRequest
{
public function rules(): array
{
return [...];
}
public function withValidator(Validator $validator): void
{
$value = $this->get('foo.1.bar') ?: $this->get('foo_1_bar');
$validator->after(function (Validator $validator) use ($value) {
if ($value == null) {
$validator->errors()->add('foo.1.bar', 'Error Message.');
$validator->errors()->add('foo_1_bar', 'Error Message.');
}
});
}
}

Laravel default values for fields in FormRequest

Can I set a default value to a not-existing field in a FormRequest in Laravel?
For example, if a field called "timezone" does not exist in the incoming request, it get set to "America/Toronto".
Well I wrote a trait for this, which checks a function called 'defaults' exist in the form request it will replace the default values
trait RequestDefaultValuesTrait {
protected function prepareForValidation(){
// add default values
if( method_exists( $this, 'defaults' ) ) {
foreach ($this->defaults() as $key => $defaultValue) {
if (!$this->has($key)) $this->merge([$key => $defaultValue]);
}
}
}
}
the thing that you need to do is adding this trait to FormRequest class and then add a function like this:
protected function defaults()
{
return [
'country' => 'US',
'language' => 'en',
'timezone' => 'America/Toronto',
];
}
Being honest I don't link this method, but It works.
Try this
if(!$request->has('timezone') {
$request->merge(['timezone' =>'America/Toronto']);
}
I'm not so sure if you need to do it in this way, but if you want to:
class CreateUpdateDataFormRequest extends Request
{
public function authorize()
{
return true;
}
public function rules()
{
return [];
}
protected function getValidatorInstance()
{
$data = $this->all();
if(!isset($data['timezone'])) {
$data['timezone'] = 'America/Toronto';
$this->getInputSource()->replace($data);
}
// modify data before sending to validator
return parent::getValidatorInstance();
}
in request class add
public function prepareForValidation()
{
$this->mergeIfMissing([
'timezone' => 'America/Toronto'
]);
}

Laravel - Error "Argument 2 passed to Illuminate\Validation\Factory::make() must be of the type array, object given"

What's wrong with this code ?
class DeleteDetail extends FormRequest {
public function authorize() {
return true;
}
public function rules() {
$request = Request::all();
$rules = [
'hobby' => [
'string',
'between:3,20',
Rule::exists('user_hobby')->where(function ($query) use ($request) {
$query->where('hobby', $request['hobby'])->where('user_id', Auth::user()->id);
}),
],
];
return Validator::make($request, $rules);
}
}
Error that I'm getting :
Argument 2 passed to Illuminate\Validation\Factory::make() must be of the type array, object given
You are returning the wrong value from inside the rules method itself, you should return the array containing your validation rules instead of Validation::make:
public function rules() {
...
return $rules;
}
Your rules function should return the array with the rules.
public function rules() {
$request = Request::all();
$rules = [
'hobby' => [
'string',
'between:3,20',
Rule::exists('user_hobby')->where(function ($query) use ($request) {
$query->where('hobby', $request['hobby'])->where('user_id', Auth::user()->id);
}),
],
];
return $rules;
}
Then in your controller:
public function store(DeleteDetail $request)
{
// the code in here has passed the validation..
}

How to add own data to POST in YII2?

i've question about adding some data outside form and send it with form data. Look! I have 3 fields ActiveForm:
name (text)
email (email)
course (hidden)
Ok, but i need to add one more named "status". I do not want to add hidden fields, just want to add inside controller or model.
How?
Controller:
public function actionFree()
{
$model = new SubscribeForm();
$this->view->title = "ШКОЛА ПИСАТЕЛЬСКОГО МАСТЕРСТВА: Новичок курс";
if ($post = $model->load(Yii::$app->request->post())) {
if ($model->save()) {
Yii::$app->session->setFlash('success', 'Данные приняты');
return $this->refresh();
}
else {
Yii::$app->session->setFlash('error', 'Ошибка');
}
}
else {
// страница отображается первый раз
return $this->render('free-course', ['model' => $model, 'course_id' => 1]);
}
}
Model:
class SubscribeForm extends ActiveRecord
{
public $fio;
public $email;
public $course;
public $status;
public static function tableName()
{
return 'users';
}
public function rules()
{
return [
// username and password are both required
[['fio', 'email'], 'required'],
[['email'], 'unique'],
['email', 'email'],
['email', 'safe']
];
}
}
You could just set the value in your controller, like this:
public function actionFree()
{
$model = new SubscribeForm();
$model->status = 'your-status-value';
// ... the rest of your code
Or you could add a default value in your model. This way you can still overrule the value from the controller or a form field, but will get this value when nothing else is supplied.
public function rules()
{
return [
['status', 'default', 'value' => 'your-default-status-value'],
// .. other rules
];
}

Laravel 5.6 FormRequest validation

I have set of input fields to be validated. I have removed commas (since user enters comma as thousand separator) before validation takes place. But it still complains that the number is not numeric.
class UpdateFamilyExpense extends FormRequest
{
public function authorize()
{
return true;
}
public function sanitize()
{
$attributes = $this->all();
for ($i=1; $i<=15; $i++)
{
$attributes['e'.$i] = str_replace(',', '', $attributes['e'.$i]);
}
$this->replace($attributes);
}
public function rules()
{
$this->sanitize();
return [
'e1' => 'required|numeric',
];
}
public function messages()
{
return [
'e1.required' => 'required',
'e1.numeric' => 'must be a numeric',
];
}
}
I cannot figure out where I am wrong. Can someone help me figure out what I am missing here?
Override prepareForValidation as:
protected function prepareForValidation()
{
$this->sanitize();
}

Resources