diff --git a/src/app/Library/Uploaders/MultipleFiles.php b/src/app/Library/Uploaders/MultipleFiles.php index ecb5c9a084..010d5c2aae 100644 --- a/src/app/Library/Uploaders/MultipleFiles.php +++ b/src/app/Library/Uploaders/MultipleFiles.php @@ -22,7 +22,7 @@ public function uploadFiles(Model $entry, $value = null) } $filesToDelete = $this->getFilesToDeleteFromRequest(); - $value = $value ?? collect(CRUD::getRequest()->file($this->getNameForRequest()))->flatten()->toArray(); + $value = $value ?? collect($value)->flatten()->toArray(); $previousFiles = $this->getPreviousFiles($entry) ?? []; if (is_array($previousFiles) && empty($previousFiles[0] ?? [])) { @@ -108,12 +108,12 @@ public function uploadRepeatableFiles($files, $previousRepeatableValues, $entry return $fileOrder; } - protected function hasDeletedFiles($value): bool + public function hasDeletedFiles($value): bool { return empty($this->getFilesToDeleteFromRequest()) ? false : true; } - protected function getEntryAttributeValue(Model $entry) + public function getEntryAttributeValue(Model $entry) { $value = $entry->{$this->getAttributeName()}; diff --git a/src/app/Library/Uploaders/SingleBase64Image.php b/src/app/Library/Uploaders/SingleBase64Image.php index 6085304c21..71ffde3d73 100644 --- a/src/app/Library/Uploaders/SingleBase64Image.php +++ b/src/app/Library/Uploaders/SingleBase64Image.php @@ -12,7 +12,6 @@ class SingleBase64Image extends Uploader { public function uploadFiles(Model $entry, $value = null) { - $value = $value ?? CRUD::getRequest()->get($this->getName()); $previousImage = $this->getPreviousFiles($entry); if (! $value && $previousImage) { @@ -61,7 +60,7 @@ public function uploadRepeatableFiles($values, $previousRepeatableValues, $entry return $values; } - protected function shouldUploadFiles($value): bool + public function shouldUploadFiles($value): bool { return $value && is_string($value) && Str::startsWith($value, 'data:image'); } @@ -70,4 +69,9 @@ public function shouldKeepPreviousValueUnchanged(Model $entry, $entryValue): boo { return $entry->exists && is_string($entryValue) && ! Str::startsWith($entryValue, 'data:image'); } + + public function getUploadedFilesFromRequest() + { + return CRUD::getRequest()->get($this->getNameForRequest()); + } } diff --git a/src/app/Library/Uploaders/SingleFile.php b/src/app/Library/Uploaders/SingleFile.php index 4a064fb5b8..0b4acf6055 100644 --- a/src/app/Library/Uploaders/SingleFile.php +++ b/src/app/Library/Uploaders/SingleFile.php @@ -10,7 +10,6 @@ class SingleFile extends Uploader { public function uploadFiles(Model $entry, $value = null) { - $value = $value ?? CrudPanelFacade::getRequest()->file($this->getName()); $previousFile = $this->getPreviousFiles($entry); if ($value === false && $previousFile) { @@ -75,12 +74,12 @@ public function shouldKeepPreviousValueUnchanged(Model $entry, $entryValue): boo return is_string($entryValue); } - protected function hasDeletedFiles($entryValue): bool + public function hasDeletedFiles($entryValue): bool { return $entryValue === null; } - protected function shouldUploadFiles($value): bool + public function shouldUploadFiles($value): bool { return is_a($value, 'Illuminate\Http\UploadedFile', true); } diff --git a/src/app/Library/Uploaders/Support/Interfaces/UploaderInterface.php b/src/app/Library/Uploaders/Support/Interfaces/UploaderInterface.php index 20df54dbc0..e8e432ecc6 100644 --- a/src/app/Library/Uploaders/Support/Interfaces/UploaderInterface.php +++ b/src/app/Library/Uploaders/Support/Interfaces/UploaderInterface.php @@ -15,10 +15,14 @@ public static function for(array $field, array $configuration): UploaderInterfac /** * Default implementation functions. */ + + // method called on `saving` event to store and update the entry with the uploaded files public function storeUploadedFiles(Model $entry); + // method called on `retrieved` event to populated the uploaded files in the entry public function retrieveUploadedFiles(Model $entry); + // method called on `deleting` event to delete the uploaded files public function deleteUploadedFiles(Model $entry); /** @@ -55,17 +59,20 @@ public function getIdentifier(): string; public function getNameForRequest(): string; - public function shouldDeleteFiles(): bool; - public function canHandleMultipleFiles(): bool; public function isRelationship(): bool; public function getPreviousFiles(Model $entry): mixed; - public function getValueWithoutPath(?string $value = null): ?string; + /** + * Strategy methods. + */ + public function shouldDeleteFiles(): bool; + + public function hasDeletedFiles($entryValue): bool; - public function isFake(): bool; + public function shouldUploadFiles(mixed $value): bool; - public function getFakeAttribute(): bool|string; + public function shouldKeepPreviousValueUnchanged(Model $entry, mixed $entryValue): bool; } diff --git a/src/app/Library/Uploaders/Support/Traits/HandleRepeatableUploads.php b/src/app/Library/Uploaders/Support/Traits/HandleRepeatableUploads.php index 30465ec4ee..858a519be1 100644 --- a/src/app/Library/Uploaders/Support/Traits/HandleRepeatableUploads.php +++ b/src/app/Library/Uploaders/Support/Traits/HandleRepeatableUploads.php @@ -62,7 +62,7 @@ protected function handleRepeatableFiles(Model $entry): Model return $this->processRelationshipRepeatableUploaders($entry); } - $processedEntryValues = $this->processRepeatableUploads($entry, $value); + $processedEntryValues = $this->processRepeatableUploads($entry, $value)->toArray(); if ($this->isFake()) { $fakeValues = $entry->{$this->getFakeAttribute()} ?? []; @@ -147,17 +147,7 @@ protected function getEntryOriginalValue(Model $entry) return $entry->getOriginal($this->getAttributeName()); } - protected function shouldUploadFiles($entryValue): bool - { - return true; - } - - protected function hasDeletedFiles($entryValue): bool - { - return $entryValue === false || $entryValue === null || $entryValue === [null]; - } - - protected function processRepeatableUploads(Model $entry, Collection $values): array + protected function processRepeatableUploads(Model $entry, Collection $values): Collection { foreach (app('UploadersRepository')->getRepeatableUploadersFor($this->getRepeatableContainerName()) as $uploader) { $uploadedValues = $uploader->uploadRepeatableFiles($values->pluck($uploader->getAttributeName())->toArray(), $this->getPreviousRepeatableValues($entry, $uploader)); @@ -169,7 +159,7 @@ protected function processRepeatableUploads(Model $entry, Collection $values): a }); } - return $values->toArray(); + return $values; } private function retrieveRepeatableFiles(Model $entry): Model diff --git a/src/app/Library/Uploaders/Uploader.php b/src/app/Library/Uploaders/Uploader.php index e1edca0c96..a11295aeb7 100644 --- a/src/app/Library/Uploaders/Uploader.php +++ b/src/app/Library/Uploaders/Uploader.php @@ -2,6 +2,7 @@ namespace Backpack\CRUD\app\Library\Uploaders; +use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD; use Backpack\CRUD\app\Library\Uploaders\Support\Interfaces\UploaderInterface; use Backpack\CRUD\app\Library\Uploaders\Support\Traits\HandleFileNaming; use Backpack\CRUD\app\Library\Uploaders\Support\Traits\HandleRepeatableUploads; @@ -76,17 +77,19 @@ public function storeUploadedFiles(Model $entry): Model return $this->handleRepeatableFiles($entry); } + $values = $this->getUploadedFilesFromRequest(); + if ($this->attachedToFakeField) { $fakeFieldValue = $entry->{$this->attachedToFakeField}; $fakeFieldValue = is_string($fakeFieldValue) ? json_decode($fakeFieldValue, true) : (array) $fakeFieldValue; - $fakeFieldValue[$this->getAttributeName()] = $this->uploadFiles($entry); + $fakeFieldValue[$this->getAttributeName()] = $this->uploadFiles($entry, $values); $entry->{$this->attachedToFakeField} = isset($entry->getCasts()[$this->attachedToFakeField]) ? $fakeFieldValue : json_encode($fakeFieldValue); return $entry; } - $entry->{$this->getAttributeName()} = $this->uploadFiles($entry); + $entry->{$this->getAttributeName()} = $this->uploadFiles($entry, $values); return $entry; } @@ -151,6 +154,21 @@ public function shouldDeleteFiles(): bool return $this->deleteWhenEntryIsDeleted; } + public function shouldUploadFiles($entryValue): bool + { + return true; + } + + public function shouldKeepPreviousValueUnchanged(Model $entry, $entryValue): bool + { + return $entry->exists && ($entryValue === null || $entryValue === [null]); + } + + public function hasDeletedFiles($entryValue): bool + { + return $entryValue === false || $entryValue === null || $entryValue === [null]; + } + public function getIdentifier(): string { if ($this->handleRepeatableFiles) { @@ -191,6 +209,11 @@ public function getValueWithoutPath(?string $value = null): ?string return $value ? Str::after($value, $this->path) : null; } + public function getUploadedFilesFromRequest() + { + return CRUD::getRequest()->file($this->getNameForRequest()); + } + public function isFake(): bool { return $this->attachedToFakeField !== false; @@ -201,11 +224,6 @@ public function getFakeAttribute(): bool|string return $this->attachedToFakeField; } - public function shouldKeepPreviousValueUnchanged(Model $entry, $entryValue): bool - { - return $entry->exists && ($entryValue === null || $entryValue === [null]); - } - /******************************* * Setters - fluently configure the uploader *******************************/ diff --git a/src/resources/views/crud/fields/summernote.blade.php b/src/resources/views/crud/fields/summernote.blade.php index ad04ba173a..4a8e08d4b8 100644 --- a/src/resources/views/crud/fields/summernote.blade.php +++ b/src/resources/views/crud/fields/summernote.blade.php @@ -13,6 +13,9 @@ name="{{ $field['name'] }}" data-init-function="bpFieldInitSummernoteElement" data-options="{{ json_encode($field['options']) }}" + data-upload-enabled="{{ isset($field['withFiles']) || isset($field['withMedia']) || isset($field['imageUploadEndpoint']) ? 'true' : 'false'}}" + data-upload-endpoint="{{ isset($field['imageUploadEndpoint']) ? $field['imageUploadEndpoint'] : 'false'}}" + data-upload-operation="{{ $crud->get('ajax-upload.formOperation') }}" bp-field-main-input @include('crud::fields.inc.attributes', ['default_class' => 'form-control summernote']) >{{ old_empty_or_null($field['name'], '') ?? $field['value'] ?? $field['default'] ?? '' }} @@ -31,8 +34,8 @@ {{-- FIELD CSS - will be loaded in the after_styles section --}} @push('crud_fields_styles') {{-- include summernote css --}} - @basset('https://unpkg.com/summernote@0.8.20/dist/summernote-lite.min.css') - @basset('https://unpkg.com/summernote@0.8.20/dist/font/summernote.woff2', false) + @basset('https://unpkg.com/summernote@0.9.1/dist/summernote-lite.min.css') + @basset('https://unpkg.com/summernote@0.9.1/dist/font/summernote.woff2', false) @bassetBlock('backpack/crud/fields/summernote-field.css')