mourningdove/cgi-bin/DW/Controller/Admin/ThemeMetadata.pm

276 lines
8.2 KiB
Perl
Raw Permalink Normal View History

2026-05-24 01:03:05 +00:00
#!/usr/bin/perl
#
# DW::Controller::Admin::ThemeMetadata
#
# Theme metadata admin page.
#
# Authors:
# Andrea Nall <anall@andreanall.com>
#
# Copyright (c) 2010 by Dreamwidth Studios, LLC.
#
# This program is free software; you may redistribute it and/or modify it under
# the same terms as Perl itself. For a copy of the license, please reference
# 'perldoc perlartistic' or 'perldoc perlgpl'.
#
package DW::Controller::Admin::ThemeMetadata;
use strict;
use warnings;
use DW::Controller;
use DW::Routing;
use DW::Template;
use DW::Controller::Admin;
DW::Routing->register_string( "/admin/themes/index", \&index_controller );
DW::Controller::Admin->register_admin_page(
'/',
path => 'themes/',
ml_scope => '/admin/themes/index.tt',
privs => ['siteadmin:themes']
);
DW::Routing->register_string( "/admin/themes/theme", \&theme_controller );
DW::Routing->register_string( "/admin/themes/category", \&category_controller );
my %system_cats = ( featured => 1, );
sub index_controller {
my ( $ok, $rv ) = controller( privcheck => ["siteadmin:themes"] );
return $rv unless $ok;
my $pub = LJ::S2::get_public_layers();
my @themes = grep { $_ !~ /^\d+$/ && $pub->{$_}->{type} eq 'theme' } keys %$pub;
my %layers = ();
foreach my $uniq (@themes) {
my ( $lay, $theme ) = split( '/', $uniq );
push @{ $layers{$lay} }, $theme;
}
my $vars = {
%$rv,
layers => \%layers,
categories => [ LJ::S2Theme->all_categories( all => 1, special => 1 ) ],
};
return DW::Template->render_template( 'admin/themes/index.tt', $vars );
}
sub _validate_category {
return 1 if $_[0] =~ /^[a-zA-Z0-9 ]+$/;
return 0;
}
sub theme_controller {
my ( $ok, $rv ) = controller( privcheck => ["siteadmin:themes"] );
return $rv unless $ok;
my $r = DW::Request->get;
my $args = $r->did_post ? $r->post_args : $r->get_args;
my $uniq = $args->{theme};
my $pub = LJ::S2::get_public_layers();
my $s2lid = $pub->{$uniq}->{s2lid};
return $r->redirect("/admin/themes/") unless $s2lid;
my $theme = LJ::S2Theme->new( themeid => $s2lid );
return $r->redirect("/admin/themes/") unless $theme;
if ( $r->method eq 'POST' ) {
return $r->redirect("/admin/themes/theme?theme=$uniq")
unless LJ::check_form_auth( $args->{lj_form_auth} );
# FIXME: This should be in S2Themes
my $cats = $theme->metadata->{cats};
my %kwid_map = map { $_->{kwid} => $_ } values %$cats;
my @kwids = keys %kwid_map;
my %change_act;
my %delete;
foreach my $kwid (@kwids) {
my $act_db = $kwid_map{$kwid}->{active};
if ( $args->{"cat_remove_$kwid"} ) {
$delete{$kwid} = 1;
}
else {
$change_act{$kwid} = 1
if $args->{"cat_act_$kwid"} && !$act_db;
$change_act{$kwid} = 0
if !$args->{"cat_act_$kwid"}
&& $act_db
&& exists $kwid_map{$kwid};
}
}
foreach my $kw ( split( ',', $args->{cat_add} ) ) {
$kw = LJ::trim($kw);
next unless _validate_category($kw);
my $kwid = LJ::get_sitekeyword_id( $kw, 1, allowmixedcase => 1 );
next if $delete{$kwid};
my $add = 1;
$add = 0 if $kwid_map{$kwid} && $kwid_map{$kwid}->{active};
$change_act{$kwid} = 1 if $add;
}
my $dbh = LJ::get_db_writer();
if (%change_act) {
my @bind;
my @vals;
foreach my $kwid ( keys %change_act ) {
push @vals, "(?,?,?)";
push @bind, ( $s2lid, $kwid, $change_act{$kwid} );
}
$dbh->do(
"REPLACE INTO s2categories ( s2lid, kwid, active ) "
. "VALUES "
. join( ',', @vals ),
undef, @bind
) or die $dbh->errstr;
}
if (%delete) {
$dbh->do(
"DELETE FROM s2categories where s2lid = ? "
. "AND kwid IN ( "
. join( ',', map { $dbh->quote($_) } keys %delete ) . " )",
undef, $s2lid
) or die $dbh->errstr;
}
$theme->clear_cache;
LJ::S2Theme->clear_global_cache;
return $r->redirect("/admin/themes/theme?theme=$uniq");
}
my %cats = %{ $theme->metadata->{cats} };
my @cat_keys = sort {
my $ah = $cats{$a};
my $bh = $cats{$b};
return
( $ah->{order} || 0 ) <=> ( $bh->{order} || 0 )
|| ( $bh->{active} || 0 ) <=> ( $ah->{active} || 0 )
|| $ah->{keyword} cmp $bh->{keyword}
} keys %cats;
my $vars = {
%$rv,
theme_arg => $uniq,
theme => $theme,
cats => \%cats,
cat_keys => \@cat_keys,
};
return DW::Template->render_template( 'admin/themes/theme.tt', $vars );
}
sub category_controller {
my ( $ok, $rv ) = controller( privcheck => ["siteadmin:themes"] );
return $rv unless $ok;
my $r = DW::Request->get;
my $args = $r->did_post ? $r->post_args : $r->get_args;
my $cat = $args->{category};
$cat = undef unless _validate_category($cat);
return $r->redirect("/admin/themes/") unless $cat;
my $pub = LJ::S2::get_public_layers();
my @themes = grep { $_ !~ /^\d+$/ && $pub->{$_}->{type} eq 'theme' } keys %$pub;
my %layers = ();
foreach my $uniq (@themes) {
my ( $lay, $theme ) = split( '/', $uniq );
$layers{$lay}->{$theme} = $pub->{$uniq};
}
my %s2lid_act = map { $_->s2lid => 1 } LJ::S2Theme->load_by_cat($cat);
my $can_delete = 0;
my $is_system = $system_cats{$cat} ? 1 : 0;
$can_delete = ( %s2lid_act ? 0 : 1 ) unless $is_system;
if ( $r->method eq 'POST' ) {
return $r->redirect("/admin/themes/category?category=$cat")
unless LJ::check_form_auth( $args->{lj_form_auth} );
my $dbh = LJ::get_db_writer();
if ( $args->{delete} ) {
return $r->redirect("/admin/themes/category?category=$cat")
unless $can_delete;
my $kwid = LJ::get_sitekeyword_id( $cat, 1, allowmixedcase => 1 );
my $to_clear =
$dbh->selectall_arrayref( "SELECT s2lid FROM s2categories WHERE kwid = ?",
undef, $kwid )
or die $dbh->errstr;
$dbh->do( "DELETE FROM s2categories WHERE kwid = ?", undef, $kwid ) or die $dbh->errstr;
LJ::S2Theme->new( themeid => $_->[0] )->clear_cache foreach @$to_clear;
LJ::S2Theme->clear_global_cache;
return $r->redirect("/admin/themes/");
}
else {
my %change_act;
foreach my $theme (@themes) {
my $s2lid = $pub->{$theme}->{s2lid};
my $db_act = $s2lid_act{$s2lid};
my $act = $args->{"s2lid_act_$s2lid"} || 0;
$change_act{$s2lid} = 1 if $act && !$db_act;
$change_act{$s2lid} = 0 if !$act && $db_act;
}
if (%change_act) {
my @bind;
my @vals;
my $kwid = LJ::get_sitekeyword_id( $cat, 1, allowmixedcase => 1 );
foreach my $s2lid ( keys %change_act ) {
push @vals, "(?,?,?)";
push @bind, ( $s2lid, $kwid, $change_act{$s2lid} );
}
$dbh->do(
"REPLACE INTO s2categories ( s2lid, kwid, active ) "
. "VALUES "
. join( ',', @vals ),
undef, @bind
) or die $dbh->errstr;
}
LJ::S2Theme->new( themeid => $_ )->clear_cache foreach keys %change_act;
LJ::S2Theme->clear_global_cache;
return $r->redirect("/admin/themes/category?category=$cat");
}
}
my $vars = {
%$rv,
category => $cat,
layers => \%layers,
active => \%s2lid_act,
can_delete => $can_delete,
is_system => $is_system,
};
return DW::Template->render_template( 'admin/themes/category.tt', $vars );
}
1;