| … | |
… | |
| 23 | ################################################################################ |
23 | ################################################################################ |
| 24 | # This is a very unruly file, so I'm going to use very large comments to divide |
24 | # This is a very unruly file, so I'm going to use very large comments to divide |
| 25 | # it into logical sections. |
25 | # it into logical sections. |
| 26 | ################################################################################ |
26 | ################################################################################ |
| 27 | |
27 | |
| 28 | # new(Apache::Request, WeBWorK::CourseEnvironment) - create a new instance of a |
28 | # new(Apache::Request, WeBWorK::CourseEnvironment, WeBWorK::DB) - create a new |
| 29 | # content generator. Usually only called by the dispatcher, although one might |
29 | # instance of a content generator. Usually only called by the dispatcher, although |
| 30 | # be able to use it for things like "sub-requests". Uh... uh... I have to think |
30 | # one might be able to use it for things like "sub-requests". Uh... uh... I have |
| 31 | # about that one. The dispatcher uses this idiom: |
31 | # to think about that one. The dispatcher uses this idiom: |
| 32 | # |
32 | # |
| 33 | # WeBWorK::ContentGenerator::WHATEVER->new($r, $ce)->go(@whatever); |
33 | # WeBWorK::ContentGenerator::WHATEVER->new($r, $ce, $db)->go(@whatever); |
| 34 | # |
34 | # |
| 35 | # and throws away the result ;) |
35 | # and throws away the result ;) |
| 36 | # |
36 | # |
| 37 | sub new($$$$) { |
37 | sub new { |
| 38 | my ($invocant, $r, $ce, $db) = @_; |
38 | my ($invocant, $r, $ce, $db) = @_; |
| 39 | my $class = ref($invocant) || $invocant; |
39 | my $class = ref($invocant) || $invocant; |
| 40 | my $self = { |
40 | my $self = { |
| 41 | r => $r, |
41 | r => $r, |
| 42 | ce => $ce, |
42 | ce => $ce, |
| 43 | db => $db, |
43 | db => $db, |
| 44 | authz => WeBWorK::Authz->new($r, $ce, $db), |
44 | authz => WeBWorK::Authz->new($r, $ce, $db), |
| 45 | noContent => undef, # false |
45 | noContent => undef, |
| 46 | }; |
46 | }; |
| 47 | bless $self, $class; |
47 | bless $self, $class; |
| 48 | return $self; |
48 | return $self; |
| 49 | } |
49 | } |
| 50 | |
50 | |
| … | |
… | |
| 84 | $self->pre_header_initialize(@_) if $self->can("pre_header_initialize"); |
84 | $self->pre_header_initialize(@_) if $self->can("pre_header_initialize"); |
| 85 | my $headerReturn = $self->header(@_); |
85 | my $headerReturn = $self->header(@_); |
| 86 | $returnValue = $headerReturn if defined $headerReturn; |
86 | $returnValue = $headerReturn if defined $headerReturn; |
| 87 | return $returnValue if $r->header_only or $self->{noContent}; |
87 | return $returnValue if $r->header_only or $self->{noContent}; |
| 88 | |
88 | |
|
|
89 | # if the sendFile flag is set, send the file and exit; |
|
|
90 | if ($self->{sendFile}) { |
|
|
91 | return $self->sendFile; |
|
|
92 | } |
|
|
93 | |
| 89 | $self->initialize(@_) if $self->can("initialize"); |
94 | $self->initialize(@_) if $self->can("initialize"); |
| 90 | |
95 | |
| 91 | # A content generator will have a "content" method if it does not |
96 | # A content generator will have a "content" method if it does not |
| 92 | # wish to be passed through template processing, but wishes to be |
97 | # wish to be passed through template processing, but wishes to be |
| 93 | # completely responsible for it's own output. |
98 | # completely responsible for it's own output. |
| … | |
… | |
| 105 | $templateName = "system" unless exists $ce->{templates}->{$templateName}; |
110 | $templateName = "system" unless exists $ce->{templates}->{$templateName}; |
| 106 | $self->template($ce->{templates}->{$templateName}, @_); |
111 | $self->template($ce->{templates}->{$templateName}, @_); |
| 107 | } |
112 | } |
| 108 | |
113 | |
| 109 | return $returnValue; |
114 | return $returnValue; |
|
|
115 | } |
|
|
116 | |
|
|
117 | sub sendFile { |
|
|
118 | my ($self) = @_; |
|
|
119 | |
|
|
120 | my $file = $self->{sendFile}->{source}; |
|
|
121 | |
|
|
122 | return NOT_FOUND unless -e $file; |
|
|
123 | return FORBIDDEN unless -r $file; |
|
|
124 | |
|
|
125 | open my $fh, "<", $file |
|
|
126 | or return SERVER_ERROR; |
|
|
127 | while (<$fh>) { |
|
|
128 | print $_; |
|
|
129 | } |
|
|
130 | close $fh; |
|
|
131 | |
|
|
132 | return OK; |
| 110 | } |
133 | } |
| 111 | |
134 | |
| 112 | # template(STRING, @otherArguments) - parse a template, looking for escapes of |
135 | # template(STRING, @otherArguments) - parse a template, looking for escapes of |
| 113 | # the form <!--#NAME ARG1="FOO" ARG2="BAR"--> and calling a member function NAME |
136 | # the form <!--#NAME ARG1="FOO" ARG2="BAR"--> and calling a member function NAME |
| 114 | # (if available) for each NAME. The escapes are called like: |
137 | # (if available) for each NAME. The escapes are called like: |
| … | |
… | |
| 441 | # body |
464 | # body |
| 442 | |
465 | |
| 443 | sub header { |
466 | sub header { |
| 444 | my $self = shift; |
467 | my $self = shift; |
| 445 | my $r = $self->{r}; |
468 | my $r = $self->{r}; |
|
|
469 | |
|
|
470 | if ($self->{sendFile}) { |
|
|
471 | my $contentType = $self->{sendFile}->{type}; |
|
|
472 | my $fileName = $self->{sendFile}->{name}; |
|
|
473 | $r->content_type($contentType); |
|
|
474 | $r->header_out("Content-Disposition" => "attachment; filename=\"$fileName\""); |
|
|
475 | } else { |
| 446 | $r->content_type('text/html'); |
476 | $r->content_type("text/html"); |
|
|
477 | |
|
|
478 | } |
|
|
479 | |
| 447 | $r->send_http_header(); |
480 | $r->send_http_header(); |
| 448 | return OK; |
481 | return OK; |
| 449 | } |
482 | } |
| 450 | |
483 | |
| 451 | sub loginstatus { |
484 | sub loginstatus { |
| … | |
… | |
| 513 | my $users = "$root/$courseName/instructor/users/?" . $self->url_authen_args(); |
546 | my $users = "$root/$courseName/instructor/users/?" . $self->url_authen_args(); |
| 514 | my $email = "$root/$courseName/instructor/send_mail/?" . $self->url_authen_args(); |
547 | my $email = "$root/$courseName/instructor/send_mail/?" . $self->url_authen_args(); |
| 515 | my $scoring = "$root/$courseName/instructor/scoring/?" . $self->url_authen_args(); |
548 | my $scoring = "$root/$courseName/instructor/scoring/?" . $self->url_authen_args(); |
| 516 | my $statsRoot = "$root/$courseName/instructor/stats"; |
549 | my $statsRoot = "$root/$courseName/instructor/stats"; |
| 517 | my $stats = $statsRoot. '/?'.$self->url_authen_args(); |
550 | my $stats = $statsRoot. '/?'.$self->url_authen_args(); |
|
|
551 | my $fileXfer = "$root/$courseName/instructor/files/?" . $self->url_authen_args(); |
| 518 | |
552 | |
| 519 | |
553 | |
| 520 | # Add direct links to sets e.g. 3:4 for set3 problem 4 |
554 | # Add direct links to sets e.g. 3:4 for set3 problem 4 |
| 521 | my $setURL = (defined $set) |
555 | my $setURL = (defined $set) |
| 522 | ? "$root/$courseName/instructor/sets/$set/?" . $self->url_authen_args() |
556 | ? "$root/$courseName/instructor/sets/$set/?" . $self->url_authen_args() |
| … | |
… | |
| 556 | ? ' '.CGI::a({-href=>"$statsRoot/set/$set/?".$self->url_authen_args}, "$set").CGI::br() |
590 | ? ' '.CGI::a({-href=>"$statsRoot/set/$set/?".$self->url_authen_args}, "$set").CGI::br() |
| 557 | : '', |
591 | : '', |
| 558 | (defined($userName)) |
592 | (defined($userName)) |
| 559 | ? ' '.CGI::a({-href=>"$statsRoot/student/$userName/?".$self->url_authen_args}, "$userName").CGI::br() |
593 | ? ' '.CGI::a({-href=>"$statsRoot/student/$userName/?".$self->url_authen_args}, "$userName").CGI::br() |
| 560 | : '', |
594 | : '', |
|
|
595 | ' ',CGI::a({-href=>$fileXfer}, "File Transfer"), CGI::br(), |
| 561 | ); |
596 | ); |
| 562 | } |
597 | } |
| 563 | |
598 | |
| 564 | # &if_can will return 1 if the current object->can("do $_[1]") |
599 | # &if_can will return 1 if the current object->can("do $_[1]") |
| 565 | sub if_can ($$) { |
600 | sub if_can ($$) { |