# ==================================================================
# Gossamer Community
#
# Website : http://gossamer-threads.com/
# Support : http://gossamer-threads.com/scripts/support/
# CVS Info :
# Revision : $Id: Admin.pm,v 1.65 2003/05/31 23:26:30 aki Exp $
#
# Copyright (c) 2002 Gossamer Threads Inc. All Rights Reserved.
# Redistribution in part or in whole strictly prohibited. Please
# see LICENSE file for full details.
# ==================================================================
package Community::Web::Admin;
# ===================================================================
use strict 'vars', 'subs';
use GT::Base qw/:all/;
use Community qw/
$IN $DB $CFG
comm_encrypt
comm_compare_pass
comm_language
comm_fatal
comm_debug
/;
use GT::Plugins;
sub process {
# -------------------------------------------------------------------
my $do = shift;
# Check that the IP the user coming from is allowed to access the admin area.
if (@{$CFG->{admin_ips}}) {
my $ip = $ENV{REMOTE_ADDR};
unless (grep { $ip eq $_ } @{$CFG->{admin_ips}}) {
print $IN->header;
require Community::Web::User;
return Community::Web::User::user_page('user_login.html', { error => comm_language('LOGIN_BANNEDIP') });
}
}
my %valid = (
map { $_ => 1 } qw(
admin_home
admin_help
admin_user
admin_user_form
admin_user_add
admin_user_mod
admin_user_del
admin_verify
admin_import
admin_export
admin_sql
admin_online
admin_setup
admin_setup_sql
admin_setup_pwd
admin_env
admin_logout
admin_initial_setup
admin_database_resync
admin_database_editor
admin_database_column_add
admin_database_column_editor
admin_database_column_modify
admin_database_column_delete
admin_apps
admin_apps_add
admin_apps_form
admin_apps_modify
admin_apps_delete
admin_apps_users
admin_view_file
admin_download_file
admin_plugin
)
);
$do = exists $valid{$do} ? $do : 'admin_home';
admin_date_init();
my ($tpl, $vars, $opts, $cookies) = GT::Plugins->dispatch(
$CFG->{path_private} . '/lib/Plugins/Community',
"web_$do",
\&$do,
@_
);
if ($tpl) {
return GT::Plugins->dispatch(
$CFG->{path_private} . '/lib/Plugins/Community',
'web_admin_page',
\&admin_page,
$tpl, $vars, $opts, $cookies
);
}
}
sub admin_home {
# -------------------------------------------------------------------
my $pg = $IN->param('pg') || 'admin_home.html';
return $pg;
}
sub admin_page {
# -------------------------------------------------------------------
my ( $page, $vars, $opts, $cookies ) = @_;
$page ||= 'admin_home.html';
if ($page !~ /^[\w\-]+\.[\w\-]+$/) {
die "Invalid page: $page\n";
$page = 'admin_home.html';
}
my $template_dir = "$CFG->{path_private}/templates/$CFG->{system_template_set}";
$vars ||= {};
$opts ||= {};
exists $opts->{compress} or ($opts->{compress} = $CFG->{system_compress});
exists $opts->{print} or ($opts->{print} = 1);
exists $opts->{escape} or ($opts->{escape} = 1);
exists $opts->{root} or ($opts->{root} = $template_dir);
# Used for menu to show if we are logged in.
$vars->{comm_admin} = $IN->cookie('Community_Admin_Pass') unless (exists $vars->{comm_admin});
# Add version number which gets displayed on footer.
$vars->{comm_version} = $CFG->{version};
# Add config vars.
foreach my $key (keys %$CFG) {
$vars->{$key} = $CFG->{$key} unless (exists $vars->{$key});
}
# Add globals
my $globals = GT::Config->load($template_dir . '/globals.txt', {
local => 1,
cache => 1,
inheritance => 1,
create_ok => 1,
compile_subs => 'Community::Web::Admin'
});
foreach my $global (keys %$globals) {
unless (exists $vars->{$global}) {
$vars->{$global} = ref $globals->{$global} ?
$globals->{$global} :
\$globals->{$global};
}
}
# Used for HTML editor.
my $version;
if ($ENV{HTTP_USER_AGENT} and $ENV{HTTP_USER_AGENT} =~ /MSIE (\d+(?:\.\d+)?)/) {
$version = $1;
}
$vars->{is_ie} = $version && $version >= 5.5;
if ($ENV{HTTP_USER_AGENT} and $ENV{HTTP_USER_AGENT} =~ m{Mozilla/(\d+\.\d+)}) {
$version = $1;
}
$vars->{is_mozilla5} = $version && $version >= 5;
# Make CGI input available.
foreach my $key ($IN->param) {
$vars->{$key} = $IN->param($key) unless (exists $vars->{$key});
}
print $IN->header( $cookies ? ( -cookie => $cookies ) : () ) if $opts->{print};
GT::Template->parse($page, $vars, $opts);
}
sub admin_date_init {
#--------------------------------------------------------------------
require GT::Date;
$GT::Date::OFFSET = $CFG->{date_offset} * 3600;
$GT::Date::LANGUAGE = {
'month_names' => $CFG->{date_month_long},
'day_names' => $CFG->{date_days_long},
'short_month_names' => $CFG->{date_month_short},
'short_day_names' => $CFG->{date_days_short}
};
GT::Date::build_lang();
}
sub admin_user {
#--------------------------------------------------------------------
my $msg = shift;
my $cgi = $IN->get_hash();
my $mh = $cgi->{mh} || $CFG->{admin_page_per_screen} || 25;
my $nh = $cgi->{nh} || 1;
my $bg = ( $nh == 1 ) ? 0 : ( $nh - 1 ) * $mh; # started record
my $sb = $cgi->{sb} || 'comm_username';
my $so = $cgi->{so} || 'ASC';
my $al = $cgi->{alpha};
require GT::SQL::Condition;
my $cd = new GT::SQL::Condition;
my $db = $DB->table('comm_users');
my (@results, $speed_bar, $error);
if ( $cgi->{bsearch} ) { # search users
if ( !$cgi->{search_val} ) {
$error = comm_language('ADMIN_USER_SRC_INVALID');
}
elsif ( $cgi->{search_val} ne '*' ) {
if ( $cgi->{search_col} ) { # search on specified field
$cd->add($cgi->{search_col}, 'like', "%$cgi->{search_val}%");
}
else { # all fields
my @cols = qw/comm_username comm_email prof_first_name prof_last_name prof_company prof_country prof_state prof_city prof_phone/;
my $cd_sub = new GT::SQL::Condition('OR');
foreach ( @cols ) {
next unless (exists $db->cols->{$_});
$cd_sub->add($_, 'like', "%$cgi->{search_val}%");
}
$cd->add($cd_sub);
}
$msg = comm_language('ADMIN_USER_SRC_RESULTS');
}
}
elsif ( $al and $al ne 'all') { # quick search users
$cd->add('comm_username', 'like', "$al%");
$msg = comm_language('ADMIN_USER_SRC_RESULTS');
}
my $hits = $db->count($cd);
$msg ||= comm_language('ADMIN_USER_RESULTS');
$msg = sprintf($msg, $hits);
if ( $hits ) {
$db->select_options("ORDER BY $sb $so", "LIMIT $bg, $mh");
my $sth = $db->select($cd);
while ( my $rs = $sth->fetchrow_hashref ) {
push @results, $rs;
}
if ( $hits > $mh ) {
my $url = GT::CGI->url(remove_empty => 1);
my $disp = $DB->html($db, $cgi);
$speed_bar .= $disp->toolbar($nh, $mh, $hits, $url);
}
}
my $search_bar = _search_bar();
return ('admin_user.html', {
hits => $hits,
speed_bar => \$speed_bar,
results => \@results,
search_bar => \$search_bar,
msg => \$msg,
error => \$error
});
}
sub admin_user_form {
#--------------------------------------------------------------------
my $error = shift;
my @questions;
foreach my $question ( @{$CFG->{signup_questions}} ) {
push @questions, { question => $question };
}
my $app_hits = $DB->table('comm_apps')->count;
my $enctype = $DB->table('comm_users')->_file_cols() ? 'enctype="multipart/form-data"' : '';
# Display the modify form if we have a community id already.
if ($IN->param('comm_id')) {
my $user = $DB->table('comm_users')->get($IN->param('comm_id'));
if (! $user) {
return admin_user(comm_language('ADMIN_USER_MOD_INVALID', $IN->param('comm_id')))
}
$user = _user_from_cgi($IN->get_hash, $user, $error ? 1 : 0);
return ('admin_user_modify_form.html', {
comm_question_loop => \@questions,
apps_hits => $app_hits,
enctype => $enctype,
error => \$error,
%$user,
});
}
# Otherwise, display the add form.
else {
my %apps;
# If this is pulling up the form for the first time, make sure to default which
# apps are going to be active.
if ($IN->param('do') eq 'admin_user_form') {
my $apps = $DB->table('comm_apps')->select->fetchall_hashref;
foreach my $app (@$apps) {
$apps{'app_' . $app->{app_keyword}} = $app->{app_autocreate} ? 2 : 0;
}
}
my $enabled = defined $IN->param('comm_enabled') ? $IN->param('comm_enabled') : 1;
return ('admin_user_add_form.html', {
comm_question_loop => \@questions,
comm_enabled => $enabled,
apps_hits => $app_hits,
enctype => $enctype,
error => \$error,
%apps
});
}
}
sub admin_user_add {
#--------------------------------------------------------------------
my $db = $DB->table('comm_users');
my $cols = $db->cols;
my $user = _user_from_cgi($IN->get_hash);
require Community::User;
my $error;
$error = Community::User::cuser_un_validate_error($user->{comm_username});
if ($error) {
return admin_user_form(comm_language($error, $user->{comm_username}));
}
$error = Community::User::cuser_email_validate_error($user->{comm_email});
if ($error) {
return admin_user_form(comm_language($error, $user->{comm_email}));
}
unless ( $user->{comm_password} ) {
return admin_user_form(comm_language('ADMIN_INVALID_PASSWORD'));
}
my $clear_pass = $user->{comm_password};
$clear_pass =~ s/^\s*|\s*$//g;
if ( $CFG->{system_store_clear_pass} ) {
$user->{comm_clr_pass} = $clear_pass;
}
$user->{comm_password} = comm_encrypt($clear_pass);
$user->{comm_created} = time;
$user->{comm_email_val} = 1;
local $GT::SQL::ERRORS->{ILLEGALVAL} = comm_language('ADMIN_DB_ILLEGALVAL');
local $GT::SQL::ERRORS->{UNIQUE} = comm_language('ADMIN_DB_UNIQUE');
local $GT::SQL::ERRORS->{NOTNULL} = comm_language('ADMIN_DB_NOTNULL');
my $comm_id = Community::User::cuser_insert($user);
if (! $comm_id) {
my $error_msg = $Community::error;
$error_msg =~ s,\n,
\n,g;
return admin_user_form($error_msg)
}
admin_user(comm_language('ADMIN_USER_ADDED', $user->{comm_username}));
}
sub admin_user_mod {
#--------------------------------------------------------------------
my $db = $DB->table('comm_users');
my $cols = $db->cols;
my $cgi = $IN->get_hash;
my $user = $db->get($cgi->{comm_id});
if (! $user) {
return admin_user(comm_language('ADMIN_USER_MOD_INVALID', $cgi->{comm_id}));
}
$user = _user_from_cgi($IN->get_hash, $user, 1);
require Community::User;
if (Community::User::cuser_email_isinvalid($user->{comm_email})) {
return admin_user_form(comm_language('SIGNUP_EMAIL_INVALID', $user->{comm_email}));
}
if ( $IN->param('new_comm_password') ) {
my $new_pass = $cgi->{new_comm_password};
$new_pass =~ s/^\s*|\s*$//g;
if ( $CFG->{system_store_clear_pass} ) {
$user->{comm_clr_pass} = $new_pass;
}
$user->{comm_password} = comm_encrypt($new_pass);
}
local $GT::SQL::ERRORS->{ILLEGALVAL} = comm_language('ADMIN_DB_ILLEGALVAL');
local $GT::SQL::ERRORS->{UNIQUE} = comm_language('ADMIN_DB_UNIQUE');
local $GT::SQL::ERRORS->{NOTNULL} = comm_language('ADMIN_DB_NOTNULL');
my $res = Community::User::cuser_update($user);
if (! $res) {
my $error_msg = $Community::error;
$error_msg =~ s,\n,
\n,g;
return admin_user_form($error_msg);
}
else {
return admin_user(comm_language('ADMIN_USER_MODIFIED', $user->{comm_username}));
}
}
sub admin_user_del {
#--------------------------------------------------------------------
my $db = $DB->table('comm_users');
my $cgi = $IN->get_hash();
# If they selected only one record to delete we still need an array ref
my $mod = (ref $cgi->{user} eq 'ARRAY') ? $cgi->{user} : [ $cgi->{user} ];
my $rec_modified = 0;
require Community::User;
foreach my $rec_num ( @{$mod} ) {
if ( $cgi->{"$rec_num-comm_username"} ) {
my $user = $db->select( { comm_username => $cgi->{"$rec_num-comm_username"} })->fetchrow_hashref;
next if (! $user);
my $ret = Community::User::cuser_delete($user);
if ( defined $ret and ($ret != 0 ) ) {
$rec_modified++;
}
else {
return admin_user(comm_language('ADMIN_USER_ERROR', $Community::error));
}
}
}
return admin_user(comm_language('ADMIN_USER_DELETED', $rec_modified));
}
sub admin_verify {
#--------------------------------------------------------------------
require Community::User;
my $id = $IN->param('comm_id');
my $user = $DB->table('comm_users')->select( { comm_id => $id } )->fetchrow_hashref;
$user->{comm_email_tmp} ||= $user->{comm_email}; # If the user never had a tmp set.
$user->{comm_email_val} = 1;
$user->{comm_email_code} = '';
$user->{comm_email_redir} = '';
$user->{comm_email} = $user->{comm_email_tmp};
$user->{comm_email_tmp} = '';
require Community::User;
my $res = Community::User::cuser_update($user);
if (! $res) {
my $error_msg = $Community::error;
$error_msg =~ s,\n,
\n,g;
return admin_user_form($error_msg);
}
return admin_user(comm_language('ADMIN_EMAIL_VERIFIED', $user->{comm_username}));
}
sub admin_import {
#--------------------------------------------------------------------
# Import data from either text file or textare box
#
my $method = $IN->param('import_from') || 'text';
my ($dbh, $def_path, $root_path);
if ( $method ne 'text' ) {
$root_path = $IN->param('gt_root_path') || '';
$def_path = $root_path;
if ( $method eq 'gmail' ) {
my $cfg = do "$root_path/GMail/Config/Data.pm";
if ( !$cfg ) {
return ('admin_database_import_step1.html', { error => comm_language('ADMIN_IMPORT_INVALID_CFG_PATH', "$root_path/GMail/ConfigData.pm") });
}
else {
$def_path = "$cfg->{location}->{path}->{data}/admin";
}
}
if ( !-e "$def_path/defs/database.def" ) {
return ('admin_database_import_step1.html', { error => comm_language('ADMIN_IMPORT_INVALID_DB_PATH', "$def_path/defs/database.def") });
}
require GT::SQL;
$dbh = GT::SQL->new({ def_path => "$def_path/defs", debug => $CFG->{debug} });
}
require Community::Import;
Community::Import::process( pro_id => $method, dbh => $dbh, root_path => $root_path, def_path => $def_path);
return;
}
sub admin_export {
#--------------------------------------------------------------------
# Export data from comm_users table to either text file or screen
#
require Community::Export;
Community::Export::process();
return;
}
sub admin_database_resync {
#--------------------------------------------------------------------
# Resync database
#
my $name = $IN->param('db') || 'comm_users';
# We need a creator for this.
my $c = $DB->creator($name);
my $db = $DB->table($name);
$c->load_table or return admin_database_editor({ error => comm_language('ADMIN_DB_RESYNC_ERROR', $GT::SQL::error) });
# Re Load our table object.
$db->reload;
return admin_database_editor({ msg => comm_language('ADMIN_DB_RESYNC') });
}
sub admin_database_editor {
#--------------------------------------------------------------------
# Print profile fields
#
my $opts = ref $_[0] eq 'HASH' ? shift : { @_ };
my $msg = $opts->{msg};
my $error = $opts->{error};
my $db = $DB->table('comm_users');
my $cols = $db->cols;
my @output;
foreach ( $db->ordered_columns ) {
/^prof_/ or next;
$cols->{$_}->{name} = $_;
push @output, $cols->{$_};
}
return ('admin_database_editor.html', { fields => \@output, msg => \$msg, error => \$error });
}
sub admin_database_column_add {
#--------------------------------------------------------------------
# Add a profile field
#
my $column = $IN->param('comm_column') || '';
( $column and $column =~ /^prof_\w+/ ) or return ('admin_database_add_form.html', { error => comm_language('ADMIN_DB_COLUMN_INVALID') });
my $db = $DB->table('comm_users');
my %cols = $db->cols;
my $attribs = _col_spec();
# Error checking
my $errors = _field_check();
if ( exists $cols{$column} ) {
$errors .= comm_language('ADMIN_TAB_COL_TAKEN', $column);
}
$errors and return ('admin_database_add_form.html', { error => \$errors });
$attribs->{pos} = keys (%cols) + 1;
$attribs->{edit} = 1;
$attribs->{default} ||= '';
my $editor = $DB->editor('comm_users');
# Add a column
delete $attribs->{column};
$editor->add_col($column, $attribs) or return ('admin_database_add_form.html', { error => comm_language('ADMIN_DB_ADD_ERROR', $column, $GT::SQL::error) });
# Add the indexes.
if ( $IN->param('comm_index') eq 'regular' ) {
$editor->add_index($column . '_idx' => [$column]) or return ('admin_database_add_form.html', { error => comm_language('ADMIN_DB_INDEX_ERROR', $GT::SQL::error) });
}
if ( $IN->param('comm_index') eq 'unique' ) {
$editor->add_index($column . '_idx' => [$column]) or return ('admin_database_add_form.html', { error => comm_language('ADMIN_DB_UNIQUE_ERROR', $GT::SQL::error) });
}
$db->reload;
return admin_database_editor(msg => comm_language('ADMIN_DB_ADDED', $column));
}
sub admin_database_column_editor {
#--------------------------------------------------------------------
# Form to modify a selected column
#
my $opts = ref $_[0] eq 'HASH' ? shift : { @_ };
my $msg = $opts->{msg};
my $error = $opts->{error};
my %cols = $DB->table('comm_users')->cols;
my $column = $IN->param('c') || return admin_database_editor(error => comm_language('ADMIN_DB_MOD_INVALID'));
my %attribs = %{$cols{$column}};
exists $cols{$column} or return admin_database_editor(error => comm_language('ADMIN_DB_MOD_NOTFOUND', $column));
( $column =~ /^prof_/mi ) or return admin_database_editor(error => comm_language('ADMIN_DB_MOD_NOTPER', $column));
# Set up defaults for the fields
foreach my $col (qw/column type not_null file_save_in file_max_size file_save_scheme default form_display form_type form_size form_names form_values regex values size/) {
$attribs{"comm_$col"} = $IN->param("comm_$col") if ( defined $IN->param("comm_$col") );
}
$attribs{column} ||= $column;
$attribs{form_type} ||= 'TEXT';
$attribs{form_size} ||= ($attribs{form_type} eq 'SELECT') ? 0 : '';
ref $attribs{form_size} and ($attribs{form_size} = join (",", @{$attribs{form_size}}));
ref $attribs{form_names} and ($attribs{form_names} = join ("\n", @{$attribs{form_names}}));
ref $attribs{form_values} and ($attribs{form_values} = join ("\n", @{$attribs{form_values}}));
ref $attribs{values} and ($attribs{values} = join ("\n", @{$attribs{values}}));
my %output;
foreach (keys %attribs ) {
$output{"comm_$_"} = $attribs{$_};
}
my $indexed = _index_list($column);
return ('admin_database_modify_form.html', { msg => \$msg, error => \$error, comm_index => $indexed, %output });
}
sub admin_database_column_modify {
#--------------------------------------------------------------------
# Modify a column
#
my $column = $IN->param('c') || return admin_database_editor(error => comm_language('ADMIN_DB_MOD_INVALID'));
( $column =~ /^prof_/mi ) or return admin_database_editor(error => comm_language('ADMIN_DB_MOD_NOTPER', $column));
# Keep any values that where there before
my $db = $DB->table('comm_users');
my $editor = $DB->editor('comm_users');
my $old_def = $db->cols->{$column};
( $old_def ) or return admin_database_editor(error => comm_language('ADMIN_DB_MOD_NOTFOUND', $column));
my $attribs = _col_spec();
for my $val ( keys %$old_def ) {
$attribs->{$val} = $old_def->{$val} unless exists $attribs->{$val};
}
# Error checking
my $errors = _field_check();
$errors and return admin_database_column_editor(error => \$errors);
# Add/Drop indexes.
my $index_type = _index_type($column);
if ( $index_type ne $IN->param('comm_index') ) {
if ($index_type eq 'none') {
if ( $IN->param('comm_index') eq 'regular' ) {
$editor->add_index( $column . "_idx" => [$column] );
}
else {
$editor->add_unique( $column . "_idx" => [$column] );
}
}
elsif ( $IN->param('comm_index') eq 'none' ) {
if ( $index_type eq 'regular' ) {
my $index = $db->index;
INDEX: foreach my $index_name (keys %$index) {
foreach my $col_name ( @{$index->{$index_name}} ) {
next unless ($col_name eq $column);
$editor->drop_index($index_name) or return admin_database_column_editor(error => $GT::SQL::error);
last INDEX;
}
}
}
else {
my $unique = $db->unique;
INDEX: foreach my $unique_name (keys %$unique) {
foreach my $col_name (@{$unique->{$unique_name}}) {
next unless ($col_name eq $column);
$editor->drop_unique($unique_name) or return admin_database_column_editor(error => $GT::SQL::error);
last INDEX;
}
}
}
}
}
# Make the changes
delete $attribs->{column};
$editor->alter_col($column, $attribs) or return admin_database_column_editor(error => $editor->error);
return admin_database_editor(msg => comm_language('ADMIN_DB_UPDATED', $column));
}
sub admin_database_column_delete {
#--------------------------------------------------------------------
# Remove a profile field
#
my $column = $IN->param('c') || return admin_database_editor(error => comm_language('ADMIN_DB_MOD_INVALID'));
( $column =~ /^prof_/mi ) or return admin_database_editor(error => comm_language('ADMIN_DB_MOD_NOTPER', $column));
# Keep any values that where there before
my $db = $DB->table('comm_users');
my $editor = $DB->editor('comm_users');
my $old_def = $db->cols->{$column};
$old_def or return admin_database_editor(error => comm_language('ADMIN_DB_MOD_NOTFOUND', $column));
# Drop the column from the database.
$editor->drop_col($column) or return admin_database_column_editor(error => $GT::SQL::error);
admin_database_editor(msg => comm_language('ADMIN_DB_DELETED', $column));
}
sub admin_apps {
#--------------------------------------------------------------------
#
my $opts = ref $_[0] eq 'HASH' ? shift : { @_ };
my $msg = $opts->{msg};
my $error = $opts->{error};
my $db = $DB->table('comm_apps');
$db->select_options('ORDER BY app_keyword');
my $cgi = $IN->get_hash;
my $sth = $db->query_sth();
my $hits = $db->hits();
if ( $hits == 0 ) {
$msg ||= comm_language('ADMIN_APPS_NORESULT');
return ('admin_application.html', { msg => \$msg });
}
# Build speed bar
my $speedbar = '';
if ( $hits > ($cgi->{mh} || 25) ) {
my $name = GT::CGI->url(remove_empty => 1);
my $disp = $DB->html($db, $cgi);
$speedbar .= $disp->toolbar($cgi->{nh} || 1, $cgi->{mh} || 25, $hits, $name);
}
my @output;
while ( my $rs = $sth->fetchrow_hashref ) {
push @output, $rs;
}
return ('admin_application.html', {
msg => \$msg,
error => \$error,
results => \@output,
hits => $hits
});
}
sub admin_apps_add {
#--------------------------------------------------------------------
# Add a application
#
my $db = $DB->table('comm_apps');
my $cols = $db->cols;
my $app;
foreach ( keys % $cols ) {
$app->{$_} = $IN->param("$_") if ( $IN->param("$_") );
}
$app->{app_local} = ( $app->{app_type} =~ /^Local\// ) ? 1 : 0;
if ( $app->{app_keyword} !~ /^\w+$/ ) {
return ('admin_apps_add_form.html', { error => comm_language('ADMIN_APPS_INVALID_KEYWORD') });
}
if ( $app->{app_local} ) {
if ( ! -e $app->{app_location} ) {
return ('admin_apps_add_form.html', { error => comm_language('ADMIN_APPS_LOCAL_INVALID') });
}
}
else {
require GT::WWW;
GT::WWW->get($app->{app_location});
}
local $GT::SQL::ERRORS->{ILLEGALVAL} = comm_language('ADMIN_DB_ILLEGALVAL');
local $GT::SQL::ERRORS->{UNIQUE} = comm_language('ADMIN_DB_UNIQUE');
local $GT::SQL::ERRORS->{NOTNULL} = comm_language('ADMIN_DB_NOTNULL');
my $comm_id = $db->add($app);
return ('admin_apps_add_form.html', { error => $GT::SQL::error }) if (! $comm_id );
my $editor = $DB->editor('comm_users');
my $res = $editor->add_col('app_' . $app->{app_keyword}, {
type => 'TINYINT',
unsigned => 1,
default => 0,
form_display => $app->{app_keyword},
form_type => 'checkbox'
});
if (! $res) {
$db->delete($comm_id);
return ('admin_apps_add_form.html', { error => $GT::SQL::error });
}
require Community::Apps;
$res = Community::Apps::run($app, 'install');
if (! $res) {
$db->delete($comm_id);
$editor->drop_col('app_' . $app->{app_keyword});
return ('admin_apps_add_form.html', { error => $Community::error });
}
admin_apps(msg => comm_language('ADMIN_APPS_ADDED', $app->{app_keyword}));
}
sub admin_apps_form {
#--------------------------------------------------------------------
# Print modify form
#
my $opts = ref $_[0] eq 'HASH' ? shift : { @_ };
my $msg = $opts->{msg};
my $error = $opts->{error};
my $app_id = $IN->param('app_id') or return admin_apps(error => comm_language('ADMIN_APPS_INVALID'));
my $app = $DB->table('comm_apps')->get($app_id);
( $app ) or return admin_apps(error => comm_language('ADMIN_APPS_NOTFOUND', $app_id));
my $users = $DB->table('comm_users');
my $enable = $users->count({ "app_$app->{app_keyword}" => 2 });
my $disable = $users->count({ "app_$app->{app_keyword}" => 1 });
my $null = $users->count({ "app_$app->{app_keyword}" => 0 });
return ('admin_apps_modify_form.html', {
msg => \$msg,
error => \$error,
enabled => $enable,
disabled => $disable,
not_registered => $null,
%$app
});
}
sub admin_apps_modify {
#--------------------------------------------------------------------
# Modify a application
#
my $app_id = $IN->param('app_id') or return admin_apps(error => comm_language('ADMIN_APPS_INVALID'));
my $cgi = $IN->get_hash;
my $db = $DB->table('comm_apps');
my $cols = $db->cols;
my $app = $db->get($app_id);
my $hash;
foreach ( keys % $cols ) {
if ( $_ eq 'app_autocreate' ) {
$hash->{$_} = ( $cgi->{$_} ) ? 1 : 0;
}
elsif ( $_ eq 'app_location') {
$hash->{$_} = $cgi->{$_} if ( $cgi->{$_} );
}
else {
$hash->{$_} = $app->{$_};
}
}
$hash->{app_local} = ( $hash->{app_type} =~ /^Local\// ) ? 1 : 0;
if ( $hash->{app_local} ) {
return admin_apps_form(error => comm_language('ADMIN_APPS_LOCAL_INVALID')) if ( !-e $hash->{app_location} );
}
else {
require GT::WWW;
GT::WWW->get($hash->{app_location});
}
# Setup the language for GT::SQL.
local $GT::SQL::ERRORS->{ILLEGALVAL} = comm_language('ADMIN_DB_ILLEGALVAL');
local $GT::SQL::ERRORS->{UNIQUE} = comm_language('ADMIN_DB_UNIQUE');
local $GT::SQL::ERRORS->{NOTNULL} = comm_language('ADMIN_DB_NOTNULL');
if ( $db->modify ($hash) ) {
return admin_apps(msg => comm_language('ADMIN_APPS_UPDATED', $hash->{app_keyword}));
}
else {
local $^W;
my $error = $GT::SQL::error;
$error =~ s/\n/
\n
'; # Stack trace. my $i = 0; $info .= "Stack Trace\n======================================\n"; $info .= GT::Base::stack_trace('Community', 1, 1); $info .= "\n\n"; # Print GT::SQL error if it exists. $info .= "System Information\n======================================\n"; $info .= "Perl Version: $]\n"; $info .= "DBI.pm Version: $DBI::VERSION\n" if ($DBI::VERSION); $info .= "Persistant Env: mod_perl ($MOD_PERL) SpeedyCGI ($SPEEDY)\n"; $info .= "Mod Perl Version: $mod_perl::VERSION\n" if (defined $ENV{GATEWAY_INTERFACE} and ($ENV{GATEWAY_INTERFACE} =~ /perl/i)); $info .= "GT::SQL::error = $GT::SQL::error\n" if ($GT::SQL::error); $info .= "DBI::errstr = $DBI::errstr\n" if (defined $DBI::errstr); $info .= "\@INC = \n\t" . join ("\n\t", @INC) . "\n"; $info .= "\$\@: $@\n" if ($@); $info .= "\n"; # CGI Parameters and Cookies. if (ref $IN eq 'GT::CGI') { if ($IN->param) { $info .= "CGI INPUT\n======================================\n"; foreach (sort $IN->param) { $info .= "$_ => " . $IN->param($_) . "\n"; } $info .= "\n\n"; } if ($IN->cookie) { $info .= "CGI Cookies\n======================================\n"; foreach (sort $IN->cookie) { $info .= "$_ => " . $IN->cookie($_) . "\n"; } $info .= "\n\n"; } } # Environement info. $info .= "ENVIRONMENT\n======================================\n"; foreach (sort keys %ENV) { $info .= "$_ => $ENV{$_}\n"; } $info .= ""; return ('admin_environment.html', { info => \$info }); } sub admin_logout { #--------------------------------------------------------------------- my $cookies = [ $IN->cookie( -name => 'Community_Admin_Pass', -value => '', -expire => '-1y' ) ]; require Community::Web::User; Community::Web::User::user_page( 'user_login.html', { session_admin => 0 }, {}, $cookies ); return; } sub admin_initial_setup { #--------------------------------------------------------------------- # my ($host, $port, $overwrite); unless ( $IN->param('initial_step') ) { return ('admin_initial_setup_first.html'); } if ( $IN->param('initial_step') == 2 ) { return ('admin_initial_setup_second.html'); } # Test the ability to create a def file. unless (open (TEST, "> $CFG->{path_private}/defs/database.def") ) { return ('admin_initial_setup_second.html', { error => \qq~ Unable to create our def file in $CFG->{path_private}/defs/.
$output" } ); } sub admin_view_file { #--------------------------------------------------------------------------- my $msg = shift; my $id = $IN->param('id'); my $cn = $IN->param('cn'); my $src = $IN->param('src') || 'db'; my $fname = $IN->param('fname'); die comm_language('ADMIN_FILE_INVALID') if ( not ( $id and $cn ) ) ; my $tbl = $DB->table('comm_users'); my ( $fh, $mimetype, $size ); if ( $src eq 'db' ) { print $src; eval { $fh = $tbl->file_info( $cn, $id ); }; if ( $fh ) { $fname = $fh->File_Name(); $mimetype = $fh->File_MimeType(); $size = $fh->File_Size(); } } else { require GT::SQL::File; require GT::MIMETypes; eval { $fh = GT::SQL::File->open($fname) }; $mimetype = GT::MIMETypes->guess_type($fname); $fname = GT::SQL::File::get_filename($fname); } if ( !$fh ) { die comm_language('ADMIN_FILE_ERROR'); } else { print $IN->header( '-type' => $mimetype, '-Content-Length' => $size, '-Content-Disposition' => \("inline; filename=".$fname) ); $fh->File_Binary() and binmode STDOUT; while ( read($fh, my $buffer, 4096) ) { print $buffer; } } return; } sub admin_download_file { #--------------------------------------------------------------------------- my $msg = shift; my $id = $IN->param('id'); my $cn = $IN->param('cn'); my $src = $IN->param('src') || 'db'; my $fname = $IN->param('fname'); die comm_language('ADMIN_FILE_INVALID') if ( not ( $id and $cn ) ) ; my $tbl = $DB->table('comm_users'); my ($fh, $mimetype, $size); if ( $src eq 'db' ) { eval { $fh = $tbl->file_info($cn, $id ); }; if ( $fh ) { $fname = $fh->File_Name(); $mimetype = $fh->File_MimeType(); $size = $fh->File_Size(); } } else { require GT::SQL::File; require GT::MIMETypes; eval { $fh = GT::SQL::File->open($fname) }; $mimetype = GT::MIMETypes->guess_type($fname); $fname = GT::SQL::File::get_filename($fname); } if (!$fh) { die comm_language('ADMIN_FILE_ERROR'); } else { print $IN->header( '-type' => 'application/download', '-Content-Length' => $size, '-Content-Transfer-Encoding' => 'binary', '-Content-Disposition' => \("attachment; filename=".$fname) ); $fh->File_Binary() and binmode STDOUT; while ( read ($fh, my $buffer, 4096) ) { print $buffer; } } return; } sub admin_plugin { # ------------------------------------------------------------------ # Run a plugin function. # my $plugin = $IN->param('plugin'); if ($IN->param('download') and ($plugin =~ /^[\w\-]+$/)) { my $path = "$CFG->{path_private}/lib/Plugins/Community/Uninstalled/$plugin.tar"; -e $path or die "No plugin ($path) found."; open FH, $path or die "Could not open $path for reading"; print $IN->header( '-type' => 'application/octet-stream', '-Content-Disposition' => 'attachment; filename="'.$plugin.'.tar"' ); print while