Rev 121 | Rev 196 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
#!/usr/bin/perl# Redirect error messages to a log of my choosing. (it's annoying to filter for errors in the shared env)my $error_log_path = $ENV{SERVER_NAME} eq "volunteers.rollercon.com" ? "/home3/rollerco/logs/" : "/tmp/";close STDERR;open STDERR, '>>', $error_log_path.'vorc_error.log' or warn "Failed to open redirected logfile ($0): $!";#warn "Redirecting errors to ${error_log_path}vorc_error.log";#if ($ENV{SHELL}) { die "This script shouldn't be executed from the command line!\n"; }#use strict;use cPanelUserConfig;use CGI qw/param cookie header start_html url/;use HTML::Tiny;use tableViewer;use RollerCon;use DateTime;#use DateTime::Duration;my $now = DateTime->now (time_zone => 'America/Los_Angeles');our $h = HTML::Tiny->new( mode => 'html' );my $cookie_string;our ($EML, $PWD, $LVL);my $user;my $username;my $RCid;my $RCAUTH_cookie;my $YEAR = 1900 + (localtime)[5];$cookie_string = authenticate(1) || die;($EML, $PWD, $LVL) = split /&/, $cookie_string;$user = getUser($EML);$user->{department} = convertDepartments $user->{department};$username = $h->a ({ href=>"/schedule/view_user.pl?submit=View&RCid=$user->{RCid}" }, $user->{derby_name});$RCid = $user->{RCid};$RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");if (!$user->{MVPid} and $LVL < RollerCon::ADMIN and $user->{department}->{MVP} < RollerCon::USER and $user->{department}->{COA} < RollerCon::USER) {print header(-cookie=>$RCAUTH_cookie);printRCHeader("Unauthorized Page");print $h->div ({ class=>"error" }, "No Access");print $h->div ("Your user account is not registered to sign up for MVP Classes, so you can't see this page. It's possible that your access is still being reviewed. Please be patient.");print $h->a ({ href=>"/schedule/" }, "[Go Home]");print $h->close ("html");exit;}my $pageTitle = "MVP Classes";my $prefscookie = "allnewmvpclasses";our $DBTABLE = 'v_class';my %COLUMNS = (# colname => [qw(DisplayName N type status)], status -> static | default | <blank>name => [qw(Class 5 text static )],date => [qw(Date 10 date )],dayofweek => [qw(Day 15 select default )],start_time => [qw(StartTime 20 text )],end_time => [qw(EndTime 25 text )],time => [qw(Time 30 text default )],location => [qw(Track 35 select default )],level => [qw(Level 37 select default )],coach => [qw(Coach 40 select default )]);if ($LVL >= RollerCon::ADMIN) {$COLUMNS{id} = [qw(Admin 1 none default )];$COLUMNS{available}= [qw(SignUp 45 text )]}if ($LVL >= RollerCon::ADMIN or $user->{department}->{MVP} >= RollerCon::VOLUNTEER or $user->{department}->{COA} >= RollerCon::USER) {$COLUMNS{note} = [qw(Notes 60 text )],$COLUMNS{capacity} = [qw(Capacity 65 number default )],$COLUMNS{count} = [qw(Count 70 number default )],$COLUMNS{stars} = [qw(Stars 75 number default )],$COLUMNS{responses} = [qw(Responses 80 number default )],}if ($user->{MVPid} and $LVL < RollerCon::ADMIN) {$COLUMNS{available}= [qw(SignUp 45 text static)]}my $stylesheet = "/style.css";my $homeURL = '/schedule/';my @pagelimitoptions = ("All", 5, 10, 25);# Set any custom "where" DB filters here...my @whereClause;# If we need to modify line item values, create a subroutine named "modify_$columnname"# It will receive a hashref to the object lineitem#use WebDB;#my $dbh = WebDB::connect;my $dbh = getRCDBH;sub modify_id {my $hr = shift;my $clicky = $hr->{count} ? "event.stopPropagation(); if (confirm('WARNING!\\nYou are modifying a class that someone has signed up for.')==true) {return true;} else {return false;}" : "return true;";my $extrawarning = $hr->{count} ? "\\nWARNING! It appears someone is signed up for it." : "";return join " ", #$hr->{id},$h->a ({ href=>"view_class.pl?id=$hr->{id}&choice=Update", onClick=>$clicky }, "[Edit]"),$h->a ({ href=>"view_class.pl?id=$hr->{id}&choice=Copy" }, "[Copy]"),$h->a ({ href=>"view_class.pl?id=$hr->{id}&choice=Delete", onClick=>"event.stopPropagation(); if (confirm('Are you sure you want to DELETE this class?$extrawarning')==true) {return true;} else {return false;}" }, "[Delete]");};sub modify_available {my $t = shift;my ($yyyy, $mm, $dd) = split /\-/, $t->{date};my $cutoff = DateTime->new(year => $yyyy,month => $mm,day => $dd,hour => 5,minute => 0,second => 0,time_zone => 'America/Los_Angeles');return "CLOSED" unless $now < $cutoff;my $classkey = join '|', $t->{date}, $t->{start_time}, $t->{location};($t->{signedup}) = $dbh->selectrow_array ("select role from v_class_signup where RCid = ? and id = ?", undef, $RCid, $t->{id} );my $droplink = $h->a ({ onClick=>"if (confirm('Really? You want to drop this class?')==true) { window.open('make_shift_change.pl?change=del&RCid=$RCid&id=$t->{id}&role=$t->{signedup}','Confirm Change','resizable,height=260,width=370'); return false; }" }, "[DROP]");if (!$t->{available}) {my $full = "FULL";$full .= " | ".$droplink unless !$t->{signedup};return $full;}$t->{available} .= " Open";$t->{available} .= " | ".$droplink unless !$t->{signedup};if (findConflict ($ORCUSER->{RCid}, $t->{id}, "class")) {$t->{available} .= " | *schedule conflict*" unless $t->{signedup};} elsif (signUpEligible ($ORCUSER, $t, "class")) {# SIGN UP$t->{available} .= " | ".$h->a ({ onClick=>"event.stopPropagation(); window.open('make_shift_change.pl?change=add&RCid=$RCid&id=$classkey','Confirm Class Change','resizable,height=260,width=370'); return false;" }, "[SIGN UP]");}if ($LVL > 4 or $user->{department}->{VCI} >= 2) {# ADD USER$t->{available} ? $t->{available} .= " | " : {};$t->{available} .= $h->a ({ onClick=>"event.stopPropagation(); window.open('make_shift_change.pl?change=lookup&RCid=$RCid&id=$classkey','Confirm Class Change','resizable,height=260,width=370'); return false;" }, "[ADD USER]");}return $t->{available};}sub filter_available {my $colName = shift;my $filter = shift;if (defined $filter) {if ($filter eq "Full") {return "$colName = 0";}return "$colName > 0";} else {my $thing = "filter-${colName}";my $Options = "<OPTION></OPTION>"."<OPTION>Available</OPTION>"."<OPTION>Full</OPTION>";$Options =~ s/>($FORM{$thing})/ selected>$1/;return "<SELECT name=filter-${colName} $onChange>$Options</SELECT>";}}sub modify_time {my $t = shift;return convertTime $t->{time};}sub modify_start_time {my $t = shift;return convertTime $t->{start_time};}sub modify_end_time {my $t = shift;return convertTime $t->{end_time};}sub modify_stars {my $t = shift;if ($t->{coach} eq $user->{derby_name} or $LVL >= RollerCon::ADMIN or $user->{department}->{MVP} >= RollerCon::MANAGER) {$t->{stars} = $t->{stars};} else {$t->{stars} = ' ';}}sub modify_responses {my $t = shift;if ($t->{coachRCid} == $user->{RCid} or $LVL >= RollerCon::ADMIN or $user->{department}->{MVP} >= RollerCon::MANAGER) {$t->{responses} = $t->{responses} // '0';} else {$t->{responses} = ' ';}}# Ideally, nothing below this comment needs to change#-------------------------------------------------------------------------------our %NAME = map { $_ => $COLUMNS{$_}->[0] } keys %COLUMNS;our %colOrderHash = map { $_ => $COLUMNS{$_}->[1] } keys %COLUMNS;our %colFilterTypeHash = map { $_ => $COLUMNS{$_}->[2] } keys %COLUMNS;our @staticFields = sort byfield grep { $COLUMNS{$_}->[3] eq 'static' } keys %COLUMNS;our @defaultFields = sort byfield grep { defined $COLUMNS{$_}->[3] } keys %COLUMNS;#our @defaultFields = grep { $COLUMNS{$_}->[3] eq 'default' or inArray ($_, \@staticFields) } keys %COLUMNS;our @allFields = sort byfield keys %NAME;our @displayFields = ();our @hideFields = ();my $QUERY_STRING;my $pagelimit = param ("limit") // "All"; #$pagelimitoptions[$#pagelimitoptions];my $curpage = param ("page") // 1;our %FORM;my $FILTER;foreach (param()) {if (/^year$/) { #$YEAR = param($_);next;}$FORM{$_} = param($_); # Retrieve all of the FORM data submittedif ((/^filter/) and ($FORM{$_} ne '')) { # Build a set of filters to applymy ($filter,$field) = split /-/, $_;$FILTER->{$field} = $FORM{$_} unless notInArray ($field, \@allFields);} elsif ($FORM{$_} eq "true") { # Compile list of fields to displayif ($_ ne "shiftinclude") {push @displayFields, $_;}}}push @whereClause, "year(date) = '$YEAR'";if (exists $FORM{autoload}) { # If the FORM was submitted (i.e. the page is being redisplayed),# build the data for the cookie that remembers the page setupmy $disFields = join ":", @displayFields;my $fils = join ":", map { "$_=$FILTER->{$_}" } keys %{$FILTER};$QUERY_STRING = $disFields.'&'.$fils.'&'.$FORM{sortby}.'&'.$FORM{autoload}.'&'.$FORM{shiftinclude};}if (!(exists $FORM{autoload})) { # No FORM was submitted...if (my $prefs = cookie ($prefscookie) and !defined param ("ignoreCookie")) { # Check for cookies from previous visits.my ($disF, $filts, $sb, $al, $si) = split /&/,$prefs;@displayFields = split /:/,$disF;foreach my $pair (split /:/, $filts) {my ($key, $value) = split /=/, $pair;$FORM{"filter-$key"} = $value;$FILTER->{$key} = $value;}$FORM{sortby} = $sb;$FORM{autoload} = $al;$FORM{shiftinclude} = $si;$QUERY_STRING = $prefs;} else {@displayFields = @defaultFields; # Otherwise suppply a default list of columns.$FORM{autoload} = 1; # And turn aut0load on by default.$FORM{sortby} = "note";}}# let's just make sure the columns are in the right order (and there aren't any missing)@displayFields = grep { inArray($_, \@allFields) } sort byfield uniq @displayFields, @staticFields;# If the field isn't in the displayFields list, then add it to the hideFields list@hideFields = grep { notInArray ($_, \@displayFields) } @allFields;# Process any filters provided in the form to pass to the databasepush @whereClause, map { filter ($_, $FILTER->{$_}) } grep { defined $FILTER->{$_} } @displayFields;push @whereClause, "year(date) = '$YEAR'";#warn join " and ", @whereClause;# Given the fields to display and the where conditions,# "getData" will return a reference to an array of# hash references of the results.my ($data, $datacount) = getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit);my @ProductList = @{ $data };#my @ProductList = @{ getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit) };my $x = scalar @ProductList; # How many results were returned?# If the user is trying to download the Excel file, send it to them and then exit out.if ($FORM{excel}) {exportExcel (\@ProductList, "MVP_Class_List");exit;}my @shifts;if ($FORM{shiftinclude} eq "true") {my @SIWhere; # = ("year(date) = '$YEAR'");push @SIWhere, "RCid = $ORCUSER->{RCid}";my ($d, $c) = getData (\@displayFields, \@SIWhere, 'v_class_signup', 'date');@shifts = @{ $d };}my $signedOnAs = $username ? "Welcome, $username. ".$h->a ({ href=>"index.pl?LOGOUT" }, "[Log Out]") : "You are not signed in.";# Set some cookie stuff...my $path = `dirname $ENV{SCRIPT_NAME}`; chomp $path; $path .= '/' unless $path eq "/";my $queryCookie = cookie(-NAME=>$prefscookie,-VALUE=>"$QUERY_STRING",-PATH=>"$path",-EXPIRES=>'+365d');my $SIChecked;if ($FORM{shiftinclude}) {$SIChecked = $h->input ({ type=>"checkbox", name=>"shiftinclude", value=>"true", checked=>[], onClick=>'submit();' });} else {$SIChecked = $h->input ({ type=>"checkbox", name=>"shiftinclude", value=>"true", onClick=>'submit();' });}# Print the headerprint header(-cookie=>[$RCAUTH_cookie,$queryCookie]);# print "<!-- FORM \n\n"; # Debug code to dump the FORM to a html comment# print "I'm catching updates!!!\n\n";# foreach $key (sort (keys %FORM)) # Must be done after the header is written!# { print "\t$key: $FORM{$key}\n"; }# print "--> \n\n";### print "<!-- ENV \n\n"; # Debug code to dump the ENV to a html comment# foreach $key (sort (keys %ENV)) # Must be done after the header is written!# { print "\t$key: $ENV{$key}\n"; }# print "--> \n\n";## print "\n\n\n\n<!-- $QUERY_STRING --> \n\n\n\n";#------------------# Toggle the autoload fields within the table elementsour ($onClick, $onChange); # (also used in scanFunctions)my ($radiobutton, $refreshbutton, $sortby);if ($FORM{autoload}) {$onClick = "onClick='submit();'";$onChange = "onChange='page.value = 1; submit();'";$radiobutton = $h->div ({ class=>'autoload' },["Autoload Changes: ",$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();', checked=>[] }), "On ",$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();' }), "Off ",]);$refreshbutton = "";$sortby = $h->select ({name=>"sortby", onChange=>'submit();' }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);} else {$onClick = "";$onChange = "onChange='page.value = 1;'";$radiobutton = $h->div ({ class=>'autoload' },["Autoload Changes: ",$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();' }), "On ",$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();', checked=>[] }), "Off ",]);$refreshbutton = $h->input ({ type=>"button", value=>"Refresh", onClick=>"submit(); return false;" });$sortby = $h->select ({name=>"sortby" }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);}print start_html (-title => $pageTitle, -style => {'src' => $stylesheet} );print $h->open ('form', { action=>url, method=>'POST', name=>'Req' });print $h->input ({ type=>"hidden", name=>"excel", value=>0 });print $h->div ({ class => "accent pageheader" }, [$h->h1 ($pageTitle),$h->div ({ class=>"sp0" }, [$h->div ({ class=>"spLeft" }, [$radiobutton]),$h->div ({ class=>"spRight" }, [$h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),$refreshbutton]),]),]);# Print the Hidden fields' check boxes (if there are any)my $c = 1;my @hiddencheckboxes;my @hiddenrows;foreach my $field (sort { $NAME{$a} cmp $NAME{$b}; } @hideFields) {if ($FORM{autoload}) {push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.click();" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation(); submit();" }), $NAME{$field} ]);} else {push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.checked=!Req.$field.checked;" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation();" }), $NAME{$field} ]);}if ($c++ % 4 == 0) {push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]);@hiddencheckboxes = [];}}push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]) unless --$c % 4 == 0;my @yearoptions;foreach (@{&getYears()}) {push @yearoptions, $YEAR eq $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_);}if (scalar @hideFields) {my @topleft;push @topleft, $h->div ({ class=>"nowrap" }, "Hidden Columns:");push @topleft, $h->div ({ class=>'rTable' }, [ @hiddenrows ]);print $h->div ({ class=>"sp0" }, [$h->div ({ class=>"spLeft" }, [ @topleft ]),$h->div ({ class=>"spRight" }, [$signedOnAs, $h->br,"Show my classes: ", $SIChecked, $h->br,$h->input ({ type=>"button", value=>"Block Personal Time", onClick=>"window.location.href='personal_time.pl'" }),])]);}# Print the main table...............................................print $h->open ('div', { class=>'rTable' });my @tmptitlerow;foreach my $f (@displayFields) { # Print the Column headingsif (inArray ($f, \@staticFields)) {push @tmptitlerow, $h->div ({ class=>'rTableHead' }, [ $h->input ({ type=>"hidden", name=>$f, value=>"true" }), $NAME{$f} ]);} else {if ($FORM{autoload}) {push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.click();" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>'event.stopPropagation(); submit();' }), $NAME{$f} ]);} else {push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.checked=!Req.$f.checked;" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>"event.stopPropagation();" }), $NAME{$f} ]);}}}# Print the filter boxes...print $h->div ({ class=>'rTableHeading' }, [ @tmptitlerow ], [ map { $h->div ({ class=>'rTableCell filters' }, filter ($_)) } @displayFields ], $h->div ({ class=>"rTableCell" }));if ($FORM{shiftinclude}) { # Include all of the user's shifts at the topforeach my $t (@shifts) {print $h->div ({ class=>'rTableRow highlighted' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_} ? $t->{$_} : "") } @displayFields ]);}print $h->hr ({ width=>"500%" });}# Print the thingsforeach my $t (@ProductList) {my @display = map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields;if ($LVL >= RollerCon::ADMIN or $user->{department}->{MVP} >= RollerCon::VOLUNTEER or $user->{department}->{COA} >= RollerCon::VOLUNTEER) {print $t->{signedup} ? $h->div ({ class=>'rTableRow highlighted', onclick=>"location.href='view_class.pl?id=$t->{id}&choice=View'" }, [ @display ]): $h->div ({ class=>'rTableRow shaded', onclick=>"location.href='view_class.pl?id=$t->{id}&choice=View'" }, [ @display ]);} else {print $t->{signedup} ? $h->div ({ class=>'rTableRow highlighted' }, [ @display ]): $h->div ({ class=>'rTableRow shaded' }, [ @display ]);}}print $h->close ('div');# close things out................................................my $pages = $pagelimit eq "All" ? 1 : int( $datacount / $pagelimit + 0.99 );if ($curpage > $pages) { $curpage = $pages; }my @pagerange;if ($pages <= 5 ) {@pagerange = 1 .. $pages;} else {if ($curpage <= 3) {@pagerange = (1, 2, 3, 4, ">>");} elsif ($curpage >= $pages - 2) {@pagerange = ("<<", $pages-3, $pages-2, $pages-1, $pages);} else {@pagerange = ("<<", $curpage-1, $curpage, $curpage+1, ">>");}}my @excelcode;push @excelcode, $h->br;push @excelcode, $h->a ({ href=>"", target=>"_new", onClick=>"window.document.Req.excel.value=1; window.document.Req.submit(); window.document.Req.excel.value=0; return false;" }, "[Export Displayed Data as an Excel Document.]");print $h->br; # print $h->br;print $h->div ({ class=>"sp0" }, [$h->div ({ class=>"spLeft" }, [$h->div ({ class=>"footer" }, ["To bookmark, save, or send this exact view, use the ",$h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),$h->br,"If this page is displaying oddly, ", $h->a ({ href=>url ()."?ignoreCookie=1" }, "[Reset Your View]"),@excelcode,$h->br,"This page was displayed on ", currentTime (),$h->br,"Please direct questions, problems, and concerns to $SYSTEM_EMAIL",$h->br,"Displaying: ", $h->select ({ name=>"year", onchange=>"Req.submit();" }, [ @yearoptions ])])]),$h->div ({ class=>"spRight" }, [$h->h5 (["$x of $datacount Record". ($x == 1 ? "" : "s") ." Displayed", $h->br,"Sorted by ", $sortby, $h->br,"Displaying ", $h->select ({ name=>"limit", onChange=>"page.value = 1; submit();" }, [ map { $pagelimit == $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @pagelimitoptions ]), " Per Page", $h->br,( $pages > 1 ? ( join " ", map { $_ == $curpage ? "<B>$_</b>" :$_ eq "<<" ? $h->a ({ onClick=>qq{Req.page.value=1; Req.submit();} }, "$_") :$_ eq ">>" ? $h->a ({ onClick=>qq{Req.page.value=$pages; Req.submit();} }, "$_") :$h->a ({ onClick=>qq{Req.page.value=$_; Req.submit();} }, "[$_]") } @pagerange ) : "" ), $h->br,$h->input ({ type=>"hidden", name=>"page", value=>$curpage })])]),]);print $h->close('form');print $h->close('html');