#5148 closed defect (bug) (fixed)
Make notifications a separate component
Reported by: | johnjamesjacoby | Owned by: | johnjamesjacoby |
---|---|---|---|
Milestone: | 1.9 | Priority: | normal |
Severity: | normal | Version: | |
Component: | Toolbar & Notifications | Keywords: | |
Cc: | henrywright |
Description (last modified by )
Notifications in BuddyPress are powerful, but in their infancy, and in need of some love.
A few possible enhancements:
- Ability to enable/disable at the component level.
- Add a UI for read/unread notifications.
- A control panel for moderators to see all notifications, to clear them, delete them, etc...
- Allow users to toggle notifications back to unread.
- Improve the
BP_Core_Notification
class methods so they are more flexible like the activity and group components.
Attachments (8)
Change History (58)
#3
@
11 years ago
I know this is slated for 2.0, but I wanted to get some groundwork done to improve the BP_Core_Notification
class methods.
class.01.patch
does the following:
- Adds missing static method -
delete()
- as referenced inbp_core_delete_notification()
. (Can't believe no one has ever reported this!) - Adds static method -
get()
. We don't currently have a flexible get method like the activity and groups components, so this covers that. For a use-case on flexibility, seebp_activity_at_message_notification()
in the patch. I also deprecated a bunch ofget_*()
static methods in favor of this. - Adds '_before_' and '_after_' hooks in the
save()
method. - Adds static method -
get_where_sql()
. TheWHERE
sql is shared between bothget()
anddelete()
methods, so I created a helper method for this. - Removed references to the
$bp
global and replaced with thebuddypress()
singeleton.
Feedback welcome.
#4
@
11 years ago
Patch looks really good, r-a-y. I'm a big fan of moving the miscellaneous methods into central delete()
and get()
methods. Also, the fact that you fixed a couple of these basic but major bugs is crazy to me - I guess that means that few people are hacking on Notifications at the moment. (Heck, I've hardly ever hacked on it.)
Couple small comments:
- Since we're essentially gutting a couple of user facing functions and replacing them with the new all-purpose
get
anddelete
methods, we should have unit tests for the procedural wrappers. Then we can rest assured that the refactor didn't break anything. get_where_sql()
looks good to me, but let's mark itprotected static
. It's probably a bad idea to encourage developers to use BP's utility methods for building partial SQL statements, as it binds our hands if we ever want to make internal syntax modifications.
But yeah, these look like very solid improvements for 1.9.
#5
@
11 years ago
Thanks for the feedback, Boone. Good catch on marking get_where_sql()
as protected.
class.01b.patch
adds unit tests and fixes some minor things in get_where_sql()
method when passing the secondary_item_id
and is_new
parameters. (Thank you unit tests!)
For the unit tests, I'm testing the generated SQL statement made by the get_where_sql()
method against the current statements generated in 1.8.
Let me know what you think.
#6
@
11 years ago
Awesome, r-a-y!
I'd suggest that, since get_where_sql()
is protected and thus shouldn't really be used externally, we don't need to test it directly; in the same way that we don't want others to use it because the implementation might change, we'll also be forced to rewrite those tests should we wish to reimplement the SQL. I humbly submit that the tests be for the public API functions/methods instead.
Rest of the patch looks really great.
#7
@
11 years ago
I humbly submit that the tests be for the public API functions/methods instead.
class.01c.patch
uses the public API functions in the unit tests. I wanted to test the WHERE sql statement only so that required using the new filter hooks, which work great!
#8
@
11 years ago
I guess I was more thinking of test for, for example, bp_core_get_notifications_for_user()
, which would show us that the refactored function (which uses the new get()
under the hood) is returning the same values as the function currently does. That said, I don't think it's a showstopper, as the changes seem pretty straightforward.
#9
follow-up:
↓ 10
@
11 years ago
- Cc henrywright added
If notifications is to become a component, does that mean a dedicated notifications screen will be introduced? members/username/notifications
I find the current notifications drop-down doesn't work very well when there are 5, 6, 7 etc notifications to display due to a lack of physical space. So for each member, I've introduced a dedicated page to display their (un-clicked) notifications:
function setup_notifications() { bp_core_new_nav_item( array( 'name' => __( 'Notifications', 'buddypress' ), 'slug' => 'notifications', 'position' => 40, 'show_for_displayed_user' => false, 'item_css_id' => 'notifications', 'screen_function' => 'notifications_screen', ) ); } add_action( 'bp_setup_nav', 'setup_notifications' ); function notifications_screen() { bp_core_load_template( 'members/single/notifications' ); }
A standalone page (having lots more space than the drop-down) opens up the possibility of having a 'rich notifications' log such as
[avatar] member X followed you
[avatar] member X replied to your comment
There would be little need to 'dismiss' or delete a notification as the page could grow endlessly allowing the member to check back over old notifications.
The log might grow big so notifications might need to be paged. So bp_core_new_subnav_item()
might be needed.
Hopefully i'm not way off with my thoughts on this one. Just thought i'd throw an idea into the mixing pot.
@
11 years ago
bp-notifications component. backpat, no unit tests, mock template parts for bp-legacy. Needs output API.
#10
in reply to:
↑ 9
@
11 years ago
Replying to henrywright:
If notifications is to become a component, does that mean a dedicated notifications screen will be introduced?
members/username/notifications
Yes, exactly.
A standalone page (having lots more space than the drop-down) opens up the possibility of having a 'rich notifications' log such as
[avatar] member X followed you
[avatar] member X replied to your comment
There would be little need to 'dismiss' or delete a notification as the page could grow endlessly allowing the member to check back over old notifications.
Correct. Notifications currently are always deleted, rather than mark is_new
as 0
. My attached patch introduces logic for marking notifications as read/unread.
The log might grow big so notifications might need to be paged. So
bp_core_new_subnav_item()
might be needed.
Attached patch introduces two notifications screens: Unread and Read. This should help with both the logging of events, and providing a more robust interface to see individual notifications, rather than lumping them all together like we do now.
Hopefully i'm not way off with my thoughts on this one. Just thought i'd throw an idea into the mixing pot.
You're spot on with what's been in my imagination for a while now.
#11
@
11 years ago
- Milestone changed from 2.0 to 1.9
I'd like to suggest fitting this into 1.9, since we've extended putting out a beta, and this is mostly complete.
#12
@
11 years ago
johnjamesjacoby thanks for giving an overview of how the new component will function. The new component will certainly open up lots of possibilities. Excited to see this in 1.9!
#13
@
11 years ago
To-do's:
Because there's no full-text of the notification itself, bp-notifications should be responsible for putting the item_id, secondary_item_id, component_name, component_action, and date_notiified into real words.
In the current implementation, notification_callback
is used as a singlular/cumulative catch-all; bp_activity_format_notifications()
is a good example. bp_core_get_notifications_for_user()
will be used as a foundation to loop through active notifications, and build the full-text strings for each line item, without grouping all similar notifications into 1 to be acknowledged.
We'll also need to change the behavior from delete
to mark read
and make sure bp_core_get_notifications_for_user()
only shows unread notifications. This won't be difficult, but will likely touch each component, since they are individually responsible for knowing when their notifications are no longer new.
#14
@
11 years ago
johnjamesjacoby - Thanks for the initial patch. You've done much of the hard work.
As I mentioned to you earlier, I think that you were too conservative in porting from the current implementation. This is particularly true in the database class, where you've kept almost exactly the same logic. This loses all the elegance, flexibility, robustness, testability, maintainability, etc of what r-a-y had been exploring with his earlier patches.
In 5148.02.patch, I implement most of what r-a-y originally suggested on top of 5148.02.patch. All update, insert, delete, and get queries are now being piped through single, all-purpose methods. Unit tests have been provided for most major database functionality. Since $wpdb
provides update()
, insert()
, and delete()
, but nothing for SELECT, I knew I'd need my own get()
with my own SQL; since I was going to do it anyway, I added support so that all params for get()
can be either single values or arrays of values for an IN
clause. I think this technique will give us much more flexibility down the road, and will be far easier to maintain (in addition to being far more DRY).
I've kept most of the original database methods suggested by 5148.patch, but they are all internally using the primary CRUD methods of the class. This includes everything under the header "Convienience Methods" in bp-notifications-classes.php. IMHO, these could all be removed, with their logic put instead into procedural functions with similar names. That'd keep the database class lean-n-mean, and promote a proper separation of duties.
Other miscellaneous cleanup in 5148.02.patch:
- Added/improved docblocks
- Better coding standards compliance (commas after final array values, stuff like that)
- Fixed some of the half-implemented logic for pagination (you had 'max' but hadn't fully implemented 'page' and 'per_page')
I haven't really touched any of the front-end stuff, as I'm going a little nutso staring at this all day :) Pagination obviously needs to be cleaned up in the display, in addition to the concatenation of strings like you mention above.
Another todo: activate the Notifications (and Settings) components for upgrading systems.
#42
@
11 years ago
Everything is done, minus some JS for the sort-order drop-down selection. Anyone want some easy props?
#45
@
11 years ago
Ok, quick rundown on the behavior of the JS order select:
If 1 page of notifications or less, JS swaps order of existing items
If > 1 page of notifications, we have some options:
- JS resets order and loads first page of notifications based on new sort.
- JS resets order but keeps current page (i.e. page 4 of ASC sort flips and shows page 4 of DESC sort)
- JS resets order and loads inverse of page (i.e. loads page 7 of 8 instead of 2 of 8)
I'm leaning towards one of the first two options, but am open to hearing how this behavior works throughout BP and matching that.
#46
@
11 years ago
Ok, here's a first stab at the functionality outlined above, using the first option for paginated notifications (i.e. reverses sort and sends the user back to the first page of that sort order). Possible red flags:
- We're checking a $_GET var directly to set the selected value of the select input in /bp-templates/bp-legacy/buddypress/members/single/notifications.php. I'm doing this because it seems the BP_Notifications_Template object has not yet instantiated at that point with the corresponding sort_order property. If there's a better way to do this, the code should be updated to use that.
- JS is being enqueued in bp-notifications-template.php conditionally when the object finds notifications for the user. This is great performance-wise, but I'm not sure if it's the right place for the enqueue.
- The closing </tbody> tag must be fixed (included in this patch) for the JS to work--otherwise it will balk at the presence of multiple tbody tags in the table.
This would be incredibly useful and could think of some nice ways to extend this for future projects. Would this use a new database table or existing? Would love to see users mute or suspend notifications for a time (maybe while they are on vacation), but guessing this can be a plugin as well.