Guia da Extensão #13 - Avaliação e Comentários
Como usar e inserir corretamente nos websites - requer a Extensão de Usuários #8
Essa extensão permite que usuários logados possam criar comentários com avaliação para, a princípio, páginas de produtos.
✅ Está na instalação padrão das lojas virtuais
⚠️ Só é usada para produtos
⚠️ Salvo uma aplicação específica no www.etalproduto.com.br - só é possível avaliar e comentar produtos após a "Entrega" após a compra e recebimento.
Sobre as configurações (e limitações atuais)
1) As avaliações são aplicadas nas páginas dos produtos, somente. O rating precisa estar associado à um item, no caso, ao produto.
2) Apesar de ter a chance de escolha, somente Estrelas está funcional;
3) Mesmo que possa escolher, todos os comentários precisam ser aprovados via painel;
4) O usuário pode enviar outro nome além do seu de usuário
5) O usuário poderá enviar telefone e e-mail (somente o site pode ver, outros usuários, não);
6) Habilitar notificações (apesar de estar presente, não há disparos);
Como utilizar
Função com o resumo de avaliações para um produto específico
//função que retorna falso caso não haja avaliações ou um array com a quantidade de avaliações e soma de todas as notas
$ratingStars = getproductRatingResume($productData['productId']);
Código que utiliza o resumo para imprimir es estrelas (é necessário usar o estilo CSS abaixo), mensagem e dados estruturados dos produtos com ou sem avaliaçãa$ratingResumeLabel = '';
//if $ratingStars is false
if($ratingStars == false) {
$ratingResumeLabel .= '<span ratingCommentRating><p><small>Produto ainda não avaliado.</small></p></span>';
if($productData['productPrice'] != '0.00') {
$item .= '<script type="application/ld+json">
{
"@context": "https://schema.org/",
"@type": "Product",
"name": "'.$productData['productTitle'].'",
"image": "'.$productData['productImg'].'",
"description": "'.$productData['productDescription'].'",
"sku": "'.$productData['productSKU'].'",
"brand": {
"@type": "Brand",
"name": "'.$productData['brandName'].'"
},
"offers": {
"@type": "Offer",
"url": "https://'.$mainData['siteDomain'].''.$mainData['configPath'].'/item/'.$productData['productUrl'].'",
"priceCurrency": "BRL",
"price": "'.$productPrice.'",
"availability": "https://schema.org/InStock",
"priceValidUntil": "'.date('c', strtotime('+5 years')).'"
}
}
</script>';
}
}
else {
$average = $ratingStars['ratingAggregateRating']/$ratingStars['ratingQuantity'];
$ratingResumeLabel .= '<span ratingCommentRating>';
//show the stars
for($i = 1; $i <= 5; $i++) {
if($i <= $average) {
$ratingResumeLabel .= '<span class="ratingResumeStar resumeActiveRatingStar"></span>';
}
else if($i > $average && $i < $average+1) {
$ratingResumeLabel .= '<span class="ratingResumeStar resumeHalfRatingStar"></span>';
}
else {
$ratingResumeLabel .= '<span class="ratingResumeStar"></span>';
}
}
$ratingResumeLabel .= '</span>';
$ratingResumeLabel .= '<p><small>Nota '.number_format($average, 1, ',', '.').' de 5 por '.$ratingStars['ratingQuantity'].' avaliações</small></p>';
if($productData['productPrice'] != '0.00') {
$item .= '<script type="application/ld+json">
{
"@context": "https://schema.org/",
"@type": "Product",
"name": "'.$productData['productTitle'].'",
"image": "'.$productData['productImg'].'",
"description": "'.$productData['productDescription'].'",
"sku": "'.$productData['productSKU'].'",
"brand": {
"@type": "Brand",
"name": "'.$productData['brandName'].'"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "'.$average.'",
"reviewCount": "'.$ratingStars['ratingQuantity'].'"
},
"offers": {
"@type": "Offer",
"url": "https://'.$mainData['siteDomain'].''.$mainData['configPath'].'/item/'.$productData['productUrl'].'",
"priceCurrency": "BRL",
"price": "'.$productPrice.'",
"availability": "https://schema.org/InStock",
"priceValidUntil": "'.date('c', strtotime('+5 years')).'"
}
}
</script>';
}
}
Função para carregar os comentários, réplicas da loja e avaliações individuais
$ratingComments = getProductRatingComments($productData['productId']);
Exemplo de aplicação e exibição na loja dos comentários com as respectivas notas (precisa do CSS descrito abaixo)
$ratingCommentsLabel = '';
//check if ratingComments is false
if($ratingComments == false) {
$ratingCommentsLabel .= '<p><small>Nenhum comentário sobre este produto.</small></p>';
}
else {
$ratingCommentsLabel .= '<h3>Comentários</h3>';
foreach($ratingComments as $k => $v) {
$ratingCommentsLabel .= '<div class="ratingCommentBox">
<div class="ratingCommentContent">
<div class="ratingCommentRating">';
//show the stars
for($i = 1; $i <= 5; $i++) {
if($i <= $v['ratingdetailsRating']) {
$ratingCommentsLabel .= '<span class="ratingResumeStar resumeActiveRatingStar"></span>';
}
else if($i > $v['ratingdetailsRating'] && $i < $v['ratingdetailsRating']+1) {
$ratingCommentsLabel .= '<span class="ratingResumeStar resumeHalfRatingStar"></span>';
}
else {
//empty star
$ratingCommentsLabel .= '<span class="ratingResumeStar"></span>';
}
}
$ratingCommentsLabel .= '</div>
<p class="ratingCommentText">'.nl2br($v['ratingdetailsComment']).'</p>
<p class="ratingCommentDate"><small>Comentado em '.date('d/m/Y H:i', strtotime($v['ratingdetailsDate'])).'</small></p>';
if($v['ratingdetailsReply'] != '') {
$ratingCommentsLabel .= '<div class="ratingCommentReply">
<p><small>Resposta da loja:</small></p>
<p>'.nl2br($v['ratingdetailsReply']).'</p>
</div>';
}
$ratingCommentsLabel .= '</div>
</div>';
}
}
Use o $ratingCommentsLabel onde deseja imprimir os resultados, por exemplo, abaixo da descrição do produto:
$item .= '</div>
<div class="row boxProductDescription">
<div class="col-12">
<h3>Descrição</h3>
<p class="productItemDescription">'.nl2br($richTextFilterData).'</p>
</div>
<div class="col-12">
'.$ratingCommentsLabel.'
</div>
</div>
</div>
</main>';
CSS padrão utilizado para exibir os comentários e, principalmente, exibir a estrelas cheias, meias estrelas ou vazias:
<!-- rating --><style> /* Desktop styles */ @media (min-width: 768px) { #ratingCommentName, #ratingCommentEmail, #ratingCommentPhone { width: 30%; } #ratingCommentTextArea { width: 100%; } } /* Mobile styles */ @media (max-width: 767px) { #ratingCommentName, #ratingCommentEmail, #ratingCommentPhone, #ratingCommentTextArea { width: 100%; } } .ratingCommentStar { cursor:pointer; font-size: 22px; margin: 2px 0; } /* Shake animation */ @keyframes shake { 0% { transform: translateX(0); } 20% { transform: translateX(-3px); } 40% { transform: translateX(3px); } 60% { transform: translateX(-1px); } 80% { transform: translateX(1px); } 100% { transform: translateX(0); } } #productRatingComment { background-color: white; padding: 20px; border-radius: 20px; } #ratingCommentTextArea { margin-top: 10px; border: 1px solid #c4c4c4; border-radius: 5px; padding: 8px; font-size: 16px; color: #333; } #ratingCommentName, #ratingCommentEmail, #ratingCommentPhone { margin-right: 15px; margin-top: 20px; border-radius: 5px; border: 1px solid #c4c4c4; padding: 12px; font-size: 16px; margin-bottom: 10px; } #ratingCommentConsentMessage { display: block; font-size: 11px; color: #555; margin:15px 0px; } #ratingCommentSendButton { background-color: #412293; color: white !important; padding: 8px 50px; margin-top: 10px; display: inline-block; border-radius: 5px; font-size: 18px; font-weight: bold; transition: 0.3s ease; cursor:pointer; } #ratingCommentFirstCommentLabel { display:block; margin-top:10px; } .ratingCommentStar { display:inline-flex; width:32px; height:32px; background-image:url(https://www.interago.com.br/App/Sites/416/mc/rating/starRatingEmpty.svg); background-size:contain; } .activeRatingStar { background-image:url(https://www.interago.com.br/App/Sites/416/mc/rating/starRating.svg); } .ratingResumeStar { display:inline-flex; width:24px; height:24px; background-size:contain; background-image:url(https://www.interago.com.br/App/Sites/416/mc/rating/starRatingEmpty.svg); } .resumeActiveRatingStar { background-image:url(https://www.interago.com.br/App/Sites/416/mc/rating/starRating.svg); } .resumeHalfRatingStar { background-image:url(https://www.interago.com.br/App/Sites/416/mc/rating/starRatingHalf.svg); } #ratingCommentRating { display:inline-flex; align-items:center; grid-gap:5px; } #ratingCommentInviteToRating { background-color: #ffa333; padding: 4px 16px; font-size: 12px; font-weight: bold; border-radius: 5px; margin-right: 5px; cursor: pointer; margin-left:10px; display:inline-block; } #ratingCommentFirstRatingLabel { color:#555; font-size:13px; } #ratingCommentTextAreaCounter { font-size:13px; display:block; } #ratingCommentTextAreaMessage { font-weight:bold; margin-left:10px; } #ratingCommentFirstCommentLabel { color:#555; font-size:13px; margin-top:30px; } #ratingCommentInviteUserToLogIn, #ratingCommentInviteUserToLogInOnComments { display: block; font-size: 14px; margin: 10px 0; background-color: #de1857; color: white; padding: 5px 20px; border-radius: 5px; font-weight: bold; width: fit-content; } #ratingCommentSendingMessage { display: block; color: #ffa332; margin: 10px; font-weight: bold; } #ratingCommentErrorMessage { display:block; color:red; font-weight:bold; margin:10px; } #ratingCommentSuccessfullSent { font-weight: normal; background-color: #e5fde5; padding: 10px; border-radius: 10px; } .ratingComment { background-color: white; padding: 10px; border-radius: 10px; margin-bottom: 30px; font-size: 13px; line-height: 18px; } .ratingCommentsStarsOnComments { display:block; margin-bottom:15px; } .ratingCommentsStarsOnComments .ratingResumeStar { width:18px; height:18px; }.ratingCommentBox {margin-bottom:20px; border-bottom:1px solid #dedede;}</style>