src/Administration/Controller/NotificationController.php line 81

  1. <?php declare(strict_types=1);
  2. namespace Shopware\Administration\Controller;
  3. use Shopware\Administration\Notification\Exception\NotificationThrottledException;
  4. use Shopware\Administration\Notification\NotificationService;
  5. use Shopware\Core\Framework\Api\Context\AdminApiSource;
  6. use Shopware\Core\Framework\Api\Context\Exception\InvalidContextSourceException;
  7. use Shopware\Core\Framework\Context;
  8. use Shopware\Core\Framework\Log\Package;
  9. use Shopware\Core\Framework\RateLimiter\Exception\RateLimitExceededException;
  10. use Shopware\Core\Framework\RateLimiter\RateLimiter;
  11. use Shopware\Core\Framework\Uuid\Uuid;
  12. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  13. use Symfony\Component\HttpFoundation\JsonResponse;
  14. use Symfony\Component\HttpFoundation\Request;
  15. use Symfony\Component\HttpFoundation\Response;
  16. use Symfony\Component\Routing\Annotation\Route;
  17. #[Route(defaults: ['_routeScope' => ['api']])]
  18. #[Package('administration')]
  19. class NotificationController extends AbstractController
  20. {
  21.     final public const NOTIFICATION 'notification';
  22.     final public const LIMIT 5;
  23.     /**
  24.      * @internal
  25.      */
  26.     public function __construct(private readonly RateLimiter $rateLimiter, private readonly NotificationService $notificationService)
  27.     {
  28.     }
  29.     #[Route(path'/api/notification'name'api.notification'defaults: ['_acl' => ['notification:create']], methods: ['POST'])]
  30.     public function saveNotification(Request $requestContext $context): Response
  31.     {
  32.         $status $request->request->get('status');
  33.         $message $request->request->get('message');
  34.         $adminOnly = (bool) $request->request->get('adminOnly'false);
  35.         $requiredPrivileges $request->request->all('requiredPrivileges');
  36.         $source $context->getSource();
  37.         if (!$source instanceof AdminApiSource) {
  38.             throw new InvalidContextSourceException(AdminApiSource::class, $context->getSource()::class);
  39.         }
  40.         if (empty($status) || empty($message)) {
  41.             throw new \InvalidArgumentException('status and message cannot be empty');
  42.         }
  43.         if (!\is_array($requiredPrivileges)) {
  44.             throw new \InvalidArgumentException('requiredPrivileges must be an array');
  45.         }
  46.         $integrationId $source->getIntegrationId();
  47.         $createdByUserId $source->getUserId();
  48.         try {
  49.             $cacheKey $createdByUserId ?? $integrationId '-' $request->getClientIp();
  50.             $this->rateLimiter->ensureAccepted(self::NOTIFICATION$cacheKey);
  51.         } catch (RateLimitExceededException $exception) {
  52.             throw new NotificationThrottledException($exception->getWaitTime(), $exception);
  53.         }
  54.         $notificationId Uuid::randomHex();
  55.         $this->notificationService->createNotification([
  56.             'id' => $notificationId,
  57.             'status' => $status,
  58.             'message' => $message,
  59.             'adminOnly' => $adminOnly,
  60.             'requiredPrivileges' => $requiredPrivileges,
  61.             'createdByIntegrationId' => $integrationId,
  62.             'createdByUserId' => $createdByUserId,
  63.         ], $context);
  64.         return new JsonResponse(['id' => $notificationId]);
  65.     }
  66.     #[Route(path'/api/notification/message'name'api.notification.message'methods: ['GET'])]
  67.     public function fetchNotification(Request $requestContext $context): Response
  68.     {
  69.         $limit $request->query->get('limit');
  70.         $limit $limit ? (int) $limit self::LIMIT;
  71.         $latestTimestamp $request->query->has('latestTimestamp') ? (string) $request->query->get('latestTimestamp') : null;
  72.         $responseData $this->notificationService->getNotifications($context$limit$latestTimestamp);
  73.         return new JsonResponse($responseData);
  74.     }
  75. }