--- trunk/webwork-modperl/lib/WeBWorK/ContentGenerator.pm 2002/11/20 19:11:55 633 +++ trunk/webwork-modperl/lib/WeBWorK/ContentGenerator.pm 2003/06/05 00:02:24 1018 @@ -16,30 +16,33 @@ use Apache::Constants qw(:common); use CGI qw(); use URI::Escape; -use WeBWorK::DB::Auth; +use WeBWorK::DB; use WeBWorK::Utils qw(readFile); -use Carp qw(cluck); +use WeBWorK::Authz; ################################################################################ # This is a very unruly file, so I'm going to use very large comments to divide # it into logical sections. ################################################################################ -# new(Apache::Request, WeBWorK::CourseEnvironment) - create a new instance of a +# new(Apache::Request, WeBWorK::CourseEnvironment) - create a new instance of a # content generator. Usually only called by the dispatcher, although one might # be able to use it for things like "sub-requests". Uh... uh... I have to think # about that one. The dispatcher uses this idiom: # -# # WeBWorK::ContentGenerator::WHATEVER->new($r, $ce)->go(@whatever); # # and throws away the result ;) # -sub new($$$) { - my $invocant = shift; +sub new($$$$) { + my ($invocant, $r, $ce, $db) = @_; my $class = ref($invocant) || $invocant; - my $self = {}; - ($self->{r}, $self->{courseEnvironment}) = @_; + my $self = { + r => $r, + ce => $ce, + db => $db, + authz => WeBWorK::Authz->new($r, $ce, $db) + }; bless $self, $class; return $self; } @@ -65,7 +68,7 @@ sub go { my $self = shift; my $r = $self->{r}; - my $courseEnvironment = $self->{courseEnvironment}; + my $courseEnvironment = $self->{ce}; $self->pre_header_initialize(@_) if $self->can("pre_header_initialize"); $self->header(@_); @@ -89,7 +92,7 @@ sub template { my ($self, $templateFile) = (shift, shift); my $r = $self->{r}; - my $courseEnvironment = $self->{courseEnvironment}; + my $courseEnvironment = $self->{ce}; my @ifstack = (1); # Start off in printing mode # say $ifstack[-1] to get the result of the last <#!--if--> @@ -115,19 +118,20 @@ print $before; } - warn '$function undefined' if !defined $function; - warn '@ifstack undefined' if !defined @ifstack; - warn '@args undefined' if !defined @args; - if ($function eq "if") { - push @ifstack, $self->$function(@_, [@args]); + # a predicate can only be true if everything else on the ifstack is already true, for ANDing + push @ifstack, ($self->$function(@_, [@args]) && $ifstack[-1]); } elsif ($function eq "else" and @ifstack > 1) { $ifstack[-1] = not $ifstack[-1]; } elsif ($function eq "endif" and @ifstack > 1) { pop @ifstack; } elsif ($ifstack[-1]) { if ($self->can($function)) { - print $self->$function(@_, {@args}); + my $result = $self->$function(@_, {@args}); + unless (defined $result) { + warn "Template escape $function returned an undefined value."; + } + print $result; } } } @@ -141,7 +145,7 @@ # cook_args(STRING) - parses a string of the form ARG1="FOO" ARG2="BAR". Returns # a list which pairs into key/values and fits nicely in {}s. # -sub cook_args($) { +sub cook_args($) { # ... also used by bin/wwdb, so watch out my ($raw_args) = @_; my @args = (); @@ -244,15 +248,28 @@ sub navMacro { my $self = shift; my %args = %{ shift() }; + my $tail = shift; my @links = @_; my $auth = $self->url_authen_args; + my $ce = $self->{ce}; + my $prefix = $ce->{webworkURLs}->{htdocs}."/images"; my @result; while (@links) { my $name = shift @links; my $url = shift @links; - push @result, $url - ? CGI::a({-href=>"$url?$auth"}, $name) + my $img = shift @links; + my $html = + ($img && $args{style} eq "images") + ? CGI::img( + {src=>($prefix."/".$img.$args{imagesuffix}), + border=>"", + alt=>"$name"}) : $name; + unless($img && !$url) { + push @result, $url + ? CGI::a({-href=>"$url?$auth$tail"}, $html) + : $html; + } } return join($args{separator}, @result), "\n"; } @@ -265,7 +282,7 @@ my $r = $self->{r}; my @fields = @_; @fields or @fields = $r->param; - my $courseEnvironment = $self->{courseEnvironment}; + my $courseEnvironment = $self->{ce}; my $html = ""; foreach my $param (@fields) { @@ -292,7 +309,7 @@ my $r = $self->{r}; my @fields = @_; @fields or @fields = $r->param; - my $courseEnvironment = $self->{courseEnvironment}; + my $courseEnvironment = $self->{ce}; my @pairs; foreach my $param (@fields) { @@ -336,6 +353,36 @@ return $return_string; } +sub errorOutput($$$) { + my ($self, $error, $details) = @_; + return + CGI::h2("Software Error"), + CGI::p(<send_http_header(); } -# drunk code. rewrite. +sub loginstatus { + my $self = shift; + my $r = $self->{r}; + my $user = $r->param("user"); + my $eUser = $r->param("effectiveUser"); + my $key = $r->param("key"); + return "" unless $key; + my $exitURL = $r->uri() . "?user=$user&key=$key"; + print CGI::small("User:", "$user"); + if ($user ne $eUser) { + print CGI::br(), CGI::font({-color=>'red'}, + CGI::small("Acting as:", "$eUser") + ), + CGI::br(), CGI::a({-href=>$exitURL}, + CGI::small("Stop Acting") + ); + } + return ""; +} + +# *** drunk code. rewrite. +# also, this should be structured s.t. subclasses can add items to the links +# area, i.e. "stacking" sub links { my $self = shift; - my $ce = $self->{courseEnvironment}; + my $ce = $self->{ce}; + my $db = $self->{db}; my $userName = $self->{r}->param("user"); my $courseName = $ce->{courseName}; my $root = $ce->{webworkURLs}->{root}; - my $permLevel = WeBWorK::DB::Auth->new($ce)->getPermissions($userName); - return "" unless defined $permLevel; - - my $probSets = "$root/$courseName/?" . $self->url_authen_args(); - my $prefs = "$root/$courseName/prefs/?" . $self->url_authen_args(); - my $prof = "$root/$courseName/prof/?" . $self->url_authen_args(); - my $profLine; - if ($permLevel > 0) { - $profLine = CGI::a({-href=>$prof}, "Professor") . CGI::br(), - } - my $help = $ce->{webworkURLs}->{docs} . "?" . $self->url_authen_args(); - my $logout = "$root/$courseName/?user=$userName"; + my $permLevel = $db->getPermissionLevel($userName)->permission(); + my $key = $db->getKey($userName)->key(); + return "" unless defined $key; + + # URLs to parts of the system + my $probSets = "$root/$courseName/?" . $self->url_authen_args(); + my $prefs = "$root/$courseName/options/?" . $self->url_authen_args(); + my $instructor = "$root/$courseName/instructor/?" . $self->url_authen_args(); + my $help = "$ce->{webworkURLs}->{docs}?" . $self->url_authen_args(); + my $logout = "$root/$courseName/logout/?" . $self->url_authen_args(); return - CGI::a({-href=>$probSets}, "Problem Sets"), CGI::br(), - CGI::a({-href=>$prefs}, "User Options"), CGI::br(), - $profLine, - CGI::a({-href=>$help}, "Help"), CGI::br(), - CGI::a({-href=>$logout}, "Log Out"), CGI::br(), + CGI::a({-href=>$probSets}, "Problem Sets"). CGI::br(). + CGI::a({-href=>$prefs}, "User Options"). CGI::br(). + ($permLevel > 0 + ? CGI::a({-href=>$instructor}, "Instructor") . CGI::br() + : ""). + CGI::a({-href=>$help}, "Help"). CGI::br(). + CGI::a({-href=>$logout}, "Log Out"). CGI::br() ; } +sub submiterror { + my ($self) = @_; + if (exists $self->{submitError}) { + return $self->{submitError}; + } else { + return ""; + } +} + # &if_can will return 1 if the current object->can("do $_[1]") sub if_can ($$) { my ($self, $arg) = (@_); @@ -404,6 +484,22 @@ } } +# Every content generator is logged in unless it says otherwise. +sub if_loggedin($$) { + my ($self, $arg) = (@_); + + return $arg; +} + +sub if_submiterror($$) { + my ($self, $arg) = @_; + if (exists $self->{submitError}) { + return $arg; + } else { + return !$arg; + } +} + 1; __END__