Files
kupshop/bundles/KupShop/CatalogBundle/View/ReviewsView.php
2025-08-02 16:30:27 +02:00

249 lines
7.2 KiB
PHP

<?php
namespace KupShop\CatalogBundle\View;
use KupShop\CatalogBundle\Util\ReviewsUtil;
use KupShop\ContentBundle\Util\Captcha;
use KupShop\ContentBundle\View\Exception\ValidationException;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Views\Traits\RequestTrait;
use KupShop\KupShopBundle\Views\View;
use Product;
use Query\Operator;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Contracts\Service\Attribute\Required;
class ReviewsView extends View
{
use \DatabaseCommunication;
use RequestTrait;
protected ReviewsUtil $reviewsUtil;
// tohle by bylo potřeba asi udělat jinak ?? > ale na X shopech bych ideálně potřeboval tuhle šablonu pro přidání hodnocení
protected $template = 'focus/focus.review-form.tpl';
private $user;
private $checkUserLog;
protected $productId;
/**
* @var SessionInterface
*/
protected $session;
#[Required]
public function setReviewsUtil(ReviewsUtil $reviewsUtil): void
{
$this->reviewsUtil = $reviewsUtil;
}
public function getBodyVariables()
{
$vars = [];
if (!$this->productId) {
$this->productId = $this->request->get('id_product');
}
$product = $this->getProduct();
if (!$product) {
return $vars;
}
$review = $this->reviewsUtil;
$fields = ['id_product', 'id_product_variation', 'date', 'rating', 'summary', 'pros', 'cons',
'id_user', 'figure', 'id_order', 'data', 'source', ];
if (findModule(\Modules::SALES)) {
$fields[] = 'id_sale';
}
$vars['product'] = $product;
$vars['id_product_variation'] = null;
$vars['date'] = date('Y-m-d H:i:s');
$vars['figure'] = ReviewsUtil::RANK_UNCONFIRMED;
$vars['id_user'] = null;
$vars['verified'] = false;
$vars['data'] = null;
$vars['source'] = null;
if ($name = $this->request->get('name')) {
$fields[] = 'name';
$vars['name'] = $name;
}
$data = $this->request->request->all();
$boughtProduct = null;
if (!empty($data['email']) && !empty($data['order_no'])) {
$vars['data']['email'] = $data['email'];
$vars['data']['order_no'] = $data['order_no'];
// nacteni objednavky pro uzivatele bez registrace
$boughtProduct = $review->hasUserBoughtProduct($this->productId, null, $data['email'], $data['order_no']);
if ($boughtProduct) {
$this->user = \User::createFromSpec(Operator::equals(['email' => $data['email']]));
$vars['id_user'] = $this->user ? $this->user->id : null;
$this->setTemplate('block.reviews.form.tpl');
} else {
$vars['error'] = translate('error_order_not_found', 'returns');
}
} else {
$user = $this->getUser();
$vars['id_user'] = $user ? $user->id : null;
$boughtProduct = $review->hasUserBoughtProduct($this->productId, $vars['id_user']);
}
if ($boughtProduct) {
$vars['verified'] = true;
// possible types: order, sale
$vars["id_{$boughtProduct['type']}"] = $boughtProduct['id'];
if ($this->productId != $boughtProduct['id_product']) {
$this->setProductId($boughtProduct['id_product']);
$vars['product'] = $this->getProduct();
}
}
// Allow rating only once per product
if ($review->hasUserAlreadyRated($this->productId, $vars['id_user'])) {
$vars['already_rated'] = true;
return $vars;
}
$acn = $data['acn'] ?? null;
if ($acn == 'SendReview') {
// Rating is missing
if (!$this->request->get('rating')) {
return $vars;
}
if ($this->checkCaptcha($data)) {
$this->addErrorMessage(translate('errorCaptcha', 'form'));
$vars['error'] = translate('errorCaptcha', 'form');
$vars['data'] = $data;
return $vars;
}
$data = array_merge($this->request->request->all(), $vars);
if (findModule(\Modules::TRANSLATIONS)) {
$languagesContext = ServiceContainer::getService(LanguageContext::class);
$data['id_language'] = $languagesContext->getActiveId();
$fields[] = 'id_language';
}
if (!$this->addReview($review, $data, $fields)) {
return $vars;
}
$vars['sent'] = true;
return $vars;
}
$verified_only = \Settings::getDefault()['review_verified_only'] ?? 'N';
if (($verified_only == 'Y') && !$vars['verified']) {
$this->setTemplate('focus/focus.review-verify-form.tpl');
}
return $vars;
}
public function setCheckUserLog($checkUserLog)
{
$this->checkUserLog = $checkUserLog;
return $this;
}
protected function addReview(ReviewsUtil $review, array $data, array $fields): ?int
{
$reviewId = sqlGetConnection()->transactional(
function () use ($review, $data, $fields) {
if (!empty($data['data'])) {
$data['data'] = json_encode($data['data']);
}
$this->insertSQL('reviews', $this->filterFields($data, $fields));
$reviewId = (int) sqlInsertId();
// Confirm review without comments
if (!$review->hasComment($data)) {
$this->updateSQL('reviews', ['figure' => ReviewsUtil::RANK_CONFIRMED], ['id' => $reviewId]);
}
return $reviewId;
}
);
$this->session->set(
'review',
[
'email' => getVal('email', $data),
'firstname' => getVal('name', $data),
]
);
return $reviewId;
}
protected function checkUserLog()
{
if ($this->checkUserLog) {
// Allow rating only to logged in users
if (!$this->getUser()) {
redirection('LOGIN');
}
}
}
protected function checkCaptcha(array $data)
{
// Check CAPTCHA
if (!$this->getUser()) {
try {
Captcha::checkCaptcha($data, 'shared');
} catch (ValidationException $e) {
return 1;
}
return 0;
}
}
private function getUser()
{
if ($this->user) {
return $this->user;
}
return $this->user = \User::getCurrentUser();
}
/**
* @required
*/
public function setSession(SessionInterface $session)
{
$this->session = $session;
}
public function setProductId(int $id): void
{
$this->productId = $id;
}
private function getProduct(): ?\Product
{
if ($this->productId) {
$product = new \Product();
if ($product->createFromDB($this->productId)) {
return $product;
}
}
return null;
}
}