1 package LJ
::Event
::JournalNewComment
;
3 use Scalar
::Util
qw(blessed);
4 use Class
::Autouse
qw(LJ::Comment LJ::HTML::Template);
10 # we don't allow subscriptions to comments on friends' journals, so
11 # setting undef on this skips some nasty queries
12 sub zero_journalid_subs_means
{ undef }
15 my ($class, $comment) = @_;
16 croak
'Not an LJ::Comment' unless blessed
$comment && $comment->isa("LJ::Comment");
17 return $class->SUPER::new
($comment->journal, $comment->jtalkid);
23 my @_ml_strings_en = (
24 'esn.mail_comments.fromname.user', # "[[user]] - [[sitenameabbrev]] Comment",
25 'esn.mail_comments.fromname.anonymous', # "[[sitenameshort]] Comment",
26 'esn.mail_comments.subject.edit_reply_to_your_comment', # "Edited reply to your comment...",
27 'esn.mail_comments.subject.reply_to_your_comment', # "Reply to your comment...",
28 'esn.mail_comments.subject.edit_reply_to_your_entry', # "Edited reply to your entry...",
29 'esn.mail_comments.subject.reply_to_your_entry', # "Reply to your entry...",
30 'esn.mail_comments.subject.edit_reply_to_an_entry', # "Edited reply to an entry...",
31 'esn.mail_comments.subject.reply_to_an_entry', # "Reply to an entry...",
32 'esn.mail_comments.subject.edit_reply_to_a_comment', # "Edited reply to a comment...",
33 'esn.mail_comments.subject.reply_to_a_comment', # "Reply to a comment...",
34 'esn.mail_comments.subject.comment_you_posted', # "Comment you posted...",
35 'esn.mail_comments.subject.comment_you_edited', # "Comment you edited...",
37 'esn.mail_comments.alert.user_edited_reply_to_your_comment', #[[user]] edited a reply to your comment.
38 'esn.mail_comments.alert.user_edited_reply_to_a_comment', #[[user]] edited a reply to a comment.
39 'esn.mail_comments.alert.user_reply_to_your_comment', #[[user]] replied to your comment.
40 'esn.mail_comments.alert.user_reply_to_a_comment', #[[user]] replied to a comment.
41 'esn.mail_comments.alert.user_edited_reply_to_your_post', #[[user]] edited a reply to your post.
42 'esn.mail_comments.alert.user_edited_reply_to_a_post', #[[user]] edited a reply to a post.
43 'esn.mail_comments.alert.user_reply_to_your_post', #[[user]] replied to your post.
44 'esn.mail_comments.alert.user_reply_to_a_post', #[[user]] replied to a post.
45 'esn.mail_comments.alert.anonymous_edited_reply_to_your_comment', #Anonymous user edited a reply to your comment.
46 'esn.mail_comments.alert.anonymous_edited_reply_to_a_comment', #Anonymous user edited a reply to a comment.
47 'esn.mail_comments.alert.anonymous_reply_to_your_comment', #Anonymous user replied to your comment.
48 'esn.mail_comments.alert.anonymous_reply_to_a_comment', #Anonymous user replied to a comment.
49 'esn.mail_comments.alert.anonymous_edited_reply_to_your_post', #Anonymous user edited a reply to your post.
50 'esn.mail_comments.alert.anonymous_edited_reply_to_a_post', #Anonymous user edited a reply to a post.
51 'esn.mail_comments.alert.anonymous_reply_to_your_post', #Anonymous user replied to your post.
52 'esn.mail_comments.alert.anonymous_reply_to_a_post', #Anonymous user replied to a post.
54 'esn.journal_new_comment.actions.link', # Link
55 'esn.journal_new_comment.actions.reply', # Reply
56 'esn.journal_new_comment.comment.params.body', # New <a href="[[url]]">comment</a> [[subject]] [[poster]] on [[in_text]] in [[journal]].
57 'esn.journal_new_comment.comment.params.subject', # Someone has posted new comment
58 'esn.journal_new_comment.del.comment.params.body', # (Deleted comment in [[journal]])
59 'esn.journal_new_comment.del.comment.params.subject', # (Deleted comment)
60 'esn.journal_new_comment.del.entry.params.body', # (Comment on a deleted entry in [[journal]])
61 'esn.journal_new_comment.del.entry.params.subject', # (Comment on a deleted entry)
62 'esn.journal_new_comment.edited.params.body', # Edited <a href="[[url]]">comment</a> [[subject]] [[poster]] on [[in_text]] in [[journal]].
63 'esn.journal_new_comment.edited.params.subject', # Someone has edited comment
64 'esn.journal_new_comment.noauth.params.body', # (You are not authorized to view this comment)
65 'esn.journal_new_comment.noauth.params.subject', # (You are not authorized to view this comment)
68 sub as_email_from_name
{
71 my $lang = $u->prop('browselang');
74 user
=> $self->comment->poster ?
$self->comment->poster->display_username : '',
75 sitenameabbrev
=> $LJ::SITENAMEABBREV
,
76 sitenameshort
=> $LJ::SITENAMESHORT
,
79 my $key = 'esn.mail_comments.fromname.';
80 if($self->comment->poster) {
86 return LJ
::Lang
::get_text
($lang, $key, undef, $vars);
89 sub as_email_headers
{
92 my $this_msgid = $self->comment->email_messageid;
93 my $top_msgid = $self->comment->entry->email_messageid;
96 if ($self->comment->parent) { # a reply to a comment
97 $par_msgid = $self->comment->parent->email_messageid;
98 } else { # reply to an entry
99 $par_msgid = $top_msgid;
100 $top_msgid = ""; # so it's not duplicated
103 my $journalu = $self->comment->entry->journal;
105 'Message-ID' => $this_msgid,
106 'In-Reply-To' => $par_msgid,
107 'References' => "$top_msgid $par_msgid",
108 'X-LJ-Journal' => $journalu->user,
115 sub as_email_subject
{
118 my $edited = $self->comment->is_edited;
119 my $lang = $u->prop('browselang');
121 my $filename = $self->template_file_for(section
=> 'subject', lang
=> $lang);
123 # Load template file into template processor
124 my $t = LJ
::HTML
::Template
->new(filename
=> $filename);
125 $t->param(subject
=> $self->comment->subject_html);
129 my $key = 'esn.mail_comments.subject.';
130 if ( my $comment_subject = $self->comment->subject_orig ) {
131 return LJ
::strip_html
($comment_subject);
132 } elsif (LJ
::u_equals
($self->comment->poster, $u)) {
133 $key .= $edited ?
'comment_you_edited' : 'comment_you_posted';
134 } elsif ($self->comment->parent) {
136 $key .= LJ
::u_equals
($self->comment->parent->poster, $u) ?
'edit_reply_to_your_comment' : 'edit_reply_to_a_comment';
138 $key .= LJ
::u_equals
($self->comment->parent->poster, $u) ?
'reply_to_your_comment' : 'reply_to_a_comment';
142 $key .= LJ
::u_equals
($self->comment->entry->poster, $u) ?
'edit_reply_to_your_entry' : 'edit_reply_to_an_entry';
144 $key .= LJ
::u_equals
($self->comment->entry->poster, $u) ?
'reply_to_your_entry' : 'reply_to_an_entry';
149 if ( my $entry_subject = $self->comment->entry->subject_raw ) {
150 $key .= '.entry_subject';
151 $ml_params->{'subject'} = LJ
::strip_html
($entry_subject);
154 return LJ
::Lang
::get_text
( $lang, $key, undef, $ml_params );
157 sub as_email_string
{
159 my $comment = $self->comment or return "(Invalid comment)";
161 my $filename = $self->template_file_for(section
=> 'body_text', lang
=> $u->prop('browselang'));
163 # Load template file into template processor
164 my $t = LJ
::HTML
::Template
->new(filename
=> $filename);
166 return $comment->format_template_text_mail($u, $t) if $t;
169 return $comment->format_text_mail($u);
174 my $comment = $self->comment or return "(Invalid comment)";
176 my $filename = $self->template_file_for(section
=> 'body_html', lang
=> $u->prop('browselang'));
178 # Load template file into template processor
179 my $t = LJ
::HTML
::Template
->new(filename
=> $filename);
181 return $comment->format_template_html_mail($u, $t) if $t;
184 return $comment->format_html_mail($u);
189 my $comment = $self->comment;
190 my $journal = $comment->entry->journal->user;
192 return "There is a new anonymous comment in $journal at " . $comment->url
193 unless $comment->poster;
195 my $poster = $comment->poster->display_username;
196 if ($self->comment->is_edited) {
197 return "$poster has edited a comment in $journal at " . $comment->url;
199 return "$poster has posted a new comment in $journal at " . $comment->url;
203 # 'esn.mail_comments.alert.user_edited_reply_to_your_comment', #[[user]] edited a reply to your comment.
204 # 'esn.mail_comments.alert.user_edited_reply_to_a_comment', #[[user]] edited a reply to a comment.
205 # 'esn.mail_comments.alert.user_reply_to_your_comment', #[[user]] replied to your comment.
206 # 'esn.mail_comments.alert.user_reply_to_a_comment', #[[user]] replied to a comment.
207 # 'esn.mail_comments.alert.user_edited_reply_to_your_post', #[[user]] edited a reply to your post.
208 # 'esn.mail_comments.alert.user_edited_reply_to_a_post', #[[user]] edited a reply to a post.
209 # 'esn.mail_comments.alert.user_reply_to_your_post', #[[user]] replied to your post.
210 # 'esn.mail_comments.alert.user_reply_to_a_post', #[[user]] replied to a post.
211 # 'esn.mail_comments.alert.anonymous_edited_reply_to_your_comment', #Anonymous user edited a reply to your comment.
212 # 'esn.mail_comments.alert.anonymous_edited_reply_to_a_comment', #Anonymous user edited a reply to a comment.
213 # 'esn.mail_comments.alert.anonymous_reply_to_your_comment', #Anonymous user replied to your comment.
214 # 'esn.mail_comments.alert.anonymous_reply_to_a_comment', #Anonymous user replied to a comment.
215 # 'esn.mail_comments.alert.anonymous_edited_reply_to_your_post', #Anonymous user edited a reply to your post.
216 # 'esn.mail_comments.alert.anonymous_edited_reply_to_a_post', #Anonymous user edited a reply to a post.
217 # 'esn.mail_comments.alert.anonymous_reply_to_your_post', #Anonymous user replied to your post.
218 # 'esn.mail_comments.alert.anonymous_reply_to_a_post', #Anonymous user replied to a post.
224 # TODO: [[post]] [[reply]] etc
225 my $comment = $self->comment;
226 my $user = $comment->poster ?
$comment->poster->ljuser_display() : '(Anonymous user)';
227 my $edited = $comment->is_edited;
229 return LJ
::Lang
::get_text
($u->prop('browselang'),
230 'esn.mail_comments.alert.' .
231 ($comment->poster ?
'user' : 'anonymous') . '_' .
232 ($edited ?
'edited_' : '') . 'reply_' .
233 (LJ
::u_equals
($comment->entry->poster, $u) ?
'to_your' : 'to_a') . '_' .
234 ($comment->parent ?
'comment' : 'post'), undef,
237 openlink
=> '<a href="' . $comment->url . '">',
243 my ($self, $u, $opt) = @_;
245 my $user = $self->comment->poster ?
$self->comment->poster->display_username(1) : '(Anonymous user)';
246 my $edited = $self->comment->is_edited;
248 my $parent = $self->comment->parent;
249 my $entry = $self->comment->entry;
250 my $lang = $u->prop('browselang') || $LJ::DEFAULT_LANG
;
252 my ($ml_key, $ml_params);
253 if ($self->event_journal->journaltype eq 'C') {
256 $ml_key = LJ
::u_equals
($parent->poster, $u) ?
257 'sms.communityentryreply.edit_reply_your_comment' : 'sms.communityentryreply.edit_reply_a_comment';
259 $ml_key = LJ
::u_equals
($parent->poster, $u) ?
260 'sms.communityentryreply.replied_your_comment' : 'sms.communityentryreply.replied_a_comment';
264 $ml_key = LJ
::u_equals
($entry->poster, $u) ?
265 'sms.communityentryreply.edit_reply_your_post' : 'sms.communityentryreply.edit_reply_a_post';
267 $ml_key = LJ
::u_equals
($entry->poster, $u) ?
268 'sms.communityentryreply.replied_your_post' : 'sms.communityentryreply.replied_a_post';
271 $ml_params = { user
=> $user, community
=> $self->event_journal->user };
275 $ml_key = LJ
::u_equals
($parent->poster, $u)
276 ?
'sms.journalnewcomment.edit_reply_your_comment' : 'sms.journalnewcomment.edit_reply_a_comment';
278 $ml_key = LJ
::u_equals
($parent->poster, $u)
279 ?
'sms.journalnewcomment.replied_your_comment' : 'sms.journalnewcomment.replied_a_comment';
283 $ml_key = LJ
::u_equals
($entry->poster, $u)
284 ?
'sms.journalnewcomment.edit_reply_your_post' : 'sms.journalnewcomment.edit_reply_a_post';
286 $ml_key = LJ
::u_equals
($entry->poster, $u)
287 ?
'sms.journalnewcomment.replied_your_post' : 'sms.journalnewcomment.replied_a_post';
290 $ml_params = { user
=> $user };
293 my $msg = LJ
::Lang
::get_text
($lang, $ml_key, undef, $ml_params);
294 #/read/user/%username%/%post_ID%/comments/%comment_ID%#comments
295 my $tinyurl = "http://m.livejournal.com/read/user/".$self->event_journal->user."/".$entry->ditemid."/comments/".$self->comment->dtalkid;
296 my $mparms = $opt->{mobile_url_extra_params
};
297 $tinyurl .= '?' . join('&', map {$_ . '=' . $mparms->{$_}} keys %$mparms) if $mparms;
298 $tinyurl .= "#comments";
299 $tinyurl = LJ
::Client
::BitLy
->shorten($tinyurl);
300 undef $tinyurl if $tinyurl =~ /^500/;
301 return $msg . " " . $tinyurl;
305 my ($self, $target) = @_;
307 my $comment = $self->comment;
309 return undef unless $comment && $comment->valid;
310 return undef unless $comment->entry && $comment->entry->valid;
311 return undef unless $comment->visible_to($target);
312 return undef if $comment->is_deleted;
314 LJ
::need_res
('js/commentmanage.js');
316 my $comment_body = $comment->body_html;
317 my $buttons = $comment->manage_buttons;
318 my $dtalkid = $comment->dtalkid;
320 $comment_body =~ s/\n/<br \/>/g
;
323 <div id
="ljcmt$dtalkid" class="JournalNewComment">
324 <div
class="ManageButtons">$buttons</div
>
325 <div
class="Body">$comment_body</div
>
329 my $cmt_info = $comment->info;
330 my $cmt_info_js = LJ
::js_dumper
($cmt_info) || '{}';
332 my $posterusername = $self->comment->poster ?
$self->comment->poster->{user
} : "";
335 <script language
="JavaScript">
338 while (my ($k, $v) = each %$cmt_info) {
341 $ret .= "LJ_cmtinfo['$k'] = '$v';\n";
344 my $dtid_cmt_info = {u
=> $posterusername, rc
=> []};
346 $ret .= "LJ_cmtinfo['$dtalkid'] = " . LJ
::js_dumper
($dtid_cmt_info) . "\n";
351 $ret .= $self->as_html_actions;
357 my ($self, $target) = @_;
359 my $comment = $self->comment;
360 my $journal = $self->u;
362 return sprintf("(Deleted comment in %s)", $journal->ljuser_display)
363 unless $comment && $comment->valid && !$comment->is_deleted;
365 my $entry = $comment->entry;
366 return sprintf("(Comment on a deleted entry in %s)", $journal->ljuser_display)
367 unless $entry && $entry->valid;
369 return "(You are not authorized to view this comment)" unless $comment->visible_to($target);
371 my $ju = LJ
::ljuser
($journal);
372 my $pu = LJ
::ljuser
($comment->poster);
373 my $url = $comment->url;
375 my $in_text = '<a href="' . $entry->url . '">an entry</a>';
376 my $subject = $comment->subject_text ?
' "' . $comment->subject_text . '"' : '';
378 my $poster = $comment->poster ?
"by $pu" : '';
379 if ($comment->is_edited) {
380 return "Edited <a href=\"$url\">comment</a> $subject $poster on $in_text in $ju.";
382 return "New <a href=\"$url\">comment</a> $subject $poster on $in_text in $ju.";
387 my ($self, $target) = @_;
389 my $comment = $self->comment;
390 my $journal = $self->u;
392 my $lang = $target->prop('browselang') || $LJ::DEFAULT_LANG
;
395 body
=> LJ
::Lang
::get_text
($lang, 'esn.journal_new_comment.del.comment.params.body', undef, { journal
=> $journal->ljuser_display } ),
396 subject
=> LJ
::Lang
::get_text
($lang, 'esn.journal_new_comment.del.comment.params.subject'),
397 } unless $comment && $comment->valid && !$comment->is_deleted;
399 my $entry = $comment->entry;
401 body
=> LJ
::Lang
::get_text
($lang, 'esn.journal_new_comment.del.entry.params.body', undef, { journal
=> $journal->ljuser_display } ),
402 subject
=> LJ
::Lang
::get_text
($lang, 'esn.journal_new_comment.del.entry.params.subject'),
403 } unless $entry && $entry->valid;
406 body
=> LJ
::Lang
::get_text
($lang, 'esn.journal_new_comment.noauth.params.body'),
407 subject
=> LJ
::Lang
::get_text
($lang, 'esn.journal_new_comment.noauth.params.subject'),
408 } unless $comment->visible_to($target);
410 my $ju = LJ
::ljuser
($journal);
411 my $pu = LJ
::ljuser
($comment->poster);
412 my $url = $comment->url;
413 my $reply_url = $comment->reply_url;
415 my $in_text = '<a href="' . $entry->url . '">an entry</a>';
416 my $subject = $comment->subject_text ?
' "' . $comment->subject_text . '"' : '';
417 my $comment_body = $comment->body_html;
418 $comment_body =~ s/\n/<br \/>/g
;
420 my $poster = $comment->poster ?
"by $pu" : '';
421 if ($comment->is_edited) {
423 body
=> LJ
::Lang
::get_text
($lang, 'esn.journal_new_comment.edited.params.body', undef,
431 subject
=> LJ
::Lang
::get_text
($lang, 'esn.journal_new_comment.edited.params.subject'),
432 content
=> $comment_body,
433 userpic
=> $comment->poster && $comment->poster->userpic ?
$comment->poster->userpic->url : '',
435 action_url
=> $reply_url,
436 action
=> LJ
::Lang
::get_text
($lang, 'esn.journal_new_comment.actions.reply'),
439 action
=> LJ
::Lang
::get_text
($lang, 'esn.journal_new_comment.actions.link'),
444 body
=> LJ
::Lang
::get_text
($lang, 'esn.journal_new_comment.comment.params.body', undef,
452 subject
=> LJ
::Lang
::get_text
($lang, 'esn.journal_new_comment.comment.params.subject'),,
453 content
=> $comment_body,
454 userpic
=> $comment->poster && $comment->poster->userpic ?
$comment->poster->userpic->url : '',
456 action_url
=> $reply_url,
457 action
=> LJ
::Lang
::get_text
($lang, 'esn.journal_new_comment.actions.reply'),
460 action
=> LJ
::Lang
::get_text
($lang, 'esn.journal_new_comment.actions.link'),
466 sub as_html_actions
{
469 my $comment = $self->comment;
470 my $url = $comment->url;
471 my $reply_url = $comment->reply_url;
473 my $ret .= "<div class='actions'>";
474 $ret .= " <a href='$reply_url'>Reply</a>";
475 $ret .= " <a href='$url'>Link</a>";
481 # ML-keys and contents of all items used in this subroutine:
482 # 01 event.journal_new_comment.friend=Someone comments in any journal on my friends page
483 # 02 event.journal_new_comment.my_journal=Someone comments in my journal, on any entry
484 # 03 event.journal_new_comment.user_journal=Someone comments in [[user]], on any entry
485 # 04 event.journal_new_comment.user_journal.deleted=Someone comments on a deleted entry in [[user]]
486 # 05 event.journal_new_comment.my_journal.deleted=Someone comments on a deleted entry in my journal
487 # 06 event.journal_new_comment.user_journal.titled_entry=Someone comments on <a href='[[entryurl]]'>[[entrydesc]]</a> in [[user]]
488 # 07 event.journal_new_comment.user_journal.untitled_entry=Someone comments on <a href='[[entryurl]]'>en entry</a> in [[user]]
489 # 08 event.journal_new_comment.my_journal.titled_entry=Someone comments on <a href='[[entryurl]]'>[[entrydesc]]</a> my journal
490 # 09 event.journal_new_comment.my_journal.untitled_entry=Someone comments on <a href='[[entryurl]]'>en entry</a> my journal
491 # 10 event.journal_new_comment.my_journal.titled_entry.titled_thread.user=Someone comments under <a href='[[threadurl]]'>[[thread_desc]]</a> by [[posteruser]] in <a href='[[entryurl]]'>[[entrydesc]]</a> on my journal
492 # 11 event.journal_new_comment.my_journal.titled_entry.untitled_thread.user=Someone comments under <a href='[[threadurl]]'>the thread</a> by [[posteruser]] in <a href='[[entryurl]]'>[[entrydesc]]</a> on my journal
493 # 12 event.journal_new_comment.my_journal.titled_entry.titled_thread.me=Someone comments under <a href='[[threadurl]]'>[[thread_desc]]</a> by me in <a href='[[entryurl]]'>[[entrydesc]]</a> on my journal
494 # 13 event.journal_new_comment.my_journal.titled_entry.untitled_thread.me=Someone comments under <a href='[[threadurl]]'>the thread</a> by me in <a href='[[entryurl]]'>[[entrydesc]]</a> on my journal
495 # 14 event.journal_new_comment.my_journal.titled_entry.titled_thread.anonymous=Someone comments under <a href='[[threadurl]]'>[[thread_desc]]</a> by (Anonymous) in <a href='[[entryurl]]'>[[entrydesc]]</a> on my journal
496 # 15 event.journal_new_comment.my_journal.titled_entry.untitled_thread.anonymous=Someone comments under <a href='[[threadurl]]'>the thread</a> by (Anonymous) in <a href='[[entryurl]]'>[[entrydesc]]</a> on my journal
497 # 16 event.journal_new_comment.my_journal.untitled_entry.titled_thread.user=Someone comments under <a href='[[threadurl]]'>[[thread_desc]]</a> by [[posteruser]] in <a href='[[entryurl]]'>en entry</a> on my journal
498 # 17 event.journal_new_comment.my_journal.untitled_entry.untitled_thread.user=Someone comments under <a href='[[threadurl]]'>the thread</a> by [[posteruser]] in <a href='[[entryurl]]'>en entry</a> on my journal
499 # 18 event.journal_new_comment.my_journal.untitled_entry.titled_thread.me=Someone comments under <a href='[[threadurl]]'>[[thread_desc]]</a> by me in <a href='[[entryurl]]'>en entry</a> on my journal
500 # 19 event.journal_new_comment.my_journal.untitled_entry.untitled_thread.me=Someone comments under <a href='[[threadurl]]'>the thread</a> by me in <a href='[[entryurl]]'>en entry</a> on my journal
501 # 20 event.journal_new_comment.my_journal.untitled_entry.titled_thread.anonymous=Someone comments under <a href='[[threadurl]]'>[[thread_desc]]</a> by (Anonymous) in <a href='[[entryurl]]'>en entry</a> on my journal
502 # 21 event.journal_new_comment.my_journal.untitled_entry.untitled_thread.anonymous=Someone comments under <a href='[[threadurl]]'>the thread</a> by (Anonymous) in <a href='[[entryurl]]'>en entry</a> on my journal
503 # 22 event.journal_new_comment.user_journal.titled_entry.titled_thread.user=Someone comments under <a href='[[threadurl]]'>[[thread_desc]]</a> by [[posteruser]] in <a href='[[entryurl]]'>[[entrydesc]]</a> in [[user]]
504 # 23 event.journal_new_comment.user_journal.titled_entry.untitled_thread.user=Someone comments under <a href='[[threadurl]]'>the thread</a> by [[posteruser]] in <a href='[[entryurl]]'>[[entrydesc]]</a> in [[user]]
505 # 24 event.journal_new_comment.user_journal.titled_entry.titled_thread.me=Someone comments under <a href='[[threadurl]]'>[[thread_desc]]</a> by me in <a href='[[entryurl]]'>[[entrydesc]]</a> in [[user]]
506 # 25 event.journal_new_comment.user_journal.titled_entry.untitled_thread.me=Someone comments under <a href='[[threadurl]]'>the thread</a> by me in <a href='[[entryurl]]'>[[entrydesc]]</a> in [[user]]
507 # 26 event.journal_new_comment.user_journal.titled_entry.titled_thread.anonymous=Someone comments under <a href='[[threadurl]]'>[[thread_desc]]</a> by (Anonymous) in <a href='[[entryurl]]'>[[entrydesc]]</a> in [[user]]
508 # 27 event.journal_new_comment.user_journal.titled_entry.untitled_thread.anonymous=Someone comments under <a href='[[threadurl]]'>the thread</a> by (Anonymous) in <a href='[[entryurl]]'>[[entrydesc]]</a> in [[user]]
509 # 28 event.journal_new_comment.user_journal.untitled_entry.titled_thread.user=Someone comments under <a href='[[threadurl]]'>[[thread_desc]]</a> by [[posteruser]] in <a href='[[entryurl]]'>en entry</a> in [[user]]
510 # 29 event.journal_new_comment.user_journal.untitled_entry.untitled_thread.user=Someone comments under <a href='[[threadurl]]'>the thread</a> by [[posteruser]] in <a href='[[entryurl]]'>en entry</a> in [[user]]
511 # 30 event.journal_new_comment.user_journal.untitled_entry.titled_thread.me=Someone comments under <a href='[[threadurl]]'>[[thread_desc]]</a> by me in <a href='[[entryurl]]'>en entry</a> in [[user]]
512 # 31 event.journal_new_comment.user_journal.untitled_entry.untitled_thread.me=Someone comments under <a href='[[threadurl]]'>the thread</a> by me in <a href='[[entryurl]]'>en entry</a> in [[user]]
513 # 32 event.journal_new_comment.user_journal.untitled_entry.titled_thread.anonymous=Someone comments under <a href='[[threadurl]]'>[[thread_desc]]</a> by (Anonymous) in <a href='[[entryurl]]'>en entry</a> in [[user]]
514 # 33 event.journal_new_comment.user_journal.untitled_entry.untitled_thread.anonymous=Someone comments under <a href='[[threadurl]]'>the thread</a> by (Anonymous) in <a href='[[entryurl]]'>en entry</a> in [[user]]
515 # -- now, let's begin.
516 sub subscription_as_html
{
517 my ($class, $subscr) = @_;
519 my $arg1 = $subscr->arg1;
520 my $arg2 = $subscr->arg2;
521 my $journal = $subscr->journal;
523 my $key = 'event.journal_new_comment';
526 ### 01 event.journal_new_comment.friend=Someone comments in any journal on my friends page
527 return LJ
::Lang
::ml
($key . '.friend');
530 my ($user, $journal_is_owner);
531 if (LJ
::u_equals
($journal, $subscr->owner)) {
532 $user = 'my journal';
533 $key .= '.my_journal';
534 my $journal_is_owner = 1;
536 $user = LJ
::ljuser
($journal);
537 $key .= '.user_journal';
538 my $journal_is_owner = 0;
541 if ($arg1 == 0 && $arg2 == 0) {
542 ### 02 event.journal_new_comment.my_journal=Someone comments in my journal, on any entry
543 ### 03 event.journal_new_comment.user_journal=Someone comments in [[user]], on any entry
544 return LJ
::Lang
::ml
($key, { user
=> $user });
547 # load ditemid from jtalkid if no ditemid
550 $comment = LJ
::Comment
->new($journal, jtalkid
=> $arg2);
551 return "(Invalid comment)" unless $comment && $comment->valid;
552 $arg1 = eval { $comment->entry->ditemid } unless $arg1;
553 return "(Invalid entry [$arg1:$arg2])" if $@
;
556 my $entry = LJ
::Entry
->new($journal, ditemid
=> $arg1);
557 ### 04 event.journal_new_comment.user_journal.deleted=Someone comments on a deleted entry in [[user]]
558 ### 05 event.journal_new_comment.my_journal.deleted=Someone comments on a deleted entry in my journal
559 return LJ
::Lang
::ml
($key . '.deleted', { user
=> $user }) unless $entry && $entry->valid;
561 my $entrydesc = $entry->subject_text;
563 $entrydesc = "\"$entrydesc\"";
564 $key .= '.titled_entry';
566 $entrydesc = "an entry";
567 $key .= '.untitled_entry';
570 my $entryurl = $entry->url;
571 ### 06 event.journal_new_comment.user_journal.titled_entry=Someone comments on <a href='[[entryurl]]'>[[entrydesc]]</a> in [[user]]
572 ### 07 event.journal_new_comment.user_journal.untitled_entry=Someone comments on <a href='[[entryurl]]'>en entry</a> in [[user]]
573 ### 08 event.journal_new_comment.my_journal.titled_entry=Someone comments on <a href='[[entryurl]]'>[[entrydesc]]</a> my journal
574 ### 09 event.journal_new_comment.my_journal.untitled_entry=Someone comments on <a href='[[entryurl]]'>en entry</a> my journal
575 return LJ
::Lang
::ml
($key,
578 entryurl
=> $entryurl,
579 entrydesc
=> $entrydesc,
582 my $posteru = $comment->poster;
585 my $threadurl = $comment->url;
586 my $thread_desc = $comment->subject_text;
588 $thread_desc = "\"$thread_desc\"";
589 $key .= '.titled_thread';
591 $thread_desc = "the thread";
592 $key .= '.untitled_thread';
596 if ($journal_is_owner) {
597 $posteruser = LJ
::ljuser
($posteru);
600 $posteruser = LJ
::ljuser
($posteru);
604 $posteruser = "(Anonymous)";
605 $key .= '.anonymous';
608 if ($comment->state eq 'B') {
613 return LJ
::Lang
::ml
($key,
616 threadurl
=> $threadurl,
617 thread_desc
=> $thread_desc,
618 posteruser
=> $posteruser,
619 entryurl
=> $entryurl,
620 entrydesc
=> $entrydesc,
625 my ($self, $subscr) = @_;
628 LJ
::Event
->class($subscr->etypeid) ne __PACKAGE__
||
631 my $sjid = $subscr->journalid;
632 my $ejid = $self->event_journal->{userid
};
634 # if subscription is for a specific journal (not a wildcard like 0
635 # for all friends) then it must match the event's journal exactly.
636 return 0 if $sjid && $sjid != $ejid;
638 my ($earg1, $earg2) = ($self->arg1, $self->arg2);
639 my ($sarg1, $sarg2) = ($subscr->arg1, $subscr->arg2);
641 my $comment = $self->comment;
642 my $parent_comment = $comment->parent;
643 my $parent_comment_author = $parent_comment ?
644 $parent_comment->poster : undef;
646 my $entry = $comment->entry;
648 my $watcher = $subscr->owner;
651 $comment->visible_to($watcher) ||
652 LJ
::u_equals
($parent_comment_author, $watcher);
654 # not a match if this user posted the comment and they don't
655 # want to be notified of their own posts
656 # moreover, getselfemail only applies to email, so if it's not an email
657 # notification, it's not a match either
658 if (LJ
::u_equals
($comment->poster, $watcher)) {
660 unless $watcher->get_cap('getselfemail')
661 && $watcher->prop('opt_getselfemail')
662 && $subscr->ntypeid == LJ
::NotificationMethod
::Email
->ntypeid;
665 # watching a specific journal
666 if ($sarg1 == 0 && $sarg2 == 0) {
667 # if this is a community, maintainer gets notified no matter
668 # what entry settings are
669 return 1 unless LJ
::u_equals
($entry->journal, $entry->poster);
671 # if this is their own journal and they selected not to be notified
672 # of comments to this specific entry, well, don't notify them
673 return 0 if $entry->prop('opt_noemail');
678 my $wanted_ditemid = $sarg1;
679 # a (journal, dtalkid) pair identifies a comment uniquely, as does
680 # a (journal, ditemid, dtalkid pair). So ditemid is optional. If we have
681 # it, though, it needs to be correct.
682 return 0 if $wanted_ditemid && $entry->ditemid != $wanted_ditemid;
685 return 1 if $sarg2 == 0;
688 my $wanted_jtalkid = $sarg2;
690 return 1 if $comment->jtalkid == $wanted_jtalkid;
691 $comment = $comment->parent;
701 # when was this comment posted or edited?
704 my $cmt = $self->comment;
706 my $time = $cmt->is_edited ?
$cmt->edit_time : $cmt->unixtime;
707 return $cmt ?
$time : $self->SUPER::eventtime_unix
;
712 return LJ
::Comment
->new($self->event_journal, jtalkid
=> $self->jtalkid);
715 sub available_for_user
{
718 my $journal = $self->event_journal;
719 my ($arg1, $arg2) = ($self->arg1, $self->arg2);
721 # user can always track all comments to their own journal
722 if (LJ
::u_equals
($journal, $u) && !$arg1 && !$arg2) {
726 # user does not receive notification if entry is not visible to user
727 if (my $comment = $self->comment) {
728 if (my $entry = $comment->entry) {
729 unless ($entry->visible_to($u)) {
735 # user can always track comments to a specific entry
740 # user can track comments left to a thread if and only if they have a paid
743 return $u->get_cap('track_thread') ?
1 : 0;
746 # user can track all comments to their community journal, provided
747 # that the community is paid
748 if ($u && $u->can_manage($journal)) {
749 return $journal->get_cap('maintainer_track_comments') ?
1 : 0;
755 sub is_subscription_visible_to
{ 1 }
757 sub get_disabled_pic
{
760 my $journal = $self->event_journal;
762 return LJ
::run_hook
('esn_community_comments_track_upgrade', $u, $journal) || ''
763 unless ref $self ne 'LJ::Event::JournalNewComment' ||
764 $self->arg1 || $self->arg2 || LJ
::u_equals
($u, $journal);
766 return $self->SUPER::get_disabled_pic
($u);
769 # return detailed data for XMLRPC::getinbox
771 my ($self, $target, $flags) = @_;
772 my $extended = ($flags and $flags->{extended
}) ?
1 : 0; # add comments body
774 my $res = $self->SUPER::raw_info
;
776 my $comment = $self->comment;
777 my $journal = $self->u;
779 $res->{journal
} = $journal->user;
781 return { %$res, action
=> 'deleted' }
782 unless $comment && $comment->valid && !$comment->is_deleted;
784 my $entry = $comment->entry;
785 return { %$res, action
=> 'comment_deleted' }
786 unless $entry && $entry->valid;
788 return { %$res, visibility
=> 'no' } unless $comment->visible_to($target);
790 $res->{entry
} = $entry->url;
791 $res->{comment
} = $comment->url;
792 if (my $poster = $comment->poster) {
793 $res->{poster
} = $poster->user;
794 if($poster->is_identity){
795 my $i = $poster->identity;
796 $res->{'poster_identity_type'} = $i->pretty_type;
797 $res->{'poster_identity_value'} = $i->value;
798 $res->{'poster_identity_url'} = $i->url($poster);
799 $res->{'poster_identity_display'} = $poster->display_name;
802 $res->{subject
} = $comment->subject_text;
805 $res->{extended
}->{subject_raw
} = $comment->subject_raw;
806 $res->{extended
}->{body
} = $comment->body_raw;
807 $res->{extended
}->{dtalkid
} = $comment->dtalkid;
810 if ($comment->is_edited) {
811 return { %$res, action
=> 'edited' };
813 return { %$res, action
=> 'new' };
818 my ($self, %args) = @_;
819 my $cid = delete $args{'cluster'}; # optional
820 my $limit = int delete $args{'limit'}; # optional
821 my $original_limit = int $limit;
823 croak
("Unknown options: " . join(', ', keys %args)) if %args;
824 croak
("Can't call in web context") if LJ
::is_web_context
();
826 my $comment = $self->comment;
827 my $parent_comment = $comment->parent;
828 my $entry = $comment->entry;
830 my $comment_author = $comment->poster;
831 my $parent_comment_author = $parent_comment ?
832 $parent_comment->poster :
834 my $entry_author = $entry->poster;
835 if (!$entry_author) {
836 warn "No entry author for entry " . $entry->url;
840 my $entry_journal = $entry->journal;
844 if ($comment_author && $comment->state eq 'B' && $entry_journal->is_personal && $entry_journal->in_class('paid')) {
847 my @ids = $comment_author->friend_uids;
848 my %is_friend = map { $_ => 1 } @ids; # uid -> 1
850 require LJ
::M
::ProfilePage
;
851 my $pm = LJ
::M
::ProfilePage
->new($comment_author);
852 require LJ
::M
::FriendsOf
;
853 my $fro_m = LJ
::M
::FriendsOf
->new($comment_author,
854 sloppy
=> 1, # approximate if no summary info
855 mutuals_separate
=> 0,
856 # TODO: lame that we have to pass this in, but currently
857 # it's not cached on the $u singleton
858 friends
=> \
%is_friend,
859 hide_test_cb
=> sub {
860 return $pm->should_hide_friendof($_[0]);
863 my $friend_ofs_count = $fro_m->friend_ofs;
865 return if $friend_ofs_count <= $LJ::SPAM_MAX_FRIEND_OFS
&&
866 (time() - $comment_author->timecreate) / 86400 <= $LJ::SPAM_MAX_DAYS_CREATED
;
868 return if LJ
::AntiSpam
->is_spam_in_friends_journals($entry_journal, $comment_author);
871 my $acquire_sub_slot = sub {
875 return $how_much unless $original_limit;
877 $how_much = $limit if $limit < $how_much;
883 croak
("Unknown options: " . join(', ', keys %args)) if %args;
884 croak
("Can't call in web context") if LJ
::is_web_context
();
886 my $email_ntypeid = LJ
::NotificationMethod
::Email
->ntypeid;
888 # own comments are deliberately sent to email only
891 (!$cid || $comment_author->clusterid == $cid) &&
892 $comment_author->prop('opt_getselfemail') &&
893 $comment_author->get_cap('getselfemail') &&
894 $acquire_sub_slot->()
896 push @subs, LJ
::Subscription
->new_from_row({
897 'etypeid' => LJ
::Event
::JournalNewComment
->etypeid,
898 'userid' => $comment_author->id,
899 'ntypeid' => $email_ntypeid,
903 # send a notification to the author of the "parent" comment, if they
906 $parent_comment && $parent_comment_author &&
907 (!$cid || $parent_comment_author->clusterid == $cid) &&
909 # if they are responding to themselves and wish to get that, we've
910 # already handled it above
911 !LJ
::u_equals
($comment_author, $parent_comment_author) &&
913 # if parent_comment_author is also the author of the container entry,
914 # we should respect their choice to not get this comment, as set
915 # in the entry properties
916 (!LJ
::u_equals
($parent_comment_author, $entry_author) ||
917 !$entry->prop('opt_noemail'))
919 my @subs2 = LJ
::Subscription
->find($parent_comment_author,
920 'event' => 'CommentReply',
921 'require_active' => 1,
924 push @subs2, LJ
::Subscription
->new_from_row({
925 'etypeid' => LJ
::Event
::CommentReply
->etypeid,
926 'userid' => $parent_comment_author->id,
927 'ntypeid' => $email_ntypeid,
928 }) if $parent_comment_author->{'opt_gettalkemail'} eq 'Y';
930 my $count = scalar(@subs2);
931 if ($count && ($count = $acquire_sub_slot->($count))) {
932 $#subs2 = $count - 1;
937 # send a notification to the author of the entry, if they
940 # if they are responding to themselves and wish to get that, we've
941 # already handled it above
942 !LJ
::u_equals
($comment_author, $entry_author) &&
943 (!$cid || $entry_author->clusterid == $cid) &&
945 !$entry->prop('opt_noemail')
948 if (!LJ
::u_equals
($entry_author, $entry_journal)) {
950 my @subs2 = LJ
::Subscription
->find($entry_author,
951 'event' => 'CommunityEntryReply',
952 'require_active' => 1,
955 my $count = scalar(@subs2);
956 if ($count && ($count = $acquire_sub_slot->($count))) {
957 $#subs2 = $count - 1;
962 push @subs, LJ
::Subscription
->new_from_row({
963 'etypeid' => LJ
::Event
::JournalNewComment
->etypeid,
964 'userid' => $entry_author->id,
965 'ntypeid' => $email_ntypeid,
967 $entry_author->{'opt_gettalkemail'} eq 'Y' && $acquire_sub_slot->();
970 return @subs unless ($limit || !$original_limit);
972 # handle tracks as usual
973 push @subs, $self->SUPER::subscriptions
(
982 my ($self, $ownerid) = @_;
984 return 1 if $self->arg1 || $self->arg2;
985 return 1 unless $self->event_journal->id == $ownerid;
997 my $parent = $self->comment->parent;
998 my $entry = $self->comment->entry;
1001 if($subject = $entry->subject_text) {
1003 $subject = (substr $subject, 0, $opts{cut
})."..."
1004 if $opts{cut
} && length($subject) > $opts{cut
};
1007 $subject = LJ
::Lang
::get_text
($lang, "widget.officialjournals.nosubject")
1011 unless($u->equals($self->event_journal)) {
1013 if($self->event_journal->journaltype eq 'C') {
1015 if($self->comment->parent) {
1016 return LJ
::Lang
::get_text
($lang, "esn.push.notification.eventtrackcommetstreadinentrytitle", 1, {
1017 user
=> $self->comment->poster->user,
1018 subject
=> $subject,
1019 poster
=> $self->comment->parent->poster->user,
1020 journal
=> $self->event_journal->user,
1024 return LJ
::Lang
::get_text
($lang, "esn.push.notification.eventtrackcommetsonentrytitle", 1, {
1025 user
=> $self->comment->poster->user,
1026 subject
=> $subject,
1027 journal
=> $self->event_journal->user,
1031 return LJ
::Lang
::get_text
($lang, "esn.push.notification.eventtrackcommetsonentrytitle", 1, {
1032 user
=> $self->comment->poster->user,
1033 subject
=> $subject,
1034 journal
=> $self->event_journal->user,
1040 if($parent && LJ
::u_equals
($parent->poster, $u)) {
1041 return LJ
::Lang
::get_text
($lang, "esn.push.notification.commentreply", 1, {
1042 user
=> $self->comment->poster->user,
1043 journal
=> $self->event_journal->user,
1046 } elsif($self->event_journal->journaltype eq 'C') {
1047 return LJ
::Lang
::get_text
($lang, "esn.push.notification.communityentryreply", 1, {
1048 user
=> $self->comment->poster->user,
1049 community
=> $self->event_journal->user,
1053 return LJ
::Lang
::get_text
($lang, "esn.push.notification.journalnewcomment", 1, {
1054 user
=> $self->comment->poster->user,
1060 sub as_push_payload
{
1065 my $entry = $self->comment->entry;
1066 my $parent = $self->comment->parent;
1068 my $payload = { 'p' => $entry->ditemid,
1069 'c' => $self->comment->dtalkid,
1073 unless($u->equals($self->event_journal)) {
1075 if($self->event_journal->journaltype eq 'C') {
1077 $payload->{'t'} = 26;
1078 $payload->{'j'} = $self->event_journal->user;
1079 $payload->{'r'} = $self->comment->parent->dtalkid;
1083 $payload->{'t'} = 25;
1084 $payload->{'j'} = $self->event_journal->user;
1089 $payload->{'j'} = $self->event_journal->user;
1091 if($parent && LJ
::u_equals
($parent->poster, $u)) {
1092 $payload->{'t'} = 5;
1094 } elsif($self->event_journal->journaltype eq 'C') {
1095 $payload->{'t'} = 4;
1098 $payload->{'t'} = 3;
1104 sub update_events_counter
{
1107 my $comment = $self->comment;
1108 my $journalu = $self->event_journal;
1110 return unless $comment && $comment->valid;
1111 return unless $journalu;
1113 return if $comment->is_deleted || $comment->is_spam;
1115 my $entry = $comment->entry;
1116 my $parent = $comment->parent;
1117 my $jtalkid = $comment->jtalkid;
1118 my $poster = $comment->poster;
1120 return unless $entry && $entry->valid;
1122 return if $poster && ($poster->is_suspended || $poster->is_expunged);
1124 my $jitemid = $entry->jitemid;
1125 my $user = $entry->poster;
1127 my $journalid = $journalu->userid;
1129 return unless $user;
1131 my $pposter = $parent && $parent->poster;
1133 unless ( $user->equals($poster) ) {
1134 LJ
::Widget
::HomePage
::CommentsCounter
->add_comment($user, pack("NNN", $journalid, $jitemid, $jtalkid));
1137 if ( $pposter && !$pposter->equals($poster) && !$pposter->equals($user) ) {
1138 LJ
::Widget
::HomePage
::CommentsCounter
->add_comment($pposter, pack("NNN", $journalid, $jitemid, $jtalkid));