187 lines
6.2 KiB
PHP
187 lines
6.2 KiB
PHP
<?php
|
|
|
|
namespace App\Rules;
|
|
|
|
use App\Enums\VideoProviderEnum;
|
|
use Illuminate\Contracts\Validation\DataAwareRule;
|
|
use Illuminate\Contracts\Validation\ValidationRule;
|
|
use Illuminate\Support\Arr;
|
|
use Uwil\LaravelCommon\Rules\IsValidVimeoId;
|
|
use Uwil\LaravelCommon\Rules\IsValidYoutubeId;
|
|
|
|
/**
|
|
* Check the length of a Wysiwyg field, excluding tags and end spaces.
|
|
*
|
|
* @package Uwil\LaravelCommon\Rules
|
|
*/
|
|
class Video implements ValidationRule, DataAwareRule
|
|
{
|
|
protected array $data = [];
|
|
|
|
public function setData(array $data): static
|
|
{
|
|
$this->data = $data;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Construct method.
|
|
*
|
|
* @param integer $min The minimum length of the content (excluding tags). Default is 15.
|
|
* @param integer|null $max The maximum length of the content (excluding tags).
|
|
* Default is null (max will be defined by the type of the column in DB).
|
|
* @return void
|
|
* @throws \InvalidArgumentException If $max < $min.
|
|
*/
|
|
public function __construct() {}
|
|
|
|
/**
|
|
* Run the validation rule.
|
|
*
|
|
* @param string $attribute
|
|
* @param mixed $value
|
|
* @param \Closure $fail
|
|
*
|
|
* @return void
|
|
*/
|
|
public function validate(string $attribute, mixed $value, \Closure $fail): void
|
|
{
|
|
|
|
$lengthRules = [
|
|
$attribute . '.alt' => ['min' => 3, 'max' => 255],
|
|
$attribute . '.caption' => ['min' => 3, 'max' => 255],
|
|
];
|
|
|
|
if (!$value) {
|
|
return;
|
|
}
|
|
|
|
$fields = [
|
|
$attribute . '.alt',
|
|
$attribute . '.caption',
|
|
$attribute . '.isMuted',
|
|
$attribute . '.hasControls',
|
|
$attribute . '.canFullScreen',
|
|
$attribute . '.provider',
|
|
$attribute . '.videoId',
|
|
$attribute . '.format',
|
|
];
|
|
|
|
foreach ($fields as $field) {
|
|
$fieldValue = Arr::get($this->data, $field);
|
|
if (in_array($field, [
|
|
$attribute . '.alt',
|
|
$attribute . '.caption'
|
|
])) {
|
|
$lengthRule = $lengthRules[$field] ?? null;
|
|
|
|
if ($lengthRule) {
|
|
$min = $lengthRule['min'] ?? 0;
|
|
$max = $lengthRule['max'] ?? PHP_INT_MAX;
|
|
if ($fieldValue === null && $field === $attribute . '.caption') {
|
|
continue;
|
|
}
|
|
if ($fieldValue === null && $field === $attribute . '.title') {
|
|
continue;
|
|
}
|
|
if (strlen($fieldValue) < $min) {
|
|
$fail(__('validation.min.string', [
|
|
'attribute' => self::getTranslatedAttribute($field),
|
|
'min' => $min
|
|
]));
|
|
return;
|
|
}
|
|
|
|
if (strlen($fieldValue) > $max) {
|
|
$fail(__('validation.max.string', [
|
|
'attribute' => self::getTranslatedAttribute($field),
|
|
'max' => $max
|
|
]));
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Boolean fields
|
|
if (in_array($field, [$attribute . '.isMuted', $attribute . '.hasControls', $attribute . '.canFullScreen'])) {
|
|
$fieldValue = (bool)$fieldValue;
|
|
if (!is_bool($fieldValue)) {
|
|
$fail(__('validation.boolean', [
|
|
'attribute' => self::getTranslatedAttribute($field),
|
|
]));
|
|
return;
|
|
}
|
|
}
|
|
|
|
if($field === $attribute . '.format') {
|
|
if($fieldValue != "landscape" && $fieldValue != "portrait") {
|
|
$fail(__('validation.custom.format', [
|
|
'attribute' => self::getTranslatedAttribute($field),
|
|
]));
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ($field === $attribute . '.provider') {
|
|
|
|
$fieldValue = (int) $fieldValue;
|
|
|
|
if (!is_int($fieldValue)) {
|
|
$fail(__('validation.integer', [
|
|
'attribute' => self::getTranslatedAttribute($field),
|
|
]));
|
|
return;
|
|
}
|
|
|
|
$enumValues = array_map(fn($case) => $case->value, VideoProviderEnum::cases());
|
|
if (!in_array($fieldValue, $enumValues)) {
|
|
$fail(__('validation.in', [
|
|
'attribute' => self::getTranslatedAttribute($field),
|
|
]));
|
|
return;
|
|
}
|
|
|
|
if ($field === $attribute . '.videoId') {
|
|
$provider = Arr::get($this->data, $attribute . '.provider');
|
|
|
|
if ($provider === \App\Enums\VideoProviderEnum::vimeo->value) {
|
|
$rule = new IsValidVimeoId();
|
|
} elseif ($provider === \App\Enums\VideoProviderEnum::youtube->value) {
|
|
$rule = new IsValidYoutubeId();
|
|
} else {
|
|
$fail(__('validation.invalid', [
|
|
'attribute' => self::getTranslatedAttribute($attribute . '.provider'),
|
|
]));
|
|
return;
|
|
}
|
|
$rule->validate($field, $fieldValue, $fail);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the correct translation for the given attrribute.
|
|
*
|
|
* @param string $attribute
|
|
* @return string
|
|
*/
|
|
private static function getTranslatedAttribute(string $attribute): string
|
|
{
|
|
$parts = explode('.', $attribute);
|
|
if (count($parts) > 1) {
|
|
$parts[0] = 'video_';
|
|
$attribute = implode('.', $parts);
|
|
}
|
|
|
|
/** @var \Illuminate\Translation\Translator $trans */
|
|
$trans = trans();
|
|
if ($trans->has('validation.attributes.' . $attribute)) {
|
|
return trans('validation.attributes.' . $attribute);
|
|
}
|
|
if ($trans->has('validation.custom.' . $attribute)) {
|
|
return trans('validation.custom.' . $attribute);
|
|
}
|
|
return $attribute;
|
|
}
|
|
}
|