@@ -176,6 +176,71 @@ public function test_is_user_member_of_blog() {
176176 wp_set_current_user ( $ old_current );
177177 }
178178
179+ /**
180+ * Ensures the `is_user_member_of_blog` filter can override the return value
181+ * and receives the resolved user ID and blog ID.
182+ *
183+ * @ticket 65096
184+ *
185+ * @covers ::is_user_member_of_blog
186+ */
187+ public function test_is_user_member_of_blog_filter () {
188+ $ user_id = self ::factory ()->user ->create ();
189+ $ blog_id = self ::factory ()->blog ->create ();
190+
191+ // Sanity check: the user is not a member of the blog by default.
192+ $ this ->assertFalse ( is_user_member_of_blog ( $ user_id , $ blog_id ) );
193+
194+ $ filter_args = array ();
195+ $ filter = function ( $ is_member , $ filtered_user_id , $ filtered_blog_id ) use ( &$ filter_args ) {
196+ $ filter_args [] = array ( $ is_member , $ filtered_user_id , $ filtered_blog_id );
197+ return true ;
198+ };
199+
200+ add_filter ( 'is_user_member_of_blog ' , $ filter , 10 , 3 );
201+ $ result = is_user_member_of_blog ( $ user_id , $ blog_id );
202+
203+ $ this ->assertTrue ( $ result , 'Filter should be able to force a truthy return value. ' );
204+ $ this ->assertCount ( 1 , $ filter_args , 'Filter should run exactly once per call on a valid multisite blog. ' );
205+ $ this ->assertSame ( array ( false , $ user_id , $ blog_id ), $ filter_args [0 ], 'Filter should receive the computed membership, user ID, and blog ID. ' );
206+ }
207+
208+ /**
209+ * Ensures the `is_user_member_of_blog` filter is not invoked for requests
210+ * that short-circuit before the membership is computed.
211+ *
212+ * @ticket 65096
213+ *
214+ * @covers ::is_user_member_of_blog
215+ */
216+ public function test_is_user_member_of_blog_filter_not_called_for_invalid_input () {
217+ $ filter_calls = 0 ;
218+ $ filter = function ( $ is_member ) use ( &$ filter_calls ) {
219+ ++$ filter_calls ;
220+ return $ is_member ;
221+ };
222+
223+ add_filter ( 'is_user_member_of_blog ' , $ filter );
224+
225+ // No current user, and no user ID provided.
226+ $ old_current = get_current_user_id ();
227+ wp_set_current_user ( 0 );
228+ $ is_member = is_user_member_of_blog ();
229+ wp_set_current_user ( $ old_current );
230+ $ this ->assertFalse ( $ is_member , 'Filter should not run when no user ID was provided. ' );
231+
232+ // Unknown user ID.
233+ $ this ->assertFalse ( is_user_member_of_blog ( PHP_INT_MAX ), 'Filter should not run without a valid user ID. ' );
234+
235+ // Known user, but an archived/deleted/spam site short-circuits.
236+ $ user_id = self ::factory ()->user ->create ();
237+ $ blog_id = self ::factory ()->blog ->create ();
238+ update_blog_details ( $ blog_id , array ( 'archived ' => 1 ) );
239+ $ this ->assertFalse ( is_user_member_of_blog ( $ user_id , $ blog_id ) );
240+
241+ $ this ->assertSame ( 0 , $ filter_calls , 'Filter should not run when the function short-circuits before computing membership. ' );
242+ }
243+
179244 /**
180245 * @ticket 23192
181246 */
0 commit comments