body<= qr/./); my $head = \$_[1]->{'head'}; my $bodyopts = \$_[1]->{'bodyopts'}; my $remote = LJ::get_remote(); return "" unless $remote; my $mode = $GET{'mode'} || $POST{'mode'} || "init"; if ($GET{'itemid'} || $POST{'itemid'}) { $mode = "edit"; } LJ::need_res( { priority => $LJ::OLD_RES_PRIORITY }, 'stc/entry.css' ); LJ::need_res( 'js/6alib/inputcomplete.js' ); # are they asking to be authed as someone else? my $authas = $GET{'authas'} || $remote->{'user'}; my $u = LJ::get_authas_user($authas); return LJ::bad_input( $ML{'error.invalidauth'} ) unless $u; return LJ::bad_input( $ML{'error.person'} ) unless $u->is_individual; # are we modify a community post? my $usejournal = $GET{'usejournal'} || $POST{'usejournal'} || $GET{'journal'}; undef $usejournal if $usejournal eq $u->{'user'}; # ignore if it's the user # extra get arguments my $getextra = ''; $getextra .= "authas=$authas&" if $authas ne $u->{'user'}; $getextra .= "usejournal=$usejournal&" if $usejournal; chop $getextra; $getextra = "?$getextra" if $getextra; my $entry_chooser = sub { my $ret; my $ref = shift; my %opts = @_; my %res = %$ref; $ret .= ""; $ret .= "
"; my %props = (); for (my $i=1; $i<=$res{'prop_count'}; $i++) { $props{$res{"prop_${i}_itemid"}}->{$res{"prop_${i}_name"}} = $res{"prop_${i}_value"}; } my $ev_count = $res{'events_count'}; for (my $i=1; $i<=$ev_count; $i++) { my $itemid = $res{"events_${i}_itemid"}; my $ditemid = $itemid * 256 + $res{"events_${i}_anum"}; $ret .= "
"; $ret .= "
\n"; $ret .= LJ::html_hidden('itemid',$ditemid,'mode',"edit"); $ret .= LJ::html_submit( "itemid-$ditemid", $ML{'.edit.this.entry'} ); $ret .= "
"; $ret .= "
"; $ret .= " "; $ret .= " (Posted by: " . LJ::ljuser($res{"events_${i}_poster"}) . ")" if $usejournal; ### security indicator my $sec = ' '; if ($res{"events_${i}_security"} eq "private") { $sec .= BML::fill_template("securityprivate"); } elsif ($res{"events_${i}_security"} eq "usemask") { if ($res{"events_${i}_allowmask"} == 0) { # custom security with no group -- essentially private $sec .= BML::fill_template("securityprivate"); } elsif ($res{"events_${i}_allowmask"} > 1) { # custom group $sec .= BML::fill_template("securitygroups"); } else { # friends only $sec .= BML::fill_template("securityprotected"); } } $ret .= $sec; if (my $subj = $res{"events_${i}_subject"}) { LJ::CleanHTML::clean_subject_all(\$subj); # clean_subject_all returns plain text, so no HTML escaping here $ret .= " $subj"; } $ret .= "
\n"; # Use LJ::Entry object and event_html_summary for cleaner HTML handling my $journal_u = $usejournal ? LJ::load_user($usejournal) : $u; my $entry = LJ::Entry->new($journal_u, ditemid => $ditemid); if ($entry && $entry->valid && $entry->visible_to($remote)) { my $event = $entry->event_html_summary(300); if ( defined $event && length $event ) { $ret .= $event; } else { $ret .= $ML{'.htmlonly'}; } } $ret .= "
\n"; } $ret .= "
"; return $ret; }; if ($mode eq "edit") { # user object for community if we're modifying one my $usejournal_u; if ($usejournal) { $usejournal_u = LJ::load_user($usejournal); return LJ::bad_input( $ML{'error.nocomm'} ) unless $usejournal_u; return LJ::bad_input( $ML{'error.invalidauth'} ) unless $usejournal_u->is_comm; } ### ### HAVE AN ITEMID TO EDIT ### if ($GET{'itemid'} || $POST{'itemid'}) { # the 'itemid' form element is really an 'itemid' my $ditemid = $GET{'itemid'} || $POST{'itemid'}; my $anum = $ditemid % 256; my $itemid = $ditemid >> 8; my $u_for_entry = $usejournal ? $usejournal_u : $u; my $entry_obj = LJ::Entry->new($u_for_entry, ditemid => $ditemid); # this is a sanity check, make sure the entry we got is visible to the # person trying to edit it. return "" unless $entry_obj->visible_to( $remote ); # do getevents request my %res = (); LJ::do_request({ 'mode' => 'getevents', 'selecttype' => 'one', 'ver' => $LJ::PROTOCOL_VER, 'user' => $u->{'user'}, 'usejournal' => $usejournal, 'itemid' => $itemid }, \%res, { "noauth" => 1, 'u' => $u, ignorecanuse => 1 } ); # was there a protocol error? return "" unless $res{'success'} eq 'OK'; # does the requested entry exist? return "" unless $res{'events_count'} && $res{'events_1_anum'} == $anum; # are we authorized to edit other peoples' posts in this community? my $disabled_save = 0; my $disabled_delete = 0; my $disabled_spamdelete = 0; if ( $usejournal && $res{'events_1_poster'} ne $u->user ) { $disabled_delete = ! $u->can_manage( $usejournal_u ); $disabled_save++; } $disabled_spamdelete = $disabled_delete || !$usejournal || ($res{'events_1_poster'} eq $u->{'user'}); $disabled_spamdelete ||= LJ::sysban_check( 'spamreport', $usejournal_u->user ) if $usejournal_u; # read-only posters and journals cannot be edited if (!$disabled_save && ($u->is_readonly || ($usejournal_u && $usejournal_u->is_readonly))) { $disabled_save++; } return BML::redirect( "/entry/" . $u_for_entry->user . "/$ditemid/edit" ) if ! $disabled_save && LJ::BetaFeatures->user_in_beta( $remote => "updatepage" ); ### ### SAVE EDITS ### # add in this value in case we had to submit the form using # javascript if ( $POST{'submit_value'} ) { $POST{$POST{'submit_value'}} = 1; } # are we spellchecking before we post? my $spellcheck_html; my $did_spellcheck; if ($LJ::SPELLER && $POST{'action:spellcheck'}) { $did_spellcheck++; my $s = new LJ::SpellCheck { 'spellcommand' => $LJ::SPELLER, 'color' => '', }; my $event = LJ::ehtml($POST{'event'}); $spellcheck_html = $s->check_html(\$event); $spellcheck_html = "" unless $spellcheck_html ne ""; } # TODO: Move this to the protocol? if ($POST{'action:savemaintainer'} && !$disabled_spamdelete) { return LJ::bad_input($ML{'error.invalidform'}) unless LJ::check_form_auth(); my @props = qw( adult_content_maintainer_reason adult_content_maintainer opt_nocomments_maintainer ); my $propset = {}; foreach my $pname (@props) { my $p = LJ::get_prop("log", $pname); next unless $p; $propset->{$pname} = $POST{"prop_$pname"}; } LJ::set_logprop($usejournal_u, $itemid, $propset); return BML::redirect($entry_obj->url); } # they clicked the save or delete button if (!$spellcheck_html && ($POST{'action:save'} || $POST{'action:delete'} || $POST{'action:deletespam'})) { return LJ::bad_input($ML{'error.invalidform'}) unless LJ::check_form_auth(); my %req = ( 'mode' => 'editevent', 'ver' => $LJ::PROTOCOL_VER, 'user' => $u->{'user'}, 'usejournal' => $usejournal, 'itemid' => $itemid, 'xpost' => '0' ); LJ::entry_form_decode(\%req, \%POST); # Delete $req{'event'} = '' if $POST{'action:delete'} || $POST{'action:deletespam'}; # mark as spam, if need be LJ::mark_entry_as_spam($usejournal_u, $itemid) if $POST{'action:deletespam'}; # if the action is to delete it, then let's note that if ($POST{'action:delete'} || $POST{'action:deletespam'}) { # now log the event created above ($usejournal ? $usejournal_u : $u)->log_event('delete_entry', { remote => $remote, actiontarget => $ditemid, method => 'web', }); } # check for spam domains LJ::Hooks::run_hooks('spam_check', $u, \%req, 'entry'); # do editevent request LJ::do_request(\%req, \%res, { 'noauth' => 1, 'u' => $u }); # check response unless ($res{'success'} eq "OK") { return "
  • $res{'errmsg'}
  • p?>"; } my $deleted = $req{event} ? 0 : 1; my $journalu = $usejournal ? $usejournal_u : $u; my $j_base = $journalu->journal_base; my $entry_url = $entry_obj->url; my $edititemlink = "/editjournal?itemid=$ditemid"; my $edit_url = $edititemlink . "&journal=" . $journalu->user; # update crosspost if we're posting to our own journal and have # selected crosspost. my $xpost_result = ''; if ($journalu == $remote && ($POST{prop_xpost_check} || $GET{prop_xpost_check})) { my ($xpost_successes, $xpost_failures) = LJ::Protocol::schedule_xposts($remote, $ditemid, $deleted, sub { my $acctid = (shift)->acctid; ($POST{"prop_xpost_$acctid"} || $GET{"prop_xpost_$acctid"}, {password => $POST{"prop_xpost_password_$acctid"} || $GET{"prop_xpost_password_$acctid"}, auth_challenge => $POST{"prop_xpost_chal_$acctid"} || $GET{"prop_xpost_chal_$acctid"}, auth_response => $POST{"prop_xpost_resp_$acctid"} || $GET{"prop_xpost_resp_$acctid"}}) }); $xpost_result .= "\n"; $xpost_result .= "
    "; } my $result = ""; $result .= ""; $result .= "
    "; my $message; if ($deleted) { $result .= ($journalu->is_community) ? "" : ""; $result .= "" if $POST{'action:deletespam'}; $result .= $xpost_result; my $deleted_extras = LJ::Hooks::run_hook('entry_deleted_page_extras'); $result .= $deleted_extras if defined $deleted_extras; } else { $message = LJ::auto_linkify( LJ::html_newlines( LJ::ehtml( $res{message} ) ) ); $result .= ($journalu->is_community) ? "" : ""; $result .= "
    $message
    " if $message; $result .= $xpost_result; if ($POST{'action:save'} && $entry_obj->is_suspended) { $result .= ""; } } if (!$deleted) { my $security_ml; my $filternames = ''; my $c_or_p = $journalu->is_community ? 'c' : 'p'; if ($req{"security"} eq "private") { $security_ml = "post.security.private.$c_or_p"; } elsif ($req{"security"} eq "usemask") { if ($req{"allowmask"} == 0) { # custom security with no group -- essentially private $security_ml = "post.security.private.$c_or_p"; } elsif ($req{"allowmask"} > 1) { # custom group $filternames = $journalu->security_group_display( $req{allowmask} ); $security_ml = "post.security.custom"; } else { # access list only $security_ml = "post.security.access.$c_or_p"; } } else { $security_ml = "post.security.public"; } $result .= " $filternames } ) . " p?>"; my $subject = $req{subject}; if ( length $subject > 0 ) { # use the HTML cleaner on the entry subject, # then display it without escaping LJ::CleanHTML::clean_subject( \$subject ); } else { # display (no subject) if subject is empty $subject = $ML{'.extradata.subj.no_subject'}; } $result .= ""; } $result .= "
    $ML{'.success.fromhere'}
    "; $result .= "
    "; return $result; } ### ### SHOW EDIT FORM ### my $auth = "

    "; $auth .= ""; $auth .= $usejournal ? LJ::ljuser($res{'events_1_poster'}) . " in community " . LJ::ljuser($usejournal) : LJ::ljuser($remote); $auth .= LJ::html_hidden("usejournal", $usejournal); $auth .= "

    "; my $username = $usejournal ? $usejournal : $remote->user; $auth .= ""; my ($year, $mon, $mday, $hour, $min) = split(/\D/, $res{"events_1_eventtime"}); my $datetime; my $date = LJ::html_datetime_decode({ 'name' => "date_ymd", }, \%POST); if ($date ne "0000-00-00 00:00:00") { my ($date, $time) = split( m/ /, $date); $datetime = "$date $POST{'hour'}:$POST{'min'}"; } else { $datetime = "$year-$mon-$mday $hour:$min"; } my $subject = $POST{'subject'} || $res{'events_1_subject'}; my $event = $POST{'event'} || $res{'events_1_event'}; my $curmask = $res{'events_1_allowmask'}; my $cursec = $res{'events_1_security'} || $POST{'security'}; if ($cursec eq 'usemask') { $cursec = $curmask == 1 ? "friends" : "custom"; } # start edit form my $ret; my $js; $ret .= ""; $ret .= "
    "; $ret .= "
    "; $ret .= LJ::form_auth(); $ret .= LJ::html_hidden('itemid', $ditemid,'mode','edit','edited',1) . "\n"; $event = LJ::durl($event); my $journalu = $usejournal ? LJ::load_user($usejournal) : $remote; LJ::EmbedModule->parse_module_embed($journalu, \$event, edit => 1); $event = LJ::eurl($event); my $suspend_msg = $entry_obj && $entry_obj->should_show_suspend_msg_to($remote) ? 1 : 0; my $entry = { 'mode' => "edit", 'auth_as_remote' => 1, 'subject' => $subject, 'event' => $event, 'datetime' => $datetime, 'usejournal' => $usejournal, 'security' => $cursec, 'security_mask' => $curmask, 'auth' => $auth, 'remote' => $remote, 'spellcheck_html' => $spellcheck_html, 'richtext' => LJ::is_enabled('richtext'), 'mood' => $res{'events_1_'}, 'disabled_save' => $disabled_save, 'disabled_delete' => $disabled_delete, 'disabled_spamdelete' => $disabled_spamdelete, 'maintainer_mode' => !$disabled_spamdelete, 'suspended' => $suspend_msg, }; for (my $i = 1; $i <= $res{'prop_count'}; $i++) { $entry->{"prop_" . $res{"prop_${i}_name"}} = $res{"prop_${i}_value"}; } # add property for current music button displaying if last.fm user specified $entry->{prop_last_fm_user} = $u_for_entry->prop('last_fm_user'); # add property for xpost data (this is removed by the getevents protocol) # FIXME: this should be added by the entry form, but since it doesn't have an # entry object right now, this is just easier $entry->{prop_xpost} = $entry_obj->prop( 'xpost' ); $entry->{$_} = $POST{$_} foreach keys %POST; $entry->{'richtext_default'} = $entry->{"prop_used_rte"} ? 1 : 0, my $onload; if ( $res{events_1_converted_with_loss} ) { $ret .= "
    $ML{'.invalid_encoding'}

    "; } $ret .= LJ::entry_form($entry, \$$head, \$onload); $ret .= "
    "; $ret .= "
    "; # javascript to initialize entry form since we've just called into entry_form # -- shove into \$head which is a reference into $_[1]->{head} and will # be placed in the correct BML head portion later # -- this is a hack, should be done by weblib and pushed into \$$head above # in a way which is compatible with both this page and update $$head .= qq{ }; return $ret; } ### ### NO ITEMID - SELECT ENTRY TO EDIT ### ### already authenticated from above return BML::redirect("$LJ::SITEROOT/editjournal") unless LJ::did_post(); my %res; my %req = ( 'mode' => 'getevents', 'ver' => $LJ::PROTOCOL_VER, 'user' => $u->{'user'}, 'usejournal' => $usejournal, 'truncate' => 300, 'noprops' => 1, ); # last 1 if ($POST{'selecttype'} eq "last") { $req{'selecttype'} = 'one'; $req{'itemid'} = -1; # last n } elsif ($POST{'selecttype'} eq 'lastn') { $req{'selecttype'} = 'lastn'; $req{'howmany'} = $POST{'howmany'}; # day } elsif ($POST{'selecttype'} eq 'day') { $req{'selecttype'} = 'day'; $req{$_} = $POST{$_} foreach qw(year month day); } # do getevents request LJ::do_request(\%req, \%res, { 'noauth' => 1, 'u' => $u }); # check response unless ($res{'success'} eq "OK") { return "\n" . "
  • p?>"; } # only one item returned? go directly to edit it if ($res{'events_count'} == 1) { my $ditemid = ($res{'events_1_itemid'} << 8) + $res{'events_1_anum'}; my $ditemid_get = $getextra ? "$getextra&itemid=$ditemid" : "?itemid=$ditemid"; return BML::redirect("$LJ::SITEROOT/editjournal$ditemid_get"); } # how many results did we get? my $ev_count = $res{'events_count'}; unless ($ev_count) { if ($req{'selecttype'} eq 'lastn') { return "\n" . "\n"; } return "\n" . "\n"; } ### display results return $entry_chooser->(\%res, show_ad => 1); } elsif ($mode eq "init") { my $ret = ''; # no authentication needs to be done on this page, it's just a form anyway $ret .= "
    "; # user switcher $ret .= "
    \n"; $ret .= LJ::make_authas_select($remote, { 'authas' => $GET{'authas'}, 'type' => 'P' }); $ret .= "
    \n\n"; # header $ret .= " "href='$LJ::SITEROOT/editprivacy'" } ) if $remote->can_use_mass_privacy; $ret .= " p?>\n"; # edit form $ret .= "
    \n"; $ret .= LJ::html_hidden("mode","edit"); $ret .= "\n"; # view type $ret .= "\n\n"; # use journal $ret .= "\n"; # submit button $ret .= "\n"; $ret .= "
    $ML{'.viewwhat'}\n"; $ret .= LJ::html_check({ 'type' => 'radio', 'name' => 'selecttype', 'id' => 'selecttype-last', 'value' => 'last', 'selected' => 1 }); $ret .= "
    \n"; $ret .= LJ::html_check({ 'type' => 'radio', 'name' => 'selecttype', 'id' => 'selecttype-lastn', 'value' => 'lastn' }) . " "; $ret .= LJ::html_text({ 'name' => 'howmany', 'size' => '3', 'maxlength' => '2', 'value' => '20', 'onchange' => "checkRadioButton('selecttype-lastn');" }) . " "; $ret .= "
    \n"; $ret .= LJ::html_check({ 'type' => 'radio', 'name' => 'selecttype', 'id' => 'selecttype-day', 'value' => 'day' }); $ret .= ""; my @time = localtime(time); my $mday = sprintf("%02d", $time[3]); my $mon = sprintf("%02d", $time[4] + 1); my $year = $time[5] + 1900; $ret .= LJ::html_text({ 'name' => 'year', 'size' => '5', 'maxlength' => '4', 'value' => $year, 'onchange' => "checkRadioButton('selecttype-day');" }) . "-"; $ret .= LJ::html_text({ 'name' => 'month', 'size' => '3', 'maxlength' => '2', 'value' => $mon, 'onchange' => "checkRadioButton('selecttype-day');" }) . "-"; $ret .= LJ::html_text({ 'name' => 'day', 'size' => '3', 'maxlength' => '2', 'value' => $mday, 'onchange' => "checkRadioButton('selecttype-day');" }) . "\n"; $ret .= "
    $ML{'.in'}\n"; $ret .= LJ::html_text({ 'name' => 'usejournal', 'size' => '20', 'maxlength' => '25', 'value' => $GET{'usejournal'} }) . " "; $ret .= " $ML{'optional'}
     " . LJ::html_submit(undef, $ML{'.btn.proceed'}) . "
    \n"; $ret .= "
    \n"; my %res; my %req = ( mode => 'getevents', ver => $LJ::PROTOCOL_VER, user => $u->user, usejournal => $usejournal, truncate => 300, noprops => 1, selecttype => 'lastn', howmany => 5, ); # do getevents request LJ::do_request(\%req, \%res, { noauth => 1, u => $u }); if ($res{success} eq "OK" && $res{events_count} > 0) { $ret .= $entry_chooser->(\%res); } $ret .= "
    "; return $ret; } } _code?> <=body bodyopts=>{'bodyopts'}; _code?> head<= {'head'}; _code?> }; _code?> <=head page?>