Skip to:
Content

BuddyPress.org

Opened 7 years ago

Closed 3 years ago

#5555 closed enhancement (maybelater)

Notification on favorite

Reported by: mpa4hu Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Toolbar & Notifications Keywords: needs-patch, trac-tidy-2018
Cc: mpa4hu@…

Description

What about sending internal notification to author when somebody favorites it.

I think this is expected behavior from plugin sending internal notifications when favorite happens.

+ maybe even internal notifications for comments?

I have code for those so tell me if you are interested and I can share it.

Change History (8)

#1 @boonebgorges
7 years ago

  • Keywords needs-patch added
  • Milestone changed from Awaiting Review to Future Release

Cool idea. Would like to see the code.

#2 @mpa4hu
7 years ago

@boonebgorges sorry for delay

I took some days to explore some other possibilities.

My previous code was based on Brajesh Singhs code introduced in http://buddydev.com/plugins/buddypress-activity-comment-notifier/

This is a hack with actions column and this is how I'm adding notification for favorite.
While its works, I don't think manipulating action column in core is a good idea.

bp_core_add_notification( $id, $activity->user_id, 'component', 'new_fav_'.$id, $bp->loggedin_user->id );

and this is callback for notification

function bp_favorite_format_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string' ) { 
	$action_checker = explode('_', $action);

	$glue = '';
	$user_names = array();

	$users = find_favorite_involved_persons($item_id, $action);
	$total_user = $count = count($users);

	if($count > 2) {
		$users = array_slice($users, $count - 2);
		$count = $count - 2;
		$glue = ", ";
	} else if($total_user == 2) {
		$glue = " and ";
	}

	foreach((array)$users as $user_id) {
		$user_names[] = bp_core_get_user_displayname($user_id);
	}

	if(!empty($user_names)) {
		$favoriting_users = join($glue, $user_names);
	}

	switch ( $action ) {
		case 'new_fav_'.$item_id:
			if($total_user > 2) {
				$text = $favoriting_users." and ".$count." others favorited your activity";
			} else {
				$text = $favoriting_users." favorited your activity";
			}
		break;
	}

	$link = favorite_activity_get_permalink( $item_id );

	if($format=='string') {
		return apply_filters( 'bp_activity_multiple_favorite_notifications', '<a href="' . $link. '">' . $text . '</a>', $users, $total_user, $count, $glue, $link );
	} else {
		return array(
			'link' => $link,
			'text' => $text
		);
	}
}
function find_favorite_involved_persons($activity_id, $action) {
	global $bp,$wpdb;
	$table = $wpdb->prefix . 'bp_notifications';
	return $wpdb->get_col($wpdb->prepare("select DISTINCT(secondary_item_id) from {$table} where item_id=%d and secondary_item_id!=%d and component_action = %s",$activity_id,$bp->loggedin_user->id, $action));
}
function favorite_activity_get_permalink( $activity_id, $activity_obj = false ) {
	global $bp;

	if ( !$activity_obj )
		$activity_obj = new BP_Activity_Activity( $activity_id );
                    
		if ( 'activity_comment' == $activity_obj->type )
			$link = bp_get_activity_directory_permalink(). 'p/' . $activity_obj->item_id . '/';
		else
			$link = bp_get_activity_directory_permalink() . 'p/' . $activity_obj->id . '/';

	return apply_filters( 'ac_notifier_activity_get_permalink', $link );
}

well this was working fine before new modifications. I have not done some heavy tests but with just a glance this still works.

But I went farther researching other possibilities and this is what I wrote

add_action( 'bp_activity_add_user_favorite', 'add_favorite_notification', 1, 2);
function add_favorite_notification($activity_id, $user_id) {
	global $wpdb;

	// first get activity, bail if it does not exist
	$activity = bp_activity_get_specific( array( 'activity_ids' => $activity_id, 'display_comments' => false ) );
	if ( empty( $activity['total'] ) || ( 1 !== (int) $activity['total'] ) ) {
		return false;
	}

	$author_id = $activity['activities'][0]->user_id;

	// if favoriting own activity, dont send notification
	if( $user_id == $author_id ) {
		return false;
	}

	$notification = $wpdb->get_results("
		SELECT *
		FROM " . buddypress()->notifications->table_name ."
		WHERE user_id = " . $author_id . "
		AND item_id = " . $activity_id . "
		AND component_name = '" . buddypress()->activity->id . "'
		AND component_action = 'favorite'
	");

	if(empty($notification)) {
		$favoriters = array();
		$favoriters[$user_id] = 1;
		$secondary_item_id = maybe_serialize( $favoriters );
		$data = array(
			'user_id'           => $author_id,
			'item_id'           => $activity_id,
			'secondary_item_id' => $secondary_item_id,
			'component_name'    => buddypress()->activity->id,
			'component_action'  => 'favorite',
			'date_notified'     => bp_core_current_time(),
			'is_new'            => 1
		);
		$format = array( '%d', '%d', '%s', '%s', '%s', '%s', '%d' );
		$wpdb->insert( buddypress()->notifications->table_name, $data, $format );
	} else {
		$favoriters = maybe_unserialize( $notification[0]->secondary_item_id );
		if(isset($favoriters[$user_id])){
			// unnessasary doublecheck if user has aready sent notificaiton
			return false;
		}
		$favoriters[$user_id] = 1;
		$favoriters = maybe_serialize( $secondary_item_id );
		BP_Notifications_Notification::update(
			array(
				'secondary_item_id' => $secondary_item_id,
				'date_notified'     => bp_core_current_time()
			),
			array(
				'user_id'           => $author_id,
				'item_id'           => $activity_id,
				'component_name'    => buddypress()->activity->id,
				'component_action'  => 'favorite'
			)
		);
	}
}

The idea was to save users who have favorited activity inside secondary_activity_id. Then value for user_id (for example $notification[$user_id]) will determine if notification from this user is read. This would allow using same notification for one activity (I tried using multiple but that would introduce searching inside serialized array when unfavoriting it)

Also I used direct query on notifications table to check if activity had previously Favorited since original function BP_Notifications_Notification::get requires is_new to be eather true or false and in our case it can be both.

Anyways this was terrible idea from the begining since column secondary_item_id is BIGINT (fail)

This leaves two options here.
One would be to just send mulitple notifications in format like:

user_id 1 favorited activity 3
user_id 2 favorited activity 3
user_id 3 favorited activity 3
user_id 1 favorited activity 4
user_id 2 favorited activity 4

Or just don't record names and send in format:

3 users favorited activity 3
2 users favorited activity 4

Second is better in my opinion since Buddypress does not show users who have favorited activity anyway.

I tried to search more possibilities but this seems impossible in my opinion without modifying current notifications functionality which may be an option since comment notifications will require something similar.

Well I didn't had much success to come up with perfect solution but still wanted to share some of my thoughts.
Hope this helps a bit ^_^

#3 follow-up: @r-a-y
7 years ago

I think this would be cool, but should wait until #5644 is completed.

#4 in reply to: ↑ 3 @imath
7 years ago

Replying to r-a-y:

I think this would be cool, but should wait until #5644 is completed.

Absolutely !!

#5 @chatty24
6 years ago

Does this code work?

Where to add the code?

#6 @tw2113
5 years ago

@chatty24 since it's just function declarations and add_action callbacks, your own custom plugin or theme's functions.php file would work for trying it out.

#7 @DJPaul
3 years ago

  • Keywords trac-tidy-2018 added

We're closing this ticket because it has not received any contribution or comments for at least two years. We have decided that it is better to close tickets that are good ideas, which have not gotten (or are unlikely to get) contributions, rather than keep things open indefinitely. This will help us share a more realistic roadmap for BuddyPress with you.

Everyone very much appreciates the time and effort that you spent sharing your idea with us. On behalf of the entire BuddyPress team, thank you.

If you feel strongly that this enhancement should still be added to BuddyPress, and you are able to contribute effort towards it, we encourage you to re-open the ticket, or start a discussion about it in our Slack channel. Please consider that time has proven that good ideas without contributions do not get built.

For more information, see https://bpdevel.wordpress.com/2018/01/21/our-awaiting-contributions-milestone-contains/
or find us on Slack, in the #buddypress channel: https://make.wordpress.org/chat/

#8 @DJPaul
3 years ago

  • Milestone Awaiting Contributions deleted
  • Resolution set to maybelater
  • Status changed from new to closed
Note: See TracTickets for help on using tickets.