[buddypress-trac] [BuddyPress Trac] #5555: Notification on favorite
buddypress-trac
noreply at wordpress.org
Mon Apr 28 00:25:56 UTC 2014
#5555: Notification on favorite
---------------------------+-----------------------------
Reporter: mpa4hu | Owner:
Type: enhancement | Status: new
Priority: normal | Milestone: Future Release
Component: Notifications | Version:
Severity: normal | Resolution:
Keywords: needs-patch |
---------------------------+-----------------------------
Comment (by mpa4hu):
@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 {{{^_^}}}
--
Ticket URL: <https://buddypress.trac.wordpress.org/ticket/5555#comment:2>
BuddyPress Trac <http://buddypress.org/>
BuddyPress Trac
More information about the buddypress-trac
mailing list