I have a big laravel project that contains a lot of deletion in that project, in all of those deletion didn't put alert before deleting, now I can't modify the project one by one and adding alert or confirm before deleting...
I was searching about a solution that we listen to DELETE query or override the \Illuminate\Database\Query\Builder delete method, but now I'm comfused about how to handle it so that works correctly, I really need your help.
I put all of my implementation up to now to do that:
namespace App\Extensions;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Database\Query\Grammars\Grammar;
use Illuminate\Database\Query\Processors\Processor;
use Illuminate\Database\Query\Builder as QueryBuilder;
use Illuminate\Database\Eloquent\Model;
class CustomQueryBuilder extends QueryBuilder
{
public function delete($id = null)
{
dd("...");
// You can add your confirmation logic here
if ($this->confirmDelete()) {
return parent::delete($id);
}
dd("Delete method called..!");
// If confirmation is not provided, return false or handle it accordingly.
return false;
}
private function confirmDelete()
{
return false;
// Implement your confirmation dialog with user interaction here
// You can use JavaScript for a client-side confirmation or a form for a server-side confirmation
}
In this way make a CustomQueryBuilder and bind it with the Builder in thev appServiceProvider boot(), then use CustomQueryBuilder in our Model instead of Builder
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
use Illuminate\Support\Facades\DB;
class ConfirmDeleteMiddleware
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
// Check if the request has a DELETE SQL query
$sql = DB::getQueryLog();
dd($sql);
foreach ($sql as $query) {
if (str_starts_with($query['query'], 'delete') || str_starts_with($query['query'], 'DELETE')) {
// Display a confirmation dialog to the user
return response()
->view('confirm_delete', ['deleteRoute' => url()->full()], 200)
->header('Content-Type', 'text/html');
}
}
return $next($request);
}
}
In this way we use DB::getQueryLog to get latest queries and after that check DELETE in the query to handle the delete logic.
test the addGlobalScope method:
Model::addGlobalScope(function (Builder $builder) {
return new CustomQueryBuilder($builder);
});
and use a lot of method like event listener, macro, etc but can't do it as well
deleteon a model that fires and event, if you are directly doing a delete query on a query builder that wont fire anything specific ... are you using Eloquent Models and calling thedeletemethod or are you building delete queries? ... also this sounds like it could just be a front end issue (asking for confirmation of something), you should be able to update very little javascript to add something like this inQueryBuilderclass ?