head<= <=head body<= {'user'}; my $u = LJ::get_authas_user($authas); return LJ::bad_input("You could not be authenticated as the specified user.") unless $u; return $LJ::MSG_READONLY_USER if LJ::get_cap($remote, "readonly"); ### user is now authenticated ### my $dbr = LJ::get_db_reader(); my $sth; my $capstyles = LJ::get_cap($u, "styles"); LJ::load_user_props($u, "opt_usesharedpic", "s1_lastn_style", "s1_calendar_style", "s1_day_style", "s1_friends_style", "stylesys", "journaldomain"); # if a POST, update their info if (LJ::did_post()) { return "" unless LJ::text_in(\%POST); # database error reporting my $dberr = sub { return "@_[0] p?>"; }; my $dbh = LJ::get_db_writer(); # setup what we're gonna update in the user table: my %update = (); # what userprops we'll be setting. my %uprop; # journal domains my $dom_cap = LJ::get_cap($u, 'userdomain'); if ((exists $POST{'journaldomain'} && $u->{'journaldomain'} ne $POST{'journaldomain'}) || (! $dom_cap && $POST{'journaldomain_del'})) { $POST{'journaldomain'} =~ s!^(http://)?(www\.)?!!; my $dom = lc($POST{'journaldomain'}); if (($dom_cap && ! $dom) || (! $dom_cap && $POST{'journaldomain_del'})) { $dbh->do("DELETE FROM domains WHERE userid=?", undef, $u->{'userid'}); } else { $dbh->do("INSERT INTO domains VALUES (?, ?)", undef, $dom, $u->{'userid'}); if ($dbh->err) { my $otherid = $dbh->selectrow_array("SELECT userid FROM domains WHERE domain=?", undef, $dom); return LJ::bad_input($ML{'.error.dupdomainalias'}) if $otherid != $u->{'userid'}; } if ($u->{'journaldomain'}) { $dbh->do("DELETE FROM domains WHERE userid=? AND domain <> ?", undef, $u->{'userid'}, $dom); } } # set journaldomain prop if it's been changed $uprop{'journaldomain'} = $dom unless $POST{'journaldomain'} eq $u->{'journaldomain'}; } # validate moodthemeid # mood theme, make sure they're allowed to use it my $moodthemeid = $POST{'moodthemeid'}+0; if ($moodthemeid) { my ($mownerid, $mpublic) = $dbr->selectrow_array("SELECT ownerid, is_public FROM moodthemes ". "WHERE moodthemeid=?", undef, $moodthemeid); $moodthemeid = 0 unless $mpublic eq 'Y' || $mownerid == $u->{'userid'}; } $update{'moodthemeid'} = $moodthemeid; $update{'opt_forcemoodtheme'} = $POST{'opt_forcemoodtheme'} ? "Y" : "N"; # all of these options should only be processed for S1 users if ($u->{'stylesys'} != 2) { # color themes $update{'themeid'} = $POST{'themetype'} eq "custom" ? 0 : $POST{'themeid'}; if ($POST{'themetype'} eq "custom") { my $dig = Digest::MD5::md5_hex(join(",", map { $POST{"theme_cust:$_"} } map { $_->[0] } @LJ::S1::themecoltypes)); if ($dig ne $POST{'themecolors_dig'}) { my %cols; foreach my $col (@LJ::S1::themecoltypes) { my $val = $POST{"theme_cust:$col->[0]"}; next if length($val) > 20; next unless ($val =~ /^\#[a-f0-9]{6,6}$/i || $val !~ /[^\s\w]/); $cols{$col->[0]} = $val; } return $ML{"error.nodb"} unless $u->writer; $u->do("INSERT IGNORE INTO s1usercache (userid) VALUES (?)", undef, $u->{'userid'}); $u->do("UPDATE s1usercache SET color_stor=? WHERE userid=?", undef, Storable::freeze(\%cols), $u->{'userid'}); LJ::MemCache::delete([$u->{'userid'}, "s1uc:$u->{'userid'}"]); $dbh->do("DELETE FROM themecustom WHERE user=?", undef, $u->{'user'}) if $dbh->selectrow_array("SELECT user FROM themecustom ". "WHERE user=? LIMIT 1", undef, $u->{'user'}); } } # update 'overrides' table if ($POST{'overrides'} !~ /\S/) { LJ::S1::clear_overrides($u); $update{'useoverrides'} = "N"; } else { my $oldoverrides = ""; if ($u->{'useoverrides'} eq "Y") { $oldoverrides = LJ::S1::get_overrides($u); } # This allows users to keep their current illegal overrides, # but they may not create new ones nor edit the ones they already have. # They may only delete or keep illegal overrides. my %overrides = (); my %newoverrides = (); LJ::parse_vars(\$oldoverrides,\%overrides); LJ::parse_vars(\$POST{'overrides'},\%newoverrides); # head overrides should only have valid head elements in them foreach my $a (qw(GLOBAL LASTN FRIENDS CALENDAR DAY)) { my $sec = "${a}_HEAD"; next unless $newoverrides{$sec} ne $overrides{$sec}; my $testtag = sub { my $tag = lc(shift); return "<$tag" if ($tag eq "title" || $tag eq "base" || $tag eq "style" || $tag eq "link" || $tag eq "meta" || $tag eq "xx"); return "($1)/eig; $newoverrides{$sec} =~ s/\<\/head/\<\/xx-head/ig; } # load all the properties to see which ones are overridable my @vars; LJ::load_objects_from_file("vars.dat", \@vars); foreach my $v (@vars) { my $ov = $v->{'props'}->{'override'}; if ($ov eq "yes" || $ov eq "only" || $capstyles) { my $name = $v->{'name'}; if (defined $newoverrides{$name}) { $overrides{$name} = $newoverrides{$name}; } } } # make the new override code we'll put in the database my $overr=''; foreach (keys %overrides) { if ($newoverrides{$_}) { if ($overrides{$_} =~ /\n/) { $overr .= "$_<=\n".$overrides{$_}."\n<=$_\n\n"; } else { $overr .= "$_=>".$overrides{$_}."\n\n"; } } } # no value, delete overrides if ($overr !~ /\S/) { LJ::S1::clear_overrides($u); $update{'useoverrides'} = "N"; # have a value, update overrides } else { LJ::S1::save_overrides($u, $overr); $update{'useoverrides'} = "Y"; } } # friends view shared pic option for s1 $uprop{'opt_usesharedpic'} = $POST{'opt_usesharedpic'} ? "1" : "0"; # set all the styles { my @picked = (); foreach my $view (@LJ::views) { my $sid = $POST{"s1_${view}_style"}+0; if ($sid) { $uprop{"s1_${view}_style"} = $sid; push @picked, $sid; } } # verify they haven't forged the style numbers unless ($capstyles) { # just load whole structure since it should be cached my $pubstyles = LJ::S1::get_public_styles(); my $userstyles = LJ::S1::get_user_styles($u); foreach (@picked) { my $type = $userstyles->{$_}->{'type'}; return LJ::bad_input($ML{'.error.stylenotavailable'}) unless exists $pubstyles->{$_} || exists $userstyles->{$_} && ($capstyles || $_ == $u->{"s1_${type}_style"}); } } } } # update 'user' table foreach (keys %update) { delete $update{$_} if $u->{$_} eq $update{$_}; } LJ::update_user($u, \%update) if %update; # change any of the userprops ? foreach my $uprop (keys %uprop) { next if $POST{$uprop} eq $u->{$uprop}; LJ::set_userprop($u, $uprop, $uprop{$uprop}); } # tell the user all is well return " LJ::journal_base($u)})." p?>"; } # not submitting a post, show edit form my $ret; # user switcher $ret .= "
\n"; $ret .= LJ::make_authas_select($remote, { 'authas' => $GET{'authas'} }); $ret .= "
\n\n"; ### journal style $ret .= "\n\n\n"; ### ### LAYOUT OPTIONS ### $ret .= "
\n"; # using S1, need to take style input if ($u->{'stylesys'} != 2) { my $and = $capstyles ? "" : $ML{'.pagelayoutstyle.warning'}; $ret .= "\n"; $ret .= "\n"; $ret .= "\n"; my $pubstyles = LJ::S1::get_public_styles(); my %pubstyles = (); foreach (sort { $a->{'styledes'} cmp $b->{'styledes'} } values %$pubstyles) { push @{$pubstyles{$_->{'type'}}}, $_; } my $userstyles = LJ::S1::get_user_styles($u); my %userstyles = (); foreach (sort { $a->{'styledes'} cmp $b->{'styledes'} } values %$userstyles) { push @{$userstyles{$_->{'type'}}}, $_; } foreach my $view (@LJ::views) { $ret .= "\n"; } $ret .= "
$ML{'.availablestyles.head'}
$LJ::viewinfo{$view}->{'des'}"; my @list = map { $_->{'styleid'}, $_->{'styledes'} } @{$pubstyles{$view} || []}; if (@{$userstyles{$view} || []}) { my @user_list = map { $_->{'styleid'}, $_->{'styledes'} } grep { $capstyles || $u->{"s1_${view}_style"} == $_->{'styleid'} } @{$userstyles{$view} || []}; push @list, { value => "", text => "--- $ML{'.availablestyles.userstyles'} ---", disabled => 1 }, @user_list if @user_list; my @disabled_list = map { { value => $_->{'styleid'}, text => $_->{'styledes'}, disabled => 1 } } grep { ! $capstyles && $u->{"s1_${view}_style"} != $_->{'styleid'} } @{$userstyles{$view} || []}; push @list, { value => '', text => "--- $ML{'.availablestyles.disabledstyles'} ---", disabled => 1 }, @disabled_list if @disabled_list; } $ret .= LJ::html_select({ 'name' => "s1_${view}_style", 'selected' => $u->{"s1_${view}_style"} }, @list); $ret .= "
\n\n"; ### ### COLOR THEME OPTIONS ### $ret .= "\n"; $ret .= "
\n"; $ret .= LJ::html_check({ 'type' => 'radio', 'name' => 'themetype', 'value' => 'default', 'selected' => $u->{'themeid'} > 0 }); $ret .= "$ML{'.colortheme.defaulttheme'}: "; my @list; $sth = $dbr->prepare("SELECT themeid, name FROM themelist ORDER BY name"); $sth->execute; while ($_ = $sth->fetchrow_hashref) { push @list, ($_->{'themeid'}, $_->{'name'}); } $ret .= LJ::html_select({ 'name' => 'themeid', 'selected' => $u->{'themeid'} }, @list) . "
\n"; $ret .= LJ::html_check({ 'type' => 'radio', 'name' => 'themetype', 'id' => 'themetype:custom', 'value' => 'custom', 'selected' => $u->{'themeid'} == 0 }) . "\n"; $ret .= "$ML{'.colortheme.customcolors'}:"; $ret .= "\n"; $ret .= "\n"; # get the user's custom colors my %custcolors = (); if ($u->{'themeid'} == 0) { my $dbcr = LJ::get_cluster_reader($u); my $stor = $dbcr->selectrow_array("SELECT color_stor FROM s1usercache WHERE userid=?", undef, $u->{'userid'}); if ($stor) { %custcolors = %{ Storable::thaw($stor) }; } else { # ancient table. $sth = $dbr->prepare("SELECT coltype, color FROM themecustom WHERE user=?"); $sth->execute($u->{'user'}); $custcolors{$_->{'coltype'}} = $_->{'color'} while $_ = $sth->fetchrow_hashref; } } else { $sth = $dbr->prepare("SELECT coltype, color FROM themedata WHERE themeid=?"); $sth->execute($u->{'themeid'}); $custcolors{$_->{'coltype'}} = $_->{'color'} while $_ = $sth->fetchrow_hashref; } my $dig; foreach my $col (@LJ::S1::themecoltypes) { $ret .= "\n"; $dig .= $col->[0]; } $dig = Digest::MD5::md5_hex($dig); $ret .= LJ::html_hidden("themecolors_dig", $dig) unless $u->{'themeid'}; $ret .= "
$ML{'.colortheme.area.head'}$ML{'.colortheme.color.head1'}
$ML{'.colortheme.color.head2'}
$col->[1]"; $ret .= LJ::html_text({ 'name' => "theme_cust:$col->[0]", 'size' => '20', 'maxlength' => '30', 'value' => $custcolors{$col->[0]}, 'onchange' => "checkRadioButton('themetype:custom');" }); $ret .= "
\n\n"; ### ### FRIENDS VIEW OPTIONS ### $ret .= ""; $ret .= "\n"; $ret .= "\n"; $ret .= "\n"; $ret .= "
"; $ret .= LJ::html_check({ 'type' => 'check', 'name' => 'opt_usesharedpic', 'selected' => $u->{'opt_usesharedpic'} }); $ret .= "$ML{'.friends.opt.usesharedpic.head'}
 $ML{'.friends.opt.usesharedpic.about'}
\n\n"; ### ### STYLE OVERRIDES ### # first, load the overrides if they use 'em: my $overrides = ""; if ($u->{'useoverrides'} eq "Y") { $overrides = LJ::S1::get_overrides($u); LJ::text_out(\$overrides); } $ret .= "
\n"; $ret .= "\n"; $ret .= "$ML{'.overrides.warning'} p?>\n"; $ret .= "\n"; $ret .= "$ML{'.overrides.box.head'}
"; $ret .= LJ::html_textarea({ 'name' => 'overrides', 'cols' => '60', 'rows' => '15', 'wrap' => 'off', 'value' => $overrides }) . " standout?>"; $ret .= "
\n\n"; } ### ### MOOD THEME OPTIONS ### $ret .= "\n"; $sth = $dbr->prepare("SELECT moodthemeid, name FROM moodthemes WHERE is_public='Y'"); $sth->execute; my @themes = ({ 'moodthemeid' => 0, 'name' => '(None)' }); push @themes, $_ while ($_ = $sth->fetchrow_hashref); ### user's private themes { my @theme_user; $sth = $dbr->prepare("SELECT moodthemeid, name FROM moodthemes WHERE ownerid=? AND is_public='N'"); $sth->execute($u->{'userid'}); push @theme_user, $_ while ($_ = $sth->fetchrow_hashref); if (@theme_user) { push @themes, { 'moodthemeid' => 0, 'name' => "--- $ML{'.moodicons.personal'} ---" }; push @themes, @theme_user; } } $ret .= "
$ML{'.moodicons.select'} \n"; $ret .= LJ::html_select({ 'name' => 'moodthemeid', 'selected' => $u->{'moodthemeid'} }, map { $_->{'moodthemeid'}, $_->{'name'} } @themes) . "\n"; $ret .= "($ML{'.moodicons.preview'})\n"; $ret .= "
" . LJ::html_check({ 'type' => 'check', 'name' => 'opt_forcemoodtheme', 'id' => 'opt_forcemoodtheme', 'selected' => $u->{'opt_forcemoodtheme'} eq 'Y' }) . "\n"; $ret .= "
\n\n"; ### ### JOURNAL DOMAIN OPTIONS ### my $has_cap = LJ::get_cap($u, 'userdomain'); my $has_dom = $u->{journaldomain} ? 1 : 0; if ($LJ::OTHER_VHOSTS && ($has_cap || $has_dom)) { $ret .= "\n"; $ret .= "
"; $ret .= ""; $ret .= "
$ML{'.domainalias.domainname'}"; $ret .= LJ::html_text({ 'name' => 'journaldomain', 'size' => '30', 'maxlength' => '80', 'value' => $u->{'journaldomain'}, 'disabled' => ! $has_cap }); $ret .= LJ::html_submit('journaldomain_del' => "Remove") unless $has_cap; $ret .= "
 $ML{'.domainalias.example'}
"; $ret .= " $LJ::SITENAME})." p?>
\n\n"; } ### ending submit block $ret .= "\n"; $ret .= "\n"; $ret .= "
\n"; return $ret; } _code?> <=body page?> link: htdocs/moodlist.bml, htdocs/developer/index.bml, htdocs/developer/varlist.bml, htdocs/styles/create.bml post: htdocs/modify_do.bml _c?>