<?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' ]; } }
Preview:
downloadDownload PNG
downloadDownload JPEG
downloadDownload SVG
Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!
Click to optimize width for Twitter