Remove S3 storage support and standardize local media handling

This commit is contained in:
fatihalp 2026-03-19 23:42:57 +03:00
parent 6b3a8b8581
commit 057620b715
26 changed files with 224 additions and 341 deletions

View File

@ -4,21 +4,18 @@ namespace Modules\Admin\Filament\Pages;
use BackedEnum; use BackedEnum;
use Filament\Forms\Components\FileUpload; use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Hidden;
use Filament\Forms\Components\Select; use Filament\Forms\Components\Select;
use Filament\Forms\Components\TagsInput; use Filament\Forms\Components\TagsInput;
use Filament\Forms\Components\Textarea; use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput; use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle; use Filament\Forms\Components\Toggle;
use Filament\Pages\SettingsPage; use Filament\Pages\SettingsPage;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Modules\Admin\Support\HomeSlideFormSchema; use Modules\Admin\Support\HomeSlideFormSchema;
use Modules\Location\Support\CountryCodeManager; use Modules\Location\Support\CountryCodeManager;
use Modules\S3\Support\MediaStorage;
use Modules\Site\App\Settings\GeneralSettings; use Modules\Site\App\Settings\GeneralSettings;
use Modules\Site\App\Support\HomeSlideDefaults; use Modules\Site\App\Support\HomeSlideDefaults;
use Modules\Site\App\Support\LocalMedia;
use Tapp\FilamentCountryCodeField\Forms\Components\CountryCodeSelect; use Tapp\FilamentCountryCodeField\Forms\Components\CountryCodeSelect;
use UnitEnum; use UnitEnum;
use Ysfkaya\FilamentPhoneInput\Forms\PhoneInput; use Ysfkaya\FilamentPhoneInput\Forms\PhoneInput;
@ -44,15 +41,8 @@ class ManageGeneralSettings extends SettingsPage
return [ return [
'site_name' => filled($data['site_name'] ?? null) ? $data['site_name'] : $defaults['site_name'], 'site_name' => filled($data['site_name'] ?? null) ? $data['site_name'] : $defaults['site_name'],
'site_description' => filled($data['site_description'] ?? null) ? $data['site_description'] : $defaults['site_description'], 'site_description' => filled($data['site_description'] ?? null) ? $data['site_description'] : $defaults['site_description'],
'media_disk' => MediaStorage::normalizeDriver($data['media_disk'] ?? $defaults['media_disk']), 'home_slides' => $this->normalizeHomeSlides($data['home_slides'] ?? $defaults['home_slides']),
'home_slides' => $this->normalizeHomeSlides(
$data['home_slides'] ?? $defaults['home_slides'],
MediaStorage::storedDisk('public'),
),
'site_logo' => $data['site_logo'] ?? null, 'site_logo' => $data['site_logo'] ?? null,
'site_logo_disk' => filled($data['site_logo'] ?? null)
? MediaStorage::storedDisk($data['site_logo_disk'] ?? 'public')
: null,
'sender_name' => filled($data['sender_name'] ?? null) ? $data['sender_name'] : $defaults['sender_name'], 'sender_name' => filled($data['sender_name'] ?? null) ? $data['sender_name'] : $defaults['sender_name'],
'sender_email' => filled($data['sender_email'] ?? null) ? $data['sender_email'] : $defaults['sender_email'], 'sender_email' => filled($data['sender_email'] ?? null) ? $data['sender_email'] : $defaults['sender_email'],
'default_language' => filled($data['default_language'] ?? null) ? $data['default_language'] : $defaults['default_language'], 'default_language' => filled($data['default_language'] ?? null) ? $data['default_language'] : $defaults['default_language'],
@ -77,14 +67,7 @@ class ManageGeneralSettings extends SettingsPage
protected function mutateFormDataBeforeSave(array $data): array protected function mutateFormDataBeforeSave(array $data): array
{ {
$mediaDriver = MediaStorage::normalizeDriver($data['media_disk'] ?? null); $data['home_slides'] = $this->normalizeHomeSlides($data['home_slides'] ?? []);
$mediaDisk = MediaStorage::diskFromDriver($mediaDriver);
$data['media_disk'] = $mediaDriver;
$data['home_slides'] = $this->normalizeHomeSlides($data['home_slides'] ?? [], $mediaDisk);
$data['site_logo_disk'] = MediaStorage::managesPath($data['site_logo'] ?? null)
? MediaStorage::storedDisk($data['site_logo_disk'] ?? null, $mediaDriver)
: null;
$data['currencies'] = $this->normalizeCurrencies($data['currencies'] ?? []); $data['currencies'] = $this->normalizeCurrencies($data['currencies'] ?? []);
return $data; return $data;
@ -106,32 +89,16 @@ class ManageGeneralSettings extends SettingsPage
->default($defaults['site_description']) ->default($defaults['site_description'])
->rows(3) ->rows(3)
->maxLength(500), ->maxLength(500),
Select::make('media_disk')
->label('Media Storage')
->options(MediaStorage::options())
->default($defaults['media_disk'])
->required()
->native(false)
->helperText('Storage driver used for listing images, videos, the site logo, and home slide visuals.'),
HomeSlideFormSchema::make( HomeSlideFormSchema::make(
$defaults['home_slides'], $defaults['home_slides'],
fn ($state): array => $this->normalizeHomeSlides($state, MediaStorage::activeDisk()), fn ($state): array => $this->normalizeHomeSlides($state),
), ),
Hidden::make('site_logo_disk'),
FileUpload::make('site_logo') FileUpload::make('site_logo')
->label('Site Logo') ->label('Site Logo')
->image() ->image()
->disk(fn (Get $get): string => MediaStorage::storedDisk($get('site_logo_disk'), $get('media_disk'))) ->disk(LocalMedia::disk())
->directory('settings') ->directory('settings')
->visibility('public') ->visibility('public'),
->afterStateUpdated(function (Get $get, Set $set, mixed $state): void {
$set(
'site_logo_disk',
MediaStorage::managesPath($state)
? MediaStorage::diskFromDriver($get('media_disk'))
: null,
);
}),
TextInput::make('sender_name') TextInput::make('sender_name')
->label('Sender Name') ->label('Sender Name')
->default($defaults['sender_name']) ->default($defaults['sender_name'])
@ -242,9 +209,7 @@ class ManageGeneralSettings extends SettingsPage
return [ return [
'site_name' => $siteName, 'site_name' => $siteName,
'site_description' => 'A fast and secure marketplace for buying and selling.', 'site_description' => 'A fast and secure marketplace for buying and selling.',
'media_disk' => MediaStorage::defaultDriver(),
'home_slides' => $this->defaultHomeSlides(), 'home_slides' => $this->defaultHomeSlides(),
'site_logo_disk' => null,
'sender_name' => $siteName, 'sender_name' => $siteName,
'sender_email' => (string) config('mail.from.address', 'info@'.$siteHost), 'sender_email' => (string) config('mail.from.address', 'info@'.$siteHost),
'default_language' => in_array(config('app.locale'), array_keys($this->localeOptions()), true) ? (string) config('app.locale') : 'en', 'default_language' => in_array(config('app.locale'), array_keys($this->localeOptions()), true) ? (string) config('app.locale') : 'en',
@ -292,8 +257,8 @@ class ManageGeneralSettings extends SettingsPage
return HomeSlideDefaults::defaults(); return HomeSlideDefaults::defaults();
} }
private function normalizeHomeSlides(mixed $state, ?string $defaultDisk = null): array private function normalizeHomeSlides(mixed $state): array
{ {
return HomeSlideDefaults::normalize($state, $defaultDisk); return HomeSlideDefaults::normalize($state);
} }
} }

View File

@ -3,13 +3,10 @@
namespace Modules\Admin\Support; namespace Modules\Admin\Support;
use Filament\Forms\Components\FileUpload; use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Hidden;
use Filament\Forms\Components\Repeater; use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Textarea; use Filament\Forms\Components\Textarea;
use Filament\Schemas\Components\Utilities\Get; use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Utilities\Set; use Modules\Site\App\Support\LocalMedia;
use Modules\S3\Support\MediaStorage;
final class HomeSlideFormSchema final class HomeSlideFormSchema
{ {
@ -19,24 +16,15 @@ final class HomeSlideFormSchema
->label('Homepage Slides') ->label('Homepage Slides')
->helperText('Use 1 to 5 slides. Upload a wide image for each slide to improve the hero area.') ->helperText('Use 1 to 5 slides. Upload a wide image for each slide to improve the hero area.')
->schema([ ->schema([
Hidden::make('disk'),
FileUpload::make('image_path') FileUpload::make('image_path')
->label('Slide Image') ->label('Slide Image')
->image() ->image()
->disk(fn (Get $get): string => MediaStorage::storedDisk($get('disk'), self::mediaDriver($get))) ->disk(LocalMedia::disk())
->directory('home-slides') ->directory('home-slides')
->visibility('public') ->visibility('public')
->imageEditor() ->imageEditor()
->imagePreviewHeight('200') ->imagePreviewHeight('200')
->helperText('Recommended: 1600x1000 or wider.') ->helperText('Recommended: 1600x1000 or wider.')
->afterStateUpdated(function (Get $get, Set $set, mixed $state): void {
$set(
'disk',
MediaStorage::managesPath($state)
? MediaStorage::diskFromDriver(self::mediaDriver($get))
: null,
);
})
->columnSpanFull(), ->columnSpanFull(),
TextInput::make('badge') TextInput::make('badge')
->label('Badge') ->label('Badge')
@ -72,13 +60,4 @@ final class HomeSlideFormSchema
->itemLabel(fn (array $state): string => filled($state['title'] ?? null) ? (string) $state['title'] : 'New Slide') ->itemLabel(fn (array $state): string => filled($state['title'] ?? null) ? (string) $state['title'] : 'New Slide')
->dehydrateStateUsing(fn ($state) => $normalizeSlides($state)); ->dehydrateStateUsing(fn ($state) => $normalizeSlides($state));
} }
private static function mediaDriver(Get $get): string
{
$driver = $get('../../media_disk');
return is_string($driver) && trim($driver) !== ''
? MediaStorage::normalizeDriver($driver)
: MediaStorage::activeDriver();
}
} }

View File

@ -11,9 +11,11 @@ use Illuminate\Support\Carbon;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Modules\Category\Models\Category; use Modules\Category\Models\Category;
use Modules\Conversation\App\Models\Conversation;
use Modules\Listing\States\ListingStatus; use Modules\Listing\States\ListingStatus;
use Modules\Listing\Support\ListingImageViewData; use Modules\Listing\Support\ListingImageViewData;
use Modules\Listing\Support\ListingPanelHelper; use Modules\Listing\Support\ListingPanelHelper;
use Modules\Site\App\Support\LocalMedia;
use Modules\User\App\Models\User; use Modules\User\App\Models\User;
use Modules\Video\Enums\VideoStatus; use Modules\Video\Enums\VideoStatus;
use Modules\Video\Models\Video; use Modules\Video\Models\Video;
@ -63,23 +65,23 @@ class Listing extends Model implements HasMedia
public function category() public function category()
{ {
return $this->belongsTo(\Modules\Category\Models\Category::class); return $this->belongsTo(Category::class);
} }
public function user() public function user()
{ {
return $this->belongsTo(\Modules\User\App\Models\User::class); return $this->belongsTo(User::class);
} }
public function favoritedByUsers() public function favoritedByUsers()
{ {
return $this->belongsToMany(\Modules\User\App\Models\User::class, 'favorite_listings') return $this->belongsToMany(User::class, 'favorite_listings')
->withTimestamps(); ->withTimestamps();
} }
public function conversations() public function conversations()
{ {
return $this->hasMany(\Modules\Conversation\App\Models\Conversation::class); return $this->hasMany(Conversation::class);
} }
public function videos() public function videos()
@ -453,6 +455,7 @@ class Listing extends Model implements HasMedia
return; return;
} }
$disk = $this->mediaDisk();
$targetFileName = trim((string) ($fileName ?: basename($absolutePath))); $targetFileName = trim((string) ($fileName ?: basename($absolutePath)));
$existingMediaItems = $this->getMedia('listing-images'); $existingMediaItems = $this->getMedia('listing-images');
@ -462,7 +465,7 @@ class Listing extends Model implements HasMedia
if ( if (
$existingMedia $existingMedia
&& (string) $existingMedia->file_name === $targetFileName && (string) $existingMedia->file_name === $targetFileName
&& (string) $existingMedia->disk === 'public' && (string) $existingMedia->disk === $disk
) { ) {
try { try {
if (is_file($existingMedia->getPath())) { if (is_file($existingMedia->getPath())) {
@ -474,12 +477,25 @@ class Listing extends Model implements HasMedia
} }
$this->clearMediaCollection('listing-images'); $this->clearMediaCollection('listing-images');
$this->attachListingImage($absolutePath, $targetFileName, $disk);
}
public function attachListingImage(string $absolutePath, string $fileName, ?string $disk = null): void
{
if (! is_file($absolutePath)) {
return;
}
$targetDisk = is_string($disk) && trim($disk) !== ''
? trim($disk)
: $this->mediaDisk();
$this $this
->addMedia($absolutePath) ->addMedia($absolutePath)
->usingFileName($targetFileName) ->usingFileName(trim($fileName))
->withCustomProperties(self::mediaCustomProperties())
->preservingOriginal() ->preservingOriginal()
->toMediaCollection('listing-images', 'public'); ->toMediaCollection('listing-images', $targetDisk);
} }
public function statusValue(): string public function statusValue(): string
@ -571,7 +587,7 @@ class Listing extends Model implements HasMedia
public function registerMediaCollections(): void public function registerMediaCollections(): void
{ {
$this->addMediaCollection('listing-images')->useDisk('public'); $this->addMediaCollection('listing-images')->useDisk($this->mediaDisk());
} }
public function registerMediaConversions(?Media $media = null): void public function registerMediaConversions(?Media $media = null): void
@ -644,6 +660,37 @@ class Listing extends Model implements HasMedia
return str_contains($argv, 'db:seed') || str_contains($argv, '--seed'); return str_contains($argv, 'db:seed') || str_contains($argv, '--seed');
} }
private function mediaDisk(): string
{
return LocalMedia::disk();
}
public static function mediaCustomProperties(): array
{
$scope = static::mediaPathScope();
return $scope !== null
? ['path_scope' => $scope]
: [];
}
public static function mediaPathScope(): ?string
{
$connection = (string) config('database.default', 'pgsql');
$searchPath = config("database.connections.{$connection}.search_path");
$value = is_array($searchPath)
? implode('_', $searchPath)
: (string) $searchPath;
$scope = (string) Str::of($value)
->before(',')
->trim()
->lower()
->replaceMatches('/[^a-z0-9_]+/', '_')
->trim('_');
return $scope !== '' ? $scope : null;
}
protected function location(): Attribute protected function location(): Attribute
{ {
return Attribute::make( return Attribute::make(

View File

@ -23,6 +23,7 @@ use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Filters\TernaryFilter; use Filament\Tables\Filters\TernaryFilter;
use Filament\Tables\Table; use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Str;
use Modules\Admin\Support\Filament\ResourceTableActions; use Modules\Admin\Support\Filament\ResourceTableActions;
use Modules\Category\Models\Category; use Modules\Category\Models\Category;
use Modules\Listing\Models\Listing; use Modules\Listing\Models\Listing;
@ -31,6 +32,7 @@ use Modules\Listing\Support\ListingPanelHelper;
use Modules\Location\Models\City; use Modules\Location\Models\City;
use Modules\Location\Models\Country; use Modules\Location\Models\Country;
use Modules\Location\Support\CountryCodeManager; use Modules\Location\Support\CountryCodeManager;
use Modules\Site\App\Support\LocalMedia;
use Modules\Video\Support\Filament\VideoFormSchema; use Modules\Video\Support\Filament\VideoFormSchema;
use Ysfkaya\FilamentPhoneInput\Forms\PhoneInput; use Ysfkaya\FilamentPhoneInput\Forms\PhoneInput;
@ -39,7 +41,7 @@ class AdminListingResourceSchema
public static function form(): array public static function form(): array
{ {
return [ return [
TextInput::make('title')->required()->maxLength(255)->live(onBlur: true)->afterStateUpdated(fn ($state, $set) => $set('slug', \Illuminate\Support\Str::slug($state).'-'.\Illuminate\Support\Str::random(4))), TextInput::make('title')->required()->maxLength(255)->live(onBlur: true)->afterStateUpdated(fn ($state, $set) => $set('slug', Str::slug($state).'-'.Str::random(4))),
TextInput::make('slug')->required()->maxLength(255)->unique(ignoreRecord: true), TextInput::make('slug')->required()->maxLength(255)->unique(ignoreRecord: true),
Textarea::make('description')->rows(4), Textarea::make('description')->rows(4),
TextInput::make('price') TextInput::make('price')
@ -101,6 +103,8 @@ class AdminListingResourceSchema
->columnSpanFull(), ->columnSpanFull(),
SpatieMediaLibraryFileUpload::make('images') SpatieMediaLibraryFileUpload::make('images')
->collection('listing-images') ->collection('listing-images')
->disk(fn (): string => LocalMedia::disk())
->customProperties(fn (): array => Listing::mediaCustomProperties())
->multiple() ->multiple()
->image() ->image()
->reorderable(), ->reorderable(),

View File

@ -18,7 +18,7 @@ use Modules\Listing\Support\ListingPanelHelper;
use Modules\Listing\Support\QuickListingCategorySuggester; use Modules\Listing\Support\QuickListingCategorySuggester;
use Modules\Location\Models\City; use Modules\Location\Models\City;
use Modules\Location\Models\Country; use Modules\Location\Models\Country;
use Modules\S3\Support\MediaStorage; use Modules\Site\App\Support\LocalMedia;
use Modules\User\App\Models\Profile; use Modules\User\App\Models\Profile;
use Modules\Video\Models\Video; use Modules\Video\Models\Video;
use Throwable; use Throwable;
@ -641,10 +641,11 @@ class PanelQuickListingForm extends Component
continue; continue;
} }
$listing $listing->attachListingImage(
->addMedia($photo->getRealPath()) $photo->getRealPath(),
->usingFileName($photo->getClientOriginalName()) $photo->getClientOriginalName(),
->toMediaCollection('listing-images', $mediaDisk); $mediaDisk
);
} }
foreach ($this->videos as $index => $video) { foreach ($this->videos as $index => $video) {
@ -757,7 +758,7 @@ class PanelQuickListingForm extends Component
private function frontendMediaDisk(): string private function frontendMediaDisk(): string
{ {
return (string) config('media_storage.local_disk', MediaStorage::diskFromDriver(MediaStorage::DRIVER_LOCAL)); return LocalMedia::disk();
} }
private function handlePublishValidationFailure(ValidationException $exception): void private function handlePublishValidationFailure(ValidationException $exception): void

View File

@ -1,13 +0,0 @@
<?php
namespace Modules\S3\Providers;
use Illuminate\Support\ServiceProvider;
class S3ServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->mergeConfigFrom(module_path('S3', 'config/s3.php'), 'media_storage');
}
}

View File

@ -1,145 +0,0 @@
<?php
namespace Modules\S3\Support;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Storage;
use Modules\Site\App\Settings\GeneralSettings;
use Throwable;
final class MediaStorage
{
public const DRIVER_LOCAL = 'local';
public const DRIVER_S3 = 's3';
public static function options(): array
{
return [
self::DRIVER_S3 => 'S3 Object Storage',
self::DRIVER_LOCAL => 'Local Storage',
];
}
public static function defaultDriver(): string
{
return self::coerceDriver(config('media_storage.default_driver'))
?? self::DRIVER_S3;
}
public static function activeDriver(): string
{
if (! self::hasSettingsTable()) {
return self::defaultDriver();
}
try {
return self::normalizeDriver(app(GeneralSettings::class)->media_disk ?? null);
} catch (Throwable) {
return self::defaultDriver();
}
}
public static function normalizeDriver(mixed $driver): string
{
return self::coerceDriver($driver) ?? self::defaultDriver();
}
public static function diskFromDriver(mixed $driver = null): string
{
return self::normalizeDriver($driver) === self::DRIVER_LOCAL
? (string) config('media_storage.local_disk', 'public')
: (string) config('media_storage.cloud_disk', 's3');
}
public static function activeDisk(): string
{
return self::diskFromDriver(self::activeDriver());
}
public static function storedDisk(mixed $disk = null, mixed $driver = null): string
{
if (is_string($disk) && trim($disk) !== '') {
return self::diskFromDriver(trim($disk) === 'public' ? self::DRIVER_LOCAL : trim($disk));
}
return self::diskFromDriver($driver);
}
public static function managesPath(mixed $path): bool
{
$path = is_string($path) ? trim($path) : '';
if ($path === '') {
return false;
}
return ! self::isExternalUrl($path) && ! self::isAssetPath($path);
}
public static function url(mixed $path, mixed $disk = null): ?string
{
$path = is_string($path) ? trim($path) : '';
if ($path === '') {
return null;
}
if (self::isExternalUrl($path)) {
return $path;
}
if (self::isAssetPath($path)) {
return asset($path);
}
return Storage::disk(self::storedDisk($disk))->url($path);
}
public static function applyRuntimeConfig(): void
{
$disk = self::activeDisk();
config([
'filesystems.default' => $disk,
'filemanager.disk' => $disk,
'filament.default_filesystem_disk' => $disk,
'media-library.disk_name' => $disk,
'video.disk' => $disk,
]);
}
private static function coerceDriver(mixed $driver): ?string
{
if (! is_string($driver)) {
return null;
}
return match (strtolower(trim($driver))) {
self::DRIVER_LOCAL, 'public' => self::DRIVER_LOCAL,
self::DRIVER_S3 => self::DRIVER_S3,
default => null,
};
}
private static function hasSettingsTable(): bool
{
try {
return Schema::hasTable('settings');
} catch (Throwable) {
return false;
}
}
private static function isAssetPath(string $path): bool
{
return str_starts_with($path, 'images/');
}
private static function isExternalUrl(string $path): bool
{
return str_starts_with($path, 'http://')
|| str_starts_with($path, 'https://')
|| str_starts_with($path, '//');
}
}

View File

@ -1,7 +0,0 @@
<?php
return [
'default_driver' => env('MEDIA_DISK', env('FILESYSTEM_DISK', 's3')),
'local_disk' => env('LOCAL_MEDIA_DISK', 'public'),
'cloud_disk' => env('CLOUD_MEDIA_DISK', 's3'),
];

View File

@ -1,12 +0,0 @@
{
"name": "S3",
"alias": "s3",
"description": "Media storage selection and S3 object storage integration",
"keywords": [],
"priority": 0,
"providers": [
"Modules\\S3\\Providers\\S3ServiceProvider"
],
"aliases": {},
"files": []
}

View File

@ -4,9 +4,24 @@ namespace Modules\Site\App\Providers;
use Illuminate\Support\Facades\View; use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use Modules\Site\App\Support\LocalMedia;
use Modules\Site\App\Support\ScopedMediaPathGenerator;
class SiteServiceProvider extends ServiceProvider class SiteServiceProvider extends ServiceProvider
{ {
public function register(): void
{
config([
'filesystems.default' => LocalMedia::disk(),
'filament.default_filesystem_disk' => LocalMedia::disk(),
'filemanager.storage_mode.disk' => LocalMedia::disk(),
'filemanager.upload.disk' => LocalMedia::disk(),
'media-library.disk_name' => LocalMedia::disk(),
'media-library.path_generator' => ScopedMediaPathGenerator::class,
'video.disk' => LocalMedia::disk(),
]);
}
public function boot(): void public function boot(): void
{ {
$viewPath = module_path('Site', 'resources/views'); $viewPath = module_path('Site', 'resources/views');

View File

@ -10,12 +10,8 @@ class GeneralSettings extends Settings
public string $site_description; public string $site_description;
public string $media_disk;
public ?string $site_logo; public ?string $site_logo;
public ?string $site_logo_disk;
public string $default_language; public string $default_language;
public string $default_country_code; public string $default_country_code;

View File

@ -3,7 +3,6 @@
namespace Modules\Site\App\Support; namespace Modules\Site\App\Support;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Modules\S3\Support\MediaStorage;
final class HomeSlideDefaults final class HomeSlideDefaults
{ {
@ -17,7 +16,6 @@ final class HomeSlideDefaults
'primary_button_text' => 'Browse Listings', 'primary_button_text' => 'Browse Listings',
'secondary_button_text' => 'Post Listing', 'secondary_button_text' => 'Post Listing',
'image_path' => 'images/home-slides/slide-marketplace.svg', 'image_path' => 'images/home-slides/slide-marketplace.svg',
'disk' => null,
], ],
[ [
'badge' => 'Fresh Categories', 'badge' => 'Fresh Categories',
@ -26,7 +24,6 @@ final class HomeSlideDefaults
'primary_button_text' => 'See Categories', 'primary_button_text' => 'See Categories',
'secondary_button_text' => 'Start Now', 'secondary_button_text' => 'Start Now',
'image_path' => 'images/home-slides/slide-categories.svg', 'image_path' => 'images/home-slides/slide-categories.svg',
'disk' => null,
], ],
[ [
'badge' => 'Local Shopping', 'badge' => 'Local Shopping',
@ -35,12 +32,11 @@ final class HomeSlideDefaults
'primary_button_text' => 'Nearby Deals', 'primary_button_text' => 'Nearby Deals',
'secondary_button_text' => 'Sell for Free', 'secondary_button_text' => 'Sell for Free',
'image_path' => 'images/home-slides/slide-local.svg', 'image_path' => 'images/home-slides/slide-local.svg',
'disk' => null,
], ],
]; ];
} }
public static function normalize(mixed $slides, ?string $defaultDisk = null): array public static function normalize(mixed $slides): array
{ {
$defaults = self::defaults(); $defaults = self::defaults();
$source = is_array($slides) ? $slides : []; $source = is_array($slides) ? $slides : [];
@ -48,7 +44,7 @@ final class HomeSlideDefaults
$normalized = collect($source) $normalized = collect($source)
->filter(fn ($slide): bool => is_array($slide)) ->filter(fn ($slide): bool => is_array($slide))
->values() ->values()
->map(function (array $slide, int $index) use ($defaults, $defaultDisk): ?array { ->map(function (array $slide, int $index) use ($defaults): ?array {
$fallback = $defaults[$index] ?? $defaults[array_key_last($defaults)]; $fallback = $defaults[$index] ?? $defaults[array_key_last($defaults)];
$badge = trim((string) ($slide['badge'] ?? '')); $badge = trim((string) ($slide['badge'] ?? ''));
$title = trim((string) ($slide['title'] ?? '')); $title = trim((string) ($slide['title'] ?? ''));
@ -56,9 +52,6 @@ final class HomeSlideDefaults
$primaryButtonText = trim((string) ($slide['primary_button_text'] ?? '')); $primaryButtonText = trim((string) ($slide['primary_button_text'] ?? ''));
$secondaryButtonText = trim((string) ($slide['secondary_button_text'] ?? '')); $secondaryButtonText = trim((string) ($slide['secondary_button_text'] ?? ''));
$imagePath = self::normalizeImagePath($slide['image_path'] ?? null); $imagePath = self::normalizeImagePath($slide['image_path'] ?? null);
$disk = MediaStorage::managesPath($imagePath)
? MediaStorage::storedDisk($slide['disk'] ?? null, $defaultDisk)
: null;
if ($title === '') { if ($title === '') {
return null; return null;
@ -71,7 +64,6 @@ final class HomeSlideDefaults
'primary_button_text' => $primaryButtonText !== '' ? $primaryButtonText : $fallback['primary_button_text'], 'primary_button_text' => $primaryButtonText !== '' ? $primaryButtonText : $fallback['primary_button_text'],
'secondary_button_text' => $secondaryButtonText !== '' ? $secondaryButtonText : $fallback['secondary_button_text'], 'secondary_button_text' => $secondaryButtonText !== '' ? $secondaryButtonText : $fallback['secondary_button_text'],
'image_path' => $imagePath !== '' ? $imagePath : ($fallback['image_path'] ?? null), 'image_path' => $imagePath !== '' ? $imagePath : ($fallback['image_path'] ?? null),
'disk' => $imagePath !== '' ? $disk : ($fallback['disk'] ?? null),
]; ];
}) })
->filter(fn ($slide): bool => is_array($slide)) ->filter(fn ($slide): bool => is_array($slide))

View File

@ -0,0 +1,55 @@
<?php
namespace Modules\Site\App\Support;
use Illuminate\Support\Facades\Storage;
final class LocalMedia
{
public const DISK = 'public';
public static function disk(): string
{
return self::DISK;
}
public static function managesPath(mixed $path): bool
{
$value = is_string($path) ? trim($path) : '';
return $value !== ''
&& ! self::isExternalUrl($value)
&& ! self::isAssetPath($value);
}
public static function url(mixed $path): ?string
{
$value = is_string($path) ? trim($path) : '';
if ($value === '') {
return null;
}
if (self::isExternalUrl($value)) {
return $value;
}
if (self::isAssetPath($value)) {
return asset($value);
}
return Storage::disk(self::DISK)->url($value);
}
private static function isAssetPath(string $path): bool
{
return str_starts_with($path, 'images/');
}
private static function isExternalUrl(string $path): bool
{
return str_starts_with($path, 'http://')
|| str_starts_with($path, 'https://')
|| str_starts_with($path, '//');
}
}

View File

@ -8,7 +8,6 @@ use Illuminate\Support\Facades\View;
use Modules\Category\Models\Category; use Modules\Category\Models\Category;
use Modules\Location\Models\Country; use Modules\Location\Models\Country;
use Modules\Location\Support\CountryCodeManager; use Modules\Location\Support\CountryCodeManager;
use Modules\S3\Support\MediaStorage;
use Modules\Site\App\Settings\GeneralSettings; use Modules\Site\App\Settings\GeneralSettings;
use Modules\User\App\Models\User; use Modules\User\App\Models\User;
use Throwable; use Throwable;
@ -42,12 +41,10 @@ final class RequestAppData
$fallbackAppleClientId = config('services.apple.client_id'); $fallbackAppleClientId = config('services.apple.client_id');
$fallbackAppleClientSecret = config('services.apple.client_secret'); $fallbackAppleClientSecret = config('services.apple.client_secret');
$fallbackDefaultCountryCode = (string) config('app.default_country_code', '+90'); $fallbackDefaultCountryCode = (string) config('app.default_country_code', '+90');
$fallbackMediaDriver = MediaStorage::defaultDriver();
$generalSettings = [ $generalSettings = [
'site_name' => $fallbackName, 'site_name' => $fallbackName,
'site_description' => $fallbackDescription, 'site_description' => $fallbackDescription,
'media_disk' => $fallbackMediaDriver,
'home_slides' => $fallbackHomeSlides, 'home_slides' => $fallbackHomeSlides,
'site_logo_url' => null, 'site_logo_url' => null,
'default_language' => $fallbackLocale, 'default_language' => $fallbackLocale,
@ -94,18 +91,13 @@ final class RequestAppData
$appleClientId = trim((string) ($settings->apple_client_id ?: $fallbackAppleClientId)); $appleClientId = trim((string) ($settings->apple_client_id ?: $fallbackAppleClientId));
$appleClientSecret = trim((string) ($settings->apple_client_secret ?: $fallbackAppleClientSecret)); $appleClientSecret = trim((string) ($settings->apple_client_secret ?: $fallbackAppleClientSecret));
$defaultCountryCode = CountryCodeManager::normalizeCountryCode($settings->default_country_code ?? $fallbackDefaultCountryCode); $defaultCountryCode = CountryCodeManager::normalizeCountryCode($settings->default_country_code ?? $fallbackDefaultCountryCode);
$mediaDriver = MediaStorage::normalizeDriver($settings->media_disk ?? null);
return [ return [
'site_name' => trim((string) ($settings->site_name ?: $fallbackName)), 'site_name' => trim((string) ($settings->site_name ?: $fallbackName)),
'site_description' => trim((string) ($settings->site_description ?: $fallbackDescription)), 'site_description' => trim((string) ($settings->site_description ?: $fallbackDescription)),
'media_disk' => $mediaDriver, 'home_slides' => HomeSlideDefaults::normalize($settings->home_slides ?? []),
'home_slides' => HomeSlideDefaults::normalize(
$settings->home_slides ?? [],
MediaStorage::diskFromDriver($mediaDriver),
),
'site_logo_url' => filled($settings->site_logo) 'site_logo_url' => filled($settings->site_logo)
? MediaStorage::url($settings->site_logo, $settings->site_logo_disk ?? null) ? LocalMedia::url($settings->site_logo)
: null, : null,
'default_language' => $defaultLanguage, 'default_language' => $defaultLanguage,
'default_country_code' => $defaultCountryCode, 'default_country_code' => $defaultCountryCode,
@ -164,8 +156,6 @@ final class RequestAppData
'app.default_country_code' => $generalSettings['default_country_code'] ?? '+90', 'app.default_country_code' => $generalSettings['default_country_code'] ?? '+90',
'app.default_country_iso2' => CountryCodeManager::iso2FromCountryCode($generalSettings['default_country_code'] ?? '+90') ?? 'TR', 'app.default_country_iso2' => CountryCodeManager::iso2FromCountryCode($generalSettings['default_country_code'] ?? '+90') ?? 'TR',
]); ]);
MediaStorage::applyRuntimeConfig();
} }
private function resolveHeaderLocationCountries(): array private function resolveHeaderLocationCountries(): array

View File

@ -0,0 +1,34 @@
<?php
namespace Modules\Site\App\Support;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
use Spatie\MediaLibrary\Support\PathGenerator\PathGenerator;
class ScopedMediaPathGenerator implements PathGenerator
{
public function getPath(Media $media): string
{
return $this->basePath($media).'/';
}
public function getPathForConversions(Media $media): string
{
return $this->basePath($media).'/conversions/';
}
public function getPathForResponsiveImages(Media $media): string
{
return $this->basePath($media).'/responsive-images/';
}
private function basePath(Media $media): string
{
$scope = trim((string) $media->getCustomProperty('path_scope', ''));
$key = (string) $media->getKey();
return $scope !== ''
? $scope.'/'.$key
: $key;
}
}

View File

@ -44,7 +44,7 @@
'subtitle' => $subtitle !== '' ? $subtitle : 'Buy and sell everything in your area', 'subtitle' => $subtitle !== '' ? $subtitle : 'Buy and sell everything in your area',
'primary_button_text' => $primaryButtonText !== '' ? $primaryButtonText : 'Browse Listings', 'primary_button_text' => $primaryButtonText !== '' ? $primaryButtonText : 'Browse Listings',
'secondary_button_text' => $secondaryButtonText !== '' ? $secondaryButtonText : 'Post Listing', 'secondary_button_text' => $secondaryButtonText !== '' ? $secondaryButtonText : 'Post Listing',
'image_url' => \Modules\S3\Support\MediaStorage::url($imagePath, $slide['disk'] ?? null), 'image_url' => \Modules\Site\App\Support\LocalMedia::url($imagePath),
]; ];
}) })
->values(); ->values();

View File

@ -2,6 +2,7 @@
namespace Modules\User\App\Models; namespace Modules\User\App\Models;
use Database\Factories\UserFactory;
use Filament\Models\Contracts\FilamentUser; use Filament\Models\Contracts\FilamentUser;
use Filament\Models\Contracts\HasAvatar; use Filament\Models\Contracts\HasAvatar;
use Filament\Panel; use Filament\Panel;
@ -17,7 +18,7 @@ use Modules\Conversation\App\Models\Conversation;
use Modules\Conversation\App\Models\ConversationMessage; use Modules\Conversation\App\Models\ConversationMessage;
use Modules\Favorite\App\Models\FavoriteSearch; use Modules\Favorite\App\Models\FavoriteSearch;
use Modules\Listing\Models\Listing; use Modules\Listing\Models\Listing;
use Modules\S3\Support\MediaStorage; use Modules\Site\App\Support\LocalMedia;
use Modules\User\App\States\UserStatus; use Modules\User\App\States\UserStatus;
use Spatie\Activitylog\LogOptions; use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity; use Spatie\Activitylog\Traits\LogsActivity;
@ -50,7 +51,7 @@ class User extends Authenticatable implements FilamentUser, HasAvatar
protected static function newFactory(): Factory protected static function newFactory(): Factory
{ {
return \Database\Factories\UserFactory::new(); return UserFactory::new();
} }
public function getActivitylogOptions(): LogOptions public function getActivitylogOptions(): LogOptions
@ -128,21 +129,17 @@ class User extends Authenticatable implements FilamentUser, HasAvatar
$path = trim((string) $this->avatar_url); $path = trim((string) $this->avatar_url);
if (! MediaStorage::managesPath($path)) { if (! LocalMedia::managesPath($path)) {
return MediaStorage::url($path); return LocalMedia::url($path);
} }
$activeDisk = MediaStorage::activeDisk(); $disk = LocalMedia::disk();
if (Storage::disk($activeDisk)->exists($path)) { if (Storage::disk($disk)->exists($path)) {
return Storage::disk($activeDisk)->url($path); return Storage::disk($disk)->url($path);
} }
if ($activeDisk !== 'public' && Storage::disk('public')->exists($path)) { return LocalMedia::url($path);
return Storage::disk('public')->url($path);
}
return MediaStorage::url($path, $activeDisk);
} }
public function getDisplayName(): string public function getDisplayName(): string

View File

@ -9,7 +9,7 @@ use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile; use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
use Modules\Listing\Models\Listing; use Modules\Listing\Models\Listing;
use Modules\S3\Support\MediaStorage; use Modules\Site\App\Support\LocalMedia;
use Modules\User\App\Models\User; use Modules\User\App\Models\User;
use Modules\Video\Enums\VideoStatus; use Modules\Video\Enums\VideoStatus;
use Modules\Video\Jobs\ProcessVideo; use Modules\Video\Jobs\ProcessVideo;
@ -94,7 +94,7 @@ class Video extends Model
public static function createFromTemporaryUpload(Listing $listing, TemporaryUploadedFile $file, array $attributes = []): self public static function createFromTemporaryUpload(Listing $listing, TemporaryUploadedFile $file, array $attributes = []): self
{ {
$disk = (string) ($attributes['disk'] ?? config('video.disk', MediaStorage::activeDisk())); $disk = (string) ($attributes['disk'] ?? config('video.disk', LocalMedia::disk()));
$path = $file->storeAs( $path = $file->storeAs(
trim((string) config('video.upload_directory', 'videos/uploads').'/'.$listing->getKey(), '/'), trim((string) config('video.upload_directory', 'videos/uploads').'/'.$listing->getKey(), '/'),
Str::ulid().'.'.($file->getClientOriginalExtension() ?: $file->guessExtension() ?: 'mp4'), Str::ulid().'.'.($file->getClientOriginalExtension() ?: $file->guessExtension() ?: 'mp4'),
@ -117,7 +117,7 @@ class Video extends Model
public static function createFromUploadedFile(Listing $listing, UploadedFile $file, array $attributes = []): self public static function createFromUploadedFile(Listing $listing, UploadedFile $file, array $attributes = []): self
{ {
$disk = (string) ($attributes['disk'] ?? config('video.disk', MediaStorage::activeDisk())); $disk = (string) ($attributes['disk'] ?? config('video.disk', LocalMedia::disk()));
$path = $file->storeAs( $path = $file->storeAs(
trim((string) config('video.upload_directory', 'videos/uploads').'/'.$listing->getKey(), '/'), trim((string) config('video.upload_directory', 'videos/uploads').'/'.$listing->getKey(), '/'),
Str::ulid().'.'.($file->getClientOriginalExtension() ?: $file->extension() ?: 'mp4'), Str::ulid().'.'.($file->getClientOriginalExtension() ?: $file->extension() ?: 'mp4'),
@ -176,9 +176,9 @@ class Video extends Model
$uploadPath = $this->upload_path; $uploadPath = $this->upload_path;
$this->forceFill([ $this->forceFill([
'disk' => $attributes['disk'] ?? (string) config('video.disk', MediaStorage::activeDisk()), 'disk' => $attributes['disk'] ?? (string) config('video.disk', LocalMedia::disk()),
'path' => $attributes['path'] ?? null, 'path' => $attributes['path'] ?? null,
'upload_disk' => (string) config('video.disk', MediaStorage::activeDisk()), 'upload_disk' => (string) config('video.disk', LocalMedia::disk()),
'upload_path' => null, 'upload_path' => null,
'mime_type' => $attributes['mime_type'] ?? 'video/mp4', 'mime_type' => $attributes['mime_type'] ?? 'video/mp4',
'size' => $attributes['size'] ?? null, 'size' => $attributes['size'] ?? null,
@ -227,14 +227,14 @@ class Video extends Model
$status = $this->currentStatus(); $status = $this->currentStatus();
if (($status !== VideoStatus::Ready) && filled($this->upload_path)) { if (($status !== VideoStatus::Ready) && filled($this->upload_path)) {
return (string) ($this->upload_disk ?: config('video.disk', MediaStorage::activeDisk())); return (string) ($this->upload_disk ?: config('video.disk', LocalMedia::disk()));
} }
if (filled($this->path)) { if (filled($this->path)) {
return (string) ($this->disk ?: config('video.disk', MediaStorage::activeDisk())); return (string) ($this->disk ?: config('video.disk', LocalMedia::disk()));
} }
return (string) ($this->upload_disk ?: config('video.disk', MediaStorage::activeDisk())); return (string) ($this->upload_disk ?: config('video.disk', LocalMedia::disk()));
} }
public function playableUrl(): ?string public function playableUrl(): ?string
@ -355,7 +355,7 @@ class Video extends Model
$this->previousUploadDisk = filled($this->getOriginal('upload_disk')) $this->previousUploadDisk = filled($this->getOriginal('upload_disk'))
? (string) $this->getOriginal('upload_disk') ? (string) $this->getOriginal('upload_disk')
: (string) config('video.disk', MediaStorage::activeDisk()); : (string) config('video.disk', LocalMedia::disk());
$this->previousUploadPath = filled($this->getOriginal('upload_path')) $this->previousUploadPath = filled($this->getOriginal('upload_path'))
? (string) $this->getOriginal('upload_path') ? (string) $this->getOriginal('upload_path')
@ -380,11 +380,11 @@ class Video extends Model
protected function normalizeStatus(): void protected function normalizeStatus(): void
{ {
if (blank($this->disk)) { if (blank($this->disk)) {
$this->disk = (string) config('video.disk', MediaStorage::activeDisk()); $this->disk = (string) config('video.disk', LocalMedia::disk());
} }
if (blank($this->upload_disk)) { if (blank($this->upload_disk)) {
$this->upload_disk = (string) config('video.disk', MediaStorage::activeDisk()); $this->upload_disk = (string) config('video.disk', LocalMedia::disk());
} }
if (! $this->isDirty('upload_path')) { if (! $this->isDirty('upload_path')) {
@ -452,7 +452,7 @@ class Video extends Model
protected function replaceUploadFromUploadedFile(UploadedFile $file): void protected function replaceUploadFromUploadedFile(UploadedFile $file): void
{ {
$disk = (string) config('video.disk', MediaStorage::activeDisk()); $disk = (string) config('video.disk', LocalMedia::disk());
$path = $file->storeAs( $path = $file->storeAs(
trim((string) config('video.upload_directory', 'videos/uploads').'/'.$this->listing_id, '/'), trim((string) config('video.upload_directory', 'videos/uploads').'/'.$this->listing_id, '/'),
Str::ulid().'.'.($file->getClientOriginalExtension() ?: $file->extension() ?: 'mp4'), Str::ulid().'.'.($file->getClientOriginalExtension() ?: $file->extension() ?: 'mp4'),

View File

@ -15,7 +15,7 @@ use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\HtmlString; use Illuminate\Support\HtmlString;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile; use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
use Modules\S3\Support\MediaStorage; use Modules\Site\App\Support\LocalMedia;
use Modules\Video\Models\Video; use Modules\Video\Models\Video;
class VideoFormSchema class VideoFormSchema
@ -127,7 +127,7 @@ class VideoFormSchema
return FileUpload::make('upload_path') return FileUpload::make('upload_path')
->label('Source video') ->label('Source video')
->disk(fn (?Video $record): string => MediaStorage::storedDisk($record?->upload_disk)) ->disk(fn (): string => LocalMedia::disk())
->directory(trim((string) config('video.upload_directory', 'videos/uploads'), '/')) ->directory(trim((string) config('video.upload_directory', 'videos/uploads'), '/'))
->visibility('public') ->visibility('public')
->acceptedFileTypes([ ->acceptedFileTypes([
@ -192,7 +192,7 @@ class VideoFormSchema
protected static function normalizeData(array $data): array protected static function normalizeData(array $data): array
{ {
$data['upload_disk'] = (string) config('video.disk', MediaStorage::activeDisk()); $data['upload_disk'] = (string) config('video.disk', LocalMedia::disk());
if (blank($data['title'] ?? null) && filled($data['upload_path'] ?? null)) { if (blank($data['title'] ?? null) && filled($data['upload_path'] ?? null)) {
$data['title'] = str(pathinfo((string) $data['upload_path'], PATHINFO_FILENAME)) $data['title'] = str(pathinfo((string) $data['upload_path'], PATHINFO_FILENAME))

View File

@ -4,7 +4,7 @@ namespace Modules\Video\Support;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Modules\S3\Support\MediaStorage; use Modules\Site\App\Support\LocalMedia;
use Modules\Video\Models\Video; use Modules\Video\Models\Video;
use RuntimeException; use RuntimeException;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
@ -13,7 +13,7 @@ class VideoTranscoder
{ {
public function transcode(Video $video): array public function transcode(Video $video): array
{ {
$disk = (string) config('video.disk', MediaStorage::activeDisk()); $disk = (string) config('video.disk', LocalMedia::disk());
$inputDisk = Storage::disk((string) ($video->upload_disk ?: $disk)); $inputDisk = Storage::disk((string) ($video->upload_disk ?: $disk));
$outputDisk = Storage::disk($disk); $outputDisk = Storage::disk($disk);
$workspace = storage_path('app/private/video-processing/'.Str::uuid()); $workspace = storage_path('app/private/video-processing/'.Str::uuid());

View File

@ -1,7 +1,7 @@
<?php <?php
return [ return [
'disk' => env('VIDEO_DISK', env('MEDIA_DISK', env('FILESYSTEM_DISK', 's3'))), 'disk' => env('VIDEO_DISK', env('FILESYSTEM_DISK', 'public')),
'upload_directory' => env('VIDEO_UPLOAD_DIRECTORY', 'videos/uploads'), 'upload_directory' => env('VIDEO_UPLOAD_DIRECTORY', 'videos/uploads'),
'processed_directory' => env('VIDEO_PROCESSED_DIRECTORY', 'videos/mobile'), 'processed_directory' => env('VIDEO_PROCESSED_DIRECTORY', 'videos/mobile'),
'queue' => env('VIDEO_QUEUE', 'videos'), 'queue' => env('VIDEO_QUEUE', 'videos'),

View File

@ -9,7 +9,6 @@
"php": "^8.2", "php": "^8.2",
"a909m/filament-statefusion": "^2.3", "a909m/filament-statefusion": "^2.3",
"ariaieboy/filament-currency": "^3.0", "ariaieboy/filament-currency": "^3.0",
"aws/aws-sdk-php": "^3.322",
"bezhansalleh/filament-language-switch": "^4.1", "bezhansalleh/filament-language-switch": "^4.1",
"cheesegrits/filament-google-maps": "^5.0", "cheesegrits/filament-google-maps": "^5.0",
"dutchcodingcompany/filament-developer-logins": "^2.1", "dutchcodingcompany/filament-developer-logins": "^2.1",
@ -23,7 +22,6 @@
"laravel/reverb": "^1.8", "laravel/reverb": "^1.8",
"laravel/sanctum": "^4.3", "laravel/sanctum": "^4.3",
"laravel/tinker": "^2.10.1", "laravel/tinker": "^2.10.1",
"league/flysystem-aws-s3-v3": "^3.25",
"mwguerra/filemanager": "^2.0", "mwguerra/filemanager": "^2.0",
"nwidart/laravel-modules": "^11.0", "nwidart/laravel-modules": "^11.0",
"pxlrbt/filament-activity-log": "^2.1", "pxlrbt/filament-activity-log": "^2.1",

View File

@ -1,9 +1,12 @@
<?php <?php
use MWGuerra\FileManager\Models\FileSystemItem;
use MWGuerra\FileManager\Policies\FileSystemItemPolicy;
return [ return [
'mode' => 'database', // 'database' or 'storage' 'mode' => 'database', // 'database' or 'storage'
'storage_mode' => [ 'storage_mode' => [
'disk' => env('FILEMANAGER_DISK', env('FILESYSTEM_DISK', 'public')), 'disk' => 'public',
'root' => env('FILEMANAGER_ROOT', ''), 'root' => env('FILEMANAGER_ROOT', ''),
'show_hidden' => env('FILEMANAGER_SHOW_HIDDEN', false), 'show_hidden' => env('FILEMANAGER_SHOW_HIDDEN', false),
'url_expiration' => env('FILEMANAGER_URL_EXPIRATION', 60), 'url_expiration' => env('FILEMANAGER_URL_EXPIRATION', 60),
@ -17,7 +20,7 @@ return [
'public_disks' => ['public'], 'public_disks' => ['public'],
'public_access_disks' => [], 'public_access_disks' => [],
], ],
'model' => \MWGuerra\FileManager\Models\FileSystemItem::class, 'model' => FileSystemItem::class,
'file_manager' => [ 'file_manager' => [
'enabled' => true, 'enabled' => true,
'navigation' => [ 'navigation' => [
@ -40,7 +43,7 @@ return [
'enabled' => true, 'enabled' => true,
], ],
'upload' => [ 'upload' => [
'disk' => env('FILEMANAGER_DISK', env('FILESYSTEM_DISK', 'public')), 'disk' => 'public',
'directory' => env('FILEMANAGER_UPLOAD_DIR', 'uploads'), 'directory' => env('FILEMANAGER_UPLOAD_DIR', 'uploads'),
'max_file_size' => 100 * 1024, // 100 MB in kilobytes 'max_file_size' => 100 * 1024, // 100 MB in kilobytes
'allowed_mimes' => [ 'allowed_mimes' => [
@ -91,7 +94,7 @@ return [
'delete_any' => null, // Bulk delete 'delete_any' => null, // Bulk delete
'download' => null, // Download files 'download' => null, // Download files
], ],
'policy' => \MWGuerra\FileManager\Policies\FileSystemItemPolicy::class, 'policy' => FileSystemItemPolicy::class,
], ],
'sidebar' => [ 'sidebar' => [
'enabled' => true, 'enabled' => true,

View File

@ -1,7 +1,7 @@
<?php <?php
return [ return [
'default' => env('FILESYSTEM_DISK', env('MEDIA_DISK', 's3')), 'default' => env('FILESYSTEM_DISK', 'public'),
'disks' => [ 'disks' => [
'local' => [ 'local' => [
@ -21,20 +21,6 @@ return [
'report' => false, 'report' => false,
], ],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID', env('OBJECT_STORAGE_ACCESS_KEY_ID')),
'secret' => env('AWS_SECRET_ACCESS_KEY', env('OBJECT_STORAGE_SECRET_ACCESS_KEY')),
'region' => env('AWS_DEFAULT_REGION', env('OBJECT_STORAGE_REGION', 'hel1')),
'bucket' => env('AWS_BUCKET', env('OBJECT_STORAGE_BUCKET')),
'url' => env('AWS_URL', env('OBJECT_STORAGE_URL')),
'endpoint' => env('AWS_ENDPOINT', env('OBJECT_STORAGE_ENDPOINT')),
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
'visibility' => 'public',
'throw' => false,
'report' => false,
],
], ],
'links' => [ 'links' => [
public_path('storage') => storage_path('app/public'), public_path('storage') => storage_path('app/public'),

View File

@ -1,5 +1,6 @@
<?php <?php
use Modules\Site\App\Support\HomeSlideDefaults;
use Spatie\LaravelSettings\Migrations\SettingsMigration; use Spatie\LaravelSettings\Migrations\SettingsMigration;
return new class extends SettingsMigration return new class extends SettingsMigration
@ -8,9 +9,7 @@ return new class extends SettingsMigration
{ {
$this->migrator->add('general.site_name', 'OpenClassify'); $this->migrator->add('general.site_name', 'OpenClassify');
$this->migrator->add('general.site_description', 'The marketplace for buying and selling everything.'); $this->migrator->add('general.site_description', 'The marketplace for buying and selling everything.');
$this->migrator->add('general.media_disk', \Modules\S3\Support\MediaStorage::defaultDriver());
$this->migrator->add('general.site_logo', null); $this->migrator->add('general.site_logo', null);
$this->migrator->add('general.site_logo_disk', null);
$this->migrator->add('general.default_language', 'en'); $this->migrator->add('general.default_language', 'en');
$this->migrator->add('general.default_country_code', '+90'); $this->migrator->add('general.default_country_code', '+90');
$this->migrator->add('general.currencies', ['USD']); $this->migrator->add('general.currencies', ['USD']);
@ -30,6 +29,6 @@ return new class extends SettingsMigration
$this->migrator->add('general.enable_apple_login', false); $this->migrator->add('general.enable_apple_login', false);
$this->migrator->add('general.apple_client_id', null); $this->migrator->add('general.apple_client_id', null);
$this->migrator->add('general.apple_client_secret', null); $this->migrator->add('general.apple_client_secret', null);
$this->migrator->add('general.home_slides', \Modules\Site\App\Support\HomeSlideDefaults::defaults()); $this->migrator->add('general.home_slides', HomeSlideDefaults::defaults());
} }
}; };

View File

@ -8,7 +8,6 @@
"Favorite": true, "Favorite": true,
"User": true, "User": true,
"Video": true, "Video": true,
"S3": true,
"Demo": true, "Demo": true,
"Panel": true, "Panel": true,
"Site": true "Site": true