<?php
namespace App\Controller;
use App\Service\Document\Areabrick\Series;
use App\Service\DolpoSearchService;
use App\Service\PageHtmlCacheService;
use Pimcore\Controller\FrontendController;
use Pimcore\Model\DataObject\Book;
use Pimcore\Model\DataObject\OnixProduct;
use Pimcore\Model\DataObject\Serie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Pimcore\Model\DataObject\Contributor;
use CoreShop\Component\Core\Context\ShopperContextInterface;
class DefaultController extends FrontendController
{
private const DOLPO_RATING_LABELS_FALLBACK = [
'0' => 'Décevant, abandonné',
'1' => 'Décevant mais terminé',
'2' => 'A lire pour les accros au genre',
'3' => 'Bouquin sympa, à lire',
'4' => 'Vraiment bon livre',
'5' => 'Très bon livre, une référence',
];
public function __construct(
private string $websiteUrl,
protected ShopperContextInterface $shopperContext,
private PageHtmlCacheService $pageHtmlCacheService,
) {
}
/**
* @param Request $request
*
* @return Response
*/
public function defaultAction(Request $request): Response
{
if ($this->document) {
$homeKey = 'page_'.$this->document->getId();
$forceRefresh = $request->query->get('refresh');
if (!$forceRefresh && !$this->editmode && ($page = $this->pageHtmlCacheService->load($homeKey)) !== null) {
// Page loaded from cache, placeholders are replaced below.
}
else {
$page = $this->renderView('default/default.html.twig', [
'requestforcache' => true,
]);
if (!$this->editmode) {
$this->pageHtmlCacheService->save($homeKey, $page);
}
}
$headerContent = $this->renderView('account/_header.html.twig', [
'websiteUrl' => $this->websiteUrl,
'customer' => $this->shopperContext->hasCustomer() ? $this->shopperContext->getCustomer() : null
]);
$cartwidgetContent = $this->renderView('basket/_widget.html.twig', [
'cart' => $this->shopperContext->getCart()
]);
$page = str_replace('[[HEADER_ACTION]]', $headerContent, $page);
$page = str_replace('[[CARTWIDGET_ACTION]]', $cartwidgetContent, $page);
return new Response($page);
}
return $this->render('default/default.html.twig');
}
/**
* @param Request $request
*
* @return Response
*/
public function testcacheAction(Request $request): Response
{
// Cache Pimcore
$key = 'serie.'.'testcw';
//$cacheKey = md5( $key );
$cacheKey = 'cachetest';
var_dump($cacheKey);
echo '<br/>cache enabled : ';
var_dump(\Pimcore\Cache::isEnabled());
echo '<br/>';
//\Pimcore\Cache::setForceImmediateWrite(true);
//var_dump(\Pimcore\Cache::remove($cacheKey));
$items = (\Pimcore\Cache::load($cacheKey));
echo '<br/>';
//die();
if (!$items = \Pimcore\Cache::load($cacheKey)) {
$items = ['test1'=>'test '.date('Y-m-d H:i:s')];
echo '<br/>';
echo 'cache broken !';
echo '<br/>';
$save = \Pimcore\Cache::save(
$items,
$cacheKey,
['cache-test'],
86400, // 86400 sec = 24h // 1800 sec = 30min
10,
false); // force
var_dump($save);
} else {
echo 'cache works ;)';
echo '<br/>';
}
echo '<br/>';
var_dump($items);
/*
// Exemple de test Messenger
$message = new TestMessage('Hello, Messenger!');
// Envoi du message au bus
$messageBus->dispatch($message)->setMessageBus('async');
*/
// Emtpy response
return new Response(
'',
200,
);
}
public function categoryPageAction(Request $request): Response
{
$categoryKey = 'page_'.$this->document->getId() ;
$forceRefresh = $request->query->get('refresh');
if (!$forceRefresh && !$this->editmode && ($page = $this->pageHtmlCacheService->load($categoryKey)) !== null) {
//rien tout de suite, il faut changer ensuite, changer la balise
}
else{
// Get the root Category Page
$pagesCategories = [];
$pageCategoryRoot = $this->document;
$pagesCategories[] = $pageCategoryRoot->getId();
$parent = $pageCategoryRoot->getParent();
while ($parent && strpos($parent->getController(), 'categoryPage') > 0) {
$pageCategoryRoot = $parent;
$pagesCategories[] = $pageCategoryRoot->getId();
$parent = $pageCategoryRoot->getParent();
}
$pagesCategories = array_reverse($pagesCategories);
// Take the child of category root if third level
$pageCategoryRootForMenu = $pageCategoryRoot->getId();
if($this->document->getId() != $pageCategoryRoot->getId()) {
$pageCategoryRootForMenu = $pagesCategories[1];
}
$page = $this->renderView('default/category.html.twig',
[
'categoryPageRootId' => $pageCategoryRootForMenu,
'showMenuLeft' => true,
'requestforcache' => true,
'websiteUrl' => $this->websiteUrl
]);
if(!$this->editmode){
$this->pageHtmlCacheService->save($categoryKey, $page);
}
}
$headerContent = $this->renderView('account/_header.html.twig', [
'websiteUrl' => $this->websiteUrl,
'customer' => $this->shopperContext->hasCustomer() ? $this->shopperContext->getCustomer() : null
]);
$cartwidgetContent = $this->renderView('basket/_widget.html.twig', [
'cart' => $this->shopperContext->getCart()
]);
// Remplacer la balise
$page = str_replace('[[HEADER_ACTION]]', $headerContent, $page);
$page = str_replace('[[CARTWIDGET_ACTION]]', $cartwidgetContent, $page);
return new Response($page);
}
public function articlePageAction(Request $request): Response
{
return $this->render('default/article.html.twig',
[
//'showMenuLeft' => true,
]
);
}
public function wikiPageAction(Request $request): Response
{
return $this->render('default/wiki.html.twig',
[
//'showMenuLeft' => true,
]
);
}
public function SeriesPageAction(Request $request): Response
{
return $this->render('default/series.html.twig',
[
//'showMenuLeft' => true,
]
);
}
private function _getObjectBookOrSerie($id)
{
$item = Book::getById((int)$id);
if (! $item instanceof Book) {
$item = Serie::getById((int)$id);
}
return $item;
}
private function _getObjectBookSerieOrOnixProduct($id)
{
$item = $this->_getObjectBookOrSerie($id);
if ($item instanceof Book || $item instanceof Serie) {
return $item;
}
return OnixProduct::getById((int)$id);
}
/*
AREABRICK RENDERLET
-------------------
*/
public function articleAction(Request $request): Response
{
if ($request->get('type') === 'document') {
$params = [];
$item = \Pimcore\Model\Document::getById((int)$request->get('id'));
if($item == null) {
throw new NotFoundHttpException('Document needed');
}
$params['item'] = $item;
$params['modelactu'] = $request->get('modelactu');
$dateTimestamp = ($item->getCreationDate());
$dateToShow = date('d/m/Y', $dateTimestamp);
if($item->getEditable('myDate') != null) {
$dateCustom = $item->getEditable('myDate')->getData();
if($dateCustom instanceof \Carbon\Carbon) {
$dateToShow = $dateCustom->format('d/m/Y');
}
}
$length = 100;
$shortDesc = $item->getEditable('intro')->getData();
$shortDesc = \App\Service\Website\Tool\Text::cutStringRespectingWhitespace($item->getEditable('intro')->getData(), $length);
$params['shortDesc'] = strip_tags($shortDesc);
$params['dateToShow'] = strip_tags($dateToShow);
return $this->render('default/article_renderlet.html.twig', $params);
}
}
/*
AREABRICK RENDERLET
-------------------
*/
public function bookSelectionAction(Request $request): Response
{
if ($request->get('type') === 'object') {
$params = [];
$item = $this->_getObjectBookSerieOrOnixProduct((int)$request->get('id'));
if ($item == null) {
throw new NotFoundHttpException('Book, Serie or OnixProduct needed');
}
$params['item'] = $item;
$params['tagsToShow'] = $request->get('tagsToShow');
$params['showCount'] = (bool)$request->get("showCount");
$params['blogger'] = $request->get('blogger') ? Contributor::getById($request->get('blogger')) : null ;
return $this->render('default/book_selection.html.twig', $params);
}
}
public function bookWikiAction(Request $request): Response
{
if ($request->get('type') === 'object') {
$params = [];
$item = $this->_getObjectBookSerieOrOnixProduct((int)$request->get('id'));
if ($item == null) {
throw new NotFoundHttpException('Book, Serie or OnixProduct needed');
}
$params['item'] = $item;
return $this->render('default/book_wiki.html.twig', $params);
}
}
public function bookRankingAction(Request $request): Response
{
$rankKey = md5(json_encode([
$request->get('id'),
$request->get('tagsToShow'),
$request->get('type'),
$request->get('indexLoopRenderlet'),
]));
// if ($gallery = \Pimcore\Cache::load($rankKey)) {
// return new Response($gallery);
// }
$params = [];
$item = $this->_getObjectBookSerieOrOnixProduct((int)$request->get('id'));
if ($item == null) {
throw new NotFoundHttpException('Book, Serie or OnixProduct needed');
}
$params['item'] = $item;
$params['tagsToShow'] = $request->get('tagsToShow');
$params['indexLoopRenderlet'] = $request->get('indexLoopRenderlet');
$view = $this->renderView('default/book_ranking.html.twig', $params);
// \Pimcore\Cache::save(
// $view,
// $rankKey,
// ["book_ranking"],
// $this->cachetime);
return new Response($view);
}
public function bookHighlightOneAction(Request $request): Response
{
if ($request->get('type') === 'object') {
$params = [];
$item = $this->_getObjectBookSerieOrOnixProduct((int)$request->get('id'));
if ($item == null) {
throw new NotFoundHttpException('Book, Serie or OnixProduct needed');
}
$params['item'] = $item;
$params['tagsToShow'] = $request->get('tagsToShow');
return $this->render('default/book_highlight_one.html.twig', $params);
}
}
public function bookHighlightTwoAction(Request $request): Response
{
$params = [];
$item = $this->_getObjectBookSerieOrOnixProduct((int)$request->get('id'));
if ($item == null) {
throw new NotFoundHttpException('Book, Serie or OnixProduct needed');
}
$params['item'] = $item;
$params['tagsToShow'] = $request->get('tagsToShow');
$params['blogger'] = $request->get('blogger') ? Contributor::getById($request->get('blogger')) : null ;
$params['showwishadd'] = true;
$view = $this->renderView('default/book_highlight_two.html.twig', $params);
return new Response($view);
}
public function bookSeriesAction(Request $request, DolpoSearchService $dolpoSearchService): Response
{
$paginationDefault = \Pimcore\Model\WebsiteSetting::getByName('paginationSeriesDefault');
$paginationDefaultVal = $paginationDefault->getData();
$pagination = $request->get('pagination');
if($pagination == 0) {
$pagination = $paginationDefaultVal;
}
// Filters JS
$tagsFilterArray = [];
if(($request->get('tagsFilter') && count($request->get('tagsFilter')))) {
foreach($request->get('tagsFilter') as $tag) {
$tagsFilterArray[$tag->getId()] = $tag;
}
}
//TAGS SELECTED BY JS
$conditionsByTagsFiltered = [];
$tagsFilteredSelectedrRawArray = (explode(',', $request->get('tagsFiltersSelectedIds')));
if(($tagsFilteredSelectedrRawArray && count($tagsFilteredSelectedrRawArray))) {
// Selection of all sub tags of the current tag
foreach($tagsFilteredSelectedrRawArray as $tagId) {
if($tagId != '') {
$conditionsByTagsFiltered[$tagId] = $tagId;
}
}
}
if(!(count($conditionsByTagsFiltered) > 0)) {
$tags = explode(',', $request->get('tagsSelectionIds'));
foreach($tags as $tagid) {
$conditionsByTagsFiltered[$tagid] = $tagid;
}
}
// Use DolpoSearch Service with ElasticSearch
// Keep only numeric IDs (same behavior as bookGalleryAction).
$filters = [];
$tagIds = array_values(array_filter(array_map('intval', $conditionsByTagsFiltered)));
if (count($tagIds) > 0) {
$filters['DolpoTags'] = $tagIds;
}
$results = $dolpoSearchService->serieSearchFilter($filters, 0, 1000, ['o_id']);
$arrObjectSelectionIds = [];
foreach($results as $infos) {
$arrObjectSelectionIds[] = $infos['o_id'];
}
$itemsArray = $arrObjectSelectionIds;
$params = [
'tagsToShow' => false,
'pagination' => $pagination,
'objectsSelectionIds' => implode(',', $itemsArray),
'frontFilters' => null,
'showCount' => true,
'ad' => null,
'tagsSelectionIds' => $request->get('tagsSelectionIds'), // Tags used to selection of series shown
'tagsFilterArray' => $tagsFilterArray, // Filters to show as button selectables
'title' => 'Résultats',
'fromAjax' => $request->get('fromAjax', null),
'editmode' => $request->get('editmode'),
];
$html = $this->render('default/book_series.html.twig', $params);
return $html;
}
/*
* Format the array items;
*/
private function _addKeyIdsInListing($listing)
{
$return = [];
foreach($listing as $item) {
$return[$item->getId()] = $item;
}
return $return;
}
public function bookGalleryAction(Request $request, DolpoSearchService $dolpoSearchService): Response
{
$galleryCacheKey = md5(json_encode([$request->get('tagsToShow'),
$request->get('tagsToExcludeIds'),
$request->get('objectsSelectionIds'),
$request->get('tagsSelectionIds'),
$request->get('text_search'),
$request->get('pagination'),
$request->get('offset', 0)]
));
$paginationDefault = \Pimcore\Model\WebsiteSetting::getByName('paginationGalleryDefault');
$paginationDefaultVal = $paginationDefault->getData();
$pagination = $request->get('pagination');
if ($pagination == 0) {
$pagination = $paginationDefaultVal;
}
// Book Or Series added (manually or auto)
$itemsArray = [];
// for automatic render
if ($request->get('uniqueIdForAjax') != null) {
$uniqueId = $request->get('uniqueIdForAjax');
} else {
$uniqueId = uniqid();
}
// Get all Book and Series already added manually in the document
// !! The brick need to be empty before deleted (because the brick data is still in bdd).
/*
$itemsAlreadyAddedInCurrentPage = []; // Book and Series already added
$editables = $this->document->getEditables();
foreach ($editables as $editable) {
if ($editable instanceof \Pimcore\Model\Document\Editable\Renderlet) {
$objectInRenderlet = $editable->getO();
if ($objectInRenderlet instanceof Book || $objectInRenderlet instanceof Series) {
$itemsAlreadyAddedInCurrentPage[$objectInRenderlet->getId()] = $objectInRenderlet->getId();
}
}
}
*/
$filters = [];
$textSearch = $request->get('text_search');
if (is_string($textSearch)) {
$textSearch = trim($textSearch);
} else {
$textSearch = null;
}
if (($textSearch === null || $textSearch === '') && is_string($request->get('q'))) {
$textSearch = trim($request->get('q'));
}
if ($textSearch !== null && $textSearch !== '') {
$filters['TextSearch'] = $textSearch;
}
// Manual mode: if the parameter exists (even empty), keep ObjectIds in filters.
$hasObjectsSelectionIds = $request->attributes->has('objectsSelectionIds')
|| $request->query->has('objectsSelectionIds')
|| $request->request->has('objectsSelectionIds');
if ($hasObjectsSelectionIds) {
$objectsSelectionRaw = $request->get('objectsSelectionIds');
if (is_array($objectsSelectionRaw)) {
$arrObjectSelectionIds = array_values(array_filter(array_map('intval', $objectsSelectionRaw)));
} else {
$arrObjectSelectionIds = array_values(array_filter(array_map(
'intval',
explode(',', (string)$objectsSelectionRaw)
)));
}
$filters['ObjectIds'] = $arrObjectSelectionIds;
}
// Automatic mode by DolpoTag Filters
//
if ($request->get('tagsSelectionIds') != null) {
$tags = array_values(array_filter(array_map(
'intval',
explode(',', $request->get('tagsSelectionIds'))
)));
// Use DolpoSearch Service with ElasticSearch
$filters['DolpoTags'] = $tags;
}
if ($request->get('tagsToExcludeIds') != null) {
$tagsExclude = array_values(array_filter(array_map(
'intval',
explode(',', $request->get('tagsToExcludeIds'))
)));
$filters['DolpoTagsToExclude'] = $tagsExclude;
}
$returnFields=['o_id', 'ean', 'book_id', 'book_title', 'title_long', 'serie_name', 'serie_dolpo_id', 'book_dolpo_id', 'authors_json', 'babelio_rating', 'babelio_reviews_number', 'dolpo_rating', 'blogger_rating', 'dolpotags_json', 'orderable_status', 'orderable', 'sort'];
$searchAfter=null;
$offset = $request->get('offset', 0);
// Pagination
$results = $dolpoSearchService->bookSearchFilter($filters, $searchAfter, $offset, $pagination, $returnFields);
$count = $dolpoSearchService->bookSearchTotal($filters);
$dolpoRatingLabels = $this->getDolpoRatingLabels();
foreach ($results as &$result) {
if (!array_key_exists('dolpo_rating', $result)) {
continue;
}
$rating = $result['dolpo_rating'];
if ($rating === null || $rating === '') {
continue;
}
$ratingKey = (string) ((int) $rating);
if (array_key_exists($ratingKey, $dolpoRatingLabels)) {
$result['dolpo_rating_label'] = $dolpoRatingLabels[$ratingKey];
}
}
unset($result);
// Ad inside
$itemsSplitForAd = [];
/*
// the ad is finaly not inserted between lines
if( count($arrayPaginate) > 4 && (bool)$request->get("ad") == true ){
$itemsSplitForAd[] = array_slice($arrayPaginate,0,4);
$itemsSplitForAd[] = array_slice($arrayPaginate,4);
}else{*/
$itemsSplitForAd[] = $results;
//}
$params = [
'tagsToShow' => $request->get('tagsToShow'),
'tagsToExcludeIds' => $request->get('tagsToExcludeIds'),
'objectsSelectionIds' => $request->get('objectsSelectionIds'),
'tagsSelectionIds' => $request->get('tagsSelectionIds'),
'text_search' => $textSearch,
'pagination' => $pagination,
'showAd' => (bool)$request->get('ad'),
'showCount' => (bool)$request->get('showCount'),
'title' => $request->get('title'),
'count' => $count,
'offsetNext' => (int)($offset + $pagination),
'uniqueId' => $uniqueId,
'itemsSplitForAd' => $itemsSplitForAd,
'fromAjax' => $request->get('uniqueIdForAjax', null),
'loadNextAjax' => ($count > $offset + $pagination) ? true : false,
'editmode' => $request->get('editmode'),
];
$view = $this->renderView('default/book_gallery.html.twig', $params);
return new Response($view);
}
private function getDolpoRatingLabels(): array
{
$labels = [];
$collectionDefinition = \Pimcore\Model\DataObject\Fieldcollection\Definition::getByKey('Review');
if ($collectionDefinition) {
$fieldDefinitions = $collectionDefinition->getFieldDefinitions();
if (isset($fieldDefinitions['Rating'])) {
$options = $fieldDefinitions['Rating']->getOptions();
foreach ($options as $option) {
if (isset($option['value'], $option['key'])) {
$labels[(string) $option['value']] = (string) $option['key'];
}
}
}
}
return count($labels) > 0 ? $labels : self::DOLPO_RATING_LABELS_FALLBACK;
}
/*
*Counting lines to better locate "voir plus"
*/
private function countLines($text, $lineLength)
{
$words = explode(' ', $text);
$linesCount = 1;
$currentLength = 0;
foreach ($words as $word) {
$wordLength = strlen($word);
if ($currentLength + $wordLength <= $lineLength) {
$currentLength += $wordLength + 1; // +1 for the space
} else {
$linesCount++;
$currentLength = $wordLength + 1; // Start new line, +1 for the space
}
if ($linesCount > 2) {
return 3;
}
}
return $linesCount;
}
public function bookSelectionWithTagsAction(Request $request): Response
{
if ($request->get('type') === 'object') {
$params = [];
$item = $this->_getObjectBookSerieOrOnixProduct((int)$request->get('id'));
if ($item == null) {
throw new NotFoundHttpException('Book, Serie or OnixProduct needed');
}
$tags = $item->getDolpoTags();
$mainTags = [];
$allTags=[];
if (count($tags) > 0) {
foreach ($tags as $tag) {
if($tag->getTagType() == 'category') {
$allTags[] = $tag->getKey();
}
$mainDolpoTag = $tag->getMainDolpoTag();
if($mainDolpoTag != null) {
$key = $mainDolpoTag->getKey();
if (!in_array($key, $mainTags)) {
$mainTags[] = $key;
}
}
}
$tagsForInfo = array_diff($allTags, $mainTags);
}
$additionalLinesToDisplay = 3;
$title = $item->getItemTitle();
$dolpoReview = $item->getItemReviewDolpo();
$additionalLinesToDisplay -= ($this->countLines($title, 26) - 1);
if ($dolpoReview) {
$additionalLinesToDisplay -= ($this->countLines($dolpoReview, 32));
}
$additionalLinesToDisplay = floor(1.5 * $additionalLinesToDisplay);
$descriptionSize = strlen($item->getItemDescription());
$params['item'] = $item;
$params['tagsToShow'] = $request->get('tagsToShow');
$params['showCount'] = (bool)$request->get('showCount');
$params['mainTags'] = $allTags;
$params['additionalLinesToDisplay'] = $additionalLinesToDisplay;
$params['descriptionSize'] = $descriptionSize;
return $this->render('default/book_selection_with_tags.html.twig', $params);
}
}
/*
-------------------
AREABRICK RENDERLET
*/
public function sitemapPageAction(Request $request): Response
{
$params = [];
return $this->render('default/sitemap_page.html.twig', $params);
}
}