From fac293dda0742869c34278642e29fc116066c60a Mon Sep 17 00:00:00 2001 From: Maksim Klimenko Date: Wed, 8 Nov 2023 15:36:08 +1000 Subject: [PATCH 1/2] =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D0=BE?= =?UTF-8?q?=20=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4=D0=B0=D1=86=D0=B8=D0=B8=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20Attachment,=20=D0=B7=D0=B0=D0=B3=D1=80?= =?UTF-8?q?=D1=83=D0=B6=D0=B5=D0=BD=D0=BD=D1=8B=D1=85=20=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B5=D0=B5=20=D0=BF=D0=BE=D0=BB=D1=8F=D0=BC=D0=B8=20Upload,?= =?UTF-8?q?=20Cropper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.json | 1 + src/Rule/AttachmentRule.php | 108 ++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 src/Rule/AttachmentRule.php diff --git a/composer.json b/composer.json index 896c24397..8013d2cef 100644 --- a/composer.json +++ b/composer.json @@ -66,6 +66,7 @@ "Orchid\\Filters\\": "src/Filters/", "Orchid\\Metrics\\": "src/Metrics/", "Orchid\\Platform\\": "src/Platform/", + "Orchid\\Rule\\": "src/Rule/", "Orchid\\Screen\\": "src/Screen/", "Orchid\\Support\\": "src/Support/" }, diff --git a/src/Rule/AttachmentRule.php b/src/Rule/AttachmentRule.php new file mode 100644 index 000000000..4ebec2501 --- /dev/null +++ b/src/Rule/AttachmentRule.php @@ -0,0 +1,108 @@ +} */ + protected Collection $attachment; + + /** + * @param mixed $rules правила валидации файлов Attachment см. документацию по валидации файлов. + * Например: File::image()->dimensions(Rule::dimensions()->maxWidth(960)->maxHeight(639)) или + * то-же самое 'image|dimensions:min_width=960,min_height=639' + * @param bool $removeFailed удалять или нет файлы, не прошедшие валидацию + */ + public function __construct(protected mixed $rules, protected bool $removeFailed = true) + { + } + + /** + * Получение Attachment для валидации + * @param mixed $ids + * @return void + */ + protected function setAttachment(mixed $ids): void + { + $this->attachment = is_array($ids) + ? Attachment::whereIn('id', $ids)->get() + : Attachment::where('id', $ids)->get(); + + $this->attachment = $this->attachment->mapWithKeys(fn(Attachment $attachment) => ["_{$attachment->id}" => $attachment]); + } + + /** + * Получение объекта типа \Symfony\Component\HttpFoundation\File\File из AttachmentModel + * + * @param Attachment $attachment + * @return FileSymfony|null + */ + protected function getFileObjectFromAttachment(Attachment $attachment): ?FileSymfony + { + if ($attachment->exists) { + /** @var Filesystem|Cloud $disk */ + $disk = Storage::disk($attachment->disk); + return new FileSymfony($disk->path($attachment->physicalPath())); + } + + return null; + } + + /** + * Генерация валидатора + * + * @return Validator + */ + protected function getValidator(): Validator + { + $data = $this->attachment->mapWithKeys(fn(Attachment $attachment, $key) => [$key => $this->getFileObjectFromAttachment($attachment)])->filter(fn($item) => !empty($item))->toArray(); + $rules = $this->attachment->mapWithKeys(fn(Attachment $attachment, $key) => [$key => $this->rules])->toArray(); + $attributes = $this->attachment->mapWithKeys(fn(Attachment $attachment, $key) => [$key => $attachment->original_name])->toArray(); + + return validator(data: $data, rules: $rules, attributes: $attributes); + } + + /** + * @param \Illuminate\Support\Collection $errors + * @return void + */ + protected function removeFiles(\Illuminate\Support\Collection $errors): void + { + $errors->each(function ($message, $key) { + if ($this->attachment->has($key)) { + $this->attachment[$key]->delete(); + } + }); + } + + /** + * Run the validation rule. + * + * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail + */ + public function validate(string $attribute, mixed $value, Closure $fail): void + { + $this->setAttachment($value); + $validator = $this->getValidator(); + + if ($validator->fails()) { + $errors = collect($validator->errors()->toArray()); + + if ($this->removeFailed) { + $this->removeFiles($errors); + } + + $fail($errors->flatten()->implode(' ')); + } + } +} From 5e0fcfd4b2c0d0d3de1b96b5983b49f78dfb88e9 Mon Sep 17 00:00:00 2001 From: Maksim Klimenko Date: Thu, 9 Nov 2023 09:15:41 +1000 Subject: [PATCH 2/2] =?UTF-8?q?=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=BE=20=D0=BE=D0=B1=D1=80=D0=B0=D1=89=D0=B5=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=20=D0=BA=20=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D0=B8=20Attachment;?= =?UTF-8?q?=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=B0=20=D1=81=D1=83?= =?UTF-8?q?=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D1=84=D0=B0=D0=B9=D0=BB=D0=B0,=20=D1=83=D0=BA=D0=B0?= =?UTF-8?q?=D0=B7=D0=B0=D0=BD=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=B2=20Attachmen?= =?UTF-8?q?t,=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B4=20=D1=81=D0=BE=D0=B7=D0=B4?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B5=D0=BC=20=D1=8D=D0=BA=D0=B7=D0=B5=D0=BC?= =?UTF-8?q?=D0=BF=D0=BB=D1=8F=D1=80=D0=B0=20File;=20=D0=B8=D0=B7=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=B5=D0=BD=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=20?= =?UTF-8?q?=D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=84=D0=B0?= =?UTF-8?q?=D0=B9=D0=BB=D0=BE=D0=B2,=20=D0=BD=D0=B5=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D1=88=D0=B5=D0=B4=D1=88=D0=B8=D1=85=20=D0=B2=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B4=D0=B0=D1=86=D0=B8=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Rule/AttachmentRule.php | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Rule/AttachmentRule.php b/src/Rule/AttachmentRule.php index 4ebec2501..65a520448 100644 --- a/src/Rule/AttachmentRule.php +++ b/src/Rule/AttachmentRule.php @@ -9,12 +9,13 @@ use Illuminate\Contracts\Validation\Validator; use Illuminate\Database\Eloquent\Collection; use Orchid\Attachment\Models\Attachment; +use Orchid\Support\Facades\Dashboard; use Storage; use Symfony\Component\HttpFoundation\File\File as FileSymfony; class AttachmentRule implements ValidationRule { - /** @var Collection} */ + /** @var Collection */ protected Collection $attachment; /** @@ -34,9 +35,11 @@ public function __construct(protected mixed $rules, protected bool $removeFailed */ protected function setAttachment(mixed $ids): void { + $model = Dashboard::model(Attachment::class); + $this->attachment = is_array($ids) - ? Attachment::whereIn('id', $ids)->get() - : Attachment::where('id', $ids)->get(); + ? $model::whereIn('id', $ids)->get() + : $model::where('id', $ids)->get(); $this->attachment = $this->attachment->mapWithKeys(fn(Attachment $attachment) => ["_{$attachment->id}" => $attachment]); } @@ -52,7 +55,10 @@ protected function getFileObjectFromAttachment(Attachment $attachment): ?FileSym if ($attachment->exists) { /** @var Filesystem|Cloud $disk */ $disk = Storage::disk($attachment->disk); - return new FileSymfony($disk->path($attachment->physicalPath())); + + return $disk->exists($attachment->physicalPath()) + ? new FileSymfony($disk->path($attachment->physicalPath())) + : null; } return null; @@ -78,11 +84,7 @@ protected function getValidator(): Validator */ protected function removeFiles(\Illuminate\Support\Collection $errors): void { - $errors->each(function ($message, $key) { - if ($this->attachment->has($key)) { - $this->attachment[$key]->delete(); - } - }); + $errors->filter(fn($message, $key) => $this->attachment->has($key))->each(fn($message, $key) => $this->attachment->get($key)->delete()); } /**