# ==================================================================
# Gossamer Community
#
# Website : http://gossamer-threads.com/
# Support : http://gossamer-threads.com/scripts/support/
# CVS Info :
# Revision : $Id: SSI.pm,v 1.24 2005/07/21 23:18:26 alex Exp $
#
# Copyright (c) 2004 Gossamer Threads Inc. All Rights Reserved.
# Redistribution in part or in whole strictly prohibited. Please
# see LICENSE file for full details.
# ==================================================================
package Community::Web::SSI;
# ===================================================================
use strict;
use Community qw/
$IN $DB $CFG
comm_language
comm_debug
comm_fatal
/;
use GT::Plugins;
sub process {
# -------------------------------------------------------------------
my $do = shift;
my %valid = (
map { $_ => 1 } qw(
ssi_username
ssi_login
ssi_profile_form
ssi_apps_form
)
);
$do = exists $valid{$do} ? $do : 'ssi_username';
return GT::Plugins->dispatch(
$CFG->{path_private} . '/lib/Plugins/Community',
"web_$do",
\&$do,
@_
);
}
sub ssi_username {
# -------------------------------------------------------------------
my $user = $IN->cookie($CFG->{session_cookie_name_user});
my $name = (defined $user and length $user) ? $user : comm_language('SSI_GUEST');
if ($IN->param('do') eq 'ssi_username') {
print $IN->header() unless ($IN->param('noheaders'));
print $name;
}
else {
return $name;
}
}
sub ssi_login {
# -------------------------------------------------------------------
my $user = $IN->cookie($CFG->{session_cookie_name_user});
my $name = (defined $user and length $user) ? $user : undef;
require Community::Web::User;
if ($IN->param('do') eq 'ssi_login') {
print $IN->header() unless ($IN->param('noheaders'));
Community::Web::User::user_page('user_ssi_login.html', { comm_username => $name }, { print => 1 });
}
else {
return Community::Web::User::user_page('user_ssi_login.html', { comm_username => $name }, { print => 0 });
}
}
sub ssi_profile_form {
# -------------------------------------------------------------------
require GT::SQL::Display::HTML;
require GT::SQL::Display::HTML::Table;
my $opts = ref $_[0] ? shift : {@_};
my $user_tb = $DB->table('comm_users');
$opts->{col_prefix} ||= '^prof_'; # used to filter columns
$opts->{tr} ||= 'class="body"';
$opts->{td_l} ||= 'class="body" width="40%" align="right"';
$opts->{td_r} ||= 'class="body" align="left"';
$opts->{mode} ||= 'edit'; # edit/search
$opts->{required} ||= '*';
$opts->{show_all_fields} ||= 0; # ignore sign_restricted_profile?
# Take the list of restricted profile fields
# and convert it into a hashref that can be used as a lookup
# to quickly determine matches, but check to see that
# the system isn't being requested to display all possible profile
# fields
my $restricted_fields = $opts->{show_all_fields} ?
{} :
{ map {($_=>1)} @{$CFG->{signup_restricted_profile}} };
# Choose which columns will be displayed.
unless ( $opts->{cols} ) {
my $cols = $opts->{cols} = [];
my $skip = { map {($_=>1)} @{$opts->{col_skip}||[]} };
foreach ( $user_tb->ordered_columns ) {
next if $restricted_fields->{$_};
# MOD
if ($_ eq "prof_Signup_Date") { next; }
# END MOD
next unless /$opts->{col_prefix}/;
next if $skip->{$_};
push @$cols, $_;
}
$opts->{cols} = $cols;
}
my $tags = GT::Template->tags;
my $cols = {$user_tb->cols}; # request a copy of the def
my $disp = $DB->html($user_tb, GT::Template->tags);
my $html = '';
if ( $opts->{mode} eq 'hidden' ) {
# Preserve all columns that relate to the comm_user database
my $cols = $user_tb->cols;
my $hidden_html = '';
foreach my $col ( keys %$cols ) {
foreach my $name ( map { "$col$_" } ( '', qw( -opt -gt -lt -le -ge -ne )) ) {
my $v = $tags->{$name};
next unless defined $v;
my $input_html = ssi_form_control({
form_type => 'hidden',
value => $v,
name => $name
});
$html .= $$input_html;
}
}
return \$html;
}
my %search_defs = (
string => { form_names => [qw( LIKE <> = )] },
number => { form_names => [qw( = <> < <= > >= )] },
date => { form_names => [ '', qw( = <> < <= > >= )] },
radio => { form_names => [qw( = <> )] },
minimal => { form_names => [qw( = )] }
);
foreach my $col (@{$opts->{cols}}) {
# MOD
if ($col eq "prof_Signup_Date") { next; }
# END MOD
my $control_opts = $cols->{$col}||{};
my $title = comm_language( $cols->{$col}{form_display} );
if ( $opts->{mode} eq 'search' ) {
my $col_type;
my $col_info = $cols->{$col};
if ( $col_info->{form_type} =~ /TEXT|HIDDEN|CHECKBOX/i ) {
$col_type = $col_info->{type} =~ /CHAR|TEXT/i ? 'string' :
$col_info->{type} =~ /INT|FLOAT|DOUBLE/i ? 'number' :
$col_info->{type} =~ /DATE/i ? 'date' :
'';
}
elsif ( $col_info->{form_type} =~ /CHECKBOX|RADIO/i ) {
unshift @{$control_opts->{form_values}}, comm_language( 'ADMIN_DB_FILTER_RADIO_ANY' );
unshift @{$control_opts->{form_names}}, '';
$col_type = 'radio';
}
elsif ( $col_info->{form_type} =~ /DATE/i ) {
$col_type = 'date';
}
elsif ( $col_info->{form_type} =~ /SELECT/i ) {
}
my $option_html = \'';
if ( $col_type ) {
my $search_def = $search_defs{ $col_type };
$search_def->{form_values} ||= do {
[
split /\|/,
comm_language( 'ADMIN_DB_FILTER_' . uc( $col_type ) )
];
};
$option_html = ssi_form_control({
name => $col . '-opt',
def => $search_def,
value => $tags->{$col.'-opt'}||'',
form_type => 'select',
blank => 0,
});
}
my $input_html = ssi_form_control(
name => $col,
def => $control_opts ,
value => $tags->{$col}
);
$html .= qq|
{tr}>
{td_l}>$title:
{td_r}>$$input_html
$$option_html
|;
}
else {
my $input_html = ssi_form_control({
name => $col,
def => $control_opts,
value => $tags->{$col}
});
$html .= ( $cols->{$col}->{not_null} ) ?
"
{tr}>
{td_l}>$title:
{td_r}>$$input_html $opts->{required}
" :
"
{tr}>
{td_l}>$title:
{td_r}>$$input_html
";
}
}
if ($IN->param('do') eq 'ssi_profile_form') {
print $IN->header() unless ($IN->param('noheaders'));
print $html;
}
else {
return \$html;
}
}
sub ssi_apps_form {
# -------------------------------------------------------------------
my %opts = @_;
$opts{mode} ||= 'edit'; # edit/search type forms
$opts{tr} ||= 'class="body"';
$opts{td_l} ||= 'class="body" width="40%" align="right"';
$opts{td_r} ||= 'class="body" align="left"';
$opts{tags} ||= GT::Template->tags;
my $tags = GT::Template->tags;
my $apps = $DB->table('comm_apps')->select->fetchall_hashref;
my $html = '';
my $status = comm_language('ADMIN_APPS_STATUS');
require Community::Apps;
my $search_def = {
form_names => [qw( = <> )],
form_values => [ split /\|/, comm_language( 'ADMIN_DB_FILTER_RADIO' ) ]
};
foreach my $app (@$apps) {
if ($opts{admin}) {
my $col = 'app_' . $app->{app_keyword};
my $name = $DB->table('comm_users')->cols->{$col}->{form_display} || $col;
my $select = ssi_form_control({
name => $col,
form_type => 'select',
def => {
form_values => [
comm_language('ADMIN_APPS_STATUS_NOTCREATED'),
comm_language('ADMIN_APPS_STATUS_DISABLED'),
comm_language('ADMIN_APPS_STATUS_ENABLED'),
],
form_names => [ 0, 1, 2 ]
},
value => $opts{tags}{$col},
blank => ( $opts{mode} eq 'search' )
});
$html .= qq~
$name $status
$$select
~;
if ( $opts{mode} eq 'search' ) {
my $option_html = ssi_form_control({
name => "$col-opt",
def => $search_def,
value => $tags->{"$col-opt"},
form_type => 'select',
blank => 0
});
$html .= "
$$option_html
";
}
$html .= '
';
}
unless ( $opts{mode} eq 'search' ) {
$html .= Community::Apps::run($app, 'signup_form', \%opts);
}
}
if ($IN->param('do') eq 'ssi_apps_form') {
print $IN->header() unless ($IN->param('noheaders'));
print $html;
}
else {
return \$html;
}
}
sub ssi_form_control {
# -------------------------------------------------------------------
require GT::SQL::Display::HTML;
require GT::SQL::Display::HTML::Table;
require GT::Template;
my $opts = ref $_[0] eq 'HASH' ? shift : {@_};
my $user_tb = $DB->table('comm_users');
my $tags = GT::Template->tags || {};
my $disp = $DB->html($user_tb, $tags);
my $form_type = lc( $opts->{form_type} || $opts->{def}{form_type} );
exists $opts->{blank} or $opts->{blank} = $form_type eq 'select' ? 1 : 0;
my $input_html = 'radio' eq $form_type ? $disp->radio( $opts ) :
'checkbox' eq $form_type ? $disp->checkbox( $opts ) :
'select' eq $form_type ? do {
$opts->{form_size} ||= $opts->{def}{form_size};
$disp->select( $opts );
} :
'hidden' eq $form_type ? $disp->hidden( $opts ) :
'multiple' eq $form_type ? do {
$opts->{form_size} ||= $opts->{def}{form_size};
$opts->{multiple} = $opts->{form_size};
$disp->multiple( $opts )
}:
'textarea' eq $form_type ? $disp->textarea( $opts ) :
'file' eq $form_type ? "File type not supported." :
'date' eq $form_type ? do {
require GT::Date;
my ($sel_year, $sel_mon, $sel_day) = split /\-/, GT::CGI::html_escape($opts->{value});
$sel_year ||= 1970;
$sel_mon ||= 1;
$sel_day ||= 1;
my $month_sel = $disp->select({
name => "$opts->{name}-mon",
value => $sel_mon,
values => { map { sprintf("%02d", $_) => $GT::Date::LANGUAGE->{short_month_names}->[$_ - 1] } (1 .. 12) },
sort => [ map { sprintf("%02d", $_) } (1 .. 12) ],
blank => 1
});
my $day_sel = $disp->select({
name => "$opts->{name}-day",
value => $sel_day,
values => { map { sprintf("%02d", $_) => $_ } (1 .. 31) },
sort => [ map { sprintf("%02d", $_) } (1 .. 31) ],
blank => 1
});
qq~
$day_sel /
$month_sel /
~;
} :
$disp->text($opts);
return \$input_html;
}
sub ssi_select {
#--------------------------------------------------------------------
# There are three ways of calling this include.
#
# The first is simply to provide a column name to a comm_users table
# field that has an appropriately defined select display form
# configured.
#
# The second method is to provide a single parameter that is a hashref
# which contains the values as below. The main difference is that
# single parameter options (ie. multiple and blank) to be active must
# be a true value.
#
# The third method is to manually define the options that will define
# how the select option will be created by using a quasi named parameter
# setup.
#
# name : Required. name of the select box
# options : Required. If the subsequent parameter is a hashref, it will
# use the reference (treated as { option value => option display })
# to generate the option fields. Otherwise, it will assume that the
# proceeding values are "option value", then "option display" pairs
# until the parameter "/option" is encountered
# value : Optional. "\n" delimited text or arrayref of currently
# active values, if not provided it will extract from the
# current tags based upon the name of the select box. It will then
# take the values found and "select" the appropriate entries in
# the select box.
# order : Optional. If the subsequent parameter is an arrayref, it will
# become the list of option values to force order of display.
# Otherwise, it will be assumed that until the parameter "/order"
# is encountered, that the following values provided are a
# part of the list.
# multiple : Optional. convert the select list into a multi-select form.
# This is a single parameter switch. The next parameter should
# follow immediately after this option.
# form_size : Optional. size of the form to be displayed.
# extra : Optional. extra parameters to be a part of the parameters of
# the select control. This can be used to apply a style or
# declare a style class onto a rendered select control. If
# the subsequent parameter is a hashref but if not, the code
# will assume "key", "value" pairs until "/extra" is encountered.
# blank : Optional. If a true value, a blank value will be inserted as
# the first option in the dropdown. This is a single parameter
# switch. The next parameter should follow immediately after this
# option.
#
my $select_opts = {};
require GT::Template;
my $tags = GT::Template->tags || {};
if ( @_ == 1 and 'HASH' eq ref $_[0] ) {
$select_opts = shift;
}
elsif ( @_ == 1 ) {
my $col = shift;
my $user_tb = $DB->table( 'comm_users' );
my $cols = $user_tb->cols;
my $options = {};
return if ( lc $cols->{$col}->{form_type} ne 'select' );
@$options{@{$cols->{$col}{form_names}}} = @{$cols->{$col}{form_values}};
$select_opts = {
form_type => 'select',
name => $col,
def => $cols->{$col},
options => $options,
blank => 0
};
}
else {
while ( @_ ) {
$_ = lc shift;
if ( /^name$/ ) {
$select_opts->{name} = shift;
}
elsif ( /^options$/ ) {
if ( 'HASH' eq ref $_[0] ) {
$select_opts->{options} = shift;
}
elsif ( 'ARRAY' eq ref $_[0] ) {
my $order = shift;
my $options = {map {($_=>$_)} @$order};
$select_opts->{options} = $options;
}
else {
my $options = {};
while ( @_ and lc $_[0] ne '/options' ) {
my ( $k, $v ) = splice @_, 0, 2;
$options->{$k} = $v;
}
shift;
$select_opts->{options} = $options;
}
}
elsif ( /^value$/ ) {
my $value = shift;
if ( 'ARRAY' eq ref $value ) {
$value = { map {($_=>1)} @$value };
}
elsif ( not ref $value ) {
my @values = split /\n/, $value;
$value = { map {($_=>1)} @values };
}
else {}; # assume best case: hashref
$select_opts->{value} = $value;
}
elsif ( /^order$/ ) {
if ( 'ARRAY' eq ref $_[0] ) {
$select_opts->{options} = shift;
}
else {
my $order = [];
while ( @_ and lc $_[0] ne '/order' ) {
push @$order, shift;
}
shift;
$select_opts->{order} = $order;
}
}
elsif ( /^multiple$/ ) {
$select_opts->{multiple} = 1;
}
elsif ( /^form_size$/ ) {
$select_opts->{form_size} = shift;
}
elsif ( /^extra$/ ) {
if ( 'HASH' eq ref $_[0] ) {
$select_opts->{extra} = shift;
}
else {
my $extra = {};
while ( @_ and lc $_[0] ne '/extra' ) {
my ( $k, $v ) = splice @_, 0, 2;
$extra->{$k} = $v;
}
shift;
$select_opts->{extra} = $extra;
}
}
elsif ( /^blank$/ ) {
$select_opts->{blank} = 1;
}
}
}
# Make sure we have something to work with at the very least.
return unless $select_opts->{name} and $select_opts->{options};
require GT::CGI; # should already be loaded but just in case.
my $name = GT::CGI->html_escape( $select_opts->{name} );
my $mult = $select_opts->{multiple} ? "multiple " : "";
my $size = $select_opts->{form_size} ? qq{size="$select_opts->{form_size}" } : "";
my $input_html = qq{