vendor/millerdigital/eleq-pimcore/src/Controller/ApiController.php line 46

Open in your IDE?
  1. <?php
  2. namespace Millerdigital\EleqPimcore\Controller;
  3. use Millerdigital\EleqPimcore\Formatter\ProductFormatter;
  4. use Millerdigital\EleqPimcore\Service\FilterService;
  5. use Pimcore\Model\Asset;
  6. use Pimcore\Model\DataObject\Contact;
  7. use Pimcore\Model\DataObject\Product;
  8. use Pimcore\Model\Element\Tag;
  9. use Pimcore\Model\DataObject;
  10. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  11. use Symfony\Component\HttpFoundation\Request;
  12. use Symfony\Component\HttpFoundation\Response;
  13. use Symfony\Component\HttpFoundation\StreamedResponse;
  14. use Symfony\Component\Routing\Annotation\Route;
  15. use Symfony\Contracts\Translation\TranslatorInterface;
  16. use Symfony\Polyfill\Intl\Icu\Locale;
  17. class ApiController extends AbstractController {
  18.     private TranslatorInterface $translator;
  19.     public function __construct(
  20.         TranslatorInterface $translator,
  21.     ) {
  22.         $this->translator $translator;
  23.     }
  24.     #[Route('/api/product/{slug}'name'product')]
  25.     public function fetchProduct(Request $requeststring $slug): Response
  26.     {
  27.         $language self::getRequestLanguage($request);
  28.         $this->translator->setlocale($language);
  29.         $product Product::getBySlug($slug$language1);
  30.         if ($product && $product->getPath() == "/Products/" && 
  31.             ($request->query->get('public') === null || $product->getShowOnWebsite($language))) {
  32.             $product ProductFormatter::formatProductDetail($product$this->translator$request);
  33.             return $this->json($product200, ["Content-Type" => "application/json"]);
  34.         }
  35.         throw $this->createNotFoundException();
  36.     }
  37.     #[Route('/api/products/{offset}/{limit}'name'products')]
  38.     public function fetchProducts(Request $request$offset 0$limit 20): Response
  39.     {
  40.         $language self::getRequestLanguage($request);
  41.         $this->translator->setlocale($language);
  42.         $productListing = new Product\Listing();
  43.         $productListing->setLocale($language);
  44.         $productListing->addConditionParam('o_path = ?''/Products/');
  45.         // sort by Order product-property
  46.         $productListing->setOrderKey(
  47.             ['order''oo_id',]
  48.         );
  49.         $productListing->setOrder(
  50.             ['desc''asc']
  51.         );
  52.         FilterService::applyFilters($productListing,  $request->query->all());
  53.         $filters FilterService::getFilters($productListing->load(), $this->translator);
  54.         $products $productListing->getItems($offset$limit);
  55.         $products array_map(fn(Product $product) => ProductFormatter::formatProduct($product$this->translator$request), $products);
  56.         $count $productListing->count();
  57.         $result = [ 
  58.             'count' => $count,
  59.             'filters' => $filters,
  60.             'products' => $products
  61.         ];
  62.         if (!$count) {
  63.             $contact Contact::getByELEQID('NPFR');
  64.             if ($contact) {
  65.                 $result['contact'] = ProductFormatter::formatContact($contact$language$request);
  66.             }
  67.         }
  68.         return $this->json($result200, ["Content-Type" => "application/json"]);
  69.     }
  70.     #[Route('/api/search'name'search')]
  71.     public function searchProducts(Request $request): Response
  72.     {
  73.         $language self::getRequestLanguage($request);
  74.         $this->translator->setlocale($language);
  75.         $productListing = new Product\Listing();
  76.         $productListing->setLocale($language);
  77.         $searchQuery preg_replace('/[^a-zA-Z0-9]/'''$_REQUEST['query']);
  78.         $condition 'REPLACE(REGEXP_REPLACE(%s, \'[^0-9a-zA-Z ]\', \'\'), " ", "") like "%%' $searchQuery '%%"';
  79.         $conditions array_map(fn($field) => sprintf($condition$field), ['Name''modelName']);
  80.         $productListing->addConditionParam('(' implode(' OR '$conditions) . ')');
  81.         $limit = isset($_REQUEST['limit']) ? intval($_REQUEST['limit']) : 0;
  82.         if(isset($_REQUEST['public'])) $productListing->addConditionParam('ShowOnWebsite');
  83.         $products self::postProcessSearch($productListing->getItems(0100));
  84.         if (!$limit || sizeof($products) < $limit) {
  85.             $relatedProducts array_map(fn(Product $product) => $product->getRelatedProducts(), $products);
  86.             $productListing = new Product\Listing();
  87.             $productListing->addConditionParam('RelatedProducts REGEXP ?', [',' implode('|'array_keys($products)) . ',']);
  88.             $relatedProducts self::postProcessSearch(array_merge(...$relatedProducts, ...[$productListing->load()]));   
  89.             $products array_merge($products$relatedProducts);
  90.         }
  91.         $tagListing = new Tag\Listing();
  92.         $tagListing->addConditionParam(sprintf($condition'Name'));
  93.         
  94.         $objects array_map(fn(Tag $tag) => Tag::getElementsForTag($tag'object'), $tagListing->load());
  95.         $taggedProducts array_filter(array_merge(...$objects), fn(DataObject $object) => $object instanceof Product);
  96.         $products self::postProcessSearch(array_merge($products$taggedProducts));
  97.         $products array_map(fn(Product $product) => ProductFormatter::formatProduct($product$this->translator$request), $products);
  98.         $assets array_map(fn(Tag $tag) => Tag::getElementsForTag($tag'asset'), $tagListing->load());
  99.         $assets ProductFormatter::formatDocuments(array_merge(...$assets), $language);
  100.         $searchResults array_merge($products$assets);
  101.         $searchResults $limit array_slice($searchResults0$limit) : $searchResults;
  102.         return $this->json($searchResults);
  103.     }
  104.     #[Route('/api/document/{file}/download'name'document')]
  105.     public function fetchDocument(string $file): Response
  106.     {
  107.         $assetListing = new Asset\Listing();
  108.         $assetListing->addConditionParam('filename = ?'$file);
  109.         $asset $assetListing->getItems(01)[0] ?? null;
  110.         if (!$asset) {
  111.             throw $this->createNotFoundException();
  112.         }
  113.         $stream $asset->getStream();
  114.         return new StreamedResponse(function () use ($stream) {
  115.             fpassthru($stream);
  116.         }, 200, [
  117.             'Content-Type' => $asset->getMimeType(),
  118.             'Content-Disposition' => sprintf('attachment; filename="%s"'$asset->getFilename()),
  119.             'Content-Length' => $asset->getFileSize(),
  120.         ]);
  121.     }
  122.     private static function getRequestLanguage(Request $request): ?string
  123.     {
  124.         if ($language $request->query->get('lang')) {
  125.             return $language;
  126.         }
  127.         if ($language $request->getPreferredLanguage()) {
  128.             return substr($language0strrpos($language'_'));
  129.         }
  130.         return Locale::getDefault();
  131.     }
  132.     private static function postProcessSearch(array $products): array
  133.     {
  134.         $products array_map(fn(Product $product) => is_a($product->getParent(), Product::class) ? $product->getParent() : $product$products);
  135.         return array_combine(array_map(fn(Product $product) => $product->getId(), $products), $products);
  136.     }
  137. }