<?php

/**
 * bbPress Topic Widget
 *
 * Adds a widget which displays the topic list
 *
 * @since bbPress (r2653)
 *
 * @uses WP_Widget
 */
class yp_BBP_Topics_Widget extends WP_Widget {

  /**
   * bbPress Topic Widget
   *
   * Registers the topic widget
   *
   * @since bbPress (r2653)
   *
   * @uses apply_filters() Calls 'bbp_topics_widget_options' with the
   *                        widget options
   */
  public function __construct() {
    $widget_ops = apply_filters( 'bbp_topics_widget_options', array(
      'classname'   => 'widget_display_topics',
      'description' => __( 'A list of recent topics, sorted by popularity or freshness.', 'youplay' )
    ) );

    parent::__construct( false, __( '(bbPress) Recent Topics', 'youplay' ), $widget_ops );
  }

  /**
   * Register the widget
   *
   * @since bbPress (r3389)
   *
   * @uses register_widget()
   */
  public static function register_widget() {
    register_widget( 'yp_BBP_Topics_Widget' );
  }

  /**
   * Displays the output, the topic list
   *
   * @since bbPress (r2653)
   *
   * @param mixed $args
   * @param array $instance
   * @uses apply_filters() Calls 'bbp_topic_widget_title' with the title
   * @uses bbp_topic_permalink() To display the topic permalink
   * @uses bbp_topic_title() To display the topic title
   * @uses bbp_get_topic_last_active_time() To get the topic last active
   *                                         time
   * @uses bbp_get_topic_id() To get the topic id
   */
  public function widget( $args = array(), $instance = array() ) {

    // Get widget settings
    $settings = $this->parse_settings( $instance );

    // Typical WordPress filter
    $settings['title'] = apply_filters( 'widget_title',           $settings['title'], $instance, $this->id_base );

    // bbPress filter
    $settings['title'] = apply_filters( 'bbp_topic_widget_title', $settings['title'], $instance, $this->id_base );

    // How do we want to order our results?
    switch ( $settings['order_by'] ) {

      // Order by most recent replies
      case 'freshness' :
        $topics_query = array(
          'post_type'           => bbp_get_topic_post_type(),
          'post_parent'         => $settings['parent_forum'],
          'posts_per_page'      => (int) $settings['max_shown'],
          'post_status'         => array( bbp_get_public_status_id(), bbp_get_closed_status_id() ),
          'ignore_sticky_posts' => true,
          'no_found_rows'       => true,
          'meta_key'            => '_bbp_last_active_time',
          'orderby'             => 'meta_value',
          'order'               => 'DESC',
        );
        break;

      // Order by total number of replies
      case 'popular' :
        $topics_query = array(
          'post_type'           => bbp_get_topic_post_type(),
          'post_parent'         => $settings['parent_forum'],
          'posts_per_page'      => (int) $settings['max_shown'],
          'post_status'         => array( bbp_get_public_status_id(), bbp_get_closed_status_id() ),
          'ignore_sticky_posts' => true,
          'no_found_rows'       => true,
          'meta_key'            => '_bbp_reply_count',
          'orderby'             => 'meta_value',
          'order'               => 'DESC'
        );
        break;

      // Order by which topic was created most recently
      case 'newness' :
      default :
        $topics_query = array(
          'post_type'           => bbp_get_topic_post_type(),
          'post_parent'         => $settings['parent_forum'],
          'posts_per_page'      => (int) $settings['max_shown'],
          'post_status'         => array( bbp_get_public_status_id(), bbp_get_closed_status_id() ),
          'ignore_sticky_posts' => true,
          'no_found_rows'       => true,
          'order'               => 'DESC'
        );
        break;
    }

    // Note: private and hidden forums will be excluded via the
    // bbp_pre_get_posts_normalize_forum_visibility action and function.
    $widget_query = new WP_Query( $topics_query );

    // Bail if no topics are found
    if ( ! $widget_query->have_posts() ) {
      return;
    }

    echo wp_kses_post($args['before_widget']);

    if ( !empty( $settings['title'] ) ) {
      echo wp_kses_post($args['before_title'] . $settings['title'] . $args['after_title']);
    } ?>

    <ul class="block-content">

      <?php while ( $widget_query->have_posts() ) :

        $widget_query->the_post();
        $topic_id    = bbp_get_topic_id( $widget_query->post->ID );
        $author_link = '';

        // Maybe get the topic author
        if ( ! empty( $settings['show_user'] ) ) :
          $author_link = bbp_get_topic_author_link( array( 'post_id' => $topic_id, 'type' => 'both', 'size' => 14 ) );
        endif; ?>

        <li>
          <a class="bbp-forum-title" href="<?php bbp_topic_permalink( $topic_id ); ?>"><?php bbp_topic_title( $topic_id ); ?></a>

          <?php if ( ! empty( $author_link ) ) : ?>

            <?php printf( _x( 'by %1$s', 'widgets', 'youplay' ), '<span class="topic-author">' . $author_link . '</span>' ); ?>

          <?php endif; ?>

          <?php if ( ! empty( $settings['show_date'] ) ) : ?>

            <div><?php bbp_topic_last_active_time( $topic_id ); ?></div>

          <?php endif; ?>

        </li>

      <?php endwhile; ?>

    </ul>

    <?php echo wp_kses_post($args['after_widget']);

    // Reset the $post global
    wp_reset_postdata();
  }

  /**
   * Update the topic widget options
   *
   * @since bbPress (r2653)
   *
   * @param array $new_instance The new instance options
   * @param array $old_instance The old instance options
   */
  public function update( $new_instance = array(), $old_instance = array() ) {
    $instance                 = $old_instance;
    $instance['title']        = strip_tags( $new_instance['title'] );
    $instance['order_by']     = strip_tags( $new_instance['order_by'] );
    $instance['parent_forum'] = sanitize_text_field( $new_instance['parent_forum'] );
    $instance['show_date']    = (bool) $new_instance['show_date'];
    $instance['show_user']    = (bool) $new_instance['show_user'];
    $instance['max_shown']    = (int) $new_instance['max_shown'];

    // Force to any
    if ( !empty( $instance['parent_forum'] ) && !is_numeric( $instance['parent_forum'] ) ) {
      $instance['parent_forum'] = 'any';
    }

    return $instance;
  }

  /**
   * Output the topic widget options form
   *
   * @since bbPress (r2653)
   *
   * @param $instance Instance
   * @uses BBP_Topics_Widget::get_field_id() To output the field id
   * @uses BBP_Topics_Widget::get_field_name() To output the field name
   */
  public function form( $instance = array() ) {

    // Get widget settings
    $settings = $this->parse_settings( $instance ); ?>

    <p><label for="<?php echo esc_attr($this->get_field_id( 'title' )); ?>"><?php _e( 'Title:', 'youplay' ); ?> <input class="widefat" id="<?php echo esc_attr($this->get_field_id( 'title' )); ?>" name="<?php echo esc_attr($this->get_field_name( 'title' )); ?>" type="text" value="<?php echo esc_attr( $settings['title'] ); ?>" /></label></p>
    <p><label for="<?php echo esc_attr($this->get_field_id( 'max_shown' )); ?>"><?php _e( 'Maximum topics to show:', 'youplay' ); ?> <input class="widefat" id="<?php echo esc_attr($this->get_field_id( 'max_shown' )); ?>" name="<?php echo esc_attr($this->get_field_name( 'max_shown' )); ?>" type="text" value="<?php echo esc_attr( $settings['max_shown'] ); ?>" /></label></p>

    <p>
      <label for="<?php echo esc_attr($this->get_field_id( 'parent_forum' )); ?>"><?php _e( 'Parent Forum ID:', 'youplay' ); ?>
        <input class="widefat" id="<?php echo esc_attr($this->get_field_id( 'parent_forum' )); ?>" name="<?php echo esc_attr($this->get_field_name( 'parent_forum' )); ?>" type="text" value="<?php echo esc_attr( $settings['parent_forum'] ); ?>" />
      </label>

      <br />

      <small><?php _e( '"0" to show only root - "any" to show all', 'youplay' ); ?></small>
    </p>

    <p><label for="<?php echo esc_attr($this->get_field_id( 'show_date' )); ?>"><?php _e( 'Show post date:', 'youplay' ); ?> <input type="checkbox" id="<?php echo esc_attr($this->get_field_id( 'show_date' )); ?>" name="<?php echo esc_attr($this->get_field_name( 'show_date' )); ?>" <?php checked( true, $settings['show_date'] ); ?> value="1" /></label></p>
    <p><label for="<?php echo esc_attr($this->get_field_id( 'show_user' )); ?>"><?php _e( 'Show topic author:', 'youplay' ); ?> <input type="checkbox" id="<?php echo esc_attr($this->get_field_id( 'show_user' )); ?>" name="<?php echo esc_attr($this->get_field_name( 'show_user' )); ?>" <?php checked( true, $settings['show_user'] ); ?> value="1" /></label></p>

    <p>
      <label for="<?php echo esc_attr($this->get_field_id( 'order_by' )); ?>"><?php _e( 'Order By:', 'youplay' ); ?></label>
      <select name="<?php echo esc_attr($this->get_field_name( 'order_by' )); ?>" id="<?php echo esc_attr($this->get_field_name( 'order_by' )); ?>">
        <option <?php selected( $settings['order_by'], 'newness' ); ?> value="newness"><?php _e( 'Newest Topics', 'youplay' ); ?></option>
        <option <?php selected( $settings['order_by'], 'popular' ); ?> value="popular"><?php _e( 'Popular Topics', 'youplay' ); ?></option>
        <option <?php selected( $settings['order_by'], 'freshness' ); ?> value="freshness"><?php _e( 'Topics With Recent Replies', 'youplay' ); ?></option>
      </select>
    </p>

    <?php
  }

  /**
   * Merge the widget settings into defaults array.
   *
   * @since bbPress (r4802)
   *
   * @param $instance Instance
   * @uses bbp_parse_args() To merge widget options into defaults
   */
  public function parse_settings( $instance = array() ) {
    return bbp_parse_args( $instance, array(
      'title'        => __( 'Recent Topics', 'youplay' ),
      'max_shown'    => 5,
      'show_date'    => false,
      'show_user'    => false,
      'parent_forum' => 'any',
      'order_by'     => false
    ), 'topic_widget_settings' );
  }
}