242 lines
5.9 KiB
Perl
242 lines
5.9 KiB
Perl
# This code was forked from the LiveJournal project owned and operated
|
|
# by Live Journal, Inc. The code has been modified and expanded by
|
|
# Dreamwidth Studios, LLC. These files were originally licensed under
|
|
# the terms of the license supplied by Live Journal, Inc, which can
|
|
# currently be found at:
|
|
#
|
|
# http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt
|
|
#
|
|
# In accordance with the original license, this code and all its
|
|
# modifications are provided under the GNU General Public License.
|
|
# A copy of that license can be found in the LICENSE file included as
|
|
# part of this distribution.
|
|
|
|
# This is a class representing a notification that came out of an
|
|
# LJ::NotificationInbox. You can tell it to mark itself as
|
|
# read/unread, delete it, and get the event that it contains out of
|
|
# it.
|
|
# Mischa Spiegelmock, 05/2006
|
|
|
|
package LJ::NotificationItem;
|
|
use strict;
|
|
use warnings;
|
|
no warnings "redefine";
|
|
|
|
use LJ::NotificationInbox;
|
|
use LJ::Event;
|
|
use Carp qw(croak);
|
|
|
|
*new = \&instance;
|
|
|
|
# parameters: user, notification inbox id
|
|
sub instance {
|
|
my ( $class, $u, $qid ) = @_;
|
|
|
|
my $singletonkey = $qid;
|
|
|
|
$u->{_inbox_items} ||= {};
|
|
return $u->{_inbox_items}->{$singletonkey} if $u->{_inbox_items}->{$singletonkey};
|
|
|
|
my $self = {
|
|
userid => $u->id,
|
|
qid => $qid,
|
|
state => undef,
|
|
event => undef,
|
|
when => undef,
|
|
_loaded => 0,
|
|
};
|
|
|
|
$u->{_inbox_items}->{$singletonkey} = $self;
|
|
|
|
return bless $self, $class;
|
|
}
|
|
|
|
# returns whose notification this is
|
|
*u = \&owner;
|
|
sub owner { LJ::load_userid( $_[0]->{userid} ) }
|
|
|
|
# returns this item's id in the notification queue
|
|
sub qid { $_[0]->{qid} }
|
|
|
|
# returns true if this item really exists
|
|
sub valid {
|
|
my $self = shift;
|
|
|
|
return undef unless $self->u && $self->qid;
|
|
$self->_load unless $self->{_loaded};
|
|
|
|
return $self->event;
|
|
}
|
|
|
|
# returns title of this item
|
|
sub title {
|
|
my $self = shift;
|
|
return "(Invalid event)" unless $self->event;
|
|
|
|
my %opts = @_;
|
|
my $mode = delete $opts{mode};
|
|
croak "Too many args passed to NotificationItem->as_html" if %opts;
|
|
|
|
$mode = "html" unless $mode;
|
|
|
|
if ( $mode eq "html" ) {
|
|
return eval { $self->event->as_html( $self->u ) } || $@;
|
|
}
|
|
}
|
|
|
|
# returns contents of this item for user u
|
|
sub as_html {
|
|
my $self = shift;
|
|
croak "Too many args passed to NotificationItem->as_html" if scalar @_;
|
|
return "(Invalid event)" unless $self->event;
|
|
return eval { $self->event->content( $self->u ) } || $@;
|
|
}
|
|
|
|
sub as_html_summary {
|
|
my $self = shift;
|
|
croak "Too many args passed to NotificationItem->as_html_summary" if scalar @_;
|
|
return "(Invalid event)" unless $self->event;
|
|
return eval { $self->event->content_summary( $self->u ) } || $@;
|
|
}
|
|
|
|
# returns the event that this item refers to
|
|
sub event {
|
|
my $self = shift;
|
|
|
|
$self->_load unless $self->{_loaded};
|
|
|
|
return $self->{event};
|
|
}
|
|
|
|
# loads this item
|
|
sub _load {
|
|
my $self = shift;
|
|
|
|
my $qid = $self->qid;
|
|
my $u = $self->owner;
|
|
|
|
return if $self->{_loaded};
|
|
|
|
# load info for all the currently instantiated singletons
|
|
# get current singleton qids
|
|
$u->{_inbox_items} ||= {};
|
|
my @qids = map { $_->qid } values %{ $u->{_inbox_items} };
|
|
|
|
my $bind = join( ',', map { '?' } @qids );
|
|
|
|
my $sth = $u->prepare( "SELECT userid, qid, journalid, etypeid, arg1, arg2, state, createtime "
|
|
. "FROM notifyqueue WHERE userid=? AND qid IN ($bind)" );
|
|
$sth->execute( $u->id, @qids );
|
|
die $sth->errstr if $sth->err;
|
|
|
|
my @items;
|
|
while ( my $row = $sth->fetchrow_hashref ) {
|
|
my $qid = $row->{qid} or next;
|
|
my $singleton = $u->{_inbox_items}->{$qid} or next;
|
|
|
|
push @items, $singleton->absorb_row($row);
|
|
}
|
|
}
|
|
|
|
# fills in a skeleton item from a database row hashref
|
|
sub absorb_row {
|
|
my ( $self, $row ) = @_;
|
|
|
|
$self->{_loaded} = 1;
|
|
|
|
$self->{state} = $row->{state};
|
|
$self->{when} = $row->{createtime};
|
|
|
|
my $evt = LJ::Event->new_from_raw_params( $row->{etypeid}, $row->{journalid}, $row->{arg1},
|
|
$row->{arg2} );
|
|
$self->{event} = $evt;
|
|
|
|
return $self;
|
|
}
|
|
|
|
# returns when this event happened (or got put in the inbox)
|
|
sub when_unixtime {
|
|
my $self = shift;
|
|
|
|
$self->_load unless $self->{_loaded};
|
|
|
|
return $self->{when};
|
|
}
|
|
|
|
# returns the state of this item
|
|
sub _state {
|
|
my $self = shift;
|
|
|
|
$self->_load unless $self->{_loaded};
|
|
|
|
return $self->{state};
|
|
}
|
|
|
|
# returns if this event is marked as read
|
|
sub read {
|
|
return 0 unless defined $_[0]->_state;
|
|
return $_[0]->_state eq 'R';
|
|
}
|
|
|
|
# returns if this event is marked as unread
|
|
sub unread {
|
|
return 0 unless defined $_[0]->_state;
|
|
return $_[0]->_state eq 'N';
|
|
}
|
|
|
|
# delete this item from its inbox
|
|
sub delete {
|
|
my $self = shift;
|
|
return unless $self->owner;
|
|
my $inbox = $self->owner->notification_inbox;
|
|
|
|
# delete from the inbox so the inbox stays in sync
|
|
my $ret = $inbox->delete_from_queue($self);
|
|
%$self = ();
|
|
return $ret;
|
|
}
|
|
|
|
# mark this item as read
|
|
sub mark_read {
|
|
my $self = shift;
|
|
|
|
# do nothing if it's already marked as read
|
|
return if $self->read;
|
|
$self->_set_state('R');
|
|
}
|
|
|
|
# mark this item as read
|
|
sub mark_unread {
|
|
my $self = shift;
|
|
|
|
# do nothing if it's already marked as unread
|
|
return if $self->unread;
|
|
$self->_set_state('N');
|
|
}
|
|
|
|
# sets the state of this item
|
|
sub _set_state {
|
|
my ( $self, $state ) = @_;
|
|
|
|
$self->owner->do( "UPDATE notifyqueue SET state=? WHERE userid=? AND qid=?",
|
|
undef, $state, $self->owner->id, $self->qid )
|
|
or die $self->owner->errstr;
|
|
$self->{state} = $state;
|
|
|
|
# expire unread cache
|
|
my $userid = $self->u->id;
|
|
my $memkey = [ $userid, "inbox:newct:${userid}" ];
|
|
LJ::MemCache::delete($memkey);
|
|
}
|
|
|
|
# JSON output implementation for NotificationItem objects
|
|
sub TO_JSON {
|
|
my $self = shift;
|
|
my $json = {
|
|
title => $self->title,
|
|
content => $self->as_html,
|
|
unread => $self->unread,
|
|
timestamp => $self->when_unixtime
|
|
|
|
};
|
|
}
|