qr/./); my $dbr = LJ::get_db_reader(); $title = $ML{'.title'}; $body = ""; my $err = sub { $title = "Error"; $body = LJ::bad_input(@_); return; }; $POST{'oldkeywords'} = [ split('\0', $POST{'oldkeywords'}) ]; unless (LJ::text_in(\%POST)) { return $err->("Invalid UTF-8 Input"); } my $remote = LJ::get_remote(); unless ($remote) { $body = ""; return; } my $authas = $GET{'authas'} || $remote->{'user'}; my $memoryu = LJ::get_authas_user($authas); return $err->($ML{'error.invalidauth'}) unless $memoryu; my $authextra = $authas ne $remote->{'user'} ? "?authas=$authas" : ''; my %secopts = ( 'public' => $ML{'label.security.public'}, 'friends' => $ML{'label.security.accesslist'}, 'private' => $ML{'label.security.private'}, ); if ( $memoryu->is_community ) { $secopts{'private'} = $ML{'label.security.maintainers'}; $secopts{'friends'} = $ML{'label.security.members'}; } my $sth; my $journal = $GET{'journal'} || $POST{'journal'}; my $ditemid = $GET{'itemid'}+0 || $POST{'itemid'}+0; # OK. the memories schema is weird and stores *display* itemids in the database. # additionally, we distinguish precluster itemids because they're stored without a userid. # it's too late to fix it in the db, so we just work around it-- # all new memories still get userid+ditemid because we can't change the ditemid/itemid problem, # but old-style itemids get fixed up to userid+ditemid. # *however*, when editing old itemids we need to keep around # the old-style ditemid so we can still edit it. # to keep this all sorted out, we fixup variables like this: # - itemid -- real, new-style itemid # - ditemid -- display itemid (with anum) # - dbitemid -- itemid that is in the database; # usually same as ditemid, but different for old-style itemids. my $dbitemid = $ditemid; my $itemid; my $oldstyle = 0; my $ju; my $jid; my $anum; if ($journal) { $ju = LJ::load_user($journal); $jid = $ju->{'userid'}; $anum = $ditemid % 256; $itemid = int($ditemid / 256); } unless ($ju && $itemid) { $title = $ML{'Error'}; $body = $ML{'error.nojournal'}; return; } # check to see if it already is memorable (thus we're editing, not adding); my $memory = LJ::Memories::get_by_ditemid($memoryu, $oldstyle ? 0 : $jid, $ditemid); # Always allow for a user to delete their memories, regardless of other permissions. if ($POST{'mode'} eq "save") { unless ($POST{'des'}) { # we're deleting. unless (LJ::check_form_auth()) { $body = ""; return; } if (defined $memory) { LJ::Memories::delete_by_id($memoryu, $memory->{memid}); LJ::Memories::updated_keywords($memoryu); $title = $ML{'.title.deleted'}; $body = " $memory->{'des'} }) . " p?>"; $body .= ""; return; } else { $title = $ML{'Error'}; $body = ""; return; } } } # do access check to see if they can see this entry my $log = LJ::get_log2_row($ju, $itemid); if ( $log ) { my $entry = LJ::Entry->new_from_row( %$log ); if ( $entry && ! $entry->visible_to( $remote ) ) { $title = $ML{'Error'}; $body = "You are not authorized to view this entry.
"; if ($memoryu->{user} eq $authas && defined $memory) { $body .= "
"; $body .= LJ::form_auth(); $body .= LJ::html_hidden(journal => $GET{journal}) if $GET{journal}; $body .= LJ::html_hidden(itemid => $GET{itemid}); $body .= LJ::html_hidden(des => ""); $body .= LJ::html_hidden('mode' => 'save'); $body .= LJ::html_submit('delete', 'Delete this memory') . "\n"; $body .= "
\n"; } return; } } # do check to see if entry is deleted unless ( $log || $POST{'mode'}) { $title = $ML{'Error'}; $body = "The entry that this memory references has been deleted.
"; if ($memoryu->{user} eq $authas && defined $memory) { $body .= "
"; $body .= LJ::form_auth(); $body .= LJ::html_hidden(journal => $GET{journal}) if $GET{journal}; $body .= LJ::html_hidden(itemid => $GET{itemid}); $body .= LJ::html_hidden('mode' => 'save'); $body .= LJ::html_submit('delete', 'Delete this memory') . "\n"; $body .= "
\n"; } return; } my $subject = LJ::get_logtext2($ju, $itemid)->{$log->{jitemid}}[0]; my $dbcr = LJ::get_cluster_reader($ju); # if the entry is pre-UTF-8 conversion, the # subject may need conversion into UTF-8 { my %props = (); LJ::load_log_props2($dbcr, $log->{'journalid'}, [ $itemid ], \%props); if ($props{$itemid}->{'unknown8bit'}) { my $u = LJ::load_userid($log->{'journalid'}); my ($error, $subj); $subj = LJ::text_convert($subject, $u, \$error); $subject = $subj unless $error; } LJ::text_out(\$subject); } if ($oldstyle) { # ditemid was an old-style itemid, so we update it to the new style. $anum = $log->{anum}; $ditemid = $itemid<<8 + $anum; } # get keywords user has used my $exist_kw = LJ::Memories::get_keywords($memoryu); unless ($exist_kw) { $title = $ML{'Error'}; $body = "Error fetching existing keywords."; return; } if ($POST{'mode'} eq "") { my ($des, $keywords); my @all_keywords; my %selected_keyword; @all_keywords = sort values %$exist_kw; if (defined $memory) { $title = $ML{'.title.edit_memory'}; $des = $memory->{'des'}; my $kwids = LJ::Memories::get_keywordids($memoryu, $memory->{memid}) || []; foreach my $kwid (@$kwids) { my $kw = $exist_kw->{$kwid}; next if ($kw eq "*"); if ($keywords) { $keywords .= ", "; } $keywords .= $kw; $selected_keyword{$kw} = 1; } if (!$log || ($jid && $log->{'anum'} != $anum)) { LJ::Memories::delete_by_id($memoryu, $memory->{memid}); LJ::Memories::updated_keywords($memoryu); $title = $ML{'Error'}; $body = $ML{'.error.entry_deleted2'}; return; } } elsif (!$log || ($jid && $log->{'anum'} != $anum)) { $title = $ML{'Error'}; $body = $ML{'error.noentry'}; return; } else { $title = $ML{'.title.add_memory'}; # this is a new memory. my $user = LJ::get_username($log->{'journalid'}); my $dt = substr($log->{'eventtime'}, 0, 10); $des = "$dt: $user: $subject"; } # it'd be nice to only show the authas form when adding an entry and not # when editing one, but if user u is logged in and has post p as a memory # already then wants to add it to community c, when u clicks the "add memory" # link on p, u gets the "edit entry" page and they need to be able to switch # to c. $body .= "
\n"; $body .= LJ::make_authas_select($remote, { 'authas' => $GET{'authas'} }) . "\n"; $body .= LJ::html_hidden(journal => $GET{journal}) if $GET{journal}; $body .= LJ::html_hidden(itemid => $GET{itemid}); $body .= "
\n\n"; LJ::text_out(\$des); LJ::text_out(\$keywords); if (defined $memory) { $body .= $ML{'.edit_previous'}; } else { $body .= $ML{'.add_previous2'}; } my $getextra = "?itemid=$dbitemid"; $getextra .= "&authas=$authas" if $authas ne $remote->{'user'}; # we still need to pass the dbitemid and not the itemid to ourself. $getextra .= "&journal=$journal" unless $oldstyle; $body .= "
"; $body .= LJ::form_auth(); $body .= LJ::html_hidden(mode => "save"); $body .= ""; $body .= ""; $body .= "\n"; $body .= "
$ML{'.description'}"; $body .= LJ::html_text({name => 'des', value => $des, maxlength => LJ::CMAX_MEMORY, size => 40}); $body .= "
$ML{'.description.text2'}
$ML{'.keywords'}"; $body .= LJ::html_text({name => 'keywords', size => 40, value => $keywords}); $body .= "
$ML{'.keywords.text'}
"; if (@all_keywords) { my $size = scalar(@all_keywords); $size = 15 if $size > 15; $body .= "$ML{'.keywords.select'}
"; $body .= LJ::html_select( { name => 'oldkeywords', size => $size, multiple => 1, selected => [ keys %selected_keyword ], noescape => 1 }, map { (LJ::ehtml($_), LJ::ehtml($_)) } @all_keywords); $body .= "
$ML{'.multiple_selections'}"; } else { $body .= "$ML{'.keywords.example'}"; } $body .= "
$ML{'.security'}"; $body .= LJ::html_select({name => 'security', selected => defined $memory ? $memory->{'security'} : undef}, map { ($_, $secopts{$_}) } qw(public friends private)); if ( $memoryu->is_community ) { $body .= "
$ML{'.whocansee.comm'}
\n"; } else { $body .= "
$ML{'.whocansee'}
\n"; } $body .= LJ::html_submit(undef, $ML{'.form.submit'}); $body .= LJ::html_submit(undef, $ML{'.form.reset'}, {type => 'reset'}) if defined $memory; $body .= "
"; return; } if ($POST{'mode'} eq "save") { return " $ML{'error.invalidform'}" unless LJ::check_form_auth(); my $dbh = LJ::get_db_writer(); #### we're inserting/replacing now into memories my @keywords; { my %kws; foreach (split(/\s*,\s*/, $POST{'keywords'})) { $kws{$_} = 1; } # oldkeywords were split at the beginning foreach (@{$POST{'oldkeywords'}}) { $kws{$_} = 1; } @keywords = keys %kws; } if (scalar(@keywords) > 5) { $title = $ML{'Error'}; $body = ""; return; } @keywords = grep { $_ } map { s/\s\s+/ /g; LJ::trim($_); } @keywords; push @keywords, "*" unless (@keywords); my @kwid; my $needflush = 0; foreach my $kw (@keywords) { if (length($kw) > 40) { $title = $ML{'Error'}; $body = " LJ::ehtml($kw) }) . " p?>"; return; } my $kwid = $memoryu->get_keyword_id( $kw ); $needflush = 1 unless defined $exist_kw->{$kwid}; push @kwid, $kwid; } unless (exists $secopts{$POST{'security'}}) { $title = $ML{'Error'}; $body = $ML{'.error.invalid_security'}; return; } my $des = LJ::text_trim($POST{'des'}, LJ::BMAX_MEMORY, LJ::CMAX_MEMORY); my $sec = $POST{'security'}; # handle edits by deleting the old memory and recreating LJ::Memories::delete_by_id($memoryu, $memory->{memid}) if defined $memory; LJ::Memories::create($memoryu, { journalid => $jid, ditemid => $ditemid, des => $des, security => $sec, }, \@kwid); LJ::Memories::updated_keywords($memoryu) if $needflush; $exist_kw = LJ::Memories::get_keywords($memoryu) if $needflush; $title = $ML{'.title.added'}; $body .= ""; $body .= ""; my $entry = LJ::Entry->new($ju, jitemid => $itemid); $body .= ""; return; } $title = $ML{'Error'}; $body = $ML{'error.unknownmode'}; return; } _code?> body=> page?>