Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions demo/app/Models/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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]
: [];
}
}
9 changes: 1 addition & 8 deletions demo/app/Models/PostAttachment.php
Original file line number Diff line number Diff line change
Expand Up @@ -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']);
}
}
9 changes: 1 addition & 8 deletions demo/app/Models/PostBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -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']);
}
}
9 changes: 1 addition & 8 deletions demo/app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -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']);
}
}
123 changes: 72 additions & 51 deletions docs/guide/sharp-uploads.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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
Expand Down Expand Up @@ -120,7 +146,7 @@ class SharpServiceProvider extends SharpAppServiceProvider
thumbnailsDisk: 'public',
thumbnailsDir: 'thumbnails',
)
// [...]
// ...
}
}
```
Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -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'))
);
```

Expand Down
9 changes: 1 addition & 8 deletions tests-e2e/site/app/Models/TestModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -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]
: [];
}
}
Loading