#!/usr/bin/perl
# This script is licensed under the FDL (Free Documentation License)
# The complete license text can be found at http://www.gnu.org/copyleft/fdl.html
use strict;
use SAL::WebApplication;
my $app = new SAL::WebApplication;
my $q = $app->{cgi};
my $self_url = $app->{cgi}->script_name();
my $user_id = $app->{cgi}->remote_user();
my $user_name = lookup_name($user_id);
my $survey_question = '';
my $survey_server = 'localhost';
my $survey_user = '';
my $survey_pass = '';
my $survey_db = 'Survey';
my $canvas;
# Register our application's modes
if (! $app->register_default(\&start)) { $app->throw_error("Could not register default mode 'start'\n"); }
if (! $app->register_mode('cast', \&cast)) { $app->throw_error("Could not register mode 'cast'\n"); }
if (! $app->register_mode('help', \&help)) { $app->throw_error("Could not register mode 'help'\n"); }
if (! $app->register_toolbar(\&build_toolbar)) { $app->throw_error("Could not register toolbar\n"); }
if (! $app->register_html_header(\&build_html_header)) { $app->throw_error("Could not register html header\n"); }
# Setup any databases
my $dbo_data = $app->{dbo_factory}->spawn_mysql($survey_server, $survey_user, $survey_pass, $survey_db);
my $dbo_results = $app->{dbo_factory}->spawn_mysql($survey_server, $survey_user, $survey_pass, $survey_db);
# Run the application
$app->run();
#===========
# Callbacks
#===========
###############################################################
sub start {
my $sid = $q->param('sid') || '0';
my $is_ok_to_vote = 0;
my ($w, $h, $rh, $rw);
# Get the Question...
($w, $h) = $dbo_data->execute(qq[SELECT Question FROM SurveyQuestions WHERE SID=?], $sid);
$survey_question = $dbo_data->{data}->[0][0];
# Find out if this user's already voted...
($w, $h) = $dbo_data->execute(qq[SELECT * FROM SurveyData WHERE SID=? AND Name=?], $sid, $user_id);
if ($h < 1) { $is_ok_to_vote = 1; }
# Get the Survey Choices...
($w, $h) = $dbo_data->execute(qq[SELECT * FROM SurveyChoices WHERE SID=? ORDER BY ChoiceNum], $sid);
# Calculate results
($rw, $rh) = $dbo_results->execute(qq[SELECT sum(if(SurveyData.Choice='0', 1, 0)) as a, sum(if(SurveyData.Choice='1', 1, 0)) as b, sum(if(SurveyData.Choice='2', 1, 0)) as c FROM SurveyData WHERE SID=?], $sid);
my $total_votes = $dbo_results->{data}->[0][0] + $dbo_results->{data}->[0][1] + $dbo_results->{data}->[0][2];
my @pctgs;
if ($dbo_results->{data}->[0][0] > 0) { $pctgs[0] = ($dbo_results->{data}->[0][0] / $total_votes) * 100; }
if ($dbo_results->{data}->[0][1] > 0) { $pctgs[1] = ($dbo_results->{data}->[0][1] / $total_votes) * 100; }
if ($dbo_results->{data}->[0][2] > 0) { $pctgs[2] = ($dbo_results->{data}->[0][2] / $total_votes) * 100; }
$pctgs[0] = sprintf("%.2f", $pctgs[0]);
$pctgs[1] = sprintf("%.2f", $pctgs[1]);
$pctgs[2] = sprintf("%.2f", $pctgs[2]);
my $canvas = qq[
Survey Question:
$survey_question
];
if ($is_ok_to_vote) {
$canvas .= qq[];
} else {
######### User has already cast a vote, so display a message instead of displaying the form.
$canvas .= qq[
You have already voted in this survey.
];
}
######### Display Results
$canvas .= qq[
Survey Results ($total_votes Total Votes)
];
for (my $y = 0; $y < $h; $y++) {
my $progress_width= $pctgs[$y] * 2;
my $style;
if ($y == 0) {
$style = "border-top: 1px solid #000; border-bottom: 1px solid #000; border-left: 1px solid #000; background-color: #ddd;";
} else {
$style = "border-bottom: 1px solid #000; border-left: 1px solid #000; background-color: #ddd;";
}
$canvas .= qq[| $dbo_data->{data}->[$y][1] | $pctgs[$y]% |  |
];
}
$canvas .= qq[
];
$app->write($canvas);
$app->paint("User Feedback Survey");
}
###############################################################
sub cast {
my $sid = $q->param('sid') || '0';
my $choice = $q->param('choice');
$dbo_data->do(qq[INSERT INTO SurveyData (SID, Name, Choice) VALUES('$sid', '$user_id', '$choice')]);
my $canvas = qq[
Your vote has been cast!
Back to start
];
$app->write($canvas);
$app->paint("User Feedback Survey");
}
###############################################################
sub help {
my $pod_file = "/var/www$self_url";
# define some html tags we want to substitute in
my $hr_html = '';
my $titlebg_html = '';
my $section_title_html = '';
my $index_section_html = '';
# get the html version of the pod
my $pod_contents = `pod2html --infile=$pod_file --index`;
# make it nicer
# remove extraneous simple tags
my @bad_tags = qw( );
foreach my $tag (@bad_tags) {
$pod_contents =~ s/$tag//ig;
}
# remove the title tags seperately, so we can take out the text between them
$pod_contents =~ s/.*<\/title>//ig;
# remove the link tag seperately so we can remove the text inside it
$pod_contents =~ s///ig;
# substitute our settings in
$pod_contents =~ s//$hr_html/ig;
$pod_contents =~ s//$titlebg_html/ig;
$pod_contents =~ s//$section_title_html/ig;
# remove any multi-newlines
$pod_contents =~ s/\n+/\n/g;
$app->write($index_section_html . "Index
" . $pod_contents);
$app->paint("Help Files...");
}
###############################################################
sub build_toolbar {
my $mode = $app->{cgi}->param('mode');
my $toolbar;
if ($mode ne 'help') {
$toolbar = qq[
];
} else {
$toolbar .= qq[
];
}
return $toolbar
}
###############################################################
sub build_html_header {
my $html_header = qq[
];
return $html_header
}
###############################################################
#===============
# Support Funcs
#===============
sub lookup_name {
my $id = shift;
my @record = split(/:/, `getent passwd | grep ^$id`);
return $record[4];
}
sub sql_build_value_list {
my @items = @_;
my @clean = sql_clean(@items);
my $value_list;
foreach my $item (@clean) {
$value_list .= qq['$item', ];
}
$value_list =~ s/,\s$//;
return $value_list;
}
sub sql_clean {
my @items = @_;
my @clean;
foreach my $item (@items) {
$item =~ s/'//g;
$item =~ s/"//g;
$item =~ s/;//g;
push (@clean, $item);
}
return @clean;
}
sub get_datetime {
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime();
$mon++;
$year += 1900;
my $datetime = qq[$year-$mon-$mday $hour:$min:$sec];
return $datetime;
}
=pod
=head1 SAL Surveys
=head2 Requirements
=item Apache
- Basic Auth authentication (mod_auth_mysql, mod_auth_external, etc)
=item SAL
=item MySQL Database "Surveys"
Tables:
- SurveyQuestions (SID int(11), Question varchar(255))
- SurveyChoices (SID int(11), Choice varchar(255), ChoiceNum int(11))
- SurveyData (SID int(11), Name varchar(16), Choice int(11))
=item Images
- progress.png (a 1px wide image for the progress bar)
- unknown.gif for toolbar-link to help (image can be found in apache icon directory)
- list.gif for toolbar-link to back to the survey from help (or alternate from apache icon directory)
=cut