# ================================================================== # Gossamer List - enhanced mailing list management system # # Website : http://gossamer-threads.com/ # Support : http://gossamer-threads.com/scripts/support/ # CVS Info : # Revision : $Id: Tools.pm,v 1.37 2004/10/06 17:58:17 bao 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 GList::Tools; use strict; use GList qw/:objects $LANGUAGE $GLOBALS/; use constants KB => 1024, MB => 1024 * 1024; sub generate_used_bar { #------------------------------------------------------------------- # my ($type, $max_width) = @_; my ($percent, $img_width, $msg) = (0, 0, ''); if ($type eq 'email30') { require GT::Date; require GT::SQL::Condition; my $last30 = GT::Date::date_sub(GT::Date::date_get(), 30); my $unix_time = GList::date_to_time($last30); my $num_sent = $DB->table('MailingIndex', 'EmailMailings')->count( GT::SQL::Condition->new( mli_user_id_fk => '=' => $USER->{usr_username}, eml_sent => '>=' => $unix_time ) ); if ($num_sent >= $USER->{usr_limit_email30}) { $percent = 100; $img_width = $max_width; } else { $percent = int(100 * $num_sent / $USER->{usr_limit_email30}); $img_width = int($num_sent * $max_width / $USER->{usr_limit_email30}); } $msg = GList::language('SYS_USEDBAR_EMAIL30', $percent, $USER->{usr_limit_email30}); } elsif ($type eq 'sublist') { my $num_lists = $DB->table('Lists')->count({ lst_user_id_fk => $USER->{usr_username} }); my $num_subs = $DB->table('Subscribers')->count({ sub_user_id_fk => $USER->{usr_username} }); my $sub_limit = ($num_lists) ? $num_lists * $USER->{usr_limit_sublist} : $USER->{usr_limit_sublist}; if ($num_subs >= $sub_limit) { $percent = 100; $img_width = $max_width; } else { $percent = int(100 * $num_subs / $sub_limit); $img_width = int($num_subs * $max_width / $sub_limit); } $msg = GList::language('SYS_USEDBAR_SUBLIST', $percent, $sub_limit); } return { used_message => $msg, used_percent => $percent, used_image_width => $img_width }; } sub generate_list { # ------------------------------------------------------------------ # Generates a list of lists # my $object = shift; my $tags = GT::Template->tags; my $lists = $DB->table('Lists'); $lists->select_options('ORDER BY lst_Title'); my $sth = $lists->select({ lst_user_id_fk => $tags->{usr_username} }) or die $GT::SQL::error; my $html = ""; my $current = $tags->{$object}; while ( my $rs = $sth->fetchrow_hashref ) { if (ref $current eq 'ARRAY') { my $id = 0; foreach (@$current) { if ($_ == $rs->{lst_id}) { $id = $_;last; } } $html .= ( $id == $rs->{lst_id} ) ? "" : ""; } else { $html .= ( $current == $rs->{lst_id} ) ? "" : ""; } } return $html; } sub default_email_editor { #------------------------------------------------------------------ # Load the default email templates editor # my $tags = GT::Template->tags; my $cgi = $IN->get_hash(); my $selected_dir = $cgi->{tpl_dir} || $CFG->{template_set} || 'gossamer'; my $demo; #------------demo code----------- # Build the select lists. my $d_select_list = _template_dir_select(); my ($f_select_list, $selected_file) = _default_select("$CFG->{priv_path}/templates/$selected_dir", $cgi->{tpl_file}); return { select_list => $f_select_list, tpl_dir => "$CFG->{priv_path}/templates/", selected_dir => $selected_dir, dir_select => $d_select_list, demo => $demo, tpl_file => $selected_file, bload => ($selected_file) ? 1 : 0 }; } sub email_editor { #------------------------------------------------------------------ # Load the email template editor # my $tags = GT::Template->tags; my $cgi = $IN->get_hash(); my $tpl = {}; my $db = $DB->table('EmailTemplates'); my $cols = $db->cols; my ($msg, $error, $demo); #------------demo code----------- # Save the email template my $save_as = $cgi->{save_as}; if ( $cgi->{bsave} and $save_as ) { if ( $demo ) { $msg = 'Edit email template has been disabled in the demo!'; } else { my @required = ('tpl_to', 'tpl_from', 'tpl_subject', 'tpl_body'); my $hsh = {}; foreach ( @required ) { $hsh->{$_} = $cgi->{$_} if ( defined $cgi->{$_} ); } $hsh->{tpl_user_id_fk} = $tags->{usr_username}; $hsh->{tpl_name} = $save_as; if ( $cgi->{tpl_extra} ) { for ( split /\s*\n\s*/, $cgi->{tpl_extra} ) { # This will weed out any blank lines my ($key, $value) = split /\s*:\s*/, $_, 2; $hsh->{tpl_extra} .= "$key: $value\n" if $key and $value; } } else { $hsh->{tpl_extra} = ''; } foreach ( @required ) { if ( !$hsh->{$_} ) { $msg = GList::language('TPL_INVALID'); $error = 1; last; } } if ( !$msg ) { if ( $save_as eq $cgi->{tpl_name} ) { # Update an exist template $db->update($hsh, { tpl_user_id_fk => $tags->{usr_username}, tpl_name => $save_as }); $msg = ( $GT::SQL::error ) ? "$GT::SQL::error" : GList::language('TPL_UPDATED', $save_as); } else { # Add a new template $db->insert($hsh); $msg = ( $GT::SQL::error ) ? "$GT::SQL::error" : GList::language('TPL_ADDED', $save_as); $cgi->{tpl_name} = $save_as if ( !$GT::SQL::error ); } } } } elsif ( $cgi->{txtdelete} ) { # Delete an existing template if ( $demo ) { $msg = 'Edit email template has been disabled in the demo !'; } else { require GT::SQL::Condition; my $cond = GT::SQL::Condition->new('lst_user_id_fk', '=', $tags->{usr_username}); $cond->add(GT::SQL::Condition->new('lst_opt_template', '=', $cgi->{tpl_name}, 'lst_subs_template', '=', $cgi->{tpl_name}, 'lst_unsubs_template', '=', $cgi->{tpl_name}, 'OR')); my $sth = $DB->table('Lists')->select($cond); if ( $sth->rows ) { $msg = GList::language('TPL_DELETE_ERROR', $cgi->{tpl_name}); } else { $db->delete({ tpl_user_id_fk => $tags->{usr_username}, tpl_name => $cgi->{tpl_name} }); $msg = ( $GT::SQL::error ) ? "$GT::SQL::error" : GList::language('TPL_DELETED', $cgi->{tpl_name}); } } } elsif ( $cgi->{bdefault} ) { # Load default templates GList::set_default_template('validation.eml', $tags->{usr_username}); GList::set_default_template('subscribe.eml', $tags->{usr_username}); GList::set_default_template('unsubscribe.eml', $tags->{usr_username}); $msg = ( $GT::SQL::error ) ? "$GT::SQL::error" : GList::language('TPL_LOADED'); } # Build the select lists. my $f_current_list = _current_select('tpl_name', $cgi->{tpl_name}); if ( $cgi->{tpl_name} and !$GT::SQL::error and !$error ) { $tpl = $db->get({ tpl_user_id_fk => $tags->{usr_username}, tpl_name => $cgi->{tpl_name} }); if ( !$tpl ) { foreach (keys %$cols) { $tpl->{$_} = ''; } } } return { current_list => $f_current_list, msg => $msg, %$tpl }; } sub template_editor { # ------------------------------------------------------------------ # Loads the template editor. # _editor_obj()->process; } sub language_editor { # ------------------------------------------------------------------ # Loads the language file editor. # my $tags = GT::Template->tags; my ($font, $message, $table); my $cgi = $IN->get_hash; my $selected_dir = $cgi->{tpl_dir} || $CFG->{template_set} || 'gossamer'; $font = 'face="Tahoma,Arial,Helvetica" size="2"'; my $demo; #------------demo code----------- GList::load_language($selected_dir); if ($cgi->{save}) { if ($demo) { $message = 'The language editor has been disabled in the demo!'; } else { my $need_save; foreach my $code (keys %$cgi) { if ($code =~ /^del-(.*)$/) { delete $LANGUAGE->{$1}; ++$need_save; } elsif ($code =~ /^save-(.*)/) { my $key = $1; next if $cgi->{"del-$key"}; my $var = $cgi->{$code}; $var =~ s/\r\n/\n/g; # Remove windows linefeeds. next if exists $LANGUAGE->{$key} and $LANGUAGE->{$key} eq $var; $LANGUAGE->{$key} = $var; ++$need_save; } } if (my $key = $cgi->{new} and my $var = $cgi->{'new-val'}) { $var =~ s/\r\n/\n/g; if ($key =~ /^([^_]*)_/) { $LANGUAGE->{$key} = $var; ++$need_save; } else { $message = GList::language('TPL_LANG_INVALID'); } } elsif ($cgi->{'new-val'}) { $message = GList::language('TPL_LANG_ERROR'); } if ($need_save) { $LANGUAGE->save(); $LANGUAGE = undef; # Force a reload to catch inherited values $message = GList::language('TPL_LANG_SAVED'); $tags->{'new-val'} = ''; } } } my $prefix = $cgi->{'prefix'}; my %prefix_list; foreach my $code (sort keys %$LANGUAGE) { if ($code =~ /^([^_]*)_/) { $prefix_list{$1}++; } next if $prefix and $code !~ /^$prefix\_/; my $lang = $IN->html_escape($LANGUAGE->{$code}); $table .= < $code HTML } my $prefix_output = join " | ", map qq'$_ ($prefix_list{$_})', sort keys %prefix_list; my $d_select_list = _template_dir_select(); return { language_table => $table, prefix => $prefix, dir_select => $d_select_list, message => $message, prefix_list => $prefix_output }; } sub global_editor { # ------------------------------------------------------------------ # Loads the global template vars. # my $tags = GT::Template->tags; my ($dir, $font, $file, $message, $table); my $cgi = $IN->get_hash(); my $selected_dir = $cgi->{tpl_dir} || $CFG->{template_set} || 'gossamer'; $dir = $CFG->{priv_path} . "/templates/common"; GList::load_globals(1); my $demo; #------------demo code----------- if ($cgi->{save}) { if ($demo) { $message = 'The global editor has been disabled in the demo!'; } else { my $need_save; foreach my $code (keys %$cgi) { if ($code =~ /^del-(.*)$/) { delete $GLOBALS->{$1}; ++$need_save; } elsif ($code =~ /^save-(.*)/) { my $key = $1; next if $cgi->{"del-$key"}; my $var = $cgi->{$code}; $var =~ s/\r\n/\n/g; # Remove windows linefeeds. next if exists $GLOBALS->{$key} and $GLOBALS->{$key} eq $var; $GLOBALS->{$key} = $var; ++$need_save; } } if (my $key = $cgi->{new} and my $var = $cgi->{'new-val'}) { $var =~ s/\r\n/\n/g; $GLOBALS->{$key} = $var; ++$need_save; } elsif ($cgi->{'new-val'}) { $message = GList::language('TPL_GLOBAL_ERROR'); } if ($need_save) { $GLOBALS->save(); $GLOBALS = undef; # Force a reload, to catch inherited/local values GList::load_globals(1); $message = GList::language('TPL_GLOBAL_SAVED'); $tags->{'new-val'} = ''; } } } for my $code (sort keys %$GLOBALS) { my $val = $IN->html_escape($GLOBALS->{$code}); $table .= < $code HTML } return { global_table => $table, message => $message }; } sub convert_date { #---------------------------------------------------------------------- my $time = shift or return GList::language('ADMNEVER_LOGIN'); my $format = "%mm%-%dd%-%yyyy% %hh%:%MM%:%ss%"; require GT::Date; return GT::Date::date_get($time, $format); } sub friendly_size { my $size = shift; return $size <= 100 ? "$size " . GList::language('FILESIZE_BYTES') : $size < 10 * KB ? sprintf("%.2f ", $size / KB) . GList::language('FILESIZE_KILOBYTES') : $size < 100 * KB ? sprintf("%.1f ", $size / KB) . GList::language('FILESIZE_KILOBYTES') : $size < MB ? sprintf("%.0f ", $size / KB) . GList::language('FILESIZE_KILOBYTES') : $size < 10 * MB ? sprintf("%.2f ", $size / MB) . GList::language('FILESIZE_MEGABYTES') : $size < 100 * MB ? sprintf("%.1f ", $size / MB) . GList::language('FILESIZE_MEGABYTES') : sprintf("%.0f ", $size / MB) . GList::language('FILESIZE_MEGABYTES'); } sub list_title { my $list_id = shift; return if (!$list_id); my $info = $DB->table('Lists')->get($list_id); return $info->{lst_title}; } sub _editor_obj { my ($name, $skip) = @_; $skip ||= [qw/CVS safe help/]; require GT::Template::Editor; my $demo = 0; #------------demo code----------- GT::Template::Editor->new( root => "$CFG->{priv_path}/templates", backup => $CFG->{template_backups}, cgi => $IN, demo => $demo, class => "object", default_dir => $CFG->{template_set} || 'gossamer', skip_dir => $skip, skip_file => [qw/*.eml/], $name ? (select_dir => $name) : () ); } sub _template_dir_select { # ------------------------------------------------------------------ # Returns a select list of template directories. # my $name = shift; _editor_obj($name, [qw/CVS help safe common/])->template_dir_select; } sub _current_select { # ------------------------------------------------------------------ # Returns a select list of user email templates # my ($name, $selected_file) = @_; my $tags = GT::Template->tags; my $sth = $DB->table('EmailTemplates')->select({ tpl_user_id_fk => $tags->{usr_username} }, ['tpl_name']); return if ( !$sth->rows ); $selected_file ||= $tags->{$name}; my $f_select_list = ""; } sub _default_select { # ------------------------------------------------------------------ # Returns a select list of email templates in a given dir. # my ( $dir, $selected_file ) = @_; my ($file, @files); opendir (TPL, $dir) or die GList::language('DIR_OPEN_ERR', $dir, $!); while (defined($file = readdir TPL)) { my ($ext) = $file =~ /\.([^.]+)$/; next unless $ext and $ext eq 'eml'; push @files, $file; } closedir TPL; my $f_select_list = ""; return ($f_select_list, $selected_file); } sub schedule_status { my $tags = GT::Template->tags; my ($scm_id, $scm_sent, $scm_type) = ($tags->{scm_id}, $tags->{scm_sent}, $tags->{scm_type}); my $schedule = $DB->table('ScheduledMailings')->get({ scm_id => $scm_id }); return unless $schedule; return unless $scm_sent; require GT::Date; if ($scm_type == 2) { return 1 if GT::Date::date_get(time, "%yyyy%-%mm%-%dd%") eq GT::Date::date_get($scm_sent, "%yyyy%-%mm%-%dd%"); } elsif ($scm_type == 3) { my $today = GT::Date::date_get(time, "%yyyy%-%mm%-%dd%"); my $next_7days = GT::Date::date_add(GT::Date::date_get($scm_sent, "%yyyy%-%mm%-%dd%"), 7); return GT::Date::date_is_greater($next_7days, $today); } elsif ($scm_type == 4) { return 1 if GT::Date::date_get(time, "%mm%") eq GT::Date::date_get($scm_sent, "%mm%"); } return; } sub schedule_info { my $mli_id = shift; return unless $mli_id; my $info = $DB->table('ScheduledMailings')->get({ scm_mailing_id_fk => $mli_id }); if ($info->{scm_type} == 1) { require GT::Date; my $format = $USER->{usr_date_format} || '%yyyy%-%mm%-%dd%'; $info->{scm_option} = GT::Date::date_get($info->{scm_option}, $format); } return $info; } 1;