Skip to content

Instantly share code, notes, and snippets.

@kmuenkel
Last active November 30, 2020 17:59
Show Gist options
  • Save kmuenkel/dcf128af745e84e1d0dc8c3dd94d4aec to your computer and use it in GitHub Desktop.
Save kmuenkel/dcf128af745e84e1d0dc8c3dd94d4aec to your computer and use it in GitHub Desktop.
Custom Validator Rule that combines 'in' with filter_var() filters.
<?php
namespace App\Validators\Rules;
use Illuminate\Support\Arr;
use Illuminate\Validation\Validator;
use Illuminate\Contracts\Validation\Rule;
use function Lti\{filter_var_multi, get_flag_names, str_putcsv};
/**
* Class Any
* @package Lti\Validators\Rules
*/
class EnumOrFilter implements Rule
{
/**
* @var string[]
*/
protected $parameters = [];
/**
* @var string[]
*/
protected $enum = [];
/**
* @var string[]
*/
protected $filters = [];
/**
* EnumOrFilter constructor.
* @param array $parameters
*/
public function __construct($parameters = [])
{
$this->parameters = $parameters;
}
/**
* @inheritDoc
*/
public function passes($attribute, $value, $parameters = [], Validator $validator = null)
{
$parameters = $parameters ?: $this->parameters;
$parameters = array_map('str_getcsv', $parameters);
[$this->enum, $this->filters] = array_pad($parameters, 2, []);
return in_array($value, $this->enum) || filter_var_multi($value, $this->filters);
}
/**
* @inheritDoc
*/
public function message()
{
$filterNames = get_flag_names('FILTER_VALIDATE_*', 'filter');
$filters = Arr::only($filterNames, $this->filters);
return 'The :attribute must be: '.str_putcsv($this->enum, ',').', or match: '.implode(',', $filters).'.'
. ' :input given.';
}
}
if (!function_exists('str_putcsv')) {
/**
* @param array $input
* @param string $delimiter
* @param string $enclosure
* @return string
*/
function str_putcsv(array $input, $delimiter = ',', $enclosure = '"')
{
$handle = fopen('php://temp', 'r+');
try {
fputcsv($handle, $input, $delimiter, $enclosure);
rewind($handle);
$data = fread($handle, 1048576);
} finally {
fclose($handle);
}
return rtrim($data, "\n");
}
}
if (!function_exists('filter_var_multiple')) {
/**
* @param mixed $value
* @param array $filters
* @return bool
*/
function filter_var_multi($value, array $filters): bool
{
return array_reduce($filters, function ($passes, $filter) use ($value) {
return $passes || filter_var($value, $filter);
}, false);
}
}
if (!function_exists('get_flag_names')) {
/**
* @param string $pattern
* @param string $filter
* @return array
*/
function get_flag_names(string $pattern, string $filter = '')
{
$filterNames = $filter ? get_defined_constants(true)[$filter] : get_defined_constants();
return array_flip(array_filter($filterNames, function (string $key) use ($pattern) {
return fnmatch($pattern, $key);
}, ARRAY_FILTER_USE_KEY));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment