vendor/store.shopware.com/viob2blogin/src/Core/Framework/Subscriber/PluginLifecycleSubscriber.php line 72

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace VioB2BLogin\Core\Framework\Subscriber;
  4. use Shopware\Core\Framework\Context;
  5. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  6. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  9. use Shopware\Core\Framework\Plugin\Event\PluginPostActivateEvent;
  10. use Shopware\Core\Framework\Plugin\Event\PluginPostUninstallEvent;
  11. use Shopware\Core\Framework\Plugin\Event\PluginPostUpdateEvent;
  12. use Shopware\Core\Framework\Plugin\Event\PluginPreDeactivateEvent;
  13. use Shopware\Core\Framework\Plugin\PluginEntity;
  14. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  15. use VioB2BLogin\Entity\Employee\EmployeeEntity;
  16. use VioB2BLogin\Entity\Privilege\AbstractPrivilegeProvider;
  17. class PluginLifecycleSubscriber implements EventSubscriberInterface
  18. {
  19.     /** @var iterable<AbstractPrivilegeProvider> */
  20.     private iterable $priviligeProviders;
  21.     private EntityRepository $privilegeRepository;
  22.     private EntityRepository $employeePrivilegeRepository;
  23.     private EntityRepositoryInterface $employeeRepository;
  24.     public function __construct(
  25.         iterable         $priviligeProviders,
  26.         EntityRepository $privilegeRepository,
  27.         EntityRepositoryInterface $employeeRepository,
  28.         EntityRepository $employeePrivilegeRepository
  29.     )
  30.     {
  31.         $this->priviligeProviders $priviligeProviders;
  32.         $this->privilegeRepository $privilegeRepository;
  33.         $this->employeePrivilegeRepository $employeePrivilegeRepository;
  34.         $this->employeeRepository $employeeRepository;
  35.     }
  36.     /**
  37.      * @inheritDoc
  38.      */
  39.     public static function getSubscribedEvents(): array
  40.     {
  41.         return [
  42.             PluginPostActivateEvent::class => 'onPostPluginActivate',
  43.             PluginPostUpdateEvent::class => 'onPostPluginUpdate',
  44.             PluginPreDeactivateEvent::class => 'onPrePluginDeactivate',
  45.             PluginPostUninstallEvent::class => 'onPostPluginUninstall',
  46.         ];
  47.     }
  48.     public function onPostPluginActivate(PluginPostActivateEvent $event): void
  49.     {
  50.         $this->installACLRules($event->getContext()->getContext());
  51.         $this->activateACLRules($event->getContext()->getContext(), $event->getPlugin());
  52.     }
  53.     public function onPrePluginDeactivate(PluginPreDeactivateEvent $event): void
  54.     {
  55.         $this->deactivateACLRules($event->getContext()->getContext(), $event->getPlugin());
  56.     }
  57.     public function onPostPluginUninstall(PluginPostUninstallEvent $event): void
  58.     {
  59.         if (!$event->getContext()->keepUserData()) {
  60.             $this->deleteACLRules($event->getContext()->getContext(), $event->getPlugin());
  61.         }
  62.     }
  63.     public function onPostPluginUpdate(PluginPostUpdateEvent $event): void
  64.     {
  65.         $this->installACLRules($event->getContext()->getContext());
  66.         if( $event->getPlugin()->getActive() ) {
  67.             $this->activateACLRules($event->getContext()->getContext(), $event->getPlugin());
  68.         }
  69.     }
  70.     protected function activateACLRules(Context $contextPluginEntity $plugin): void
  71.     {
  72.         foreach ($this->priviligeProviders as $privilegeProvider) {
  73.             if ($privilegeProvider->getPlugin($context)->getId() === $plugin->getId()) {
  74.                 $this->setRuleActive($context$privilegeProvidertrue);
  75.             }
  76.         }
  77.     }
  78.     protected function deactivateACLRules(Context $contextPluginEntity $plugin): void
  79.     {
  80.         foreach ($this->priviligeProviders as $privilegeProvider) {
  81.             if ($privilegeProvider->getPlugin($context)->getId() === $plugin->getId()) {
  82.                 $this->setRuleActive($context$privilegeProviderfalse);
  83.             }
  84.         }
  85.     }
  86.     protected function deleteACLRules(Context $contextPluginEntity $plugin): void
  87.     {
  88.         $deletePrivileges = [];
  89.         $criteria = (new Criteria())->addFilter(new EqualsFilter('pluginId'$plugin->getId()));
  90.         $matchingPrivilege $this->privilegeRepository->search($criteria$context);
  91.         if ($matchingPrivilege->getTotal() > 0) {
  92.             foreach ($matchingPrivilege->getIds() as $id) {
  93.                 $deletePrivileges[] = ['id' => $id];
  94.             }
  95.         }
  96.         if (!empty($deletePrivileges)) {
  97.             $this->privilegeRepository->delete($deletePrivileges$context);
  98.         }
  99.     }
  100.     /** Install or Update all available ACL-Rules */
  101.     protected function installACLRules(Context $context): void
  102.     {
  103.         foreach ($this->priviligeProviders as $privilegeProvider) {
  104.             if ($this->checkACLRules($privilegeProvider)) {
  105.                 $upsertPrivileges = [];
  106.                 foreach ($privilegeProvider->getACLRules() as $namespace => $actions) {
  107.                     foreach ($actions as $action) {
  108.                         $privilegeData = [
  109.                             'active' => false,
  110.                             'namespace' => $namespace,
  111.                             'name' => $action,
  112.                             'pluginId' => $privilegeProvider->getPlugin($context)->getId()
  113.                         ];
  114.                         $criteria = (new Criteria())
  115.                             ->addFilter(new EqualsFilter('namespace'$namespace))
  116.                             ->addFilter(new EqualsFilter('name'$action));
  117.                         $matchingPrivilege $this->privilegeRepository->searchIds($criteria$context);
  118.                         if ($matchingPrivilege->getTotal() !== 0) {
  119.                             $privilegeData['id'] = $matchingPrivilege->firstId();
  120.                             unset($privilegeData['active']);
  121.                         }
  122.                         $upsertPrivileges[] = $privilegeData;
  123.                     }
  124.                 }
  125.                 if (!empty($upsertPrivileges)) {
  126.                     $this->privilegeRepository->upsert($upsertPrivileges$context);
  127.                     // search in the upsert data for all entries without ID to determine the new privileges
  128.                     $newPrivileges array_filter($upsertPrivileges, function ($privilege) {
  129.                         return !isset($privilege['id']);
  130.                     });
  131.                     if (!empty($newPrivileges)) {
  132.                         $this->assignNewPrivilegesToAllEmployees($context$newPrivileges);
  133.                     }
  134.                 }
  135.             }
  136.         }
  137.     }
  138.     protected function setRuleActive(Context $contextAbstractPrivilegeProvider $privilegeProviderbool $active): void
  139.     {
  140.         if ($this->checkACLRules($privilegeProvider)) {
  141.             $activatePrivileges = [];
  142.             foreach ($privilegeProvider->getACLRules() as $namespace => $actions) {
  143.                 foreach ($actions as $action) {
  144.                     $criteria = (new Criteria())
  145.                         ->addFilter(new EqualsFilter('namespace'$namespace))
  146.                         ->addFilter(new EqualsFilter('name'$action));
  147.                     $matchingPrivilege $this->privilegeRepository->search($criteria$context);
  148.                     if ($matchingPrivilege->getTotal() > 0) {
  149.                         foreach ($matchingPrivilege->getIds() as $id) {
  150.                             $activatePrivileges[] = [
  151.                                 'active' => $active,
  152.                                 'id' => $id
  153.                             ];
  154.                         }
  155.                     }
  156.                 }
  157.             }
  158.             if (!empty($activatePrivileges)) {
  159.                 $this->privilegeRepository->update($activatePrivileges$context);
  160.             }
  161.         }
  162.     }
  163.     protected function checkACLRules(AbstractPrivilegeProvider $privilegeProvider): bool
  164.     {
  165.         $aclRules $privilegeProvider->getACLRules();
  166.         if (is_array($aclRules)) {
  167.             foreach ($aclRules as $namespace => $actions) {
  168.                 if (is_string($namespace)) {
  169.                     if (is_array($actions)) {
  170.                         foreach ($actions as $action) {
  171.                             if (!is_string($action)) {
  172.                                 return false;
  173.                             }
  174.                         }
  175.                     }
  176.                 } else {
  177.                     return false;
  178.                 }
  179.             }
  180.         } else {
  181.             return false;
  182.         }
  183.         return true;
  184.     }
  185.     private function assignNewPrivilegesToAllEmployees(Context $context, array $newPrivileges)
  186.     {
  187.         // get all employees with assigned privileges
  188.         $criteria = (new Criteria())->addAssociation('privileges');
  189.         $employees $this->employeeRepository->search($criteria$context);
  190.         // filter out employees without privileges
  191.         $employees $employees->filter(function (EmployeeEntity $employee) {
  192.             return $employee->getPrivileges()->count() > 0;
  193.         });
  194.         $employeeIds $employees->getIds();
  195.         if(empty($employeeIds)) {
  196.             return;
  197.         }
  198.         $upsertData = [];
  199.         foreach ( $newPrivileges as $newPrivilege ) {
  200.             // get the new privilege
  201.             $criteria = (new Criteria())
  202.                 ->addFilter(new EqualsFilter('namespace'$newPrivilege['namespace']))
  203.                 ->addFilter(new EqualsFilter('name'$newPrivilege['name']));
  204.             $privilegeId $this->privilegeRepository->searchIds($criteria$context)->firstId();
  205.             if ($privilegeId) {
  206.                 // assign the new privilege to all employees
  207.                 $employeePrivileges array_values(array_map(function ($employeeId) use ($privilegeId) {
  208.                     return [
  209.                         'employeeId' => $employeeId,
  210.                         'privilegeId' => $privilegeId
  211.                     ];
  212.                 }, $employeeIds));
  213.                 $upsertData array_merge($upsertData$employeePrivileges);
  214.             }
  215.         }
  216.         if (!empty($upsertData)) {
  217.             $this->employeePrivilegeRepository->upsert($upsertData$context);
  218.         }
  219.     }
  220. }