qr/./); # $_[0] is a pre-request scratch area # put variables here so that we can access them later # outside of this _code block my $title = \$_[0]->{'title'}; my $head = \$_[0]->{'head'}; my $body = \$_[0]->{'body'}; my $bodyopts = \$_[0]->{'bodyopts'}; my $onload = \$_[0]->{'onload'}; my $update_type = $POST{'type'} || $GET{'type'}; $$title = ($update_type eq 'sticky') ? $ML{'.title2_sticky'} : $ML{'.title2'}; if ($GET{qotd} && !LJ::is_enabled('qotd')) { $$body = LJ::error_list( BML::ml('qotd.disabled', { sitename => $LJ::SITENAMESHORT } )); return; } # server down? if ($LJ::SERVER_DOWN) { $$body = LJ::server_down_html(); return; } LJ::set_active_crumb("postentry"); LJ::Controller::Post->rte_langmap(); # invalid text input? unless (LJ::text_in(\%POST)) { $$body = ""; return; } ## This header is to pass page content through IE8 XSS Filter. ## See also htdocs/preview/entry.bml. LJ::Request->header_out("X-XSS-Protection" => 0); ## And this header is to prevent Clickjacking attacks LJ::Request->header_out("X-Frame-Options" => 'deny'); my $usejournalu; if (my $usejournal = $GET{'usejournal'} || $POST{'usejournal'}) { $usejournalu = LJ::load_user($usejournal); unless ($usejournalu) { # invalid usejournal $$body = $ML{'.error.invalidusejournal'}; return; } } # get remote and see if they can post right now my $remote = LJ::get_remote(); # Should we show try and buy my $show_trynbuy = LJ::TryNBuy->can_enable($remote) || LJ::TryNBuy->active($remote); # Errors that are unlikely to change between starting # to compose an entry and submitting it. if ($remote) { if ($remote->underage) { return BML::redirect("$LJ::SITEROOT/agecheck/?s=1"); } return if LJ::bad_password_redirect(); my @posting_access = $remote->posting_access_list; if ( $remote->is_identity && scalar(@posting_access) == 0 && ! $usejournalu ) { $$title = $ML{'Sorry'}; $$body = BML::ml('.error.nonusercantpost', {'sitename' => $LJ::SITENAME}); return; } if (! LJ::get_cap($remote, "can_post")) { $$title = $ML{'.error.cantpost.title'}; $$body = $LJ::MSG_NO_POST || $ML{'.error.cantpost'}; return; } if (LJ::get_cap($remote, "disable_can_post")) { unless (LJ::run_hook("update.bml_disable_can_post", { title => $title, body => $body, })) { $$title = $ML{'.error.disabled.title'}; $$body = $ML{'.error.disabled'}; } return; } } my %res = (); # see if we need to do any transformations LJ::run_hooks("transform_update_$POST{transform}", \%GET, \%POST) if $POST{transform}; LJ::need_res(qw( stc/display_none.css stc/lj_base.css stc/entry.css stc/trava.css stc/widgets/selecttags.css js/lib/jquery-ui/jquery.ui.position.min.js js/lib/jquery-ui/jquery.ui.autocomplete.min.js js/jquery/jquery.bgiframe.js js/gears_init.js js/scanner.js js/photobucket_jw.js )); LJ::need_var(last_fm_user => $remote && $remote->{'last_fm_user'}); LJ::need_var(last_fm_api_key => $LJ::LAST_FM_API_KEY); ## figure out times my $now = DateTime->now; # if user has timezone, use it! if ($remote && $remote->prop("timezone")) { my $tz = $remote->prop("timezone"); $tz = $tz ? eval { DateTime::TimeZone->new(name => $tz); } : undef; $now = eval { DateTime->from_epoch(epoch => time(), time_zone => $tz); } if $tz; } if (LJ::is_enabled("delayed_entries")) { LJ::need_string(qw/ entryform.sticky_replace.edit entryform.sticky.edit entryform.choose_date/); } my ($year, $mon, $mday, $hour, $min) = ($now->year, sprintf("%02d", $now->month), sprintf("%02d", $now->day), $now->hour, sprintf("%02d", $now->minute)); my $subject = $POST{'subject'} || $GET{'subject'}; my $event = $POST{'event'} || $GET{'event'} || $POST{'body'}; my $tags = $POST{'prop_taglist'} || $GET{'prop_taglist'}; my $url = $GET{'url'}; # Tags if ($remote) { my @tag_names; my $u = $usejournalu || $remote; my $utags = $u->tags; my $username = $u->user; if (keys %$utags) { @tag_names = sort { lc $a cmp lc $b } map { $_->{name} } values %$utags; } $$head .= "\n"; } # if a QotD id was passed in, fill in the fields with that QotD my $qid = $GET{qotd}+0; my $qotd = $qid ? LJ::QotD->get_single_question($qid) : ''; if ($qotd) { $subject = LJ::Widget::QotD->subject_text($qotd, user => $remote); my $lncode = ($remote && $remote->prop('browselang')) ? $remote->prop('browselang') : $LJ::DEFAULT_LANG; $event = LJ::Widget::QotD->embed_text($qotd, $lncode); $tags = LJ::Widget::QotD->tags_text($qotd); LJ::run_hooks('qotd_modify_tags', \$tags); my $text = LJ::Widget::QotD->qotd_display_embed( questions => [ $qotd ], form_disabled => 1 ); $$head .= ""; } if ($url) { ## currently, the URL is for YouTube only. ## in future support for other quick embeds will be added. ## TODO: use oEmbed for YouTube (http://apiblog.youtube.com/2009/10/oembed-support.html) if ($url =~ m!http://www.youtube.com/watch\?v=([\w\-]+)! || $url =~ m!http://www.youtube.com/v/([\w\-]+)!) { $event = <<"EMBED"; EMBED } } my $reposted_from = ''; my $repost_hidden = ''; # in case of repost other entry by its uri we should check its visibility # for remote user. if (my $repost = ($POST{repost} || $GET{repost})){ my $entry = LJ::Entry->new_from_url($repost); unless ($entry){ $$body = ""; return; } if ($entry->visible_to($remote)) { $subject ||= ( LJ::ehtm($entry->subject_orig) || LJ::Lang::ml("repost.default_subject")); unless ($event) { $event = $entry->event_raw; LJ::EmbedModule->add_user_to_embed($entry->journal->username, \$event); $event = LJ::Lang::ml( "repost.wrapper", { username => $entry->poster->username, url => $entry->url, subject => $subject, text => $event, }); } $reposted_from = $entry->url; $repost_hidden = LJ::repost_auth($POST{'repost_type'} || $GET{'repost_type'} || 'd', $entry->poster->username, $entry->url, $subject); } } # try to call a hook to fill in the fields my $override_fields = LJ::run_hook('update_fields', \%GET); my $opt_preformatted = 0; if ($override_fields) { $event = $override_fields->{'event'} if exists($override_fields->{'event'}); $subject = $override_fields->{'subject'} if exists($override_fields->{'subject'}); $tags = $override_fields->{'tags'} if exists($override_fields->{'tags'}); $opt_preformatted = $override_fields->{'prop_opt_preformatted'} if exists($override_fields->{'prop_opt_preformatted'}); } ### define some bools with common logic ### my $did_post = LJ::did_post() && !$POST{transform}; # transforms aren't posts my $user_is_remote = $remote && $remote->{'user'} eq $POST{'user'}; # user is remote my $auth_as_remote = $remote && (! $GET{'altlogin'} || $user_is_remote); # auth as remote my $auth_missing = $POST{'user'} && ! $POST{'password'} && ! $user_is_remote && ! $POST{'response'}; # user w/o password # which authentication option do we display by default? my $altlogin_display = 'none'; my $remotelogin_display = 'none'; if ($auth_as_remote) { $remotelogin_display = ''; } else { $altlogin_display = ''; } # Check for errors, store in hash to render later my $errors = {}; my $showform = $POST{'showform'} || $auth_missing || exists $POST{'ljpost:off'}; # show entry form my $preview = $POST{'action:preview'}; if ( exists $POST{'ljpost:off'} ) { LJ::Request->set_cookie( ljpost => 0, expires => time + 86400 * 7, ); } # are we spellchecking before we post? my $did_spellcheck; my $spellcheck_html; if ($LJ::SPELLER && $POST{'action:spellcheck'}) { $did_spellcheck++; my $s = LJ::SpellCheck->new({ 'spellcommand' => $LJ::SPELLER, 'color' => '', 'lang' => $remote ? $remote->prop('browselang') : $LJ::DEFAULT_LANG, }); $spellcheck_html = $s->check_html(\$event); $spellcheck_html = "" unless $spellcheck_html ne ""; my $date = LJ::html_datetime_decode({ 'name' => "date_ymd", }, \%POST); ($year, $mon, $mday) = split( /\D/, $date); ($hour, $min) = split(/:/, $POST{'time'}); } my $print_entry_form = sub { my $opts = shift; # authentication box my $auth = ''; if ($altlogin_display eq 'none') { $auth.= "
  • \n"; $auth .= "\n"; $auth .= "" . $remote->display_name . " $ML{'entryform.switchuser'}\n"; $auth .= "
  • \n\n"; } # table with username/password fields $auth .= "
  • \n"; $auth .= "\n"; $auth .= "\n"; $auth .= LJ::html_text({ 'name' => 'user', 'id' => 'altlogin_username', 'class' => 'text', 'size' => '15', 'maxlength' => '15', 'tabindex' => '5', 'value' => $POST{'user'} || $GET{'user'} }) . "\n"; $auth .= "\n"; $auth .= "
  • \n"; $auth .= "
  • \n"; $auth .= "\n"; $auth .= "\n"; $auth .= LJ::html_text({ 'type' => 'password', 'id' => 'altlogin_password', 'class' => 'text', 'name' => 'password', 'tabindex' => '6', 'size' => '15', 'maxlength' => '30' }) . "\n"; $auth .= "\n"; # posted with a user, but no password if ($did_post && $auth_missing) { $auth .= "
    "; } $auth .= "
  • \n\n"; # if they submit the form and are spellchecking, remember # their settings from the GET requests my $getextra = '?'; $getextra .= "altlogin=1&" if $GET{'altlogin'}; $getextra .= "qotd=" . LJ::eurl($GET{qotd}) . "&" if $GET{'qotd'}; chop $getextra; my $entry = { 'mode' => "update", 'auth_as_remote' => $auth_as_remote, 'subject' => $subject, 'event' => $event, 'prop_taglist' => $tags, 'datetime' => "$year-$mon-$mday $hour:$min", 'usejournal' => ($usejournalu) ? $usejournalu->user : undef, 'auth' => $auth, 'remote' => $remote, 'spellcheck_html' => $spellcheck_html, 'clientversion' => "WebUpdate/2.0.0", 'richtext' => $LJ::DISABLED{'richtext'} ? 0 : 1, 'richtext_default' => $remote ? $remote->new_entry_editor eq 'rich' ? 1 : 0 # User setting : $LJ::DEFAULT_EDITOR eq 'rich' ? 1 : 0, # Site default 'include_insert_object' => $GET{'insobj'}, 'prop_qotdid' => $qid, 'altlogin' => $GET{altlogin} ? 1 : 0, 'prop_opt_preformatted' => $opt_preformatted ? 1 : 0, 'qid' => $qid, 'albums_id' => $POST{'albums_id'} || $GET{'albums_id'}, 'photos_id' => $POST{'photos_id'} || $GET{'photos_id'}, 'repost_budget' => $POST{'repost_budget'}, 'repost_limit_sc' => $POST{'repost_limit_sc'}, }; if ($remote) { $entry->{prop_opt_default_noemail} = $remote->prop('opt_gettalkemail'); $entry->{prop_opt_default_nocomments} = $remote->prop('opt_showtalklinks'); $entry->{prop_last_fm_user} = $remote->prop('last_fm_user'); $entry->{prop_trava_user} = $remote->prop('trava_uid'); } if ($did_post) { $entry->{$_} = $POST{$_} foreach keys %POST; # Copy things over from the transform } elsif (LJ::did_post()) { foreach (qw(event_format richtext_default)) { $entry->{$_} = $POST{$_} if defined $POST{$_}; } } # If they got an error, or spellchecked, and we're in rich text mode, enable rich text mode: if ($did_post && $POST{'switched_rte_on'}) { $entry->{richtext_default} = 1; } if (LJ::isu($remote) && (!$did_post || $did_spellcheck) && $remote->readonly) { $$body .= "
    "", 'a_close' => ""} ); } else { $$body .= BML::ml('.rowarn', { 'a_open' => '', 'a_close' => ''} ); } $$body .= " warningbar?>
    "; } $$body .= "\n\n
    \n\n"; $$body .= LJ::form_auth(); if ($reposted_from) { $$body .= LJ::html_hidden( 'reposted_from' => $reposted_from ); $$body .= $repost_hidden; } if ($update_type) { $$body .= LJ::html_hidden( 'type' => $update_type ); } if ($opts->{require_tos}){ $$body .= LJ::tosagree_html('update', $POST{agree_tos}, $errors->{require_tos}); } my $js = undef; $$body .= LJ::entry_form($entry, \$$head, $onload, $errors, \$js); $$body .= "
    \n"; LJ::need_var(faqLink => LJ::help_icon_html('like', undef, undef, BML::ml('fcklang.ljlike.faq'))); $$body .= $js; $$body .= LJ::Widget::SettingWindow->render; return; }; my $okay_formauth = !$remote || LJ::check_form_auth(); if ($did_post && !$did_spellcheck && !$showform && !$preview && $okay_formauth && !$POST{'moreoptsbtn'} ) { # what's our authentication scheme for subsequent protocol actions? my $flags = {}; my ($u, $user); if ($POST{'user'} && # user argument given ! $user_is_remote && # user != remote (!$remote || $GET{'altlogin'})) { # user has clicked alt auth $user = $POST{'user'}; $u = LJ::load_user($user); # Verify entered password, if it is present. my $ok; if ($POST{response}) { $ok = LJ::challenge_check_login($u, $POST{chal}, $POST{response}); } else { # js disabled, fallback to plaintext $ok = LJ::auth_okay($u, $POST{password}); } $flags = { 'noauth' => 1, 'u' => $u } if $ok; } elsif ($remote && LJ::check_referer()) { # assume remote if we have it $flags = { 'noauth' => 1, 'u' => $remote }; $user = $remote->{'user'}; $u = $remote; } if ($u && ! $u->tosagree_verify) { if ($POST{agree_tos}) { my $err = ""; unless ($u->tosagree_set(\$err)) { # error $errors->{require_tos} = $err; $print_entry_form->({ require_tos => 1 }); return; } # successfully set } else { $errors->{require_tos} = $ML{'tos.error'}; $print_entry_form->({ require_tos => 1 }); return; } } # Check if the account they're posting to is read-only my $uj = $usejournalu || $u; if ($uj && $uj->readonly) { # Tell the user they can't post since read only $$body .= "$ML{'.error.update'} "; $$body .= $LJ::MSG_READONLY_USER; $$body .= " errorbar?>
    "; $print_entry_form->(); return } # do a login action my $login_message; { # build a clientversion string my $clientversion = "Web/2.0.0"; $clientversion .= 's' if $did_spellcheck; # build a request object my %req = ( 'mode' => 'login', 'ver' => $LJ::PROTOCOL_VER, 'clientversion' => $clientversion, 'user' => $user, ); my %res; LJ::do_request(\%req, \%res, $flags); # error logging in ? unless ($res{'success'} eq 'OK') { $errors->{'auth'} = $ML{'.error.login'} . " " . LJ::ehtml($res{'errmsg'}); } # server login message for user? $login_message = LJ::auto_linkify(LJ::ehtml($res{'message'})) if $res{'message'}; } # any messages from the server? if ($login_message) { $$body .= "$ML{'.loggingin'} $ML{'.servermsg'} p?>
    $login_message
    "; } my $sticky = $POST{'sticky_type'} || $GET{'sticky_type'}; my $type = $POST{'type'} || $GET{'type'}; my $timezone = $POST{'timezone'} || $GET{'timezone'}; my $custom_time = $POST{'custom_time'} || $GET{'custom_time'}; $timezone = sprintf("%+.4d", $timezone); my %req = ( 'ver' => 4, 'username' => $user, 'password' => $POST{'password'}, 'usejournal' => ($usejournalu) ? $usejournalu->user : undef, 'sticky' => $sticky, 'custom_time' => $custom_time, 'tz' => $timezone, 'posttype' => $type, 'repost_budget' => $POST{'repost_budget'}, 'repost_limit_sc' => $POST{'repost_limit_sc'}, ); $flags->{'use_custom_time'} = 1; LJ::entry_form_decode(\%req, \%POST); if ($req{'event'} eq "") { $errors->{'entry'} = $ML{'.error.noentry'}; } if (grep { $_->[0] } LJ::run_hooks("validate_entry_form", \%req, $errors)) { $print_entry_form->(); return; } $req{prop_qotdid} = $qid; $req{prop_interface} = "web"; if ( $POST{'repost_params'} ) { my ( $type, $username, $url, $subject, $auth ) = split(/:/, $POST{'repost_params'} ); $req{'prop_repost_url'} = LJ::durl($url); $req{'prop_repost_author'} = LJ::durl($username); $req{'prop_repost_subject'} = LJ::durl($subject); my $new_auth = LJ::repost_auth($type, $req{'prop_repost_author'}, $req{'prop_repost_url'}, $req{'prop_repost_subject'}, 1); $req{'prop_repost'} = $auth eq $new_auth ? $type : 'N'; } foreach my $k (keys %req) { next unless ($k =~ /^prop_(.+)$/); $req{'props'}->{$1} = $req{$k}; delete $req{$k}; } my $err = 0; my $res = LJ::Protocol::do_request("postevent", \%req, \$err, $flags); if (!keys %$errors) { # examine response my $update_message; if ($res && $res->{'message'}) { $update_message = LJ::auto_linkify(LJ::ehtml($res->{'message'})); } # report results $$body .= "$ML{'.updating'} "; unless ($res) { # update failed? $$body .= "
    $ML{'.error.update'} "; $$body .= LJ::ehtml(LJ::Protocol::error_message($err)) . " errorbar?>"; $$body .= "
    p?>"; } else { # Clear out a draft $remote->set_prop('entry_draft', '') if $remote; # Store what editor they last used unless (!$remote || $remote->prop('entry_editor') =~ /^always_/) { $POST{'switched_rte_on'} ? $remote->set_prop('entry_editor', 'rich') : $remote->set_prop('entry_editor', 'plain'); } $$body .= "
    \n\n"; my ($ju, $itemlink); # short bail if this was posted moderated or some other special case (no itemid but a message) if (!defined $res->{itemid} && $res->{message}) { $$body .= "
    $res->{message} p?>"; } else { # update success # some other code at this bml-page can check this flag # with 'exists $BMLCodeBlock::POST{success}' $POST{success} = 1; if ($qotd) { LJ::MemCache::delete('qotd_count:'.$qotd->{qid}); } if ($usejournalu) { $ju = $usejournalu; # posting as community } elsif ($user) { $ju = LJ::load_user($user); # posting not as user from form } else { $ju = $remote; # posting as remote }; my $juser = $ju->{'user'}; my ($itemid, $anum) = ($res->{'itemid'}, $res->{'anum'}); my $delayedid = $res->{'delayedid'}; if ($res->{'itemid'}) { $itemlink = LJ::item_link($ju, $itemid, $anum); } else { $itemlink = LJ::DelayedEntry::item_link($ju, $res->{'delayedid'}); } if ($itemid) { $itemid = $itemid * 256 + $anum; $$body .= BML::ml('.update.success2', {'aopts' => "href='" . $ju->journal_base . "/'"}); } else { my $ext = $remote->equals($ju) ? '' : "?usejournal=" . $ju->username; $$body .= BML::ml('.update.success3', {'aopts' => "href=$LJ::SITEROOT/manage/scheduled_posts.bml$ext"}); } $$body .= $res->{extra_result_message}; $$body .= join('
    ', @{$res->{warnings}} ) if $res->{warnings} and @{$res->{warnings}}; my $juser = $ju->{'user'}; my ($itemid, $anum) = ($res->{'itemid'}, $res->{'anum'}); my $delayedid = $res->{'delayedid'}; if ($res->{'itemid'}) { $itemlink = LJ::item_link($ju, $itemid, $anum); } else { $itemlink = LJ::DelayedEntry::item_link($ju, $res->{'delayedid'}); } $itemid = $itemid * 256 + $anum; my $writersblocklink = ''; if ($qid && LJ::run_hook('show_qotd_extra_text', $remote)) { $writersblocklink = "
  • View answers to Writer's Block
  • "; } my @after_entry_post_extra_options = LJ::run_hooks('after_entry_post_extra_options', user => $ju, itemlink => $itemlink); my $after_entry_post_extra_options = join('', map {$_->[0]} @after_entry_post_extra_options) || ''; $$body .= " p?>"; $$body .= '
    ' . LJ::Widget::Trynbuy->render(stage => 'simple') if ($show_trynbuy); $$body .= LJ::Widget::GettingStarted->render; $$body .= '
    ' if ($show_trynbuy); } $$body .= "
    "; { $$body .= LJ::get_ads({ location => 'bml.update/error', ljadwrapper => 1, below_ad => LJ::CProd->full_box_for($u, width => 300), interests_extra => $qid ? { qotd => $qotd } : {}, }); } $$body .= "
    "; $$body .= LJ::run_hook('after_entry_post_extra_html', user => $ju, itemlink => $itemlink, request => \%req); return; } } } $$body .= ""; { my $ad_details; my $ad = LJ::get_ads({ location => 'bml.update/main', get_slots_params => \$ad_details, interests_extra => $qid ? { qotd => $qotd } : {} }); my $trynbuy; $trynbuy = LJ::Widget::Trynbuy->render( 'stage' => 'simple' ) if $show_trynbuy; if ( $ad ) { my $width = $ad_details->[-1]->{width}; my $adunit = $ad_details->[-1]->{adunit}; $$body .= "
    "; $print_entry_form->(); $$body .= "$ad"; } else { $$body .= ""; } } $$body .= "
    "; return; } _code?> {'title'}; _code?> body=> {'body'}; _code?> bodyopts=>{'bodyopts'}; _code?> head<= {'head'}; LJ::need_res(qw( js/widget_ippu/selecttags.js js/entry.js js/poll.js js/md5.js )); # draft autosave and restore my $remote = LJ::get_remote(); my $draft = '""'; if ($remote) { $draft = LJ::ejs_string(get_draft_text($remote->draft_text)); } my $eMLautosave = LJ::ejs(BML::ml('.draft.autosave', { 'time' => '[[time]]' })); my $eMLconfirm = LJ::ejs($ML{'.draft.confirm'}); if ($POST{'photos_id'} || $GET{'photos_id'} || $POST{'albums_id'} || $GET{'albums_id'}) { $eMLconfirm = LJ::ejs($ML{'.draft.confirm.add_photos'}); } my $eMLrestored = LJ::ejs($ML{'.draft.restored'}); # Setup draft saving and try to restore from a draft # unless we did a post action my $initDraft = ''; if ($remote && !$LJ::DISABLED{'update_draft'}) { # While transforms aren't considered posts, we don't want to # prompt the user to restore from a draft on a transform if (!LJ::did_post()) { $initDraft = 'window.isInitDraft = true;'; } else { $initDraft = 'window.isInitDraft = false;'; } } my $pageload = $LJ::SPELLER && $POST{'action:spellcheck'} ? "new_post_load(0);" : "new_post_load(1);"; # JS vars for the RTE $ret .= LJ::rte_js_vars($remote); # Turning off BML parsing for the rest of this code block # The draft might contain BML like syntax and cause problems BML::noparse(); LJ::need_string(qw( entryform.close.confirm )); # append months names tranlation to Site.ml_text['month.names.long'] my @ml_months = map { LJ::Lang::month_long_langcode($_) } (1 .. 12); my @ml_months_texts = map { LJ::Lang::ml($_) } @ml_months; $LJ::JSML{'month.names.long'} = \@ml_months_texts; $ret .= qq^ ^; $ret .= (! $LJ::REQ_HEAD_HAS{'chalresp_js'}++) ? $LJ::COMMON_CODE{'chalresp_js'} : ""; return $ret; } _code?> <=head page?>