AnsPress_Reputation_Query()

Description #

User reputations loop Query wrapper for fetching reputations of a specific user by ID

Parameters #

  • $args
    array | string (Required) arguments passed to class. @param string $user_id WordPress user_id, default is current user_id @param integer $number Numbers of rows to fetch from database, default is 20 @param integer $offset Rows to offset

Source #

File: includes/reputation.php

class AnsPress_Reputation_Query {
	/**
	 * The loop iterator.
	 *
	 * @access public
	 * @var int
	 */
	public $current = -1;

	/**
	 * The number of rows returned by the paged query.
	 *
	 * @access public
	 * @var int
	 */
	public $count;

	/**
	 * Array of users located by the query.
	 *
	 * @access public
	 * @var array
	 */
	public $reputations;

	/**
	 * The reputation object currently being iterated on.
	 *
	 * @access public
	 * @var object
	 */
	public $reputation;

	/**
	 * A flag for whether the loop is currently being iterated.
	 *
	 * @access public
	 * @var bool
	 */
	public $in_the_loop;

	/**
	 * The total number of rows matching the query parameters.
	 *
	 * @access public
	 * @var int
	 */
	public $total_count;

	/**
	 * Items to show per page
	 *
	 * @access public
	 * @var int
	 */
	public $per_page = 20;

	/**
	 * Total pages count.
	 *
	 * @var int
	 */
	public $total_pages = 1;

	/**
	 * Maximum numbers of pages.
	 *
	 * @var int
	 */
	public $max_num_pages = 0;

	/**
	 * Currently paginated page.
	 *
	 * @var int
	 */
	public $paged;

	/**
	 * Current offset.
	 *
	 * @var int
	 */
	public $offset;

	/**
	 * Array of items without any points.
	 *
	 * @var array
	 */
	public $with_zero_points = array();

	/**
	 * Reputation events.
	 *
	 * @var array
	 */
	public $events;

	/**
	 * Ids for prefetching.
	 *
	 * @var array
	 */
	public $ids = array(
		'post'     => array(),
		'comment'  => array(),
		'question' => array(),
		'answer'   => array(),
	);

	/**
	 * Position.
	 *
	 * @var array
	 */
	public $pos = array();

	/**
	 * Arguments.
	 *
	 * @var array
	 */
	public $args = array();

	/**
	 * Initialize the class.
	 *
	 * @param array $args Arguments.
	 */
	public function __construct( $args = array() ) {
		$this->events = ap_get_reputation_events();
		$this->get_events_with_zero_points();

		$this->paged  = isset( $args['paged'] ) ? (int) $args['paged'] : 1;
		$this->offset = $this->per_page * ( $this->paged - 1 );

		$this->args = wp_parse_args(
			$args,
			array(
				'user_id' => 0,
				'number'  => $this->per_page,
				'offset'  => $this->offset,
				'order'   => 'DESC',
			)
		);

		$this->per_page = $this->args['number'];
		$this->query();
	}

	/**
	 * Get events having zero points.
	 */
	public function get_events_with_zero_points() {
		foreach ( (array) $this->events as $slug => $args ) {
			if ( 0 === $args['points'] ) {
				$this->with_zero_points[] = $slug;
			}
		}
	}

	/**
	 * Prepare and fetch reputations from database.
	 */
	private function query() {
		global $wpdb;

		$order    = 'DESC' === $this->args['order'] ? 'DESC' : 'ASC';
		$excluded = sanitize_comma_delimited( $this->with_zero_points, 'str' );

		$not_in = '';
		if ( ! empty( $excluded ) ) {
			$not_in = " AND rep_event NOT IN({$excluded})";
		}

		$query = $wpdb->prepare( "SELECT SQL_CALC_FOUND_ROWS * FROM {$wpdb->ap_reputations} WHERE rep_user_id = %d{$not_in} ORDER BY rep_date {$order} LIMIT %d,%d", $this->args['user_id'], $this->offset, $this->per_page ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared

		$result            = $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB
		$this->total_count = $wpdb->get_var( apply_filters( 'ap_reputations_found_rows', 'SELECT FOUND_ROWS()', $this ) ); // phpcs:ignore WordPress.DB
		$this->reputations = $result;
		$this->total_pages = ceil( $this->total_count / $this->per_page );
		$this->count       = count( $result );
		$this->prefetch();
	}

	/**
	 * Prefetch related items.
	 */
	public function prefetch() {
		foreach ( (array) $this->reputations as $key => $rep ) {
			$event = $this->events[ $rep->rep_event ];

			if ( ! isset( $this->ids[ $event['parent'] ] ) ) {
				$this->ids[ $event['parent'] ] = array();
			}

			$this->ids[ $event['parent'] ][]   = $rep->rep_ref_id;
			$this->reputations[ $key ]->parent = $event['parent'];
			$this->pos[ $rep->rep_ref_id ]     = $key;
		}

		$this->prefetch_posts();
		$this->prefetch_comments();
	}

	/**
	 * Pre fetch post contents and append to object.
	 */
	public function prefetch_posts() {
		global $wpdb;

		$ids = array_merge( $this->ids['post'], $this->ids['answer'], $this->ids['question'] );

		$ids = esc_sql( sanitize_comma_delimited( $ids ) );

		if ( ! empty( $ids ) ) {
			$posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} WHERE ID in ({$ids})" ); // phpcs:ignore WordPress.DB

			foreach ( (array) $posts as $_post ) {
				$this->reputations[ $this->pos[ $_post->ID ] ]->ref = $_post;
			}
		}
	}

	/**
	 * Pre fetch comments and append data to object.
	 */
	public function prefetch_comments() {
		global $wpdb;

		if ( empty( $this->ids['comment'] ) ) {
			return;
		}

		$ids      = esc_sql( sanitize_comma_delimited( $this->ids['comment'] ) );
		$comments = $wpdb->get_results( "SELECT * FROM {$wpdb->comments} WHERE comment_ID in ({$ids})" ); // phpcs:ignore WordPress.DB

		foreach ( (array) $comments as $_comment ) {
			$this->reputations[ $this->pos[ $_comment->comment_ID ] ]->ref = $_comment;
		}
	}

	/**
	 * Check if lopp has reputation.
	 *
	 * @return boolean
	 */
	public function have() {
		if ( $this->current + 1 < $this->count ) {
			return true;
		} elseif ( ( $this->current + 1 ) === $this->count ) {
			do_action( 'ap_reputations_loop_end' );
			// Do some cleaning up after the loop.
			$this->rewind_reputation();
		}

		$this->in_the_loop = false;
		return false;
	}

	/**
	 * Rewind the reputations and reset index.
	 */
	public function rewind_reputation() {
		$this->current = -1;
		if ( $this->count > 0 ) {
			$this->reputation = $this->reputations[0];
		}
	}
	/**
	 * Check if there are reputations.
	 *
	 * @return bool
	 */
	public function has() {
		if ( $this->count ) {
			return true;
		}

		return false;
	}

	/**
	 * Set up the next reputation and iterate index.
	 *
	 * @return object The next reputation to iterate over.
	 */
	public function next_reputation() {
		++$this->current;
		$this->reputation = $this->reputations[ $this->current ];
		return $this->reputation;
	}

	/**
	 * Set up the current reputation inside the loop.
	 */
	public function the_reputation() {
		$this->in_the_loop = true;
		$this->reputation  = $this->next_reputation();

		// Loop has just started.
		if ( 0 === $this->current ) {
			/**
			 * Fires if the current reputation is the first in the loop.
			 */
			do_action( 'ap_reputation_loop_start' );
		}
	}

	/**
	 * Return current reputation event.
	 *
	 * @return string
	 */
	public function get_event() {
		return $this->reputation->rep_event;
	}

	/**
	 * Echo current reputation event.
	 */
	public function the_event() {
		echo wp_kses_post( $this->get_event() );
	}

	/**
	 * Return current reputation points.
	 *
	 * @return integer
	 */
	public function get_points() {
		return ap_get_reputation_event_points( $this->reputation->rep_event );
	}

	/**
	 * Echo current reputation points.
	 * Alice of `get_points`.
	 */
	public function the_points() {
		echo esc_attr( $this->get_points() );
	}

	/**
	 * Return current reputation date date.
	 *
	 * @return string
	 */
	public function get_date() {
		return $this->reputation->rep_date;
	}

	/**
	 * Echo current reputation date.
	 */
	public function the_date() {
		echo esc_attr( ap_human_time( $this->get_date(), false ) );
	}

	/**
	 * Return current reputation icon.
	 *
	 * @return string
	 */
	public function get_icon() {
		return ap_get_reputation_event_icon( $this->reputation->rep_event );
	}

	/**
	 * Echo current reputation icon.
	 */
	public function the_icon() {
		echo esc_attr( $this->get_icon() );
	}

	/**
	 * Return current reputation activity.
	 *
	 * @return string
	 */
	public function get_activity() {
		return ap_get_reputation_event_activity( $this->reputation->rep_event );
	}

	/**
	 * Echo current reputation activity.
	 */
	public function the_activity() {
		echo wp_kses_post( $this->get_activity() );
	}

	/**
	 * Out put reference content.
	 */
	public function the_ref_content() {
		if ( in_array( $this->reputation->parent, array( 'post', 'question', 'answer' ), true ) ) {
			echo '<a class="ap-reputation-ref" href="' . esc_url( ap_get_short_link( array( 'ap_p' => $this->reputation->rep_ref_id ) ) ) . '">';

			if ( ! empty( $this->reputation->ref->post_title ) ) {
				echo '<strong>' . esc_html( $this->reputation->ref->post_title ) . '</strong>';
			}

			if ( ! empty( $this->reputation->ref->post_content ) ) {
				echo '<p>' . esc_html( ap_truncate_chars( wp_strip_all_tags( $this->reputation->ref->post_content ), 200 ) ) . '</p>';
			}

			echo '</a>';
		} elseif ( 'comment' === $this->reputation->parent ) {
			echo '<a class="ap-reputation-ref" href="' . esc_url( ap_get_short_link( array( 'ap_c' => $this->reputation->rep_ref_id ) ) ) . '">';
			if ( ! empty( $this->reputation->ref->comment_content ) ) {
				echo '<p>' . esc_html( ap_truncate_chars( wp_strip_all_tags( $this->reputation->ref->comment_content ), 200 ) ) . '</p>';
			}
			echo '</a>';
		}
	}
}

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Add your comment