Subida del módulo y tema de PrestaShop

This commit is contained in:
Kaloyan
2026-04-09 18:31:51 +02:00
parent 12c253296f
commit 16b3ff9424
39262 changed files with 7418797 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
<?php
$config = new PrestaShop\CodingStandards\CsFixer\Config();
$config
->setUsingCache(true)
->getFinder()
->in(__DIR__)
->exclude('vendor');
return $config;

View File

@@ -0,0 +1,415 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class ProductComment extends ObjectModel
{
/** @var int */
public $id;
/** @var int */
public $id_product;
/** @var int */
public $id_customer;
/** @var int */
public $id_guest;
/** @var int */
public $customer_name;
/** @var string */
public $title;
/** @var string */
public $content;
/** @var int */
public $grade;
/** @var bool */
public $validate = false;
/** @var bool */
public $deleted = false;
/** @var string Object creation date */
public $date_add;
/**
* @see ObjectModel::$definition
*/
public static $definition = [
'table' => 'product_comment',
'primary' => 'id_product_comment',
'fields' => [
'id_product' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true],
'id_customer' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true],
'id_guest' => ['type' => self::TYPE_INT],
'customer_name' => ['type' => self::TYPE_STRING],
'title' => ['type' => self::TYPE_STRING],
'content' => ['type' => self::TYPE_STRING, 'validate' => 'isMessage', 'size' => 65535, 'required' => true],
'grade' => ['type' => self::TYPE_FLOAT, 'validate' => 'isFloat'],
'validate' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
'deleted' => ['type' => self::TYPE_BOOL],
'date_add' => ['type' => self::TYPE_DATE],
],
];
/**
* Get comments by IdProduct
*
* @return array|bool
*/
public static function getByProduct($id_product, $p = 1, $n = null, $id_customer = null)
{
if (!Validate::isUnsignedId($id_product)) {
return false;
}
$validate = (bool) Configuration::get('PRODUCT_COMMENTS_MODERATE');
$p = (int) $p;
$n = (int) $n;
$id_customer = (int) $id_customer;
if ($p <= 1) {
$p = 1;
}
if ($n != null && $n <= 0) {
$n = 5;
}
$cache_id = 'ProductComment::getByProduct_' . $id_product . '-' . $p . '-' . $n . '-' . $id_customer . '-' . $validate;
if (!Cache::isStored($cache_id)) {
$result = Db::getInstance((bool) _PS_USE_SQL_SLAVE_)->executeS('
SELECT pc.`id_product_comment`,
(SELECT count(*) FROM `' . _DB_PREFIX_ . 'product_comment_usefulness` pcu WHERE pcu.`id_product_comment` = pc.`id_product_comment` AND pcu.`usefulness` = 1) AS total_useful,
(SELECT count(*) FROM `' . _DB_PREFIX_ . 'product_comment_usefulness` pcu WHERE pcu.`id_product_comment` = pc.`id_product_comment`) AS total_advice, ' .
($id_customer ? '(SELECT count(*) FROM `' . _DB_PREFIX_ . 'product_comment_usefulness` pcuc WHERE pcuc.`id_product_comment` = pc.`id_product_comment` AND pcuc.id_customer = ' . $id_customer . ') AS customer_advice, ' : '') .
($id_customer ? '(SELECT count(*) FROM `' . _DB_PREFIX_ . 'product_comment_report` pcrc WHERE pcrc.`id_product_comment` = pc.`id_product_comment` AND pcrc.id_customer = ' . $id_customer . ') AS customer_report, ' : '') . '
IF(c.id_customer, CONCAT(c.`firstname`, \' \', LEFT(c.`lastname`, 1)), pc.customer_name) customer_name, pc.`content`, pc.`grade`, pc.`date_add`, pc.title
FROM `' . _DB_PREFIX_ . 'product_comment` pc
LEFT JOIN `' . _DB_PREFIX_ . 'customer` c ON c.`id_customer` = pc.`id_customer`
WHERE pc.`id_product` = ' . $id_product . ($validate ? ' AND pc.`validate` = 1' : '') . '
ORDER BY pc.`date_add` DESC
' . ($n ? 'LIMIT ' . (($p - 1) * $n) . ', ' . $n : ''));
Cache::store($cache_id, $result);
}
return Cache::retrieve($cache_id);
}
/**
* Return customer's comment
*
* @return array Comments
*/
public static function getByCustomer($id_product, $id_customer, $get_last = false, $id_guest = false)
{
$cache_id = 'ProductComment::getByCustomer_' . (int) $id_product . '-' . (int) $id_customer . '-' . (bool) $get_last . '-' . (int) $id_guest;
if (!Cache::isStored($cache_id)) {
$results = Db::getInstance()->executeS('
SELECT *
FROM `' . _DB_PREFIX_ . 'product_comment` pc
WHERE pc.`id_product` = ' . (int) $id_product . '
AND ' . (!$id_guest ? 'pc.`id_customer` = ' . (int) $id_customer : 'pc.`id_guest` = ' . (int) $id_guest) . '
ORDER BY pc.`date_add` DESC '
. ($get_last ? 'LIMIT 1' : '')
);
if ($get_last && count($results)) {
$results = array_shift($results);
}
Cache::store($cache_id, $results);
}
return Cache::retrieve($cache_id);
}
/**
* Get Grade By product
*
* @return array|bool
*/
public static function getGradeByProduct($id_product, $id_lang)
{
if (!Validate::isUnsignedId($id_product) ||
!Validate::isUnsignedId($id_lang)) {
return false;
}
$validate = (bool) Configuration::get('PRODUCT_COMMENTS_MODERATE');
return Db::getInstance((bool) _PS_USE_SQL_SLAVE_)->executeS('
SELECT pc.`id_product_comment`, pcg.`grade`, pccl.`name`, pcc.`id_product_comment_criterion`
FROM `' . _DB_PREFIX_ . 'product_comment` pc
LEFT JOIN `' . _DB_PREFIX_ . 'product_comment_grade` pcg ON (pcg.`id_product_comment` = pc.`id_product_comment`)
LEFT JOIN `' . _DB_PREFIX_ . 'product_comment_criterion` pcc ON (pcc.`id_product_comment_criterion` = pcg.`id_product_comment_criterion`)
LEFT JOIN `' . _DB_PREFIX_ . 'product_comment_criterion_lang` pccl ON (pccl.`id_product_comment_criterion` = pcg.`id_product_comment_criterion`)
WHERE pc.`id_product` = ' . $id_product . '
AND pccl.`id_lang` = ' . $id_lang .
($validate ? ' AND pc.`validate` = 1' : ''));
}
public static function getRatings($id_product)
{
$validate = Configuration::get('PRODUCT_COMMENTS_MODERATE');
$sql = 'SELECT AVG(pc.`grade`) AS avg,
MIN(pc.`grade`) AS min,
MAX(pc.`grade`) AS max
FROM `' . _DB_PREFIX_ . 'product_comment` pc
WHERE pc.`id_product` = ' . (int) $id_product . '
AND pc.`deleted` = 0' .
($validate == '1' ? ' AND pc.`validate` = 1' : '');
return Db::getInstance((bool) _PS_USE_SQL_SLAVE_)->getRow($sql);
}
public static function getAveragesByProduct($id_product, $id_lang)
{
/* Get all grades */
$grades = ProductComment::getGradeByProduct((int) $id_product, (int) $id_lang);
$total = ProductComment::getGradedCommentNumber((int) $id_product);
if (!count($grades) || !$total) {
return [];
}
/* Addition grades for each criterion */
$criterionsGradeTotal = [];
$count_grades = count($grades);
for ($i = 0; $i < $count_grades; ++$i) {
if (array_key_exists($grades[$i]['id_product_comment_criterion'], $criterionsGradeTotal) === false) {
$criterionsGradeTotal[$grades[$i]['id_product_comment_criterion']] = (int) ($grades[$i]['grade']);
} else {
$criterionsGradeTotal[$grades[$i]['id_product_comment_criterion']] += (int) ($grades[$i]['grade']);
}
}
/* Finally compute the averages */
$averages = [];
foreach ($criterionsGradeTotal as $key => $criterionGradeTotal) {
$averages[(int) $key] = $criterionGradeTotal / $total;
}
return $averages;
}
/**
* Return number of comments and average grade by products
*
* @return int|bool
*/
public static function getGradedCommentNumber($id_product)
{
if (!Validate::isUnsignedId($id_product)) {
return false;
}
$validate = (int) Configuration::get('PRODUCT_COMMENTS_MODERATE');
$result = Db::getInstance((bool) _PS_USE_SQL_SLAVE_)->getRow('
SELECT COUNT(pc.`id_product`) AS nbr
FROM `' . _DB_PREFIX_ . 'product_comment` pc
WHERE `id_product` = ' . $id_product . ($validate == '1' ? ' AND `validate` = 1' : '') . '
AND `grade` > 0');
return (int) ($result['nbr']);
}
/**
* Get comments by Validation
*
* @return array Comments
*
* @deprecated 6.0.0
*/
public static function getByValidate($validate = '0', $deleted = false, $p = null, $limit = null, $skip_validate = false)
{
$sql = '
SELECT pc.`id_product_comment`, pc.`id_product`, c.id_customer AS customer_id, IF(c.id_customer, CONCAT(c.`firstname`, \' \', c.`lastname`), pc.customer_name) customer_name, pc.`title`, pc.`content`, pc.`grade`, pc.`date_add`, pl.`name`
FROM `' . _DB_PREFIX_ . 'product_comment` pc
LEFT JOIN `' . _DB_PREFIX_ . 'customer` c ON (c.`id_customer` = pc.`id_customer`)
LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON (pl.`id_product` = pc.`id_product` AND pl.`id_lang` = ' . (int) Context::getContext()->language->id . Shop::addSqlRestrictionOnLang('pl') . ')';
if (!$skip_validate) {
$sql .= ' WHERE pc.`validate` = ' . (int) $validate;
}
$sql .= ' ORDER BY pc.`date_add` DESC';
if ($p && $limit) {
$offset = ($p - 1) * $limit;
$sql .= ' LIMIT ' . (int) $offset . ',' . (int) $limit;
}
return Db::getInstance()->executeS($sql);
}
/**
* Get numbers of comments by Validation
*
* @return int Count of comments
*
* @deprecated 6.0.0
*/
public static function getCountByValidate($validate = '0', $skip_validate = false)
{
$sql = '
SELECT COUNT(*)
FROM `' . _DB_PREFIX_ . 'product_comment`';
if (!$skip_validate) {
$sql .= ' WHERE `validate` = ' . (int) $validate;
}
return (int) Db::getInstance()->getValue($sql);
}
/**
* Get all comments
*
* @return array Comments
*/
public static function getAll()
{
return Db::getInstance()->executeS('
SELECT pc.`id_product_comment`, pc.`id_product`, IF(c.id_customer, CONCAT(c.`firstname`, \' \', c.`lastname`), pc.customer_name) customer_name, pc.`content`, pc.`grade`, pc.`date_add`, pl.`name`
FROM `' . _DB_PREFIX_ . 'product_comment` pc
LEFT JOIN `' . _DB_PREFIX_ . 'customer` c ON (c.`id_customer` = pc.`id_customer`)
LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON (pl.`id_product` = pc.`id_product` AND pl.`id_lang` = ' . (int) Context::getContext()->language->id . Shop::addSqlRestrictionOnLang('pl') . ')
ORDER BY pc.`date_add` DESC');
}
/**
* Validate a comment
*
* @return bool succeed
*/
public function validate($validate = '1')
{
if (!Validate::isUnsignedId($this->id)) {
return false;
}
$success = (Db::getInstance()->execute('
UPDATE `' . _DB_PREFIX_ . 'product_comment` SET
`validate` = ' . (int) $validate . '
WHERE `id_product_comment` = ' . $this->id));
Hook::exec('actionObjectProductCommentValidateAfter', ['object' => $this]);
return $success;
}
/**
* Delete a comment, grade and report data
*
* @return bool succeed
*
* @deprecated 6.0.0
*/
public function delete()
{
return parent::delete()
&& ProductComment::deleteGrades($this->id)
&& ProductComment::deleteReports($this->id)
&& ProductComment::deleteUsefulness($this->id);
}
/**
* Delete Grades
*
* @return bool succeed
*
* @deprecated 6.0.0
*/
public static function deleteGrades($id_product_comment)
{
if (!Validate::isUnsignedId($id_product_comment)) {
return false;
}
return Db::getInstance()->execute('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_grade`
WHERE `id_product_comment` = ' . $id_product_comment);
}
/**
* Delete Reports
*
* @return bool succeed
*
* @deprecated 6.0.0
*/
public static function deleteReports($id_product_comment)
{
if (!Validate::isUnsignedId($id_product_comment)) {
return false;
}
return Db::getInstance()->execute('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_report`
WHERE `id_product_comment` = ' . $id_product_comment);
}
/**
* Delete usefulness
*
* @return bool succeed
*
* @deprecated 6.0.0
*/
public static function deleteUsefulness($id_product_comment)
{
if (!Validate::isUnsignedId($id_product_comment)) {
return false;
}
return Db::getInstance()->execute('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_usefulness`
WHERE `id_product_comment` = ' . $id_product_comment);
}
/**
* Get reported comments
*
* @return array Comments
*
* @deprecated 6.0.0
*/
public static function getReportedComments()
{
return Db::getInstance((bool) _PS_USE_SQL_SLAVE_)->executeS('
SELECT DISTINCT(pc.`id_product_comment`), pc.`id_product`, IF(c.id_customer, CONCAT(c.`firstname`, \' \', c.`lastname`), pc.customer_name) customer_name, pc.`content`, pc.`grade`, pc.`date_add`, pl.`name`, pc.`title`
FROM `' . _DB_PREFIX_ . 'product_comment_report` pcr
LEFT JOIN `' . _DB_PREFIX_ . 'product_comment` pc
ON pcr.id_product_comment = pc.id_product_comment
LEFT JOIN `' . _DB_PREFIX_ . 'customer` c ON (c.`id_customer` = pc.`id_customer`)
LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON (pl.`id_product` = pc.`id_product` AND pl.`id_lang` = ' . (int) Context::getContext()->language->id . ' AND pl.`id_lang` = ' . (int) Context::getContext()->language->id . Shop::addSqlRestrictionOnLang('pl') . ')
ORDER BY pc.`date_add` DESC');
}
}

View File

@@ -0,0 +1,237 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
class ProductCommentCriterion extends ObjectModel
{
const NAME_MAX_LENGTH = 64;
public $id;
public $id_product_comment_criterion_type;
public $name;
public $active = true;
/**
* @see ObjectModel::$definition
*/
public static $definition = [
'table' => 'product_comment_criterion',
'primary' => 'id_product_comment_criterion',
'multilang' => true,
'fields' => [
'id_product_comment_criterion_type' => ['type' => self::TYPE_INT],
'active' => ['type' => self::TYPE_BOOL],
// Lang fields
'name' => ['type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'required' => true, 'size' => self::NAME_MAX_LENGTH],
],
];
/**
* @deprecated 6.0.0 - migrated to src/Repository/ProductCommentCriterionRepository
*/
public function delete()
{
if (!parent::delete()) {
return false;
}
if ($this->id_product_comment_criterion_type == 2) {
if (!Db::getInstance()->execute('
DELETE FROM ' . _DB_PREFIX_ . 'product_comment_criterion_category
WHERE id_product_comment_criterion=' . (int) $this->id)) {
return false;
}
} elseif ($this->id_product_comment_criterion_type == 3) {
if (!Db::getInstance()->execute('
DELETE FROM ' . _DB_PREFIX_ . 'product_comment_criterion_product
WHERE id_product_comment_criterion=' . (int) $this->id)) {
return false;
}
}
return Db::getInstance()->execute('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_grade`
WHERE `id_product_comment_criterion` = ' . (int) $this->id);
}
public function update($nullValues = false)
{
$previousUpdate = new self((int) $this->id);
if (!parent::update($nullValues)) {
return false;
}
if ($previousUpdate->id_product_comment_criterion_type != $this->id_product_comment_criterion_type) {
if ($previousUpdate->id_product_comment_criterion_type == 2) {
return Db::getInstance()->execute('
DELETE FROM ' . _DB_PREFIX_ . 'product_comment_criterion_category
WHERE id_product_comment_criterion = ' . (int) $previousUpdate->id);
} elseif ($previousUpdate->id_product_comment_criterion_type == 3) {
return Db::getInstance()->execute('
DELETE FROM ' . _DB_PREFIX_ . 'product_comment_criterion_product
WHERE id_product_comment_criterion = ' . (int) $previousUpdate->id);
}
}
return true;
}
/**
* Link a Comment Criterion to a product
*
* @return bool succeed
*
* @deprecated 6.0.0 - migrated to src/Repository/ProductCommentCriterionRepository
*/
public function addProduct($id_product)
{
if (!Validate::isUnsignedId($id_product)) {
exit(Tools::displayError());
}
return Db::getInstance()->execute('
INSERT INTO `' . _DB_PREFIX_ . 'product_comment_criterion_product` (`id_product_comment_criterion`, `id_product`)
VALUES(' . (int) $this->id . ',' . $id_product . ')
');
}
/**
* Link a Comment Criterion to a category
*
* @return bool succeed
*
* @deprecated 6.0.0 - migrated to src/Repository/ProductCommentCriterionRepository
*/
public function addCategory($id_category)
{
if (!Validate::isUnsignedId($id_category)) {
exit(Tools::displayError());
}
return Db::getInstance()->execute('
INSERT INTO `' . _DB_PREFIX_ . 'product_comment_criterion_category` (`id_product_comment_criterion`, `id_category`)
VALUES(' . (int) $this->id . ',' . $id_category . ')
');
}
/**
* Get Criterions
*
* @return array Criterions
*
* @deprecated 6.0.0
*/
public static function getCriterions($id_lang, $type = false, $active = false)
{
if (!Validate::isUnsignedId($id_lang)) {
exit(Tools::displayError());
}
$sql = '
SELECT pcc.`id_product_comment_criterion`, pcc.id_product_comment_criterion_type, pccl.`name`, pcc.active
FROM `' . _DB_PREFIX_ . 'product_comment_criterion` pcc
JOIN `' . _DB_PREFIX_ . 'product_comment_criterion_lang` pccl ON (pcc.id_product_comment_criterion = pccl.id_product_comment_criterion)
WHERE pccl.`id_lang` = ' . $id_lang . ($active ? ' AND active = 1' : '') . ($type ? ' AND id_product_comment_criterion_type = ' . (int) $type : '') . '
ORDER BY pccl.`name` ASC';
$criterions = Db::getInstance()->executeS($sql);
$types = self::getTypes();
foreach ($criterions as $key => $data) {
$criterions[$key]['type_name'] = $types[$data['id_product_comment_criterion_type']];
}
return $criterions;
}
/**
* @deprecated 6.0.0
*/
public function getProducts()
{
$res = Db::getInstance()->executeS('
SELECT pccp.id_product, pccp.id_product_comment_criterion
FROM `' . _DB_PREFIX_ . 'product_comment_criterion_product` pccp
WHERE pccp.id_product_comment_criterion = ' . (int) $this->id);
$products = [];
if ($res) {
foreach ($res as $row) {
$products[] = (int) $row['id_product'];
}
}
return $products;
}
/**
* @deprecated 6.0.0
*/
public function getCategories()
{
$res = Db::getInstance()->executeS('
SELECT pccc.id_category, pccc.id_product_comment_criterion
FROM `' . _DB_PREFIX_ . 'product_comment_criterion_category` pccc
WHERE pccc.id_product_comment_criterion = ' . (int) $this->id);
$criterions = [];
if ($res) {
foreach ($res as $row) {
$criterions[] = (int) $row['id_category'];
}
}
return $criterions;
}
/**
* @deprecated 6.0.0
*/
public function deleteCategories()
{
return Db::getInstance()->execute('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_criterion_category`
WHERE `id_product_comment_criterion` = ' . (int) $this->id);
}
/**
* @deprecated 6.0.0
*/
public function deleteProducts()
{
return Db::getInstance()->execute('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_criterion_product`
WHERE `id_product_comment_criterion` = ' . (int) $this->id);
}
/**
* @deprecated 6.0.0
*/
public static function getTypes()
{
// Instance of module class for translations
$module = new ProductComments();
return [
1 => $module->getTranslator()->trans('Valid for the entire catalog', [], 'Modules.Productcomments.Admin'),
2 => $module->getTranslator()->trans('Restricted to some categories', [], 'Modules.Productcomments.Admin'),
3 => $module->getTranslator()->trans('Restricted to some products', [], 'Modules.Productcomments.Admin'),
];
}
}

2426
modules/productcomments/composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>productcomments</name>
<displayName><![CDATA[Product Comments]]></displayName>
<version><![CDATA[8.0.0]]></version>
<description><![CDATA[Allows users to post reviews and rate products on specific criteria.]]></description>
<author><![CDATA[PrestaShop]]></author>
<tab><![CDATA[front_office_features]]></tab>
<is_configurable>1</is_configurable>
<need_instance>0</need_instance>
<limited_countries></limited_countries>
</module>

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,18 @@
imports:
- { resource: ../common.yml }
services:
product_comment_criterion_form_data_provider:
class: 'PrestaShop\Module\ProductComment\Form\ProductCommentCriterionFormDataProvider'
public: true
arguments:
- '@product_comment_criterion_repository'
- '@prestashop.core.admin.lang.repository'
product_comment_criterion_form_data_handler:
class: 'PrestaShop\Module\ProductComment\Form\ProductCommentCriterionFormDataHandler'
public: true
arguments:
- '@product_comment_criterion_repository'
- '@prestashop.core.admin.lang.repository'
- '@doctrine.orm.default_entity_manager'

View File

@@ -0,0 +1,19 @@
services:
_defaults:
public: true
product_comment_criterion_repository:
class: PrestaShop\Module\ProductComment\Repository\ProductCommentCriterionRepository
arguments:
- '@doctrine'
- '@doctrine.dbal.default_connection'
- '%database_prefix%'
product_comment_repository:
class: PrestaShop\Module\ProductComment\Repository\ProductCommentRepository
arguments:
- '@doctrine'
- '@doctrine.dbal.default_connection'
- '%database_prefix%'
- '@=service("prestashop.adapter.legacy.configuration").get("PRODUCT_COMMENTS_ALLOW_GUESTS")'
- '@=service("prestashop.adapter.legacy.configuration").get("PRODUCT_COMMENTS_MINIMAL_TIME")'

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,2 @@
imports:
- { resource: ../common.yml }

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,66 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
use PrestaShop\Module\ProductComment\Repository\ProductCommentRepository;
class ProductCommentsCommentGradeModuleFrontController extends ModuleFrontController
{
public function display()
{
$idProducts = Tools::getValue('id_products');
/* @var ProductCommentRepository $productCommentRepository */
header('Content-Type: application/json');
if (!is_array($idProducts)) {
return $this->ajaxRender(null);
}
$idProducts = array_unique(array_map('intval', $idProducts));
$productCommentRepository = $this->context->controller->getContainer()->get('product_comment_repository');
$productsCommentsNb = $productCommentRepository->getCommentsNumberForProducts($idProducts, Configuration::get('PRODUCT_COMMENTS_MODERATE'));
$averageGrade = $productCommentRepository->getAverageGrades($idProducts, Configuration::get('PRODUCT_COMMENTS_MODERATE'));
$resultFormated = [];
foreach ($idProducts as $i => $id) {
$resultFormated[] = [
'id_product' => $id,
'comments_nb' => $productsCommentsNb[$id],
'average_grade' => $averageGrade[$id],
];
}
$this->ajaxRender(
json_encode(
[
'products' => $resultFormated,
]
)
);
}
}

View File

@@ -0,0 +1,113 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
use PrestaShop\Module\ProductComment\Repository\ProductCommentRepository;
class ProductCommentsListCommentsModuleFrontController extends ModuleFrontController
{
public function display()
{
$idProduct = (int) Tools::getValue('id_product');
$page = (int) Tools::getValue('page', 1);
$isLastNameAnonymous = Configuration::get('PRODUCT_COMMENTS_ANONYMISATION');
/** @var ProductCommentRepository $productCommentRepository */
$productCommentRepository = $this->context->controller->getContainer()->get('product_comment_repository');
$productComments = $productCommentRepository->paginate(
$idProduct,
$page,
(int) Configuration::get('PRODUCT_COMMENTS_COMMENTS_PER_PAGE'),
(bool) Configuration::get('PRODUCT_COMMENTS_MODERATE')
);
$productCommentsNb = $productCommentRepository->getCommentsNumber(
$idProduct,
(bool) Configuration::get('PRODUCT_COMMENTS_MODERATE')
);
$responseArray = [
'comments_nb' => $productCommentsNb,
'comments_per_page' => Configuration::get('PRODUCT_COMMENTS_COMMENTS_PER_PAGE'),
'comments' => [],
];
foreach ($productComments as $productComment) {
$dateAdd = new \DateTime($productComment['date_add'], new \DateTimeZone('UTC'));
$dateAdd->setTimezone(new \DateTimeZone(date_default_timezone_get()));
$dateFormatter = new \IntlDateFormatter(
$this->context->language->locale,
\IntlDateFormatter::SHORT,
\IntlDateFormatter::SHORT
);
$productComment['title'] = htmlentities($productComment['title']);
$productComment['content'] = htmlentities($productComment['content']);
$productComment['date_add'] = $dateFormatter->format($dateAdd);
// The customer has firstname and lastname, for guest we only have customer_name field
$productComment['customer_name'] = !empty($productComment['customer_name'])
? $productComment['customer_name']
: $productComment['firstname'] . ' ' . $productComment['lastname'];
if ($isLastNameAnonymous) {
$productComment['customer_name'] = $this->anonymizeName($productComment['customer_name']);
$productComment['lastname'] = '...';
}
$productComment['customer_name'] = htmlentities($productComment['customer_name']);
$usefulness = $productCommentRepository->getProductCommentUsefulness($productComment['id_product_comment']);
$productComment = array_merge($productComment, $usefulness);
if (empty($productComment['customer_name'])) {
$productComment['customer_name'] = $this->trans('Deleted account', [], 'Modules.Productcomments.Shop');
}
$responseArray['comments'][] = $productComment;
}
header('Content-Type: application/json');
$this->ajaxRender(
json_encode(
$responseArray
)
);
}
/**
* Anonymize the user's last name. Display only initials, e.g. John D.
*
* @param string $name
*/
private function anonymizeName($name)
{
$parts = explode(' ', $name);
$firstName = $parts[0];
$lastName = count($parts) > 1 ? array_pop($parts) : '';
$name = $firstName;
if (!empty($lastName)) {
$name .= ' ' . mb_substr($lastName, 0, 1, 'UTF-8') . '.';
}
return $name;
}
}

View File

@@ -0,0 +1,213 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
use Doctrine\ORM\EntityManagerInterface;
use PrestaShop\Module\ProductComment\Entity\ProductComment;
use PrestaShop\Module\ProductComment\Entity\ProductCommentCriterion;
use PrestaShop\Module\ProductComment\Entity\ProductCommentGrade;
use PrestaShop\Module\ProductComment\Repository\ProductCommentRepository;
class ProductCommentsPostCommentModuleFrontController extends ModuleFrontController
{
public function display()
{
header('Content-Type: application/json');
if (!$this->context->customer->isLogged() && !Configuration::get('PRODUCT_COMMENTS_ALLOW_GUESTS')) {
$this->ajaxRender(
json_encode(
[
'success' => false,
'error' => $this->trans(
'You need to be [1]logged in[/1] or [2]create an account[/2] to post your review.',
[
'[1]' => '<a href="' . $this->context->link->getPageLink('my-account') . '">',
'[/1]' => '</a>',
'[2]' => '<a href="' . $this->context->link->getPageLink('authentication&create_account=1') . '">',
'[/2]' => '</a>',
],
'Modules.Productcomments.Shop'
),
]
)
);
return false;
}
$id_product = (int) Tools::getValue('id_product');
$comment_title = Tools::getValue('comment_title');
$comment_content = Tools::getValue('comment_content');
$customer_name = Tools::getValue('customer_name');
$criterions = (array) Tools::getValue('criterion');
/** @var ProductCommentRepository $productCommentRepository */
$productCommentRepository = $this->context->controller->getContainer()->get('product_comment_repository');
$isPostAllowed = $productCommentRepository->isPostAllowed(
$id_product,
(int) $this->context->cookie->id_customer,
(int) $this->context->cookie->id_guest
);
if (!$isPostAllowed) {
$this->ajaxRender(
json_encode(
[
'success' => false,
'error' => $this->trans('You are not allowed to post a review at the moment, please try again later.', [], 'Modules.Productcomments.Shop'),
]
)
);
return false;
}
/** @var EntityManagerInterface $entityManager */
$entityManager = $this->container->get('doctrine.orm.entity_manager');
//Create product comment
$productComment = new ProductComment();
$productComment
->setProductId($id_product)
->setTitle($comment_title)
->setContent($comment_content)
->setCustomerName($customer_name)
->setCustomerId($this->context->cookie->id_customer)
->setGuestId($this->context->cookie->id_guest)
->setDateAdd(new \DateTime('now', new \DateTimeZone('UTC')))
;
//Validate comment
$errors = array_merge($this->validateComment($productComment), $this->validateCriterions($criterions));
if (!empty($errors)) {
$this->ajaxRender(
json_encode(
[
'success' => false,
'errors' => $errors,
]
)
);
return false;
}
$entityManager->persist($productComment);
$this->addCommentGrades($productComment, $criterions);
$entityManager->flush();
$this->ajaxRender(
json_encode(
[
'success' => true,
'product_comment' => $productComment->toArray(),
]
)
);
}
/**
* @param ProductComment $productComment
* @param array $criterions
*
* @throws Exception
*/
private function addCommentGrades(ProductComment $productComment, array $criterions)
{
/** @var EntityManagerInterface $entityManager */
$entityManager = $this->container->get('doctrine.orm.entity_manager');
$criterionRepository = $entityManager->getRepository(ProductCommentCriterion::class);
$averageGrade = 0;
foreach ($criterions as $criterionId => $grade) {
$criterion = $criterionRepository->findOneBy(['id' => $criterionId]);
$criterionGrade = new ProductCommentGrade(
$productComment,
$criterion,
$grade
);
$entityManager->persist($criterionGrade);
$averageGrade += $grade;
}
$averageGrade /= count($criterions);
$productComment->setGrade($averageGrade);
}
/**
* Manual validation for now, this would be nice to use Symfony validator with the annotation
*
* @param ProductComment $productComment
*
* @return array
*/
private function validateComment(ProductComment $productComment)
{
$errors = [];
if (empty($productComment->getTitle())) {
$errors[] = $this->trans('Title cannot be empty', [], 'Modules.Productcomments.Shop');
} elseif (strlen($productComment->getTitle()) > ProductComment::TITLE_MAX_LENGTH) {
$errors[] = $this->trans('Title cannot be more than %s characters', [ProductComment::TITLE_MAX_LENGTH], 'Modules.Productcomments.Shop');
}
if (!$productComment->getCustomerId()) {
if (empty($productComment->getCustomerName())) {
$errors[] = $this->trans('Customer name cannot be empty', [], 'Modules.Productcomments.Shop');
} elseif (strlen($productComment->getCustomerName()) > ProductComment::CUSTOMER_NAME_MAX_LENGTH) {
$errors[] = $this->trans('Customer name cannot be more than %s characters', [ProductComment::CUSTOMER_NAME_MAX_LENGTH], 'Modules.Productcomments.Shop');
}
}
return $errors;
}
/**
* Valdiate criterions values
*
* @todo manage validation for criterion restricted on categories or products
*
* @param array $criterions
*
* @return array
*/
private function validateCriterions(array $criterions)
{
$errors = [];
/** @var EntityManagerInterface $entityManager */
$entityManager = $this->container->get('doctrine.orm.entity_manager');
$criterionRepository = $entityManager->getRepository(ProductCommentCriterion::class);
foreach ($criterions as $criterionId => $grade) {
// @todo manage validation for criterion restricted on categories or products
$criterion = $criterionRepository->findOneBy(['id' => $criterionId]);
if (empty($criterion)) {
$errors[] = $this->trans('Criterions not available', [], 'Modules.Productcomments.Shop');
}
}
return $errors;
}
}

View File

@@ -0,0 +1,107 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
use Doctrine\ORM\EntityManagerInterface;
use PrestaShop\Module\ProductComment\Entity\ProductComment;
use PrestaShop\Module\ProductComment\Entity\ProductCommentReport;
class ProductCommentsReportCommentModuleFrontController extends ModuleFrontController
{
public function display()
{
header('Content-Type: application/json');
$customerId = (int) $this->context->cookie->id_customer;
if (!$customerId) {
$this->ajaxRender(
json_encode(
[
'success' => false,
'error' => $this->trans('You need to be logged in to report a review.', [], 'Modules.Productcomments.Shop'),
]
)
);
return false;
}
$id_product_comment = (int) Tools::getValue('id_product_comment');
/** @var EntityManagerInterface $entityManager */
$entityManager = $this->container->get('doctrine.orm.entity_manager');
$productCommentEntityRepository = $entityManager->getRepository(ProductComment::class);
/** @var ProductComment|null $productComment */
$productComment = $productCommentEntityRepository->findOneBy(['id' => $id_product_comment]);
if (!$productComment) {
$this->ajaxRender(
json_encode(
[
'success' => false,
'error' => $this->trans('Cannot find the requested product review.', [], 'Modules.Productcomments.Shop'),
]
)
);
return false;
}
$productCommentAbuseRepository = $entityManager->getRepository(ProductCommentReport::class);
/** @var ProductCommentReport|null $productCommentAbuse */
$productCommentAbuse = $productCommentAbuseRepository->findOneBy([
'comment' => $id_product_comment,
'customerId' => $customerId,
]);
if ($productCommentAbuse) {
$this->ajaxRender(
json_encode(
[
'success' => false,
'error' => $this->trans('You already reported this review as abusive.', [], 'Modules.Productcomments.Shop'),
]
)
);
return false;
}
$productCommentAbuse = new ProductCommentReport(
$productComment,
$customerId
);
$entityManager->persist($productCommentAbuse);
$entityManager->flush();
$this->ajaxRender(
json_encode(
[
'success' => true,
'id_product_comment' => $id_product_comment,
]
)
);
}
}

View File

@@ -0,0 +1,130 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
use Doctrine\ORM\EntityManagerInterface;
use PrestaShop\Module\ProductComment\Entity\ProductComment;
use PrestaShop\Module\ProductComment\Entity\ProductCommentUsefulness;
use PrestaShop\Module\ProductComment\Repository\ProductCommentRepository;
class ProductCommentsUpdateCommentUsefulnessModuleFrontController extends ModuleFrontController
{
public function display()
{
header('Content-Type: application/json');
if (!Configuration::get('PRODUCT_COMMENTS_USEFULNESS')) {
$this->ajaxRender(
json_encode(
[
'success' => false,
'error' => $this->trans('This feature is not enabled.', [], 'Modules.Productcomments.Shop'),
]
)
);
return false;
}
$customerId = (int) $this->context->cookie->id_customer;
if (!$customerId) {
$this->ajaxRender(
json_encode(
[
'success' => false,
'error' => $this->trans(
'You need to be [1]logged in[/1] or [2]create an account[/2] to give your appreciation of a review.',
[
'[1]' => '<a href="' . $this->context->link->getPageLink('my-account') . '">',
'[/1]' => '</a>',
'[2]' => '<a href="' . $this->context->link->getPageLink('authentication&create_account=1') . '">',
'[/2]' => '</a>',
],
'Modules.Productcomments.Shop'
),
]
)
);
return false;
}
$id_product_comment = (int) Tools::getValue('id_product_comment');
$usefulness = (bool) Tools::getValue('usefulness');
/** @var EntityManagerInterface $entityManager */
$entityManager = $this->container->get('doctrine.orm.entity_manager');
$productCommentEntityRepository = $entityManager->getRepository(ProductComment::class);
/** @var ProductComment|null $productComment */
$productComment = $productCommentEntityRepository->findOneBy(['id' => $id_product_comment]);
if (!$productComment) {
$this->ajaxRender(
json_encode(
[
'success' => false,
'error' => $this->trans('Cannot find the requested product review.', [], 'Modules.Productcomments.Shop'),
]
)
);
return false;
}
$productCommentUsefulnesRepository = $entityManager->getRepository(ProductCommentUsefulness::class);
/** @var ProductCommentUsefulness|null $productCommentUsefulness */
$productCommentUsefulness = $productCommentUsefulnesRepository->findOneBy([
'comment' => $id_product_comment,
'customerId' => $customerId,
]);
if ($productCommentUsefulness) {
$productCommentUsefulness->setUsefulness($usefulness);
} else {
$productCommentUsefulness = new ProductCommentUsefulness(
$productComment,
$customerId,
$usefulness
);
$entityManager->persist($productCommentUsefulness);
}
$entityManager->flush();
/** @var ProductCommentRepository $productCommentRepository */
$productCommentRepository = $this->context->controller->getContainer()->get('product_comment_repository');
$commentUsefulness = $productCommentRepository->getProductCommentUsefulness($id_product_comment);
$this->ajaxRender(
json_encode(
array_merge(
[
'success' => true,
'id_product_comment' => $id_product_comment,
],
$commentUsefulness
)
)
);
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 752 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 715 B

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

Binary file not shown.

After

Width:  |  Height:  |  Size: 500 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 B

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,75 @@
CREATE TABLE IF NOT EXISTS `PREFIX_product_comment` (
`id_product_comment` int(10) unsigned NOT NULL auto_increment,
`id_product` int(10) unsigned NOT NULL,
`id_customer` int(10) unsigned NOT NULL,
`id_guest` int(10) unsigned NULL,
`title` varchar(64) NULL,
`content` text NOT NULL,
`customer_name` varchar(64) NULL,
`grade` float unsigned NOT NULL,
`validate` tinyint(1) NOT NULL,
`deleted` tinyint(1) NOT NULL,
`date_add` datetime NOT NULL,
PRIMARY KEY (`id_product_comment`),
KEY `id_product` (`id_product`),
KEY `id_customer` (`id_customer`),
KEY `id_guest` (`id_guest`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `PREFIX_product_comment_criterion` (
`id_product_comment_criterion` int(10) unsigned NOT NULL auto_increment,
`id_product_comment_criterion_type` tinyint(1) NOT NULL,
`active` tinyint(1) NOT NULL,
PRIMARY KEY (`id_product_comment_criterion`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `PREFIX_product_comment_criterion_product` (
`id_product` int(10) unsigned NOT NULL,
`id_product_comment_criterion` int(10) unsigned NOT NULL,
PRIMARY KEY(`id_product`, `id_product_comment_criterion`),
KEY `id_product_comment_criterion` (`id_product_comment_criterion`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `PREFIX_product_comment_criterion_lang` (
`id_product_comment_criterion` INT(11) UNSIGNED NOT NULL ,
`id_lang` INT(11) UNSIGNED NOT NULL ,
`name` VARCHAR(64) NOT NULL ,
PRIMARY KEY ( `id_product_comment_criterion` , `id_lang` )
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `PREFIX_product_comment_criterion_category` (
`id_product_comment_criterion` int(10) unsigned NOT NULL,
`id_category` int(10) unsigned NOT NULL,
PRIMARY KEY(`id_product_comment_criterion`, `id_category`),
KEY `id_category` (`id_category`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `PREFIX_product_comment_grade` (
`id_product_comment` int(10) unsigned NOT NULL,
`id_product_comment_criterion` int(10) unsigned NOT NULL,
`grade` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_product_comment`, `id_product_comment_criterion`),
KEY `id_product_comment_criterion` (`id_product_comment_criterion`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `PREFIX_product_comment_usefulness` (
`id_product_comment` int(10) unsigned NOT NULL,
`id_customer` int(10) unsigned NOT NULL,
`usefulness` tinyint(1) unsigned NOT NULL,
PRIMARY KEY (`id_product_comment`, `id_customer`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `PREFIX_product_comment_report` (
`id_product_comment` int(10) unsigned NOT NULL,
`id_customer` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_product_comment`, `id_customer`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8mb4;
INSERT IGNORE INTO `PREFIX_product_comment_criterion` VALUES ('1', '1', '1');
INSERT IGNORE INTO `PREFIX_product_comment_criterion_lang` (`id_product_comment_criterion`, `id_lang`, `name`)
(
SELECT '1', l.`id_lang`, 'Quality'
FROM `PREFIX_lang` l
);

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,127 @@
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
function getCommentForm()
{
if (document.forms)
return (document.forms['comment_form']);
else
return (document.comment_form);
}
function getCommentDeleteForm()
{
if (document.forms)
return (document.forms['delete_comment_form']);
else
return (document.delete_comment_form);
}
function acceptComment(id)
{
var form = getCommentForm();
if (id)
form.elements['id_product_comment'].value = id;
form.elements['action'].value = 'accept';
form.submit();
}
function deleteComment(id)
{
var form = getCommentForm();
if (id)
form.elements['id_product_comment'].value = id;
form.elements['action'].value = 'delete';
form.submit();
}
function delComment(id, confirmation)
{
var answer = confirm(confirmation);
if (answer)
{
var form = getCommentDeleteForm();
if (id)
form.elements['delete_id_product_comment'].value = id;
form.elements['delete_action'].value = 'delete';
form.submit();
}
}
function getCriterionForm()
{
if (document.forms)
return (document.forms['criterion_form']);
else
return (document.criterion_form);
}
function editCriterion(id)
{
var form = getCriterionForm();
form.elements['id_product_comment_criterion'].value = id;
form.elements['criterion_name'].value = document.getElementById('criterion_name_' + id).value;
form.elements['criterion_action'].value = 'edit';
form.submit();
}
function deleteCriterion(id)
{
var form = getCriterionForm();
form.elements['id_product_comment_criterion'].value = id;
form.elements['criterion_action'].value = 'delete';
form.submit();
}
$( document ).ready(function() {
$('select#id_product_comment_criterion_type').change(function() {
// PS 1.6
$('#categoryBox').closest('div.form-group').hide();
$('#ids_product').closest('div.form-group').hide();
// PS 1.5
$('#categories-treeview').closest('div.margin-form').hide();
$('#categories-treeview').closest('div.margin-form').prev().hide();
$('#ids_product').closest('div.margin-form').hide();
$('#ids_product').closest('div.margin-form').prev().hide();
if (this.value == 2)
{
$('#categoryBox').closest('div.form-group').show();
// PS 1.5
$('#categories-treeview').closest('div.margin-form').show();
$('#categories-treeview').closest('div.margin-form').prev().show();
}
else if (this.value == 3)
{
$('#ids_product').closest('div.form-group').show();
// PS 1.5
$('#ids_product').closest('div.margin-form').show();
$('#ids_product').closest('div.margin-form').prev().show();
}
});
$('select#id_product_comment_criterion_type').trigger( "change" );
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,346 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
namespace PrestaShop\Module\ProductComment\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table()
* @ORM\Entity()
*/
class ProductComment
{
const TITLE_MAX_LENGTH = 64;
const CUSTOMER_NAME_MAX_LENGTH = 64;
/**
* @var int
*
* @ORM\Id
* @ORM\Column(name="id_product_comment", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var int
*
* @ORM\Column(name="id_product", type="integer")
*/
private $productId;
/**
* @var int
*
* @ORM\Column(name="id_customer", type="integer")
*/
private $customerId;
/**
* @var int
*
* @ORM\Column(name="id_guest", type="integer")
*/
private $guestId;
/**
* @var string
*
* @ORM\Column(name="customer_name", type="string", length=64)
*/
private $customerName;
/**
* @var string
*
* @ORM\Column(name="title", type="string", length=64)
*/
private $title;
/**
* @var string
*
* @ORM\Column(name="content", type="text")
*/
private $content;
/**
* @var int
*
* @ORM\Column(name="grade", type="integer")
*/
private $grade;
/**
* @var bool
*
* @ORM\Column(name="validate", type="boolean")
*/
private $validate = false;
/**
* @var bool
*
* @ORM\Column(name="deleted", type="boolean")
*/
private $deleted = false;
/**
* @var \DateTime
*
* @ORM\Column(name="date_add", type="datetime")
*/
private $dateAdd;
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @return int
*/
public function getProductId()
{
return $this->productId;
}
/**
* @param int $productId
*
* @return ProductComment
*/
public function setProductId($productId)
{
$this->productId = $productId;
return $this;
}
/**
* @return int
*/
public function getCustomerId()
{
return $this->customerId;
}
/**
* @param int $customerId
*
* @return ProductComment
*/
public function setCustomerId($customerId)
{
$this->customerId = $customerId;
return $this;
}
/**
* @return int
*/
public function getGuestId()
{
return $this->guestId;
}
/**
* @param int $guestId
*
* @return ProductComment
*/
public function setGuestId($guestId)
{
$this->guestId = $guestId;
return $this;
}
/**
* @return string
*/
public function getCustomerName()
{
return $this->customerName;
}
/**
* @param string $customerName
*
* @return ProductComment
*/
public function setCustomerName($customerName)
{
$this->customerName = $customerName;
return $this;
}
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @param string $title
*
* @return ProductComment
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* @return string
*/
public function getContent()
{
return $this->content;
}
/**
* @param string $content
*
* @return ProductComment
*/
public function setContent($content)
{
$this->content = $content;
return $this;
}
/**
* @return int
*/
public function getGrade()
{
return $this->grade;
}
/**
* @param int $grade
*
* @return ProductComment
*/
public function setGrade($grade)
{
$this->grade = $grade;
return $this;
}
/**
* @return bool
*/
public function isValidate()
{
return $this->validate;
}
/**
* @param bool $validate
*
* @return ProductComment
*/
public function setValidate($validate)
{
$this->validate = $validate;
return $this;
}
/**
* @return bool
*/
public function isDeleted()
{
return $this->deleted;
}
/**
* @param bool $deleted
*
* @return ProductComment
*/
public function setDeleted($deleted)
{
$this->deleted = $deleted;
return $this;
}
/**
* @return \DateTime
*/
public function getDateAdd()
{
return $this->dateAdd;
}
/**
* Date is stored in UTC timezone
*
* @param \DateTime $dateAdd
*
* @return ProductComment
*/
public function setDateAdd($dateAdd)
{
$this->dateAdd = $dateAdd;
return $this;
}
/**
* @return array
*/
public function toArray()
{
return [
'id_product' => $this->getProductId(),
'id_product_comment' => $this->getId(),
'title' => $this->getTitle(),
'content' => $this->getContent(),
'customer_name' => $this->getCustomerName(),
'date_add' => $this->dateAdd->format(\DateTime::ATOM),
'grade' => $this->grade,
'usefulness' => 3,
'total_usefulness' => 5,
];
}
}

View File

@@ -0,0 +1,207 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
namespace PrestaShop\Module\ProductComment\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Validate;
/**
* @ORM\Table()
* @ORM\Entity()
*/
class ProductCommentCriterion
{
const NAME_MAX_LENGTH = 64;
const ENTIRE_CATALOG_TYPE = 1;
const CATEGORIES_TYPE = 2;
const PRODUCTS_TYPE = 3;
/**
* @var int
*
* @ORM\Id
* @ORM\Column(name="id_product_comment_criterion", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var int
*
* @ORM\Column(name="id_product_comment_criterion_type", type="integer")
*/
private $type;
/**
* @var bool
*
* @ORM\Column(name="active", type="boolean")
*/
private $active = false;
/**
* @ORM\OneToMany(targetEntity="PrestaShop\Module\ProductComment\Entity\ProductCommentCriterionLang", cascade={"persist", "remove"}, mappedBy="productcommentcriterion")
*/
private $criterionLangs;
/**
* @var array
*
* @todo implement as ORM\OneToMany in the future
*/
private $categories;
/**
* @var array
*
* @todo implement as ORM\OneToMany in the future
*/
private $products;
public function __construct()
{
$this->criterionLangs = new ArrayCollection();
}
/**
* @return ArrayCollection
*/
public function getCriterionLangs()
{
return $this->criterionLangs;
}
/**
* @return ProductCommentCriterionLang|null
*/
public function getCriterionLangByLangId(int $langId)
{
foreach ($this->criterionLangs as $criterionLang) {
if ($langId === $criterionLang->getLang()->getId()) {
return $criterionLang;
}
}
return null;
}
public function addCriterionLang(ProductCommentCriterionLang $criterionLang): self
{
$criterionLang->setProductCommentCriterion($this);
$this->criterionLangs->add($criterionLang);
return $this;
}
public function getCriterionName(): string
{
if ($this->criterionLangs->count() <= 0) {
return '';
}
$criterionLang = $this->criterionLangs->first();
return $criterionLang->getName();
}
/**
* @return array
*/
public function getCategories()
{
return $this->categories;
}
/**
* @param array $selectedCategories
*/
public function setCategories($selectedCategories): self
{
$this->categories = $selectedCategories;
return $this;
}
/**
* @return array
*/
public function getProducts()
{
return $this->products;
}
/**
* @param array $selectedProducts
*/
public function setProducts($selectedProducts): self
{
$this->products = $selectedProducts;
return $this;
}
public function getId(): int
{
return $this->id;
}
public function getType(): int
{
return $this->type;
}
public function setType(int $type): self
{
$this->type = $type;
return $this;
}
public function isActive(): bool
{
return $this->active;
}
public function setActive(bool $active): self
{
$this->active = $active;
return $this;
}
public function isValid(): bool
{
foreach ($this->criterionLangs as $criterionLang) {
if (!Validate::isGenericName($criterionLang->getName())) {
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,97 @@
<?php
/**
* 2007-2020 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0).
* It is also available through the world-wide-web at this URL: https://opensource.org/licenses/AFL-3.0
*/
declare(strict_types=1);
namespace PrestaShop\Module\ProductComment\Entity;
use Doctrine\ORM\Mapping as ORM;
use PrestaShopBundle\Entity\Lang;
/**
* @ORM\Table()
*
* @ORM\Entity()
*/
class ProductCommentCriterionLang
{
/**
* @var ProductCommentCriterion
*
* @ORM\Id
*
* @ORM\ManyToOne(targetEntity="PrestaShop\Module\ProductComment\Entity\ProductCommentCriterion", inversedBy="criterionLangs")
*
* @ORM\JoinColumn(name="id_product_comment_criterion", referencedColumnName="id_product_comment_criterion", nullable=false)
*/
private $productcommentcriterion;
/**
* @var Lang
*
* @ORM\Id
*
* @ORM\ManyToOne(targetEntity="PrestaShopBundle\Entity\Lang")
*
* @ORM\JoinColumn(name="id_lang", referencedColumnName="id_lang", nullable=false, onDelete="CASCADE")
*/
private $lang;
/**
* @var string
*
* @ORM\Column(name="name", type="string", nullable=false)
*/
private $name;
/**
* @return ProductCommentCriterion
*/
public function getProductCommentCriterion()
{
return $this->productcommentcriterion;
}
public function setProductCommentCriterion(ProductCommentCriterion $productcommentcriterion): self
{
$this->productcommentcriterion = $productcommentcriterion;
return $this;
}
/**
* @return Lang
*/
public function getLang()
{
return $this->lang;
}
/**
* @param Lang $lang
*/
public function setLang(Lang $lang): self
{
$this->lang = $lang;
return $this;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
}

View File

@@ -0,0 +1,88 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
namespace PrestaShop\Module\ProductComment\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table()
* @ORM\Entity()
*/
class ProductCommentGrade
{
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="ProductComment")
* @ORM\JoinColumn(name="id_product_comment", referencedColumnName="id_product_comment")
*/
private $comment;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="ProductCommentCriterion")
* @ORM\JoinColumn(name="id_product_comment_criterion", referencedColumnName="id_product_comment_criterion")
*/
private $criterion;
/**
* @var int
*
* @ORM\Column(name="grade", type="integer")
*/
private $grade;
/**
* @param ProductComment $comment
* @param ProductCommentCriterion $criterion
* @param int $grade
*/
public function __construct(
ProductComment $comment,
ProductCommentCriterion $criterion,
$grade
) {
$this->comment = $comment;
$this->criterion = $criterion;
$this->grade = $grade;
}
/**
* @return mixed
*/
public function getComment()
{
return $this->comment;
}
/**
* @return mixed
*/
public function getCriterion()
{
return $this->criterion;
}
}

View File

@@ -0,0 +1,81 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
namespace PrestaShop\Module\ProductComment\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table()
* @ORM\Entity()
*/
class ProductCommentReport
{
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="ProductComment")
* @ORM\JoinColumn(name="id_product_comment", referencedColumnName="id_product_comment")
*
* @var ProductComment
*/
private $comment;
/**
* @ORM\Id
* @ORM\Column(name="id_customer", type="integer")
*
* @var int
*/
private $customerId;
/**
* @param ProductComment $comment
* @param int $customerId
*/
public function __construct(
ProductComment $comment,
$customerId
) {
$this->comment = $comment;
$this->customerId = $customerId;
}
/**
* @return ProductComment
*/
public function getComment()
{
return $this->comment;
}
/**
* @return int
*/
public function getCustomerId()
{
return $this->customerId;
}
}

View File

@@ -0,0 +1,109 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
namespace PrestaShop\Module\ProductComment\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table()
* @ORM\Entity()
*/
class ProductCommentUsefulness
{
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="ProductComment")
* @ORM\JoinColumn(name="id_product_comment", referencedColumnName="id_product_comment")
*/
private $comment;
/**
* @var int
*
* @ORM\Id
* @ORM\Column(name="id_customer", type="integer")
*/
private $customerId;
/**
* @var bool
*
* @ORM\Column(name="usefulness", type="boolean")
*/
private $usefulness;
/**
* @param ProductComment $comment
* @param int $customerId
* @param bool $usefulness
*/
public function __construct(
ProductComment $comment,
$customerId,
$usefulness
) {
$this->comment = $comment;
$this->customerId = $customerId;
$this->usefulness = $usefulness;
}
/**
* @return mixed
*/
public function getComment()
{
return $this->comment;
}
/**
* @return int
*/
public function getCustomerId()
{
return $this->customerId;
}
/**
* @return bool
*/
public function isUsefulness()
{
return $this->usefulness;
}
/**
* @param bool $usefulness
*
* @return ProductCommentUsefulness
*/
public function setUsefulness($usefulness)
{
$this->usefulness = $usefulness;
return $this;
}
}

View File

@@ -0,0 +1,121 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
declare(strict_types=1);
namespace PrestaShop\Module\ProductComment\Form;
use Doctrine\ORM\EntityManagerInterface;
use PrestaShop\Module\ProductComment\Entity\ProductCommentCriterion;
use PrestaShop\Module\ProductComment\Entity\ProductCommentCriterionLang;
use PrestaShop\Module\ProductComment\Repository\ProductCommentCriterionRepository;
use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\FormDataHandlerInterface;
use PrestaShopBundle\Entity\Repository\LangRepository;
class ProductCommentCriterionFormDataHandler implements FormDataHandlerInterface
{
/**
* @var ProductCommentCriterionRepository
*/
private $pccriterionRepository;
/**
* @var LangRepository
*/
private $langRepository;
/**
* @var EntityManagerInterface
*/
private $entityManager;
/**
* @param ProductCommentCriterionRepository $pccriterionRepository
* @param LangRepository $langRepository
* @param EntityManagerInterface $entityManager
*/
public function __construct(
ProductCommentCriterionRepository $pccriterionRepository,
LangRepository $langRepository,
EntityManagerInterface $entityManager
) {
$this->pccriterionRepository = $pccriterionRepository;
$this->langRepository = $langRepository;
$this->entityManager = $entityManager;
}
/**
* {@inheritdoc}
*/
public function create(array $data)
{
}
/**
* {@inheritdoc}
*/
public function update($id, array $data)
{
}
/**
* @param ProductCommentCriterion $pccriterion
* @param array $pcc_languages
*
* @todo migrate this temporary function to above standard function create
*/
public function createLangs($pccriterion, $pcc_languages): void
{
foreach ($pcc_languages as $langId => $langContent) {
$lang = $this->langRepository->find($langId);
$pccriterionLang = new ProductCommentCriterionLang();
$pccriterionLang
->setLang($lang)
->setName($langContent)
;
$pccriterion->addCriterionLang($pccriterionLang);
}
$this->entityManager->persist($pccriterion);
$this->entityManager->flush();
}
/**
* @param ProductCommentCriterion $pccriterion
* @param array $pcc_languages
*
* @todo migrate this temporary function to above standard function update
*/
public function updateLangs($pccriterion, $pcc_languages): void
{
foreach ($pcc_languages as $langId => $langContent) {
$lang = $this->langRepository->find($langId);
$pccriterionLang = $pccriterion->getCriterionLangByLangId($langId);
if (null === $pccriterionLang) {
continue;
}
$pccriterionLang
->setName($langContent)
;
}
$this->entityManager->persist($pccriterion);
$this->entityManager->flush();
}
}

View File

@@ -0,0 +1,88 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
declare(strict_types=1);
namespace PrestaShop\Module\ProductComment\Form;
use PrestaShop\Module\ProductComment\Repository\ProductCommentCriterionRepository;
use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\FormDataProviderInterface;
use PrestaShopBundle\Entity\Repository\LangRepository;
class ProductCommentCriterionFormDataProvider implements FormDataProviderInterface
{
/**
* @var ProductCommentCriterionRepository
*/
private $pccriterionRepository;
/**
* @var LangRepository
*/
private $langRepository;
/**
* @param ProductCommentCriterionRepository $pccriterionRepository
* @param LangRepository $langRepository
*/
public function __construct(
ProductCommentCriterionRepository $pccriterionRepository,
LangRepository $langRepository
) {
$this->pccriterionRepository = $pccriterionRepository;
$this->langRepository = $langRepository;
}
/**
* {@inheritdoc}
*/
public function getData($criterionId)
{
$criterion = $this->pccriterionRepository->find($criterionId);
$criterionData = [
'type' => $criterion->getType(),
'active' => $criterion->isActive(),
];
foreach ($criterion->getCriterionLangs() as $criterionLang) {
$criterionData['name'][$criterionLang->getLang()->getId()] = $criterionLang->getName();
}
return $criterionData;
}
/**
* {@inheritdoc}
*/
public function getDefaultData()
{
$default_name = [];
$langEntities = $this->langRepository->findBy(['active' => 1]);
foreach ($langEntities as $langEntity) {
$default_name[$langEntity->getId()] = $langEntity->getIsoCode();
}
return [
'type' => '',
'active' => false,
'name' => $default_name,
];
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,307 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
namespace PrestaShop\Module\ProductComment\Repository;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Query\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
use PrestaShop\Module\ProductComment\Entity\ProductCommentCriterion;
use PrestaShop\PrestaShop\Adapter\SymfonyContainer;
/**
* @extends ServiceEntityRepository<ProductCommentCriterion>
*
* @method ProductCommentCriterion|null find($id, $lockMode = null, $lockVersion = null)
* @method ProductCommentCriterion|null findOneBy(array $criteria, array $orderBy = null)
* @method ProductCommentCriterion[] findAll()
* @method ProductCommentCriterion[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class ProductCommentCriterionRepository extends ServiceEntityRepository
{
/**
* @var ManagerRegistry the Doctrine Registry
*/
private $registry;
/**
* @var Connection the Database connection
*/
private $connection;
/**
* @var string the Database prefix
*/
private $databasePrefix;
/**
* @param ManagerRegistry $registry
* @param Connection $connection
* @param string $databasePrefix
*/
public function __construct($registry, $connection, $databasePrefix)
{
parent::__construct($registry, ProductCommentCriterion::class);
$this->connection = $connection;
$this->databasePrefix = $databasePrefix;
}
public function add(ProductCommentCriterion $entity, bool $flush = false): void
{
$this->getEntityManager()->persist($entity);
if ($flush) {
$this->getEntityManager()->flush();
}
}
public function remove(ProductCommentCriterion $entity, bool $flush = false): void
{
$this->getEntityManager()->remove($entity);
if ($flush) {
$this->getEntityManager()->flush();
}
}
private function deleteCategories($criterion): int
{
return $this->connection->executeUpdate('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_criterion_category`
WHERE `id_product_comment_criterion` = ' . $criterion->getId());
}
private function deleteProducts($criterion): int
{
return $this->connection->executeUpdate('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_criterion_product`
WHERE `id_product_comment_criterion` = ' . $criterion->getId());
}
private function deleteGrades($criterion): int
{
return $this->connection->executeUpdate('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_grade`
WHERE `id_product_comment_criterion` = ' . $criterion->getId());
}
/* Remove a criterion and Delete its manual relation _category, _product, _grade */
public function delete(ProductCommentCriterion $criterion): int
{
$res = 0;
$criterionType = $criterion->getType();
if ($criterionType == ProductCommentCriterion::CATEGORIES_TYPE) {
$res += $this->deleteCategories($criterion);
} elseif ($criterionType == ProductCommentCriterion::PRODUCTS_TYPE) {
$res += $this->deleteProducts($criterion);
} else {
$res = 1;
}
$res += $this->deleteGrades($criterion);
$this->remove($criterion, true);
// todo: return void, and use try catch Exception instead
return $res;
}
/* Update a criterion and Update its manual relation _category, _product */
public function update(ProductCommentCriterion $criterion): int
{
$res = 0;
$criterionType = $criterion->getType();
$this->getEntityManager()->persist($criterion);
$this->getEntityManager()->flush();
if ($criterionType == ProductCommentCriterion::CATEGORIES_TYPE) {
$res += $this->deleteCategories($criterion);
$res += $this->updateCategories($criterion);
} elseif ($criterionType == ProductCommentCriterion::PRODUCTS_TYPE) {
$res += $this->deleteProducts($criterion);
$res += $this->updateProducts($criterion);
} else {
$res = 1;
}
// todo: return void, and use try catch Exception instead
return $res;
}
private function updateCategories($criterion): int
{
$res = 0;
$criterionId = $criterion->getId();
foreach ($criterion->getCategories() as $id_category) {
$res += $this->connection->executeUpdate(
'INSERT INTO `' .
_DB_PREFIX_ . 'product_comment_criterion_category` (`id_product_comment_criterion`, `id_category`)
VALUES(' . $criterionId . ',' . $id_category . ')'
);
}
return $res;
}
private function updateProducts($criterion): int
{
$res = 0;
$criterionId = $criterion->getId();
foreach ($criterion->getProducts() as $id_product) {
$res += $this->connection->executeUpdate(
'INSERT INTO `' .
_DB_PREFIX_ . 'product_comment_criterion_product` (`id_product_comment_criterion`, `id_product`)
VALUES(' . $criterionId . ',' . $id_product . ')'
);
}
return $res;
}
public function updateGeneral(ProductCommentCriterion $criterion): void
{
$this->getEntityManager()->persist($criterion);
$this->getEntityManager()->flush();
}
/**
* @return array
*
* @throws \PrestaShopException
*/
public function getByProduct(int $idProduct, int $idLang)
{
/** @var QueryBuilder $qb */
$qb = $this->connection->createQueryBuilder();
$qb
->select('pcc.id_product_comment_criterion, pccl.name')
->from($this->databasePrefix . 'product_comment_criterion', 'pcc')
->leftJoin('pcc', $this->databasePrefix . 'product_comment_criterion_lang', 'pccl', 'pcc.id_product_comment_criterion = pccl.id_product_comment_criterion')
->leftJoin('pcc', $this->databasePrefix . 'product_comment_criterion_product', 'pccp', 'pcc.id_product_comment_criterion = pccp.id_product_comment_criterion')
->leftJoin('pcc', $this->databasePrefix . 'product_comment_criterion_category', 'pccc', 'pcc.id_product_comment_criterion = pccc.id_product_comment_criterion')
->leftJoin('pccc', $this->databasePrefix . 'category', 'c', 'pccc.id_category = c.id_category')
->leftJoin('c', $this->databasePrefix . 'category_product', 'cp', 'c.id_category = cp.id_category')
->andWhere($qb->expr()->orX(
$qb->expr()->eq('pcc.id_product_comment_criterion_type', ':catalog_type'),
$qb->expr()->eq('pccp.id_product', ':id_product'),
$qb->expr()->eq('cp.id_product', ':id_product')
))
->andWhere('pccl.id_lang = :id_lang')
->andWhere('pcc.active = :active')
->setParameter('catalog_type', ProductCommentCriterion::ENTIRE_CATALOG_TYPE)
->setParameter('active', 1)
->setParameter('id_product', $idProduct)
->setParameter('id_lang', $idLang)
->addGroupBy('pcc.id_product_comment_criterion')
;
return $qb->execute()->fetchAll();
}
/**
* @return array Criterions
*/
public function getCriterions(int $id_lang, $type = false, $active = false)
{
$sql = '
SELECT pcc.`id_product_comment_criterion`, pcc.id_product_comment_criterion_type, pccl.`name`, pcc.active
FROM `' . _DB_PREFIX_ . 'product_comment_criterion` pcc
JOIN `' . _DB_PREFIX_ . 'product_comment_criterion_lang` pccl ON (pcc.id_product_comment_criterion = pccl.id_product_comment_criterion)
WHERE pccl.`id_lang` = ' . $id_lang . ($active ? ' AND active = 1' : '') . ($type ? ' AND id_product_comment_criterion_type = ' . (int) $type : '') . '
ORDER BY pccl.`name` ASC';
$criterions = $this->connection->executeQuery($sql)->fetchAll();
$types = self::getTypes();
foreach ($criterions as $key => $data) {
$criterions[$key]['type_name'] = $types[$data['id_product_comment_criterion_type']];
}
return $criterions;
}
/**
* @return array
*/
public function getProducts(int $id_criterion)
{
$sql = '
SELECT pccp.id_product, pccp.id_product_comment_criterion
FROM `' . _DB_PREFIX_ . 'product_comment_criterion_product` pccp
WHERE pccp.id_product_comment_criterion = ' . $id_criterion;
$res = $this->connection->executeQuery($sql)->fetchAll();
$products = [];
if ($res) {
foreach ($res as $row) {
$products[] = (int) $row['id_product'];
}
}
return $products;
}
/**
* @return array
*/
public function getCategories(int $id_criterion)
{
$sql = '
SELECT pccc.id_category, pccc.id_product_comment_criterion
FROM `' . _DB_PREFIX_ . 'product_comment_criterion_category` pccc
WHERE pccc.id_product_comment_criterion = ' . $id_criterion;
$res = $this->connection->executeQuery($sql)->fetchAll();
$criterions = [];
if ($res) {
foreach ($res as $row) {
$criterions[] = (int) $row['id_category'];
}
}
return $criterions;
}
/**
* @return array
*/
public function getTypes()
{
$sfTranslator = SymfonyContainer::getInstance()->get('translator');
return [
1 => $sfTranslator->trans('Valid for the entire catalog', [], 'Modules.Productcomments.Admin'),
2 => $sfTranslator->trans('Restricted to some categories', [], 'Modules.Productcomments.Admin'),
3 => $sfTranslator->trans('Restricted to some products', [], 'Modules.Productcomments.Admin'),
];
}
}

View File

@@ -0,0 +1,620 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
namespace PrestaShop\Module\ProductComment\Repository;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Query\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
use Hook;
use PrestaShop\Module\ProductComment\Entity\ProductComment;
/**
* @extends ServiceEntityRepository<ProductComment>
*
* @method ProductComment|null find($id, $lockMode = null, $lockVersion = null)
* @method ProductComment|null findOneBy(array $criteria, array $orderBy = null)
* @method ProductComment[] findAll()
* @method ProductComment[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class ProductCommentRepository extends ServiceEntityRepository
{
/**
* @var ManagerRegistry the Doctrine Registry
*/
private $registry;
/**
* @var Connection the Database connection
*/
private $connection;
/**
* @var string the Database prefix
*/
private $databasePrefix;
/**
* @var bool
*/
private $guestCommentsAllowed;
/**
* @var int
*/
private $commentsMinimalTime;
const DEFAULT_COMMENTS_PER_PAGE = 5;
/**
* @param ManagerRegistry $registry
* @param Connection $connection
* @param string $databasePrefix
* @param bool $guestCommentsAllowed
* @param int $commentsMinimalTime
*/
public function __construct(
$registry,
$connection,
$databasePrefix,
$guestCommentsAllowed,
$commentsMinimalTime
) {
parent::__construct($registry, ProductComment::class);
$this->connection = $connection;
$this->databasePrefix = $databasePrefix;
$this->guestCommentsAllowed = (bool) $guestCommentsAllowed;
$this->commentsMinimalTime = (int) $commentsMinimalTime;
}
public function add(ProductComment $entity, bool $flush = false): void
{
$this->getEntityManager()->persist($entity);
if ($flush) {
$this->getEntityManager()->flush();
}
}
public function remove(ProductComment $entity, bool $flush = false): void
{
$this->getEntityManager()->remove($entity);
if ($flush) {
$this->getEntityManager()->flush();
}
}
public function delete(ProductComment $entity): void
{
$entityId = $entity->getId();
$this->remove($entity, true);
$this->deleteGrades($entityId);
$this->deleteReports($entityId);
$this->deleteUsefulness($entityId);
}
/**
* @param int $productId
* @param int $page
* @param int $commentsPerPage
* @param bool $validatedOnly
*
* @return array
*/
public function paginate($productId, $page, $commentsPerPage, $validatedOnly)
{
if (empty($commentsPerPage)) {
$commentsPerPage = self::DEFAULT_COMMENTS_PER_PAGE;
}
/** @var QueryBuilder $qb */
$qb = $this->connection->createQueryBuilder();
$qb
->addSelect('pc.id_product, pc.id_product_comment, pc.title, pc.content, pc.customer_name, pc.date_add, pc.grade')
->addSelect('c.firstname, c.lastname')
->from($this->databasePrefix . 'product_comment', 'pc')
->leftJoin('pc', $this->databasePrefix . 'customer', 'c', 'pc.id_customer = c.id_customer AND c.deleted = :not_deleted')
->andWhere('pc.id_product = :id_product')
->andWhere('pc.deleted = :not_deleted')
->setParameter('not_deleted', 0)
->setParameter('id_product', $productId)
->setMaxResults($commentsPerPage)
->setFirstResult(($page - 1) * $commentsPerPage)
->addGroupBy('pc.id_product_comment')
->addOrderBy('pc.date_add', 'DESC')
;
if ($validatedOnly) {
$qb
->andWhere('pc.validate = :validate')
->setParameter('validate', 1)
;
}
return $qb->execute()->fetchAll();
}
/**
* @param int $productCommentId
*
* @return array
*/
public function getProductCommentUsefulness($productCommentId)
{
/** @var QueryBuilder $qb */
$qb = $this->connection->createQueryBuilder();
$qb
->addSelect('pcu.usefulness')
->from($this->databasePrefix . 'product_comment_usefulness', 'pcu')
->andWhere('pcu.id_product_comment = :id_product_comment')
->setParameter('id_product_comment', $productCommentId)
;
$usefulnessInfos = [
'usefulness' => 0,
'total_usefulness' => 0,
];
$customerAppreciations = $qb->execute()->fetchAll();
foreach ($customerAppreciations as $customerAppreciation) {
if ((int) $customerAppreciation['usefulness']) {
++$usefulnessInfos['usefulness'];
}
++$usefulnessInfos['total_usefulness'];
}
return $usefulnessInfos;
}
/**
* @param int $productId
* @param bool $validatedOnly
*
* @return float
*/
public function getAverageGrade($productId, $validatedOnly)
{
/** @var QueryBuilder $qb */
$qb = $this->connection->createQueryBuilder();
$qb
->select('AVG(pc.grade) AS averageGrade')
->from($this->databasePrefix . 'product_comment', 'pc')
->andWhere('pc.id_product = :id_product')
->andWhere('pc.deleted = :deleted')
->setParameter('deleted', 0)
->setParameter('id_product', $productId)
;
if ($validatedOnly) {
$qb
->andWhere('pc.validate = :validate')
->setParameter('validate', 1)
;
}
return (float) $qb->execute()->fetch(\PDO::FETCH_COLUMN);
}
/**
* @param int $langId
* @param int $shopId
* @param int $validate
* @param bool $deleted
* @param int $page
* @param int $limit
* @param bool $skip_validate
*
* @return array
*/
public function getByValidate($langId, $shopId, $validate = 0, $deleted = false, $page = null, $limit = null, $skip_validate = false)
{
/** @var QueryBuilder $qb */
$qb = $this->connection->createQueryBuilder();
$qb
->select('pc.`id_product_comment`, pc.`id_product`, c.id_customer AS customer_id,
IF(c.id_customer, CONCAT(c.`firstname`, \' \', c.`lastname`), pc.customer_name) customer_name,
pc.`title`, pc.`content`, pc.`grade`, pc.`date_add`, pl.`name`')
->from($this->databasePrefix . 'product_comment', 'pc')
->leftJoin('pc', $this->databasePrefix . 'customer', 'c', 'pc.id_customer = c.id_customer')
->leftJoin('pc', $this->databasePrefix . 'product_lang', 'pl', 'pc.id_product = pl.id_product')
->andWhere('pc.deleted = :deleted')
->setParameter('deleted', $deleted)
->andWhere('pl.id_lang = :id_lang')
->setParameter('id_lang', $langId)
->andWhere('pl.id_shop = :id_shop')
->setParameter('id_shop', $shopId)
->addOrderBy('pc.date_add', 'DESC')
;
if (!$skip_validate) {
$qb
->andWhere('pc.validate = :validate')
->setParameter('validate', $validate)
;
}
if ($page && $limit) {
$limit = (int) $limit;
$offset = ($page - 1) * $limit;
$qb
->setFirstResult($offset)
->setMaxResults($limit);
}
return $this->connection->executeQuery(
$qb->getSQL(), $qb->getParameters(), $qb->getParameterTypes()
)->fetchAll();
}
/**
* @param int $validate
* @param bool $skip_validate
*
* @return int
*/
public function getCountByValidate($validate = 0, $skip_validate = false)
{
/** @var QueryBuilder $qb */
$qb = $this->connection->createQueryBuilder();
$qb
->select('COUNT(*)')
->from($this->databasePrefix . 'product_comment', 'pc')
;
if (!$skip_validate) {
$qb
->andWhere('pc.validate = :validate')
->setParameter('validate', $validate)
;
}
return (int) $this->connection->executeQuery(
$qb->getSQL(), $qb->getParameters(), $qb->getParameterTypes()
)->fetch(\PDO::FETCH_COLUMN);
}
/**
* @param array $productIds
* @param bool $validatedOnly
*
* @return array
*/
public function getAverageGrades(array $productIds, $validatedOnly)
{
$sql = 'SELECT';
$count = count($productIds);
foreach ($productIds as $index => $id) {
$esqID = (int) $id;
$sql .= ' SUM(IF(id_product = ' . $esqID . ' AND deleted = 0';
if ($validatedOnly) {
$sql .= ' AND validate = 1';
}
$sql .= ',grade, 0))';
$sql .= ' / SUM(IF(id_product = ' . $esqID . ' AND deleted = 0';
if ($validatedOnly) {
$sql .= ' AND validate = 1';
}
$sql .= ',1, 0)) AS "' . $esqID . '"';
if ($count - 1 > $index) {
$sql .= ',';
}
}
$sql .= ' FROM ' . $this->databasePrefix . 'product_comment';
return $this->connection->executeQuery($sql)->fetch();
}
/**
* @param int $productId
* @param bool $validatedOnly
*
* @return int
*/
public function getCommentsNumber($productId, $validatedOnly)
{
/** @var QueryBuilder $qb */
$qb = $this->connection->createQueryBuilder();
$qb
->select('COUNT(pc.id_product_comment) AS commentNb')
->from($this->databasePrefix . 'product_comment', 'pc')
->andWhere('pc.id_product = :id_product')
->andWhere('pc.deleted = :deleted')
->setParameter('deleted', 0)
->setParameter('id_product', $productId)
;
if ($validatedOnly) {
$qb
->andWhere('pc.validate = :validate')
->setParameter('validate', 1)
;
}
return (int) $qb->execute()->fetch(\PDO::FETCH_COLUMN);
}
/**
* @param array $productIds
* @param bool $validatedOnly
*
* @return array
*/
public function getCommentsNumberForProducts(array $productIds, $validatedOnly)
{
$sql = 'SELECT';
$count = count($productIds);
foreach ($productIds as $index => $id) {
$esqID = (int) $id;
$sql .= ' SUM(IF(id_product = ' . $esqID . ' AND deleted = 0';
if ($validatedOnly) {
$sql .= ' AND validate = 1';
}
$sql .= ' ,1, 0)) AS "' . $esqID . '"';
if ($count - 1 > $index) {
$sql .= ',';
}
}
$sql .= ' FROM ' . $this->databasePrefix . 'product_comment';
return (array) $this->connection->executeQuery($sql)->fetch();
}
/**
* @param int $productId
* @param int $idCustomer
* @param int $idGuest
*
* @return bool
*/
public function isPostAllowed($productId, $idCustomer, $idGuest)
{
if (!$idCustomer && !$this->guestCommentsAllowed) {
$postAllowed = false;
} else {
$lastCustomerComment = null;
if ($idCustomer) {
$lastCustomerComment = $this->getLastCustomerComment($productId, $idCustomer);
} elseif ($idGuest) {
$lastCustomerComment = $this->getLastGuestComment($productId, $idGuest);
}
$postAllowed = true;
if (null !== $lastCustomerComment && isset($lastCustomerComment['date_add'])) {
$postDate = new \DateTime($lastCustomerComment['date_add'], new \DateTimeZone('UTC'));
if (time() - $postDate->getTimestamp() < $this->commentsMinimalTime) {
$postAllowed = false;
}
}
}
return $postAllowed;
}
/**
* @param int $productId
* @param int $idCustomer
*
* @return array
*/
public function getLastCustomerComment($productId, $idCustomer)
{
return $this->getLastComment(['id_product' => $productId, 'id_customer' => $idCustomer]);
}
/**
* @param int $productId
* @param int $idGuest
*
* @return array
*/
public function getLastGuestComment($productId, $idGuest)
{
return $this->getLastComment(['id_product' => $productId, 'id_guest' => $idGuest]);
}
/**
* @param int $customerId
*/
public function cleanCustomerData($customerId)
{
//We anonymize the customer comment by unlinking them (the name won't be visible any more but the grade and comment are still visible)
$qb = $this->connection->createQueryBuilder();
$qb
->update($this->databasePrefix . 'product_comment', 'pc')
->set('id_customer', (string) 0)
->andWhere('pc.id_customer = :id_customer')
->setParameter('id_customer', $customerId)
;
$qb->execute();
//But we remove every report and votes for comments
$qb = $this->connection->createQueryBuilder();
$qb
->delete($this->databasePrefix . 'product_comment_report')
->andWhere('id_customer = :id_customer')
->setParameter('id_customer', $customerId)
;
$qb->execute();
$qb = $this->connection->createQueryBuilder();
$qb
->delete($this->databasePrefix . 'product_comment_usefulness')
->andWhere('id_customer = :id_customer')
->setParameter('id_customer', $customerId)
;
$qb->execute();
}
/**
* @param int $customerId
* @param int $langId
*
* @return array
*/
public function getCustomerData($customerId, $langId)
{
$qb = $this->connection->createQueryBuilder();
$qb
->select('pl.name, pc.id_product, pc.id_product_comment, pc.title, pc.content, pc.grade, pc.validate, pc.deleted, pcu.usefulness, pc.date_add')
->from($this->databasePrefix . 'product_comment', 'pc')
->leftJoin('pc', $this->databasePrefix . 'product_comment_usefulness', 'pcu', 'pc.id_product_comment = pcu.id_product_comment')
->leftJoin('pc', $this->databasePrefix . 'product', 'p', 'pc.id_product = p.id_product')
->leftJoin('p', $this->databasePrefix . 'product_lang', 'pl', 'p.id_product = pl.id_product')
->leftJoin('pl', $this->databasePrefix . 'lang', 'l', 'pl.id_lang = l.id_lang')
->andWhere('pc.id_customer = :id_customer')
->andWhere('l.id_lang = :id_lang')
->setParameter('id_customer', $customerId)
->setParameter('id_lang', $langId)
->addGroupBy('pc.id_product_comment')
->addOrderBy('pc.date_add', 'ASC')
;
return $qb->execute()->fetchAll();
}
/**
* @param array $criteria
*
* @return array
*/
private function getLastComment(array $criteria)
{
/** @var QueryBuilder $qb */
$qb = $this->connection->createQueryBuilder();
$qb
->select('pc.*')
->from($this->databasePrefix . 'product_comment', 'pc')
->andWhere('pc.deleted = :deleted')
->setParameter('deleted', 0)
->addOrderBy('pc.date_add', 'DESC')
->setMaxResults(1)
;
foreach ($criteria as $field => $value) {
$qb
->andWhere(sprintf('pc.%s = :%s', $field, $field))
->setParameter($field, $value)
;
}
$comments = $qb->execute()->fetchAll();
return empty($comments) ? [] : $comments[0];
}
/**
* @param ProductComment $productComment
* @param int $validate
*
* @return bool
*/
public function validate($productComment, $validate = 1)
{
$success = $this->connection->executeUpdate('
UPDATE `' . _DB_PREFIX_ . 'product_comment` SET
`validate` = ' . $validate . '
WHERE `id_product_comment` = ' . $productComment->getId());
Hook::exec('actionObjectProductCommentValidateAfter', ['object' => $productComment]);
return (bool) $success;
}
/**
* @param int $id_product_comment
*
* @return bool
*/
public function deleteGrades($id_product_comment)
{
$success = $this->connection->executeUpdate('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_grade`
WHERE `id_product_comment` = ' . $id_product_comment);
return (bool) $success;
}
/**
* @param int $id_product_comment
*
* @return bool
*/
public function deleteReports($id_product_comment)
{
$success = $this->connection->executeUpdate('
DELETE FROM `' . $this->databasePrefix . 'product_comment_report`
WHERE `id_product_comment` = ' . $id_product_comment);
return (bool) $success;
}
/**
* @param int $id_product_comment
*
* @return bool
*/
public function deleteUsefulness($id_product_comment)
{
$success = $this->connection->executeUpdate('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_usefulness`
WHERE `id_product_comment` = ' . $id_product_comment);
return (bool) $success;
}
/**
* @param int $langId
* @param int $shopId
*
* @return array
*/
public function getReportedComments($langId, $shopId)
{
$sql = 'SELECT DISTINCT(pc.`id_product_comment`), pc.`id_product`, pc.`content`, pc.`grade`, pc.`date_add`, pc.`title`
, IF(c.id_customer, CONCAT(c.`firstname`, \' \', c.`lastname`), pc.customer_name) customer_name, pl.`name`
FROM `' . $this->databasePrefix . 'product_comment_report` pcr
LEFT JOIN `' . $this->databasePrefix . 'product_comment` pc
ON pcr.id_product_comment = pc.id_product_comment
LEFT JOIN `' . $this->databasePrefix . 'customer` c ON (c.`id_customer` = pc.`id_customer`)
LEFT JOIN `' . $this->databasePrefix . 'product_lang` pl ON ' .
'(pl.`id_product` = pc.`id_product` ' .
' AND pl.`id_lang` = ' . $langId .
' AND pl.`id_shop` = ' . $shopId .
')
ORDER BY pc.`date_add` DESC';
return $this->connection->executeQuery($sql)->fetchAll();
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,33 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
function upgrade_module_2_4_0($object)
{
return $object->registerHook('displayProductListReviews') && $object->registerHook('top');
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
function upgrade_module_2_9_7($object)
{
return $object->unregisterHook('top');
}

View File

@@ -0,0 +1,44 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
function upgrade_module_4_0_0($object)
{
$res = true;
if (!Configuration::hasKey('PRODUCT_COMMENTS_COMMENTS_PER_PAGE')) {
$res &= (bool) Configuration::updateValue('PRODUCT_COMMENTS_COMMENTS_PER_PAGE', 5);
}
if (!Configuration::hasKey('PRODUCT_COMMENTS_USEFULNESS')) {
$res &= (bool) Configuration::updateValue('PRODUCT_COMMENTS_USEFULNESS', 1);
}
$res &= (bool) $object->unregisterHook('displayRightColumnProduct');
$res &= (bool) $object->registerHook('displayProductAdditionalInfo');
$res &= (bool) $object->registerHook('displayFooterProduct');
return (bool) $res;
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
function upgrade_module_5_0_0($object)
{
return $object->registerHook('filterProductContent') && $object->registerHook('displayGDPRConsent');
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
function upgrade_module_5_0_1($object)
{
return $object->unregisterHook('displayGDPRConsent')
&& $object->unregisterHook('header')
&& $object->registerHook('displayHeader');
}

View File

@@ -0,0 +1,40 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
function upgrade_module_6_0_3($object)
{
return Db::getInstance()->execute('ALTER TABLE `' . _DB_PREFIX_ . 'product_comment` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci')
&& Db::getInstance()->execute('ALTER TABLE `' . _DB_PREFIX_ . 'product_comment_criterion` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci')
&& Db::getInstance()->execute('ALTER TABLE `' . _DB_PREFIX_ . 'product_comment_criterion_product` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci')
&& Db::getInstance()->execute('ALTER TABLE `' . _DB_PREFIX_ . 'product_comment_criterion_lang` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci')
&& Db::getInstance()->execute('ALTER TABLE `' . _DB_PREFIX_ . 'product_comment_criterion_category` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci')
&& Db::getInstance()->execute('ALTER TABLE `' . _DB_PREFIX_ . 'product_comment_grade` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci')
&& Db::getInstance()->execute('ALTER TABLE `' . _DB_PREFIX_ . 'product_comment_usefulness` CHARACTER SET = utf8mb4 COLLATE utf8mb4_general_ci')
&& Db::getInstance()->execute('ALTER TABLE `' . _DB_PREFIX_ . 'product_comment_report` CHARACTER SET = utf8mb4 COLLATE utf8mb4_general_ci');
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,677 @@
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
/**
* Product comments CSS
*/
.product-comment-modal .material-icons[data-icon]:before,
.product-comment-list-item .material-icons[data-icon]:before,
.product-comments-additional-info .material-icons[data-icon]:before,
#product-comments-list-header .material-icons[data-icon]:before,
#product-comments-list-footer .material-icons[data-icon]:before {
content: attr(data-icon);
}
.btn-comment,
.btn-comment-inverse {
height: 36px;
border-radius: 2px;
background-color: #6b868f;
color: #ffffff;
font-size: 14px;
box-shadow: 2px 2px 4px 0 rgba(0, 0, 0, 0.2);
padding: 8px;
}
.btn-comment .material-icons,
.btn-comment-inverse .material-icons {
font-size: 20px;
margin-right: 7px;
}
.btn-comment:hover {
background-color: #3c4d52;
}
.btn-comment-inverse {
background-color: #ffffff;
color: #363a41;
border: 1px solid #979797;
}
.btn-comment-inverse:hover {
background-color: #6b868f;
border: 1px solid #6b868f;
color: #ffffff;
}
.btn-comment-big {
padding: 13px 16px;
height: 45px;
}
.btn-comment-huge {
padding: 13px 28px;
height: 45px;
}
.link-comment {
color: #232323;
}
.link-comment:hover,
.link-comment:active {
text-decoration: underline;
color: #232323;
}
/**
* Additional product infos
*/
.product-comments-additional-info {
margin: 20px 0;
font-weight: 300;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
font-size: 14px;
}
.product-comments-additional-info .link-comment.post-product-comment {
border-left: 1px solid #979797;
padding-left: 12px;
margin-left: 12px;
}
.product-comments-additional-info .comments-note {
margin-right: 30px;
margin-bottom: 20px;
}
/**
* Post comment modal
*/
.product-comment-modal .modal-header {
border: none;
padding: 30px 30px 15px;
}
.product-comment-modal .modal-body {
padding: 15px 30px 30px;
}
.product-comment-modal .modal-header .h2 {
float: left;
font-size: 20px;
}
.product-comment-modal .modal-dialog {
width: calc(100% - 30px);
max-width: 774px;
}
.product-comment-modal .modal-dialog .h3 {
font-size: 14px;
}
.product-comment-modal .modal-dialog .product-flag {
display: none;
}
.product-comment-modal .modal-dialog .product-cover,
.product-comment-modal .modal-dialog .product-cover img {
width: 99px;
height: 99px;
}
.product-comment-modal label.form-label {
font-size: 16px;
margin: 10px 0;
}
.product-comment-modal input {
width: 100%;
height: 44px;
border: 1px solid #bfbfbf;
padding: 0 10px;
}
.product-comment-modal textarea {
width: 100%;
min-height: 80px;
border: 1px solid #bfbfbf;
margin-bottom: 10px;
padding: 10px 10px;
}
.product-comment-modal .btn-comment,
.product-comment-modal .btn-comment-inverse {
font-size: 16px;
line-height: 16px;
font-weight: bold;
}
.product-comment-modal .required {
font-size: 12px;
margin-left: 5px;
}
.product-comment-modal .post-comment-buttons {
display: flex;
flex-direction: row;
justify-content: flex-end;
}
.product-comment-modal .post-comment-buttons .btn-comment {
margin-left: 15px;
}
#product-comment-posted-modal .post-comment-buttons,
#product-comment-post-error .post-comment-buttons,
#update-comment-usefulness-post-error .post-comment-buttons {
margin-top: 30px;
}
.product-comment-modal .modal-header .material-icons {
color: #40a85f;
font-size: 30px;
line-height: 25px;
}
.product-comment-modal .modal-header .material-icons.error {
color: #a94442;
}
.product-comment-modal .modal-header .material-icons.feedback {
color: #f39d72;
}
/**
* Star component
*/
.star-content {
margin: 0 0 0 5px;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
.star-content div.star,
.star-content div.star-on,
.star-content div.star-hover {
display: block;
width: 20px;
height: 20px;
background: url(../img/stars.png) no-repeat 0 0 transparent;
flex: auto;
margin-left: 3px;
}
.star-content div.star-on,
.star-content div.star-hover {
background-position: -24px 0;
}
.small-stars .star-content div.star,
.small-stars .star-content div.star-on,
.small-stars .star-content div.star-hover {
background: url(../img/small_stars.png) no-repeat 0 0 transparent;
width: 16px;
height: 16px;
margin-left: 2px;
}
.small-stars .star-content div.star-on,
.small-stars .star-content div.star-hover {
background-position: -19px 0;
}
.star-content div.star-hover {
cursor: pointer;
}
.grade-stars {
position: relative;
height: 20px;
min-width: 120px;
display: inline-block;
}
.grade-stars.small-stars {
min-width: 100px;
}
.grade-stars .star-content {
position: absolute;
top: 3px;
left: 0;
}
.criterion-rating .grade-stars .star-content {
top: 0;
}
#post-product-comment-modal .star-content div.star a {
display: block;
position: absolute;
text-indent: -5000px;
}
#post-product-comment-modal .criterion-rating {
display: flex;
flex-direction: row;
justify-content: flex-end;
}
#post-product-comment-modal .criterion-rating label {
color: #363a41;
font-size: 14px;
font-weight: bold;
}
#ratingNotChosen {
font-size: smaller;
color: #ab4746;
text-align: right;
}
#post-product-comment-form input.error,
#post-product-comment-form textarea.error {
background-color: #f2dede;
border: solid 1px #ebcccc;
}
#post-product-comment-form input.valid,
#post-product-comment-form textarea.valid {
border: solid 1px #d0e9c6;
}
/**
* Product comments list
*/
#product-comments-list-header {
padding: 20px 15px;
color: #232323;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
}
#product-comments-list-header .comments-nb {
padding-left: 0;
padding-top: 3px;
}
#product-comments-list-header .comments-nb .material-icons {
margin-right: 3px;
}
#product-comments-list .btn-comment {
margin: 0 auto;
display: block;
}
.product-comment-list-item {
padding: 26px 0;
margin: 0 0 20px;
background-color: #ffffff;
text-align: left;
}
#empty-product-comment {
text-align: center;
}
.product-comment-list-item .grade-stars .star-content {
margin: 0 0 10px;
}
.product-comment-list-item .comment-infos {
height: 19px;
color: #6b868f;
font-size: 14px;
letter-spacing: -0.28px;
line-height: 19px;
min-height: 100px;
}
.product-comment-list-item .comment-infos .grade-stars {
margin-bottom: 20px;
}
.product-comment-list-item .comment-content .h4 {
height: 22px;
color: #363a41;
font-size: 16px;
font-weight: 600;
letter-spacing: -0.32px;
line-height: 22px;
}
.product-comment-list-item .comment-content p {
color: #363a42;
font-size: 14px;
letter-spacing: -0.28px;
line-height: 19px;
word-break: break-word;
white-space: pre-wrap;
}
.product-comment-list-item .comment-content .comment-buttons a {
color: #6b868f;
font-size: 14px;
letter-spacing: -0.28px;
line-height: 19px;
margin-right: 8px;
}
.product-comment-list-item .comment-content .comment-buttons a .material-icons {
font-size: 18px;
cursor: pointer;
}
/*
** Quickview style
*/
.product-quickview-review {
display: flex;
flex-direction: row;
}
.product-quickview-review .grade-stars .star-content {
margin: 0 0 0 0;
top: 0;
}
/*
** Product list override
*/
#products .thumbnail-container.has-reviews:hover .highlighted-informations,
#products .thumbnail-container.has-reviews:focus .highlighted-informations,
.featured-products
.thumbnail-container.has-reviews:hover
.highlighted-informations,
.featured-products
.thumbnail-container.has-reviews:focus
.highlighted-informations,
.product-accessories
.thumbnail-container.has-reviews:hover
.highlighted-informations,
.featured-products
.thumbnail-container.has-reviews:focus
.highlighted-informations,
.product-miniature
.thumbnail-container.has-reviews:hover
.highlighted-informations,
.product-miniature
.thumbnail-container.has-reviews:focus
.highlighted-informations {
height: 4.5rem;
}
#products
.thumbnail-container.has-reviews:hover
.highlighted-informations
.variant-links,
#products
.thumbnail-container.has-reviews:focus
.highlighted-informations
.variant-links,
.featured-products
.thumbnail-container.has-reviews:hover
.highlighted-informations
.variant-links,
.featured-products
.thumbnail-container.has-reviews:focus
.highlighted-informations
.variant-links,
.product-accessories
.thumbnail-container.has-reviews:hover
.highlighted-informations
.variant-links,
.featured-products
.thumbnail-container.has-reviews:focus
.highlighted-informations
.variant-links,
.product-miniature
.thumbnail-container.has-reviews:hover
.highlighted-informations
.variant-links,
.product-miniature
.thumbnail-container.has-reviews:focus
.highlighted-informations
.variant-links {
min-height: 3.7rem;
}
#products
.thumbnail-container.has-reviews:hover
.highlighted-informations.no-variants,
#products
.thumbnail-container.has-reviews:focus
.highlighted-informations.no-variants,
.featured-products
.thumbnail-container.has-reviews:hover
.highlighted-informations.no-variants,
.featured-products
.thumbnail-container.has-reviews:focus
.highlighted-informations.no-variants,
.product-accessories
.thumbnail-container.has-reviews:hover
.highlighted-informations.no-variants,
.featured-products
.thumbnail-container.has-reviews:focus
.highlighted-informations.no-variants,
.product-miniature
.thumbnail-container.has-reviews:hover
.highlighted-informations.no-variants,
.product-miniature
.thumbnail-container.has-reviews:focus
.highlighted-informations.no-variants {
height: 4.125rem;
}
#products
.product-miniature
.thumbnail-container.has-reviews
.discount-amount.online-only,
#products
.product-miniature
.thumbnail-container.has-reviews
.discount-percentage.online-only,
#products
.product-miniature
.thumbnail-container.has-reviews
.on-sale.online-only,
#products
.product-miniature
.thumbnail-container.has-reviews
.online-only.online-only,
#products .product-miniature .thumbnail-container.has-reviews .pack.online-only,
#products
.product-miniature
.thumbnail-container.has-reviews
.product-flags
.new.online-only,
.featured-products
.product-miniature
.thumbnail-container.has-reviews
.discount-amount.online-only,
.featured-products
.product-miniature
.thumbnail-container.has-reviews
.discount-percentage.online-only,
.featured-products
.product-miniature
.thumbnail-container.has-reviews
.on-sale.online-only,
.featured-products
.product-miniature
.thumbnail-container.has-reviews
.online-only.online-only,
.featured-products
.product-miniature
.thumbnail-container.has-reviews
.pack.online-only,
.featured-products
.product-miniature
.thumbnail-container.has-reviews
.product-flags
.new.online-only,
.product-accessories
.product-miniature
.thumbnail-container.has-reviews
.discount-amount.online-only,
.product-accessories
.product-miniature
.thumbnail-container.has-reviews
.discount-percentage.online-only,
.product-accessories
.product-miniature
.thumbnail-container.has-reviews
.on-sale.online-only,
.product-accessories
.product-miniature
.thumbnail-container.has-reviews
.online-only.online-only,
.product-accessories
.product-miniature
.thumbnail-container.has-reviews
.pack.online-only,
.product-accessories
.product-miniature
.thumbnail-container.has-reviews
.product-flags
.new.online-only {
top: 11.5rem;
}
.product-list-reviews {
position: absolute;
top: -26px;
left: 0;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: center;
width: 100%;
background: rgba(255, 255, 255, 0.5);
padding: 4px 0;
visibility: hidden;
}
.product-list-reviews .grade-stars .star-content {
top: 1px;
}
.product-list-reviews .comments-nb {
margin-left: 5px;
font-size: 13px;
}
@media (min-width: 960px) {
#product-comments-list-footer {
position: relative;
min-height: 45px;
}
#product-comments-list-footer .post-product-comment {
margin: 0 auto;
display: block;
}
#product-comments-list-pagination {
position: absolute;
right: 0;
top: 5px;
}
}
@media (max-width: 960px) {
#product-comments-list-footer {
display: flex;
flex-direction: row-reverse;
flex-wrap: nowrap;
justify-content: space-between;
}
}
@media (max-width: 768px) {
#product-comments-list-footer {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-items: center;
}
#product-comments-list-pagination {
margin-bottom: 10px;
}
}
#product-comments-list-pagination {
height: 32px;
}
#product-comments-list-pagination ul {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
#product-comments-list-pagination ul li span {
height: 32px;
width: 24px;
margin: 0 5px;
cursor: pointer;
display: block;
text-align: center;
font-size: 20px;
line-height: 32px;
color: #6b868f;
}
#product-comments-list-pagination ul li.active span,
#product-comments-list-pagination ul li span.next i,
#product-comments-list-pagination ul li span.prev i {
font-weight: bold;
}
#product-comments-list-pagination ul li.disabled span {
opacity: 0.3;
cursor: not-allowed;
}
#product-comments-list-pagination ul li.active span {
cursor: not-allowed;
}
#product-comments-list-pagination ul li.hidden {
display: none;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../../');
exit;

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,158 @@
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
jQuery.fn.rating = function(generalOptions) {
const $ratings = $(this);
$ratings.each(function initRating() {
const $ratingComponent = $(this);
var options = generalOptions ? generalOptions : {};
if (!options.grade && $ratingComponent.data('grade')) {
options.grade = $ratingComponent.data('grade');
}
if (!options.min && $ratingComponent.data('min')) {
options.min = $ratingComponent.data('min');
}
if (!options.max && $ratingComponent.data('max')) {
options.max = $ratingComponent.data('max');
}
if (!options.input && $ratingComponent.data('input')) {
options.input = $ratingComponent.data('input');
}
var componentOptions = jQuery.extend({
grade: null,
input: null,
min: 1,
max: 5,
starWidth: 20
}, options);
const minValue = Math.min(componentOptions.min, componentOptions.max);
const maxValue = Math.max(componentOptions.min, componentOptions.max);
const ratingValue = Math.min(Math.max(minValue, componentOptions.grade), maxValue);
$ratingComponent.html('');
$ratingComponent.append('<div class="star-content star-empty clearfix"></div>');
$ratingComponent.append('<div class="star-content star-full clearfix"></div>');
const emptyStars = $('.star-empty', this);
const fullStars = $('.star-full', this);
const emptyStar = $('<div class="star"></div>');
const fullStar = $('<div class="star-on"></div>');
var ratingInput;
if (componentOptions.input) {
ratingInput = $('<input type="number" name="'+componentOptions.input+'" id="'+componentOptions.input+'" />');
ratingInput.val(ratingValue);
ratingInput.css('display', 'none');
ratingInput.on('change', displayInteractiveGrade);
$ratingComponent.append(ratingInput);
initInteractiveGrade();
} else {
displayGrade(ratingValue);
}
function initInteractiveGrade() {
emptyStars.html('');
fullStars.html('');
var newStar;
for (var i = minValue; i <= maxValue; ++i) {
newStar = emptyStar.clone();
newStar.data('grade', i);
newStar.on('mouseenter mouseleave', function overStar() {
var overIndex = $('.star', fullStars).index($(this));
$('.star', fullStars).each(function overStars() {
$(this).removeClass('star-on');
var starIndex = $('.star', fullStars).index($(this));
if (starIndex <= overIndex) {
$(this).addClass('star-hover');
} else {
$(this).removeClass('star-hover');
}
});
});
newStar.on('click', function selectGrade() {
var selectedGrade = $(this).data('grade');
ratingInput.val(selectedGrade);
ratingChosen = true;
});
fullStars.append(newStar);
}
fullStars.on('mouseenter', function(){}).on('mouseleave', displayInteractiveGrade);
displayInteractiveGrade();
}
function displayInteractiveGrade() {
$('.star', fullStars).each(function displayStar() {
var starValue = $(this).data('grade');
$(this).removeClass('star-hover');
if (starValue <= ratingInput.val()) {
$(this).addClass('star-on');
} else {
$(this).removeClass('star-on');
}
});
}
function displayGrade(grade) {
emptyStars.html('');
fullStars.html('');
var newStar;
for (var i = minValue; i <= maxValue; ++i) {
if (i <= Math.floor(grade)) {
newStar = emptyStar.clone();
newStar.css('visibility', 'hidden');
emptyStars.append(newStar);
fullStars.append(fullStar.clone());
} else if (i > Math.ceil(grade)) {
newStar = emptyStar.clone();
emptyStars.append(newStar.clone());
} else {
//This the partial star composed of
// - one invisible partial empty star
// - one visible partial empty star (remaining part)
// - one visible partial full star
var fullWidth = (grade - i + 1) * componentOptions.starWidth;
var emptyWidth = componentOptions.starWidth - fullWidth;
newStar = emptyStar.clone();
newStar.css('visibility', 'hidden');
newStar.css('width', fullWidth);
emptyStars.append(newStar);
newStar = emptyStar.clone();
newStar.css('width', emptyWidth);
newStar.css('background-position', '0px -'+fullWidth+'px');
newStar.css('background-position', '-'+fullWidth+'px 0px');
newStar.css('marginLeft', 0);
emptyStars.append(newStar);
fullStar.css('width', fullWidth);
fullStars.append(fullStar.clone());
}
}
}
});
}

View File

@@ -0,0 +1,254 @@
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
jQuery(document).ready(function () {
const $ = jQuery;
const commentsList = $('#product-comments-list');
const emptyProductComment = $('#empty-product-comment');
const commentsListUrl = commentsList.data('list-comments-url');
const updateCommentUsefulnessUrl = commentsList.data('update-comment-usefulness-url');
const reportCommentUrl = commentsList.data('report-comment-url');
const commentPrototype = commentsList.data('comment-item-prototype');
const pagesListId = '#product-comments-list-pagination';
const pageIdPrefix = '#pcl_page_';
const totalPages = commentsList.data('total-pages');
const prevCount = 0;
const nextCount = totalPages + 1;
const gapText = '&hellip;';
$('#product-comments-list .grade-stars').rating();
$('.product-comments-additional-info .grade-stars').rating();
prestashop.on('updatedProduct', function() {
$('.product-comments-additional-info .grade-stars').rating();
})
document.addEventListener('updateRating', function() {
$('#product-comments-list .grade-stars').rating();
$('.product-comments-additional-info .grade-stars').rating();
});
const updateCommentPostErrorModal = $('#update-comment-usefulness-post-error');
const confirmAbuseModal = $('#report-comment-confirmation');
const reportCommentPostErrorModal = $('#report-comment-post-error');
const reportCommentPostedModal = $('#report-comment-posted');
function showUpdatePostCommentErrorModal(errorMessage) {
$('#update-comment-usefulness-post-error-message').html(errorMessage);
updateCommentPostErrorModal.modal('show');
}
function showReportCommentErrorModal(errorMessage) {
$('#report-comment-post-error-message').html(errorMessage);
reportCommentPostErrorModal.modal('show');
}
async function fetchComments(page) {
let response = await fetch(commentsListUrl + "&page=" + page);
if (response.status === 200) {
let data = await response.text();
populateComments((JSON.parse(data)).comments);
}
}
$(pagesListId + ' li').on('click',
function() {
let oldCount = commentsList.data('current-page');
let newCount = $(this).index();
if (newCount === prevCount) { // click prev
newCount = oldCount - 1;
if (newCount <= 0) return;
}
if (newCount === nextCount) { // click next
newCount = oldCount + 1;
if (newCount >= nextCount) return;
}
$(`${pageIdPrefix}${oldCount} span`).removeClass('current');
$(`${pageIdPrefix}${oldCount}`).removeClass('active');
fetchComments(newCount); // fetch new page's comments
$(`${pageIdPrefix}${newCount}`).addClass('active');
$(`${pageIdPrefix}${newCount} span`).addClass('current');
$(`${pageIdPrefix}${newCount} span`).html(newCount);
commentsList.data('current-page', newCount);
if (newCount === 1) // disable prev
$(`${pageIdPrefix}${prevCount}`).addClass('disabled');
else
$(`${pageIdPrefix}${prevCount}`).removeClass('disabled');
if (newCount === totalPages) // disable next
$(`${pageIdPrefix}${nextCount}`).addClass('disabled');
else
$(`${pageIdPrefix}${nextCount}`).removeClass('disabled');
// long list with over 9 pages
if (9 <= totalPages) {
generateGap(newCount, prevCount);
generateGap(newCount, nextCount);
}
}
)
function generateGap(start, stop) {
if (start == stop)
return 0;
let step = (start < stop) ? +1 : -1;
let i = start + step;
if (4 < Math.abs(stop - start)) {
$(`${pageIdPrefix}${i}`).removeClass('hidden').removeClass('disabled');
$(`${pageIdPrefix}${i} span`).html(i);
i = i + step;
$(`${pageIdPrefix}${i}`).removeClass('hidden').removeClass('disabled');
$(`${pageIdPrefix}${i} span`).html(gapText);
i = i + step;
for (; i != stop - 2*step; i = i + step) {
$(`${pageIdPrefix}${i}`).addClass('hidden');
}
}
else {
for (; i != stop; i = i + step) {
$(`${pageIdPrefix}${i}`).removeClass('hidden').removeClass('disabled');
$(`${pageIdPrefix}${i} span`).html(i);
}
}
}
function populateComments(comments) {
commentsList.html('');
comments.forEach(addComment);
}
function addComment(comment) {
var commentTemplate = commentPrototype;
var customerName = comment.customer_name;
if (!customerName) {
customerName = comment.firstname+' '+comment.lastname;
}
commentTemplate = commentTemplate.replace(/@COMMENT_ID@/, comment.id_product_comment);
commentTemplate = commentTemplate.replace(/@PRODUCT_ID@/, comment.id_product);
commentTemplate = commentTemplate.replace(/@CUSTOMER_NAME@/, customerName);
commentTemplate = commentTemplate.replace(/@COMMENT_DATE@/, comment.date_add);
commentTemplate = commentTemplate.replace(/@COMMENT_TITLE@/, comment.title);
commentTemplate = commentTemplate.replace(/@COMMENT_COMMENT@/, comment.content);
commentTemplate = commentTemplate.replace(/@COMMENT_USEFUL_ADVICES@/, comment.usefulness);
commentTemplate = commentTemplate.replace(/@COMMENT_GRADE@/, comment.grade);
commentTemplate = commentTemplate.replace(/@COMMENT_NOT_USEFUL_ADVICES@/, (comment.total_usefulness - comment.usefulness));
commentTemplate = commentTemplate.replace(/@COMMENT_TOTAL_ADVICES@/, comment.total_usefulness);
const $comment = $(commentTemplate);
$('.grade-stars', $comment).rating({
grade: comment.grade
});
$('.useful-review', $comment).click(function() {
updateCommentUsefulness($comment, comment.id_product_comment, 1);
});
$('.not-useful-review', $comment).click(function() {
updateCommentUsefulness($comment, comment.id_product_comment, 0);
});
$('.report-abuse', $comment).click(function() {
confirmCommentAbuse(comment.id_product_comment);
});
commentsList.append($comment);
}
async function updateCommentUsefulness($comment, commentId, usefulness) {
try {
const response = await fetch(updateCommentUsefulnessUrl, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "id_product_comment=" + commentId + "&usefulness=" + usefulness,
});
if (response.status === 200) {
const jsonData = await response.json();
if (jsonData.success) {
$('.useful-review-value', $comment).html(jsonData.usefulness);
$('.not-useful-review-value', $comment).html(jsonData.total_usefulness - jsonData.usefulness);
} else {
const decodedErrorMessage = $("<div/>").html(jsonData.error).text();
showUpdatePostCommentErrorModal(decodedErrorMessage);
}
} else {
showUpdatePostCommentErrorModal(productCommentUpdatePostErrorMessage);
}
} catch (error) {
showUpdatePostCommentErrorModal(error);
}
}
function confirmCommentAbuse(commentId) {
confirmAbuseModal.modal('show');
confirmAbuseModal.one('modal:confirm', function(event, confirm) {
if (!confirm) {
return;
}
confirmCommentAbuseFetch(commentId);
})
}
async function confirmCommentAbuseFetch(commentId) {
try {
const response = await fetch(reportCommentUrl, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "id_product_comment=" + commentId,
});
if (response.status === 200) {
const jsonData = await response.json();
if (jsonData.success) {
reportCommentPostedModal.modal('show');
} else {
showReportCommentErrorModal(jsonData.error);
}
} else {
showReportCommentErrorModal(productCommentAbuseReportErrorMessage);
}
} catch (error) {
showReportCommentErrorModal(error);
}
}
if (totalPages <= 1)
$(pagesListId).hide();
if (totalPages > 0) {
emptyProductComment.hide();
$(`${pageIdPrefix}1`).trigger('click');
}
});

View File

@@ -0,0 +1,144 @@
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
jQuery(document).ready(function () {
const $ = jQuery;
$('body').on('click', '.post-product-comment', function (event) {
event.preventDefault();
showPostCommentModal();
});
const postCommentModal = $('#post-product-comment-modal');
postCommentModal.on('hidden.bs.modal', function () {
postCommentModal.modal('hide');
clearPostCommentForm();
});
const commentPostedModal = $('#product-comment-posted-modal');
const commentPostErrorModal = $('#product-comment-post-error');
const criterionsList = $('#criterions_list');
criterionsList.append('<div id="ratingNotChosen">* ' + productCommentMandatoryMessage + '</div>');
const criterionsInfo = $('#ratingNotChosen');
function showPostCommentModal() {
commentPostedModal.modal('hide');
commentPostErrorModal.modal('hide');
postCommentModal.modal('show');
ratingChosen = false;
criterionsInfo.hide();
}
function showCommentPostedModal() {
postCommentModal.modal('hide');
commentPostErrorModal.modal('hide');
clearPostCommentForm();
commentPostedModal.modal('show');
}
function showPostErrorModal(errorMessage) {
postCommentModal.modal('hide');
commentPostedModal.modal('hide');
clearPostCommentForm();
$('#product-comment-post-error-message').html(errorMessage);
commentPostErrorModal.modal('show');
}
function clearPostCommentForm() {
$('#post-product-comment-form input[type="text"]').val('');
$('#post-product-comment-form input[type="text"]').removeClass('valid error');
$('#post-product-comment-form textarea').val('');
$('#post-product-comment-form textarea').removeClass('valid error');
$('#post-product-comment-form .criterion-rating input').val(3).trigger('change');
}
function initCommentModal() {
$('#post-product-comment-modal .grade-stars').rating();
$('body').on('click', '.post-product-comment', function (event) {
event.preventDefault();
showPostCommentModal();
});
$('#post-product-comment-form').on('submit', submitCommentForm);
}
function submitCommentForm(event) {
event.preventDefault();
var formData = $(this).serializeArray();
if (!validateFormData(formData)) {
return;
}
$.post($(this).attr('action'), $(this).serialize(), function(jsonData) {
if (jsonData) {
if (jsonData.success) {
clearPostCommentForm();
showCommentPostedModal();
} else {
if (jsonData.errors) {
var errorList = '<ul>';
for (var i = 0; i < jsonData.errors.length; ++i) {
errorList += '<li>' + jsonData.errors[i] + '</li>';
}
errorList += '</ul>';
showPostErrorModal(errorList);
} else {
const decodedErrorMessage = $("<div/>").html(jsonData.error).text();
showPostErrorModal(decodedErrorMessage);
}
}
} else {
showPostErrorModal(productCommentPostErrorMessage);
}
}).fail(function() {
showPostErrorModal(productCommentPostErrorMessage);
});
}
function validateFormData(formData) {
var isValid = true;
formData.forEach(function(formField) {
const fieldSelector = '#post-product-comment-form [name="'+formField.name+'"]';
if (!formField.value) {
$(fieldSelector).addClass('error');
$(fieldSelector).removeClass('valid');
isValid = false;
} else {
$(fieldSelector).removeClass('error');
$(fieldSelector).addClass('valid');
}
if (!ratingChosen) {
criterionsInfo.show();
isValid = false;
} else {
criterionsInfo.hide();
}
});
return isValid;
}
initCommentModal();
});

View File

@@ -0,0 +1,205 @@
/**
* 2007-2019 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
$(document).ready(function() {
productListingComments.init();
productListingComments.load();
});
var productListingComments = (function () {
var data = {
productIDs: [],
commentsLoadingInProgress: false,
ajaxIDsLimit: 50,
ajaxUrl: ''
}
var DOMStrings = {
productListReviewsContainer: '.product-list-reviews',
productListReviewsNumberOfComments: '.comments-nb',
productListReviewsStarsContainer: '.grade-stars',
productContainer: '.js-product-miniature'
};
var DOMClasses = {
inProgress: 'reviews-loading',
reviewsLoaded: 'reviews-loaded',
hasReviews: 'has-reviews'
};
function setEvents() {
prestashop.on('updateProductList', function() {
addProductsIDs();
});
prestashop.on("updatedProduct", function () {
updateRatings();
});
}
function setAjaxUrl() {
if (data.ajaxUrl !== '')
return;
var url = $(DOMStrings.productListReviewsContainer).first().data('url');
data.ajaxUrl = url;
}
function getNewProductsReviewsElements() {
var $productListReviews = $(DOMStrings.productContainer)
.not('.' + DOMClasses.reviewsLoaded + ', .' + DOMClasses.inProgress)
.addClass(DOMClasses.inProgress)
.find(DOMStrings.productListReviewsContainer);
return $productListReviews;
}
function addProductsIDs() {
var $productsList = getNewProductsReviewsElements(),
seenIds = {};
$productsList.each(function () {
var id = $(this).data('id');
seenIds[id] = true;
});
var IDsArray = Object.keys(seenIds).filter(e => e !== 'undefined');
var prevDataIDs = data.productIDs.splice(0);
data.productIDs = prevDataIDs.concat(IDsArray);
if (!data.commentsLoadingInProgress) {
loadProductsData();
}
}
function loadProductsData() {
if (data.productIDs.length === 0)
return;
data.commentsLoadingInProgress = true;
var dataIDsCopy = data.productIDs.slice(0);
selectedProductIDs = dataIDsCopy.splice(0, data.ajaxIDsLimit);
$.get(data.ajaxUrl, { id_products: selectedProductIDs }, function (jsonData) {
if (jsonData) {
$.each(jsonData.products, function(i, elem) {
var productData = elem;
var $productsReviewsContainer = $('.product-list-reviews[data-id="' + productData.id_product + '"]');
$productsReviewsContainer.each(function () {
var $self = $(this);
if (productData.comments_nb > 0) {
$self.find(DOMStrings.productListReviewsStarsContainer).rating({ grade: productData.average_grade, starWidth: 16 });
$self.find(DOMStrings.productListReviewsNumberOfComments).text('(' + productData.comments_nb + ')');
$self.closest(DOMStrings.productContainer).addClass(DOMClasses.hasReviews);
$self.css('visibility', 'visible');
}
$self.closest(DOMStrings.productContainer).addClass(DOMClasses.reviewsLoaded);
$self.closest(DOMStrings.productContainer).removeClass(DOMClasses.inProgress);
});
data.productIDs.shift();
});
data.commentsLoadingInProgress = false;
if (data.productIDs.length > 0) {
loadProductsData();
}
}
});
}
function updateRatings() {
// Collect all product IDs that need to be updated
var productIDs = [];
var $productsList = $(DOMStrings.productContainer);
$productsList.each(function () {
var productID = $(this).find(DOMStrings.productListReviewsContainer).data("id");
if (productID) {
productIDs.push(productID);
}
});
if (productIDs.length > 0) {
$.get(
data.ajaxUrl,
{ id_products: productIDs },
function (jsonData) {
if (jsonData && jsonData.products.length > 0) {
// Create a map of product data
var productDataMap = {};
jsonData.products.forEach(function (product) {
productDataMap[product.id_product] = product;
});
// Update each product's ratings
$productsList.each(function () {
var $self = $(this);
var productID = $self.find(DOMStrings.productListReviewsContainer).data("id");
if (productDataMap[productID]) {
var productData = productDataMap[productID];
var $productReviewContainer = $self.find(DOMStrings.productListReviewsContainer);
if (productData.comments_nb > 0) {
$productReviewContainer
.find(DOMStrings.productListReviewsStarsContainer)
.rating({ grade: productData.average_grade, starWidth: 16 });
$productReviewContainer
.find(DOMStrings.productListReviewsNumberOfComments)
.text("(" + productData.comments_nb + ")");
$self.addClass(DOMClasses.hasReviews);
$productReviewContainer.css("visibility", "visible");
}
}
});
}
}
);
}
}
return {
load: function () {
addProductsIDs();
},
init: function () {
setAjaxUrl();
setEvents();
}
}
})();

View File

@@ -0,0 +1,70 @@
{**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*}
{extends file="helpers/form/form.tpl"}
{block name="input"}
{if $input.type == 'products'}
<table id="{$input.name}">
<tr>
<th></th>
<th>ID</th>
<th width="80%">{l s='Product Name' d='Modules.Productcomments.Admin'}</th>
</tr>
{foreach $input.values as $value}
<tr>
<td>
<input type="checkbox" name="{$input.name}[]" value="{$value.id_product}"
{if isset($value.selected) && $value.selected == 1} checked {/if} />
</td>
<td>{$value.id_product}</td>
<td width="80%">{$value.name}</td>
</tr>
{/foreach}
</table>
{elseif $input.type == 'switch' && $smarty.const._PS_VERSION_|@addcslashes:'\'' < '1.6'}
{foreach $input.values as $value}
<input type="radio" name="{$input.name}" id="{$value.id}" value="{$value.value|escape:'html':'UTF-8'}"
{if $fields_value[$input.name] == $value.value}checked="checked"{/if}
{if isset($input.disabled) && $input.disabled}disabled="disabled"{/if} />
<label class="t" for="{$value.id}">
{if isset($input.is_bool) && $input.is_bool == true}
{if $value.value == 1}
<img src="../img/admin/enabled.gif" alt="{$value.label}" title="{$value.label}" />
{else}
<img src="../img/admin/disabled.gif" alt="{$value.label}" title="{$value.label}" />
{/if}
{else}
{$value.label}
{/if}
</label>
{if isset($input.br) && $input.br}<br />{/if}
{if isset($value.p) && $value.p}<p>{$value.p}</p>{/if}
{/foreach}
{else}
{$smarty.block.parent}
{/if}
{/block}

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,28 @@
{**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*}
<a href="{$href}" class="btn btn-success" title="{$action}" >
<i class="icon-check"></i> {$action}
</a>

View File

@@ -0,0 +1,28 @@
{**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*}
<a href="{$href}" class="" title="{$action}" >
<i class="icon-check"></i> {$action}
</a>

View File

@@ -0,0 +1,59 @@
{**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*}
{$icon = $icon|default:'check_circle'}
{$modal_message = $modal_message|default:''}
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
const alertModal = $('#{$modal_id}');
alertModal.on('hidden.bs.modal', function () {
alertModal.modal('hide');
});
});
</script>
<div id="{$modal_id}" class="modal fade product-comment-modal" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<p class="h2">
<i class="material-icons {$icon}" data-icon="{$icon}"></i>
{$modal_title}
</p>
</div>
<div class="modal-body">
<div id="{$modal_id}-message">
{$modal_message}
</div>
<div class="post-comment-buttons">
<button type="button" class="btn btn-comment btn-comment-huge" data-dismiss="modal">
{l s='OK' d='Modules.Productcomments.Shop'}
</button>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,31 @@
{**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*}
{if $nb_comments != 0}
<div class="comments-note">
<span>{l s='Grade' d='Modules.Productcomments.Shop'}</span>
<div class="grade-stars" data-grade="{$grade}"></div>
</div>
{/if}

View File

@@ -0,0 +1,70 @@
{**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*}
{$icon = $icon|default:'check_circle'}
{$modal_message = $modal_message|default:''}
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
const confirmModal = $('#{$modal_id}');
confirmModal.on('hidden.bs.modal', function () {
confirmModal.modal('hide');
confirmModal.trigger('modal:confirm', false);
});
$('.confirm-button', confirmModal).click(function() {
confirmModal.trigger('modal:confirm', true);
});
$('.refuse-button', confirmModal).click(function() {
confirmModal.trigger('modal:confirm', false);
});
});
</script>
<div id="{$modal_id}" class="modal fade product-comment-modal" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<p class="h2">
<i class="material-icons {$icon}" data-icon="{$icon}"></i>
{$modal_title}
</p>
</div>
<div class="modal-body">
<div id="{$modal_id}-message">
{$modal_message}
</div>
<div class="post-comment-buttons">
<button type="button" class="btn btn-comment-inverse btn-comment-huge refuse-button" data-dismiss="modal">
{l s='No' d='Modules.Productcomments.Shop'}
</button>
<button type="button" class="btn btn-comment btn-comment-huge confirm-button" data-dismiss="modal">
{l s='Yes' d='Modules.Productcomments.Shop'}
</button>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,35 @@
{**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*}
<div id="empty-product-comment" class="product-comment-list-item">
{if $post_allowed}
<button class="btn btn-comment btn-comment-big post-product-comment">
<i class="material-icons edit" data-icon="edit"></i>
{l s='Be the first to write your review' d='Modules.Productcomments.Shop'}
</button>
{else}
{l s='No customer reviews for the moment.' d='Modules.Productcomments.Shop'}
{/if}
</div>

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,148 @@
{**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*}
<script type="text/javascript">
var productCommentPostErrorMessage = '{l s='Sorry, your review cannot be posted.' d='Modules.Productcomments.Shop' js=1}';
var productCommentMandatoryMessage = '{l s='Please choose a rating for your review.' d='Modules.Productcomments.Shop' js=1}';
var ratingChosen = false;
</script>
<div id="post-product-comment-modal" class="modal fade product-comment-modal" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<p class="h2">{l s='Write your review' d='Modules.Productcomments.Shop'}</p>
<button type="button" class="close" data-dismiss="modal" aria-label="{l s='Close' d='Shop.Theme.Global'}">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form id="post-product-comment-form" action="{$post_comment_url nofilter}" method="POST">
<div class="row">
<div class="col-sm-2">
{if isset($product) && $product}
{block name='product_flags'}
<ul class="product-flags">
{foreach from=$product.flags item=flag}
<li class="product-flag {$flag.type}">{$flag.label}</li>
{/foreach}
</ul>
{/block}
{block name='product_cover'}
<div class="product-cover">
{if $product.cover}
<img class="js-qv-product-cover" src="{$product.cover.bySize.medium_default.url}" alt="{$product.cover.legend}" title="{$product.cover.legend}" style="width:100%;" itemprop="image">
{else}
<img src="{$urls.no_picture_image.bySize.large_default.url nofilter}" style="width:100%;">
{/if}
</div>
{/block}
{/if}
</div>
<div class="col-sm-4">
<p class="h3">{$product.name}</p>
{block name='product_description_short'}
<div itemprop="description">{$product.description_short nofilter}</div>
{/block}
</div>
<div class="col-sm-6">
{if $criterions|@count > 0}
<ul id="criterions_list">
{foreach from=$criterions item='criterion'}
<li>
<div class="criterion-rating">
<label>{$criterion.name|escape:'html':'UTF-8'}:</label>
<div
class="grade-stars"
data-grade="3"
data-input="criterion[{$criterion.id_product_comment_criterion}]">
</div>
</div>
</li>
{/foreach}
</ul>
{/if}
</div>
</div>
{if !$logged}
<div class="row">
<div class="col-sm-8">
<label class="form-label" for="comment_title">{l s='Title' d='Modules.Productcomments.Shop'}<sup class="required">*</sup></label>
<input id="comment_title" name="comment_title" type="text" value=""/>
</div>
<div class="col-sm-4">
<label class="form-label" for="customer_name">{l s='Your name' d='Modules.Productcomments.Shop'}<sup class="required">*</sup></label>
<input id="customer_name" name="customer_name" type="text" value=""/>
</div>
</div>
{else}
<label class="form-label" for="comment_title">{l s='Title' d='Modules.Productcomments.Shop'}<sup class="required">*</sup></label>
<input id="comment_title" name="comment_title" type="text" value=""/>
{/if}
<label class="form-label" for="comment_content">{l s='Review' d='Modules.Productcomments.Shop'}<sup class="required">*</sup></label>
<textarea id="comment_content" name="comment_content"></textarea>
{hook h='displayGDPRConsent' mod='psgdpr' id_module=$id_module}
<div class="row">
<div class="col-sm-6">
<p class="required"><sup>*</sup> {l s='Required fields' d='Modules.Productcomments.Shop'}</p>
</div>
<div class="col-sm-6 post-comment-buttons">
<button type="button" class="btn btn-comment-inverse btn-comment-big" data-dismiss="modal">
{l s='Cancel' d='Modules.Productcomments.Shop'}
</button>
<button type="submit" class="btn btn-comment btn-comment-big">
{l s='Send' d='Modules.Productcomments.Shop'}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{* Comment posted modal *}
{if $moderation_active}
{$comment_posted_message = {l s='Your comment has been submitted and will be available once approved by a moderator.' d='Modules.Productcomments.Shop'}}
{else}
{$comment_posted_message = {l s='Your comment has been added!' d='Modules.Productcomments.Shop'}}
{/if}
{include file='module:productcomments/views/templates/hook/alert-modal.tpl'
modal_id='product-comment-posted-modal'
modal_title={l s='Review sent' d='Modules.Productcomments.Shop'}
modal_message=$comment_posted_message
}
{* Comment post error modal *}
{include file='module:productcomments/views/templates/hook/alert-modal.tpl'
modal_id='product-comment-post-error'
modal_title={l s='Your review cannot be sent' d='Modules.Productcomments.Shop'}
icon='error'
}

View File

@@ -0,0 +1,45 @@
{**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*}
{if $nb_comments != 0}
<script type="text/javascript">
function renderQuickViewNote() {
$('#product-quickview-{$product.id}').insertAfter($('.quickview #product-description-short'));
$('#product-quickview-{$product.id} .grade-stars').rating({ grade: {$average_grade} });
$('#product-quickview-{$product.id} .comments-nb').html('({$nb_comments})');
}
renderQuickViewNote();
prestashop.on('updatedProduct', function(){
renderQuickViewNote();
});
</script>
<div id="product-quickview-{$product.id}" class="product-quickview-review">
<div class="grade-stars"></div>
<div class="comments-nb"></div>
</div>
{/if}

View File

@@ -0,0 +1,51 @@
{**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*}
{if $nb_comments != 0 || $post_allowed}
<div class="product-comments-additional-info">
{if $nb_comments == 0}
{if $post_allowed}
<button class="btn btn-comment post-product-comment">
<i class="material-icons edit" data-icon="edit"></i>
{l s='Write your review' d='Modules.Productcomments.Shop'}
</button>
{/if}
{else}
{include file='module:productcomments/views/templates/hook/average-grade-stars.tpl' grade=$average_grade}
<div class="additional-links">
<a class="link-comment" href="#product-comments-list-header">
<i class="material-icons chat" data-icon="chat"></i>
{l s='Read user reviews' d='Modules.Productcomments.Shop'} ({$nb_comments})
</a>
{if $post_allowed}
<a class="link-comment post-product-comment" href="#product-comments-list-header">
<i class="material-icons edit" data-icon="edit"></i>
{l s='Write your review' d='Modules.Productcomments.Shop'}
</a>
{/if}
</div>
{/if}
</div>
{/if}

View File

@@ -0,0 +1,56 @@
{**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*}
<div class="product-comment-list-item row" data-product-comment-id="@COMMENT_ID@" data-product-id="@PRODUCT_ID@">
<div class="col-sm-3 comment-infos">
<div class="grade-stars" data-grade="@COMMENT_GRADE@"></div>
<div class="comment-date">
@COMMENT_DATE@
</div>
<div class="comment-author">
{l s='By %1$s' sprintf=['@CUSTOMER_NAME@'] d='Modules.Productcomments.Shop'}
</div>
</div>
<div class="col-sm-9 comment-content">
<p class="h4">@COMMENT_TITLE@</p>
<p>@COMMENT_COMMENT@</p>
<div class="comment-buttons btn-group">
{if $usefulness_enabled}
<a class="useful-review">
<i class="material-icons thumb_up" data-icon="thumb_up"></i>
<span class="useful-review-value">@COMMENT_USEFUL_ADVICES@</span>
</a>
<a class="not-useful-review">
<i class="material-icons thumb_down" data-icon="thumb_down"></i>
<span class="not-useful-review-value">@COMMENT_NOT_USEFUL_ADVICES@</span>
</a>
{/if}
<a class="report-abuse" title="{l s='Report abuse' d='Modules.Productcomments.Shop'}">
<i class="material-icons flag" data-icon="flag"></i>
</a>
</div>
</div>
</div>

View File

@@ -0,0 +1,99 @@
{**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*}
<script type="text/javascript">
var productCommentUpdatePostErrorMessage = '{l|escape:'javascript' s='Sorry, your review appreciation cannot be sent.' d='Modules.Productcomments.Shop'}';
var productCommentAbuseReportErrorMessage = '{l|escape:'javascript' s='Sorry, your abuse report cannot be sent.' d='Modules.Productcomments.Shop'}';
</script>
<div id="product-comments-list-header">
<div class="comments-nb">
<i class="material-icons chat" data-icon="chat"></i>
{l s='Comments' d='Modules.Productcomments.Shop'} ({$nb_comments})
</div>
{include file='module:productcomments/views/templates/hook/average-grade-stars.tpl' grade=$average_grade}
</div>
{include file='module:productcomments/views/templates/hook/product-comment-item-prototype.tpl' assign="comment_prototype"}
{include file='module:productcomments/views/templates/hook/empty-product-comment.tpl'}
<div id="product-comments-list"
data-list-comments-url="{$list_comments_url nofilter}"
data-update-comment-usefulness-url="{$update_comment_usefulness_url nofilter}"
data-report-comment-url="{$report_comment_url nofilter}"
data-comment-item-prototype="{$comment_prototype|escape:'html'}"
data-current-page="1"
data-total-pages="{$list_total_pages}">
</div>
<div id="product-comments-list-footer">
<div id="product-comments-list-pagination">
{if $list_total_pages > 0}
<ul>
{assign var = "prevCount" value = 0}
<li id="pcl_page_{$prevCount}"><span class="prev"><i class="material-icons">chevron_left</i></span></li>
{for $pageCount = 1 to $list_total_pages}
<li id="pcl_page_{$pageCount}"><span>{$pageCount}</span></li>
{/for}
{assign var = "nextCount" value = $list_total_pages + 1}
<li id="pcl_page_{$nextCount}"><span class="next"><i class="material-icons">chevron_right</i></span></li>
</ul>
{/if}
</div>
{if $post_allowed && $nb_comments != 0}
<button class="btn btn-comment btn-comment-big post-product-comment">
<i class="material-icons edit" data-icon="edit"></i>
{l s='Write your review' d='Modules.Productcomments.Shop'}
</button>
{/if}
</div>
{* Appreciation post error modal *}
{include file='module:productcomments/views/templates/hook/alert-modal.tpl'
modal_id='update-comment-usefulness-post-error'
modal_title={l s='Your review appreciation cannot be sent' d='Modules.Productcomments.Shop'}
icon='error'
}
{* Confirm report modal *}
{include file='module:productcomments/views/templates/hook/confirm-modal.tpl'
modal_id='report-comment-confirmation'
modal_title={l s='Report comment' d='Modules.Productcomments.Shop'}
modal_message={l s='Are you sure that you want to report this comment?' d='Modules.Productcomments.Shop'}
icon='feedback'
}
{* Report comment posted modal *}
{include file='module:productcomments/views/templates/hook/alert-modal.tpl'
modal_id='report-comment-posted'
modal_title={l s='Report sent' d='Modules.Productcomments.Shop'}
modal_message={l s='Your report has been submitted and will be considered by a moderator.' d='Modules.Productcomments.Shop'}
}
{* Report abuse error modal *}
{include file='module:productcomments/views/templates/hook/alert-modal.tpl'
modal_id='report-comment-post-error'
modal_title={l s='Your report cannot be sent' d='Modules.Productcomments.Shop'}
icon='error'
}

View File

@@ -0,0 +1,31 @@
{**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*}
{* Javascript is used to display each product grade, this allows every rating to be udpated as soon as they change *}
<div class="product-list-reviews" data-id="{$product.id}" data-url="{$product_comment_grade_url nofilter}">
<div class="grade-stars small-stars"></div>
<div class="comments-nb"></div>
</div>

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;