ultimatepos/Modules/AssetExchange/Services/MediaService.php

124 lines
4.0 KiB
PHP

<?php
namespace Modules\AssetExchange\Services;
use App\Business;
use App\User;
use App\Utils\Util;
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Modules\AssetExchange\Models\Listing;
use Modules\AssetExchange\Models\ListingMedia;
class MediaService
{
public const UPLOAD_DIR = 'aex_listings';
public function __construct(
protected Util $commonUtil
) {
}
public function uploadForListing(Business $business, Listing $listing, Request $request, ?User $user = null): int
{
if (! Schema::hasTable('aex_listing_media')) {
return 0;
}
$count = 0;
$sort = (int) $listing->media()->max('sort_order');
if ($request->hasFile('photos')) {
foreach ((array) $request->file('photos') as $file) {
if ($file instanceof UploadedFile && $file->isValid()) {
$this->storeFile($business, $listing, $file, 'photo', null, ++$sort);
$count++;
}
}
}
if ($request->hasFile('documents')) {
foreach ((array) $request->file('documents') as $file) {
if ($file instanceof UploadedFile && $file->isValid()) {
$this->storeFile($business, $listing, $file, 'document', null, ++$sort);
$count++;
}
}
}
foreach (['photo', 'document'] as $type) {
$single = $type === 'photo' ? 'photo' : 'document';
if ($request->hasFile($single) && $request->file($single)->isValid()) {
$this->storeFile($business, $listing, $request->file($single), $type, null, ++$sort);
$count++;
}
}
return $count;
}
public function storeFile(
Business $business,
Listing $listing,
UploadedFile $file,
string $mediaType,
?string $caption = null,
int $sortOrder = 0
): ListingMedia {
if (config('app.env') === 'demo') {
throw new \RuntimeException('آپلود در محیط دمو غیرفعال است.');
}
$fileType = $mediaType === 'photo' ? 'image' : 'document';
if ($fileType === 'image' && ! str_starts_with((string) $file->getMimeType(), 'image/')) {
throw new \RuntimeException('فایل تصویر نامعتبر است.');
}
if ($fileType === 'document') {
$allowed = array_keys(config('constants.document_upload_mimes_types', []));
if ($allowed && ! in_array($file->getMimeType(), $allowed, true)) {
throw new \RuntimeException('نوع فایل مجاز نیست.');
}
}
if ($file->getSize() > config('constants.document_size_limit')) {
throw new \RuntimeException('حجم فایل بیش از حد مجاز است.');
}
$original = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
$extension = $file->getClientOriginalExtension();
$stored = time().'_'.Str::slug($original).($extension ? '.'.$extension : '');
if (! $file->storeAs(self::UPLOAD_DIR, $stored)) {
throw new \RuntimeException('آپلود فایل ناموفق بود.');
}
return ListingMedia::create([
'business_id' => $business->id,
'listing_id' => $listing->id,
'media_type' => $mediaType,
'path' => $stored,
'caption' => $caption,
'sort_order' => $sortOrder,
]);
}
public function deleteMedia(ListingMedia $media): void
{
$fullPath = public_path('uploads/'.self::UPLOAD_DIR.'/'.$media->path);
if (is_file($fullPath)) {
@unlink($fullPath);
}
$media->delete();
}
public function publicUrl(ListingMedia $media): string
{
return asset('uploads/'.self::UPLOAD_DIR.'/'.$media->path);
}
}