+function get_comments( $args = '' ) {
+ $query = new WP_Comment_Query;
+ return $query->query( $args );
+}
+
+/**
+ * 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
+ */
+ var $meta_query = false;
+
+ /**
+ * Execute the query
+ *
+ * @since 3.1.0
+ *
+ * @param string|array $query_vars
+ * @return int|array
+ */
+ function query( $query_vars ) {
+ global $wpdb;
+
+ $defaults = array(
+ 'author_email' => '',
+ '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' => '',
+ );
+
+ $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 );
+
+ do_action_ref_array( 'pre_get_comments', array( &$this ) );
+ extract( $this->query_vars, EXTR_SKIP );
+
+ // $args can be whatever, only use the args defined in defaults to compute the key
+ $key = md5( serialize( compact(array_keys($defaults)) ) );
+ $last_changed = wp_cache_get( 'last_changed', 'comment' );
+ if ( ! $last_changed )
+ $last_changed = wp_cache_set( 'last_changed', 1, 'comment' );
+ $cache_key = "get_comments:$key:$last_changed";
+
+ if ( $cache = wp_cache_get( $cache_key, 'comment' ) )
+ return $cache;
+
+ $post_id = absint($post_id);
+
+ 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($order) ) ? 'ASC' : 'DESC';
+
+ if ( ! empty( $orderby ) ) {
+ $ordersby = is_array($orderby) ? $orderby : preg_split('/[,\s]/', $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($number);
+ $offset = absint($offset);
+
+ if ( !empty($number) ) {
+ if ( $offset )
+ $limits = 'LIMIT ' . $offset . ',' . $number;
+ else
+ $limits = 'LIMIT ' . $number;
+ } else {
+ $limits = '';
+ }
+
+ if ( $count )
+ $fields = 'COUNT(*)';
+ else
+ $fields = '*';
+
+ $join = '';
+ $where = $approved;
+
+ if ( ! empty($post_id) )
+ $where .= $wpdb->prepare( ' AND comment_post_ID = %d', $post_id );
+ if ( '' !== $author_email )
+ $where .= $wpdb->prepare( ' AND comment_author_email = %s', $author_email );
+ if ( '' !== $karma )
+ $where .= $wpdb->prepare( ' AND comment_karma = %d', $karma );
+ if ( 'comment' == $type ) {
+ $where .= " AND comment_type = ''";
+ } elseif( 'pings' == $type ) {
+ $where .= ' AND comment_type IN ("pingback", "trackback")';
+ } elseif ( ! empty( $type ) ) {
+ $where .= $wpdb->prepare( ' AND comment_type = %s', $type );
+ }
+ if ( '' !== $parent )
+ $where .= $wpdb->prepare( ' AND comment_parent = %d', $parent );
+ if ( '' !== $user_id )
+ $where .= $wpdb->prepare( ' AND user_id = %d', $user_id );
+ if ( '' !== $search )
+ $where .= $this->get_search_sql( $search, array( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_author_IP', 'comment_content' ) );
+
+ $post_fields = array_filter( compact( array( 'post_author', 'post_name', 'post_parent', 'post_status', 'post_type', ) ) );
+ 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";
+ }
+
+ $pieces = array( 'fields', 'join', 'where', 'orderby', 'order', 'limits', 'groupby' );
+ $clauses = apply_filters_ref_array( 'comments_clauses', array( compact( $pieces ), &$this ) );
+ foreach ( $pieces as $piece )
+ $$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : '';
+
+ if ( $groupby )
+ $groupby = 'GROUP BY ' . $groupby;
+
+ $query = "SELECT $fields FROM $wpdb->comments $join WHERE $where $groupby ORDER BY $orderby $order $limits";
+
+ if ( $count )
+ return $wpdb->get_var( $query );
+
+ $comments = $wpdb->get_results( $query );
+ $comments = apply_filters_ref_array( 'the_comments', array( $comments, &$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
+ */
+ function get_search_sql( $string, $cols ) {
+ $string = esc_sql( like_escape( $string ) );
+
+ $searches = array();
+ foreach ( $cols as $col )
+ $searches[] = "$col LIKE '%$string%'";
+
+ return ' AND (' . implode(' OR ', $searches) . ')';