custom/plugins/ExpertApiProductFinder-master/src/Storefront/Controller/ExpertSearchController.php line 232

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Expert\ExpertProductFinder\Storefront\Controller;
  4. use GuzzleHttp\Client;
  5. use Shopware\Core\Framework\Context;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  9. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  10. use Shopware\Storefront\Controller\StorefrontController;
  11. use Symfony\Component\HttpFoundation\Request;
  12. use Symfony\Component\HttpFoundation\Response;
  13. use Symfony\Component\HttpFoundation\JsonResponse;
  14. use Symfony\Component\Routing\Annotation\Route;
  15. use Shopware\Core\Framework\Routing\Annotation\RouteScope;
  16. use Shopware\Storefront\Page\GenericPageLoader;
  17. use Shopware\Storefront\Framework\Cache\Annotation\HttpCache;
  18. use Shopware\Core\Content\Product\ProductEntity;
  19. use Shopware\Core\Content\Property\PropertyGroupCollection;
  20. use Shopware\Core\Content\Property\Aggregate\PropertyGroupOption\PropertyGroupOptionCollection;
  21. /**
  22.  * @RouteScope(scopes={"storefront"})
  23.  */
  24. class ExpertSearchController extends StorefrontController
  25. {
  26.     /**
  27.      * @var Client
  28.      */
  29.     private $client;
  30.     /**
  31.      * @var GenericPageLoader
  32.      */
  33.     private $genericPageLoader;
  34.     /**
  35.      * MultiSearchByManufaturer constructor.
  36.      *
  37.      * @param GenericPageLoader $genericPageLoader
  38.      */
  39.     public function __construct(GenericPageLoader $genericPageLoader)
  40.     {
  41.         $this->client = new Client();
  42.         $this->genericPageLoader $genericPageLoader;
  43.     }
  44.     /**
  45.      * @TODO: @HttpCache() // => activates Route caching for this route
  46.      * @Route("/expert/suche", name="frontend.expert.search", options={"seo"="false"}, methods={"GET"})
  47.      */
  48.     public function searchByManufacturer(Request $requestSalesChannelContext $context): Response
  49.     {
  50.         $page $this->genericPageLoader->load($request$context);
  51.         if ($request->query->has('searchterm')) {
  52.             $searchTerms $request->query->get('searchterm');
  53.         } else {
  54.             $manufacturerName $request->query->get('Hersteller');
  55.             $modelName $request->query->get('Modell');
  56.             $typeName $request->query->get('Typ');
  57.             $typeSearchTerms $this->generateSearchTerms($manufacturerName$modelName$typeName);
  58.             $carDetails $this->getCarDetails($typeSearchTerms[0]);
  59.             $searchTerms $typeSearchTerms[1];
  60.         }
  61.         if (!is_null($searchTerms)) {
  62.             $explodedSearchTerms explode('|'$searchTerms);
  63.             $productRepo $this->container->get('product.repository');
  64.             $criteria = new Criteria();
  65.             $criteria->addFilter(new EqualsFilter('product.active'true));
  66.             $criteria->addFilter(new EqualsAnyFilter('product.manufacturerNumber'$explodedSearchTerms));
  67.             $criteria->addAssociation('manufacturer');
  68.             $criteria->addAssociation('seoUrls'); // $criteria->addAssociation('prices'); TODO: relevant for display price ranges
  69.             $criteria->addAssociation('price');
  70.             $criteria->addAssociation('media');
  71.             $criteria->addAssociation('cover');
  72.             $criteria->addAssociation('properties.group');
  73.             $criteria->addAssociation('deliveryTime');
  74.             $result $productRepo->search($criteria$context->getContext())->getEntities(); //SS-288 sortProperties for ProductEntity
  75.             foreach ($result as $product) {
  76.                 if (($properties $product->get('properties')) !== null && $properties instanceof PropertyGroupOptionCollection) {
  77.                     $sortedProperties $this->sortProperties($product);
  78.                     $product->addExtension('sortedProperties'$sortedProperties);
  79.                 }
  80.             }
  81.             $storefrontVariable = [
  82.                 'page' => $page,
  83.                 'resultData' => $result->getElements(),
  84.                 'search' => $searchTerms,
  85.             ];
  86.             if (isset($carDetails)) {
  87.                 $storefrontVariable = [
  88.                     'page' => $page,
  89.                     'resultData' => $result->getElements(),
  90.                     'search' => $searchTerms,
  91.                     "carDetails" => $carDetails,
  92.                 ];
  93.             }
  94.             return $this->renderStorefront(
  95.                 '@ExpertProductFinder/storefront/expert_search/expert-search-page.html.twig',
  96.                  $storefrontVariable
  97.             );
  98.         }
  99.         return $this->renderStorefront(
  100.             '@ExpertProductFinder/storefront/expert_search/expert-search-page.html.twig',
  101.             [
  102.                 'page' => $page,
  103.                 'resultData' => null,
  104.                 'search' => $searchTerms
  105.             ]
  106.         );
  107.     }
  108.     /**
  109.      * @Route("/expert/get-makes", defaults={"_format"="xml"}, name="frontend.expert.getmakes", options={"seo"="false"}, methods={"GET"})
  110.      */
  111.     public function getMakes(Request $request)
  112.     {
  113.         $allowReq $request->get('makes');
  114.         $baseUrl 'https://akkusysws.aldoc.eu';
  115.         $makesUrl '/MMT/mmt.asmx/GetMakes?filter=0&message=""';
  116.         $url $baseUrl $makesUrl;
  117.         if ($allowReq === 'makes') {
  118.             $contents $this->client->get($url)->getBody()->getContents();
  119.             return new Response($contents);
  120.         } else {
  121.             return new Response('No access allowed!');
  122.         }
  123.     }
  124.     /**
  125.      * @Route("/expert/get-models", defaults={"_format"="xml"}, name="frontend.expert.getmodels", options={"seo"="false"}, methods={"GET"})
  126.      */
  127.     public function getModels(Request $request)
  128.     {
  129.         $modelsCode $request->get('model');
  130.         $baseUrl 'https://akkusysws.aldoc.eu';
  131.         $modelsUrl '/MMT/mmt.asmx/GetModels?makecode=' $modelsCode '&message=""';
  132.         $url $baseUrl $modelsUrl;
  133.         $contents $this->client->get($url)->getBody()->getContents();
  134.         return new Response($contents);
  135.     }
  136.     /**
  137.      * @Route("/expert/get-types", defaults={"_format"="xml"}, name="frontend.expert.gettypes", options={"seo"="false"}, methods={"GET"})
  138.      */
  139.     public function getTypes(Request $request)
  140.     {
  141.         $typesCode $request->get('type');
  142.         $baseUrl 'https://akkusysws.aldoc.eu';
  143.         $typesUrls '/MMT/mmt.asmx/GetTypes?modelcode=' $typesCode '&bygrouptype=0&withktyp=1&message=""';
  144.         $url $baseUrl $typesUrls;
  145.         $contents $this->client->get($url)->getBody()->getContents();
  146.         return new Response($contents);
  147.     }
  148.     /**
  149.      * @Route("/expert/get-type-details", defaults={"_format"="xml"}, name="frontend.expert.gettypedetails", options={"seo"="false"}, methods={"GET"})
  150.      */
  151.      public function getTypeDetails(Request $request)
  152.      {
  153.          $typesCode $request->get('type');
  154.          $baseUrl 'https://akkusysws.aldoc.eu';
  155.          $typesUrls '/MMT/mmt.asmx/GetTypeDetails?typecode=' $typesCode '&bygrouptype=0&withktyp=1&message=""';
  156.          $url $baseUrl $typesUrls;
  157.  
  158.          $contents $this->client->get($url)->getBody()->getContents();
  159.  
  160.          return new Response($contents);
  161.      }
  162.      public function getCarDetails(string $typesCode)
  163.      {
  164.          $baseUrl 'https://akkusysws.aldoc.eu';
  165.          $typesUrls '/MMT/mmt.asmx/GetTypeDetails?typecode=' $typesCode '&bygrouptype=0&withktyp=1&message=""';
  166.          $url $baseUrl $typesUrls;
  167.  
  168.          $contents $this->client->get($url)->getBody()->getContents();
  169.          $xml = new \SimpleXMLElement($contents);
  170.          return [   'makename' => (string) $xml->makename,
  171.                     'modelname' => (string) $xml->modelname,
  172.                     'type_from' => (string) $xml->type_from,
  173.                     'type_till' => (string) $xml->type_till,
  174.                     'kw_cat' => (string) $xml->kw_cat,
  175.                     'typename' => (string) $xml->typename
  176.                 ];
  177.      }
  178.     /**
  179.      * @Route("/expert/get-by-hsn-tsn", defaults={"_format"="xml"}, name="frontend.expert.getbyhsntsn", options={"seo"="false"}, methods={"GET"})
  180.      */
  181.     public function getByHsnTsn(Request $request)
  182.     {
  183.         $kba $request->get('kba');
  184.         $baseUrl 'https://akkusysws.aldoc.eu/MMT/mmt.asmx/GetTypesByIdentifier?';
  185.         $kbaUrl 'CollectionToQuery=KBA&beginOfIdentifier=' $kba '&StartAtIndex=0&maxNrOfRecs=100&message=h';
  186.         $url $baseUrl $kbaUrl;
  187.         $contents $this->client->get($url)->getBody()->getContents();
  188.         return new Response($contents);
  189.     }
  190.     /**
  191.      * @Route("/expert/get-results", defaults={"_format"="xml"}, name="frontend.expert.getresults", options={"seo"="false"}, methods={"GET"})
  192.      */
  193.     public function getResults(Request $request)
  194.     {
  195.         $typecode $request->get('typecode');
  196.         $url 'https://akkusysws.aldoc.eu:443/PartServices/api/Parts/2/' $typecode '?language=en&message=%22%22';
  197.         $contents $this->client->get($url)->getBody()->getContents();
  198.         return new Response($contents);
  199.     }
  200.     /**
  201.      * @TODO: @HttpCache() // => activates Route caching for this route
  202.      * @Route("/expert/get-body-type-info", defaults={"_format"="xml"}, name="frontend.expert.getbodytypeinfo", options={"seo"="false"}, methods={"GET"})
  203.      */
  204.     public function getBodyTypeInfo(Request $request)
  205.     {
  206.         $lang $request->get('lang');
  207.         $baseUrl 'https://akkusysws.aldoc.eu';
  208.         $modelsUrl '/MMT/mmt.asmx/GetBodytypesInfo?lang=' $lang '&message=""';
  209.         $url $baseUrl $modelsUrl;
  210.         $contents $this->client->get($url)->getBody()->getContents();
  211.         return new Response($contents);
  212.     }
  213.     private function sortProperties(ProductEntity $product): PropertyGroupCollection
  214.     {
  215.         $properties $product->getProperties();
  216.         if ($properties === null) {
  217.             return new PropertyGroupCollection();
  218.         }
  219.         $sorted = [];
  220.         foreach ($properties as $option) {
  221.             $origin $option->getGroup();
  222.             if (!$origin || !$origin->getVisibleOnProductDetailPage()) {
  223.                 continue;
  224.             }
  225.             $group = clone $origin;
  226.             $groupId $group->getId();
  227.             if (\array_key_exists($groupId$sorted)) {
  228.                 \assert($sorted[$groupId]->getOptions() !== null);
  229.                 $sorted[$groupId]->getOptions()->add($option);
  230.                 continue;
  231.             }
  232.             if ($group->getOptions() === null) {
  233.                 $group->setOptions(new PropertyGroupOptionCollection());
  234.             }
  235.             \assert($group->getOptions() !== null);
  236.             $group->getOptions()->add($option);
  237.             $sorted[$groupId] = $group;
  238.         }
  239.         $collection = new PropertyGroupCollection($sorted);
  240.         $collection->sortByPositions();
  241.         $collection->sortByConfig();
  242.         return $collection;
  243.     }
  244.     private function generateSearchTerms($manufacturerName$modelName$typeName): ?array
  245.     {
  246.         if (!empty($manufacturerName)) {
  247.             $makeCode $this->getMakeCodeByName($manufacturerName);
  248.             if (!empty($makeCode) && !empty($modelName)) {
  249.                 $modelCode $this->getModelCodeByName($makeCode$modelName);
  250.                 if (!empty($makeCode) && !empty($modelName)) {
  251.                     $typeCode $this->getTypeCodeByName($modelCode$typeName);
  252.                     if (!empty($typeCode)) {
  253.                         $results $this->getResultsByType($typeCode);
  254.                         if (array_key_exists('Articles'$results)) {
  255.                             $searchTerms = [];
  256.                             foreach ($results['Articles'] as $item) {
  257.                                 array_push($searchTerms$item['Reference']);
  258.                             }
  259.                             return [$typeCodeimplode('|'$searchTerms)];
  260.                         }
  261.                     }
  262.                 }
  263.             }
  264.         }
  265.         return null;
  266.     }
  267.     private function getMakeCodeByName($manufacturerName): ?string
  268.     {
  269.         $baseUrl 'https://akkusysws.aldoc.eu';
  270.         $makesUrl '/MMT/mmt.asmx/GetMakes?filter=0&message=""';
  271.         $url $baseUrl $makesUrl;
  272.         $response =  $this->client->get($url)->getBody()->getContents();
  273.         $xml   simplexml_load_string($response'SimpleXMLElement'LIBXML_NOCDATA);
  274.         $data json_decode(json_encode($xml), TRUE);
  275.         if (array_key_exists('makes'$data)) {
  276.             foreach ($data['makes']['Make'] as $make) {
  277.                 if (strtolower($make['makename']) == strtolower($manufacturerName)) {
  278.                     return $make['makecode'];
  279.                 }
  280.             }
  281.         }
  282.         return null;
  283.     }
  284.     private function getModelCodeByName($makeCode$modelName): ?string
  285.     {
  286.         $baseUrl 'https://akkusysws.aldoc.eu';
  287.         $modelsUrl '/MMT/mmt.asmx/GetModels?makecode=' $makeCode '&message=""';
  288.         $url $baseUrl $modelsUrl;
  289.         $response =  $this->client->get($url)->getBody()->getContents();
  290.         $xml   simplexml_load_string($response'SimpleXMLElement'LIBXML_NOCDATA);
  291.         $data json_decode(json_encode($xml), TRUE);
  292.         if (array_key_exists('models'$data)) {
  293.             foreach ($data['models']['Model'] as $model) {
  294.                 if (strtolower($model['modelname']) == strtolower($modelName)) {
  295.                     return $model['modelcode'];
  296.                 }
  297.             }
  298.         }
  299.         return null;
  300.     }
  301.     private function getTypeCodeByName($modelCode$typeName): ?string
  302.     {
  303.         $baseUrl 'https://akkusysws.aldoc.eu';
  304.         $typesUrls '/MMT/mmt.asmx/GetTypes?modelcode=' $modelCode '&bygrouptype=0&withktyp=1&message=""';
  305.         $url $baseUrl $typesUrls;
  306.         $response =  $this->client->get($url)->getBody()->getContents();
  307.         $xml   simplexml_load_string($response'SimpleXMLElement'LIBXML_NOCDATA);
  308.         $data json_decode(json_encode($xml), TRUE);
  309.         if (array_key_exists('types'$data)) {
  310.             try {
  311.                 if (is_string(array_key_first($data['types']['Type']))) {
  312.                     $model $data['types']['Type'];
  313.                     if (strtolower($model['typename']) == strtolower($typeName)) {
  314.                         return $model['typecode'];
  315.                     }
  316.                 } else {
  317.                     foreach ($data['types']['Type'] as $model) {
  318.                         if (strtolower($model['typename']) == strtolower($typeName)) {
  319.                             return $model['typecode'];
  320.                         }
  321.                     }
  322.                 }
  323.             } catch (\Exception $e) {
  324.                 return null;
  325.             }
  326.         }
  327.         return null;
  328.     }
  329.     private function getResultsByType($typecode): ?array
  330.     {
  331.         $url 'https://akkusysws.aldoc.eu:443/PartServices/api/Parts/2/' $typecode '?language=en&message=%22%22';
  332.         $response =  $this->client->get($url)->getBody()->getContents();
  333.         $data json_decode($responseTRUE);
  334.         return $data;
  335.     }
  336. }