How to Validate and Sanitize Form Checkbox Array? - php

I'm using OctoberCMS based on Laravel and Twig.
I have a form with checkboxes queued[]. They are submitted and deleted with Laravel using a loop.
It all works but how can I validate and sanitize the array?
Validate requires an asterisk *? '*' => Input::get('queued')?
Sanitize, I get the error trim() expects parameter 1 to be string, array given.
Form
<form method="POST" action="{{ url_current() }}">
<input type="hidden" name="_handler" value="onDelete" />
<input type="checkbox" name="queued[]" value="item1" />
<input type="checkbox" name="queued[]" value="item2" />
<input type="checkbox" name="queued[]" value="item3" />
<button type="submit" name="submit" value="delete">Delete Checked</button>
</form>
PHP
public function onDelete() {
# Validator
$validator = Validator::make(
[
'_handler' => Input::get('_handler'),
'queued' => Input::get('queued'),
'submit' => Input::get('submit')
]
);
if ($validator->fails()) {
return Redirect::back()->withErrors($validator);
exit();
}
# Sanitize
function sanitize_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = strip_tags($data);
$data = htmlspecialchars($data);
return $data;
}
# Delete Checked
$checkboxes = '';
$checkboxes = isset($_POST['queued']) ? $_POST['queued'] : array();
// Sanitize
$checkboxes = $this->sanitize_input($checkboxes);
foreach($checkboxes as $file) {
File::delete("$file");
}
}

You can write your own custom validation rules.
You can define a new rule in the plugins boot() method like this:
Validator::extend('myCustomRule', function($attribute, $value, $parameters) {
# check if the $value is in valid
# return true if it is and return false if it is not valid
return true;
});
You can foreach the array and then check the values. Depends on you validation rules, you might not need to sanitize after that.
And then you can use the custom rule by the name you supplied:
$validator = Validator::make(input(), [
'queued' => 'myCustomRule',
]
);

Related

Laravel 8: Function params must be an array

I have a route that must get some parameters:
Route::get('users/{function}/{param}/{feeLimit}/{callValue}/{bandwidthLimit}' , [TronController::class, 'totalUsers']);
And the method totalUsers looks like this:
public function totalUsers($function,$params,$feeLimit,$callValue,$bandwidthLimit){
And in the browser, I call it like this:
http://localhost:8000/users/totalUsers/array()/30000000/0/0
But now I get this error:
Function params must be an array
I know this way of adding parameters is wrong, but I don't how to call the url and variables like this on the browser:
$function="totalUsers";
$params=array();
$feeLimit=30000000;
$callValue = 0;
$bandwidthLimit = 0;
How can I call totalUsers method properly with its parameters?
Update 1
In the method totalUsers:
try {
$trigger = $TransactionBuilder->triggerSmartContract(
(array)$abi,
$contractH,
$function,
$params,
$feeLimit,
$addressH,
$callValue = 0,
$bandwidthLimit = 0);
var_dump($trigger);
} catch (\IEXBase\TronAPI\Exception\TronException $e) {
die($e->getMessage());
}
Easily You can solve this problem by using this route as post:
Route::post('/users' , [TronController::class, 'totalUsers'])->name('users');
Then you can send the value by submitting a form:
<form action="{{ route('users') }}" method="post">
#csrf
<input type="text" name="function" />
<input type="text" name="params[]" />
<input type="text" name="params[]" />
<input type="text" name="params[]" />
.... // how much you want
<input type="text" name="feeLimit" />
<input type="text" name="callValue" />
<input type="text" name="bandwidthLimit" />
<input type="submit" value="Send">
</form>
You will be getting an array for this params field, this is secure and you can send a large number of data character:
In the controller:
public function totalUsers(Request $request)
{
$function=$request->function;
$params=$request->param; // this will be an array
$feeLimit=$request->feeLimit;
$callValue = $request->callValue;
$bandwidthLimit = $request->bandwidthLimit;
foreach( $params as $param )
{
$param; // do what ever you want
}
}
Your error has nothing to do with routes, it's a tron-api's error. The triggerSmartContract() function expects $params to be an array, but you're passing a string.
Easy way to solve that would be just convert your $params string to array in the arguments (array)$params.
Correct way would be to follow advice in this answer, though I'd suggest to validate user input:
public function totalUsers(Request $request)
{
$request->validate([
'function' => 'required|string',
'params' => 'required|array',
'feeLimit' => 'required|numeric',
'callValue' => 'sometimes|numeric',
'bandwidthLimit' => 'sometimes|numeric',
]);
try {
$trigger = $TransactionBuilder->triggerSmartContract(
(array)$abi,
$contractH,
$request->input('function'),
$request->input('params'),
$request->input('feeLimit'),
$addressH,
$request->input('callValue', 0),
$request->input('bandwidthLimit', 0)
);
var_dump($trigger);
} catch (\IEXBase\TronAPI\Exception\TronException $e) {
die($e->getMessage());
}
}

Laravel - Controller not setting some variables when return using Redirect::to

In my controller, I validate the input fields and if any validation fails I want to return back to the form and refill the previous values that the user was inputing (if there is any other easier way instead this please tell me). But here is what I'm doing:
Controller.php:
public function store(Request $request, AnexoController $anexoController)
{
$validator = Validator::make(
$request->all(),
$rules,
$messages
);
if($validator->fails())
{
return Redirect::to($request->headers->get('referer'))
->withErrors($validator)
->withReq($request->all());
}
// continues the function...
}
At the view.blade.php:
<input type="text"
maxlength="256"
id="text-input"
name="id"
placeholder="Código"
class="form-control"
#if(isset($req)) value="{{$req->id}}"
#else value="$REQ VARIABLE NOT SET"
#endif
required>
And when I test it, the field id value is set to "$REQ VARIABLE NOT SET" but $errors from $validator variable is set. So, why isn't the variable $req being set in this context? Thanks in advance.
Use this
$request->validate([
//rules
]);
It will automatically return to form page with all the errors and inputs,
In your form you'll neet do add a helper in value of inputs for old inputs
<input type="text" value={{ old('email')}} name="email">
see https://laravel.com/docs/5.8/validation & https://laravel.com/docs/5.8/helpers

How to apply validation on any single field having same name Laravel?

I have a project that consists of multilingual functionality. So I'm creating a form that consists of multiple languages to be inserted if User wants.
But validation should be like if any of the fields having the same name consist value then leave rest one like as
Form
<form>
<input type="text" name="name[EN]" />
<input type="text" name="name[AR]" />
<input type="text" name="name[FR]" />
<input type="submit" value="submit" />
</form>
Now I want to validate that if any one of these fields have value then submit form else throw a validation
So I've tried Laravels required_if, but it didn't work.
public function rules()
{
return [
'name.*' => 'required_if:name,1',
];
}
So how to make such validation in laravel
I've searched but could not find a built in way of doing this. You can create your own rule using
php artisan make:rule NonEmptyFiltered
and then define the rule as:
class NotEmptyFiltered implements Rule {
public function passes($attribute, $value) {
return !empty(array_filter($value));
}
public function message() {
return ':attribute must have at least one non-null element';
}
}
You can then do:
public function rules()
{
return [
'name' => [ new NonEmptyFiltered() ]
];
}
I believe this should do the trick:
$rules = [
'name.EN' => 'required_without_all:name.AR,name.FR',
'name.AR' => 'required_without_all:name.EN,name.FR',
'name.FR' => 'required_without_all:name.EN,name.AR',
];
The rule makes the field to be required if the other fields are empty https://laravel.com/docs/5.6/validation#rule-required-without-all.

Laravel update array syntax

I'm having trouble doing a record update array via POST in Laravel.
I have captured all the post data in an array cant update array achievement
<form action="{{'updateapp'}}" method="post">
<table>
<tr><td>
<input type="checkbox" class="id" name="id[]" value="{{ $quarter->id }}" />
<input type="text" name="achv[]" value="{{ $quarter->achievement }}">
</td></tr>
</table>
</form>
Controller :
public function foo(Request $request)
{
$ids = $request->id;
$achvs = $request->achv;
DB::table('quarters')->whereIn('id', $ids)
->update(array(['achievement' => $achvs ]));
return redirect('evaluator');
}
As you have set [] array in your form, you can access it as following
public function foo(Request $request)
{
$ids = $request->id[0];
$achvs = $request->achv[0];
DB::table('quarters')->where('id', $ids)
->update(['achievement' => $achvs ]);
return redirect('evaluator');
}
if you want to update multiple rows then use following code:
foreach($request->id as $key => $value){
$quarters = Quarters::find($request->id[$key]);
$quarters->achievement = $request->achv[$key];
$quarters->save();
}
public function foo(Request $request)
{
$ids = $request->id[0];
$achvs = $request->achv[0];
DB::table('quarters')->where('id', $ids)
->update(array(['achievement' => $achvs,'achievement1' => $achvs1]));
return redirect('evaluator');
}

HTML form array validation in Laravel 5.2

How to validate an array coming from HTML form?
ex:
<input type="text" name="test" value="[value1,value2,value3]">
In Laravel:
$validate = Validator::make(
$request->all(),
['test.*'=> 'max:10']
);
But in PHP code the trick doesn't work
In laravel you could try this:
Controller -
public function someAction(){
$validator = Validator::make($request->all(),
[
'test' => 'required|max:10',
'test2' => 'required|max:2'
]
);
if($validator-fails()){
return Somthing;
}else{
// Pass the form input fields values for use
$test = Input::get('test');
$test2 = Input::get('test2');
}
}
Or try this method given here

Categories