Closed lukinovec closed 2 years ago
How did you resolve the issue with the other methods/temporary URLs etc? Just by extending the class instead of creating a new one that implements the interface?
How did you resolve the issue with the other methods/temporary URLs etc? Just by extending the class instead of creating a new one that implements the interface?
Yeah. If the custom command extended the abstract class (BaseUrlGenerator
) instead, we'd copy the methods from the DefaultUrlGenerator
class (except getUrl()
which we'd override) because it looks like the methods are working as expected. Extending the class seems better than doing that
Hi, I encountered an issue where media files were not being served correctly in a multitenant Laravel application, resulting in 404 errors.
Initially, I followed the standard approach by creating a custom UrlGenerator
class to handle the URL generation.
Even with this setup, media files continued to return 404 errors, indicating that the generated URLs weren't correctly resolving to the tenant-specific storage paths.
Potential Route Conflict: I also identified that a custom route I had defined might be causing a conflict:
Route::get('{page:slug}', [PageController::class, 'show'])->name('page.show');
This route is very general and could be intercepting requests meant for media files, especially if the filename or media path resembles a slug
. This could explain why the media files were not being served as expected.
To resolve this, I made the following adjustments:
Custom Tenant-Aware URL Generator: I refined the TenantAwareUrlGenerator
class to ensure it generates URLs that correctly point to tenant-specific storage:
<?php
namespace App\Supports;
use Spatie\MediaLibrary\Support\UrlGenerator\DefaultUrlGenerator;
class TenantAwareUrlGenerator extends DefaultUrlGenerator
{
public function getUrl(): string
{
$url = asset('storage/' . $this->getPathRelativeToRoot());
return $this->versionUrl($url);
}
}
Route for Serving Media Files: I defined a dedicated route to serve media files, ensuring that the tenant context is respected and files are correctly served:
<?php
use Illuminate\Support\Facades\Route;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
use Stancl\Tenancy\Middleware\InitializeTenancyByDomain;
Route::middleware(['web', 'universal', InitializeTenancyByDomain::class])->group(function () {
Route::get('/storage/{mediaId}/{filename}', function ($mediaId, $filename) {
// Find the media record by ID
$media = Media::find($mediaId);
if (! $media) {
abort(404, 'File not found');
}
// Get the path to the file within the tenant's storage
$path = $media->getPath();
// Validate the filename to avoid potential path traversal attacks
if (basename($path) !== $filename) {
abort(404, 'File not found');
}
// Serve the file from the tenant's storage
return response()->file($path);
});
});
These changes resolved the 404 errors and ensured that media files are correctly served from tenant-specific directories. This approach integrates seamlessly with the multitenant setup.
https://github.com/stancl/tenancy-docs/issues/78