<?php
/**
* @file
* Contains belmil_product_rating.module.
*/
use Drupal\block\Entity\Block;
use Drupal\commerce_product\Entity\ProductInterface;
use Drupal\commerce_product\Entity\ProductType;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Markup;
use Drupal\Core\Routing\RouteMatchInterface;
use \Drupal\user\EntityOwnerInterface;
/**
* Implements hook_help().
*/
function belmil_product_rating_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
// Main module help for the belmil_product_rating module.
case 'help.page.belmil_product_rating':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('This module provides custom rating functionalities for products.') . '</p>';
return $output;
default:
}
return '';
}
/**
* Implements hook_theme().
*/
function belmil_product_rating_theme() {
return [
'belmil_product_rating' => [
'render element' => 'children',
],
'belmil_product_rating_statistics_widget' => [
'render element' => 'children',
]
];
}
/**
* Implements hook_ENTITY_TYPE_insert().
*/
function belmil_product_rating_comment_insert(EntityInterface $entity) {
$userRoles = \Drupal::currentUser()->getRoles();
if ($entity instanceof EntityOwnerInterface) {
$ownerEmail = $entity->getOwner()->getEmail();
if (!in_array('administrator', $userRoles) && $ownerEmail != 'trustami@studiopresent.com') {
$link = '/comment/' . $entity->id() . '/edit';
$body = t('There is new comment on your site') . '<br> <a target="_blank" href="' . $link . '">' . t('Show') . ' </a>';
// Send mail.
/** @var \Drupal\Core\Mail\MailManagerInterface $mailManager */
$mailManager = \Drupal::service('plugin.manager.mail');
$module = $key = 'belmil_product_rating';
// Get email from config and remove whitespaces.
$to = \Drupal::config('system.site')->get('mail');
$params['subject'] = t('New comment on website');
$params['body'] = $body;
$params['format'] = 'text/html';
$langcode = \Drupal::currentUser()->getPreferredLangcode();
$result = $mailManager->mail($module, $key, $to, $langcode, $params, NULL, TRUE);
// Log result.
if ($result['result'] != TRUE) {
$message = t('There was a problem sending your email notification to @email.', ['@email' => $to]);
\Drupal::logger('mail')->error($message);
}
else {
$message = t('An email notification for new comment has been sent to @email.', ['@email' => $to]);
\Drupal::logger('mail')->notice($message);
}
}
}
}
/**
* Implements hook_mail().
*/
function belmil_product_rating_mail($key, &$message, $params) {
switch ($key) {
case 'belmil_product_rating':
$message['subject'] = $params['subject'];
$message['body'][] = Markup::create($params['body']);
$message['headers']['Content-Type'] = $params['format'];
break;
}
}
/**
* Implements hook_form_alter().
*/
function belmil_product_rating_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// Open details for admin comment approval.
if ($form_id == "comment_product_comment_form") {
$form['#validate'][] = 'belmil_product_rating_settings_validate';
if (isset($form['author'])) {
$form['author']['#open'] = TRUE;
}
}
}
/**
* Implements hook_form_submit().
*/
function belmil_product_rating_settings_validate(&$form, FormStateInterface $form_state) {
$uid = \Drupal::currentUser()->id();
if (empty($form_state->getValue('uid'))) {
$form['author']['uid']['#value'] = $uid;
$form['author']['name']['#value'] = 'Anonymous';
}
}
/**
* Implements hook_entity_extra_field_info().
*/
function belmil_product_rating_entity_extra_field_info() {
$stars_field = [];
foreach (ProductType::loadMultiple() as $bundle) {
$stars_field['commerce_product'][$bundle->id()]['display']['trustamiproductreview'] = [
'label' => t('Trustami product review'),
'description' => t('A pseudo field to display the Trustami product review block'),
'weight' => 0,
'visible' => TRUE,
];
// Define stars field for displaying rating by stars and link to comment section.
$stars_field['commerce_product'][$bundle->id()]['display']['stars_field'] = [
'label' => t('Product stars'),
'description' => t('This is pseudo field for showing stars rating'),
'visible' => FALSE,
];
// Define statistic widget for rating.
$stars_field['commerce_product'][$bundle->id()]['display']['stars_widget'] = [
'label' => t('Stars widget'),
'description' => t('Stars widget with statistic by marks'),
'visible' => FALSE,
];
}
return $stars_field;
}
/**
* Implements hook_ENTITY_TYPE_view().
*
* Add stars field & widget to product view.
*/
function belmil_product_rating_commerce_product_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
if ($display->getComponent('trustamiproductreview')) {
$block = Block::load('trustamiproductreview');
if ($block) {
$build['trustamiproductreview'] = $block->getPlugin()->build();
}
}
if ($display->getComponent('stars_field') ||
$display->getComponent('stars_widget')
) {
/** @var \Drupal\belmil_product_rating\BelmilProductRatingManager $product_rating_manager */
$product_rating_manager = \Drupal::service('belmil_product_rating.belmil_product_rating_manager');
$productRating = 0;
$numOfComments = 0;
$productsWithSameTagWithComments = [];
$ratings = [];
// Get product with same tag which contain comments for default product type.
if ($entity->bundle() === "default") {
$tagId = (int) $entity->get('field_tag')->target_id;
$productsWithSameTagWithComments = $product_rating_manager
->getProductsWithSameTagWithComments($tagId);
}
// Get comments of single product for universal product type.
elseif ($entity->bundle() === "universal") {
$productsWithSameTagWithComments = [$entity->id()];
}
// Call get rating function.
$product_rating_manager->getRating($productsWithSameTagWithComments, $productRating, $numOfComments, $ratings);
// Prepare stars data - num of stars is fixed to 5.
$starsData = $product_rating_manager->prepareStarsData(5, $productRating);
}
// Render product stars.
if ($display->getComponent('stars_field')) {
$build['stars_field'] = [
'#markup' => \Drupal::theme()->render('belmil_product_rating', [
'rating' => $productRating,
'stars' => 5,
'vote_type' => "fivestar-widget-static-vote",
'num_of_comments' => $numOfComments,
'widget' => ['name' => 'fivestar-basic'],
'stars_data' => $starsData,
'product_id' => $entity->id(),
]),
];
}
// Render stars statistics widget.
if ($display->getComponent('stars_widget')) {
// Render only if there is any comment.
if (!empty($ratings)) {
$totalRating = ($productRating / 20 );
$statistics = $product_rating_manager->getStatisticsRatingData($ratings);
// Get percentage of each mark.
foreach ($statistics as $key => $rating) {
$statistics[$key] = $rating / count($ratings) * 100;
}
$build['stars_widget'] = [
'#markup' => \Drupal::theme()->render('belmil_product_rating_statistics_widget', [
'ratings' => $statistics,
'total_rating' => $totalRating,
'rating' => $productRating,
'stars' => 5,
'vote_type' => "fivestar-widget-static-vote",
'num_of_comments' => $numOfComments,
'widget' => ['name' => 'fivestar-basic'],
'stars_data' => $starsData,
'product_id' => $entity->id(),
]),
];
}
}
}
/**
* Implements hook_page_attachments().
*/
function belmil_product_rating_page_attachments(array &$page) {
// Get request and entity.
$request = \Drupal::request();
$path = $request->attributes->get('_route_object')->getPath();
/** @var \Drupal\commerce_product\Entity\ProductInterface $entity */
$entity = $request->attributes->get('_entity');
// Check if we are on product view page.
if (!empty($entity) && $path == "/product/{commerce_product}") {
// Attach google schema style script.
/** @var \Drupal\belmil_product_rating\BelmilProductRatingManager $product_rating_manager */
$product_rating_manager = \Drupal::service('belmil_product_rating.belmil_product_rating_manager');
$product_rating_manager->attachGoogleSchemaStyleScript($entity, $page);
// Attach Trustami Comment Widget.
$referrerMeta = [
'#tag' => 'meta',
'#attributes' => [
'name' => 'referrer',
'content' => 'strict-origin-when-cross-origin',
],
];
$page['#attached']['html_head'][] = [$referrerMeta, 'referrerMeta'];
// attachTrustamiCommentsWidgetScript($entity, $page);
}
}
/**
* Trustami product widget script.
*
* @param \Drupal\commerce_product\Entity\ProductInterface $entity
* The product entity.
* @param array $page
* The page array.
*/
function attachTrustamiCommentsWidgetScript(ProductInterface $entity, array &$page) {
$variations = $entity->getVariations();
$variation = reset($variations);
if ($variation) {
$trustamiProductWidgetScript = [
'#tag' => 'script',
'#attributes' => [
'type' => 'text/javascript',
'id' => 'trustami-product-widget',
'src' => 'https://cdn.trustami.com/widgetapi/productWidget/trustami-product-widget.js',
'data-uid' => '601e2fffcc96c5152b8b46de',
'data-gtin' => $variation->getSku(),
'data-asin' => $variation->get('field_asin')->value,
'data-modes' => "[4]",
],
'#value' => '',
];
// Add script to head.
$page['#attached']['html_head'][] = [
$trustamiProductWidgetScript,
'trustamiProductWidgetScript'
];
}
}
Comments