215 lines
7.1 KiB
PHP
215 lines
7.1 KiB
PHP
<?php
|
|
|
|
namespace App\Filament\Pages\Media\Services;
|
|
|
|
use App\Enums\DataChangeStatus;
|
|
use App\Filament\Resources\Manage\DataChanges\DataChangesResource;
|
|
use App\Filament\Support\CheerfulNotification;
|
|
use App\Models\DataChangeRequest;
|
|
use App\Models\PartnerMedia;
|
|
use App\Models\User;
|
|
use App\Notifications\BroadcastNotification;
|
|
use BackedEnum;
|
|
use Filament\Actions\Action;
|
|
use Filament\Support\Contracts\HasLabel;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use UnitEnum;
|
|
|
|
class MediaSaveService
|
|
{
|
|
public static function handle(
|
|
?PartnerMedia $existingMedia,
|
|
int $companyId,
|
|
array $formState,
|
|
array $pageData,
|
|
array $originalDocuments,
|
|
bool $needsReview,
|
|
array $actionData = [],
|
|
): ?PartnerMedia {
|
|
if ($needsReview && $existingMedia) {
|
|
self::createDataChangeRequest(
|
|
media: $existingMedia,
|
|
formState: $formState,
|
|
pageData: $pageData,
|
|
originalDocuments: $originalDocuments,
|
|
actionData: $actionData,
|
|
);
|
|
|
|
return $existingMedia;
|
|
}
|
|
|
|
return self::saveMediaDirectly(
|
|
existingMedia: $existingMedia,
|
|
companyId: $companyId,
|
|
formState: $formState,
|
|
pageData: $pageData,
|
|
);
|
|
}
|
|
|
|
private static function createDataChangeRequest(
|
|
PartnerMedia $media,
|
|
array $formState,
|
|
array $pageData,
|
|
array $originalDocuments,
|
|
array $actionData,
|
|
): void {
|
|
$existingRequest = DataChangeRequest::where('entity_type', PartnerMedia::class)
|
|
->where('entity_id', $media->id)
|
|
->where('status', DataChangeStatus::PENDING)
|
|
->exists();
|
|
|
|
if ($existingRequest) {
|
|
CheerfulNotification::warning(
|
|
CheerfulNotification::getByKey('data_change.existing.title'),
|
|
CheerfulNotification::getByKey('data_change.existing.body')
|
|
)->send();
|
|
|
|
return;
|
|
}
|
|
|
|
$data = array_merge($formState, $actionData);
|
|
|
|
$fieldLabels = PartnerMedia::dataChangeEntryLabels();
|
|
|
|
$editableFields = [
|
|
'name',
|
|
'link',
|
|
'address',
|
|
'type',
|
|
'classification',
|
|
'journalism_organization',
|
|
'press_council_certificate',
|
|
];
|
|
|
|
$changedFields = [];
|
|
$oldDataArr = [];
|
|
|
|
$casts = $media->getCasts();
|
|
foreach ($editableFields as $field) {
|
|
$val = $data[$field] ?? null;
|
|
$oldVal = $media->{$field};
|
|
|
|
if (isset($casts[$field]) && ! ($val instanceof BackedEnum) && enum_exists($casts[$field])) {
|
|
/** @var class-string<UnitEnum> $enumClass */
|
|
$enumClass = $casts[$field];
|
|
$val = $enumClass::tryFrom($val) ?? $val;
|
|
}
|
|
|
|
$displayVal = ($val instanceof HasLabel) ? $val->getLabel() : ($val instanceof BackedEnum ? $val->value : $val);
|
|
$displayOldVal = ($oldVal instanceof HasLabel) ? $oldVal->getLabel() : ($oldVal instanceof BackedEnum ? $oldVal->value : $oldVal);
|
|
|
|
if ($displayOldVal !== $displayVal) {
|
|
$label = $fieldLabels[$field] ?? $field;
|
|
$changedFields[$label] = $displayVal;
|
|
$oldDataArr[$label] = $displayOldVal;
|
|
}
|
|
}
|
|
|
|
$documents = [
|
|
'journalism_organization_docs',
|
|
'press_council_certificate_docs',
|
|
];
|
|
|
|
foreach ($documents as $field) {
|
|
$newValue = $pageData[$field] ?? [];
|
|
$oldValue = $originalDocuments[$field] ?? [];
|
|
|
|
if (json_encode($newValue) !== json_encode($oldValue)) {
|
|
$label = $fieldLabels[$field] ?? $field;
|
|
$changedFields[$label] = $newValue;
|
|
$oldDataArr[$label] = $oldValue;
|
|
}
|
|
}
|
|
|
|
if (empty($changedFields)) {
|
|
CheerfulNotification::info(
|
|
CheerfulNotification::getByKey('data_change.no_change.title'),
|
|
CheerfulNotification::getByKey('data_change.no_change.body')
|
|
)->send();
|
|
|
|
return;
|
|
}
|
|
|
|
$dataChangeRequest = DataChangeRequest::create([
|
|
'user_id' => auth()->id(),
|
|
'entity_type' => PartnerMedia::class,
|
|
'entity_id' => $media->id,
|
|
'old_data' => $oldDataArr,
|
|
'new_data' => $changedFields,
|
|
'change_reason' => $data['change_reason'] ?? null,
|
|
]);
|
|
|
|
CheerfulNotification::success(
|
|
CheerfulNotification::getByKey('data_change.success.title'),
|
|
CheerfulNotification::getByKey('data_change.success.body')
|
|
)->send();
|
|
|
|
User::superAdmin()
|
|
->get()
|
|
->each(function ($admin) use ($dataChangeRequest): void {
|
|
$admin->notify(new BroadcastNotification([
|
|
'title' => CheerfulNotification::getByKey('data_change.admin_notify.title'),
|
|
'body' => CheerfulNotification::getByKey('data_change.admin_notify.body', ['name' => auth()->user()->name]),
|
|
'action' => [
|
|
Action::make('view')
|
|
->label('Lihat')
|
|
->url(DataChangesResource::getUrl('view', ['record' => $dataChangeRequest->id])),
|
|
],
|
|
]));
|
|
});
|
|
}
|
|
|
|
private static function saveMediaDirectly(
|
|
?PartnerMedia $existingMedia,
|
|
int $companyId,
|
|
array $formState,
|
|
array $pageData,
|
|
): PartnerMedia {
|
|
$media = PartnerMedia::updateOrCreate([
|
|
'id' => $existingMedia?->id,
|
|
], [
|
|
'company_id' => $companyId,
|
|
'name' => $formState['name'],
|
|
'link' => $formState['link'],
|
|
'address' => $formState['address'],
|
|
'type' => $formState['type'],
|
|
'classification' => $formState['classification'],
|
|
'journalism_organization' => $formState['journalism_organization'],
|
|
'press_council_certificate' => $formState['press_council_certificate'],
|
|
]);
|
|
|
|
$documents = [
|
|
'journalism_organization_docs',
|
|
'press_council_certificate_docs',
|
|
];
|
|
|
|
foreach ($documents as $field) {
|
|
if (empty($pageData[$field])) {
|
|
continue;
|
|
}
|
|
|
|
foreach ((array) $pageData[$field] as $filePath) {
|
|
$fullPath = Storage::disk(config('filesystems.default'))->path($filePath);
|
|
|
|
if (! file_exists($fullPath)) {
|
|
continue;
|
|
}
|
|
|
|
$media
|
|
->addMediaFromDisk($filePath, config('filesystems.default'))
|
|
->preservingOriginal()
|
|
->withCustomProperties([
|
|
'feature' => 'media',
|
|
'date' => now()->toDateString(),
|
|
'doc_type' => str($field)
|
|
->replace('_docs', '')
|
|
->slug('-'),
|
|
])
|
|
->toMediaCollection('partnerMedia');
|
|
}
|
|
}
|
|
|
|
return $media;
|
|
}
|
|
}
|