custom/plugins/SteincoProducts/src/Subscriber/ProductSubscriber.php line 79

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Schoettler\SteincoProducts\Subscriber;
  3. use Schoettler\SteincoProducts\Constants;
  4. use Schoettler\SteincoProducts\Struct\PropertiesStruct;
  5. use Shopware\Core\Content\Product\ProductEntity;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
  7. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  8. use Shopware\Core\Content\Product\ProductEvents;
  9. use Shopware\Core\Checkout\Customer\Event\CustomerRegisterEvent;
  10. use Shopware\Core\Checkout\Customer\CustomerEvents;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityDeletedEvent;
  13. use Shopware\Core\System\User\UserEvents;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  16. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  17. use Shopware\Core\Content\Property\Aggregate\PropertyGroupOption\PropertyGroupOptionEntity;
  18. use Shopware\Core\Framework\Context;
  19. use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
  20. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  21. class ProductSubscriber implements EventSubscriberInterface
  22. {
  23.     /**
  24.      * @var EntityRepositoryInterface
  25.      */
  26.     private $propertyRepository;
  27.     private $propertyGroupTranslationsRepository;
  28.     private $productRepository;
  29.     private $product_propertyRepository;
  30.     private $propertyGroupRepository;
  31.     private $propertyGroupOptionRepository;
  32.     private $session;
  33.     public function __construct(EntityRepositoryInterface $propertyRepository,
  34.         EntityRepositoryInterface $propertyGroupTranslationsRepository,
  35.         EntityRepositoryInterface $productRepository,
  36.         EntityRepositoryInterface $product_propertyRepository,
  37.         EntityRepositoryInterface $propertyGroupRepository,
  38.         EntityRepositoryInterface $propertyGroupOptionRepository,
  39.         SessionInterface $session)
  40.     {
  41.         $this->propertyRepository $propertyRepository;
  42.         $this->propertyGroupTranslationsRepository $propertyGroupTranslationsRepository;
  43.         $this->productRepository $productRepository;
  44.         $this->product_propertyRepository $product_propertyRepository;
  45.         $this->propertyGroupRepository $propertyGroupRepository;
  46.         $this->propertyGroupOptionRepository $propertyGroupOptionRepository;
  47.         $this->session $session;
  48.     }
  49.     public static function getSubscribedEvents(): array
  50.     {
  51.         // Return the events to listen to as array like this:  <event to listen to> => <method to execute>
  52.         return [
  53.             ProductEvents::PRODUCT_LOADED_EVENT => 'onProductLoaded',
  54.             ProductEvents::PRODUCT_WRITTEN_EVENT => 'onProductWritten',
  55.             ProductEvents::PRODUCT_LISTING_CRITERIA => 'onProductListing'
  56.         ];
  57.     }
  58.     public function onProductListing(ProductListingCriteriaEvent $event): void
  59.     {
  60.         // Aktuell gesetztes Tag ermitteln "Rolle", "Rad" oder "Zubehoer"
  61.         $productTag $this->session->get(Constants::TAG_NAMEConstants::TAG_ROLLE);
  62.         // dump( $productTag);
  63.         $criteria $event->getCriteria();
  64.         if ($criteria) {
  65.             $criteria->addFilter(
  66.                 new EqualsFilter('product.tags.name'$productTag)
  67.             );
  68.         }
  69.     }
  70.     public function onProductLoaded(EntityLoadedEvent $event): void
  71.     {
  72.         /** @var ProductEntity $productEntity */
  73.         foreach ($event->getEntities() as $productEntity) {
  74.             //$properties = new PropertiesStruct();
  75.             //$properties->property_options = $this->get_product_properties($productEntity);
  76.             $properties $this->get_propertystruct($productEntity$event->getContext());
  77.             $productEntity->addExtension('properties'$properties);
  78.         }
  79.     }
  80.     public function get_propertystruct(ProductEntity $product$context) : PropertiesStruct
  81.     {
  82.         $result = new PropertiesStruct();
  83.         $properties $product->getProperties();
  84.         $propertyOptions null// array of propertyGroupOptionElements
  85.         if(!$context) {
  86.             $context = \Shopware\Core\Framework\Context::createDefaultContext();
  87.         }
  88.         if ($properties) {
  89.             $propertyOptions $properties->getElements();
  90.         } else {
  91.             $propertyids $product->getPropertyIds();
  92.             if($propertyids){
  93.                 /** @var EntityCollection $propentitiesEntities */
  94.                 $propentitiesEntities $this->propertyRepository->search(
  95.                 (new Criteria(array_keys(array_flip($propertyids))))->addAssociation('group'),
  96.                 $context
  97.                 );
  98.                 $propertyOptions $propentitiesEntities->getEntities()->getElements();
  99.             }
  100.         }
  101.         $counter 0;
  102.         if(!empty($propertyOptions)){
  103.             foreach( $propertyOptions as $value) {
  104.                 $name$this->getNameWithDefault$value$context);
  105.                 $description null;
  106.                 $groupName "Unnamed_" .$counter;
  107.                 if($value->getGroup()){
  108.                    $description $value->getGroup()->getDescription();
  109.                    $groupName $value->getGroup()->getName();
  110.                 }
  111.                 if(!$description){
  112.                     // to prevent nullpointerexceptions
  113.                     // following if-clause prevents a nullpointerexception in ajax-requests in backend. 
  114.                     // Not sure what causes this, as there were various calls on group in the code above.
  115.                     if($value->getGroup()){
  116.                     $description $this->fetchDefaultValueForGroup$value->getGroup(), "description"$context);
  117.                     } else {
  118.                       $description 'No_Group_' .$counter++;
  119.                     }
  120.                     if(!$description) {
  121.                         // to prevent nullpointerexceptions
  122.                         $description 'Unnamed_' $counter++;
  123.                     }
  124.                 }
  125.                 if(!$groupName){
  126.                     // to prevent nullpointerexceptions
  127.                     $groupName $this->fetchDefaultValueForGroup$value->getGroup(), "name"$context);
  128.                     if(!$groupName) {
  129.                         // to prevent nullpointerexceptions
  130.                         $groupName 'Unnamed_' $counter++;
  131.                     }
  132.                 }
  133.                 // TODO: Branche needs some special parameters
  134.                 // for the future: we need to get the ids for the unlocalized property and compare to that
  135.                 if($description === "Branche") {
  136.                     $result->branchen[] = $name;
  137.                 }
  138.                 if($description === "Anwendungsbereiche"){
  139.                     $result->anwendungen[] = $name;
  140.                 }
  141.                 if ($description === 'Rolle_Bauhoehe_mm')
  142.                 {
  143.                     $result->bauhoehe $name;
  144.                 } 
  145.                 if ($description === 'Rad_Durchmesser_mm')
  146.                 { 
  147.                     $result->durchmesser $name;
  148.                 }
  149.                 if ($description === 'Rolle_Tragkraft_kg')
  150.                 {
  151.                     $result->tragkraft $name;
  152.                 }
  153.                 if(array_key_exists($description$result->property_options)){
  154.                     $result->property_options[$description]['name'] = $groupName;
  155.                     $result->property_options[$description]['value'] = 
  156.                       $result->property_options[$description]['value'] . ", " $name;
  157.                 }
  158.                 else {
  159.                     $result->property_options[$description]['name'] = $groupName
  160.                     $result->property_options[$description]['value'] = $name;
  161.                 }
  162.             }
  163.         }
  164.         return $result;
  165.     }
  166.     public function onProductWritten(EntityWrittenEvent $event)
  167.     {
  168.         //look at the written Product
  169.         $productID null;
  170.         $writeResult $event->getWriteResults()[0];
  171.         $payload $event->getPayLoads()[0];
  172.         if($payload && array_key_exists('id'$payload)){
  173.             $productID $event->getPayLoads()[0]['id'];
  174.         } else {
  175.             // we need to get the id from the writeResult
  176.             $writeResult $event->getWriteResults()[0];
  177.             $productID $writeResult->getPrimaryKey();
  178.         }
  179.         // look into the writeresult if stock has been changed
  180.         
  181.        // if ( array_key_exists('stock', $payload))
  182.         {
  183.             // get the product
  184.             $productSearchCriteria = new Criteria();
  185.             $productSearchCriteria->addFilter(new EqualsFilter('id' $productID));
  186.             $productSearchCriteria->addAssociation('properties');
  187.             $productSearchCriteria->addAssociation('properties.group');
  188.             $entity $this->productRepository->search(
  189.                 $productSearchCriteria,
  190.                 \Shopware\Core\Framework\Context::createDefaultContext()
  191.              )->first();
  192.             $stock $entity->getStock();
  193.             $available_stock $entity->getAvailableStock();
  194.             $properties $entity->getProperties()->getElements();
  195.             $current_availabiltyPropertyOption null;
  196.             foreach ($properties as $propertyOption) {
  197.                 $propertyGroup $propertyOption->getGroup()->getDescription();
  198.                 if($propertyGroup == 'Filter_Verfuegbarkeit'
  199.                 {
  200.                     $current_availabiltyPropertyOption $propertyOption;
  201.                     $this->availabilityFilterPropertyGroupId $propertyOption->getGroup()->getId();                    
  202.                     break;
  203.                 }
  204.             }
  205.             if ($stock 0)
  206.             {
  207.                 // dump("Stock > 0");
  208.                 if($available_stock 0)
  209.                 {
  210.                     //check if "Auf Lager" is set. if not, set it ( and delete current setting).
  211.                     if (!$current_availabiltyPropertyOption || $current_availabiltyPropertyOption->getPosition() != 1)
  212.                     {
  213.                         //search the correct Propertyoption
  214.                         $this->changeAvailabilityPropertyOption($current_availabiltyPropertyOption1$productID);
  215.                     }
  216.                 } else
  217.                 {
  218.                     //check if "aktuell nicht verfügbar" is set. if not, set it ( and delete current setting).(pos 2)
  219.                     if (!$current_availabiltyPropertyOption ||$current_availabiltyPropertyOption->getPosition() != 2)
  220.                     {
  221.                         //search the correct Propertyoption
  222.                         //delete wrong option
  223.                         //set correct option
  224.                         $this->changeAvailabilityPropertyOption($current_availabiltyPropertyOption2$productID);
  225.                     }
  226.                 }
  227.             } else {
  228.                 //check if "Auf Anfrage" is set. if not, set it ( and delete current setting). (pos 3)
  229.                 if (!$current_availabiltyPropertyOption || $current_availabiltyPropertyOption->getPosition() != 3)
  230.                     {
  231.                         //search the correct Propertyoption
  232.                         //delete wrong option
  233.                         //set correct option
  234.                         $this->changeAvailabilityPropertyOption($current_availabiltyPropertyOption3$productID);
  235.                     }
  236.             }
  237.         }
  238.     }
  239.     private function changeAvailabilityPropertyOption($currentPropertyOption,int $positionToSet$productId){
  240.         // delete the current product_property entry
  241.         if ($currentPropertyOption) {
  242.             $currentPropertyId $currentPropertyOption->getId();
  243.                 $this->product_propertyRepository->delete([
  244.                        [
  245.                          'productId' => $productId,
  246.                           'optionId' => $currentPropertyId
  247.                        ]
  248.                   ], 
  249.                   \Shopware\Core\Framework\Context::createDefaultContext()
  250.                 );
  251.         } else {
  252.             $propertygroupFilter = new EqualsFilter('description''Filter_Verfuegbarkeit');
  253.             $propertyCriteria = new Criteria();
  254.             $propertyCriteria->addFilter($propertygroupFilter);
  255.             $propertySearchResult $this->propertyGroupRepository->search($propertyCriteria,
  256.             \Shopware\Core\Framework\Context::createDefaultContext()
  257.             )->first();
  258.             $this->availabilityFilterPropertyGroupId $propertySearchResult->getId();
  259.         }
  260.         // find correct option
  261.         $search_criteria = new Criteria();
  262.         $optiongroupFilter = new EqualsFilter('group.id'$this->availabilityFilterPropertyGroupId);
  263.         $positionfilter = new EqualsFilter('position'$positionToSet);
  264.         $search_criteria->addFilter($optiongroupFilter);
  265.         $search_criteria->addFilter($positionfilter);
  266.         $searchResult $this->propertyRepository->search($search_criteria,
  267.         \Shopware\Core\Framework\Context::createDefaultContext())->first();
  268.         $updateJson = [['id'=>$productId'properties'=>[['id'=>$searchResult->getId()]]]];
  269.         //set the new association
  270.         $this->productRepository->update$updateJson , \Shopware\Core\Framework\Context::createDefaultContext() );
  271.     }
  272.     private function getNameWithDefault$property$context): ?string {
  273.         $value $property->getName();
  274.         if ( !$value) {
  275.             return $this->fetchDefaultValueForProperty($property'name'$context);
  276.         }
  277.         return $value;
  278.     }
  279.     private function fetchDefaultValueForProperty($propertystring $field$context): ?string {
  280.         $defaultContext $this->getDefaultContext($context);
  281.         $criteria = new Criteria([$property->getId()]);
  282.         $criteria->addAssociation('translations');
  283.         // $criteria->addFilter(new EqualsFilter('language_id', '94F6E662FA184F45A31A047B538F249D'));
  284.         $defaultProperty $this->propertyGroupOptionRepository->search($criteria$defaultContext)->first();
  285.         if ($defaultProperty) {
  286.             $translations $defaultProperty->getTranslations();
  287.             $englishTranslation $translations->filterByLanguageId('94f6e662fa184f45a31a047b538f249d')->first();
  288.             if ($englishTranslation) {
  289.                 return $englishTranslation->get($field);
  290.             }
  291.         }
  292.         return null;
  293.     }
  294.     private function fetchDefaultValueForGroup($groupstring $field$context): ?string {
  295.         $defaultContext $this->getDefaultContext($context);
  296.         $criteria = new Criteria([$group->getId()]);
  297.         $criteria->addAssociation('translations');
  298.         $defaultGroup $this->propertyGroupRepository->search($criteria$defaultContext)->first();
  299.         if ($defaultGroup) {
  300.             $translations $defaultGroup->getTranslations();
  301.             $englishTranslation $translations->filterByLanguageId('94f6e662fa184f45a31a047b538f249d')->first();
  302.             if ($englishTranslation) {
  303.                 return $englishTranslation->get($field);
  304.             }
  305.         }
  306.         return null;
  307.     }
  308.     private function getDefaultContext($context): Context
  309.     {
  310.         return Context::createDefaultContext();
  311.     }
  312. }