<?php
namespace App\Controller;
use Carbon\Carbon;
use CoreShop\Component\Customer\Context\CustomerContextInterface;
use Pimcore;
use Pimcore\Controller\FrontendController;
use Pimcore\Db;
use Pimcore\Model\DataObject\Data\ObjectMetadata;
use Pimcore\Model\DataObject;
use Pimcore\Model\DataObject\Book;
use Pimcore\Model\DataObject\Review;
use Pimcore\Model\DataObject\ReviewCriteria;
use Pimcore\Model\DataObject\Serie;
use Pimcore\Model\DataObject\Service;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class ReviewController extends FrontendController
{
private $_currentCustomer = null;
private $_reviewPath = '';
public $productScoresRatingArray = [
0=>'Décevant, abandonné',
1=>'Décevant mais terminé',
2=>'A lire pour les accros au genre',
3=>'Bouqin sympa',
4=>'Vraiment bon livre',
5=>'Très bon livre, une référence',
];
public function __construct()
{
try {
$this->_currentCustomer = Pimcore::getContainer()->get(CustomerContextInterface::class)->getCustomer();
} catch (\Throwable $th) {
$this->_currentCustomer = null;
}
$websiteSetting = \Pimcore\Model\WebsiteSetting::getByName('reviewPath');
$this->_reviewPath = $websiteSetting->getData();
}
#[Route(path: '/product/formreview/{itemId}', name: 'manageReview')]
public function formAction(Request $request): Response
{
$param = [];
$item = DataObject::getById($request->get('itemId'), true);
$param['itemId'] = $item->getId();
$existingReview = $this->_getExistingReview($item);
$arrayRatingCriteria = [];
$param['existingReviewDecoded'] = '';
if($existingReview != null) {
// For tinyMCE defaut input :
$param['existingReviewDecoded'] = htmlspecialchars_decode($existingReview->getReview());
$param['existingReviewDecoded'] = preg_replace('/\R/', '', $param['existingReviewDecoded']); // Remove Carriage return
$param['existingReviewDecoded'] = addslashes($param['existingReviewDecoded']);
// For defaults ReviewDetailled if update Review
if(count($existingReview->getRatingCriteria())) {
foreach($existingReview->getRatingCriteria() as $ratingC) {
$arrayRatingCriteria[$ratingC->getObjectId()] = $ratingC->getRating() ;
}
}
}
$param['existingReview'] = $existingReview;
$param['arrayRatingCriteria'] = $arrayRatingCriteria;
$criterias = $item->getReviewCriteriaAvailable();
$param['criterias'] = $criterias;
//$param['form'] = $form->createView();
//$form->handleRequest($request);
if (in_array($request->getMethod(), ['POST', 'PUT', 'PATCH'])) {
//if ($form->isValid()) {
//}
/* $data = $form->getData();
var_dump($data);
*/
$message = $request->get('message');
$reviewGlobal = $request->get('reviewglobal');
$reviewCriteria = $request->get('reviewcriteria', []);
// Update if exists
$review = $this->_getExistingReview($item);
if($review instanceof Review) {
} else {
$parentFolder = $this->_getOrCreateFolderByDate();
$key = $this->_getKeyForReview($item);
$review = new Review();
$review->setParent($parentFolder);
$review->setkey($key);
}
// Update or Create : change all fields
$review->setReviewDate(Carbon::now());
$review->setReview($request->get('message'));
$review->setRating($reviewGlobal);
if($this->_currentCustomer != null) {
$review->setCustomer($this->_currentCustomer);
}
$metaDatas = [];
foreach($reviewCriteria as $idCriteria => $rating) {
$criteria = ReviewCriteria::getById($idCriteria);
if($criteria instanceof ReviewCriteria) {
$objMetadata = new ObjectMetadata('RatingCriteria', ['Rating'], $criteria);
$objMetadata->setRating($rating);
$metaDatas[] = $objMetadata;
}
}
$review->setRatingCriteria($metaDatas);
$review->setItem($item);
$review->setPublished(true);
$review->save();
return $this->json(['success' => true]);
}
return $this->render('review/form.html.twig', $param);
}
private function _getOrCreateFolderByDate()
{
$day = date('d');
$month = date('m');
$year = date('Y');
return Service::createFolderByPath($this->_reviewPath . '/'.$year.'/'.$month.'/'.$day);
}
#[Route(path: '/account/deletereview/{itemId}/{reviewId}', name: 'accountDeleteReview')]
public function deleteReviewAction(Request $request): Response
{
$item = DataObject::getById($request->get('itemId', 0));
$review = Review::getById($request->get('reviewId'), true);
if ($review instanceof Review && ($item instanceof Book || $item instanceof Serie)) {
if (($review->getItem() instanceof Book || $review->getItem() instanceof Serie) and $review->getItem()->getId() === $item->getId()) {
$review->delete();
return $this->json(['success' => true]);
}
}
return $this->json(['success' => false]);
}
public function getReviewsFromBase($itemId)
{
$reviewListing = new Review\Listing();
$reviewListing->addConditionParam('Item__id = ' . $itemId, [], ' AND ');
//$reviewListing->addConditionParam("ReviewDate < " . time() - (24*60*60), [], ' AND ');
$reviewListing->setOrderKey('o_creationDate');
$reviewListing->setOrder('DESC');
$reviewsObj = $reviewListing->load();
$reviews=[];
foreach($reviewsObj as $review) {
$customer = $review->getCustomer() ;
$tmp = [];
$tmp['id'] = $review->getId();
$tmp['rating'] = $review->getRating();
$tmp['review'] = $review->getFormattedReview();
$tmp['customer'] = '';
$tmp['image'] = '';
$defaultImageSetting = \Pimcore\Model\WebsiteSetting::getByName('defaultImageAuthor');
$imageDefault = $defaultImageSetting->getData();
if ($imageDefault != null && $imageDefault->getFullPath() != '') {
$tmp['image'] = $imageDefault;
}
if($customer != null and $customer instanceof \Pimcore\Model\DataObject\CoreShopCustomer) {
$tmp['is_contributor']=false;
$tmp['customer'] = $customer->getFirstname();
if($customer->getImage() instanceof \Pimcore\Model\Asset\Image) {
//$tmp['image'] = $customer->getImage()->getFullPath();
$tmp['image'] = $customer->getImage()->getThumbnail('profil_thumb');
}
}
if($customer != null and $customer instanceof \Pimcore\Model\DataObject\Contributor) {
$tmp['is_contributor']=true;
$tmp['customer'] = $customer->getFirstname();
if($customer->getImage() instanceof \Pimcore\Model\Asset\Image) {
//$tmp['image'] = $customer->getImage()->getFullPath();
$tmp['image'] = $customer->getImage()->getThumbnail('contributor_thumb');
if($customer->getWebsite()) {
$tmp['website']=$customer->getWebsite()->getHref();
}
}
}
// Reviews Detailled :
$productScores = [];
$detailledReviews = $review->getRatingCriteria();
foreach($detailledReviews 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))
];
}
$tmp['productScores'] = $finalProductScores;
$reviews[]=$tmp;
}
return $reviews;
}
public function listingByBookAction(Request $request): Response
{
// Number of review by pagination
$forceRefresh = $request->get('refresh');
$paginationDefault = \Pimcore\Model\WebsiteSetting::getByName('paginationReviewsBookDefault');
$paginationDefaultVal = $paginationDefault->getData();
$pagination = $request->get('pagination');
if($pagination == 0) {
$pagination = $paginationDefaultVal;
}
$param = [];
$param['isUpdate'] = false;
$param['customer'] = null;
$reviews = [];
$session = $this->get('session');
$idUniqSession = 'review'.$request->get('itemId');
$offset = $request->get('offset', 0);
$item = DataObject::getById($request->get('itemId'), true);
if ($item instanceof Book || $item instanceof Serie) { //&& $this->_currentCustomer != null
if($session->get($idUniqSession) === null or $forceRefresh) {
// Cache Pimcore
$key = 'bookreviews.'.$request->get('itemId');
$cacheKey = md5($key);
// Get reviews from cache
if($forceRefresh or !$reviewsStored = \Pimcore\Cache::load($cacheKey)) {
$reviews=$this->getReviewsFromBase($request->get('itemId'));
\Pimcore\Cache::save(
$reviews,
$cacheKey,
['book-reviews'],
1800); // 1800 sec = 30min
} else {
$reviews = $reviewsStored;
}
$session->set($idUniqSession, $reviews);
} else {
$reviews = $session->get($idUniqSession);
}
$param['customer'] = $this->_currentCustomer;
$review = $this->_getExistingReview($item);
if($review instanceof Review) {
$param['isUpdate'] = true;
}
}
// Extract by pagination
$reviewsSliced = array_slice($reviews, $offset, $pagination);
$param['reviews'] = $reviewsSliced;
$param['offsetNext'] = (int)($offset + $pagination);
$param['pagination'] = $pagination;
$param['itemId'] = $request->get('itemId');
$param['productScoresRating'] = $this->productScoresRatingArray;
$param['fromAjax'] = $request->get('fromAjax', 0);
$param['showPagination'] = (count($reviews) > $offset + $pagination) ? true : false;
return $this->render('review/listingByBook.html.twig', $param);
}
// Check if review exist for this user / item
private function _getExistingReview($item)
{
$key = $this->_getKeyForReview($item);
$reviewListing = new Review\Listing();
$reviewListing->addConditionParam('o_key = ?', $key, [], ' AND ');
$reviews = $reviewListing->load();
$review = null;
if(count($reviews)) {
$review = $reviews[0];
}
if($review instanceof Review) {
return $review;
}
return null;
}
private function _getKeyForReview($item)
{
$key = $item->getDolpoId();
if($this->_currentCustomer != null) {
$key .= '_'.$this->_currentCustomer->getId();
}
return $key;
}
/*
* Listing under Account/avis page
*/
public function listingByCustomerAction(Request $request): Response
{
$param = [];
$param['reviews'] = [];
if($this->_currentCustomer != null) {
$param['customer'] = $this->_currentCustomer;
$reviewListing = new Review\Listing();
$reviewListing->addConditionParam('Customer__id = ' . $this->_currentCustomer->getId(), [], ' AND ');
$reviews = $reviewListing->load();
$param['reviews'] = $reviews;
}
return $this->render('review/listingByCustomer.html.twig', $param);
}
/*
public function listingByCustomerAction(Request $request): Response
{
$param = [];
$param['reviews'] = [];
if($this->_currentCustomer != null){
$param['customer'] = $this->_currentCustomer;
$sql = "SELECT *
FROM object_relations_BOO r
INNER JOIN object_collection_Review_BOO cr ON ( r.src_id = cr.o_id
AND r.position = cr.index )
WHERE r.fieldname = 'Customer'
AND ownername = 'BookReview'
AND dest_id = '".$this->_currentCustomer->getId()."'
AND cr.fieldname = 'BookReview'";
$query = Db::get()->prepare($sql);
$query->execute();
$results = $query->fetchAll();
foreach($results as $result){
$item = Book::getById($result['src_id']);
if($item == null){
$item = Serie::getById($result['src_id']);
}
$result['item'] = $item;
$param['reviews'][] = $result;
}
}
return $this->render('review/listing.html.twig', $param);
}
*/
}