custom/plugins/SteincoProducts/src/Twig/SchoettlerTwigFunctions.php line 112

Open in your IDE?
  1. <?php
  2. namespace Schoettler\SteincoProducts\Twig;
  3. use Schoettler\SteincoProducts\Constants;
  4. use Schoettler\SteincoProducts\SharedFunctions;
  5. use Shopware\Core\Content\Product\Aggregate\ProductVisibility\ProductVisibilityDefinition;
  6. use Shopware\Core\Content\Product\ProductRepository;
  7. use Shopware\Core\Content\Property\Aggregate\PropertyGroupOption\PropertyGroupOptionCollection;
  8. use Shopware\Core\Framework\Context;
  9. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\RangeFilter;
  13. use Shopware\Core\Framework\Routing\Annotation\RouteScope;
  14. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  15. use Shopware\Core\System\SalesChannel\SalesChannelRepository;
  16. use Shopware\Core\System\SystemConfig\SystemConfigService;
  17. use Shopware\Storefront\Page\Product\ProductLoader;
  18. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  19. use Symfony\Component\DependencyInjection\ContainerInterface;
  20. use Symfony\Component\HttpFoundation\JsonResponse;
  21. use Symfony\Component\HttpFoundation\Request;
  22. use Symfony\Component\HttpFoundation\Response;
  23. use Symfony\Component\Routing\Annotation\Route;
  24. use Twig\Extension\AbstractExtension;
  25. use Twig\TwigFunction;
  26. use Shopware\Core\Content\Seo\SeoUrlPlaceholderHandlerInterface;
  27. use Symfony\Component\HttpFoundation\RequestStack;
  28. use Shopware\Core\System\SalesChannel\Context\AbstractSalesChannelContextFactory;
  29. use Doctrine\DBAL\Connection;
  30. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  31. use Shopware\Core\Content\Property\PropertyGroupEntity;
  32. /**
  33. * @RouteScope(scopes={"storefront"})
  34. */
  35. class SchoettlerTwigFunctions extends AbstractExtension
  36. {
  37.     private $systemConfigService;
  38.     private $dbConnection;
  39.     private $session;
  40.     public function __construct(SessionInterface $session,
  41.                                 SystemConfigService $systemConfigService,
  42.                                 Connection $dbConnection)
  43.     {
  44.         $this->session $session;
  45.         $this->systemConfigService $systemConfigService;
  46.         $this->dbConnection $dbConnection;
  47.     }
  48.     public function getFunctions(): array
  49.     {
  50.         return [
  51.             new TwigFunction('shop_url_for_product', [$this'getShopUrlForProduct']),
  52.             new TwigFunction('remote_ip', [$this'getTheRemoteIP']),
  53.             new TwigFunction('intersect', [$this'hasIntersection']),
  54.             new TwigFunction('cat_is_rolle', [$this'catIsRolle']),
  55.             new TwigFunction('cat_is_rad', [$this'catIsRad']),
  56.             new TwigFunction('cat_is_zubehoer', [$this'catIsZubehoer']),
  57.             new TwigFunction('get_tag', [$this'getTag']),
  58.             new TwigFunction('set_tag', [$this'setTag']),
  59.             new TwigFunction('get_property', [$this'getPropertyByDescription'])
  60.         ];
  61.     }
  62.     /**
  63.      * Retrieves a PropertyGroupEntity from an array of properties based on its description.
  64.      *
  65.      * This function iterates through an array of properties and returns the first
  66.      * PropertyGroupEntity that matches the given description.
  67.      *
  68.      * @param array $properties An array of PropertyGroupEntity objects to search through.
  69.      * @param string|null $description The description to match against the property descriptions.
  70.      *
  71.      * @return PropertyGroupEntity|null Returns the matching PropertyGroupEntity if found, or null if not found or if input is invalid.
  72.      */
  73.     public function getPropertyByDescription($properties, ?string $description): ?PropertyGroupEntity
  74.     {
  75.         if (empty($properties) || $description === null || trim($description) === '') {
  76.             return null;
  77.         }
  78.         foreach ($properties as $property) {
  79.             if (!($property instanceof PropertyGroupEntity)) {
  80.                 // Log this error or throw an exception in a development environment
  81.                 // error_log('Invalid element in property array: ' . gettype($property));
  82.                 continue;
  83.             }
  84.             if ($property->getDescription() === $description) {
  85.                 return $property;
  86.             }
  87.         }
  88.         return null;
  89.     }
  90.     public function catIsRolle(): bool
  91.     {
  92.         return $this->getTag() == Constants::TAG_ROLLE;
  93.     }
  94.     public function catIsRad(): bool
  95.     {
  96.         return $this->getTag() == Constants::TAG_RAD;
  97.     }
  98.     public function catIsZubehoer(): bool
  99.     {
  100.         return $this->getTag() == Constants::TAG_ZUBEHOER;
  101.     }
  102.     public function getTag(): string
  103.     {
  104.         return $this->session->get(Constants::TAG_NAMEConstants::TAG_ROLLE);
  105.     }
  106.     public function setTag(string $value): void
  107.     {
  108.         $this->session->set(Constants::TAG_NAME$value);
  109.     }
  110.     public function getTheRemoteIP(): string
  111.     {
  112.         return SharedFunctions::getRemoteIP();
  113.     }
  114.     public function hasIntersection(array $array1, array $array2): bool
  115.     {
  116.         return ! empty( array_intersect($array1$array2));
  117.     }
  118.     public function getShopUrlForProduct(string $productId, ?string $salesChannelId, ?string $languageId): string
  119.     {
  120.         /* The function returns the SEO URL for the requested product and language
  121.          * from the shop sales channel. If there is no corresponding product, an empty
  122.          * string will be returned.
  123.          */
  124.         // HALLO der Name des Verkaufskanals muss hier ausgewertet werden
  125.         if ( $salesChannelId == null || $languageId == null) {
  126.             return '';
  127.         }
  128.         $result '';
  129.         $scShopUUID $this->systemConfigService->get('SteincoProductsController.config.scShopUUID');
  130.         $sql "SELECT scd.url base_url, TRIM( su.seo_path_info) seo_path"
  131.                 " FROM product p, product_visibility pv, sales_channel sc, sales_channel_domain scd, seo_url su, language l"
  132.                 " WHERE p.id = UNHEX('" $productId "')"
  133.                     " AND l.id = UNHEX('" $languageId "')"
  134.                     " AND p.id = pv.product_id"
  135.                     " AND sc.id = UNHEX('" $salesChannelId "')"
  136.                     " AND scd.sales_channel_id = sc.id"
  137.                     " AND scd.language_id = l.id"
  138.                     " AND pv.sales_channel_id = sc.id"
  139.                     " AND su.sales_channel_id = sc.id"
  140.                     " AND su.foreign_key = p.id"
  141.                     " AND su.language_id = l.id"
  142.                     " AND su.is_canonical = true";
  143.         $stmt $this->dbConnection->executeQuery($sql);
  144.         $row =  $stmt->fetchAssociative();
  145.         if ($row) {
  146.             $result $row['base_url'] . '/' $row['seo_path'];
  147.         }
  148.         return $result;
  149.     }
  150. }