暂存
This commit is contained in:
+94
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
use Illuminate\Contracts\Validation\ValidatorAwareRule;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class AnyOf implements Rule, ValidatorAwareRule
|
||||
{
|
||||
/**
|
||||
* The rules to match against.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected array $rules = [];
|
||||
|
||||
/**
|
||||
* The validator performing the validation.
|
||||
*
|
||||
* @var \Illuminate\Validation\Validator
|
||||
*/
|
||||
protected $validator;
|
||||
|
||||
/**
|
||||
* Sets the validation rules to match against.
|
||||
*
|
||||
* @param array $rules
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct($rules)
|
||||
{
|
||||
if (! is_array($rules)) {
|
||||
throw new InvalidArgumentException('The provided value must be an array of validation rules.');
|
||||
}
|
||||
|
||||
$this->rules = $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the validation rule passes.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
foreach ($this->rules as $rule) {
|
||||
$validator = Validator::make(
|
||||
Arr::isAssoc(Arr::wrap($value)) ? $value : [$value],
|
||||
Arr::isAssoc(Arr::wrap($rule)) ? $rule : [$rule],
|
||||
$this->validator->customMessages,
|
||||
$this->validator->customAttributes
|
||||
);
|
||||
|
||||
if ($validator->passes()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation error messages.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
$message = $this->validator->getTranslator()->get('validation.any_of');
|
||||
|
||||
return $message === 'validation.any_of'
|
||||
? ['The :attribute field is invalid.']
|
||||
: $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current validator.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Validation\Validator $validator
|
||||
* @return $this
|
||||
*/
|
||||
public function setValidator($validator)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Stringable;
|
||||
|
||||
use function Illuminate\Support\enum_value;
|
||||
|
||||
class ArrayRule implements Stringable
|
||||
{
|
||||
/**
|
||||
* The accepted keys.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $keys;
|
||||
|
||||
/**
|
||||
* Create a new array rule instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|array|null $keys
|
||||
*/
|
||||
public function __construct($keys = null)
|
||||
{
|
||||
if ($keys instanceof Arrayable) {
|
||||
$keys = $keys->toArray();
|
||||
}
|
||||
|
||||
$this->keys = is_array($keys) ? $keys : func_get_args();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the rule to a validation string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
if (empty($this->keys)) {
|
||||
return 'array';
|
||||
}
|
||||
|
||||
$keys = array_map(
|
||||
static fn ($key) => enum_value($key),
|
||||
$this->keys,
|
||||
);
|
||||
|
||||
return 'array:'.implode(',', $keys);
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
use Illuminate\Contracts\Validation\ValidatorAwareRule;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class Can implements Rule, ValidatorAwareRule
|
||||
{
|
||||
/**
|
||||
* The ability to check.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $ability;
|
||||
|
||||
/**
|
||||
* The arguments to pass to the authorization check.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $arguments;
|
||||
|
||||
/**
|
||||
* The current validator instance.
|
||||
*
|
||||
* @var \Illuminate\Validation\Validator
|
||||
*/
|
||||
protected $validator;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $ability
|
||||
* @param array $arguments
|
||||
*/
|
||||
public function __construct($ability, array $arguments = [])
|
||||
{
|
||||
$this->ability = $ability;
|
||||
$this->arguments = $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the validation rule passes.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
$arguments = $this->arguments;
|
||||
|
||||
$model = array_shift($arguments);
|
||||
|
||||
return Gate::allows($this->ability, array_filter([$model, ...$arguments, $value]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation error message.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
$message = $this->validator->getTranslator()->get('validation.can');
|
||||
|
||||
return $message === 'validation.can'
|
||||
? ['The :attribute field contains an unauthorized value.']
|
||||
: $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current validator.
|
||||
*
|
||||
* @param \Illuminate\Validation\Validator $validator
|
||||
* @return $this
|
||||
*/
|
||||
public function setValidator($validator)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Stringable;
|
||||
|
||||
use function Illuminate\Support\enum_value;
|
||||
|
||||
class Contains implements Stringable
|
||||
{
|
||||
/**
|
||||
* The values that should be contained in the attribute.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $values;
|
||||
|
||||
/**
|
||||
* Create a new contains rule instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|\UnitEnum|array|string $values
|
||||
*/
|
||||
public function __construct($values)
|
||||
{
|
||||
if ($values instanceof Arrayable) {
|
||||
$values = $values->toArray();
|
||||
}
|
||||
|
||||
$this->values = is_array($values) ? $values : func_get_args();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the rule to a validation string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$values = array_map(function ($value) {
|
||||
$value = enum_value($value);
|
||||
|
||||
return '"'.str_replace('"', '""', (string) $value).'"';
|
||||
}, $this->values);
|
||||
|
||||
return 'contains:'.implode(',', $values);
|
||||
}
|
||||
}
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
use function Illuminate\Support\enum_value;
|
||||
|
||||
trait DatabaseRule
|
||||
{
|
||||
/**
|
||||
* The table to run the query against.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table;
|
||||
|
||||
/**
|
||||
* The column to check on.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $column;
|
||||
|
||||
/**
|
||||
* The extra where clauses for the query.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $wheres = [];
|
||||
|
||||
/**
|
||||
* The array of custom query callbacks.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $using = [];
|
||||
|
||||
/**
|
||||
* Create a new rule instance.
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $column
|
||||
*/
|
||||
public function __construct($table, $column = 'NULL')
|
||||
{
|
||||
$this->column = $column;
|
||||
|
||||
$this->table = $this->resolveTableName($table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the name of the table from the given string.
|
||||
*
|
||||
* @param string $table
|
||||
* @return string
|
||||
*/
|
||||
public function resolveTableName($table)
|
||||
{
|
||||
if (! str_contains($table, '\\') || ! class_exists($table)) {
|
||||
return $table;
|
||||
}
|
||||
|
||||
if (is_subclass_of($table, Model::class)) {
|
||||
$model = new $table;
|
||||
|
||||
if (str_contains($model->getTable(), '.')) {
|
||||
return $table;
|
||||
}
|
||||
|
||||
return implode('.', array_map(function (string $part) {
|
||||
return trim($part, '.');
|
||||
}, array_filter([$model->getConnectionName(), $model->getTable()])));
|
||||
}
|
||||
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a "where" constraint on the query.
|
||||
*
|
||||
* @param \Closure|string $column
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|\UnitEnum|\Closure|array|string|int|bool|null $value
|
||||
* @return $this
|
||||
*/
|
||||
public function where($column, $value = null)
|
||||
{
|
||||
if ($value instanceof Arrayable || is_array($value)) {
|
||||
return $this->whereIn($column, $value);
|
||||
}
|
||||
|
||||
if ($column instanceof Closure) {
|
||||
return $this->using($column);
|
||||
}
|
||||
|
||||
if (is_null($value)) {
|
||||
return $this->whereNull($column);
|
||||
}
|
||||
|
||||
$value = enum_value($value);
|
||||
|
||||
$this->wheres[] = compact('column', 'value');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a "where not" constraint on the query.
|
||||
*
|
||||
* @param string $column
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|\UnitEnum|array|string|int $value
|
||||
* @return $this
|
||||
*/
|
||||
public function whereNot($column, $value)
|
||||
{
|
||||
if ($value instanceof Arrayable || is_array($value)) {
|
||||
return $this->whereNotIn($column, $value);
|
||||
}
|
||||
|
||||
$value = enum_value($value);
|
||||
|
||||
return $this->where($column, '!'.$value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a "where null" constraint on the query.
|
||||
*
|
||||
* @param string $column
|
||||
* @return $this
|
||||
*/
|
||||
public function whereNull($column)
|
||||
{
|
||||
return $this->where($column, 'NULL');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a "where not null" constraint on the query.
|
||||
*
|
||||
* @param string $column
|
||||
* @return $this
|
||||
*/
|
||||
public function whereNotNull($column)
|
||||
{
|
||||
return $this->where($column, 'NOT_NULL');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a "where in" constraint on the query.
|
||||
*
|
||||
* @param string $column
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|\BackedEnum|array $values
|
||||
* @return $this
|
||||
*/
|
||||
public function whereIn($column, $values)
|
||||
{
|
||||
return $this->where(function ($query) use ($column, $values) {
|
||||
$query->whereIn($column, $values);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a "where not in" constraint on the query.
|
||||
*
|
||||
* @param string $column
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|\BackedEnum|array $values
|
||||
* @return $this
|
||||
*/
|
||||
public function whereNotIn($column, $values)
|
||||
{
|
||||
return $this->where(function ($query) use ($column, $values) {
|
||||
$query->whereNotIn($column, $values);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignore soft deleted models during the existence check.
|
||||
*
|
||||
* @param string $deletedAtColumn
|
||||
* @return $this
|
||||
*/
|
||||
public function withoutTrashed($deletedAtColumn = 'deleted_at')
|
||||
{
|
||||
$this->whereNull($deletedAtColumn);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only include soft deleted models during the existence check.
|
||||
*
|
||||
* @param string $deletedAtColumn
|
||||
* @return $this
|
||||
*/
|
||||
public function onlyTrashed($deletedAtColumn = 'deleted_at')
|
||||
{
|
||||
$this->whereNotNull($deletedAtColumn);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a custom query callback.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function using(Closure $callback)
|
||||
{
|
||||
$this->using[] = $callback;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the custom query callbacks for the rule.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function queryCallbacks()
|
||||
{
|
||||
return $this->using;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the where clauses.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function formatWheres()
|
||||
{
|
||||
return (new Collection($this->wheres))
|
||||
->map(fn ($where) => $where['column'].','.'"'.str_replace('"', '""', $where['value']).'"')
|
||||
->implode(',');
|
||||
}
|
||||
}
|
||||
+177
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Traits\Conditionable;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use Stringable;
|
||||
|
||||
class Date implements Stringable
|
||||
{
|
||||
use Conditionable, Macroable;
|
||||
|
||||
/**
|
||||
* The format of the date.
|
||||
*/
|
||||
protected ?string $format = null;
|
||||
|
||||
/**
|
||||
* The constraints for the date rule.
|
||||
*/
|
||||
protected array $constraints = [];
|
||||
|
||||
/**
|
||||
* Ensure the date has the given format.
|
||||
*/
|
||||
public function format(string $format): static
|
||||
{
|
||||
$this->format = $format;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the date is before today.
|
||||
*/
|
||||
public function beforeToday(): static
|
||||
{
|
||||
return $this->before('today');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the date is after today.
|
||||
*/
|
||||
public function afterToday(): static
|
||||
{
|
||||
return $this->after('today');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the date is before or equal to today.
|
||||
*/
|
||||
public function todayOrBefore(): static
|
||||
{
|
||||
return $this->beforeOrEqual('today');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the date is after or equal to today.
|
||||
*/
|
||||
public function todayOrAfter(): static
|
||||
{
|
||||
return $this->afterOrEqual('today');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the date is in the past.
|
||||
*/
|
||||
public function past(): static
|
||||
{
|
||||
return $this->before('now');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the date is in the future.
|
||||
*/
|
||||
public function future(): static
|
||||
{
|
||||
return $this->after('now');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the date is now or in the past.
|
||||
*/
|
||||
public function nowOrPast(): static
|
||||
{
|
||||
return $this->beforeOrEqual('now');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the date is now or in the future.
|
||||
*/
|
||||
public function nowOrFuture(): static
|
||||
{
|
||||
return $this->afterOrEqual('now');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the date is before the given date or date field.
|
||||
*/
|
||||
public function before(DateTimeInterface|string $date): static
|
||||
{
|
||||
return $this->addRule('before:'.$this->formatDate($date));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the date is after the given date or date field.
|
||||
*/
|
||||
public function after(DateTimeInterface|string $date): static
|
||||
{
|
||||
return $this->addRule('after:'.$this->formatDate($date));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the date is on or before the specified date or date field.
|
||||
*/
|
||||
public function beforeOrEqual(DateTimeInterface|string $date): static
|
||||
{
|
||||
return $this->addRule('before_or_equal:'.$this->formatDate($date));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the date is on or after the given date or date field.
|
||||
*/
|
||||
public function afterOrEqual(DateTimeInterface|string $date): static
|
||||
{
|
||||
return $this->addRule('after_or_equal:'.$this->formatDate($date));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the date is between two dates or date fields.
|
||||
*/
|
||||
public function between(DateTimeInterface|string $from, DateTimeInterface|string $to): static
|
||||
{
|
||||
return $this->after($from)->before($to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the date is between or equal to two dates or date fields.
|
||||
*/
|
||||
public function betweenOrEqual(DateTimeInterface|string $from, DateTimeInterface|string $to): static
|
||||
{
|
||||
return $this->afterOrEqual($from)->beforeOrEqual($to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom rules to the validation rules array.
|
||||
*/
|
||||
protected function addRule(array|string $rules): static
|
||||
{
|
||||
$this->constraints = array_merge($this->constraints, Arr::wrap($rules));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the date for the validation rule.
|
||||
*/
|
||||
protected function formatDate(DateTimeInterface|string $date): string
|
||||
{
|
||||
return $date instanceof DateTimeInterface
|
||||
? $date->format($this->format ?? 'Y-m-d')
|
||||
: $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the rule to a validation string.
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return implode('|', [
|
||||
$this->format === null ? 'date' : 'date_format:'.$this->format,
|
||||
...$this->constraints,
|
||||
]);
|
||||
}
|
||||
}
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Illuminate\Support\Traits\Conditionable;
|
||||
use Stringable;
|
||||
|
||||
class Dimensions implements Stringable
|
||||
{
|
||||
use Conditionable;
|
||||
|
||||
/**
|
||||
* The constraints for the dimensions rule.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $constraints = [];
|
||||
|
||||
/**
|
||||
* Create a new dimensions rule instance.
|
||||
*
|
||||
* @param array $constraints
|
||||
*/
|
||||
public function __construct(array $constraints = [])
|
||||
{
|
||||
$this->constraints = $constraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the "width" constraint.
|
||||
*
|
||||
* @param int $value
|
||||
* @return $this
|
||||
*/
|
||||
public function width($value)
|
||||
{
|
||||
$this->constraints['width'] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the "height" constraint.
|
||||
*
|
||||
* @param int $value
|
||||
* @return $this
|
||||
*/
|
||||
public function height($value)
|
||||
{
|
||||
$this->constraints['height'] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the "min width" constraint.
|
||||
*
|
||||
* @param int $value
|
||||
* @return $this
|
||||
*/
|
||||
public function minWidth($value)
|
||||
{
|
||||
$this->constraints['min_width'] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the "min height" constraint.
|
||||
*
|
||||
* @param int $value
|
||||
* @return $this
|
||||
*/
|
||||
public function minHeight($value)
|
||||
{
|
||||
$this->constraints['min_height'] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the "max width" constraint.
|
||||
*
|
||||
* @param int $value
|
||||
* @return $this
|
||||
*/
|
||||
public function maxWidth($value)
|
||||
{
|
||||
$this->constraints['max_width'] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the "max height" constraint.
|
||||
*
|
||||
* @param int $value
|
||||
* @return $this
|
||||
*/
|
||||
public function maxHeight($value)
|
||||
{
|
||||
$this->constraints['max_height'] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the "ratio" constraint.
|
||||
*
|
||||
* @param float $value
|
||||
* @return $this
|
||||
*/
|
||||
public function ratio($value)
|
||||
{
|
||||
$this->constraints['ratio'] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the minimum aspect ratio.
|
||||
*
|
||||
* @param float $value
|
||||
* @return $this
|
||||
*/
|
||||
public function minRatio($value)
|
||||
{
|
||||
$this->constraints['min_ratio'] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum aspect ratio.
|
||||
*
|
||||
* @param float $value
|
||||
* @return $this
|
||||
*/
|
||||
public function maxRatio($value)
|
||||
{
|
||||
$this->constraints['max_ratio'] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the aspect ratio range.
|
||||
*
|
||||
* @param float $min
|
||||
* @param float $max
|
||||
* @return $this
|
||||
*/
|
||||
public function ratioBetween($min, $max)
|
||||
{
|
||||
$this->constraints['min_ratio'] = $min;
|
||||
$this->constraints['max_ratio'] = $max;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the rule to a validation string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$result = '';
|
||||
|
||||
foreach ($this->constraints as $key => $value) {
|
||||
$result .= "$key=$value,";
|
||||
}
|
||||
|
||||
return 'dimensions:'.substr($result, 0, -1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Stringable;
|
||||
|
||||
use function Illuminate\Support\enum_value;
|
||||
|
||||
class DoesntContain implements Stringable
|
||||
{
|
||||
/**
|
||||
* The values that should not be contained in the attribute.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $values;
|
||||
|
||||
/**
|
||||
* Create a new doesntContain rule instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|\UnitEnum|array|string $values
|
||||
*/
|
||||
public function __construct($values)
|
||||
{
|
||||
if ($values instanceof Arrayable) {
|
||||
$values = $values->toArray();
|
||||
}
|
||||
|
||||
$this->values = is_array($values) ? $values : func_get_args();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the rule to a validation string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$values = array_map(function ($value) {
|
||||
$value = enum_value($value);
|
||||
|
||||
return '"'.str_replace('"', '""', (string) $value).'"';
|
||||
}, $this->values);
|
||||
|
||||
return 'doesnt_contain:'.implode(',', $values);
|
||||
}
|
||||
}
|
||||
+286
@@ -0,0 +1,286 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Illuminate\Contracts\Validation\DataAwareRule;
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
use Illuminate\Contracts\Validation\ValidatorAwareRule;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Traits\Conditionable;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class Email implements Rule, DataAwareRule, ValidatorAwareRule
|
||||
{
|
||||
use Conditionable, Macroable;
|
||||
|
||||
public bool $validateMxRecord = false;
|
||||
public bool $preventSpoofing = false;
|
||||
public bool $nativeValidation = false;
|
||||
public bool $nativeValidationWithUnicodeAllowed = false;
|
||||
public bool $rfcCompliant = false;
|
||||
public bool $strictRfcCompliant = false;
|
||||
|
||||
/**
|
||||
* The validator performing the validation.
|
||||
*
|
||||
* @var \Illuminate\Validation\Validator
|
||||
*/
|
||||
protected $validator;
|
||||
|
||||
/**
|
||||
* The data under validation.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* An array of custom rules that will be merged into the validation rules.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $customRules = [];
|
||||
|
||||
/**
|
||||
* The error message after validation, if any.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $messages = [];
|
||||
|
||||
/**
|
||||
* The callback that will generate the "default" version of the email rule.
|
||||
*
|
||||
* @var string|array|callable|null
|
||||
*/
|
||||
public static $defaultCallback;
|
||||
|
||||
/**
|
||||
* Set the default callback to be used for determining the email default rules.
|
||||
*
|
||||
* If no arguments are passed, the default email rule configuration will be returned.
|
||||
*
|
||||
* @param static|callable|null $callback
|
||||
* @return static|void
|
||||
*
|
||||
* @phpstan-return ($callback is null ? static : ($callback is callable ? void : ($callback is static ? void : never)))
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function defaults($callback = null)
|
||||
{
|
||||
if (is_null($callback)) {
|
||||
return static::default();
|
||||
}
|
||||
|
||||
if (! is_callable($callback) && ! $callback instanceof static) {
|
||||
throw new InvalidArgumentException('The given callback should be callable or an instance of '.static::class);
|
||||
}
|
||||
|
||||
static::$defaultCallback = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default configuration of the email rule.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function default()
|
||||
{
|
||||
$email = is_callable(static::$defaultCallback)
|
||||
? call_user_func(static::$defaultCallback)
|
||||
: static::$defaultCallback;
|
||||
|
||||
return $email instanceof static ? $email : new static;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that the email is an RFC compliant email address.
|
||||
*
|
||||
* @param bool $strict
|
||||
* @return $this
|
||||
*/
|
||||
public function rfcCompliant(bool $strict = false)
|
||||
{
|
||||
if ($strict) {
|
||||
$this->strictRfcCompliant = true;
|
||||
} else {
|
||||
$this->rfcCompliant = true;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that the email is a strictly enforced RFC compliant email address.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function strict()
|
||||
{
|
||||
return $this->rfcCompliant(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that the email address has a valid MX record.
|
||||
*
|
||||
* Requires the PHP intl extension.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function validateMxRecord()
|
||||
{
|
||||
$this->validateMxRecord = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that the email address is not attempting to spoof another email address using invalid unicode characters.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function preventSpoofing()
|
||||
{
|
||||
$this->preventSpoofing = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the email address is valid using PHP's native email validation functions.
|
||||
*
|
||||
* @param bool $allowUnicode
|
||||
* @return $this
|
||||
*/
|
||||
public function withNativeValidation(bool $allowUnicode = false)
|
||||
{
|
||||
if ($allowUnicode) {
|
||||
$this->nativeValidationWithUnicodeAllowed = true;
|
||||
} else {
|
||||
$this->nativeValidation = true;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify additional validation rules that should be merged with the default rules during validation.
|
||||
*
|
||||
* @param string|array $rules
|
||||
* @return $this
|
||||
*/
|
||||
public function rules($rules)
|
||||
{
|
||||
$this->customRules = array_merge($this->customRules, Arr::wrap($rules));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the validation rule passes.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
$this->messages = [];
|
||||
|
||||
$validator = Validator::make(
|
||||
$this->data,
|
||||
[$attribute => $this->buildValidationRules()],
|
||||
$this->validator->customMessages,
|
||||
$this->validator->customAttributes
|
||||
);
|
||||
|
||||
if ($validator->fails()) {
|
||||
$this->messages = array_merge($this->messages, $validator->messages()->all());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the array of underlying validation rules based on the current state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function buildValidationRules()
|
||||
{
|
||||
$rules = [];
|
||||
|
||||
if ($this->rfcCompliant) {
|
||||
$rules[] = 'rfc';
|
||||
}
|
||||
|
||||
if ($this->strictRfcCompliant) {
|
||||
$rules[] = 'strict';
|
||||
}
|
||||
|
||||
if ($this->validateMxRecord) {
|
||||
$rules[] = 'dns';
|
||||
}
|
||||
|
||||
if ($this->preventSpoofing) {
|
||||
$rules[] = 'spoof';
|
||||
}
|
||||
|
||||
if ($this->nativeValidation) {
|
||||
$rules[] = 'filter';
|
||||
}
|
||||
|
||||
if ($this->nativeValidationWithUnicodeAllowed) {
|
||||
$rules[] = 'filter_unicode';
|
||||
}
|
||||
|
||||
if ($rules) {
|
||||
$rules = ['email:'.implode(',', $rules)];
|
||||
} else {
|
||||
$rules = ['email'];
|
||||
}
|
||||
|
||||
return array_merge(array_filter($rules), $this->customRules);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation error message.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current validator.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Validation\Validator $validator
|
||||
* @return $this
|
||||
*/
|
||||
public function setValidator($validator)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current data under validation.
|
||||
*
|
||||
* @param array $data
|
||||
* @return $this
|
||||
*/
|
||||
public function setData($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
use Illuminate\Contracts\Validation\ValidatorAwareRule;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Traits\Conditionable;
|
||||
use Stringable;
|
||||
use TypeError;
|
||||
|
||||
use function Illuminate\Support\enum_value;
|
||||
|
||||
class Enum implements Rule, ValidatorAwareRule, Stringable
|
||||
{
|
||||
use Conditionable;
|
||||
|
||||
/**
|
||||
* The type of the enum.
|
||||
*
|
||||
* @var class-string<\UnitEnum>
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* The current validator instance.
|
||||
*
|
||||
* @var \Illuminate\Validation\Validator
|
||||
*/
|
||||
protected $validator;
|
||||
|
||||
/**
|
||||
* The cases that should be considered valid.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $only = [];
|
||||
|
||||
/**
|
||||
* The cases that should be considered invalid.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [];
|
||||
|
||||
/**
|
||||
* Create a new rule instance.
|
||||
*
|
||||
* @param class-string<\UnitEnum> $type
|
||||
*/
|
||||
public function __construct($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the validation rule passes.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
if ($value instanceof $this->type) {
|
||||
return $this->isDesirable($value);
|
||||
}
|
||||
|
||||
if (is_null($value) || ! enum_exists($this->type) || ! method_exists($this->type, 'tryFrom')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$value = $this->type::tryFrom($value);
|
||||
|
||||
return ! is_null($value) && $this->isDesirable($value);
|
||||
} catch (TypeError) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the cases that should be considered valid.
|
||||
*
|
||||
* @param \UnitEnum[]|\UnitEnum|\Illuminate\Contracts\Support\Arrayable<array-key, \UnitEnum> $values
|
||||
* @return $this
|
||||
*/
|
||||
public function only($values)
|
||||
{
|
||||
$this->only = $values instanceof Arrayable ? $values->toArray() : Arr::wrap($values);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the cases that should be considered invalid.
|
||||
*
|
||||
* @param \UnitEnum[]|\UnitEnum|\Illuminate\Contracts\Support\Arrayable<array-key, \UnitEnum> $values
|
||||
* @return $this
|
||||
*/
|
||||
public function except($values)
|
||||
{
|
||||
$this->except = $values instanceof Arrayable ? $values->toArray() : Arr::wrap($values);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given case is a valid case based on the only / except values.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function isDesirable($value)
|
||||
{
|
||||
return match (true) {
|
||||
! empty($this->only) => in_array(needle: $value, haystack: $this->only, strict: true),
|
||||
! empty($this->except) => ! in_array(needle: $value, haystack: $this->except, strict: true),
|
||||
default => true,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation error message.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
$message = $this->validator->getTranslator()->get('validation.enum');
|
||||
|
||||
return $message === 'validation.enum'
|
||||
? ['The selected :attribute is invalid.']
|
||||
: $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current validator.
|
||||
*
|
||||
* @param \Illuminate\Validation\Validator $validator
|
||||
* @return $this
|
||||
*/
|
||||
public function setValidator($validator)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the rule to a validation string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$cases = ! empty($this->only)
|
||||
? $this->only
|
||||
: array_filter($this->type::cases(), fn ($case) => ! in_array($case, $this->except, true));
|
||||
|
||||
$values = array_map(function ($case) {
|
||||
$value = enum_value($case);
|
||||
|
||||
return '"'.str_replace('"', '""', (string) $value).'"';
|
||||
}, $cases);
|
||||
|
||||
return 'in:'.implode(',', $values);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Closure;
|
||||
use InvalidArgumentException;
|
||||
use Stringable;
|
||||
|
||||
class ExcludeIf implements Stringable
|
||||
{
|
||||
/**
|
||||
* The condition that validates the attribute.
|
||||
*
|
||||
* @var (\Closure(): bool)|bool
|
||||
*/
|
||||
public $condition;
|
||||
|
||||
/**
|
||||
* Create a new exclude validation rule based on a condition.
|
||||
*
|
||||
* @param (\Closure(): bool)|bool $condition
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct($condition)
|
||||
{
|
||||
if ($condition instanceof Closure || is_bool($condition)) {
|
||||
$this->condition = $condition;
|
||||
} else {
|
||||
throw new InvalidArgumentException('The provided condition must be a callable or boolean.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the rule to a validation string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
if (is_callable($this->condition)) {
|
||||
return call_user_func($this->condition) ? 'exclude' : '';
|
||||
}
|
||||
|
||||
return $this->condition ? 'exclude' : '';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Closure;
|
||||
use InvalidArgumentException;
|
||||
use Stringable;
|
||||
|
||||
class ExcludeUnless implements Stringable
|
||||
{
|
||||
/**
|
||||
* The condition that validates the attribute.
|
||||
*
|
||||
* @var (\Closure(): bool)|bool
|
||||
*/
|
||||
public $condition;
|
||||
|
||||
/**
|
||||
* Create a new exclude validation rule based on a condition.
|
||||
*
|
||||
* @param (\Closure(): bool)|bool $condition
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct($condition)
|
||||
{
|
||||
if ($condition instanceof Closure || is_bool($condition)) {
|
||||
$this->condition = $condition;
|
||||
} else {
|
||||
throw new InvalidArgumentException('The provided condition must be a callable or boolean.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the rule to a validation string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
if (is_callable($this->condition)) {
|
||||
return call_user_func($this->condition) ? '' : 'exclude';
|
||||
}
|
||||
|
||||
return $this->condition ? '' : 'exclude';
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Illuminate\Support\Traits\Conditionable;
|
||||
use Stringable;
|
||||
|
||||
class Exists implements Stringable
|
||||
{
|
||||
use Conditionable, DatabaseRule;
|
||||
|
||||
/**
|
||||
* Convert the rule to a validation string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return rtrim(sprintf('exists:%s,%s,%s',
|
||||
$this->table,
|
||||
$this->column,
|
||||
$this->formatWheres()
|
||||
), ',');
|
||||
}
|
||||
}
|
||||
+403
@@ -0,0 +1,403 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Illuminate\Contracts\Validation\DataAwareRule;
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
use Illuminate\Contracts\Validation\ValidatorAwareRule;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Traits\Conditionable;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class File implements Rule, DataAwareRule, ValidatorAwareRule
|
||||
{
|
||||
use Conditionable, Macroable;
|
||||
|
||||
/**
|
||||
* The MIME types that the given file should match. This array may also contain file extensions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $allowedMimetypes = [];
|
||||
|
||||
/**
|
||||
* The extensions that the given file should match.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $allowedExtensions = [];
|
||||
|
||||
/**
|
||||
* The minimum size in kilobytes that the file can be.
|
||||
*
|
||||
* @var null|int
|
||||
*/
|
||||
protected $minimumFileSize = null;
|
||||
|
||||
/**
|
||||
* The maximum size in kilobytes that the file can be.
|
||||
*
|
||||
* @var null|int
|
||||
*/
|
||||
protected $maximumFileSize = null;
|
||||
|
||||
/**
|
||||
* The required file encoding.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $encoding = null;
|
||||
|
||||
/**
|
||||
* An array of custom rules that will be merged into the validation rules.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $customRules = [];
|
||||
|
||||
/**
|
||||
* The error message after validation, if any.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $messages = [];
|
||||
|
||||
/**
|
||||
* The data under validation.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* The validator performing the validation.
|
||||
*
|
||||
* @var \Illuminate\Validation\Validator
|
||||
*/
|
||||
protected $validator;
|
||||
|
||||
/**
|
||||
* The callback that will generate the "default" version of the file rule.
|
||||
*
|
||||
* @var string|array|callable|null
|
||||
*/
|
||||
public static $defaultCallback;
|
||||
|
||||
/**
|
||||
* Set the default callback to be used for determining the file default rules.
|
||||
*
|
||||
* If no arguments are passed, the default file rule configuration will be returned.
|
||||
*
|
||||
* @param static|callable|null $callback
|
||||
* @return static|void
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function defaults($callback = null)
|
||||
{
|
||||
if (is_null($callback)) {
|
||||
return static::default();
|
||||
}
|
||||
|
||||
if (! is_callable($callback) && ! $callback instanceof static) {
|
||||
throw new InvalidArgumentException('The given callback should be callable or an instance of '.static::class);
|
||||
}
|
||||
|
||||
static::$defaultCallback = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default configuration of the file rule.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function default()
|
||||
{
|
||||
$file = is_callable(static::$defaultCallback)
|
||||
? call_user_func(static::$defaultCallback)
|
||||
: static::$defaultCallback;
|
||||
|
||||
return $file instanceof Rule ? $file : new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit the uploaded file to only image types.
|
||||
*
|
||||
* @param bool $allowSvg
|
||||
* @return ImageFile
|
||||
*/
|
||||
public static function image($allowSvg = false)
|
||||
{
|
||||
return new ImageFile($allowSvg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit the uploaded file to the given MIME types or file extensions.
|
||||
*
|
||||
* @param string|array<int, string> $mimetypes
|
||||
* @return static
|
||||
*/
|
||||
public static function types($mimetypes)
|
||||
{
|
||||
return tap(new static(), fn ($file) => $file->allowedMimetypes = (array) $mimetypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit the uploaded file to the given file extensions.
|
||||
*
|
||||
* @param string|array<int, string> $extensions
|
||||
* @return $this
|
||||
*/
|
||||
public function extensions($extensions)
|
||||
{
|
||||
$this->allowedExtensions = (array) $extensions;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the uploaded file should be exactly a certain size in kilobytes.
|
||||
*
|
||||
* @param string|int $size
|
||||
* @return $this
|
||||
*/
|
||||
public function size($size)
|
||||
{
|
||||
$this->minimumFileSize = $this->toKilobytes($size);
|
||||
$this->maximumFileSize = $this->minimumFileSize;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the uploaded file should be between a minimum and maximum size in kilobytes.
|
||||
*
|
||||
* @param string|int $minSize
|
||||
* @param string|int $maxSize
|
||||
* @return $this
|
||||
*/
|
||||
public function between($minSize, $maxSize)
|
||||
{
|
||||
$this->minimumFileSize = $this->toKilobytes($minSize);
|
||||
$this->maximumFileSize = $this->toKilobytes($maxSize);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the uploaded file should be no less than the given number of kilobytes.
|
||||
*
|
||||
* @param string|int $size
|
||||
* @return $this
|
||||
*/
|
||||
public function min($size)
|
||||
{
|
||||
$this->minimumFileSize = $this->toKilobytes($size);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the uploaded file should be no more than the given number of kilobytes.
|
||||
*
|
||||
* @param string|int $size
|
||||
* @return $this
|
||||
*/
|
||||
public function max($size)
|
||||
{
|
||||
$this->maximumFileSize = $this->toKilobytes($size);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the uploaded file should be in the given encoding.
|
||||
*
|
||||
* @param string $encoding
|
||||
* @return $this
|
||||
*/
|
||||
public function encoding($encoding)
|
||||
{
|
||||
$this->encoding = $encoding;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a potentially human-friendly file size to kilobytes.
|
||||
*
|
||||
* @param string|int $size
|
||||
* @return ($size is int ? int : int|float)
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function toKilobytes($size)
|
||||
{
|
||||
if (! is_string($size)) {
|
||||
return $size;
|
||||
}
|
||||
|
||||
$size = strtolower(trim($size));
|
||||
|
||||
$value = (float) $size;
|
||||
|
||||
return round(match (true) {
|
||||
Str::endsWith($size, 'kb') => $value * 1,
|
||||
Str::endsWith($size, 'mb') => $value * 1_000,
|
||||
Str::endsWith($size, 'gb') => $value * 1_000_000,
|
||||
Str::endsWith($size, 'tb') => $value * 1_000_000_000,
|
||||
default => throw new InvalidArgumentException('Invalid file size suffix.'),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify additional validation rules that should be merged with the default rules during validation.
|
||||
*
|
||||
* @param string|array $rules
|
||||
* @return $this
|
||||
*/
|
||||
public function rules($rules)
|
||||
{
|
||||
$this->customRules = array_merge($this->customRules, Arr::wrap($rules));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the validation rule passes.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
$this->messages = [];
|
||||
|
||||
$validator = Validator::make(
|
||||
$this->data,
|
||||
[$attribute => $this->buildValidationRules()],
|
||||
$this->validator->customMessages,
|
||||
$this->validator->customAttributes
|
||||
);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return $this->fail($validator->messages()->all());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the array of underlying validation rules based on the current state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function buildValidationRules()
|
||||
{
|
||||
$rules = ['file'];
|
||||
|
||||
$rules = array_merge($rules, $this->buildMimetypes());
|
||||
|
||||
if (! empty($this->allowedExtensions)) {
|
||||
$rules[] = 'extensions:'.implode(',', array_map(strtolower(...), $this->allowedExtensions));
|
||||
}
|
||||
|
||||
$rules[] = match (true) {
|
||||
is_null($this->minimumFileSize) && is_null($this->maximumFileSize) => null,
|
||||
is_null($this->maximumFileSize) => "min:{$this->minimumFileSize}",
|
||||
is_null($this->minimumFileSize) => "max:{$this->maximumFileSize}",
|
||||
$this->minimumFileSize !== $this->maximumFileSize => "between:{$this->minimumFileSize},{$this->maximumFileSize}",
|
||||
default => "size:{$this->minimumFileSize}",
|
||||
};
|
||||
|
||||
if ($this->encoding) {
|
||||
$rules[] = 'encoding:'.$this->encoding;
|
||||
}
|
||||
|
||||
return array_merge(array_filter($rules), $this->customRules);
|
||||
}
|
||||
|
||||
/**
|
||||
* Separate the given MIME types from extensions and return an array of correct rules to validate against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function buildMimetypes()
|
||||
{
|
||||
if (count($this->allowedMimetypes) === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$rules = [];
|
||||
|
||||
$mimetypes = array_filter(
|
||||
$this->allowedMimetypes,
|
||||
fn ($type) => str_contains($type, '/')
|
||||
);
|
||||
|
||||
$mimes = array_diff($this->allowedMimetypes, $mimetypes);
|
||||
|
||||
if ($mimetypes !== []) {
|
||||
$rules[] = 'mimetypes:'.implode(',', $mimetypes);
|
||||
}
|
||||
|
||||
if ($mimes !== []) {
|
||||
$rules[] = 'mimes:'.implode(',', $mimes);
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given failures, and return false.
|
||||
*
|
||||
* @param array|string $messages
|
||||
* @return bool
|
||||
*/
|
||||
protected function fail($messages)
|
||||
{
|
||||
$this->messages = array_merge($this->messages, Arr::wrap($messages));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation error message.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current validator.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Validation\Validator $validator
|
||||
* @return $this
|
||||
*/
|
||||
public function setValidator($validator)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current data under validation.
|
||||
*
|
||||
* @param array $data
|
||||
* @return $this
|
||||
*/
|
||||
public function setData($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
class ImageFile extends File
|
||||
{
|
||||
/**
|
||||
* Create a new image file rule instance.
|
||||
*
|
||||
* @param bool $allowSvg
|
||||
*/
|
||||
public function __construct($allowSvg = false)
|
||||
{
|
||||
if ($allowSvg) {
|
||||
$this->rules('image:allow_svg');
|
||||
} else {
|
||||
$this->rules('image');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The dimension constraints for the uploaded file.
|
||||
*
|
||||
* @param \Illuminate\Validation\Rules\Dimensions $dimensions
|
||||
* @return $this
|
||||
*/
|
||||
public function dimensions($dimensions)
|
||||
{
|
||||
$this->rules($dimensions);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Stringable;
|
||||
|
||||
use function Illuminate\Support\enum_value;
|
||||
|
||||
class In implements Stringable
|
||||
{
|
||||
/**
|
||||
* The name of the rule.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $rule = 'in';
|
||||
|
||||
/**
|
||||
* The accepted values.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $values;
|
||||
|
||||
/**
|
||||
* Create a new in rule instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|\UnitEnum|array|string $values
|
||||
*/
|
||||
public function __construct($values)
|
||||
{
|
||||
if ($values instanceof Arrayable) {
|
||||
$values = $values->toArray();
|
||||
}
|
||||
|
||||
$this->values = is_array($values) ? $values : func_get_args();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the rule to a validation string.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @see \Illuminate\Validation\ValidationRuleParser::parseParameters
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$values = array_map(function ($value) {
|
||||
$value = enum_value($value);
|
||||
|
||||
return '"'.str_replace('"', '""', (string) $value).'"';
|
||||
}, $this->values);
|
||||
|
||||
return $this->rule.':'.implode(',', $values);
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Stringable;
|
||||
|
||||
use function Illuminate\Support\enum_value;
|
||||
|
||||
class NotIn implements Stringable
|
||||
{
|
||||
/**
|
||||
* The name of the rule.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $rule = 'not_in';
|
||||
|
||||
/**
|
||||
* The accepted values.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $values;
|
||||
|
||||
/**
|
||||
* Create a new "not in" rule instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|\UnitEnum|array|string $values
|
||||
*/
|
||||
public function __construct($values)
|
||||
{
|
||||
if ($values instanceof Arrayable) {
|
||||
$values = $values->toArray();
|
||||
}
|
||||
|
||||
$this->values = is_array($values) ? $values : func_get_args();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the rule to a validation string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$values = array_map(function ($value) {
|
||||
$value = enum_value($value);
|
||||
|
||||
return '"'.str_replace('"', '""', (string) $value).'"';
|
||||
}, $this->values);
|
||||
|
||||
return $this->rule.':'.implode(',', $values);
|
||||
}
|
||||
}
|
||||
+230
@@ -0,0 +1,230 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Traits\Conditionable;
|
||||
use Stringable;
|
||||
|
||||
class Numeric implements Stringable
|
||||
{
|
||||
use Conditionable;
|
||||
|
||||
/**
|
||||
* The constraints for the number rule.
|
||||
*/
|
||||
protected array $constraints = ['numeric'];
|
||||
|
||||
/**
|
||||
* The field under validation must have a size between the given min and max (inclusive).
|
||||
*
|
||||
* @param int|float $min
|
||||
* @param int|float $max
|
||||
* @return $this
|
||||
*/
|
||||
public function between(int|float $min, int|float $max): Numeric
|
||||
{
|
||||
return $this->addRule('between:'.$min.','.$max);
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must contain the specified number of decimal places.
|
||||
*
|
||||
* @param int $min
|
||||
* @param int|null $max
|
||||
* @return $this
|
||||
*/
|
||||
public function decimal(int $min, ?int $max = null): Numeric
|
||||
{
|
||||
$rule = 'decimal:'.$min;
|
||||
|
||||
if ($max !== null) {
|
||||
$rule .= ','.$max;
|
||||
}
|
||||
|
||||
return $this->addRule($rule);
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must have a different value than field.
|
||||
*
|
||||
* @param string $field
|
||||
* @return $this
|
||||
*/
|
||||
public function different(string $field): Numeric
|
||||
{
|
||||
return $this->addRule('different:'.$field);
|
||||
}
|
||||
|
||||
/**
|
||||
* The integer under validation must have an exact number of digits.
|
||||
*
|
||||
* @param int $length
|
||||
* @return $this
|
||||
*/
|
||||
public function digits(int $length): Numeric
|
||||
{
|
||||
return $this->integer()->addRule('digits:'.$length);
|
||||
}
|
||||
|
||||
/**
|
||||
* The integer under validation must between the given min and max number of digits.
|
||||
*
|
||||
* @param int $min
|
||||
* @param int $max
|
||||
* @return $this
|
||||
*/
|
||||
public function digitsBetween(int $min, int $max): Numeric
|
||||
{
|
||||
return $this->integer()->addRule('digits_between:'.$min.','.$max);
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must be greater than the given field or value.
|
||||
*
|
||||
* @param string $field
|
||||
* @return $this
|
||||
*/
|
||||
public function greaterThan(string $field): Numeric
|
||||
{
|
||||
return $this->addRule('gt:'.$field);
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must be greater than or equal to the given field or value.
|
||||
*
|
||||
* @param string $field
|
||||
* @return $this
|
||||
*/
|
||||
public function greaterThanOrEqualTo(string $field): Numeric
|
||||
{
|
||||
return $this->addRule('gte:'.$field);
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must be an integer.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function integer(bool $strict = false): Numeric
|
||||
{
|
||||
return $this->addRule($strict ? 'integer:strict' : 'integer');
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must be less than the given field.
|
||||
*
|
||||
* @param string $field
|
||||
* @return $this
|
||||
*/
|
||||
public function lessThan(string $field): Numeric
|
||||
{
|
||||
return $this->addRule('lt:'.$field);
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must be less than or equal to the given field.
|
||||
*
|
||||
* @param string $field
|
||||
* @return $this
|
||||
*/
|
||||
public function lessThanOrEqualTo(string $field): Numeric
|
||||
{
|
||||
return $this->addRule('lte:'.$field);
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must be less than or equal to a maximum value.
|
||||
*
|
||||
* @param int|float $value
|
||||
* @return $this
|
||||
*/
|
||||
public function max(int|float $value): Numeric
|
||||
{
|
||||
return $this->addRule('max:'.$value);
|
||||
}
|
||||
|
||||
/**
|
||||
* The integer under validation must have a maximum number of digits.
|
||||
*
|
||||
* @param int $value
|
||||
* @return $this
|
||||
*/
|
||||
public function maxDigits(int $value): Numeric
|
||||
{
|
||||
return $this->addRule('max_digits:'.$value);
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must have a minimum value.
|
||||
*
|
||||
* @param int|float $value
|
||||
* @return $this
|
||||
*/
|
||||
public function min(int|float $value): Numeric
|
||||
{
|
||||
return $this->addRule('min:'.$value);
|
||||
}
|
||||
|
||||
/**
|
||||
* The integer under validation must have a minimum number of digits.
|
||||
*
|
||||
* @param int $value
|
||||
* @return $this
|
||||
*/
|
||||
public function minDigits(int $value): Numeric
|
||||
{
|
||||
return $this->addRule('min_digits:'.$value);
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must be a multiple of the given value.
|
||||
*
|
||||
* @param int|float $value
|
||||
* @return $this
|
||||
*/
|
||||
public function multipleOf(int|float $value): Numeric
|
||||
{
|
||||
return $this->addRule('multiple_of:'.$value);
|
||||
}
|
||||
|
||||
/**
|
||||
* The given field must match the field under validation.
|
||||
*
|
||||
* @param string $field
|
||||
* @return $this
|
||||
*/
|
||||
public function same(string $field): Numeric
|
||||
{
|
||||
return $this->addRule('same:'.$field);
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must match the given value.
|
||||
*
|
||||
* @param int $value
|
||||
* @return $this
|
||||
*/
|
||||
public function exactly(int $value): Numeric
|
||||
{
|
||||
return $this->integer()->addRule('size:'.$value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the rule to a validation string.
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return implode('|', array_unique($this->constraints));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom rules to the validation rules array.
|
||||
*/
|
||||
protected function addRule(array|string $rules): Numeric
|
||||
{
|
||||
$this->constraints = array_merge($this->constraints, Arr::wrap($rules));
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
+450
@@ -0,0 +1,450 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use ArrayIterator;
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Contracts\Validation\DataAwareRule;
|
||||
use Illuminate\Contracts\Validation\ImplicitRule;
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
use Illuminate\Contracts\Validation\UncompromisedVerifier;
|
||||
use Illuminate\Contracts\Validation\ValidatorAwareRule;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Traits\Conditionable;
|
||||
use InvalidArgumentException;
|
||||
use IteratorAggregate;
|
||||
use Traversable;
|
||||
|
||||
class Password implements DataAwareRule, ImplicitRule, IteratorAggregate, Rule, ValidatorAwareRule
|
||||
{
|
||||
use Conditionable;
|
||||
|
||||
/**
|
||||
* The validator performing the validation.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Validation\Validator
|
||||
*/
|
||||
protected $validator;
|
||||
|
||||
/**
|
||||
* The data under validation.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* The minimum size of the password.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $min = 8;
|
||||
|
||||
/**
|
||||
* The maximum size of the password.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $max;
|
||||
|
||||
/**
|
||||
* If the password is required.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $required = false;
|
||||
|
||||
/**
|
||||
* If the password should only be validated when present.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $sometimes = false;
|
||||
|
||||
/**
|
||||
* If the password requires at least one uppercase and one lowercase letter.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $mixedCase = false;
|
||||
|
||||
/**
|
||||
* If the password requires at least one letter.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $letters = false;
|
||||
|
||||
/**
|
||||
* If the password requires at least one number.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $numbers = false;
|
||||
|
||||
/**
|
||||
* If the password requires at least one symbol.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $symbols = false;
|
||||
|
||||
/**
|
||||
* If the password should not have been compromised in data leaks.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $uncompromised = false;
|
||||
|
||||
/**
|
||||
* The number of times a password can appear in data leaks before being considered compromised.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $compromisedThreshold = 0;
|
||||
|
||||
/**
|
||||
* Additional validation rules that should be merged into the default rules during validation.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $customRules = [];
|
||||
|
||||
/**
|
||||
* The failure messages, if any.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $messages = [];
|
||||
|
||||
/**
|
||||
* The callback that will generate the "default" version of the password rule.
|
||||
*
|
||||
* @var string|array|callable|null
|
||||
*/
|
||||
public static $defaultCallback;
|
||||
|
||||
/**
|
||||
* Create a new rule instance.
|
||||
*
|
||||
* @param int $min
|
||||
*/
|
||||
public function __construct($min)
|
||||
{
|
||||
$this->min = max((int) $min, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default callback to be used for determining a password's default rules.
|
||||
*
|
||||
* If no arguments are passed, the default password rule configuration will be returned.
|
||||
*
|
||||
* @param static|callable|null $callback
|
||||
* @return static|void
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function defaults($callback = null)
|
||||
{
|
||||
if (is_null($callback)) {
|
||||
return static::default();
|
||||
}
|
||||
|
||||
if (! is_callable($callback) && ! $callback instanceof static) {
|
||||
throw new InvalidArgumentException('The given callback should be callable or an instance of '.static::class);
|
||||
}
|
||||
|
||||
static::$defaultCallback = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default configuration of the password rule.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function default()
|
||||
{
|
||||
$password = is_callable(static::$defaultCallback)
|
||||
? call_user_func(static::$defaultCallback)
|
||||
: static::$defaultCallback;
|
||||
|
||||
return $password instanceof Rule ? $password : static::min(8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default configuration of the password rule and mark the field as required.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function required()
|
||||
{
|
||||
$password = static::default();
|
||||
|
||||
$password->required = true;
|
||||
|
||||
return $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default configuration of the password rule and mark the field as sometimes being required.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function sometimes()
|
||||
{
|
||||
$password = static::default();
|
||||
|
||||
$password->sometimes = true;
|
||||
|
||||
return $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the performing validator.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Validation\Validator $validator
|
||||
* @return $this
|
||||
*/
|
||||
public function setValidator($validator)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the data under validation.
|
||||
*
|
||||
* @param array $data
|
||||
* @return $this
|
||||
*/
|
||||
public function setData($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the minimum size of the password.
|
||||
*
|
||||
* @param int $size
|
||||
* @return $this
|
||||
*/
|
||||
public static function min($size)
|
||||
{
|
||||
return new static($size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum size of the password.
|
||||
*
|
||||
* @param int $size
|
||||
* @return $this
|
||||
*/
|
||||
public function max($size)
|
||||
{
|
||||
$this->max = $size;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the password has not been compromised in data leaks.
|
||||
*
|
||||
* @param int $threshold
|
||||
* @return $this
|
||||
*/
|
||||
public function uncompromised($threshold = 0)
|
||||
{
|
||||
$this->uncompromised = true;
|
||||
|
||||
$this->compromisedThreshold = $threshold;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the password require at least one uppercase and one lowercase letter.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function mixedCase()
|
||||
{
|
||||
$this->mixedCase = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the password require at least one letter.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function letters()
|
||||
{
|
||||
$this->letters = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the password require at least one number.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function numbers()
|
||||
{
|
||||
$this->numbers = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the password require at least one symbol.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function symbols()
|
||||
{
|
||||
$this->symbols = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify additional validation rules that should be merged with the default rules during validation.
|
||||
*
|
||||
* @param \Closure|string|array $rules
|
||||
* @return $this
|
||||
*/
|
||||
public function rules($rules)
|
||||
{
|
||||
$this->customRules = Arr::wrap($rules);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the validation rule passes.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
$this->messages = [];
|
||||
|
||||
if (! $this->required && ! $this->sometimes && ! Arr::has($this->data ?? [], $attribute)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (blank($value) && ! $this->required && $this->validator?->hasRule($attribute, ['Nullable'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$validator = Validator::make(
|
||||
$this->data,
|
||||
[$attribute => [...$this]],
|
||||
$this->validator->customMessages,
|
||||
$this->validator->customAttributes
|
||||
)->after(function ($validator) use ($attribute, $value) {
|
||||
if (! is_string($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->mixedCase && ! preg_match('/(\p{Ll}+.*\p{Lu})|(\p{Lu}+.*\p{Ll})/u', $value)) {
|
||||
$validator->addFailure($attribute, 'password.mixed');
|
||||
}
|
||||
|
||||
if ($this->letters && ! preg_match('/\pL/u', $value)) {
|
||||
$validator->addFailure($attribute, 'password.letters');
|
||||
}
|
||||
|
||||
if ($this->symbols && ! preg_match('/\p{Z}|\p{S}|\p{P}/u', $value)) {
|
||||
$validator->addFailure($attribute, 'password.symbols');
|
||||
}
|
||||
|
||||
if ($this->numbers && ! preg_match('/\pN/u', $value)) {
|
||||
$validator->addFailure($attribute, 'password.numbers');
|
||||
}
|
||||
});
|
||||
|
||||
if ($validator->fails()) {
|
||||
return $this->fail($validator->messages()->all());
|
||||
}
|
||||
|
||||
if ($this->uncompromised && ! Container::getInstance()->make(UncompromisedVerifier::class)->verify([
|
||||
'value' => $value,
|
||||
'threshold' => $this->compromisedThreshold,
|
||||
])) {
|
||||
$validator->addFailure($attribute, 'password.uncompromised');
|
||||
|
||||
return $this->fail($validator->messages()->all());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation error message.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given failures, and return false.
|
||||
*
|
||||
* @param array|string $messages
|
||||
* @return bool
|
||||
*/
|
||||
protected function fail($messages)
|
||||
{
|
||||
$this->messages = array_merge($this->messages, Arr::wrap($messages));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about the current state of the password validation rules.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function appliedRules()
|
||||
{
|
||||
return [
|
||||
'min' => $this->min,
|
||||
'max' => $this->max,
|
||||
'mixedCase' => $this->mixedCase,
|
||||
'letters' => $this->letters,
|
||||
'numbers' => $this->numbers,
|
||||
'symbols' => $this->symbols,
|
||||
'uncompromised' => $this->uncompromised,
|
||||
'compromisedThreshold' => $this->compromisedThreshold,
|
||||
'customRules' => $this->customRules,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator for the password validation rules.
|
||||
*
|
||||
* @return \ArrayIterator<TKey, TValue>
|
||||
*/
|
||||
public function getIterator(): Traversable
|
||||
{
|
||||
return new ArrayIterator([
|
||||
...($this->required ? ['required'] : []),
|
||||
...($this->sometimes ? ['sometimes'] : []),
|
||||
'string',
|
||||
'min:'.$this->min,
|
||||
...($this->max ? ['max:'.$this->max] : []),
|
||||
...$this->customRules,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Closure;
|
||||
use InvalidArgumentException;
|
||||
use Stringable;
|
||||
|
||||
class ProhibitedIf implements Stringable
|
||||
{
|
||||
/**
|
||||
* The condition that validates the attribute.
|
||||
*
|
||||
* @var (\Closure(): bool)|bool
|
||||
*/
|
||||
public $condition;
|
||||
|
||||
/**
|
||||
* Create a new prohibited validation rule based on a condition.
|
||||
*
|
||||
* @param (\Closure(): bool)|bool $condition
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct($condition)
|
||||
{
|
||||
if ($condition instanceof Closure || is_bool($condition)) {
|
||||
$this->condition = $condition;
|
||||
} else {
|
||||
throw new InvalidArgumentException('The provided condition must be a callable or boolean.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the rule to a validation string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
if (is_callable($this->condition)) {
|
||||
return call_user_func($this->condition) ? 'prohibited' : '';
|
||||
}
|
||||
|
||||
return $this->condition ? 'prohibited' : '';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Closure;
|
||||
use InvalidArgumentException;
|
||||
use Stringable;
|
||||
|
||||
class ProhibitedUnless implements Stringable
|
||||
{
|
||||
/**
|
||||
* The condition that validates the attribute.
|
||||
*
|
||||
* @var (\Closure(): bool)|bool
|
||||
*/
|
||||
public $condition;
|
||||
|
||||
/**
|
||||
* Create a new prohibited validation rule based on a condition.
|
||||
*
|
||||
* @param (\Closure(): bool)|bool $condition
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct($condition)
|
||||
{
|
||||
if ($condition instanceof Closure || is_bool($condition)) {
|
||||
$this->condition = $condition;
|
||||
} else {
|
||||
throw new InvalidArgumentException('The provided condition must be a callable or boolean.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the rule to a validation string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
if (is_callable($this->condition)) {
|
||||
return call_user_func($this->condition) ? '' : 'prohibited';
|
||||
}
|
||||
|
||||
return $this->condition ? '' : 'prohibited';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Closure;
|
||||
use InvalidArgumentException;
|
||||
use Stringable;
|
||||
|
||||
class RequiredIf implements Stringable
|
||||
{
|
||||
/**
|
||||
* The condition that validates the attribute.
|
||||
*
|
||||
* @var (\Closure(): bool)|bool
|
||||
*/
|
||||
public $condition;
|
||||
|
||||
/**
|
||||
* Create a new required validation rule based on a condition.
|
||||
*
|
||||
* @param (\Closure(): bool)|bool|null $condition
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct($condition)
|
||||
{
|
||||
if (is_null($condition)) {
|
||||
$condition = false;
|
||||
}
|
||||
|
||||
if ($condition instanceof Closure || is_bool($condition)) {
|
||||
$this->condition = $condition;
|
||||
} else {
|
||||
throw new InvalidArgumentException('The provided condition must be a callable or boolean.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the rule to a validation string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
if (is_callable($this->condition)) {
|
||||
return call_user_func($this->condition) ? 'required' : '';
|
||||
}
|
||||
|
||||
return $this->condition ? 'required' : '';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Closure;
|
||||
use InvalidArgumentException;
|
||||
use Stringable;
|
||||
|
||||
class RequiredUnless implements Stringable
|
||||
{
|
||||
/**
|
||||
* The condition that validates the attribute.
|
||||
*
|
||||
* @var (\Closure(): bool)|bool
|
||||
*/
|
||||
public $condition;
|
||||
|
||||
/**
|
||||
* Create a new required validation rule based on a condition.
|
||||
*
|
||||
* @param (\Closure(): bool)|bool|null $condition
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct($condition)
|
||||
{
|
||||
if (is_null($condition)) {
|
||||
$condition = false;
|
||||
}
|
||||
|
||||
if ($condition instanceof Closure || is_bool($condition)) {
|
||||
$this->condition = $condition;
|
||||
} else {
|
||||
throw new InvalidArgumentException('The provided condition must be a callable or boolean.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the rule to a validation string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
if (is_callable($this->condition)) {
|
||||
return call_user_func($this->condition) ? '' : 'required';
|
||||
}
|
||||
|
||||
return $this->condition ? '' : 'required';
|
||||
}
|
||||
}
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Traits\Conditionable;
|
||||
use Stringable;
|
||||
|
||||
class StringRule implements Stringable
|
||||
{
|
||||
use Conditionable;
|
||||
|
||||
/**
|
||||
* The constraints for the string rule.
|
||||
*/
|
||||
protected array $constraints = ['string'];
|
||||
|
||||
/**
|
||||
* The field under validation must be entirely alphabetic characters.
|
||||
*
|
||||
* @param bool $ascii
|
||||
* @return $this
|
||||
*/
|
||||
public function alpha(bool $ascii = false): static
|
||||
{
|
||||
return $this->addRule($ascii ? 'alpha:ascii' : 'alpha');
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must be entirely alpha-numeric characters, dashes, and underscores.
|
||||
*
|
||||
* @param bool $ascii
|
||||
* @return $this
|
||||
*/
|
||||
public function alphaDash(bool $ascii = false): static
|
||||
{
|
||||
return $this->addRule($ascii ? 'alpha_dash:ascii' : 'alpha_dash');
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must be entirely alpha-numeric characters.
|
||||
*
|
||||
* @param bool $ascii
|
||||
* @return $this
|
||||
*/
|
||||
public function alphaNumeric(bool $ascii = false): static
|
||||
{
|
||||
return $this->addRule($ascii ? 'alpha_num:ascii' : 'alpha_num');
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must be entirely ASCII characters.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function ascii(): static
|
||||
{
|
||||
return $this->addRule('ascii');
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must have a length between the given min and max (inclusive).
|
||||
*
|
||||
* @param int $min
|
||||
* @param int $max
|
||||
* @return $this
|
||||
*/
|
||||
public function between(int $min, int $max): static
|
||||
{
|
||||
return $this->addRule('between:'.$min.','.$max);
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must not end with any of the given values.
|
||||
*
|
||||
* @param string ...$values
|
||||
* @return $this
|
||||
*/
|
||||
public function doesntEndWith(string ...$values): static
|
||||
{
|
||||
return $this->addRule('doesnt_end_with:'.implode(',', $values));
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must not start with any of the given values.
|
||||
*
|
||||
* @param string ...$values
|
||||
* @return $this
|
||||
*/
|
||||
public function doesntStartWith(string ...$values): static
|
||||
{
|
||||
return $this->addRule('doesnt_start_with:'.implode(',', $values));
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must end with one of the given values.
|
||||
*
|
||||
* @param string ...$values
|
||||
* @return $this
|
||||
*/
|
||||
public function endsWith(string ...$values): static
|
||||
{
|
||||
return $this->addRule('ends_with:'.implode(',', $values));
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must have an exact length.
|
||||
*
|
||||
* @param int $value
|
||||
* @return $this
|
||||
*/
|
||||
public function exactly(int $value): static
|
||||
{
|
||||
return $this->addRule('size:'.$value);
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must be entirely lowercase.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function lowercase(): static
|
||||
{
|
||||
return $this->addRule('lowercase');
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must not exceed the given length.
|
||||
*
|
||||
* @param int $value
|
||||
* @return $this
|
||||
*/
|
||||
public function max(int $value): static
|
||||
{
|
||||
return $this->addRule('max:'.$value);
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must have a minimum length.
|
||||
*
|
||||
* @param int $value
|
||||
* @return $this
|
||||
*/
|
||||
public function min(int $value): static
|
||||
{
|
||||
return $this->addRule('min:'.$value);
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must start with one of the given values.
|
||||
*
|
||||
* @param string ...$values
|
||||
* @return $this
|
||||
*/
|
||||
public function startsWith(string ...$values): static
|
||||
{
|
||||
return $this->addRule('starts_with:'.implode(',', $values));
|
||||
}
|
||||
|
||||
/**
|
||||
* The field under validation must be entirely uppercase.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function uppercase(): static
|
||||
{
|
||||
return $this->addRule('uppercase');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the rule to a validation string.
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return implode('|', array_unique($this->constraints));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom rules to the validation rules array.
|
||||
*/
|
||||
protected function addRule(array|string $rules): static
|
||||
{
|
||||
$this->constraints = array_merge($this->constraints, Arr::wrap($rules));
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Validation\Rules;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Traits\Conditionable;
|
||||
use Stringable;
|
||||
|
||||
class Unique implements Stringable
|
||||
{
|
||||
use Conditionable, DatabaseRule;
|
||||
|
||||
/**
|
||||
* The ID that should be ignored.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $ignore;
|
||||
|
||||
/**
|
||||
* The name of the ID column.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $idColumn = 'id';
|
||||
|
||||
/**
|
||||
* Ignore the given ID during the unique check.
|
||||
*
|
||||
* @param mixed $id
|
||||
* @param string|null $idColumn
|
||||
* @return $this
|
||||
*/
|
||||
public function ignore($id, $idColumn = null)
|
||||
{
|
||||
if ($id instanceof Model) {
|
||||
return $this->ignoreModel($id, $idColumn);
|
||||
}
|
||||
|
||||
$this->ignore = $id;
|
||||
$this->idColumn = $idColumn ?? 'id';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignore the given model during the unique check.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string|null $idColumn
|
||||
* @return $this
|
||||
*/
|
||||
public function ignoreModel($model, $idColumn = null)
|
||||
{
|
||||
$this->idColumn = $idColumn ?? $model->getKeyName();
|
||||
$this->ignore = $model->{$this->idColumn};
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the rule to a validation string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return rtrim(sprintf('unique:%s,%s,%s,%s,%s',
|
||||
$this->table,
|
||||
$this->column,
|
||||
$this->ignore ? '"'.addslashes($this->ignore).'"' : 'NULL',
|
||||
$this->idColumn,
|
||||
$this->formatWheres()
|
||||
), ',');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user