<?php
/**
 * class-decent-comments-widget.php
 * 
 * Copyright (c) 2011 "kento" Karim Rahimpur www.itthinx.com
 * 
 * This code is released under the GNU General Public License.
 * See COPYRIGHT.txt and LICENSE.txt.
 * 
 * This code is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * This header and all notices must be kept intact.
 * 
 * @author Karim Rahimpur
 * @package decent-comments
 * @since decent-comments 1.0.0
 * @link http://codex.wordpress.org/Widgets_API#Developing_Widgets
 */

/**
 * Versatile comments widget.
 */
class Decent_Comments_Widget extends WP_Widget {
	
	/**
	 * @var string cache id
	 */
	static $cache_id = 'decent_comments_widget';
	
	/**
	 * @var string cache flag
	 */
	static $cache_flag = 'widget';
	
	/**
	 * Initialize class.
	 */
	static function init() {
		if ( !has_action( 'wp_print_styles', array( 'Decent_Comments_Widget', '_wp_print_styles' ) ) ) {
			add_action( 'wp_print_styles', array( 'Decent_Comments_Widget', '_wp_print_styles' ) );
		}
		if ( !has_action( 'comment_post', array( 'Decent_Comments_Widget', 'cache_delete' ) ) ) {
			add_action( 'comment_post', array( 'Decent_Comments_Widget', 'cache_delete' ) );
		}
		if ( !has_action( 'transition_comment_status', array( 'Decent_Comments_Widget', 'cache_delete' ) ) ) {
			add_action( 'transition_comment_status', array( 'Decent_Comments_Widget', 'cache_delete' ) );
		}
	}
	
	/**
	 * Creates a Decent Comments widget.
	 */
	function Decent_Comments_Widget() {
		parent::WP_Widget( false, $name = 'Decent Comments' );
	}
	
	/**
	 * Clears cached comments.
	 */
	static function cache_delete() {
		wp_cache_delete( self::$cache_id, self::$cache_flag );
	}
	
	/**
	 * Enqueue styles if at least one widget is used.
	 */
	static function _wp_print_styles() {
		global $wp_registered_widgets, $DC_version;
		foreach ( $wp_registered_widgets as $widget ) {
			if ( $widget['name'] == 'Decent Comments' ) {
				//wp_enqueue_style( 'decent-comments-widget', DC_PLUGIN_URL . 'css/decent-comments-widget.css', array(), $DC_version );
				break;
			}
		}
	}
	
	/**
	 * Widget output
	 * 
	 * @see WP_Widget::widget()
	 */
	function widget( $args, $instance ) {
				
		// Note that there won't be any efficient caching unless a persistent
		// caching mechanism is used. WordPress' default cache is persistent
		// during a request only so this won't have any effect on our widget
		// unless it were printed twice on a page - and that won't happen as
		// each widget is different and cached by its own id.
		// @see http://codex.wordpress.org/Class_Reference/WP_Object_Cache
		$cache = wp_cache_get( self::$cache_id, self::$cache_flag );
		if ( ! is_array( $cache ) ) {
			$cache = array();
		}
		if ( isset( $cache[$args['widget_id']] ) ) {
			echo $cache[$args['widget_id']];
			return;
		}
		
		extract( $args );

		$title = apply_filters( 'widget_title', $instance['title'] );
		
		$widget_id = $args['widget_id'];
		
		// output
		$output = '';
		$output .= $before_widget;
		if ( !empty( $title ) ) {
			$output .= $before_title . $title . $after_title;
		}
		$output .= Decent_Comments_Renderer::get_comments( $instance );
		$output .= $after_widget;
		echo $output;
		
		$cache[$args['widget_id']] = $output;
		wp_cache_set( self::$cache_id, $cache, self::$cache_flag );
	}
		
	/**
	 * Save widget options
	 * 
	 * @see WP_Widget::update()
	 */
	function update( $new_instance, $old_instance ) {
		
		global $wpdb;
		
		$settings = $old_instance;
		
		// title
		$settings['title'] = strip_tags( $new_instance['title'] );
		
		// number		
		$number = intval( $new_instance['number'] );
		if ( $number > 0 ) {
			$settings['number'] = $number;
		}
		
		// orderby
		$orderby = $new_instance['orderby'];
		if ( key_exists( $orderby, Decent_Comments_Renderer::$orderby_options ) ) {
			$settings['orderby'] = $orderby;
		} else {
			unset( $settings['orderby'] );
		}
		
		// order
		$order = $new_instance['order'];
		if ( key_exists( $order, Decent_Comments_Renderer::$order_options ) ) {
			$settings['order'] = $order;
		} else {
			unset( $settings['order'] );
		}
		
		// post_id
		$post_id = $new_instance['post_id'];
		if ( empty( $post_id ) ) {
			unset( $settings['post_id'] );
		} else if ( ("[current]" == $post_id ) || ("{current}" == $post_id ) )  {
			$settings['post_id'] = "{current}";
		} else if ( $post = get_post( $post_id ) ) {
			$settings['post_id'] = $post->ID;
		} else if ( $post = Decent_Comments_Helper::get_post_by_title( $post_id ) ) {
			$settings['post_id'] = $post->ID;
		}
		
		// excerpt
		$settings['excerpt'] = !empty( $new_instance['excerpt'] );
		
		// max_excerpt_words
		$max_excerpt_words = intval( $new_instance['max_excerpt_words'] );
		if ( $max_excerpt_words > 0 ) {
			$settings['max_excerpt_words'] = $max_excerpt_words;
		}
		
		// ellipsis
		$settings['ellipsis'] = strip_tags( $new_instance['ellipsis'] );
		
		// show_author
		$settings['show_author'] = !empty( $new_instance['show_author'] );
		
		// show_avatar
		$settings['show_avatar'] = !empty( $new_instance['show_avatar'] );
		
		// avatar_size
		$avatar_size = intval( $new_instance['avatar_size'] );
		if ( $avatar_size > 0 ) {
			$settings['avatar_size'] = $avatar_size;
		}
		
		// show_link
		$settings['show_link'] = !empty( $new_instance['show_link'] );
		
		// show_comment
		$settings['show_comment'] = !empty( $new_instance['show_comment'] );
		
		// accept terms on a taxonomy
		// this only allows terms if there is a taxonomy
		if ( isset( $new_instance['taxonomy'] ) ) {
			if ( $taxonomy = get_taxonomy( $new_instance['taxonomy'] ) ) {
				$settings['taxonomy'] = $new_instance['taxonomy'];
				if ( isset( $new_instance['terms'] ) ) {
					// let's see if those slugs are ok
					$slugs = explode( ",", $new_instance['terms'] );
					$slugs_ = array();
					foreach( $slugs as $slug ) {
						$slug = trim( $slug );
						$slug_ = $wpdb->get_var( $wpdb->prepare( "SELECT slug FROM $wpdb->terms LEFT JOIN $wpdb->term_taxonomy ON $wpdb->terms.term_id = $wpdb->term_taxonomy.term_id WHERE slug = %s AND taxonomy = %s", $slug, $new_instance['taxonomy'] ) );
						if ( $slug_ === $slug ) {
							$slugs_[] = $slug;
						}
					}
					if ( count( $slugs_ ) > 0 ) {
						$settings['terms'] = implode( ",", $slugs_ );
					} else {
						unset( $settings['terms'] );
					}
				}
			} else {
				unset( $settings['taxonomy'] );
			}
		}

		$this->cache_delete();
		
		return $settings;
	}
	
	/**
	 * Output admin widget options form
	 * 
	 * @see WP_Widget::form()
	 */
	function form( $instance ) {
		
		extract( Decent_Comments_Renderer::$defaults );
		
		// title
		$title = isset( $instance['title'] ) ? $instance['title'] : "";
		echo "<p>";
		echo '<label for="' .$this->get_field_id( 'title' ) . '">' . __( 'Title', TD ) . '</label>'; 
		echo '<input class="widefat" id="' . $this->get_field_id( 'title' ) . '" name="' . $this->get_field_name( 'title' ) . '" type="text" value="' . esc_attr( $title ) . '" />';
		echo '</p>';
		
		// number
		$number = isset( $instance['number'] ) ? intval( $instance['number'] ) : '';
		echo "<p>";
		echo '<label class="title" title="' . __( "The number of comments to show.", TD ) .'" for="' .$this->get_field_id( 'number' ) . '">' . __( 'Number of comments', TD ) . '</label>'; 
		echo '<input class="widefat" id="' . $this->get_field_id( 'number' ) . '" name="' . $this->get_field_name( 'number' ) . '" type="text" value="' . esc_attr( $number ) . '" />';
		echo '</p>';
		
		// orderby
		$orderby = isset( $instance['orderby'] ) ? $instance['orderby'] : '';
		echo '<p>';
		echo '<label class="title" title="' . __( "Sorting criteria.", TD ) .'" for="' .$this->get_field_id( 'orderby' ) . '">' . __( 'Order by ...', TD ) . '</label>';
		echo '<select class="widefat" name="' . $this->get_field_name( 'orderby' ) . '">';
		foreach ( Decent_Comments_Renderer::$orderby_options as $orderby_option_key => $orderby_option_name ) {
			$selected = ( $orderby_option_key == $orderby ? ' selected="selected" ' : "" );
			echo '<option ' . $selected . 'value="' . $orderby_option_key . '">' . $orderby_option_name . '</option>'; 
		}
		echo '</select>';
		echo '</p>';
		
		// order
		$order = isset( $instance['order'] ) ? $instance['order'] : '';
		echo '<p>';
		echo '<label class="title" title="' . __( "Sort order.", TD ) .'" for="' .$this->get_field_id( 'order' ) . '">' . __( 'Sort order', TD ) . '</label>';
		echo '<select class="widefat" name="' . $this->get_field_name( 'order' ) . '">';
		foreach ( Decent_Comments_Renderer::$order_options as $order_option_key => $order_option_name ) {
			$selected = ( $order_option_key == $order ? ' selected="selected" ' : "" );
			echo '<option ' . $selected . 'value="' . $order_option_key . '">' . $order_option_name . '</option>'; 
		}
		echo '</select>';
		echo '</p>';
		
		// post_id
		$post_id = '';
		if ( isset( $instance['post_id'] ) ) {
			if ( ( '[current]' == strtolower( $instance['post_id'] ) ) || ( '{current}' == strtolower( $instance['post_id'] ) ) ) {
				$post_id = '{current}';
			} else {
				$post_id = $instance['post_id'];
			}
		}
		echo "<p>";
		echo '<label class="title" title="' . __( "Leave empty to show comments for all posts. To show comments for a specific post only, indicate either part of the title or the post ID. To show posts for the current post, indicate: [current]", TD ) . '" for="' .$this->get_field_id( 'post_id' ) . '">' . __( 'Post ID', TD ) . '</label>'; 
		echo '<input class="widefat" id="' . $this->get_field_id( 'post_id' ) . '" name="' . $this->get_field_name( 'post_id' ) . '" type="text" value="' . esc_attr( $post_id ) . '" />';
		echo '<br/>';
		echo '<span class="description">' . __( "Title, empty, post ID or [current]", TD ) . '</span>';
		if ( !empty( $post_id ) && ( $post_title = get_the_title( $post_id ) ) ) {
			echo '<br/>';
			echo '<span class="description"> ' . sprintf( __("Selected post: <em>%s</em>", TD ) , $post_title ) . '</span>';
		}
		echo '</p>';
        
		// excerpt
		$checked = ( ( ( !isset( $instance['excerpt'] ) && Decent_Comments_Renderer::$defaults['excerpt'] ) || ( $instance['excerpt'] === true ) ) ? 'checked="checked"' : '' );
		echo '<p>';
		echo '<input type="checkbox" ' . $checked . ' value="1" name="' . $this->get_field_name( 'excerpt' ) . '" />';
		echo '<label class="title" title="' . __( "If checked, shows an excerpt of the comment. Otherwise the full text of the comment is displayed.", TD ) .'" for="' . $this->get_field_id( 'excerpt' ) . '">' . __( 'Show comment excerpt', TD ) . '</label>';
		echo '</p>';
		
		// max_excerpt_words
		$max_excerpt_words = isset( $instance['max_excerpt_words'] ) ? intval( $instance['max_excerpt_words'] ) : '';
		echo "<p>";
		echo '<label class="title" title="' . __( "The maximum number of words shown in excerpts.", TD ) .'" for="' .$this->get_field_id( 'max_excerpt_words' ) . '">' . __( 'Number of words in excerpts', TD ) . '</label>'; 
		echo '<input class="widefat" id="' . $this->get_field_id( 'max_excerpt_words' ) . '" name="' . $this->get_field_name( 'max_excerpt_words' ) . '" type="text" value="' . esc_attr( $max_excerpt_words ) . '" />';
		echo '</p>';
		
		// ellipsis
		$ellipsis = isset( $instance['ellipsis'] ) ? $instance['ellipsis'] : '';
		echo "<p>";
		echo '<label class="title" title="' . __( "The ellipsis is shown after the excerpt when there is more content.", TD ) . '" for="' .$this->get_field_id( 'ellipsis' ) . '">' . __( 'Ellipsis', TD ) . '</label>'; 
		echo '<input class="widefat" id="' . $this->get_field_id( 'ellipsis' ) . '" name="' . $this->get_field_name( 'ellipsis' ) . '" type="text" value="' . esc_attr( $ellipsis ) . '" />';
		echo '</p>';

		// show_author
		$checked = ( ( ( !isset( $instance['show_author'] ) && Decent_Comments_Renderer::$defaults['show_author'] ) || ( $instance['show_author'] === true ) ) ? 'checked="checked"' : '' );
		echo '<p>';
		echo '<input type="checkbox" ' . $checked . ' value="1" name="' . $this->get_field_name( 'show_author' ) . '" />';
		echo '<label class="title" title="' . __( "Whether to show the author of each comment.", TD ) .'" for="' . $this->get_field_id( 'show_author' ) . '">' . __( 'Show author', TD ) . '</label>';
		echo '</p>';
		
		// show_avatar
		$checked = ( ( ( !isset( $instance['show_avatar'] ) && Decent_Comments_Renderer::$defaults['show_avatar'] ) || ( $instance['show_avatar'] === true ) ) ? 'checked="checked"' : '' );
		echo '<p>';
		echo '<input type="checkbox" ' . $checked . ' value="1" name="' . $this->get_field_name( 'show_avatar' ) . '" />';
		echo '<label class="title" title="' . __( "Show the avatar of the author.", TD ) .'" for="' . $this->get_field_id( 'show_avatar' ) . '">' . __( 'Show avatar', TD ) . '</label>';
		echo '</p>';

		// avatar size
		$avatar_size = isset( $instance['avatar_size'] ) ? intval( $instance['avatar_size'] ) : '';
		echo "<p>";
		echo '<label class="title" title="' . __( "The size of the avatar in pixels.", TD ) .'" for="' .$this->get_field_id( 'avatar_size' ) . '">' . __( 'Avatar size', TD ) . '</label>'; 
		echo '<input class="widefat" id="' . $this->get_field_id( 'avatar_size' ) . '" name="' . $this->get_field_name( 'avatar_size' ) . '" type="text" value="' . esc_attr( $avatar_size ) . '" />';
		echo '</p>';
		
		// show_link
		$checked = ( ( ( !isset( $instance['show_link'] ) && Decent_Comments_Renderer::$defaults['show_link'] ) || ( $instance['show_link'] === true ) ) ? 'checked="checked"' : '' );
		echo '<p>';
		echo '<input type="checkbox" ' . $checked . ' value="1" name="' . $this->get_field_name( 'show_link' ) . '" />';
		echo '<label class="title" title="' . __( "Show a link to the post that the comment applies to.", TD ) .'" for="' . $this->get_field_id( 'show_link' ) . '">' . __( 'Show link to post', TD ) . '</label>';
		echo '</p>';

		// show_comment
		$checked = ( ( ( !isset( $instance['show_comment'] ) && Decent_Comments_Renderer::$defaults['show_comment'] ) || ( $instance['show_comment'] === true ) ) ? 'checked="checked"' : '' );
		echo '<p>';
		echo '<input type="checkbox" ' . $checked . ' value="1" name="' . $this->get_field_name( 'show_comment' ) . '" />';
		echo '<label class="title" title="' . __( "Show an excerpt of the comment or the full comment.", TD ) .'" for="' . $this->get_field_id( 'show_comment' ) . '">' . __( 'Show the comment', TD ) . '</label>';
		echo '</p>';
		
		// taxonomy & terms
		$taxonomy = isset( $instance['taxonomy'] ) ? $instance['taxonomy'] : '';
		echo "<p>";
		echo '<label class="title" title="' . __( "A taxonomy, e.g. category or post_tag", TD ) .'" for="' .$this->get_field_id( 'taxonomy' ) . '">' . __( 'Taxonomy', TD ) . '</label>';
		echo '<input class="widefat" id="' . $this->get_field_id( 'taxonomy' ) . '" name="' . $this->get_field_name( 'taxonomy' ) . '" type="text" value="' . esc_attr( $taxonomy ) . '" />';
		echo '<br/>';
		echo '<span class="description">' . __( "Indicate <strong>category</strong> if you would like to show comments on posts in certain categories. Give the desired categories' slugs in <strong>Terms</strong>. For tags use <strong>post_tag</strong> and give the tags' slugs in <strong>Terms</strong>.", TD ) . '</span>';
		echo '</p>';
		
		$terms = '';
		if ( isset( $instance['terms'] ) ) {
			if ( ( '[current]' == strtolower( $instance['terms'] ) ) || ( '{current}' == strtolower( $instance['terms'] ) ) ) {
				$terms = '{current}';
			} else {
				$terms = $instance['terms'];
			}
		}
		echo "<p>";
		echo '<label class="title" title="' . __( "If a taxonomy is given , indicate terms in that taxonomy separated by comma to show comments for all posts related to these terms. To show comments on posts related to the same terms as the current post, indicate: {current}. If a taxonomy is given and terms is empty, no comments will be shown.", TD ) . '" for="' .$this->get_field_id( 'terms' ) . '">' . __( 'Terms', TD ) . '</label>';
		echo '<input class="widefat" id="' . $this->get_field_id( 'terms' ) . '" name="' . $this->get_field_name( 'terms' ) . '" type="text" value="' . esc_attr( $terms ) . '" />';
		echo '<br/>';
		echo '<span class="description">' . __( "Terms or {current}. A <strong>Taxonomy</strong> must be given.", TD ) . '</span>';
		echo '</p>';
		 
	}
}// class Decent_Comments_Widget

Decent_Comments_Widget::init();
register_widget( 'Decent_Comments_Widget' );
?>