Skip to content

Commit 97e8e28

Browse files
committed
Media: Enable Media Library infinite scrolling and add an opt-out user option.
Infinite scrolling in the Media Library grid is now enabled by default. Users can now opt out via a new "Infinite Scrolling" user option on the profile screen, labeled "Disable infinite scrolling in the Media Library grid view". The option is only shown to users with the `upload_files` capability, since the attachment grid is unreachable without it. Precedence is resolved as follows: the `media_library_infinite_scrolling` filter takes precedence over everything, so a hooked filter always wins. Absent a filter, the user's opt-out preference applies. Absent both, infinite scrolling defaults to enabled. Include unit tests covering persistence of the new user option and the filter, preference, and default precedence. Props tyxla, youknowriad, joedolson, sachinrajcp123. Fixes #65564. git-svn-id: https://develop.svn.wordpress.org/trunk@62632 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 712a6af commit 97e8e28

6 files changed

Lines changed: 94 additions & 4 deletions

File tree

src/wp-admin/includes/user.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ function edit_user( $user_id = 0 ) {
134134
if ( $update ) {
135135
$user->rich_editing = isset( $_POST['rich_editing'] ) && 'false' === $_POST['rich_editing'] ? 'false' : 'true';
136136
$user->syntax_highlighting = isset( $_POST['syntax_highlighting'] ) && 'false' === $_POST['syntax_highlighting'] ? 'false' : 'true';
137+
$user->infinite_scrolling = isset( $_POST['infinite_scrolling'] ) && 'false' === $_POST['infinite_scrolling'] ? 'false' : 'true';
137138
$user->admin_color = isset( $_POST['admin_color'] ) ? sanitize_text_field( $_POST['admin_color'] ) : 'modern';
138139
$user->show_admin_bar_front = isset( $_POST['admin_bar_front'] ) ? 'true' : 'false';
139140
}

src/wp-admin/user-edit.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,17 @@
376376
</td>
377377
</tr>
378378

379+
<?php if ( user_can( $profile_user, 'upload_files' ) ) : ?>
380+
<tr class="user-infinite-scrolling-wrap">
381+
<th scope="row"><?php _e( 'Infinite Scrolling' ); ?></th>
382+
<td>
383+
<label for="infinite_scrolling"><input name="infinite_scrolling" type="checkbox" id="infinite_scrolling" value="false" <?php checked( 'false', $profile_user->infinite_scrolling ); ?> />
384+
<?php _e( 'Disable infinite scrolling in the Media Library grid view' ); ?>
385+
</label>
386+
</td>
387+
</tr>
388+
<?php endif; ?>
389+
379390
<?php
380391
$languages = get_available_languages();
381392
$can_install_translations = current_user_can( 'install_languages' ) && wp_can_install_language_pack();

src/wp-includes/media.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5040,14 +5040,25 @@ function wp_enqueue_media( $args = array() ) {
50405040
);
50415041
}
50425042

5043+
$infinite_scrolling = true;
5044+
5045+
// A user can opt out of infinite scrolling via their profile's personal options.
5046+
if ( 'false' === get_user_option( 'infinite_scrolling' ) ) {
5047+
$infinite_scrolling = false;
5048+
}
5049+
50435050
/**
5044-
* Filters whether the Media Library grid has infinite scrolling. Default `false`.
5051+
* Filters whether the Media Library grid has infinite scrolling. Default `true`.
5052+
*
5053+
* This setting respects the current user's "Infinite Scrolling" personal
5054+
* option, but a filter callback takes precedence over that preference.
50455055
*
50465056
* @since 5.8.0
5057+
* @since 7.1.0 Changed default to `true` and introduced per-user opt-out of infinite scrolling.
50475058
*
5048-
* @param bool $infinite Whether the Media Library grid has infinite scrolling.
5059+
* @param bool $infinite_scrolling Whether the Media Library grid has infinite scrolling.
50495060
*/
5050-
$infinite_scrolling = apply_filters( 'media_library_infinite_scrolling', false );
5061+
$infinite_scrolling = apply_filters( 'media_library_infinite_scrolling', $infinite_scrolling );
50515062

50525063
$settings = array(
50535064
'tabs' => $tabs,

src/wp-includes/user.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2245,6 +2245,7 @@ function wp_insert_user( $userdata ) {
22452245
'description',
22462246
'rich_editing',
22472247
'syntax_highlighting',
2248+
'infinite_scrolling',
22482249
'comment_shortcuts',
22492250
'admin_color',
22502251
'use_ssl',
@@ -2509,6 +2510,8 @@ function wp_insert_user( $userdata ) {
25092510

25102511
$meta['syntax_highlighting'] = empty( $userdata['syntax_highlighting'] ) ? 'true' : $userdata['syntax_highlighting'];
25112512

2513+
$meta['infinite_scrolling'] = empty( $userdata['infinite_scrolling'] ) ? 'true' : $userdata['infinite_scrolling'];
2514+
25122515
$meta['comment_shortcuts'] = empty( $userdata['comment_shortcuts'] ) || 'false' === $userdata['comment_shortcuts'] ? 'false' : 'true';
25132516

25142517
$admin_color = empty( $userdata['admin_color'] ) ? 'modern' : $userdata['admin_color'];
@@ -3019,7 +3022,7 @@ function wp_create_user(
30193022
* @return string[] List of user keys to be populated in wp_update_user().
30203023
*/
30213024
function _get_additional_user_keys( $user ) {
3022-
$keys = array( 'first_name', 'last_name', 'nickname', 'description', 'rich_editing', 'syntax_highlighting', 'comment_shortcuts', 'admin_color', 'use_ssl', 'show_admin_bar_front', 'locale' );
3025+
$keys = array( 'first_name', 'last_name', 'nickname', 'description', 'rich_editing', 'syntax_highlighting', 'infinite_scrolling', 'comment_shortcuts', 'admin_color', 'use_ssl', 'show_admin_bar_front', 'locale' );
30233026
return array_merge( $keys, array_keys( wp_get_user_contact_methods( $user ) ) );
30243027
}
30253028

tests/phpunit/tests/media.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,69 @@ public function test_img_caption_shortcode_added() {
109109
$this->assertSame( 'img_caption_shortcode', $shortcode_tags['wp_caption'] );
110110
}
111111

112+
/**
113+
* Tests the precedence rules for the Media Library infinite scrolling setting.
114+
*
115+
* Infinite scrolling is enabled by default. A user can opt out via the
116+
* `infinite_scrolling` personal option, and the
117+
* `media_library_infinite_scrolling` filter takes precedence over both.
118+
*
119+
* @ticket 65564
120+
*
121+
* @covers ::wp_enqueue_media
122+
*/
123+
public function test_wp_enqueue_media_infinite_scrolling_precedence() {
124+
$user_id = self::factory()->user->create( array( 'role' => 'administrator' ) );
125+
wp_set_current_user( $user_id );
126+
127+
// Default: no user preference and no filter, infinite scrolling is enabled.
128+
$this->assertSame(
129+
1,
130+
$this->get_media_infinite_scrolling_setting(),
131+
'Infinite scrolling should be enabled by default.'
132+
);
133+
134+
// User preference: disabling it via the personal option turns it off.
135+
update_user_meta( $user_id, 'infinite_scrolling', 'false' );
136+
$this->assertSame(
137+
0,
138+
$this->get_media_infinite_scrolling_setting(),
139+
'The user preference should disable infinite scrolling.'
140+
);
141+
142+
// Filter precedence: a filter overrides the user preference.
143+
add_filter( 'media_library_infinite_scrolling', '__return_true' );
144+
$this->assertSame(
145+
1,
146+
$this->get_media_infinite_scrolling_setting(),
147+
'The filter should take precedence over the user preference.'
148+
);
149+
}
150+
151+
/**
152+
* Helper that runs wp_enqueue_media() and returns the computed
153+
* `infiniteScrolling` media view setting.
154+
*
155+
* @return int The infiniteScrolling setting: 1 when enabled, 0 when disabled.
156+
*/
157+
private function get_media_infinite_scrolling_setting() {
158+
// wp_enqueue_media() only runs once per request; reset the guard so it
159+
// can be invoked again for each scenario.
160+
unset( $GLOBALS['wp_actions']['wp_enqueue_media'] );
161+
162+
$infinite_scrolling = null;
163+
$capture = static function ( $settings ) use ( &$infinite_scrolling ) {
164+
$infinite_scrolling = $settings['infiniteScrolling'];
165+
return $settings;
166+
};
167+
168+
add_filter( 'media_view_settings', $capture );
169+
wp_enqueue_media();
170+
remove_filter( 'media_view_settings', $capture );
171+
172+
return $infinite_scrolling;
173+
}
174+
112175
public function test_img_caption_shortcode_with_empty_params() {
113176
$result = img_caption_shortcode( array() );
114177
$this->assertSame( '', $result );

tests/phpunit/tests/user.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ public function test_update_user() {
438438
'show_admin_bar_front' => 1,
439439
'rich_editing' => 1,
440440
'syntax_highlighting' => 1,
441+
'infinite_scrolling' => 'false', // See #65564.
441442
'first_name' => 'first',
442443
'last_name' => 'last',
443444
'nickname' => 'nick',

0 commit comments

Comments
 (0)