diff --git a/demo/app/Models/Post.php b/demo/app/Models/Post.php index 65d943f68..78daddcb3 100644 --- a/demo/app/Models/Post.php +++ b/demo/app/Models/Post.php @@ -51,7 +51,7 @@ public function author(): BelongsTo public function cover(): MorphOne { return $this->morphOne(Media::class, 'model') - ->where('model_key', 'cover'); + ->withAttributes(['model_key' => 'cover']); } public function attachments(): HasMany @@ -80,11 +80,4 @@ public function isDraft(): bool { return $this->state === PostState::DRAFT; } - - public function getDefaultAttributesFor($attribute) - { - return in_array($attribute, ['cover']) - ? ['model_key' => $attribute] - : []; - } } diff --git a/demo/app/Models/PostAttachment.php b/demo/app/Models/PostAttachment.php index b8f516322..1dcbbfe00 100644 --- a/demo/app/Models/PostAttachment.php +++ b/demo/app/Models/PostAttachment.php @@ -24,13 +24,6 @@ public function post(): BelongsTo public function document(): MorphOne { return $this->morphOne(Media::class, 'model') - ->where('model_key', 'document'); - } - - public function getDefaultAttributesFor($attribute) - { - return in_array($attribute, ['document']) - ? ['model_key' => $attribute] - : []; + ->withAttributes(['model_key' => 'document']); } } diff --git a/demo/app/Models/PostBlock.php b/demo/app/Models/PostBlock.php index c93422884..fb5906300 100644 --- a/demo/app/Models/PostBlock.php +++ b/demo/app/Models/PostBlock.php @@ -21,13 +21,6 @@ public function post(): BelongsTo public function files(): MorphMany { return $this->morphMany(Media::class, 'model') - ->where('model_key', 'files'); - } - - public function getDefaultAttributesFor($attribute) - { - return in_array($attribute, ['files']) - ? ['model_key' => $attribute] - : []; + ->withAttributes(['model_key' => 'files']); } } diff --git a/demo/app/Models/User.php b/demo/app/Models/User.php index 47a047ab8..3cead3d10 100644 --- a/demo/app/Models/User.php +++ b/demo/app/Models/User.php @@ -35,13 +35,6 @@ public function isAdmin(): bool public function avatar(): MorphOne { return $this->morphOne(Media::class, 'model') - ->where('model_key', 'avatar'); - } - - public function getDefaultAttributesFor(string $attribute): array - { - return in_array($attribute, ['avatar']) - ? ['model_key' => $attribute] - : []; + ->withAttributes(['model_key' => 'avatar']); } } diff --git a/docs/guide/sharp-uploads.md b/docs/guide/sharp-uploads.md index 1f55ee8fd..942c62bc2 100644 --- a/docs/guide/sharp-uploads.md +++ b/docs/guide/sharp-uploads.md @@ -66,6 +66,28 @@ class CreateMediasTable extends Migration Now, you need to define the relationships. Let's say you have a Book model, and you want the user to be able to upload its cover and PDF version. +**With Laravel 12:** + +```php +class Book extends Model +{ + public function cover() + { + return $this->morphOne(Media::class, 'model') + ->withAttributes(['model_key' => 'cover']); + } + + public function pdf() + { + return $this->morphOne(Media::class, 'model') + ->withAttributes(['model_key' => 'pdf']); + } +} +``` + +**Before Laravel 12:** +(The `withAttributes` method is not available before Laravel 12) + ```php class Book extends Model { @@ -83,6 +105,10 @@ class Book extends Model } ``` +::: tip +Prefer the Laravel 12+ syntax: it offers clarity and, more importantly, simplifies updates by eliminating the need for an additional method (see below). +::: + ## Use it! ### Properties @@ -120,7 +146,7 @@ class SharpServiceProvider extends SharpAppServiceProvider thumbnailsDisk: 'public', thumbnailsDir: 'thumbnails', ) - // [...] + // ... } } ``` @@ -190,52 +216,64 @@ You can provide a custom Modifier; you’ll need to create a class that extends The best part is this: Sharp will take care of everything related to update and store. -First declare your upload, like usual: +Declare your upload, as usual, and add a transformer: ```php -function buildFormFields() -{ - $this->addField( - SharpFormUploadField::make('cover') - ->setLabel('Cover') - ->setImageOnly() - ->setImageCropRatio('1:1') - ->setStorageDisk('local') - ->setStorageBasePath('data/Books') - ); -} -``` -Then add a customTransformer: +use Code16\Sharp\Form\Eloquent\Uploads\Transformers\SharpUploadModelFormAttributeTransformer; +// ... -```php -function find($id): array +class MyForm extends SharpForm { - return $this - ->setCustomTransformer( - 'cover', - new SharpUploadModelFormAttributeTransformer() - ) - ->transform( - Book::with('cover')->findOrFail($id) + function buildFormFields() + { + $this->addField( + SharpFormUploadField::make('cover') + ->setLabel('Cover') + ->setImageOnly() + ->setImageCropRatio('1:1') + ->setStorageDisk('local') + ->setStorageBasePath('data/Books') ); + // ... + } + + function find($id): array + { + return $this + ->setCustomTransformer('cover', new SharpUploadModelFormAttributeTransformer()) + ->transform(Book::with('cover')->findOrFail($id)); + } + + // ... } ``` -The full path of this transformer is `Code16\Sharp\Form\Eloquent\Uploads\Transformers\SharpUploadModelFormAttributeTransformer`. +### Updating custom attributes (Laravel 11 and below) -And finally, and this is a sad exception to the "don't touch the applicative code for Sharp", add this in your Model that declares an upload relationship (Book, in our example): +If you use the Laravel 12+ syntax for the relationships, you are done. **Otherwise, you need to add a `getDefaultAttributesFor()` method in your Model**: ```php -public function getDefaultAttributesFor($attribute) +class Book extends Model { - return in_array($attribute, ['cover']) - ? ['model_key' => $attribute] - : []; + public function cover() + { + return $this->morphOne(Media::class, 'model') + ->where('model_key', 'cover'); + } + + public function getDefaultAttributesFor($attribute) + { + return $attribute === 'cover' + ? ['model_key' => $attribute] + : []; + } + + // ... } ``` -This will tell SharpEloquentUpdater to add the necessary `model_key`attribute when creating a new upload. +This will tell SharpEloquentUpdater to add the necessary `model_key` attribute when creating a new upload. Again, this is not needed if you declare the relationship with Laravel 12+ syntax (`->withAttributes(['model_key' => 'cover'])`). And... voilà! From there, Sharp will handle the rest. @@ -286,31 +324,14 @@ $this->addField( Note that we use the special `file` key for the SharpFormUploadField in the item. -You'll have next to update your Model special `getDefaultAttributesFor()` function: - -```php -public function getDefaultAttributesFor($attribute) -{ - return in_array($attribute, ['cover','pictures']) - ? ['model_key' => $attribute] - : []; -} -``` - -All set. - #### Updating custom attributes in upload lists ```php $this->addField( SharpFormListField::make('pictures') - // [...] - ->addItemField( - SharpFormUploadField::make('file') - ) - ->addItemField( - SharpFormTextField::make('legend') - ) + // ... + ->addItemField(SharpFormUploadField::make('file')) + ->addItemField(SharpFormTextField::make('legend')) ); ``` diff --git a/tests-e2e/site/app/Models/TestModel.php b/tests-e2e/site/app/Models/TestModel.php index 916b7d0d3..a1589408e 100644 --- a/tests-e2e/site/app/Models/TestModel.php +++ b/tests-e2e/site/app/Models/TestModel.php @@ -38,18 +38,11 @@ protected function casts(): array public function upload(): MorphOne { return $this->morphOne(Media::class, 'model') - ->where('model_key', 'upload'); + ->withAttributes(['model_key' => 'upload']); } public function tags(): BelongsToMany { return $this->belongsToMany(TestTag::class); } - - public function getDefaultAttributesFor($attribute) - { - return in_array($attribute, ['upload']) - ? ['model_key' => $attribute] - : []; - } }