Skip to:
Content

BuddyPress.org

Opened 7 years ago

Last modified 6 years ago

#4535 new defect (bug)

Load More Button loads duplicates

Reported by: jtymann Owned by:
Milestone: Awaiting Contributions Priority: normal
Severity: normal Version:
Component: Activity Keywords: needs-patch
Cc:

Description

In the default buddypress theme/Activity Core there is a bug with the activity stream. If you load the activity stream. Then open up a new window, go to the site, and perform a few actions that create activities. If you go back to the original window and click 'load more' you will receive duplicate posts. This is highly noticeable on a site with multiple concurrent users creating activity.

Below is how I fixed the issue in a child theme of mine:

The concept of my changes is pretty simple, in addition to passing which page the user is on the id of the first post on the users page is passed as well. Then the sql is altered to take this into account.

javascript changes:
I added the line "'pag_first_post' : $(".activity-item:first").attr("id").split("-")[1]" (and a comma) to the following code. This passes the post id along with the load more request

/* Load more updates at the end of the page */
		if ( target.parent().hasClass('load-more') ) {
			jq("#content li.load-more").addClass('loading');

			if ( null == jq.cookie('bp-activity-oldestpage') )
				jq.cookie('bp-activity-oldestpage', 1, {
					path: '/'
				} );

			var oldest_page = ( jq.cookie('bp-activity-oldestpage') * 1 ) + 1;

			jq.post( ajaxurl, {
				action: 'activity_get_older_updates',
				'cookie': encodeURIComponent(document.cookie),
				'page': oldest_page,
				'pag_first_post' : $(".activity-item:first").attr("id").split("-")[1]
			},
			function(response)
			{
				jq("#content li.load-more").removeClass('loading');
				jq.cookie( 'bp-activity-oldestpage', oldest_page, {
					path: '/'
				} );
				jq("#content ul.activity-list").append(response.contents);

				target.parent().hide();
			}, 'json' );

			return false;
		}

ajax.php changes:
I added support to the function bp_dtheme_ajax_querystring to now handle this new parameter.

I added the lines:

	if ( ! empty( $_POST['pag_first_post'] ) && '-1' != $_POST['pag_first_post'] )
		$qs[] = 'pag_first_post=' . $_POST['pag_first_post'];

After the code

	if ( ! empty( $_POST['page'] ) && '-1' != $_POST['page'] )
		$qs[] = 'page=' . $_POST['page'];

Finally I added the following code to my functions.php file:

//Fix to correct load more duplicates
function ofa_activity_get_load_more_fix($prepared_sql, $select_sql, $from_sql, $where_sql, $sort, $pag_sql=false) {
	global $bp, $wpdb;
	$args = wp_parse_args(bp_ajax_querystring( 'activity' ));
	if($args['pag_first_post'] && $post_seed = (int)$args['pag_first_post']){
		if($pag_sql){
			$where_sql .= " AND a.id <= $post_seed";
			return $wpdb->prepare( "{$select_sql} {$from_sql} {$where_sql} ORDER BY a.date_recorded {$sort} {$pag_sql}");
		}
	}
	return $prepared_sql;
}
add_filter( 'bp_activity_get_user_join_filter', 'ofa_activity_get_load_more_fix', 10, 6 );

function ofa_activity_get_total_load_more_fix($prepared_sql, $select_sql, $from_sql, $where_sql, $sort) {
	global $bp, $wpdb;
	$args = wp_parse_args(bp_ajax_querystring( 'activity' ));
	if($args['pag_first_post'] && $post_seed = (int)$args['pag_first_post']){
		if($pag_sql){
			$where_sql .= " AND a.id <= $post_seed";
			return $wpdb->prepare( "SELECT count(a.id) FROM {$bp->activity->table_name} a {$index_hint_sql} {$where_sql} ORDER BY a.date_recorded {$sort}" );
		}
	}
	return $prepared_sql;
}
add_filter( 'ofa_activity_get_total_load_more_fix', '', 10, 5 );

Change History (3)

#1 @DJPaul
7 years ago

  • Milestone changed from Awaiting Review to 1.7

Need to check this, but I think I've seen it before.

#2 @johnjamesjacoby
7 years ago

  • Keywords needs-patch added
  • Milestone changed from 1.7 to 1.8

Happens all the time. Not a regression, and been around for years. Without a real patch, punting to 1.8.

#3 @boonebgorges
6 years ago

  • Milestone changed from 1.8 to Future Release

This issue has been partially addressed in r7116 / #4897. When creating new activity items via AJAX, duplicates are not returned. However, the OP's original scenario - leaving the window open and coming back to it later while items have been created elsewhere - will still cause duplicates.

Something like what's being suggested here would be a more general fix, but the implementation used here is designed for a plugin/theme. Filtering the activity query is fine for a plugin, but we would need to do something more systematic for BuddyPress. Something like an offset parameter for bp_has_activities() would do the trick.

Note: See TracTickets for help on using tickets.