landscape-platform/app/Traits/SoftDeleteConflictController.php
2025-03-13 19:50:56 -05:00

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);
}
}
}