Subversion Repositories VORC

Rev

Rev 121 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
56 bgadell 1
#!/usr/bin/perl
2
 
3
# Redirect error messages to a log of my choosing. (it's annoying to filter for errors in the shared env)
4
my $error_log_path = $ENV{SERVER_NAME} eq "volunteers.rollercon.com" ? "/home3/rollerco/logs/" : "/tmp/";
5
close STDERR;
6
open STDERR, '>>', $error_log_path.'vorc_error.log' or warn "Failed to open redirected logfile ($0): $!";
7
#warn "Redirecting errors to ${error_log_path}vorc_error.log";
8
 
9
use strict;
10
use cPanelUserConfig;
11
use WebDB;
12
use HTML::Tiny;
13
use RollerCon;
14
use CGI qw/param header start_html url/;
15
my $h = HTML::Tiny->new( mode => 'html' );
16
 
17
my %F;
18
 
19
my $cookie_string = authenticate (1) || die;
20
our ($EML, $PWD, $LVL) = split /&/, $cookie_string;
21
my $user = getUser ($EML);
22
$user->{department} = convertDepartments $user->{department};
23
my $username = $user->{derby_name};
24
my $RCid = $user->{RCid};
25
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
26
my $YEAR = 1900 + (localtime)[5];
27
 
28
 
29
my $pageTitle = "View Game";
30
my $homeURL = "/schedule/";
31
my $DBTable = "game";
32
my %FIELDS = (
33
	id            => [qw(GameID        5     auto        static )],
34
	title         => [qw(Title         10    text         )],
35
	team1         => [qw(Team1         15    text      required )],
36
	team2         => [qw(Team2         20    text      required )],
37
	date          => [qw(Date          25    date        required )],
38
	time          => [qw(Start         30    time        required )],
39
	end_time      => [qw(End           35    time        required )],
40
	track         => [qw(Location      40    text        required )],
41
	level         => [qw(Level         45    text        required )],
42
	restrictions  => [qw(Restrictions  50    select        required )],
43
	type          => [qw(Type          55    select        required )],
44
	notes         => [qw(Notes         60    textarea       )],
45
);
46
 
47
 
48
my %fieldDisplayName = map  { $_ => $FIELDS{$_}->[0]   } keys %FIELDS;
49
my %fieldType        = map  { $_ => $FIELDS{$_}->[2]   } keys %FIELDS;
50
my @requiredFields   = sort fieldOrder grep { defined $FIELDS{$_}->[3] } keys %FIELDS;
51
my @DBFields   = sort fieldOrder grep { $fieldType{$_} =~ /^(text|select|number|switch|date|time|auto)/ } keys %FIELDS;
52
my @ROFields   = sort fieldOrder grep { $fieldType{$_} =~ /^(readonly)/ } keys %FIELDS;
53
my $primary = $DBFields[0];
54
 
55
sub fieldOrder {
56
	$FIELDS{$a}->[1] <=> $FIELDS{$b}->[1];
57
}
58
 
59
sub saveForm {
60
  error ("ERROR: Only SysAdmins can change games.") unless $LVL >= RollerCon::ADMIN;
61
 
62
  my $FTS = shift;
63
 
64
  my $dbh = WebDB::connect ();
65
#  if ($FTS->{$DBFields[0]} eq "NEW") {
66
    $dbh->do (
67
      "REPLACE INTO $DBTable (".
68
      join (", ", @DBFields)
69
      .") VALUES (". join (", ", map { '?' } @DBFields) .")",
70
    	undef,
71
    	map { $FTS->{$_} } @DBFields
72
    );
73
    if (!$FTS->{$primary}) {
74
      ($FTS->{$primary}) = $dbh->selectrow_array ("select max($primary) from $DBTable");
75
    }
76
    logit ($RCid, "$username edited a game (".join (", ", map { $FTS->{$_} } @DBFields).")");
77
 
78
	$dbh->disconnect ();	 # stored into database successfully.
79
	return $FTS->{$primary};
80
}
81
 
82
sub delete_item {
83
  error ("ERROR: Only SysAdmins can delete games.") unless $LVL >= RollerCon::ADMIN;
84
 
85
  my $X = shift;
86
  my $dbh = WebDB::connect ();
87
 
88
  $dbh->do ("delete from $DBTable where $primary = ?", undef, $X->{$primary});
89
 
90
  $dbh->disconnect ();
91
  logit ($RCid, "$username deleted Game ($X->{$primary})");
92
  print "Game Deleted: $X->{$primary}", $h->br;
93
  print &formField ("Cancel", "Back", "POSTSAVE");
94
}
95
 
96
 
97
 
98
print header (),
99
			start_html (-title => $pageTitle, -style => {'src' => "/style.css"} );
100
 
101
print $h->div ({ class => "accent pageheader" }, [
102
  $h->h1 ($pageTitle),
103
  $h->div ({ class=>"sp0" }, [
104
    $h->div ({ class=>"spLeft" }, [
105
    ]),
106
    $h->div ({ class=>"spRight" }, [
107
      $h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),
108
    ]),
109
  ]),
110
]);
111
 
112
my %GETFORM = map { split /=/ } split /&/, $ENV{QUERY_STRING};
113
my $choice = param ("choice") || $GETFORM{choice} // "";
114
if ($choice eq "Save") {
115
	process_form ();
116
} elsif (defined (param ($primary)) || $GETFORM{$primary}) {
117
  my $thing = param ($primary) || $GETFORM{$primary};
118
  if ($choice eq "Delete") {
119
    delete_item ({ $primary => $thing });
120
  } else {
121
	  display_form ({ $primary => $thing }, $choice);
122
	}
123
} else {
124
	display_form (); # blank form
125
}
126
 
127
print $h->close ("html");
128
 
129
sub display_form  {
130
  my $R = shift;
131
  my $view = shift // "";
132
	my $actionbutton;
133
 
134
  $view = "View" unless $LVL >= RollerCon::ADMIN;
135
 
136
  if ($view eq "POSTSAVE" and $R->{$primary} eq "NEW") {
137
      print &formField ("Cancel", "Back", "POSTSAVE");
138
      return;
139
  }
140
 
141
  if ($R) {
142
    # we're dealing with an existing thing.  Get the current values out of the DB...
143
    my $dbh = WebDB::connect ();
144
 
145
	  @F{@DBFields} = $dbh->selectrow_array (
146
                     "SELECT ". join (", ", @DBFields) ." FROM $DBTable WHERE $primary = ?",
147
                      undef, $R->{$primary});
148
 
149
	  $dbh->disconnect ();
150
 
151
	  # did we find a record?
152
	  error ("Cannot find a database entry for Game with id: '$R->{$primary}'") unless defined $F{$DBFields[0]};
153
 
154
    # If the DB returns a null value, HTML::Tiny doesn't like it, so make sure nulls are converted to empty strings.
155
    map { $F{$_} = "" unless $F{$_} } @DBFields;
156
 
157
    if ($view eq "Update") {
158
      # We'd like to update that thing, give the user a form...
159
      print $h->p ("Updating Game: $R->{$primary}...");
160
 
161
      foreach (@DBFields) {
162
        $F{$_} = formField ($_, $F{$_});
163
      }
164
 
165
      $actionbutton = formField ("choice", "Save");
166
      $actionbutton .= formField ("Cancel");
167
    } elsif ($view eq "Copy") {
168
      # We'd like to copy that thing, give the user a form...
169
      print $h->p ("Copying Game: $R->{$primary}...");
170
 
171
      foreach (@DBFields) {
172
        $F{$_} = formField ($_, $F{$_});
173
      }
174
#      $F{$DBFields[0]} = "COPY".$h->input ({ type=>"hidden", name=>$DBFields[0], value=> "NEW" });
175
 
176
      $actionbutton = formField ("choice", "Save");
177
      $actionbutton .= formField ("Cancel");
178
    } else {
179
      # We're just looking at it...
180
      print $h->p ("Viewing Game: $R->{$primary}...");
181
      $F{$DBFields[0]} .= $h->input ({ type=>"hidden", name=>$DBFields[0], value=> $F{$DBFields[0]} });
182
 
183
      # Put the time fields into the user's preference
184
      map { $F{$_} = convertTime $F{$_} } grep { $fieldType{$_} eq "time" } keys %FIELDS;
185
 
186
      $actionbutton = formField ("choice", "Update") unless $LVL < RollerCon::ADMIN;
187
      if ($view eq "POSTSAVE" or $choice eq "View") {
188
        $actionbutton .= formField ("Cancel", "Back", "POSTSAVE");
189
      } else {
190
        $actionbutton .= formField ("Cancel", "Back");
191
      }
192
    }
193
  } else {
194
    error ("No Game ID provided.") unless $LVL >= RollerCon::ADMIN;
195
 
196
    print $h->p ("Adding a new Game...");
197
 
198
    foreach (@DBFields) {
199
      $F{$_} = formField ($_);
200
    }
201
#		$F{$DBFields[0]} = "NEW".$h->input ({ type=>"hidden", name=>$DBFields[0], value=> "NEW" });
202
 
203
    $actionbutton = formField ("choice", "Save");
204
    $actionbutton .= formField ("Cancel");
205
  }
206
 
207
 
208
	print $h->open ("form", { action => url (), name=>"Req", method=>"POST" });
209
	print $h->div ({ class=>"sp0" },
210
	  $h->div ({ class=>"rTable" }, [ map ({
211
      $h->div ({ class=>"rTableRow" }, [
212
        $h->div ({ class=>"rTableCell right top", style=>"font-size:unset;" }, "$fieldDisplayName{$_}: "),
213
        $h->div ({ class=>"rTableCell", style=>"font-size:unset;" }, $F{$_})
214
      ])
215
       } sort fieldOrder keys %FIELDS),
216
   ])
217
  );
218
 
219
  print $actionbutton;
220
  print $h->close ("form");
221
 
170 - 222
  print $h->p ($h->input ({ type=>"button", onClick=>"window.location.href='email_users.pl?type=game&ID=$R->{$primary}';", value=>"Email Users" })) unless $LVL < RollerCon::ADMIN;
223
 
56 bgadell 224
  use DateTime;
225
  use DateTime::Duration;
226
  my $now = DateTime->now (time_zone => 'America/Los_Angeles');
227
 	my ($yyyy, $mm, $dd) = split /\-/, $F{date};
228
	my $cutoff = DateTime->new(
229
        year => $yyyy,
230
        month => $mm,
231
        day => $dd,
232
        hour => 5,
233
        minute => 0,
234
        second => 0,
235
        time_zone => 'America/Los_Angeles'
236
  );
237
 
238
 
239
  my $dbh = WebDB::connect ();
240
  if ($F{$primary} !~ /^(NEW|COPY)/) {
241
    print $h->br, $h->br;
242
    print $h->div ({ class=>"index", style=>"max-width:610px" }, [ $h->p ({ class=>"heading" }, [ "Officiating Sign-ups:" ]),
243
      $h->ul ( [ map { $h->li ({ class=>"shaded", style=>"margin:4px;" },
244
  	    $h->div ({ class=>"lisp0" }, [
245
          $h->div ({ class=>"liLeft", style=>"width:40%" }, [ $$_[0], ":&nbsp;&nbsp;" ]),
246
          $h->div ({ class=>"liRight", style=>"width:60%" },
247
            $$_[2] ? ($$_[2] == $RCid and $now < $cutoff) ? [ $h->a ({ href=>"view_user.pl?submit=View&RCid=$$_[2]" }, $$_[3]), "&nbsp;", $h->button ({ onClick=>"if (confirm('Really? Delete $$_[3] from this game?')==true) { window.open('make_shift_change.pl?change=del&RCid=$$_[2]&id=$R->{$primary}&role=$$_[1]','Confirm Shift Change','resizable,height=260,width=370'); return false; }" }, "DROP") ]
248
                                                          : ($user->{department}->{OFF} > 1 or $LVL > 4) ? [ $h->a ({ href=>"view_user.pl?submit=View&RCid=$$_[2]" }, $$_[3]), "&nbsp;", $h->button ({ onClick=>"if (confirm('Really? Delete $$_[3] from this game?')==true) { window.open('make_shift_change.pl?change=del&RCid=$$_[2]&id=$R->{$primary}&role=$$_[1]','Confirm Shift Change','resizable,height=260,width=370'); return false; }" }, "DROP"), '&nbsp;', $h->button ({ onClick=>"if (confirm('Really? $$_[3] was a no show?')==true) { window.open('make_shift_change.pl?noshow=true&change=del&RCid=$$_[2]&id=$R->{$primary}&role=$$_[1]','Confirm Shift Change','resizable,height=260,width=370'); return false; }" }, "NO SHOW") ]
249
                                                                                                         : [ "FILLED" ]
250
                   : ($user->{department}->{OFF} > 1 or $LVL > 4) ? $h->button ({ onClick=>"window.open('make_shift_change.pl?change=lookup&RCid=$$_[2]&id=$R->{$primary}&role=$$_[1]','Confirm Shift Change','resizable,height=260,width=370'); return false;" }, "ADD USER")
251
                                                                  : ($user->{department}->{OFF} > 0 and signUpEligible ($user, $R) and $now < $cutoff) ? $h->button ({ onClick=>"window.open('make_shift_change.pl?change=add&RCid=$RCid&id=$R->{$primary}&role=$$_[1]','Confirm Shift Change','resizable,height=260,width=370'); return false;" }, "SIGN UP")
252
                                                                                                                                                       : ""
253
          )
254
        ])
62 bgadell 255
      ) } @{$dbh->selectall_arrayref ("select name, role, RCid, derby_name from v_shift_officiating where id = ?", undef, $R->{$primary})} ])
56 bgadell 256
    ]);
257
#    print $h->br;
258
    print $h->div ({ class=>"index", style=>"max-width:610px" }, [ $h->p ({ class=>"heading" }, [ "Announcer Sign-ups:" ]),
259
      $h->ul ( [ map { $h->li ({ class=>"shaded", style=>"margin:4px;" },
260
  	    $h->div ({ class=>"lisp0" }, [
261
          $h->div ({ class=>"liLeft", style=>"width:50%" }, [ $$_[0], ":&nbsp;&nbsp;" ]),
262
          $h->div ({ class=>"liRight", style=>"width:50%" },
263
            $$_[2] ? ($$_[2] == $RCid and $now < $cutoff) ? [ $h->a ({ href=>"view_user.pl?submit=View&RCid=$$_[2]" }, $$_[3]), "&nbsp;", $h->button ({ onClick=>"if (confirm('Really? Delete $$_[3] from this game?')==true) { window.open('make_shift_change.pl?change=del&RCid=$$_[2]&id=$R->{$primary}&role=$$_[1]','Confirm Shift Change','resizable,height=260,width=370'); return false; }" }, "DROP") ]
264
                                                          : ($user->{department}->{ANN} > 1 or $LVL > 4) ? [ $h->a ({ href=>"view_user.pl?submit=View&RCid=$$_[2]" }, $$_[3]), "&nbsp;", $h->button ({ onClick=>"if (confirm('Really? Delete $$_[3] from this game?')==true) { window.open('make_shift_change.pl?change=del&RCid=$$_[2]&id=$R->{$primary}&role=$$_[1]','Confirm Shift Change','resizable,height=260,width=370'); return false; }" }, "DROP"), '&nbsp;', $h->button ({ onClick=>"if (confirm('Really? $$_[3] was a no show?')==true) { window.open('make_shift_change.pl?noshow=true&change=del&RCid=$$_[2]&id=$R->{$primary}&role=$$_[1]','Confirm Shift Change','resizable,height=260,width=370'); return false; }" }, "NO SHOW") ]
265
                                                                                                         : [ "FILLED" ]
266
                   : ($user->{department}->{ANN} > 1 or $LVL > 4) ? $h->button ({ onClick=>"window.open('make_shift_change.pl?change=lookup&RCid=$$_[2]&id=$R->{$primary}&role=$$_[1]','Confirm Shift Change','resizable,height=260,width=370'); return false;" }, "ADD USER")
267
                                                                  : ($user->{department}->{ANN} > 0 and signUpEligible ($user, $R) and $now < $cutoff) ? $h->button ({ onClick=>"window.open('make_shift_change.pl?change=add&RCid=$RCid&id=$R->{$primary}&role=$$_[1]','Confirm Shift Change','resizable,height=260,width=370'); return false;" }, "SIGN UP")
268
                                                                                                                                                        : ""
269
          )
270
        ])
62 bgadell 271
      ) } @{$dbh->selectall_arrayref ("select name, role, RCid, derby_name from v_shift_announcer where id = ?", undef, $R->{$primary})} ])
56 bgadell 272
    ]);
273
  }
274
  $dbh->disconnect;
275
 
276
 
277
}
278
 
279
sub process_form  {
280
  error ("ERROR: Only SysAdmins can change games.") unless $LVL >= RollerCon::ADMIN;
281
 
282
  my %FORM;
283
  foreach (keys %FIELDS) {
284
  	if ($fieldType{$_} =~ /^text/ and $_ ne "title") {
285
  		$FORM{$_} = WebDB::trim param ($_) // "";
286
  	} else {
287
	  	$FORM{$_} = param ($_) // "";
288
  	}
289
  }
290
  $FORM{autoapprove} = 0 unless $FORM{autoapprove};
291
 
292
  	 # check for required fields
293
	my @errors = ();
294
	foreach (@requiredFields) {
295
		push @errors, "$fieldDisplayName{$_} is missing." if $FORM{$_} eq "" and $FIELDS{$_}->[3] ne "static";
296
	}
297
 
298
  if (@errors)	 {
299
    print $h->div ({ class=>"error" }, [
300
  	  $h->p ("The following errors occurred:"),
301
  	  $h->ul ($h->li (@errors)),
302
  	  $h->p ("Please click your Browser's Back button to\n"
303
  	  	   . "return to the previous page and correct the problem.")
304
  	]);
305
  	return;
306
  }	 # Form was okay.
307
 
308
  $FORM{$primary} = saveForm (\%FORM);
309
 
310
	print $h->p ({ class=>"success" }, "Game successfully saved.");
311
 
312
  display_form ({ $primary=>$FORM{$primary} }, "POSTSAVE");
313
}
314
 
315
sub error {
316
	my $msg = shift;
317
	print $h->p ({ class=>"error" }, "Error: $msg");
318
  print $h->close("html");
319
	exit (0);
320
}
321
 
322
sub formField {
323
	my $name  = shift;
324
	my $value = shift // '';
325
	my $context = shift // '';
326
	my $type = $fieldType{$name} // "button";
327
 
328
  if ($type eq "button") {
329
		if ($name eq "Cancel") {
330
		  if ($context eq "POSTSAVE") {
331
		    return $h->input ({ type=>"button", value => $value ne '' ? $value : "Cancel" , onClick=>"window.location.href = \"games.pl\"; return false;" });
332
		  } else {
333
		    return $h->input ({ type=>"button", value => $value ne '' ? $value : "Cancel" , onClick=>"history.back(); return false;" });
334
		  }
335
		} else {
336
			return $h->input ({ type=>"submit", value => $value, name=>$name })
337
		}
338
 
339
	} elsif ($type eq "textarea") {
340
	  return $h->tag ("textarea", {
341
	    name => $name,
342
	    override => 1,
343
			cols => 30,
344
			rows => 4
345
	  }, $value);
346
 
347
  } elsif ($type eq "select") {
348
    no strict;
349
    return &{"select_".$name} ($value);
350
	}	elsif ($type eq "auto") {
351
	  return $value.$h->input ({ type=>"hidden", name=>$name, value=>$value });
352
  }	elsif ($type eq "time") {
353
	  return $h->input ({
354
	    name => $name,
355
	    type => $type,
356
	    value => $value,
357
	    step => 900,
358
	    required => [],
359
	    override => 1,
360
	    size => 30
361
	  });
362
  }	elsif ($type eq "number") {
363
    return $h->input ({ name=>$name, type=>"number", value=>$value, step=>1 });
364
  }	elsif ($type eq "switch") {
365
    if ($value) {
366
      return $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>$name, value=>1, checked=>[] }), $h->span ({ class=>"slider round" })]);
367
    } else {
368
      return $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>$name, value=>1 }), $h->span ({ class=>"slider round" })]);
369
    }
370
	}	else {
371
	  use tableViewer;
372
	  if (inArray ($name, \@requiredFields)) {
373
  	  return $h->input ({
374
  	    name => $name,
375
  	    type => $type,
376
  	    value => $value,
377
  	    required => [],
378
  	    override => 1,
379
  	    size => 30
380
  	  });
381
	  } else {
382
  	  return $h->input ({
383
  	    name => $name,
384
  	    type => $type,
385
  	    value => $value,
386
  	    override => 1,
387
  	    size => 30
388
  	  });
389
  	}
390
	}
391
}
392
 
393
sub select_restrictions {
394
  my $selection = shift // "";
395
  my @options = ("");
396
 
397
  my $sub_name = (caller(0))[3];
398
  $sub_name =~ s/^main::select_//;
399
 
400
  my $dbh = WebDB::connect ();
62 bgadell 401
 	push @options, map { @{$_} } @{$dbh->selectall_arrayref ("select distinct restrictions from game where restrictions <> '' order by restrictions")};
56 bgadell 402
 	$dbh->disconnect ();
403
 
404
  return $h->select ({ name=>$sub_name }, [ map { $_ eq $selection ? $h->option ({selected=>[]}, $_) : $h->option ($_) } @options ]);
405
}
406
 
407
sub select_type {
408
  my $selection = shift // "";
409
  my @options = ("");
410
 
411
  my $sub_name = (caller(0))[3];
412
  $sub_name =~ s/^main::select_//;
413
 
414
  my $dbh = WebDB::connect ();
73 bgadell 415
 	push @options, map { @{$_} } @{$dbh->selectall_arrayref ("select distinct type from staff_template order by type")};
56 bgadell 416
 	$dbh->disconnect ();
417
 
418
  return $h->select ({ name=>$sub_name }, [ map { $_ eq $selection ? $h->option ({selected=>[]}, $_) : $h->option ($_) } @options ]);
419
}