Overview
The HandlesMediaValues trait extends the HandlesBoundValues trait to provide specialized functionality for working with the Spatie Media Library package. It handles retrieving media files from Eloquent models and generating appropriate URLs.
Namespace: Javaabu\Forms\Support
Trait Definition
trait HandlesMediaValues
{
use HandlesBoundValues;
}
Dependencies
This trait uses the HandlesBoundValues trait and integrates with:
Spatie\MediaLibrary\HasMedia interface
Spatie\MediaLibrary\MediaCollections\Models\Media model
Methods
getBoundValue
protected function getBoundValue($bind, string $name)
The model/object to retrieve value from. If false, returns null.
The attribute name in dot notation.
Overrides the parent getBoundValue method to handle media files. First attempts to get the value normally (unless ignoreAccessor is true), then falls back to retrieving media from the specified collection.
Returns: mixed - The attribute value, Media object, or null
Retrieval Logic:
- If
$bind is false, returns null
- If
$bind is null, uses currently bound target
- Attempts to get value via accessor (unless
ignoreAccessor is true)
- If value is empty and model implements
HasMedia, retrieves first media from collection
- Returns the value or Media object
Example:
// Component property
protected string $collection = 'avatar';
protected bool $ignoreAccessor = false;
// Get bound value
$media = $this->getBoundValue($user, 'avatar');
// Returns Media object from 'avatar' collection
setValue
protected function setValue(string $name, $bind = null, $default = null)
The field name in bracket notation.
The model to retrieve media from.
Default value if no media found.
Retrieves media value, generates URL, extracts filename, and sets the component’s value and fileName properties.
Returns: mixed - The media URL
Processing:
- Converts name to dot notation
- Gets bound value (Media object or URL string)
- Generates file URL using
getFileUrl()
- Extracts filename from Media object or URL
- Sets
$this->value to URL and $this->fileName to filename
Example:
public function __construct(string $name, $bind = null)
{
parent::__construct();
$this->bindModel($bind);
$this->setValue($name, $bind);
// $this->value contains URL
// $this->fileName contains filename
}
getFileNameFromUrl
protected function getFileNameFromUrl(?string $url): string
The file URL to extract filename from.
Extracts the filename from a URL path.
Returns: string - The filename, or empty string if URL is null
Example:
$filename = $this->getFileNameFromUrl('https://example.com/media/avatar.jpg');
// Returns: "avatar.jpg"
$filename = $this->getFileNameFromUrl(null);
// Returns: ""
getFileUrl
protected function getFileUrl($media): ?string
The media object or URL string.
Generates a URL for the media file with support for conversions.
Returns: string|null - The media URL or null
Conversion Handling:
- If
$conversion is set and generated, returns conversion URL
- If
$conversion is not generated, falls back to original
- If media is a string, returns it as-is
- Otherwise returns empty string
Example:
// Component properties
protected string $conversion = 'thumb';
// Media with conversion
$url = $this->getFileUrl($media);
// Returns: "https://example.com/media/1/conversions/avatar-thumb.jpg"
// Media without conversion
$this->conversion = '';
$url = $this->getFileUrl($media);
// Returns: "https://example.com/media/1/avatar.jpg"
// String URL
$url = $this->getFileUrl('https://example.com/image.jpg');
// Returns: "https://example.com/image.jpg"
Usage in Components
Image Upload Component
use Javaabu\Forms\Support\HandlesMediaValues;
use Javaabu\Forms\Views\Components\Component;
class ImageUpload extends Component
{
use HandlesMediaValues;
public string $name;
public $value; // Will contain the image URL
public string $fileName = '';
protected string $collection = 'images';
protected string $conversion = '';
protected bool $ignoreAccessor = false;
protected string $view = 'image-upload';
public function __construct(
string $name,
string $collection = 'images',
string $conversion = '',
bool $ignoreAccessor = false,
$bind = null
) {
parent::__construct();
$this->name = $name;
$this->collection = $collection;
$this->conversion = $conversion;
$this->ignoreAccessor = $ignoreAccessor;
$this->bindModel($bind);
$this->setValue($name, $bind);
}
}
File Upload Component
use Javaabu\Forms\Support\HandlesMediaValues;
use Javaabu\Forms\Views\Components\Component;
class FileUpload extends Component
{
use HandlesMediaValues;
public string $name;
public $value;
public string $fileName = '';
protected string $collection = 'documents';
protected string $conversion = '';
protected bool $ignoreAccessor = false;
public function __construct(
string $name,
string $collection = 'documents',
$bind = null
) {
parent::__construct();
$this->name = $name;
$this->collection = $collection;
$this->bindModel($bind);
$this->setValue($name, $bind);
}
public function hasFile(): bool
{
return !empty($this->value);
}
}
Blade Component Usage
Basic Image Upload
@model($post)
<x-forms::image-upload
name="featured_image"
collection="featured-images"
/>
{{-- Displays existing image from $post->getMedia('featured-images')->first() --}}
@endmodel
Image with Conversion
@model($user)
<x-forms::image-upload
name="avatar"
collection="avatars"
conversion="thumb"
/>
{{-- Displays thumbnail conversion of avatar --}}
@endmodel
File Upload
@model($document)
<x-forms::file-upload
name="attachment"
collection="attachments"
/>
{{-- Shows filename: {{ $fileName }} --}}
{{-- Download URL: {{ $value }} --}}
@endmodel
use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class Post extends Model implements HasMedia
{
use InteractsWithMedia;
public function registerMediaCollections(): void
{
$this->addMediaCollection('featured-images')
->singleFile()
->registerMediaConversions(function (Media $media) {
$this->addMediaConversion('thumb')
->width(200)
->height(200);
$this->addMediaConversion('banner')
->width(1200)
->height(400);
});
$this->addMediaCollection('attachments')
->acceptsMimeTypes(['application/pdf', 'application/msword']);
}
}
Blade View Template Example
{{-- resources/views/components/image-upload.blade.php --}}
<div class="form-group">
<label for="{{ $id() }}">{{ $label() }}</label>
@if($value)
<div class="current-image">
<img src="{{ $value }}" alt="{{ $fileName }}" class="img-thumbnail">
<p>Current file: {{ $fileName }}</p>
</div>
@endif
<input
type="file"
id="{{ $id() }}"
name="{{ $name }}"
accept="image/*"
class="form-control"
/>
@if($value)
<small class="form-text text-muted">
Leave empty to keep current image
</small>
@endif
</div>
Ignoring Accessors
Set ignoreAccessor to true when you want to bypass model accessors:
class ImageUpload extends Component
{
use HandlesMediaValues;
public function __construct(
string $name,
string $collection,
bool $ignoreAccessor = false
) {
// ...
$this->ignoreAccessor = $ignoreAccessor;
}
}
Usage:
@model($user)
{{-- Use accessor if defined --}}
<x-forms::image-upload name="avatar" collection="avatars" />
{{-- Skip accessor, get media directly --}}
<x-forms::image-upload
name="avatar"
collection="avatars"
:ignoreAccessor="true"
/>
@endmodel
Complete Example
use Javaabu\Forms\Support\HandlesMediaValues;
use Javaabu\Forms\Views\Components\Component;
class ImageUpload extends Component
{
use HandlesMediaValues;
public string $name;
public string $label;
public $value;
public string $fileName = '';
public array $acceptedTypes = [];
protected string $collection = 'images';
protected string $conversion = '';
protected bool $ignoreAccessor = false;
protected string $view = 'image-upload';
public function __construct(
string $name,
string $label = '',
string $collection = 'images',
string $conversion = '',
array $acceptedTypes = [],
bool $ignoreAccessor = false,
$bind = null,
string $framework = ''
) {
parent::__construct($framework);
$this->name = $name;
$this->label = $label;
$this->collection = $collection;
$this->conversion = $conversion;
$this->acceptedTypes = $acceptedTypes;
$this->ignoreAccessor = $ignoreAccessor;
$this->bindModel($bind);
$this->setValue($name, $bind);
}
public function accept(): string
{
return empty($this->acceptedTypes)
? 'image/*'
: implode(',', $this->acceptedTypes);
}
public function hasCurrentFile(): bool
{
return !empty($this->value);
}
public function getPreviewUrl(): string
{
return $this->value ?? '';
}
}