<?php
namespace App\Controller;
use AdvancedObjectSearchBundle\Service;
use App\Service\ElasticSearchService;
use Carbon\Carbon;
use Pimcore\Controller\FrontendController;
use Pimcore\Model\DataObject\Book;
use Pimcore\Model\DataObject\OnixProduct;
use Pimcore\Model\DataObject\ClassDefinition;
use Pimcore\Model\DataObject\Fieldcollection;
use Pimcore\Model\DataObject\InventoryItem;
use Pimcore\Model\DataObject\Serie;
use Pimcore\Model\Document;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use App\Service\DolpoSearchService;
use Symfony\Component\Routing\Annotation\Route;
use function PHPUnit\Framework\isEmpty;
class ProductController extends FrontendController
{
private $map_availability=[
'InStock'=>"<p class='edition__shipping shipping-48h'> En stock </a>",
'POD'=>"<p class='edition__shipping shipping-purple'> Imprimé sur demande </a>",
'NotYetAvailable'=>"<p class='edition__shipping shipping-purple'> Pas encore disponible </a>",
'TemporaryUnavailable'=>"<p class='edition__shipping shipping-purple'> Momentanément indisponible éditeur </a>",
'PublisherOutOfStock'=>"<p class='edition__shipping shipping-nondis'> Rupture éditeur </a>",
'PublisherReprint'=>"<p class='edition__shipping shipping-nondis'> En Réimpression </a>",
'EditorUnavailable'=>"<p class='edition__shipping shipping-nondis'>Indisponible éditeur</p>",
'Retired'=>"<p class='edition__shipping shipping-nondis'>Retiré de la vente</p>",
'EditorNoCommand'=>"<p class='edition__shipping shipping-nondis'>Pas de commande pour cet éditeur</p>"
];
public function editionPageAction(Request $request, Document $document, DolpoSearchService $dolpoSearchService): Response
{
$param=[];
if ($request->get('isbn')){
$edition = OnixProduct::getByEan($request->get('isbn'),['limit' => 1]);
if(empty($edition)){
throw new NotFoundHttpException('Edition needed');
}
else{
$BookDolpoId = $edition->getDolpoId();
}
if (!empty($BookDolpoId)) {
// Redirige vers la page du livre
return $this->redirectToRoute('product', ['dolpoId' => $BookDolpoId, 'productId' => $edition->getId()]);
}
$param['item'] = $edition;
//dump($edition->getAuthors());
// Affectation des valeurs aux propriétés de l'objet
$availabilityLabel = $edition->getAvailabilityLabel();
//isAdminUser
$user = \Pimcore\Tool\Session::getReadonly()->get("user");
$isPimcoreAdminUser= ($user !== null);
$param['isPimcoreAdminUser'] = $isPimcoreAdminUser;
$param['availabilityLabel'] = $availabilityLabel;
$param['document'] = \Pimcore\Model\Document::getById(1);
$param['document']->setTitle($edition->getLongTitle());
$param['document']->setDescription(\App\Service\Website\Tool\Text::cutStringRespectingWhitespace($edition->getDescription(),250));
$prodcutFormats = ClassDefinition::getById($edition->getClassId())->getFieldDefinition('Format')->getOptions();
foreach ($prodcutFormats as $productFormat) {
$prodcutFormatArray[$productFormat['value']] = $productFormat['key'];
}
$param['prodcutFormats'] = $prodcutFormatArray;
return $this->render('product/productEdition.html.twig', $param);
}
}
public function productPageAction(Request $request, Document $document, DolpoSearchService $dolpoSearchService): Response
{
$param = [];
if ($request->get('dolpoId')) {
$item = Book::getByDolpoId($request->get('dolpoId'));
$book = $item->load();
$collectionItem = null;
$title = null;
$subtitle = null;
$editions = null;
$selectedEdition = null;
$displayedEditions=null;
$image = null;
$productScores = [];
$productScoresOrder = [];
$productScoresRating = [];
$productScoresRatingArray = [];
$prodcutFormats = [];
$prodcutFormatArray = [];
if (empty($book)) {
//throw new NotFoundHttpException('Book needed');
return $this->redirect('/');
} else {
$book = $book[0];
$title = $book->getTitle();
$image = $book->getItemThumbnail('lg');
}
// New selection options dynamic
// Get All options dynamic for this item
$productScoresRatingArray = $book->getItemRatingOptions();
// Avis Dolpo : ex: A lire pour les accros au genre
if ($book->getReview()) {
foreach ($book->getReview()->getItems() as $collection) {
if ($collection instanceof Fieldcollection\Data\Review) {
// $productScoresRating = $collection->getDefinition()->getFieldDefinition('Rating')->getoptions();
$collectionItem = $collection;
break;
}
}
}
if( $collectionItem != null ){
$ratingsCriterias = $collectionItem->getRatingCriteria();
if(count($ratingsCriterias)) {
foreach($ratingsCriterias as $reviewCrit) {
$dataRating = ($reviewCrit->getData());
$productScores[$reviewCrit->getObjectId()][] = $dataRating['Rating'];
}
}
}
$finalProductScores = [];
// Calcul average
foreach($productScores as $idCriteria => $infos){
$criteria = \Pimcore\Model\DataObject\ReviewCriteria::getById($idCriteria);
$color = '#36A9E1';
if($criteria->getProperty("color") != ''){
$color = $criteria->getProperty("color");
}
$label = $criteria->getKey();
// label to override key
if($criteria->getLabel() != ''){
$label = $criteria->getLabel();
}
// Label front if needed
if($criteria->getProperty("label") != ''){
$label = $criteria->getProperty("label");
}
$position = $idCriteria; // todo to change by custom property with position (like label)
$finalProductScores[$position] = [
'label' => $label,
'color' => $color,
'score' => (int) ceil(array_sum($infos) / count($infos))
];
}
$productScores = $finalProductScores;
// ---------------------------------
// Title and subtitle
$serie=null;
if(!empty($book->getSerieId())){
$serie=Serie::getById($book->getSerieId());
}
if (!empty($serie)) {
$title = $serie->getName();
foreach ($serie->getVolumes() as $bookAdded) {
if ($bookAdded->getObjectId() === $book->getId()) {
if(array_key_exists( 'Tome', $bookAdded->getData())){
if (count(explode(":", $book->getTitle())) > 1) {
$subtitle = "Tome " . $bookAdded->getData()['Tome'] . " " . explode(":", $book->getTitle())[1];
} else {
$subtitle = "Tome " . $bookAdded->getData()['Tome'] . " " . $book->getTitle();
}
}
else{
}
}
}
}
// Edition
$editionIds = [];
$inventoryItemProduct = [];
if (!empty($book->getEditions())) {
$editions = $book->getAllSortedEditions();
$selectedEdition = $editions[0]['edition'];
$i=0;
$hasInStockArticles = false;
$hasOrderedArticles = false;
$hasOrderableArticles = false;
$displayed_formats=[];
foreach ($editions as $editionArray) {
$edition=$editionArray['edition'];
if (empty($editionArray['Format']) or ($editionArray['Format']=='')){
$editionArray['Format']='vide';
}
if ($request->get('productId') and $request->get('productId') == $edition->getId()) {
$inventoryItemProduct[$edition->getId()] = $edition->getAvailabilityLabel();
$selectedEdition = $edition;
$displayedEditions[]=$edition;
$displayed_formats[]=$editionArray['Format'];
}
elseif($editionArray['Availability']=='InStock'){
$inventoryItemProduct[$edition->getId()] = $this->map_availability[$editionArray['Availability']];
$hasInStockArticles=true;
$displayedEditions[]=$edition;
$displayed_formats[]=$editionArray['Format'];
$i++;
}
elseif($editionArray['Availability']=='Ordered'){
$inventoryItemProduct[$edition->getId()] = "<p class='edition__shipping shipping-48h'> En arrivage - livré en " . $editionArray['Delay'] . ($editionArray['Delay'] == 1 ? 'jour' : ' jours') . "</a>";
$hasOrderedArticles=true;
$displayedEditions[]=$edition;
$displayed_formats[]=$editionArray['Format'];
$i++;
}
elseif(in_array($editionArray['Format'], $displayed_formats)){
//on n'affiche pas l'édition si le format est déjà dans les formats proposés
}
elseif($editionArray['Availability']=='Orderable'){
$inventoryItemProduct[$edition->getId()] = "<p class='edition__shipping shipping-48h'> livré en " . $editionArray['Delay'] . ($editionArray['Delay'] == 1 ? 'jour' : ' jours') . "</a>";
$hasOrderableArticles=true;
$displayedEditions[]=$edition;
$displayed_formats[]=$editionArray['Format'];
$i++;
}
elseif($editionArray['Availability']=='PreOrderable'){
$inventoryItemProduct[$edition->getId()] = "<p class='edition__shipping shipping-48h'> Précommande </a>";
$hasOrderableArticles=true;
$displayedEditions[]=$edition;
$displayed_formats[]=$editionArray['Format'];
$i++;
}
elseif(array_key_exists($editionArray['Availability'], $this->map_availability)
&& !$hasOrderedArticles && !$hasInStockArticles && !$hasOrderableArticles){
$inventoryItemProduct[$edition->getId()] = $this->map_availability[$editionArray['Availability']];
$displayedEditions[]=$edition;
$displayed_formats[]=$editionArray['Format'];
$i++;
}
else{
}
if(!$hasOrderedArticles and !$hasInStockArticles and ($i>=3)){
break;
}
}
}
// images
if ($selectedEdition) {
$prodcutFormats = ClassDefinition::getById($selectedEdition->getClassId())->getFieldDefinition('Format')->getOptions();
if ($selectedEdition->getLargeCover()->getDirect()) {
$image = $selectedEdition->getLargItemThumbnail();
}
}
foreach ($prodcutFormats as $productFormat) {
$prodcutFormatArray[$productFormat['value']] = $productFormat['key'];
}
}
$category = null;
foreach ($book->getDolpoTags() as $dolpoTag) {
if ($dolpoTag->getTagType() == 'category') {
$category = $dolpoTag;
break;
}
}
/**
*
* Author best book
*/
if (!empty($book->getAuthors())) {
$author = $book->getAuthors()[0];
$authorBestBookDefault = \Pimcore\Model\WebsiteSetting::getByName('authorBestBookDefault');
$authorBestBookDefaultval = 4;
if ($authorBestBookDefault) {
$authorBestBookDefaultval = $authorBestBookDefault->getData();
}
$authorBookItems = $dolpoSearchService->getBooksByAuthorId($author->getId(), 0, $authorBestBookDefaultval + 1, ['o_id']);
$authorBookIds_tmp = array_values(array_unique(array_filter(array_map(
static fn ($item) => is_array($item) && array_key_exists('o_id', $item) ? $item['o_id'] : null,
$authorBookItems
), static fn ($bookId) => $bookId !== null)));
$authorBookIds=[];
foreach($authorBookIds_tmp as $itemId){
if(count($authorBookIds)<$authorBestBookDefaultval){
if($itemId!=$book->getId()){
$authorBookIds[]=$itemId;
}
}
}
$authorBookIdString = implode(',', $authorBookIds);
$param['authorBooks'] = [
"tagsToShow" => false,
"tagsSelectionIds" => '',
"objectsSelectionIds" => $authorBookIdString,
"frontFilters" => null,
"pagination" => null,
"showCount" => false,
"ad" => null,
"title" => "AUTRES LIVRES DE " . $author->getName(),
"editmode" => false,
"uniqueId" => null
];
}
/**
*
* Auther best book
*/
// add document
if ($category) {
$param['document'] = $category->getPage();
// Add snippet
$param['snippet'] = $category->getSnippet();
$dolpoBestBookDefault = \Pimcore\Model\WebsiteSetting::getByName('dolpoBestBookDefault');
$dolpoBestBookDefaultval = 4;
if ($dolpoBestBookDefault) {
$dolpoBestBookDefaultval = $dolpoBestBookDefault->getData();
}
$filters = ['DolpoTags' => [$category->getId()]];
$dolpoBooks = $dolpoSearchService->bookSearchFilter($filters, 0, 25);
$cle_hasard=[];
if ($dolpoBooks) {
if (count($dolpoBooks) === 1) {
// Si il n'y a qu'un seul livre, on prend directement la clé 0
$cle_hasard = [0];
} else {
// Sinon, on utilise array_rand pour obtenir une clé aléatoire
$cle_hasard = array_rand($dolpoBooks, min($dolpoBestBookDefaultval, count($dolpoBooks)));
}
}
$dolpoBookIds = [];
foreach ($cle_hasard as $cle) {
$dolpoBookIds[] = $dolpoBooks[$cle]['o_id'];
}
$dolpoBookIdString = implode(',', $dolpoBookIds);
$param['dolpoBooks'] = [
"tagsToShow" => false,
"tagsSelectionIds" => '',
"objectsSelectionIds" => $dolpoBookIdString,
"frontFilters" => null,
"pagination" => null,
"showCount" => false,
"ad" => null,
"title" => "DOLPO RECOMMANDE",
"editmode" => false,
"uniqueId" => null
];
}else{
$param['document'] = \Pimcore\Model\Document::getById(1);
}
$newEditable = new \Pimcore\Model\Document\Editable\Wysiwyg();
$newEditable->setName('title');
$newEditable->setDataFromResource('');
$document->setEditable($newEditable);
//isAdminUser
$user = \Pimcore\Tool\Session::getReadonly()->get("user");
$isPimcoreAdminUser= ($user !== null);
$param['refresh']=$request->query->get('refresh');
$param['item'] = $book;
$param['serie'] = $serie;
$param['title'] = $title;
$param['subtitle'] = $subtitle;
$param['collection'] = $collectionItem;
$param['editions'] = $displayedEditions;
$param['selectedEdition'] = $selectedEdition;
$param['image'] = $image;
$param['productScores'] = $productScores;
$param['productScoresOrder'] = $productScoresOrder;
$param['productScoresRating'] = $productScoresRatingArray;
//$param['colorCode'] = self::$COLOR_CODE;
$param['productId'] = $request->get('productId');
$param['prodcutFormats'] = $prodcutFormatArray;
$param['inventoryItemProduct'] = $inventoryItemProduct;
$param['isPimcoreAdminUser'] = $isPimcoreAdminUser;
// SEO
$title = $book->getTitle();
if($subtitle != ''){
$title.= ' : '.$subtitle;
}
if (!empty($book->getAuthors())) {
$authors = $book->getAuthors();
foreach ($authors as $author) {
$title.= ' : '.$author->getName();
}
}
if($param['document']){
$param['document']->setTitle($title);
$param['document']->setDescription(\App\Service\Website\Tool\Text::cutStringRespectingWhitespace($book->getDescription(),250));
}
return $this->render('product/product.html.twig', $param);
}
public function productListAction(Request $request): Response
{
return $this->render('product/product_list.html.twig');
}
public function elasticSearchAction(Request $request, DolpoSearchService $dolpoSearchService): Response
{
$query = '';
if ($request->get("q")) {
$query = $request->get("q");
}
$data = [
'serie' => [],
'auteur' => [],
'book' => [],
];
$query = trim((string) $query);
if ($query !== '') {
$filters = ['TextSearch' => $query];
$returnFields = [
'book_id',
'book_dolpo_id',
'book_title',
'title_long',
'ean',
'authors_json',
'author_names',
];
$results = $dolpoSearchService->bookSearchFilter($filters, null, 0, 7, $returnFields);
foreach ($results as $item) {
$authors = [];
$authorsJson = $item['authors_json'] ?? [];
if (is_string($authorsJson)) {
$decoded = json_decode($authorsJson, true);
if (is_array($decoded)) {
$authorsJson = $decoded;
}
}
if (is_array($authorsJson)) {
foreach ($authorsJson as $author) {
if (!is_array($author)) {
continue;
}
$name = $author['name'] ?? ($author['Name'] ?? null);
if ($name === null || $name === '') {
continue;
}
$authors[] = [
'Name' => $name,
'dolpoId' => $author['dolpo_id'] ?? ($author['dolpoId'] ?? null),
];
}
}
if ($authors === []) {
$authorNames = $item['author_names'] ?? [];
if (is_string($authorNames)) {
$authorNames = [$authorNames];
}
if (is_array($authorNames)) {
foreach ($authorNames as $name) {
if ($name !== '') {
$authors[] = ['Name' => $name, 'dolpoId' => null];
}
}
}
}
$data['book'][] = [
'id' => $item['book_id'] ?? null,
'dolpoId' => $item['book_dolpo_id'] ?? ($item['book_id'] ?? null),
'title' => $item['book_title'] ?? ($item['title_long'] ?? ''),
'ean' => $item['ean'] ?? null,
'author' => $authors,
];
}
}
$data = $this->render('product/product_serie_result.html.twig', ["data" => $data]);
return $this->json(["success" => true, "data" => $data]);
}
public function productSearchAction(Request $request): Response
{
$query = '';
if ($request->get("q")) {
$query = $request->get("q");
}
$paginationDefault = \Pimcore\Model\WebsiteSetting::getByName('paginationGalleryDefault');
$paginationDefaultVal = $paginationDefault->getData();
$param['query'] = $query;
$param["pagination"] = $paginationDefaultVal;
return $this->render('product/product_search.html.twig', $param);
}
public function productSearchNextAction(Request $request, ElasticSearchService $elasticSearchService): Response
{
$query = '';
if ($request->get("query")) {
$query = $request->get("query");
}
$total = $request->get("total");
$pagination = $request->get("pagination");
$offset = $request->get("offset");
$paginationDefault = \Pimcore\Model\WebsiteSetting::getByName('paginationGalleryDefault');
$paginationDefaultVal = $paginationDefault->getData();
$objectBooks = $elasticSearchService->bookSearchFilter($query, (int)$offset, (int)$pagination, true);
$param['query'] = $query;
$param['total'] = $objectBooks["total"];
$param["pagination"] = $pagination;
$param["offset"] = $offset + $pagination;
$param['productHtml'] = $this->render('product/book_gallary.html.twig', ["books" => $objectBooks["data"]]);
return $this->json(["success" => true, "data" => $param]);
}
}