5

Como Adicionar um Campo Extra nos Comentários do WordPress

Nesse artigo vou mostrar como adicionar um campo de avaliação do post nos comentários do WordPress. Nós vamos trabalhar com PHP para habilitar o novo campo e exibir ele no modelo dos comentários. Também vamos criar alguns estilos para o nosso sistema de avaliação. Para terminar, vamos criar um JavaScript usando jQuery para ativar o sistema.

Introdução

Nesse artigo vamos criar um sistema de avaliação em quatro passos:

  • Adicionar meta dados no comentário
  • Atualizar modelo dos comentários
  • Adicionar novos estilos CSS
  • Adicionar novo JavaScript
  • Como Exibir a Média das Avaliações (atualização)

Então vamos ao que interessa.

Meta Dados

A primeira coisa que precisamos fazer é abrir o arquivo functions.php do seu tema e adicionar o seguinte código:

add_action('comment_post','comment_ratings');

function comment_ratings($comment_id) {
    add_comment_meta($comment_id, 'rate', $_POST['rate']);
}

Como você pode ver é bem simples. Nós estamos adicionando a ação que será executada quando o comentário for postado. Dentro da função comment_ratings, nós estamos adicionando a nova informação aos meta dados do comentários. Nesse caso eu adicionei o campo rate com o valor que foi postado no campo com o mesmo nome.

Agora precisamos adicionar o campo rate no modelo dos comentários.

Modelo dos Comentários

Nós precisamos adicionar o campo em dois lugares: onde exibimos os comentários e onde o visitante digita seu comentário. Como já estamos no arquivo functions.php, vamos adicionar a seguinte função (é a mesma encontrada no WordPress Codex, mais o campo de avaliação):

function comment_template($comment, $args, $depth) {
    $GLOBALS['comment'] = $comment; ?>
    <li <?php comment_class(); ?> id="li-comment-<?php comment_ID() ?>">
        <div id="comment-<?php comment_ID(); ?>">
            <div class="comment-author vcard">
                <?php echo get_avatar($comment,$size='48'); ?>

                <?php printf(__('<cite class="fn">%s</cite> <span class="says">says:</span>'), get_comment_author_link()) ?>
            </div>

            <?php if ($comment->comment_approved == '0') : ?>
            <em><?php _e('Your comment is awaiting moderation.') ?></em>
            <br />
            <?php endif; ?>

            <div class="comment-meta commentmetadata"><a href="<?php echo htmlspecialchars( get_comment_link( $comment->comment_ID ) ) ?>"><?php printf(__('%1$s at %2$s'), get_comment_date(),  get_comment_time()) ?></a><?php edit_comment_link(__('(Edit)'),'  ','') ?></div>

            <?php
            $rate = get_comment_meta($comment->comment_ID, 'rate');
            if ($rate[0] <> '') {
                _e('Grade: ');
                echo movie_grade($rate[0]);
            }
            ?>

            <?php comment_text() ?>

            <div class="reply">
                <?php comment_reply_link(array_merge( $args, array('depth' => $depth, 'max_depth' => $args['max_depth']))) ?>
            </div>
        </div>
<?php
}

Essa função será usada para exibir a lista de comentários. Nós adicionamos a chamada para a função get_comment_meta que vai retornar um array com a informação. Se estiver vazia, não vamos mostrar nada. Caso contrário vamos usar a seguinte função para exibir a avaliação do visitante:

function movie_grade($grade) {
    switch ($grade) {
        case '0':
            $alt = 'Péssimo - 0 estrelas';
            break;
        case '1':
            $alt = 'Muito ruim - 1 estrela';
            break;
        case '2':
            $alt = 'Ruim - 2 estrelas';
            break;
        case '3':
            $alt = 'Bom - 3 estrelas';
            break;
        case '4':
            $alt = 'Muito bom - 4 estrelas';
            break;
        case '5':
            $alt = 'Excelente - 5 estrelas';
            break;
        default:
            $alt = 'Sem nota';
            break;
    }

    if (!isset($grade) || $grade == '')
        echo $alt;
    else {
        for ($i = 0; $i < 5; $i++) {
            if ($grade > $i)
                echo '<img src="'.get_stylesheet_directory_uri().'/images/star_on.png" alt="'.$alt.'" title="'.$alt.'" />';
            else
                echo '<img src="'.get_stylesheet_directory_uri().'/images/star_off.png" alt="'.$alt.'" title="'.$alt.'" />';
        }
    }
}

Nessa função estamos exibindo imagens de acordo com a avaliação. A última coisa que precisamos fazer para exibir a avaliação é utilizar nossa função na hora de exibir a lista de comentários no arquivo comments.php. Encontre a chamada para wp_list_comments e adicione o parâmetro ‘type=comment&callback=comment_template’. Deve ficar assim:

<?php wp_list_comments('type=comment&callback=comment_template'); ?>

Isso vai fazer com que a lista de comentários seja exibida usando a função comment_template que criamos anteriormente. Para completar com o modelo dos comentários precisamos atualizar a entrada dos comentários. Precisamos adicionar o campo para avaliação na entrada dos dados. Vamos adicionar alguns links e fazer um efeito usando CSS depois para deixar mais funcional.

<div>
    <div class="comment-rating">
        <ul class="star-rating">
            <li><a href="#" title="Péssimo - 0 estrelas" class="zero-star" onclick="rateClick(0); return false;">0</a></li>
            <li><a href="#" title="Muito ruim - 1 estrela" class="one-star" onclick="rateClick(1); return false;">1</a></li>
            <li><a href="#" title="Ruim - 2 estrelas" class="two-stars" onclick="rateClick(2); return false;">2</a></li>
            <li><a href="#" title="Bom - 3 estrelas" class="three-stars" onclick="rateClick(3); return false;">3</a></li>
            <li><a href="#" title="Muito bom - 4 estrelas" class="four-stars" onclick="rateClick(4); return false;">4</a></li>
            <li><a href="#" title="Excelente - 5 estrelas" class="five-stars" onclick="rateClick(5); return false;">5</a></li>
        </ul>
    </div>
    Sua avaliação
    <input type="hidden" name="rate" id="rate" value="<?php echo esc_attr($comment_author_rate); ?>" />
</div>

Agora vamos adicionar os estilos e o JavaScript para atualizar o input que criamos.

Novos Estilos CSS

Agora vamos criar os estilos usados no HTML. Esses estilos vão substituir os links por imagens e usar um efeito quando o mouse estiver sobre o link. Eu copie praticamente tudo do artigo Create a Star Rater using CSS. O CSS necessário é:

.comment-rating {float:left; width:180px;}
.star-rating,
.star-rating a:hover,
.star-rating a:active,
.star-rating a:focus,
.star-rating .current-rating{background: url(images/star.png) left -1000px repeat-x;}
.star-rating{position:relative;width:108px;height:25px;overflow:hidden;list-style:none;margin:0;padding:0;
             background-position: left top;}
.star-rating li{display: inline;}
.star-rating a,
.star-rating .current-rating{position:absolute;top:0;left:0;text-indent:-1000em;height:25px;line-height:25px;
                             outline:none;overflow:hidden;border: none;}
.star-rating a:hover,
.star-rating a:active,
.star-rating a:focus{background-position: left bottom;}
.star-rating a.one-star{width:34%;z-index:6;}
.star-rating a.two-stars{width:51%;z-index:5;}
.star-rating a.three-stars{width:68%;z-index:4;}
.star-rating a.four-stars{width:85%;z-index:3;}
.star-rating a.five-stars{width:100%;z-index:2;}
.star-rating .current-rating{z-index:1;background-position: left center;}
.star-rating a.zero-star {width:17%;z-index:8;background: url(images/no_star.png) left top no-repeat;}
.star-rating a.zero-star:hover,
.star-rating a.zero-star:active,
.star-rating a.zero-star:focus {background-position: left center;}
.star-rating a.zero-selected {background-position: left center;}

Eu defini um tamanho de 180px para todo o DIV. É uma rápida tentativa de alinhar tudo. No Crhome fica OK, mas não no Firefos. Você pode utilizar alguma outra técnica para alinhar. De qualquer maneira, você precisar das seguintes imagens:

Era possível utilizar menos imagens, mas eu fiquei com preguiça para atualizar tudo… Então, depois de criarmos as funções, atualizar o modelo e criar o CSS, só nos resta criar o JavaScript.

Novo JavaScript

Nós vamos usar jQuery aqui, então você precisa verificar se já está utilizando ele ou se precisa adicionar a referência no seu blog. No nosso arquivo js temos duas funções. Talvez não esteja muito otimizadas, mas funcionam ;-)

function clearSelected() {
    $('.star-rating a.zero-star').removeClass('zero-selected');
    $('.star-rating a.one-star').removeClass('current-rating');
    $('.star-rating a.two-stars').removeClass('current-rating');
    $('.star-rating a.three-stars').removeClass('current-rating');
    $('.star-rating a.four-stars').removeClass('current-rating');
    $('.star-rating a.five-stars').removeClass('current-rating');
}

function rateClick(num) {
    switch (num) {
        case 0:
            clearSelected();
            $('.star-rating a.zero-star').addClass('zero-selected');
            $('#rate').val('0');
            break;
        case 1:
            clearSelected();
            $('.star-rating a.one-star').addClass('current-rating');
            $('#rate').val('1');
            break;
        case 2:
            clearSelected();
            $('.star-rating a.two-stars').addClass('current-rating');
            $('#rate').val('2');
            break;
        case 3:
            clearSelected();
            $('.star-rating a.three-stars').addClass('current-rating');
            $('#rate').val('3');
            break;
        case 4:
            clearSelected();
            $('.star-rating a.four-stars').addClass('current-rating');
            $('#rate').val('4');
            break;
        case 5:
            clearSelected();
            $('.star-rating a.five-stars').addClass('current-rating');
            $('#rate').val('5');
            break;
    }
}

Na primeira função nós limpamos as classes que indicam a seleção dos links. Na segunda nós adicionamos a classe indicando a seleção a atualizamos o input com o valor correto.

Como Exibir a Média das Avaliações

Esta seção é uma atualização nesse artigo. Atualizado em 27 de Julho de 2011.

Algumas pessoas já haviam me perguntado sobre como fazer isso, então resolvi atualizar o artigo. Na realidade é bem simples calcular a média das avaliações dos comentários. Primeiro, precisamos adicionar a seguinte função no nosso arquivo functions.php:

function get_average_ratings($id) {
    $comment_array = get_approved_comments($id);
    $count = 1;

    if ($comment_array) { 
        $i = 0;
        $total = 0;
        foreach($comment_array as $comment){
            $rate = get_comment_meta($comment->comment_ID, 'rate');
            if(isset($rate[0]) && $rate[0] !== '') {
                $i++;
                $total += $rate[0];
            }
        }

        if($i == 0)
            return false;
        else
            return round($total/$i);
    } else {
        return false;
    }
}

Essa função vai buscar todos os comentários aprovados de acordo com o ID do post passado como parâmetro, percorrendo esses comentários e fazendo a soma total das avaliações. Serão somados apenas quando um valor for definido para a avaliação. Ou seja, caso um usuário não dê sua nota, o valor não será calculado. A função vai retornar a média das avaliações ou false, caso não existam comentários aprovados.

Posteriormente você pode chamar essa função no arquivo single.php. Você pode usar a função para verificar se existem avaliações. Se existirem, você pode usar a função movie_grade() para exibir as imagens corretamente. O código poderia ser algo assim:

<?php (get_average_ratings($post->ID))?movie_grade(get_average_ratings($post->ID)):'Não disponível'; ?>

Conclusão

Isso completa esse artigo. É possível utilizar o que mostrei aqui para criar qualquer tipo de entrada nos comentários. Dessa maneira você pode tornar não apenas seu blog único, mas também a discussão que ocorre nele. Aqui está uma tela do resultado (mais ou menos):

Sistema de avaliação

Sistema de avaliação

Share Button
Notice: get_the_author_ID está obsoleto desde a versão 2.8! Use get_the_author_meta('ID') em seu lugar. in /var/www/oscardias.com/br/wp-includes/functions.php on line 2908

Oscar Dias

Trabalho com desenvolvimento desde 2003 e já utilizei diversas linguagens de programação. Atualmente trabalho com PHP na minha empresa Softerize Sistemas.

5 Comments

  1. Oscar

    Adorei o post. Eu estava procurando por isso há algum tempo. Valeu!
    Eu só queria saber como faço para mostrar a média das avaliações….

    Obrigada

  2. Boa noite
    Gostaria de saber como colocar um campo no comentario.
    Por padrao ele é Nome, Email, Url e comentario, eu precisava de uma que fosse Nome e data do eventos e comentario.
    Se puder me ajudar agradeço

    Abraços

    • Opa,
      A parte de programação é bem simples e parecida com o que foi feito neste post. Seguindo a ordem deste post, você precisa adicionar a parte dos Meta Dados (utilizando campo que você precisa – ‘data_evento’), precisa criar o modelo dos comentários (exibindo a data ao invés das estrelas). Depois é só adicionar seu campo no comments.php, como um input. Depois você pode colocar um datepicker para escolher a data.
      Sei que a resposta veio tarde… Espero que ajude.
      Abraço

Deixe uma resposta

O seu endereço de email não será publicado Campos obrigatórios são marcados *