src/Controller/ProductController.php line 41

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use AdvancedObjectSearchBundle\Service;
  4. use App\Service\ElasticSearchService;
  5. use Carbon\Carbon;
  6. use Pimcore\Controller\FrontendController;
  7. use Pimcore\Model\DataObject\Book;
  8. use Pimcore\Model\DataObject\OnixProduct;
  9. use Pimcore\Model\DataObject\ClassDefinition;
  10. use Pimcore\Model\DataObject\Fieldcollection;
  11. use Pimcore\Model\DataObject\InventoryItem;
  12. use Pimcore\Model\DataObject\Serie;
  13. use Pimcore\Model\Document;
  14. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  15. use Symfony\Component\HttpFoundation\Request;
  16. use Symfony\Component\HttpFoundation\Response;
  17. use App\Service\DolpoSearchService;
  18. use Symfony\Component\Routing\Annotation\Route; 
  19. use function PHPUnit\Framework\isEmpty;
  20. class ProductController extends FrontendController
  21. {
  22.     private $map_availability=[
  23.         'InStock'=>"<p class='edition__shipping shipping-48h'>  En stock </a>",
  24.         'POD'=>"<p class='edition__shipping shipping-purple'> Imprimé sur demande </a>",
  25.         'NotYetAvailable'=>"<p class='edition__shipping shipping-purple'> Pas encore disponible </a>",
  26.         'TemporaryUnavailable'=>"<p class='edition__shipping shipping-purple'> Momentanément indisponible éditeur </a>",
  27.         'PublisherOutOfStock'=>"<p class='edition__shipping shipping-nondis'> Rupture éditeur </a>",
  28.         'PublisherReprint'=>"<p class='edition__shipping shipping-nondis'> En Réimpression </a>",
  29.         'EditorUnavailable'=>"<p class='edition__shipping shipping-nondis'>Indisponible éditeur</p>",
  30.         'Retired'=>"<p class='edition__shipping shipping-nondis'>Retiré de la vente</p>",
  31.         'EditorNoCommand'=>"<p class='edition__shipping shipping-nondis'>Pas de commande pour cet éditeur</p>"
  32.     ];
  33.     public function editionPageAction(Request $request, Document $document, DolpoSearchService $dolpoSearchService): Response
  34.     {
  35.         $param=[];
  36.         if ($request->get('isbn')){
  37.             $edition = OnixProduct::getByEan($request->get('isbn'),['limit' => 1]);
  38.             if(empty($edition)){
  39.                 throw new NotFoundHttpException('Edition needed');
  40.             }
  41.             else{
  42.                 $BookDolpoId = $edition->getDolpoId();
  43.             }
  44.             if (!empty($BookDolpoId)) {
  45.                 // Redirige vers la page du livre
  46.                 return $this->redirectToRoute('product', ['dolpoId' => $BookDolpoId, 'productId' => $edition->getId()]);
  47.             }
  48.             
  49.             
  50.             $param['item'] = $edition; 
  51.             //dump($edition->getAuthors());
  52.             
  53.             // Affectation des valeurs aux propriétés de l'objet
  54.             $availabilityLabel = $edition->getAvailabilityLabel();
  55.             //isAdminUser
  56.             $user = \Pimcore\Tool\Session::getReadonly()->get("user");
  57.             $isPimcoreAdminUser= ($user !== null);
  58.             
  59.             $param['isPimcoreAdminUser'] = $isPimcoreAdminUser;
  60.             $param['availabilityLabel'] = $availabilityLabel;
  61.             $param['document'] = \Pimcore\Model\Document::getById(1);
  62.             $param['document']->setTitle($edition->getLongTitle());
  63.             $param['document']->setDescription(\App\Service\Website\Tool\Text::cutStringRespectingWhitespace($edition->getDescription(),250));
  64.             $prodcutFormats = ClassDefinition::getById($edition->getClassId())->getFieldDefinition('Format')->getOptions();
  65.             foreach ($prodcutFormats as $productFormat) {
  66.                 $prodcutFormatArray[$productFormat['value']] = $productFormat['key'];
  67.             }
  68.             $param['prodcutFormats'] = $prodcutFormatArray;
  69.             return $this->render('product/productEdition.html.twig', $param);
  70.         }
  71.     }
  72.    
  73.     public function productPageAction(Request $request, Document $document, DolpoSearchService $dolpoSearchService): Response
  74.     {
  75.         $param = [];
  76.         if ($request->get('dolpoId')) {
  77.             $item = Book::getByDolpoId($request->get('dolpoId'));
  78.             $book = $item->load();
  79.             $collectionItem = null;
  80.             $title = null;
  81.             $subtitle = null;
  82.             $editions = null;
  83.             $selectedEdition = null;
  84.             $displayedEditions=null;
  85.             $image = null;
  86.             $productScores = [];
  87.             $productScoresOrder = [];
  88.             $productScoresRating = [];
  89.             $productScoresRatingArray = [];
  90.             $prodcutFormats = [];
  91.             $prodcutFormatArray = [];
  92.             if (empty($book)) {
  93.                 //throw new NotFoundHttpException('Book needed');
  94.                 return $this->redirect('/');
  95.             } else {
  96.                 $book = $book[0];
  97.                 $title = $book->getTitle();
  98.                 $image = $book->getItemThumbnail('lg');
  99.                
  100.             }
  101.             // New selection options dynamic
  102.             // Get All options dynamic for this item
  103.             $productScoresRatingArray = $book->getItemRatingOptions();
  104.             // Avis Dolpo : ex: A lire pour les accros au genre
  105.             if ($book->getReview()) {
  106.                 foreach ($book->getReview()->getItems() as $collection) {
  107.                     if ($collection instanceof Fieldcollection\Data\Review) {
  108.                         // $productScoresRating = $collection->getDefinition()->getFieldDefinition('Rating')->getoptions();
  109.                         $collectionItem = $collection;
  110.                         break;
  111.                     }
  112.                 }
  113.             }
  114.             
  115.             
  116.             if( $collectionItem != null ){
  117.                 $ratingsCriterias = $collectionItem->getRatingCriteria();
  118.                 if(count($ratingsCriterias)) {
  119.                     foreach($ratingsCriterias as $reviewCrit) {
  120.                         $dataRating = ($reviewCrit->getData());
  121.                         $productScores[$reviewCrit->getObjectId()][] = $dataRating['Rating'];
  122.                     }
  123.                 }
  124.             }
  125.             
  126.             $finalProductScores = [];
  127.             // Calcul average
  128.             foreach($productScores as $idCriteria => $infos){
  129.                 $criteria = \Pimcore\Model\DataObject\ReviewCriteria::getById($idCriteria);
  130.                 
  131.                 $color = '#36A9E1';
  132.                 if($criteria->getProperty("color") != ''){
  133.                     $color = $criteria->getProperty("color");
  134.                 }
  135.                 
  136.                 
  137.                 $label = $criteria->getKey();
  138.                 // label to override key
  139.                 if($criteria->getLabel() != ''){
  140.                     $label = $criteria->getLabel();
  141.                 }
  142.                 // Label front if needed
  143.                 if($criteria->getProperty("label") != ''){
  144.                     $label = $criteria->getProperty("label");
  145.                 }
  146.                 
  147.                 $position = $idCriteria; // todo to change by custom property with position (like label)
  148.                 
  149.                 $finalProductScores[$position] = [
  150.                     'label' => $label,
  151.                     'color' => $color,
  152.                     'score' => (int) ceil(array_sum($infos) / count($infos))
  153.                     ];
  154.             }
  155.             
  156.             $productScores = $finalProductScores;
  157.             
  158.             // ---------------------------------
  159.             
  160.             
  161.             
  162.             // Title and subtitle
  163.             $serie=null;
  164.             if(!empty($book->getSerieId())){
  165.                 $serie=Serie::getById($book->getSerieId());
  166.             }
  167.             
  168.             if (!empty($serie)) {
  169.                 $title = $serie->getName();
  170.                 foreach ($serie->getVolumes() as $bookAdded) {
  171.                     if ($bookAdded->getObjectId() === $book->getId()) {
  172.                         if(array_key_exists( 'Tome', $bookAdded->getData())){
  173.                             if (count(explode(":", $book->getTitle())) > 1) {
  174.                                 $subtitle = "Tome " . $bookAdded->getData()['Tome'] . " " . explode(":", $book->getTitle())[1];
  175.                             } else {
  176.                                 $subtitle = "Tome " . $bookAdded->getData()['Tome'] . " " . $book->getTitle();
  177.                             }
  178.                         }
  179.                         else{
  180.                             
  181.                         }
  182.                     }
  183.                 }
  184.             }
  185.             // Edition 
  186.             $editionIds = [];
  187.             $inventoryItemProduct = [];
  188.             if (!empty($book->getEditions())) {
  189.                 $editions = $book->getAllSortedEditions();
  190.                 $selectedEdition = $editions[0]['edition'];
  191.                 $i=0;
  192.                 $hasInStockArticles = false;
  193.                 $hasOrderedArticles = false;
  194.                 $hasOrderableArticles = false;
  195.                 $displayed_formats=[];
  196.                 foreach ($editions as $editionArray) {
  197.                     $edition=$editionArray['edition'];
  198.                     
  199.                                         
  200.                     if (empty($editionArray['Format']) or ($editionArray['Format']=='')){
  201.                         $editionArray['Format']='vide';
  202.                     }
  203.                     if ($request->get('productId') and $request->get('productId') == $edition->getId()) {
  204.                         $inventoryItemProduct[$edition->getId()] = $edition->getAvailabilityLabel();
  205.                         $selectedEdition = $edition;
  206.                         $displayedEditions[]=$edition;
  207.                         $displayed_formats[]=$editionArray['Format'];
  208.                     }
  209.                     elseif($editionArray['Availability']=='InStock'){
  210.                         $inventoryItemProduct[$edition->getId()] = $this->map_availability[$editionArray['Availability']];
  211.                         $hasInStockArticles=true;
  212.                         $displayedEditions[]=$edition;
  213.                         $displayed_formats[]=$editionArray['Format'];
  214.                         $i++;
  215.                     }
  216.                     elseif($editionArray['Availability']=='Ordered'){
  217.                         $inventoryItemProduct[$edition->getId()] = "<p class='edition__shipping shipping-48h'>  En arrivage - livré en " . $editionArray['Delay'] . ($editionArray['Delay'] == 1 ? 'jour' : ' jours') . "</a>";
  218.                         $hasOrderedArticles=true;
  219.                         $displayedEditions[]=$edition;
  220.                         $displayed_formats[]=$editionArray['Format'];
  221.                         $i++;
  222.                     }
  223.                     elseif(in_array($editionArray['Format'], $displayed_formats)){
  224.                         //on n'affiche pas l'édition si le format est déjà dans les formats proposés
  225.                     }
  226.                     elseif($editionArray['Availability']=='Orderable'){
  227.                         $inventoryItemProduct[$edition->getId()] = "<p class='edition__shipping shipping-48h'> livré en " . $editionArray['Delay'] . ($editionArray['Delay'] == 1 ? 'jour' : ' jours') . "</a>";
  228.                         $hasOrderableArticles=true;
  229.                         $displayedEditions[]=$edition;
  230.                         $displayed_formats[]=$editionArray['Format'];
  231.                         $i++;
  232.                     }
  233.                     elseif($editionArray['Availability']=='PreOrderable'){
  234.                         $inventoryItemProduct[$edition->getId()] = "<p class='edition__shipping shipping-48h'> Précommande </a>";
  235.                         $hasOrderableArticles=true;
  236.                         $displayedEditions[]=$edition;
  237.                         $displayed_formats[]=$editionArray['Format'];
  238.                         $i++;
  239.                     }
  240.                     elseif(array_key_exists($editionArray['Availability'], $this->map_availability)  
  241.                            && !$hasOrderedArticles && !$hasInStockArticles && !$hasOrderableArticles){
  242.                         $inventoryItemProduct[$edition->getId()] = $this->map_availability[$editionArray['Availability']];
  243.                         $displayedEditions[]=$edition;
  244.                         $displayed_formats[]=$editionArray['Format'];
  245.                         $i++;
  246.                     }
  247.                     else{
  248.                         
  249.                     }
  250.                    
  251.                    
  252.                    if(!$hasOrderedArticles and !$hasInStockArticles and ($i>=3)){
  253.                        break;
  254.                    }
  255.                    
  256.                 }
  257.             }
  258.             // images
  259.             
  260.             if ($selectedEdition) {
  261.                 $prodcutFormats = ClassDefinition::getById($selectedEdition->getClassId())->getFieldDefinition('Format')->getOptions();
  262.                 
  263.                 if ($selectedEdition->getLargeCover()->getDirect()) {
  264.                     $image = $selectedEdition->getLargItemThumbnail();
  265.                     
  266.                 }
  267.             }
  268.             foreach ($prodcutFormats as $productFormat) {
  269.                 $prodcutFormatArray[$productFormat['value']] = $productFormat['key'];
  270.             }
  271.         }
  272.         $category = null;
  273.         foreach ($book->getDolpoTags() as $dolpoTag) {
  274.             if ($dolpoTag->getTagType() == 'category') {
  275.                 $category = $dolpoTag;
  276.                 break;
  277.             }
  278.         }
  279.         /**
  280.          * 
  281.          * Author best book
  282.          */
  283.          
  284.         if (!empty($book->getAuthors())) {
  285.         
  286.             $author = $book->getAuthors()[0];
  287.             $authorBestBookDefault = \Pimcore\Model\WebsiteSetting::getByName('authorBestBookDefault');
  288.             $authorBestBookDefaultval = 4;
  289.             if ($authorBestBookDefault) {
  290.                 $authorBestBookDefaultval = $authorBestBookDefault->getData();
  291.             }
  292.             $authorBookItems = $dolpoSearchService->getBooksByAuthorId($author->getId(), 0, $authorBestBookDefaultval + 1, ['o_id']);
  293.             $authorBookIds_tmp = array_values(array_unique(array_filter(array_map(
  294.                 static fn ($item) => is_array($item) && array_key_exists('o_id', $item) ? $item['o_id'] : null,
  295.                 $authorBookItems
  296.             ), static fn ($bookId) => $bookId !== null)));
  297.             $authorBookIds=[];
  298.             foreach($authorBookIds_tmp as $itemId){
  299.                 if(count($authorBookIds)<$authorBestBookDefaultval){
  300.                     if($itemId!=$book->getId()){
  301.                         $authorBookIds[]=$itemId;          
  302.                     }
  303.                 }
  304.             }
  305.             $authorBookIdString = implode(',', $authorBookIds);
  306.             $param['authorBooks'] = [
  307.                 "tagsToShow" => false,
  308.                 "tagsSelectionIds" => '',
  309.                 "objectsSelectionIds" => $authorBookIdString,
  310.                 "frontFilters" => null,
  311.                 "pagination" => null,
  312.                 "showCount" => false,
  313.                 "ad" => null,
  314.                 "title" => "AUTRES LIVRES DE " . $author->getName(),
  315.                 "editmode" => false,
  316.                 "uniqueId" => null
  317.             ];
  318.         }
  319.         /**
  320.          * 
  321.          * Auther best book
  322.          */
  323.         // add document 
  324.         if ($category) {
  325.             $param['document'] = $category->getPage();
  326.             // Add snippet
  327.             $param['snippet'] = $category->getSnippet();
  328.             $dolpoBestBookDefault = \Pimcore\Model\WebsiteSetting::getByName('dolpoBestBookDefault');
  329.             $dolpoBestBookDefaultval = 4;
  330.             if ($dolpoBestBookDefault) {
  331.                 $dolpoBestBookDefaultval = $dolpoBestBookDefault->getData();
  332.             }
  333.             $filters = ['DolpoTags' => [$category->getId()]]; 
  334.             $dolpoBooks = $dolpoSearchService->bookSearchFilter($filters, 0, 25);
  335.             $cle_hasard=[];
  336.             if ($dolpoBooks) {
  337.                 if (count($dolpoBooks) === 1) {
  338.                     // Si il n'y a qu'un seul livre, on prend directement la clé 0
  339.                     $cle_hasard = [0];
  340.                 } else {
  341.                     // Sinon, on utilise array_rand pour obtenir une clé aléatoire
  342.                     $cle_hasard = array_rand($dolpoBooks, min($dolpoBestBookDefaultval, count($dolpoBooks)));
  343.                 }
  344.             }
  345.             $dolpoBookIds = [];
  346.             
  347.             foreach ($cle_hasard as $cle) {
  348.                $dolpoBookIds[] = $dolpoBooks[$cle]['o_id'];
  349.             }
  350.             $dolpoBookIdString = implode(',', $dolpoBookIds);
  351.             $param['dolpoBooks'] = [
  352.                 "tagsToShow" => false,
  353.                 "tagsSelectionIds" => '',
  354.                 "objectsSelectionIds" => $dolpoBookIdString,
  355.                 "frontFilters" => null,
  356.                 "pagination" => null,
  357.                 "showCount" => false,
  358.                 "ad" => null,
  359.                 "title" => "DOLPO RECOMMANDE",
  360.                 "editmode" => false,
  361.                 "uniqueId" => null
  362.             ];
  363.         }else{
  364.             $param['document'] = \Pimcore\Model\Document::getById(1);
  365.         }
  366.         $newEditable = new \Pimcore\Model\Document\Editable\Wysiwyg();
  367.         $newEditable->setName('title');
  368.         $newEditable->setDataFromResource('');
  369.         $document->setEditable($newEditable);
  370.         //isAdminUser
  371.         $user = \Pimcore\Tool\Session::getReadonly()->get("user");
  372.         $isPimcoreAdminUser= ($user !== null);
  373.         $param['refresh']=$request->query->get('refresh');
  374.         $param['item'] = $book;
  375.         $param['serie'] = $serie;
  376.         $param['title'] = $title;
  377.         $param['subtitle'] = $subtitle;
  378.         $param['collection'] = $collectionItem;
  379.         $param['editions'] = $displayedEditions;
  380.         $param['selectedEdition'] = $selectedEdition;
  381.         $param['image'] = $image;
  382.         $param['productScores'] = $productScores;
  383.         $param['productScoresOrder'] = $productScoresOrder;
  384.         $param['productScoresRating'] = $productScoresRatingArray;
  385.         //$param['colorCode'] = self::$COLOR_CODE;
  386.         $param['productId'] = $request->get('productId');
  387.         $param['prodcutFormats'] = $prodcutFormatArray;
  388.         $param['inventoryItemProduct'] = $inventoryItemProduct;
  389.         $param['isPimcoreAdminUser'] = $isPimcoreAdminUser;
  390.         // SEO
  391.         $title = $book->getTitle();
  392.         if($subtitle != ''){
  393.             $title.= ' : '.$subtitle;
  394.         }
  395.         if (!empty($book->getAuthors())) {
  396.             $authors = $book->getAuthors();
  397.             foreach ($authors as $author) {
  398.                 $title.= ' : '.$author->getName();
  399.             }
  400.         }
  401.         if($param['document']){
  402.             $param['document']->setTitle($title);
  403.             $param['document']->setDescription(\App\Service\Website\Tool\Text::cutStringRespectingWhitespace($book->getDescription(),250));
  404.         }
  405.         return $this->render('product/product.html.twig', $param);
  406.     }
  407.     public function productListAction(Request $request): Response
  408.     {
  409.         return $this->render('product/product_list.html.twig');
  410.     }
  411.     public function elasticSearchAction(Request $request, DolpoSearchService $dolpoSearchService): Response
  412.     {
  413.         $query = '';
  414.         if ($request->get("q")) {
  415.             $query = $request->get("q");
  416.         }
  417.         $data = [
  418.             'serie' => [],
  419.             'auteur' => [],
  420.             'book' => [],
  421.         ];
  422.         $query = trim((string) $query);
  423.         if ($query !== '') {
  424.             $filters = ['TextSearch' => $query];
  425.             $returnFields = [
  426.                 'book_id',
  427.                 'book_dolpo_id',
  428.                 'book_title',
  429.                 'title_long',
  430.                 'ean',
  431.                 'authors_json',
  432.                 'author_names',
  433.             ];
  434.             $results = $dolpoSearchService->bookSearchFilter($filters, null, 0, 7, $returnFields);
  435.             foreach ($results as $item) {
  436.                 $authors = [];
  437.                 $authorsJson = $item['authors_json'] ?? [];
  438.                 if (is_string($authorsJson)) {
  439.                     $decoded = json_decode($authorsJson, true);
  440.                     if (is_array($decoded)) {
  441.                         $authorsJson = $decoded;
  442.                     }
  443.                 }
  444.                 if (is_array($authorsJson)) {
  445.                     foreach ($authorsJson as $author) {
  446.                         if (!is_array($author)) {
  447.                             continue;
  448.                         }
  449.                         $name = $author['name'] ?? ($author['Name'] ?? null);
  450.                         if ($name === null || $name === '') {
  451.                             continue;
  452.                         }
  453.                         $authors[] = [
  454.                             'Name' => $name,
  455.                             'dolpoId' => $author['dolpo_id'] ?? ($author['dolpoId'] ?? null),
  456.                         ];
  457.                     }
  458.                 }
  459.                 if ($authors === []) {
  460.                     $authorNames = $item['author_names'] ?? [];
  461.                     if (is_string($authorNames)) {
  462.                         $authorNames = [$authorNames];
  463.                     }
  464.                     if (is_array($authorNames)) {
  465.                         foreach ($authorNames as $name) {
  466.                             if ($name !== '') {
  467.                                 $authors[] = ['Name' => $name, 'dolpoId' => null];
  468.                             }
  469.                         }
  470.                     }
  471.                 }
  472.                 $data['book'][] = [
  473.                     'id' => $item['book_id'] ?? null,
  474.                     'dolpoId' => $item['book_dolpo_id'] ?? ($item['book_id'] ?? null),
  475.                     'title' => $item['book_title'] ?? ($item['title_long'] ?? ''),
  476.                     'ean' => $item['ean'] ?? null,
  477.                     'author' => $authors,
  478.                 ];
  479.             }
  480.         }
  481.         $data = $this->render('product/product_serie_result.html.twig', ["data" => $data]);
  482.         return $this->json(["success" => true, "data" => $data]);
  483.     }
  484.     public function productSearchAction(Request $request): Response
  485.     {
  486.         $query = '';
  487.         if ($request->get("q")) {
  488.             $query = $request->get("q");
  489.         }
  490.         $paginationDefault = \Pimcore\Model\WebsiteSetting::getByName('paginationGalleryDefault');
  491.         $paginationDefaultVal = $paginationDefault->getData();
  492.         $param['query'] = $query;
  493.         $param["pagination"] = $paginationDefaultVal;
  494.         return $this->render('product/product_search.html.twig', $param);
  495.     }
  496.     public function productSearchNextAction(Request $request, ElasticSearchService $elasticSearchService): Response
  497.     {
  498.         $query = '';
  499.         if ($request->get("query")) {
  500.             $query = $request->get("query");
  501.         }
  502.         $total = $request->get("total");
  503.         $pagination = $request->get("pagination");
  504.         $offset = $request->get("offset");
  505.         $paginationDefault = \Pimcore\Model\WebsiteSetting::getByName('paginationGalleryDefault');
  506.         $paginationDefaultVal = $paginationDefault->getData();
  507.         $objectBooks = $elasticSearchService->bookSearchFilter($query, (int)$offset, (int)$pagination, true);
  508.         $param['query'] = $query;
  509.         $param['total'] = $objectBooks["total"];
  510.         $param["pagination"] = $pagination;
  511.         $param["offset"] = $offset +  $pagination;
  512.         $param['productHtml'] = $this->render('product/book_gallary.html.twig', ["books" => $objectBooks["data"]]);
  513.         return $this->json(["success" => true, "data" => $param]);
  514.     }
  515. }