Fix EV company logo upload to use public disk
Logos were being written to the default filesystem disk, which resolves to storage/app/private and isn't web-servable, so the frontend couldn't load the image. Store logos on the public disk (storage/app/public, symlinked to public/storage) instead, and resolve logoUrl() against that disk explicitly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015HaT8a5ZWh45JkjTLPWeaP
This commit is contained in:
@@ -32,7 +32,9 @@ class EvCompanyForm
|
|||||||
->required()
|
->required()
|
||||||
->maxLength(255),
|
->maxLength(255),
|
||||||
FileUpload::make('logo')
|
FileUpload::make('logo')
|
||||||
->image(),
|
->image()
|
||||||
|
->disk('public')
|
||||||
|
->directory('logos'),
|
||||||
Toggle::make('is_active')
|
Toggle::make('is_active')
|
||||||
->required()
|
->required()
|
||||||
->default(true),
|
->default(true),
|
||||||
|
|||||||
@@ -78,9 +78,10 @@ class EvCompany extends Model
|
|||||||
/**
|
/**
|
||||||
* `logo` is stored as the disk-relative path Filament's FileUpload
|
* `logo` is stored as the disk-relative path Filament's FileUpload
|
||||||
* writes (e.g. "logos/xxx.png"), not a URL — API consumers need a full
|
* writes (e.g. "logos/xxx.png"), not a URL — API consumers need a full
|
||||||
* absolute URL to render it directly. Guards against the disk itself
|
* absolute URL to render it directly. Logos are always written to the
|
||||||
* already returning an absolute URL (e.g. an s3 disk), so this stays
|
* "public" disk (storage/app/public, symlinked to public/storage) so
|
||||||
* correct if the storage disk ever changes from local.
|
* the frontend can actually reach the image, regardless of what the
|
||||||
|
* app's default filesystem disk is configured to.
|
||||||
*/
|
*/
|
||||||
public function logoUrl(): Attribute
|
public function logoUrl(): Attribute
|
||||||
{
|
{
|
||||||
@@ -90,7 +91,7 @@ class EvCompany extends Model
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$url = Storage::disk(config('filesystems.default'))->url($this->logo);
|
$url = Storage::disk('public')->url($this->logo);
|
||||||
|
|
||||||
return str($url)->startsWith(['http://', 'https://']) ? $url : url($url);
|
return str($url)->startsWith(['http://', 'https://']) ? $url : url($url);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ test('returns the company logo as a full absolute url', function () {
|
|||||||
$this->withHeader('Authorization', "Bearer {$this->token}")
|
$this->withHeader('Authorization', "Bearer {$this->token}")
|
||||||
->getJson('/api/v1/companies')
|
->getJson('/api/v1/companies')
|
||||||
->assertSuccessful()
|
->assertSuccessful()
|
||||||
->assertJsonFragment(['logo' => url(Storage::disk(config('filesystems.default'))->url($company->logo))]);
|
->assertJsonFragment(['logo' => url(Storage::disk('public')->url($company->logo))]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('returns a null logo when the company has none', function () {
|
test('returns a null logo when the company has none', function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user