Invalid language" unless $l; my $lp = $l->{'parentlnid'} ? LJ::Lang::get_lang_id($l->{'parentlnid'}) : undef; my $dbr = LJ::get_db_reader(); my $dbh; my ($sth, $ret); my $remote = LJ::get_remote(); my $can_edit = (LJ::check_priv($remote, "translate", "*") || LJ::check_priv($remote, "translate", $l->{'lncode'})); my $can_delete = LJ::check_priv($remote, "translate", "[itemdelete]"); my $can_rename = LJ::check_priv($remote, "translate", "[itemrename]"); my $mode = { '' => 'view', 'save' => 'save', }->{$FORM{'mode'}}; return "bogus mode" unless $mode; my $MAX_EDIT = 100; if ($mode eq "view") { my @load; foreach (split /,/, $FORM{'items'}) { next unless /^(\d+):(\d+)$/; last if @load >= $MAX_EDIT; push @load, { 'dmid' => $1, 'itid'=> $2 }; } return "Nothing to show." unless @load; $ret .= ""; $ret .= LJ::html_hidden('lang', $lang, 'mode', 'save'); # load item info my %ml_items; my $itwhere = join(" OR ", map { "(dmid=$_->{'dmid'} AND itid=$_->{'itid'})" } @load); $sth = $dbr->prepare("SELECT dmid, itid, itcode, notes FROM ml_items WHERE $itwhere"); $sth->execute; while (my ($dmid, $itid, $itcode, $notes) = $sth->fetchrow_array) { $ml_items{"$dmid-$itid"} = { 'itcode' => $itcode, 'notes' => $notes }; } # getting latest mappings for this lang and parent my %ml_text; my %ml_latest; $sth = $dbr->prepare("SELECT lnid, dmid, itid, txtid, chgtime, staleness FROM ml_latest ". "WHERE ($itwhere) AND lnid IN ($l->{'lnid'}, $l->{'parentlnid'})"); $sth->execute; return $dbr->errstr if $dbr->err; while ($_ = $sth->fetchrow_hashref) { $ml_latest{"$_->{'dmid'}-$_->{'itid'}"}->{$_->{'lnid'}} = $_; $ml_text{"$_->{'dmid'}-$_->{'txtid'}"} = undef; # mark to load later } # load text $sth = $dbr->prepare("SELECT dmid, txtid, lnid, itid, text FROM ml_text ". "WHERE " . join(" OR ", map { "(dmid=$_->[0] AND txtid=$_->[1])" } map { [ split(/-/, $_) ] } keys %ml_text)); $sth->execute; while ($_ = $sth->fetchrow_hashref) { $ml_text{"$_->{'dmid'}-$_->{'txtid'}"} = $_; } if ($can_delete) { $ret .= "

To delete an item: edit text to be \"XXDELXX\"

"; } # show all editing items my $ict = 0; foreach my $i (@load) { my ($dmid, $itid) = ($i->{'dmid'}, $i->{'itid'}); my $ituq = "$dmid-$itid"; my $it = $ml_items{$ituq}; my $lat = $ml_latest{$ituq}->{$l->{'lnid'}}; next unless $it and $lat; $ict++; my $plat; if ($lp && defined $ml_latest{$ituq}->{$lp->{'lnid'}}) { $plat = $ml_latest{$ituq}->{$lp->{'lnid'}}; } $ret .= LJ::html_hidden("dom_$ict", $dmid, "itid_$ict", $itid, "oldtxtid_$ict", $lat->{'txtid'}, "oldptxtid_$ict", $plat ? $plat->{'txtid'} : 0, ); # top bar $ret .= "

"; $ret .= "
"; $ret .= "
Code: "; if ($dmid != 1) { my $d = LJ::Lang::get_dom_id($dmid); $ret .= "[$d->{'uniq'}] "; } my $difflink; if ($lat->{'staleness'}) { $difflink = "($plat->{'chgtime'}, {'itid'}&lang=$lp->{'lncode'}'>diff)"; } $ret .= "$it->{'itcode'} $difflink | Sev: $lat->{'staleness'}

"; $ret .= "

"; if ($it->{'notes'}) { my $notes = $it->{'notes'}; $notes =~ s!\n!
!g; $ret .= "
Notes:
  $notes
"; } my $show_edit = 0; my $use_textarea = 0; if ($plat) { $ret .= "
$lp->{'lnname'}:
"; my $t = $ml_text{"$plat->{'dmid'}-$plat->{'txtid'}"}->{'text'}; if ($t =~ /\n/) { $use_textarea = 1; } if (length($t) > 255) { $use_textarea = 1; } $t = LJ::eall($t); $t =~ s/\n( *)/"
" . " "x length($1)/eg; $ret .= "
  $t
"; } my $curtext = LJ::eall($ml_text{"$lat->{'dmid'}-$lat->{'txtid'}"}->{'text'}); if ($curtext =~ /\n/) { $use_textarea = 1; } if (length($curtext) > 255) { $use_textarea = 1; } if ($lat->{'staleness'} >= 3) { # if wrong language, why populate it with stuff they'll just have to delete? $curtext = ""; } $ret .= "
$l->{'lnname'}:
  "; my $disabled = "disabled='disabled'"; if ($lat->{'staleness'} >= 3) { $disabled = ""; # when something's this stale, assume both it's being # edited and that the severity is major (going from wrong # language to right language is a major change, afterall) $ret .= LJ::html_hidden("ed_$ict", "1", "sev_$ict", "2", ); } else { $ret .= "Edit Text"; if ($l->{'children'} && @{$l->{'children'}}) { $ret .= " Severity: "; $ret .= LJ::html_select({ 'name' => "sev_$ict", "selected" => 1 }, 0 => "Typo/etc (no notify)", 1 => "Minor (notify translators)", 2 => "Major (require translation updates)"); } $ret .= "
  "; } if ($use_textarea) { $ret .= "$curtext"; } else { $ret .= ""; } $ret .= "
\n"; $ret .= "

"; } if ($ict) { $ret .= LJ::html_hidden("ict", $ict); my $disabled = $can_edit ? "" : "disabled='disabled'"; $ret .= "

"; } else { $ret .= "No items to show. (since been deleted, perhaps?)"; } $ret .= ""; return $ret; } if ($mode eq "save") { my $num = $FORM{'ict'}+0; $num = $MAX_EDIT if $num > $MAX_EDIT; my (@errors, @info); unless ($can_edit) { push @errors, "You don't have access to edit text for this language."; $num = 0; } unless (LJ::text_in(\%FORM)) { push @errors, "You seem to have changed your browser's encoding to something other than UTF-8. It needs to be in UTF-8."; push @errors, "Nothing saved."; $num = 0; } my $saved = 0; # do any saves? for (my $i=1; $i<=$num; $i++) { next unless $FORM{"ed_$i"}; my ($dom, $itid, $oldtxtid, $oldptxtid, $sev) = map { int($FORM{"${_}_$i"}+0) } qw(dom itid oldtxtid oldptxtid sev); my $itcode = $dbr->selectrow_array("SELECT itcode FROM ml_items WHERE dmid=$dom AND itid=$itid"); unless (defined $itcode) { push @errors, "Bogus dmid/itid: $dom/$itid"; next; } $dbh ||= LJ::get_db_writer(); my $lat = $dbh->selectrow_hashref("SELECT * FROM ml_latest WHERE lnid=$l->{'lnid'} AND dmid=$dom AND itid=$itid"); unless ($lat) { push @errors, "No existing mapping for $itcode"; next; } unless ($lat->{'txtid'} == $oldtxtid) { push @errors, "Another translator updated '$itcode' before you saved, so your edit has been ignored."; next; } my $plat; if ($lp) { $plat = $dbh->selectrow_hashref("SELECT * FROM ml_latest WHERE lnid=$lp->{'lnid'} ". "AND dmid=$dom AND itid=$itid"); my $ptid = $plat ? $plat->{'txtid'} : 0; unless ($ptid == $oldptxtid) { push @errors, "The source text of item '$itcode' changed while you were editing, so your edit has been ignored."; next; } } # did they type anything? my $text = $FORM{"newtext_$i"}; next unless $text =~ /\S/; # delete if ($text eq "XXDELXX") { if ($can_delete) { $dbh->do("DELETE FROM ml_latest WHERE dmid=$dom AND itid=$itid"); push @info, "Deleted: '$itcode'"; } else { push @errors, "You don't have access to delete items."; } next; } # did anything even change, though? my $oldtext = $dbr->selectrow_array("SELECT text FROM ml_text WHERE dmid=$dom AND txtid=$lat->{'txtid'}"); if ($oldtext eq $text && $lat->{'staleness'} == 2) { push @errors, "Severity of source language change requires change in text for item '$itcode'"; next; } # keep old txtid if text didn't change. my $opts = {}; if ($oldtext eq $text) { $opts->{'txtid'} = $lat->{'txtid'}; $text = undef; $sev = 0; } # if setting text for first time, push down to children langs if ($lat->{'staleness'} == 4) { $opts->{'childrenlatest'} = 1; } # severity of change: $opts->{'changeseverity'} = $sev; # set userid of writer $opts->{'userid'} = $remote->{'userid'}; my $res = LJ::Lang::set_text($dom, $l->{'lncode'}, $itcode, $text, $opts); unless ($res) { push @errors, LJ::Lang::last_error(); } else { push @info, "Saved: $itcode"; $saved = 1; } } $dbh ||= LJ::get_db_writer(); $dbh->do("UPDATE ml_langs SET lastupdate=NOW() WHERE lnid=$l->{'lnid'}") if $saved; if (@errors) { $ret .= "ERRORS:

"; foreach (@errors) { $ret .= "
- $_
"; } $ret .= "

"; } if (@info) { $ret .= "Results:

"; foreach (@info) { $ret .= "
- $_
"; } $ret .= "

"; } if (! @errors && ! @info) { $ret .= "No errors & nothing saved."; } return $ret; } _code?>