login. p?>" unless $remote; my @journals = ($remote->{'user'}); push @journals, LJ::get_shared_journals($remote); my $journal = $GET{'journal'} || $remote->{'user'}; unless (grep { $_ eq $journal } @journals) { return BML::redirect("/customize/"); } my $u = $remote; $u = LJ::load_user($journal) unless $journal eq $remote->{'user'}; my $userid = $u->{'userid'}; LJ::load_user_props($u, "stylesys", "s2_style"); $body = ""; $title = "Customize"; $js = ""; my $err = sub { $title = "Error"; $body = shift; return; }; my ($style, $layer); my $save_arg; my $save_redir; # when given 'w' argument, load user's current style, and edit the user layer. # this is the mode redirected to from /customize/ (the simple customization UI) if ($GET{'w'} eq "user" && $u->{'stylesys'} == 2) { $style = LJ::S2::load_style($u->{'s2_style'}); return $err->("Style not found.") unless $style && $style->{'userid'} == $u->{'userid'}; $layer = LJ::S2::load_layer($dbh, $style->{'layer'}->{'user'}); # if the b2lid of this layer has been remapped to a new layerid # then update the b2lid mapping for this layer my $b2lid = $layer->{b2lid}; if ($b2lid && $LJ::S2LID_REMAP{$b2lid}) { LJ::S2::b2lid_remap($u, $style->{'layer'}->{'user'}, $b2lid); $layer->{b2lid} = $LJ::S2LID_REMAP{$b2lid}; } $save_arg = "w=user&journal=$journal"; $save_redir = "/customize/?journal=$journal"; } return BML::redirect("/customize/") unless $layer; return $err->("Layer belongs to another user.") unless $layer->{'userid'} == $u->{'userid'}; return $err->("Layer isn't of type user or theme.") unless $layer->{'type'} eq "user" || $layer->{'type'} eq "theme"; my $lyr_layout = LJ::S2::load_layer($dbh, $layer->{'b2lid'}); return $err->("Layout layer for this $layer->{'type'} layer not found.") unless $lyr_layout; my $lyr_core = LJ::S2::load_layer($dbh, $lyr_layout->{'b2lid'}); return $err->("Core layer for layout not found.") unless $lyr_core; $lyr_layout->{'uniq'} = $dbh->selectrow_array("SELECT value FROM s2info WHERE s2lid=? AND infokey=?", undef, $lyr_layout->{'s2lid'}, "redist_uniq"); my ($lid_i18nc, $lid_theme, $lid_i18n); $lid_i18nc = $style->{'layer'}->{'i18nc'}; $lid_theme = $style->{'layer'}->{'theme'}; $lid_i18n = $style->{'layer'}->{'i18n'}; my $layerid = $layer->{'s2lid'}; my @layers; push @layers, ([ 'core' => $lyr_core->{'s2lid'} ], [ 'i18nc' => $lid_i18nc ], [ 'layout' => $lyr_layout->{'s2lid'} ], [ 'i18n' => $lid_i18n ]); if ($layer->{'type'} eq "user" && $lid_theme) { push @layers, [ 'theme' => $lid_theme ]; } push @layers, [ $layer->{'type'} => $layer->{'s2lid'} ]; my @layerids = grep { $_ } map { $_->[1] } @layers; LJ::S2::load_layers(@layerids); my %layerinfo; # load the language and layout choices for core. LJ::S2::load_layer_info(\%layerinfo, \@layerids); # action path if (LJ::did_post()) { # prevent spoofing: return BML::redirect("/customize") unless $POST{'userid'} == $u->{'userid'}; my %override; foreach my $prop (S2::get_properties($lyr_layout->{'s2lid'})) { $prop = S2::get_property($lyr_core->{'s2lid'}, $prop) unless ref $prop; next unless ref $prop; next if $prop->{'noui'}; my $name = $prop->{'name'}; next unless $POST{"$name:override"}; next unless LJ::S2::can_use_prop($u, $lyr_layout->{'uniq'}, $name); $override{$name} = [ $prop, $POST{"${name}_value"} ]; } if (LJ::S2::layer_compile_user($layer, \%override)) { return BML::redirect($save_redir) if $save_redir; $body = "Saved."; return; } else { my $error = LJ::last_error(); $body = "Error saving layer:
$error
"; } return; } $body .= "
"; $body .= LJ::html_hidden("userid", $u->{'userid'}); my %prop; # name -> hashref, deleted when added to a category my @propnames; foreach my $prop (S2::get_properties($lyr_layout->{'s2lid'})) { unless (ref $prop) { $prop = S2::get_property($lyr_core->{'s2lid'}, $prop); next unless ref $prop; } $prop{$prop->{'name'}} = $prop; push @propnames, $prop->{'name'}; } my @groups = S2::get_property_groups($lyr_layout->{'s2lid'}); my $misc_group; my %groupprops; # gname -> [ propname ] my %propgroup; # pname -> gname; foreach my $gname (@groups) { if ($gname eq "misc" || $gname eq "other") { $misc_group = $gname; } foreach my $pname (S2::get_property_group_props($lyr_layout->{'s2lid'}, $gname)) { my $prop = $prop{$pname}; next if ! $prop || $propgroup{$pname}; $propgroup{$pname} = $gname; push @{$groupprops{$gname}}, $pname; } } # put unsorted props into an existing or new unsorted/misc group if (@groups) { my @unsorted; foreach my $pname (@propnames) { my $prop = $prop{$pname}; next if ! $prop || $propgroup{$pname}; push @unsorted, $pname; } if (@unsorted) { unless ($misc_group) { $misc_group = "misc"; push @groups, "misc"; } push @{$groupprops{$misc_group}}, @unsorted; } } my $group_name = sub { my $gname = shift; foreach my $lid ($lid_i18n, $lyr_layout->{'s2lid'}, $lid_i18nc, $lyr_core->{'s2lid'}) { next unless $lid; my $name = S2::get_property_group_name($lid, $gname); return LJ::ehtml($name) if $name; } return "Misc" if $gname eq "misc"; return $gname; }; my $prop_js = ""; my $output_prop = sub { my $name = shift; my $prop = $prop{$name}; return if ! $prop || $prop->{'noui'}; my $name = $prop->{'name'}; my $type = $prop->{'type'}; my $can_use = LJ::S2::can_use_prop($u, $lyr_layout->{'uniq'}, $name); # figure out existing value (if there was no user/theme layer) my $existing; foreach my $lid (reverse @layerids) { next if $lid == $layerid; $existing = S2::get_set($lid, $name); last if defined $existing; } if (ref $existing eq "HASH") { $existing = $existing->{'as_string'}; } if ($type eq "bool") { $prop->{'values'} ||= "1|Yes|0|No"; } my %values = split(/\|/, $prop->{'values'}); my $existing_display = defined $values{$existing} ? $values{$existing} : $existing; $existing_display = LJ::eall($existing_display); my $override = S2::get_set($layerid, $name); my $had_override = defined $override; $override = $existing unless defined $override; if (ref $override eq "HASH") { $override = $override->{'as_string'}; } $body .= "{'des'}) . " h1?>"; { my $t = ""; $t .= LJ::eall($prop->{'note'}) if $prop->{'note'}; $t .= "" if $LJ::HELPURL{"s2opt_$name"}; $body .= "" if $t; } $body .= "
\n"; $body .= LJ::html_check({ 'name' => "$name:override", 'id' => "$name:override", 'selected' => $had_override, 'disabled' => ! $can_use, 'onchange' => "toggleOverride('$name');" }); my $offhelp = ! $can_use ? LJ::help_icon('s2propoff', ' ') : ""; $body .= "$offhelp
\n"; $body .= "
\n
Default:
\n
\n"; if ($type eq "int" || $type eq "string") { if ($existing_display ne "") { $body .= $existing_display; } else { $body .= "(nothing)"; } } elsif ($type eq "Color") { $body .= "  $existing_display"; } elsif ($type eq "bool") { $body .= $existing_display; } $body .= "
\n
Override:
\n
\n"; if ($prop->{'values'}) { $body .= LJ::html_select({ 'name' => "${name}_value", 'disabled' => ! $can_use, 'selected' => $override }, split(/\|/, $prop->{'values'})); } elsif ($type eq "int") { $body .= LJ::html_text({ 'name' => "${name}_value", 'disabled' => ! $can_use, 'value' => $override, 'maxlength' => 5, 'size' => 7 }); } elsif ($type eq "string") { my ($rows, $cols) = ($prop->{'rows'} + 0, $prop->{'cols'} + 0); if ($rows > 0 && $cols > 0) { $body .= LJ::html_textarea({ 'name' => "${name}_value", 'disabled' => ! $can_use, 'value' => $override, 'onfocus' => "toggleOverride('$name');", 'rows' => $rows, 'cols' => $cols }); } else { my ($size, $maxlength) = ($prop->{'size'} || 30, $prop->{'maxlength'} || 255); $body .= LJ::html_text({ 'name' => "${name}_value", 'disabled' => ! $can_use, 'value' => $override, 'maxlength' => $maxlength, 'size' => $size }); } } elsif ($type eq "Color") { $body .= LJ::html_color({ 'name' => "${name}_value", 'disabled' => ! $can_use, 'default' => $override, 'des' => $prop->{'des'} }); } $body .= "
\n
\n"; $prop_js .= "toggleOverride('$name');\n"; }; if (@groups) { $body .= "
"; my $num = 0; foreach my $gname (@groups) { my $name = $group_name->($gname); $num++; my $class = $num == 1 ? "propgrouptabsel" : "propgrouptab"; $js .= " propgroups[$num] = \"$gname\";\n"; $body .= "$name\n"; } $body .= "
"; $body .= "
"; foreach my $gname (@groups) { $body .= "\n"; $body .= "
\n"; foreach my $pname (@{$groupprops{$gname}}) { $output_prop->($pname); } $body .= "
"; } $body .= "
\n"; $body .= "\n"; } else { foreach my $pname (@propnames) { $output_prop->($pname); } } $body .= ""; $body .= "
"; $body .= LJ::html_submit('action:save', "Save"); $body .= "
"; $body .= "
"; return; } _code?> body=> head<= <=head page?>