WordPress.org

Make WordPress Core

Opened 20 months ago

Last modified 8 months ago

#21834 new enhancement

Comment History

Reported by: mattoperry Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Comments Keywords: has-patch
Focuses: Cc:

Description

This ticket provides a simple patch for comment history in core.

The Problem:

In at least a few places: (ticket:9117:10, ticket:15534:4, ticket:9495:3) Nacin has mused about the desirability of introducing comment history to core, citing Akismet’s implementation as a model for how this might be done.

There are good reasons for wanting this, as comment history could serve as a solid underpinning for a variety of other features such as more informative moderation emails, some indication of why a message was marked as spam, and even comment versioning.

The idea is that to implement any of that, we really should have basic comment versioning in core, a la Akisment.

The Solution:

Our goal was to expand the API so as to reproduce and streamline the basic history functionality provided by Akismet, port and tweak Akismet’s nice history UI, and keep the change set minimal.

Comment history API:

  • added simple functions to /wp-includes/comment.php to get and update comment history. These in turn use existing comment_meta functions.

UI:

  • there’s now a comment history meta box on the comment edit screen. It looks just like Akismet’s. This was implemented as a real meta box. A sorting function is also included.

History Events:

  • this patch supports the following history events, each of which has a nice, plain-english (internationalizable) history message, which always includes the user responsible for the action and a timesince.
    • edit_comment (“edited by user”)
    • trashed_comment (“trashed by user”)
    • untrashed_comment (“un-trashed by user”)
    • comment_unapproved_to_approved (“user approved this comment”)
  • comment_approved_to_unapproved (“user unapproved this comment”)
  • spammed_comment (“user marked this comment as spam”)
  • unspammed_comment (“user marked this comment as ham”)

Next steps:

Here’s what we’d think of doing next if this were to be introduced into core:

  • support more history events and provide more detail. In particular, support events where the comment is spammed as a result of a blacklist word or other reason.
  • include some of this detail in moderation emails

Note:

Who we are:

This patch comes from Ben Brooks, Matt Perry and Nathan Letsinger. Enjoy

Attachments (1)

comment_meta.patch (6.3 KB) - added by mattoperry 20 months ago.

Download all attachments as: .zip

Change History (10)

mattoperry20 months ago

comment:1 nacin20 months ago

Nice!

For some background, this was the project that the grist.org guys took on at the WCSF hack day. They are sadly not pictured here, as there were another 20-something people sitting off camera to the right.

I think we can do better than Akismet's current method of storing an internationalized string in the DB. The problem is, once this happens, we can't do anything else with that data, especially since internationalization makes it non-parseable (and forces the history to be stored in whatever language the user is using, which may change even user to user).

I think the best way to do this would be to utilize a message identifier, and an array of arguments. This is basically already happening with 'time', 'event' (using the action name — clever!), and 'user' (which should probably be a user ID, rather than a login). But since we have all of the data, we can avoid storing a message at all, and instead render it on runtime.

Props to Andy Skelton for putting this idea in my head a long while ago. The more fleshed out idea is each item is its own callback function with arguments — and then you simply call the callback function with the specified arguments on render. Works great for activity streams, etc. In this case, we can probably keep it to being simple message IDs (well, hook names) with a switch() statement.

(Also, you caught me; I do muse often. Though, ticket:9495:3 looks like a typo'd reference.)

comment:2 nacin20 months ago

I did find ticket:5153:6...

comment:3 follow-up: scribu20 months ago

The more fleshed out idea is each item is its own callback function with arguments — and then you simply call the callback function with the specified arguments on render.

Parser error...

comment:4 in reply to: ↑ 3 nacin20 months ago

Replying to scribu:

The more fleshed out idea is each item is its own callback function with arguments — and then you simply call the callback function with the specified arguments on render.

Parser error...

You store this: array( 'comment_history_message_edited', array( 'time' => time(), 'user_id' => $user_id ) )

Then:

call_user_func( $meta_value[1], $meta_value[2] );

Or something of the sort.

comment:5 scribu20 months ago

Yeah, I though you were suggesting storing something like that.

I don't think storing the actual callback name is a good idea; you'd end up with inflexibility similar to pluggable functions.

Better to use hooks, as you suggested:

do_action( 'comment_history_' . $meta_value[1], $meta_value[2] );

comment:6 ocean9020 months ago

  • Cc ocean90 added

comment:7 toscho20 months ago

  • Cc info@… added

comment:8 toscho20 months ago

I really like this idea.

Some minor notes.

__( "%s by %s" ) should use numbered arguments to make translations easier: __( "%1$s by %2$s" ). That will still be hard to translate.

The inline styles should be moved to the external stylesheet.

<span style="color: #999;" alt="%1$s" title="%1$s">%2$s</span> – there is no alt attribute for span.

comment:9 kraftbj8 months ago

  • Cc bk@… added
Note: See TracTickets for help on using tickets.