vendor/nellapp/sdk-bundle/src/EventSubscriber/InvalidPaginationSortSubscriber.php line 28

Open in your IDE?
  1. <?php
  2. namespace Nellapp\Bundle\SDKBundle\EventSubscriber;
  3. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  4. use Symfony\Component\HttpFoundation\RedirectResponse;
  5. use Symfony\Component\HttpKernel\Event\ExceptionEvent;
  6. use Symfony\Component\HttpKernel\KernelEvents;
  7. use UnexpectedValueException;
  8. /**
  9. * Invalid KnpPaginator sort params (e.g. "t.createdat" lowercased by a crawler, unknown field,
  10. * array value) throw an UnexpectedValueException from the sortable subscribers/walkers.
  11. * Redirect to the same URL without sort params instead of returning a 500.
  12. */
  13. class InvalidPaginationSortSubscriber implements EventSubscriberInterface
  14. {
  15. private const SORTABLE_NAMESPACE = 'Knp\\Component\\Pager\\Event\\Subscriber\\Sortable\\';
  16. public static function getSubscribedEvents(): array
  17. {
  18. return [
  19. // Before Sentry (128) and Symfony's ErrorListener (0) so the exception is not reported.
  20. KernelEvents::EXCEPTION => ['onKernelException', 200],
  21. ];
  22. }
  23. public function onKernelException(ExceptionEvent $event): void
  24. {
  25. $request = $event->getRequest();
  26. $exception = $event->getThrowable();
  27. if (
  28. !$request->isMethod('GET')
  29. || !$exception instanceof UnexpectedValueException
  30. || !$this->isFromSortable($exception)
  31. ) {
  32. return;
  33. }
  34. $query = $request->query->all();
  35. unset($query['sort'], $query['direction']);
  36. $event->setResponse(new RedirectResponse(
  37. $request->getBaseUrl() . $request->getPathInfo() . ($query ? '?' . http_build_query($query) : '')
  38. ));
  39. $event->stopPropagation();
  40. }
  41. private function isFromSortable(UnexpectedValueException $exception): bool
  42. {
  43. foreach ($exception->getTrace() as $frame) {
  44. if (str_starts_with($frame['class'] ?? '', self::SORTABLE_NAMESPACE)) {
  45. return true;
  46. }
  47. }
  48. return false;
  49. }
  50. }