custom/plugins/SpnoActivityLog/src/Framework/ActivityLog/Subscriber/EntityWrittenSubscriber.php line 50

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. /*
  3.  * (c) webpiloten. <kontakt@web-piloten.de>
  4.  * For the full copyright and license information, please view the LICENSE
  5.  * file that was distributed with this source code.
  6.  */
  7. namespace Spno\ActivityLog\Framework\ActivityLog\Subscriber;
  8. use Shopware\Core\Framework\Api\Context\AdminApiSource;
  9. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  10. use Shopware\Core\Framework\DataAbstractionLayer\EntityWriteResult;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityDeletedEvent;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Write\EntityExistence;
  14. use Shopware\Core\Framework\Uuid\Uuid;
  15. use Spno\ActivityLog\Framework\ActivityLog\Serializer\KebabCaseToCamelCaseNameConverter;
  16. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  17. use Symfony\Component\HttpFoundation\ParameterBag;
  18. use Symfony\Component\HttpFoundation\Request;
  19. use Symfony\Component\HttpFoundation\RequestStack;
  20. class EntityWrittenSubscriber implements EventSubscriberInterface
  21. {
  22.     const EVENT_CREATED 'created';
  23.     const EVENT_WRITTEN 'written';
  24.     const EVENT_DELETED 'deleted';
  25.     const ENTITY_ID 0;
  26.     const ENTITY_ASSOCIATION 1;
  27.     const ENTITY_ASSOCIATION_ID 2;
  28.     private EntityRepositoryInterface $activityLogRepository;
  29.     private RequestStack $requestStack;
  30.     public function __construct(
  31.         EntityRepositoryInterface $activityLogRepository,
  32.         RequestStack $requestStack
  33.     ) {
  34.         $this->activityLogRepository $activityLogRepository;
  35.         $this->requestStack $requestStack;
  36.     }
  37.     public static function getSubscribedEvents(): array
  38.     {
  39.         return EntityEvents::ENTITY_EVENTS;
  40.     }
  41.     public function onEntityDeleted(EntityDeletedEvent $event): void
  42.     {
  43.         if (!$this->requestStack->getCurrentRequest() instanceof Request) {
  44.             return;
  45.         }
  46.         if (!$event->getContext()->getSource() instanceof AdminApiSource) {
  47.             return;
  48.         }
  49.         $requestBag $this->requestStack->getCurrentRequest()->request;
  50.         $this->prepareDeleteEvent($event$requestBag);
  51.     }
  52.     public function onEntityWritten(EntityWrittenEvent $event): void
  53.     {
  54.         if (!$this->requestStack->getCurrentRequest() instanceof Request) {
  55.             return;
  56.         }
  57.         if (!$event->getContext()->getSource() instanceof AdminApiSource) {
  58.             return;
  59.         }
  60.         if (empty($event->getWriteResults()) || !array_key_exists(0$event->getWriteResults())) {
  61.             return;
  62.         }
  63.         $requestBag $this->requestStack->getCurrentRequest()->request;
  64.         $writeResult $event->getWriteResults()[0];
  65.         if (!$writeResult instanceof EntityWriteResult) {
  66.             return;
  67.         }
  68.         $primaryKeys = [];
  69.         if ($this->requestStack->getCurrentRequest()->getRealMethod() === Request::METHOD_DELETE) {
  70.             $this->prepareDeleteEvent($event$requestBag);
  71.             return;
  72.         }
  73.         if ($writeResult->getExistence() instanceof EntityExistence) {
  74.             $primaryKeys $writeResult->getExistence()->getPrimaryKey();
  75.             if ($writeResult->getExistence()->exists()) {
  76.                 $this->createLog($event$requestBagself::EVENT_WRITTEN$primaryKeys);
  77.                 return;
  78.             }
  79.         }
  80.         if ($writeResult->getPayload()) {
  81.             $primaryKeys array_merge($primaryKeys$writeResult->getPayload());
  82.         }
  83.         $this->createLog($event$requestBagself::EVENT_CREATED$primaryKeys);
  84.     }
  85.     private function prepareDeleteEvent(EntityWrittenEvent $eventParameterBag $requestBag): void
  86.     {
  87.         if (!$this->requestStack->getCurrentRequest() instanceof Request) {
  88.             return;
  89.         }
  90.         if (!$this->requestStack->getCurrentRequest()->attributes->has('_route_params')) {
  91.             return;
  92.         }
  93.         $kebabCaseConverter = new KebabCaseToCamelCaseNameConverter();
  94.         $attrRouteParams $this->requestStack->getCurrentRequest()->attributes->get('_route_params');
  95.         if (!is_array($attrRouteParams) || !array_key_exists('path'$attrRouteParams)) {
  96.             return;
  97.         }
  98.         $path $attrRouteParams['path'];
  99.         $routeParams explode('/'$path);
  100.         foreach ($routeParams as &$param) {
  101.             if (Uuid::isValid($param)) {
  102.                 continue;
  103.             }
  104.             $param $kebabCaseConverter->normalize($param);
  105.         }
  106.         if (
  107.             !array_key_exists(self::ENTITY_ID$routeParams) ||
  108.             !array_key_exists(self::ENTITY_ASSOCIATION$routeParams) ||
  109.             !array_key_exists(self::ENTITY_ASSOCIATION_ID$routeParams)
  110.         ) {
  111.             return;
  112.         }
  113.         $primaryKeys = [
  114.             'id' => $routeParams[self::ENTITY_ID],
  115.         ];
  116.         $requestBag->add([
  117.             $routeParams[self::ENTITY_ASSOCIATION] => [
  118.                 'id' => $routeParams[self::ENTITY_ASSOCIATION_ID],
  119.             ],
  120.         ]);
  121.         $this->createLog($event$requestBagself::EVENT_DELETED$primaryKeys);
  122.     }
  123.     private function createLog(EntityWrittenEvent $eventParameterBag $requestBagstring $eventName, array $primaryKeys): void
  124.     {
  125.         if (!$primaryKeys) {
  126.             return;
  127.         }
  128.         $source $event->getContext()->getSource();
  129.         if (!$source instanceof AdminApiSource) {
  130.             return;
  131.         }
  132.         $userId $source->getUserId();
  133.         $integrationId $source->getIntegrationId();
  134.         $message sprintf('%s.%s'$event->getEntityName(), $eventName);
  135.         $this->activityLogRepository->create([
  136.             [
  137.                 'userId' => $userId,
  138.                 'integrationId' => $integrationId,
  139.                 'message' => $message,
  140.                 'context' => [
  141.                     'entity' => [
  142.                         'name' => $event->getEntityName(),
  143.                         'primaryKey' => $primaryKeys,
  144.                     ],
  145.                     'languageId' => $event->getContext()->getLanguageId(),
  146.                     'result' => $requestBag->all(),
  147.                 ],
  148.             ],
  149.         ], $event->getContext());
  150.     }
  151. }