wp/wp-includes/class-wp-comment-query.php
changeset 16 a86126ab1dd4
parent 9 177826044cd9
child 18 be944660c56a
--- a/wp/wp-includes/class-wp-comment-query.php	Tue Oct 22 16:11:46 2019 +0200
+++ b/wp/wp-includes/class-wp-comment-query.php	Tue Dec 15 13:49:49 2020 +0100
@@ -28,7 +28,7 @@
 	 * Metadata query container
 	 *
 	 * @since 3.5.0
-	 * @var object WP_Meta_Query
+	 * @var WP_Meta_Query A meta query instance.
 	 */
 	public $meta_query = false;
 
@@ -69,7 +69,7 @@
 	 * Date query container
 	 *
 	 * @since 3.7.0
-	 * @var object WP_Date_Query
+	 * @var WP_Date_Query A date query instance.
 	 */
 	public $date_query = false;
 
@@ -118,13 +118,13 @@
 	 *
 	 * @since 4.0.0
 	 *
-	 * @param string   $name      Method to call.
-	 * @param array    $arguments Arguments to pass when calling.
+	 * @param string $name      Method to call.
+	 * @param array  $arguments Arguments to pass when calling.
 	 * @return mixed|false Return value of the callback, false otherwise.
 	 */
 	public function __call( $name, $arguments ) {
 		if ( 'get_search_sql' === $name ) {
-			return call_user_func_array( array( $this, $name ), $arguments );
+			return $this->get_search_sql( ...$arguments );
 		}
 		return false;
 	}
@@ -292,7 +292,7 @@
 			'meta_key'                  => '',
 			'meta_value'                => '',
 			'meta_query'                => '',
-			'date_query'                => null, // See WP_Date_Query
+			'date_query'                => null, // See WP_Date_Query.
 			'hierarchical'              => false,
 			'cache_domain'              => 'core',
 			'update_comment_meta_cache' => true,
@@ -360,7 +360,7 @@
 
 		$this->parse_query();
 
-		// Parse meta query
+		// Parse meta query.
 		$this->meta_query = new WP_Meta_Query();
 		$this->meta_query->parse_query_vars( $this->query_vars );
 
@@ -379,6 +379,31 @@
 			$this->meta_query_clauses = $this->meta_query->get_sql( 'comment', $wpdb->comments, 'comment_ID', $this );
 		}
 
+		$comment_data = null;
+
+		/**
+		 * Filter the comments data before the query takes place.
+		 *
+		 * Return a non-null value to bypass WordPress's default comment queries.
+		 *
+		 * The expected return type from this filter depends on the value passed in the request query_vars.
+		 * When `$this->query_vars['count']` is set, the filter should return the comment count as an int.
+		 * When `'ids' === $this->query_vars['fields']`, the filter should return an array of comment IDs.
+		 * Otherwise the filter should return an array of WP_Comment objects.
+		 *
+		 * @since 5.3.0
+		 *
+		 * @param array|int|null   $comment_data Return an array of comment data to short-circuit WP's comment query,
+		 *                                       the comment count as an integer if `$this->query_vars['count']` is set,
+		 *                                       or null to allow WP to run its normal queries.
+		 * @param WP_Comment_Query $this         The WP_Comment_Query instance, passed by reference.
+		 */
+		$comment_data = apply_filters_ref_array( 'comments_pre_query', array( $comment_data, &$this ) );
+
+		if ( null !== $comment_data ) {
+			return $comment_data;
+		}
+
 		/*
 		 * Only use the args defined in the query_var_defaults to compute the key,
 		 * but ignore 'fields', which does not affect query results.
@@ -419,7 +444,7 @@
 
 		$comment_ids = array_map( 'intval', $comment_ids );
 
-		if ( 'ids' == $this->query_vars['fields'] ) {
+		if ( 'ids' === $this->query_vars['fields'] ) {
 			$this->comments = $comment_ids;
 			return $this->comments;
 		}
@@ -429,7 +454,8 @@
 		// Fetch full comment objects from the primed cache.
 		$_comments = array();
 		foreach ( $comment_ids as $comment_id ) {
-			if ( $_comment = get_comment( $comment_id ) ) {
+			$_comment = get_comment( $comment_id );
+			if ( $_comment ) {
 				$_comments[] = $_comment;
 			}
 		}
@@ -454,7 +480,7 @@
 		 */
 		$_comments = apply_filters_ref_array( 'the_comments', array( $_comments, &$this ) );
 
-		// Convert to WP_Comment instances
+		// Convert to WP_Comment instances.
 		$comments = array_map( 'get_comment', $_comments );
 
 		if ( $this->query_vars['hierarchical'] ) {
@@ -490,7 +516,7 @@
 		}
 
 		// 'any' overrides other statuses.
-		if ( ! in_array( 'any', $statuses ) ) {
+		if ( ! in_array( 'any', $statuses, true ) ) {
 			foreach ( $statuses as $status ) {
 				switch ( $status ) {
 					case 'hold':
@@ -524,13 +550,18 @@
 			$unapproved_ids    = array();
 			$unapproved_emails = array();
 			foreach ( $include_unapproved as $unapproved_identifier ) {
-				// Numeric values are assumed to be user ids.
+				// Numeric values are assumed to be user IDs.
 				if ( is_numeric( $unapproved_identifier ) ) {
 					$approved_clauses[] = $wpdb->prepare( "( user_id = %d AND comment_approved = '0' )", $unapproved_identifier );
-
+				} else {
 					// Otherwise we match against email addresses.
-				} else {
-					$approved_clauses[] = $wpdb->prepare( "( comment_author_email = %s AND comment_approved = '0' )", $unapproved_identifier );
+					if ( ! empty( $_GET['unapproved'] ) && ! empty( $_GET['moderation-hash'] ) ) {
+						// Only include requested comment.
+						$approved_clauses[] = $wpdb->prepare( "( comment_author_email = %s AND comment_approved = '0' AND comment_ID = %d )", $unapproved_identifier, (int) $_GET['unapproved'] );
+					} else {
+						// Include all of the author's unapproved comments.
+						$approved_clauses[] = $wpdb->prepare( "( comment_author_email = %s AND comment_approved = '0' )", $unapproved_identifier );
+					}
 				}
 			}
 		}
@@ -544,7 +575,7 @@
 			}
 		}
 
-		$order = ( 'ASC' == strtoupper( $this->query_vars['order'] ) ) ? 'ASC' : 'DESC';
+		$order = ( 'ASC' === strtoupper( $this->query_vars['order'] ) ) ? 'ASC' : 'DESC';
 
 		// Disable ORDER BY with 'none', an empty array, or boolean false.
 		if ( in_array( $this->query_vars['orderby'], array( 'none', array(), false ), true ) ) {
@@ -569,7 +600,7 @@
 					$_order   = $_value;
 				}
 
-				if ( ! $found_orderby_comment_id && in_array( $_orderby, array( 'comment_ID', 'comment__in' ) ) ) {
+				if ( ! $found_orderby_comment_id && in_array( $_orderby, array( 'comment_ID', 'comment__in' ), true ) ) {
 					$found_orderby_comment_id = true;
 				}
 
@@ -708,7 +739,7 @@
 
 			foreach ( $_raw_types as $type ) {
 				switch ( $type ) {
-					// An empty translates to 'all', for backward compatibility
+					// An empty translates to 'all', for backward compatibility.
 					case '':
 					case 'all':
 						break;
@@ -716,6 +747,7 @@
 					case 'comment':
 					case 'comments':
 						$comment_types[ $operator ][] = "''";
+						$comment_types[ $operator ][] = "'comment'";
 						break;
 
 					case 'pings':
@@ -750,7 +782,7 @@
 			$this->sql_clauses['where']['user_id'] = $wpdb->prepare( 'user_id = %d', $this->query_vars['user_id'] );
 		}
 
-		// Falsy search strings are ignored.
+		// Falsey search strings are ignored.
 		if ( strlen( $this->query_vars['search'] ) ) {
 			$search_sql = $this->get_search_sql(
 				$this->query_vars['search'],
@@ -770,7 +802,9 @@
 			$join_posts_table = true;
 			foreach ( $post_fields as $field_name => $field_value ) {
 				// $field_value may be an array.
-				$esses                                     = array_fill( 0, count( (array) $field_value ), '%s' );
+				$esses = array_fill( 0, count( (array) $field_value ), '%s' );
+
+				// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
 				$this->sql_clauses['where'][ $field_name ] = $wpdb->prepare( " {$wpdb->posts}.{$field_name} IN (" . implode( ',', $esses ) . ')', $field_value );
 			}
 		}
@@ -791,7 +825,9 @@
 
 				$join_posts_table = true;
 
-				$esses                                     = array_fill( 0, count( $q_values ), '%s' );
+				$esses = array_fill( 0, count( $q_values ), '%s' );
+
+				// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
 				$this->sql_clauses['where'][ $field_name ] = $wpdb->prepare( " {$wpdb->posts}.{$field_name} IN (" . implode( ',', $esses ) . ')', $q_values );
 			}
 		}
@@ -950,8 +986,9 @@
 		$exclude_keys = array( 'parent', 'parent__in', 'parent__not_in' );
 		do {
 			// Parent-child relationships may be cached. Only query for those that are not.
-			$child_ids   = $uncached_parent_ids = array();
-			$_parent_ids = $levels[ $level ];
+			$child_ids           = array();
+			$uncached_parent_ids = array();
+			$_parent_ids         = $levels[ $level ];
 			foreach ( $_parent_ids as $parent_id ) {
 				$cache_key        = "get_comment_child_ids:$parent_id:$key:$last_changed";
 				$parent_child_ids = wp_cache_get( $cache_key, 'comment' );
@@ -1009,7 +1046,8 @@
 
 		// If a threaded representation was requested, build the tree.
 		if ( 'threaded' === $this->query_vars['hierarchical'] ) {
-			$threaded_comments = $ref = array();
+			$threaded_comments = array();
+			$ref               = array();
 			foreach ( $all_comments as $k => $c ) {
 				$_c = get_comment( $c->comment_ID );
 
@@ -1047,7 +1085,7 @@
 	 * @global wpdb $wpdb WordPress database abstraction object.
 	 *
 	 * @param string $string
-	 * @param array $cols
+	 * @param array  $cols
 	 * @return string
 	 */
 	protected function get_search_sql( $string, $cols ) {
@@ -1106,14 +1144,14 @@
 		}
 
 		$parsed = false;
-		if ( $orderby == $this->query_vars['meta_key'] || $orderby == 'meta_value' ) {
+		if ( $this->query_vars['meta_key'] === $orderby || 'meta_value' === $orderby ) {
 			$parsed = "$wpdb->commentmeta.meta_value";
-		} elseif ( $orderby == 'meta_value_num' ) {
+		} elseif ( 'meta_value_num' === $orderby ) {
 			$parsed = "$wpdb->commentmeta.meta_value+0";
-		} elseif ( $orderby == 'comment__in' ) {
+		} elseif ( 'comment__in' === $orderby ) {
 			$comment__in = implode( ',', array_map( 'absint', $this->query_vars['comment__in'] ) );
 			$parsed      = "FIELD( {$wpdb->comments}.comment_ID, $comment__in )";
-		} elseif ( in_array( $orderby, $allowed_keys ) ) {
+		} elseif ( in_array( $orderby, $allowed_keys, true ) ) {
 
 			if ( isset( $meta_query_clauses[ $orderby ] ) ) {
 				$meta_clause = $meta_query_clauses[ $orderby ];