Skip to content

Instantly share code, notes, and snippets.

@nacin
Created August 13, 2011 22:44
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nacin/1144331 to your computer and use it in GitHub Desktop.
Save nacin/1144331 to your computer and use it in GitHub Desktop.
P2 Q&A Comments
<?php
/* Plugin Name: P2 Q&A Comments
* Description: Allows you to mark P2 comments as +1/-1 and as answered. Ideal for live Q&A sessions.
* Author: Andrew Nacin
* Author URI: http://andrewnacin.com/
*/
/* WARNING about studying and copying this code:
*
* P2 is not currently an ideal platform for developing extensions. Some of this
* plugin is hacky and may make kittens and core developers cry. It is not
* guaranteed to work as-is in a future version of P2. While I'll keep it updated
* to work, please do your best to avoid these techniques. Do as I say, not as I do.
*
* -- Nacin
*/
/**
* @package P2_QA_Comments
*/
class P2_QA_Comments {
static $instance;
/**
* Constructor. Saves instance and sets up initial hook.
*/
function __construct() {
self::$instance = $this;
add_action( 'after_setup_theme', array( $this, 'after_setup_theme' ) );
}
/**
* Sets up initial hooks, if the P2 theme is in play.
*/
function after_setup_theme() {
if ( ! class_exists( 'P2' ) )
return;
add_action( 'wp_head', array( $this, 'wp_head' ) );
add_action( 'wp_footer', array( $this, 'wp_footer' ) );
add_filter( 'comment_text', array( $this, 'comment_text' ), 9 );
add_filter( 'comment_class', array( $this, 'comment_class' ), 10, 3 );
add_action( 'admin_post_p2_qa_comments', array( $this, 'admin_post_p2_qa_comments' ) );
add_action( 'wp_ajax_p2_qa_polling', array( $this, 'wp_ajax_p2_qa_polling' ) );
}
function wp_ajax_p2_qa_polling() {
global $wpdb;
$post_id = absint( $_GET['p'] );
$results = $wpdb->get_results( $wpdb->prepare( "SELECT m.comment_id, m.meta_value FROM $wpdb->commentmeta m INNER JOIN $wpdb->comments c ON c.comment_ID = m.comment_id WHERE c.comment_post_ID = %d", $post_id ) );
echo json_encode( $results );
die();
}
/**
* Adds voting options to comments.
*/
function comment_text( $text, $comment = null ) {
if ( $comment === null )
$comment = $GLOBALS['comment'];
$id = $comment->comment_ID;
$meta = get_comment_meta( $id, '_p2_qa_comments', true );
if ( ! current_user_can( 'edit_published_posts' ) ) {
if ( 'answered' == $meta )
$text .= "\n\n" . '<div class="p2_qa_comments_links"><strong>Answered</strong></div>';
return $text;
}
$go = add_query_arg( array(
'action' => 'p2_qa_comments',
'comment' => $id,
'_wp_http_referer' => urlencode( stripslashes( $_SERVER['REQUEST_URI'] ) )
), admin_url( 'admin-post.php' ) );
$go = wp_nonce_url( $go, 'p2_qa_comments-' . $id );
$text .= "\n\n" . '<div class="p2_qa_comments_links"><a class="promote' . ( 'promote' == $meta ? ' current' : '' ) . '" href="' . esc_url( add_query_arg( array( 'qa' => 'promote' ), $go ) ) . '">Promote</a> ';
$text .= '<a class="demote' . ( 'demote' == $meta ? ' current' : '' ) . '" href="' . esc_url( add_query_arg( array( 'qa' => 'demote' ), $go ) ) . '">Demote</a> ';
$text .= '<a class="answered' . ( 'answered' == $meta ? ' current' : '' ) . '" href="' . esc_url( add_query_arg( array( 'qa' => 'answered' ), $go ) ) . '">Answered</a> ';
$text .= '<a class="zero" href="' . esc_url( add_query_arg( array( 'qa' => '0' ), $go ) ) . '">(Clear)</a></div>';
return $text;
}
function comment_class( $classes, $class, $comment_id = null ) {
if ( $comment_id === null )
$comment_id = $GLOBALS['comment']->comment_ID;
if ( ! is_single() )
return $classes;
$meta = get_comment_meta( $comment_id, '_p2_qa_comments', true );
if ( $meta !== false && $meta !== '0' )
$classes[] = 'p2-qa-' . $meta;
return $classes;
}
function admin_post_p2_qa_comments() {
$comment_id = absint( $_GET['comment'] );
if ( ! current_user_can( 'edit_published_posts' ) )
wp_die( __( "You can't do that.", 'p2-qa-comments' ) );
if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'p2_qa_comments-' . $comment_id ) )
wp_die( __( 'Did you intend to do this?', 'p2-qa-comments' ) );
$do = $_GET['qa'];
if ( ! in_array( $do, array( 'promote', 'demote', 'answered' ) ) )
$do = '0';
update_comment_meta( $comment_id, '_p2_qa_comments', $do );
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
wp_safe_redirect( wp_get_referer() );
die();
}
/**
* Drop in some CSS.
*/
function wp_head() {
echo "<style>
.p2_qa_comments_links a { margin: 0 5px }
.p2_qa_comments_links { margin-bottom: 10px; font-size: 13px }
.p2_qa_comments_links a.current { font-weight: bold; color: #000 }
.p2-qa-promote {
background: #eef9fc;
}
.p2-qa-promote > .children {
background: white;
}
.p2-qa-demote > *,
.p2-qa-answered > * {
opacity: 0.5;
}
.p2-qa-demote > .children,
.p2-qa-answered > .children {
opacity: 1;
}
</style>\n";
}
/**
* Drop in some JS.
*/
function wp_footer() {
?>
<script>
(function($){
$(document).ready( function() {
$('.p2_qa_comments_links a').click( function(e) {
e.preventDefault();
$.ajax({
url : $(this).attr('href'),
context : $(this),
success : function() {
$(this).parent().find('a').removeClass('current'); // self included, not siblings
$(this).closest('li').removeClass('p2-qa-promote p2-qa-demote p2-qa-answered').addClass( 'p2-qa-' + this[0].className );
if ( ! $(this).hasClass('zero') )
$(this).addClass('current');
}
});
});
<?php if ( is_single() ) : ?>
var p2QAPollForFormatting = function() {
$.ajax({
url : ajaxurl + '?action=p2_qa_polling&p=' + <?php echo get_the_ID(); ?>,
context : $(this),
success : function(data) {
data = $.parseJSON(data);
$.each( data, function ( index, value ) {
$('#comment-' + value.comment_id)
.removeClass('p2-qa-promote p2-qa-demote p2-qa-answered')
.addClass('p2-qa-' + value.meta_value)
.find('.p2_qa_comments_links').first()
.find('a').removeClass('current')
.filter('.' + value.meta_value)
.addClass('current');
});
}
});
};
window.setInterval( p2QAPollForFormatting, 10000 );
<?php endif; ?>
});
})(jQuery);
</script>
<?php
}
}
new P2_QA_Comments;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment