#!/usr/bin/perl # # LJ::Event::JournalNewComment::Reply - Someone replies to any comment I make # # Authors: # Andrea Nall # # Copyright (c) 2013 by Dreamwidth Studios, LLC. # # This program is free software; you may redistribute it and/or modify it under # the same terms as Perl itself. For a copy of the license, please reference # 'perldoc perlartistic' or 'perldoc perlgpl'. # package LJ::Event::JournalNewComment::Reply; use strict; use List::MoreUtils qw/uniq/; use base 'LJ::Event::JournalNewComment'; sub zero_journalid_subs_means { return 'all'; } sub subscription_as_html { my ( $class, $subscr, $key_prefix ) = @_; my $key = $key_prefix || 'event.journal_new_comment.reply'; my $arg2 = $subscr->arg2; my %key_suffixes = ( 0 => '.comment', 1 => '.community', 2 => '.mycomment', ); return BML::ml( $key . $key_suffixes{$arg2} ); } sub available_for_user { return 1; } sub _relevant_userids { my $comment = $_[0]->comment; return () unless $comment; my $entry = $comment->entry; return () unless $entry; my @prepart; push @prepart, $comment->posterid if $comment->posterid; my $parent = $comment->parent; push @prepart, $parent->posterid if $parent && $parent->posterid; push @prepart, $entry->posterid if $entry->journal->is_community; return uniq @prepart; } sub early_filter_event { my @userids = _relevant_userids( $_[1] ); return scalar @userids ? 1 : 0; } sub additional_subscriptions_sql { my @userids = _relevant_userids( $_[1] ); return ( 'userid IN (' . join( ",", map { '?' } @userids ) . ')', @userids ) if scalar @userids; return undef; } sub migrate_user { my ( $class, $u ) = @_; # Cannot use $u->migrate_prop_to_esn # * opt_gettalkemail isn't really a prop # * ->migrate_prop_to_esn won't take arg1/arg2 # * it no longer exists following https://github.com/dreamwidth/dreamwidth/issues/2052 my $opt_gettalkemail = $u->prop('opt_gettalkemail') // ''; my $opt_getselfemail = $u->prop('opt_getselfemail') // ''; my @pending_subscriptions; if ( $opt_gettalkemail ne 'X' ) { if ( $opt_gettalkemail eq 'Y' ) { push @pending_subscriptions, map { ( # FIXME(dre): Remove when ESN can bypass inbox LJ::Subscription::Pending->new( $u, event => 'JournalNewComment::Reply', method => 'Inbox', arg2 => $_, ), LJ::Subscription::Pending->new( $u, event => 'JournalNewComment::Reply', method => 'Email', arg2 => $_, ), ) } ( 0, 1 ); } $u->update_self( { 'opt_gettalkemail' => 'X' } ); } if ( $opt_getselfemail ne 'X' ) { if ( $opt_getselfemail eq '1' ) { push @pending_subscriptions, ( # FIXME(dre): Remove when ESN can bypass inbox LJ::Subscription::Pending->new( $u, event => 'JournalNewComment::Reply', method => 'Inbox', arg2 => 2, ), LJ::Subscription::Pending->new( $u, event => 'JournalNewComment::Reply', method => 'Email', arg2 => 2, ), ); } $u->set_prop( 'opt_getselfemail' => 'X' ); } $_->commit foreach @pending_subscriptions; } # override parent class sbuscriptions method to # convert opt_gettalkemail to a subscription sub raw_subscriptions { my ( $class, $self, %args ) = @_; my $cid = delete $args{'cluster'}; croak("Cluser id (cluster) must be provided") unless defined $cid; my $scratch = delete $args{'scratch'}; # optional croak( "Unknown options: " . join( ', ', keys %args ) ) if %args; croak("Can't call in web context") if LJ::is_web_context(); my @userids = _relevant_userids( $_[1] ); foreach my $userid (@userids) { my $u = LJ::load_userid($userid); next unless $u; next unless ( $cid == $u->clusterid ); $class->migrate_user($u); } return eval { LJ::Event::raw_subscriptions( $class, $self, cluster => $cid, scratch => $scratch ) } unless scalar @userids; my @rows = eval { LJ::Event::raw_subscriptions( $class, $self, cluster => $cid, scratch => $scratch ) }; return @rows; } sub matches_filter { my ( $self, $subscr ) = @_; my $sjid = $subscr->journalid; my $ejid = $self->event_journal->{userid}; my $watcher = $subscr->owner; my $arg2 = $subscr->arg2; my $comment = $self->comment; # Do not send on own comments return 0 unless $comment->visible_to($watcher); # For unscreen events, skip users who were already notified # when the comment was screened (they could already see it). if ( $self->is_unscreen_event ) { return 0 if $watcher->can_manage( $comment->journal ); return 0 if $comment->entry && $comment->entry->poster && $watcher->equals( $comment->entry->poster ); } # Do not send if opt_noemail applies return 0 if $self->apply_noemail( $watcher, $comment, $subscr->method ); my $parent = $comment->parent; if ( $arg2 == 0 ) { # Someone replies to my comment return 0 unless $parent; return 0 unless $parent->posterid == $watcher->id; # Make sure we didn't post the comment return 1 unless $comment->posterid == $watcher->id; } elsif ( $arg2 == 1 ) { # Someone replies to my entry in a community my $entry = $comment->entry; return 0 unless $entry; # Make sure the entry is posted by the watcher return 0 unless $entry->posterid == $watcher->id; # Make sure we didn't post the comment return 1 unless $comment->posterid == $watcher->id; } elsif ( $arg2 == 2 ) { # I comment on any entry in someone else's journal my $entry = $comment->entry; return 0 unless $entry; # Make sure we posted the comment return 1 if $comment->posterid == $watcher->id; } return 0; } 1;