172 lines
5.9 KiB
PHP
172 lines
5.9 KiB
PHP
<?php
|
|
|
|
namespace App\Traits;
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
/**
|
|
* SoftDeleteConflictController Trait
|
|
*
|
|
* This trait provides controller methods for handling soft delete conflicts in the UI.
|
|
*/
|
|
trait SoftDeleteConflictController
|
|
{
|
|
/**
|
|
* Check if a record would conflict with a soft-deleted record.
|
|
*
|
|
* @param Request $request
|
|
* @param string $modelClass The fully qualified class name of the model
|
|
* @return JsonResponse
|
|
*/
|
|
public function checkSoftDeleteConflict(Request $request, string $modelClass): JsonResponse
|
|
{
|
|
if (!class_exists($modelClass)) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Invalid model class provided',
|
|
], 400);
|
|
}
|
|
|
|
try {
|
|
// Create a new instance of the model
|
|
/** @var Model $model */
|
|
$model = new $modelClass();
|
|
|
|
// Ensure the model uses SoftDeleteResolution trait
|
|
if (!method_exists($model, 'findSoftDeletedDuplicate')) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Model does not support soft delete conflict resolution',
|
|
], 400);
|
|
}
|
|
|
|
// Only include fields that are present in request
|
|
$attributes = $request->only($model->getFillable());
|
|
|
|
// If editing an existing record, pass the ID to exclude it from the check
|
|
if ($request->has('id')) {
|
|
$attributes['id'] = $request->input('id');
|
|
}
|
|
|
|
// Check for soft-deleted duplicate
|
|
$duplicate = $model->findSoftDeletedDuplicate($attributes);
|
|
|
|
if ($duplicate) {
|
|
// Return details about the conflicting record
|
|
return response()->json([
|
|
'success' => true,
|
|
'conflict' => true,
|
|
'message' => 'A deleted record with the same unique identifier exists.',
|
|
'duplicate' => [
|
|
'id' => $duplicate->getKey(),
|
|
'attributes' => $duplicate->toArray(),
|
|
'deleted_at' => $duplicate->deleted_at->format('Y-m-d H:i:s'),
|
|
],
|
|
]);
|
|
}
|
|
|
|
// No conflict found
|
|
return response()->json([
|
|
'success' => true,
|
|
'conflict' => false,
|
|
'message' => 'No conflict found',
|
|
]);
|
|
} catch (\Exception $e) {
|
|
Log::error('Error checking for soft delete conflict', [
|
|
'error' => $e->getMessage(),
|
|
'model' => $modelClass,
|
|
'data' => $request->all(),
|
|
]);
|
|
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'An error occurred while checking for conflicts',
|
|
'error' => $e->getMessage(),
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Resolve a soft delete conflict by restoring the deleted record.
|
|
*
|
|
* @param Request $request
|
|
* @param string $modelClass The fully qualified class name of the model
|
|
* @param mixed $id The ID of the soft-deleted record to restore
|
|
* @return JsonResponse
|
|
*/
|
|
public function resolveSoftDeleteConflict(Request $request, string $modelClass, $id): JsonResponse
|
|
{
|
|
if (!class_exists($modelClass)) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Invalid model class provided',
|
|
], 400);
|
|
}
|
|
|
|
try {
|
|
// Attempt to find the soft-deleted record
|
|
/** @var Model $model */
|
|
$modelInstance = new $modelClass();
|
|
|
|
// Ensure the model uses SoftDeleteResolution trait
|
|
if (!method_exists($modelInstance, 'restoreSoftDeletedRecord')) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Model does not support soft delete conflict resolution',
|
|
], 400);
|
|
}
|
|
|
|
$deletedRecord = $modelClass::withTrashed()->find($id);
|
|
|
|
if (!$deletedRecord) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Deleted record not found',
|
|
], 404);
|
|
}
|
|
|
|
if (!$deletedRecord->trashed()) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Record is not deleted',
|
|
], 400);
|
|
}
|
|
|
|
// Only include fields that are present in request and fillable
|
|
$attributes = $request->only($modelInstance->getFillable());
|
|
|
|
// Restore the record with updated attributes
|
|
$restored = $modelInstance->restoreSoftDeletedRecord($deletedRecord, $attributes);
|
|
|
|
if (!$restored) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Failed to restore record',
|
|
], 500);
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Record restored successfully',
|
|
'record' => $restored->fresh()->toArray(),
|
|
]);
|
|
} catch (\Exception $e) {
|
|
Log::error('Error restoring soft-deleted record', [
|
|
'error' => $e->getMessage(),
|
|
'model' => $modelClass,
|
|
'id' => $id,
|
|
'data' => $request->all(),
|
|
]);
|
|
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'An error occurred while restoring the record',
|
|
'error' => $e->getMessage(),
|
|
], 500);
|
|
}
|
|
}
|
|
}
|