@@ -1886,6 +1886,7 @@ public function set( $query_var, $value ) {
18861886 * database query.
18871887 *
18881888 * @since 1.5.0
1889+ * @since x.x.x Adds deterministic ordering to prevent duplicate records across pages.
18891890 *
18901891 * @global wpdb $wpdb WordPress database abstraction object.
18911892 *
@@ -2501,12 +2502,45 @@ public function get_posts() {
25012502 if ( isset ( $ query_vars ['orderby ' ] ) && ( is_array ( $ query_vars ['orderby ' ] ) || false === $ query_vars ['orderby ' ] ) ) {
25022503 $ orderby = '' ;
25032504 } else {
2504- $ orderby = "{$ wpdb ->posts }.post_date " . $ query_vars ['order ' ];
2505+ /*
2506+ * Ensure deterministic ordering to prevent duplicate records across pages.
2507+ * When multiple posts have the same value for a field, add ID as secondary sort to guarantee consistent ordering.
2508+ * Note: this is to circumvent a bug that is currently being tracked in https://core.trac.wordpress.org/ticket/44349.
2509+ */
2510+ $ orderby = "{$ wpdb ->posts }.post_date " . $ query_vars ['order ' ] . ', ' . "{$ wpdb ->posts }.ID " . $ query_vars ['order ' ];
25052511 }
25062512 } elseif ( 'none ' === $ query_vars ['orderby ' ] ) {
25072513 $ orderby = '' ;
25082514 } else {
2509- $ orderby_array = array ();
2515+ /*
2516+ * Ensure deterministic ordering to prevent duplicate records across pages.
2517+ * When multiple posts have the same value for a field, add ID as secondary sort to guarantee consistent ordering.
2518+ * Note: this is to circumvent a bug that is currently being tracked in https://core.trac.wordpress.org/ticket/44349.
2519+ */
2520+ $ fields_requiring_deterministic_orderby = array (
2521+ 'post_name ' ,
2522+ 'post_author ' ,
2523+ 'post_date ' ,
2524+ 'post_title ' ,
2525+ 'post_modified ' ,
2526+ 'post_mime_type ' ,
2527+ 'post_parent ' ,
2528+ 'post_type ' ,
2529+ 'name ' ,
2530+ 'author ' ,
2531+ 'date ' ,
2532+ 'title ' ,
2533+ 'modified ' ,
2534+ 'parent ' ,
2535+ 'type ' ,
2536+ 'menu_order ' ,
2537+ 'comment_count ' ,
2538+ );
2539+
2540+ $ orderby_array = array ();
2541+ $ needs_deterministic_orderby = false ;
2542+ $ has_id_orderby = false ;
2543+
25102544 if ( is_array ( $ query_vars ['orderby ' ] ) ) {
25112545 foreach ( $ query_vars ['orderby ' ] as $ _orderby => $ order ) {
25122546 $ orderby = addslashes_gpc ( urldecode ( $ _orderby ) );
@@ -2517,7 +2551,20 @@ public function get_posts() {
25172551 }
25182552
25192553 $ orderby_array [] = $ parsed . ' ' . $ this ->parse_order ( $ order );
2554+
2555+ // Check if this field needs deterministic ordering
2556+ if ( in_array ( $ _orderby , $ fields_requiring_deterministic_orderby , true ) ) {
2557+ $ needs_deterministic_orderby = true ;
2558+ } elseif ( 'ID ' === $ _orderby ) {
2559+ $ has_id_orderby = true ;
2560+ }
2561+ }
2562+
2563+ // Add ID as tie-breaker if needed and not already present
2564+ if ( $ needs_deterministic_orderby && ! $ has_id_orderby ) {
2565+ $ orderby_array [] = "{$ wpdb ->posts }.ID " . $ query_vars ['order ' ];
25202566 }
2567+
25212568 $ orderby = implode ( ', ' , $ orderby_array );
25222569
25232570 } else {
@@ -2532,11 +2579,21 @@ public function get_posts() {
25322579 }
25332580
25342581 $ orderby_array [] = $ parsed ;
2582+
2583+ // Check if this field needs deterministic ordering
2584+ if ( in_array ( $ orderby , $ fields_requiring_deterministic_orderby , true ) ) {
2585+ $ needs_deterministic_orderby = true ;
2586+ } elseif ( 'ID ' === $ orderby ) {
2587+ $ has_id_orderby = true ;
2588+ }
25352589 }
25362590 $ orderby = implode ( ' ' . $ query_vars ['order ' ] . ', ' , $ orderby_array );
25372591
25382592 if ( empty ( $ orderby ) ) {
2539- $ orderby = "{$ wpdb ->posts }.post_date " . $ query_vars ['order ' ];
2593+ $ orderby = "{$ wpdb ->posts }.post_date " . $ query_vars ['order ' ] . ', ' . "{$ wpdb ->posts }.ID " . $ query_vars ['order ' ];
2594+ } elseif ( $ needs_deterministic_orderby && ! $ has_id_orderby ) {
2595+ // Add ID as tie-breaker for deterministic ordering
2596+ $ orderby .= ", {$ wpdb ->posts }.ID " . $ query_vars ['order ' ];
25402597 } elseif ( ! empty ( $ query_vars ['order ' ] ) ) {
25412598 $ orderby .= " {$ query_vars ['order ' ]}" ;
25422599 }
0 commit comments