-/**
- * WordPress Comment Query class.
- *
- * @since 3.1.0
- */
-class WP_Comment_Query {
- /**
- * Metadata query container
- *
- * @since 3.5.0
- * @access public
- * @var object WP_Meta_Query
- */
- public $meta_query = false;
-
- /**
- * Date query container
- *
- * @since 3.7.0
- * @access public
- * @var object WP_Date_Query
- */
- public $date_query = false;
-
- /**
- * Make private/protected methods readable for backwards compatibility.
- *
- * @since 4.0.0
- * @access public
- *
- * @param callable $name Method to call.
- * @param array $arguments Arguments to pass when calling.
- * @return mixed|bool Return value of the callback, false otherwise.
- */
- public function __call( $name, $arguments ) {
- return call_user_func_array( array( $this, $name ), $arguments );
- }
-
- /**
- * Execute the query
- *
- * @since 3.1.0
- *
- * @param string|array $query_vars
- * @return int|array
- */
- public function query( $query_vars ) {
- global $wpdb;
-
- $defaults = array(
- 'author_email' => '',
- 'fields' => '',
- 'ID' => '',
- 'karma' => '',
- 'number' => '',
- 'offset' => '',
- 'orderby' => '',
- 'order' => 'DESC',
- 'parent' => '',
- 'post_ID' => '',
- 'post_id' => 0,
- 'post_author' => '',
- 'post_name' => '',
- 'post_parent' => '',
- 'post_status' => '',
- 'post_type' => '',
- 'status' => '',
- 'type' => '',
- 'user_id' => '',
- 'search' => '',
- 'count' => false,
- 'meta_key' => '',
- 'meta_value' => '',
- 'meta_query' => '',
- 'date_query' => null, // See WP_Date_Query
- );
-
- $groupby = '';
-
- $this->query_vars = wp_parse_args( $query_vars, $defaults );
-
- // Parse meta query
- $this->meta_query = new WP_Meta_Query();
- $this->meta_query->parse_query_vars( $this->query_vars );
-
- /**
- * Fires before comments are retrieved.
- *
- * @since 3.1.0
- *
- * @param WP_Comment_Query &$this Current instance of WP_Comment_Query, passed by reference.
- */
- do_action_ref_array( 'pre_get_comments', array( &$this ) );
-
- // $args can be whatever, only use the args defined in defaults to compute the key
- $key = md5( serialize( wp_array_slice_assoc( $this->query_vars, array_keys( $defaults ) ) ) );
- $last_changed = wp_cache_get( 'last_changed', 'comment' );
- if ( ! $last_changed ) {
- $last_changed = microtime();
- wp_cache_set( 'last_changed', $last_changed, 'comment' );
- }
- $cache_key = "get_comments:$key:$last_changed";
-
- if ( $cache = wp_cache_get( $cache_key, 'comment' ) ) {
- return $cache;
- }
-
- $status = $this->query_vars['status'];
- if ( 'hold' == $status ) {
- $approved = "comment_approved = '0'";
- } elseif ( 'approve' == $status ) {
- $approved = "comment_approved = '1'";
- } elseif ( ! empty( $status ) && 'all' != $status ) {
- $approved = $wpdb->prepare( "comment_approved = %s", $status );
- } else {
- $approved = "( comment_approved = '0' OR comment_approved = '1' )";
- }
- $order = ( 'ASC' == strtoupper( $this->query_vars['order'] ) ) ? 'ASC' : 'DESC';
-
- if ( ! empty( $this->query_vars['orderby'] ) ) {
- $ordersby = is_array( $this->query_vars['orderby'] ) ?
- $this->query_vars['orderby'] :
- preg_split( '/[,\s]/', $this->query_vars['orderby'] );
-
- $allowed_keys = array(
- 'comment_agent',
- 'comment_approved',
- 'comment_author',
- 'comment_author_email',
- 'comment_author_IP',
- 'comment_author_url',
- 'comment_content',
- 'comment_date',
- 'comment_date_gmt',
- 'comment_ID',
- 'comment_karma',
- 'comment_parent',
- 'comment_post_ID',
- 'comment_type',
- 'user_id',
- );
- if ( ! empty( $this->query_vars['meta_key'] ) ) {
- $allowed_keys[] = $this->query_vars['meta_key'];
- $allowed_keys[] = 'meta_value';
- $allowed_keys[] = 'meta_value_num';
- }
- $ordersby = array_intersect( $ordersby, $allowed_keys );
- foreach ( $ordersby as $key => $value ) {
- if ( $value == $this->query_vars['meta_key'] || $value == 'meta_value' ) {
- $ordersby[ $key ] = "$wpdb->commentmeta.meta_value";
- } elseif ( $value == 'meta_value_num' ) {
- $ordersby[ $key ] = "$wpdb->commentmeta.meta_value+0";
- }
- }
- $orderby = empty( $ordersby ) ? 'comment_date_gmt' : implode(', ', $ordersby);
- } else {
- $orderby = 'comment_date_gmt';
- }
-
- $number = absint( $this->query_vars['number'] );
- $offset = absint( $this->query_vars['offset'] );
-
- if ( ! empty( $number ) ) {
- if ( $offset ) {
- $limits = 'LIMIT ' . $offset . ',' . $number;
- } else {
- $limits = 'LIMIT ' . $number;
- }
- } else {
- $limits = '';
- }
-
- if ( $this->query_vars['count'] ) {
- $fields = 'COUNT(*)';
- } else {
- switch ( strtolower( $this->query_vars['fields'] ) ) {
- case 'ids':
- $fields = "$wpdb->comments.comment_ID";
- break;
- default:
- $fields = "*";
- break;
- }
- }
-
- $join = '';
- $where = $approved;
-
- $post_id = absint( $this->query_vars['post_id'] );
- if ( ! empty( $post_id ) ) {
- $where .= $wpdb->prepare( ' AND comment_post_ID = %d', $post_id );
- }
-
- if ( '' !== $this->query_vars['author_email'] ) {
- $where .= $wpdb->prepare( ' AND comment_author_email = %s', $this->query_vars['author_email'] );
- }
-
- if ( '' !== $this->query_vars['karma'] ) {
- $where .= $wpdb->prepare( ' AND comment_karma = %d', $this->query_vars['karma'] );
- }
-
- if ( 'comment' == $this->query_vars['type'] ) {
- $where .= " AND comment_type = ''";
- } elseif( 'pings' == $this->query_vars['type'] ) {
- $where .= ' AND comment_type IN ("pingback", "trackback")';
- } elseif ( ! empty( $this->query_vars['type'] ) ) {
- $where .= $wpdb->prepare( ' AND comment_type = %s', $this->query_vars['type'] );
- }
-
- if ( '' !== $this->query_vars['parent'] ) {
- $where .= $wpdb->prepare( ' AND comment_parent = %d', $this->query_vars['parent'] );
- }
-
- if ( is_array( $this->query_vars['user_id'] ) ) {
- $where .= ' AND user_id IN (' . implode( ',', array_map( 'absint', $this->query_vars['user_id'] ) ) . ')';
- } elseif ( '' !== $this->query_vars['user_id'] ) {
- $where .= $wpdb->prepare( ' AND user_id = %d', $this->query_vars['user_id'] );
- }
-
- if ( '' !== $this->query_vars['search'] ) {
- $where .= $this->get_search_sql(
- $this->query_vars['search'],
- array( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_author_IP', 'comment_content' )
- );
- }
-
- $plucked = wp_array_slice_assoc( $this->query_vars, array( 'post_author', 'post_name', 'post_parent', 'post_status', 'post_type' ) );
- $post_fields = array_filter( $plucked );
-
- if ( ! empty( $post_fields ) ) {
- $join = "JOIN $wpdb->posts ON $wpdb->posts.ID = $wpdb->comments.comment_post_ID";
- foreach( $post_fields as $field_name => $field_value )
- $where .= $wpdb->prepare( " AND {$wpdb->posts}.{$field_name} = %s", $field_value );
- }
-
- if ( ! empty( $this->meta_query->queries ) ) {
- $clauses = $this->meta_query->get_sql( 'comment', $wpdb->comments, 'comment_ID', $this );
- $join .= $clauses['join'];
- $where .= $clauses['where'];
- $groupby = "{$wpdb->comments}.comment_ID";
- }
-
- $date_query = $this->query_vars['date_query'];
- if ( ! empty( $date_query ) && is_array( $date_query ) ) {
- $date_query_object = new WP_Date_Query( $date_query, 'comment_date' );
- $where .= $date_query_object->get_sql();
- }
-
- $pieces = array( 'fields', 'join', 'where', 'orderby', 'order', 'limits', 'groupby' );
- /**
- * Filter the comment query clauses.
- *
- * @since 3.1.0
- *
- * @param array $pieces A compacted array of comment query clauses.
- * @param WP_Comment_Query &$this Current instance of WP_Comment_Query, passed by reference.
- */
- $clauses = apply_filters_ref_array( 'comments_clauses', array( compact( $pieces ), &$this ) );
-
- $fields = isset( $clauses[ 'fields' ] ) ? $clauses[ 'fields' ] : '';
- $join = isset( $clauses[ 'join' ] ) ? $clauses[ 'join' ] : '';
- $where = isset( $clauses[ 'where' ] ) ? $clauses[ 'where' ] : '';
- $orderby = isset( $clauses[ 'orderby' ] ) ? $clauses[ 'orderby' ] : '';
- $order = isset( $clauses[ 'order' ] ) ? $clauses[ 'order' ] : '';
- $limits = isset( $clauses[ 'limits' ] ) ? $clauses[ 'limits' ] : '';
- $groupby = isset( $clauses[ 'groupby' ] ) ? $clauses[ 'groupby' ] : '';
-
- if ( $groupby ) {
- $groupby = 'GROUP BY ' . $groupby;
- }
- $query = "SELECT $fields FROM $wpdb->comments $join WHERE $where $groupby ORDER BY $orderby $order $limits";
-
- if ( $this->query_vars['count'] ) {
- return $wpdb->get_var( $query );
- }
-
- if ( 'ids' == $this->query_vars['fields'] ) {
- $this->comments = $wpdb->get_col( $query );
- return array_map( 'intval', $this->comments );
- }
-
- $results = $wpdb->get_results( $query );
- /**
- * Filter the comment query results.
- *
- * @since 3.1.0
- *
- * @param array $results An array of comments.
- * @param WP_Comment_Query &$this Current instance of WP_Comment_Query, passed by reference.
- */
- $comments = apply_filters_ref_array( 'the_comments', array( $results, &$this ) );
-
- wp_cache_add( $cache_key, $comments, 'comment' );
-
- return $comments;
- }
-
- /**
- * Used internally to generate an SQL string for searching across multiple columns
- *
- * @access protected
- * @since 3.1.0
- *
- * @param string $string
- * @param array $cols
- * @return string
- */
- protected function get_search_sql( $string, $cols ) {
- global $wpdb;
-
- $like = '%' . $wpdb->esc_like( $string ) . '%';
-
- $searches = array();
- foreach ( $cols as $col ) {
- $searches[] = $wpdb->prepare( "$col LIKE %s", $like );
- }
-
- return ' AND (' . implode(' OR ', $searches) . ')';
- }
-}
-