Skip to content

Instantly share code, notes, and snippets.

@kmuenkel
Last active November 4, 2021 16:53
Show Gist options
  • Save kmuenkel/8b926c398c22d7641ef1e99bb8c2508a to your computer and use it in GitHub Desktop.
Save kmuenkel/8b926c398c22d7641ef1e99bb8c2508a to your computer and use it in GitHub Desktop.
Laravel Request Parameter Filtering: Remove request parameters not defined in the request ruleset, if there is one. Returns false if parameters were attempted, but none were permitted.
<?php
namespace App\Http\Requests;
class Request extends FormRequest
{
/**
* @return bool
*/
public function filterFields()
{
//Dot notation makes it possible to parse nested values without recursion
$original = array_dot($this->all());
$filtered = [];
//If there are no rules, accept any input
$rules = collect($this->rules());
if ($rules->isEmpty()) {
return true;
}
//Make room for tokens being placed as a URL query parameter, and Fractal includes
$exceptions = [
self::TOKEN_NAME => 'string',
self::INCLUDE_NAME => 'string',
camel_case(self::ADMIN_TOKEN_NAME) => 'string',
snake_case(self::ADMIN_TOKEN_NAME) => 'string'
];
$keys = $rules->keys()->merge(array_keys($exceptions));
$rules = $rules->merge($exceptions);
$rules->each(function ($rules, $key) use ($original, $keys, &$filtered) {
//Allow for array or pipe-delimited rule-sets
if (is_string($rules)) {
$rules = explode('|', $rules);
}
//In case a rule requires an element to be an array, look for nested rules
$nestedRules = $keys->filter(function ($otherKey) use ($key) {
return (strpos($otherKey, "$key.") === 0);
});
//If the input must be an array, default missing nested rules to a wildcard
if (in_array('array', $rules) && $nestedRules->isEmpty()) {
$key .= ".*";
}
foreach ($original as $dotIndex => $element) {
//fnmatch respects wildcard asterisks
if (fnmatch($key, $dotIndex)) {
//array_set respects dot-notation, building out a normal array
array_set($filtered, $dotIndex, $element);
}
}
});
//Replace all input values with the filtered set
$this->replace($filtered);
//If field changes were attempted, but non were permitted, false here may indicate a 403 if used in authorize()
return (empty($original) || !empty($this->all()));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment