| … | |
… | |
| 52 | my $userName = $r->param('user'); |
52 | my $userName = $r->param('user'); |
| 53 | my $effectiveUserName = $r->param('effectiveUser'); |
53 | my $effectiveUserName = $r->param('effectiveUser'); |
| 54 | |
54 | |
| 55 | my $user = $db->getUser($userName); |
55 | my $user = $db->getUser($userName); |
| 56 | my $effectiveUser = $db->getUser($effectiveUserName); |
56 | my $effectiveUser = $db->getUser($effectiveUserName); |
|
|
57 | |
| 57 | # obtain the effective user set, or if that is not yet defined obtain global set |
58 | # obtain the effective user set, or if that is not yet defined obtain global set |
| 58 | my $set = $db->getGlobalUserSet($effectiveUserName, $setName); |
59 | my $set = $db->getGlobalUserSet($effectiveUserName, $setName); |
| 59 | #$set = $db->getGlobalSet($setName) unless defined($set); |
|
|
| 60 | unless (defined $set) { |
60 | unless (defined $set) { |
| 61 | my $userSetClass = $courseEnv->{dbLayout}->{set_user}->{record}; |
61 | my $userSetClass = $courseEnv->{dbLayout}->{set_user}->{record}; |
| 62 | $set = global2user($userSetClass, $db->getGlobalSet($setName)); |
62 | $set = global2user($userSetClass, $db->getGlobalSet($setName)); |
| 63 | $set->psvn('000'); |
63 | $set->psvn('000'); |
| 64 | } |
64 | } |
|
|
65 | my $psvn = $set->psvn(); |
|
|
66 | |
| 65 | # obtain the effective user problem, or if that is not yet defined obtain global problem |
67 | # obtain the effective user problem, or if that is not yet defined obtain global problem |
| 66 | my $problem = $db->getGlobalUserProblem($effectiveUserName, $setName, $problemNumber); |
68 | my $problem = $db->getGlobalUserProblem($effectiveUserName, $setName, $problemNumber); |
| 67 | unless (defined $problem) { |
69 | unless (defined $problem) { |
| 68 | my $userProblemClass = $courseEnv->{dbLayout}->{problem_user}->{record}; |
70 | my $userProblemClass = $courseEnv->{dbLayout}->{problem_user}->{record}; |
| 69 | $problem = global2user($userProblemClass, $db->getGlobalProblem($setName,$problemNumber)); |
71 | $problem = global2user($userProblemClass, $db->getGlobalProblem($setName,$problemNumber)); |
|
|
72 | |
|
|
73 | # $problem->max_attempts(-1); # default is infinite number of attempts |
|
|
74 | # $problem->value; |
|
|
75 | # $problem->problem_seed; |
|
|
76 | # $problem->source_file; |
|
|
77 | $problem->user_id($userName); # is this the right value for this unassigned problem? FIXME |
|
|
78 | $problem->status(0); |
| 70 | $problem->max_attempts(-1); |
79 | $problem->attempted(0); |
|
|
80 | $problem->num_correct(0); |
|
|
81 | $problem->num_incorrect(0); |
|
|
82 | $problem->last_answer(' '); |
| 71 | } |
83 | } |
| 72 | #$problem = $db->getGlobalProblem($setName, $problemNumber) unless defined($problem); |
84 | #$problem = $db->getGlobalProblem($setName, $problemNumber) unless defined($problem); |
| 73 | # FIXME |
85 | # FIXME |
| 74 | # a better solution at this point would be to take set and problem, convert them to global_user type |
86 | # a better solution at this point would be to take set and problem, convert them to global_user type |
| 75 | # so that they have the right methods. |
87 | # so that they have the right methods. |
| … | |
… | |
| 80 | |
92 | |
| 81 | # This supplies a psvn if $set doesn't have it. Unfortunately the problem is called on to provide |
93 | # This supplies a psvn if $set doesn't have it. Unfortunately the problem is called on to provide |
| 82 | # data in many places and it might not even have methods defined. |
94 | # data in many places and it might not even have methods defined. |
| 83 | |
95 | |
| 84 | # global sets will not have a defined psvn |
96 | # global sets will not have a defined psvn |
| 85 | my $psvn; |
97 | # my $psvn; |
| 86 | if ($set->can('psvn') ) { |
98 | # if ($set->can('psvn') ) { |
| 87 | $psvn = $set->psvn(); |
99 | # $psvn = $set->psvn(); |
| 88 | } else { # we are viewing an unassigned problem set, psvn's are irrelevant |
100 | # } else { # we are viewing an unassigned problem set, psvn's are irrelevant |
| 89 | $psvn = '0000'; |
101 | # $psvn = '0000'; |
| 90 | } |
102 | # } |
| 91 | |
103 | |
| 92 | my $permissionLevel = $db->getPermissionLevel($userName)->permission(); |
104 | my $permissionLevel = $db->getPermissionLevel($userName)->permission(); |
| 93 | |
105 | |
| 94 | $self->{userName} = $userName; |
106 | $self->{userName} = $userName; |
| 95 | $self->{user} = $user; |
107 | $self->{user} = $user; |
| … | |
… | |
| 113 | my $editMode = undef; |
125 | my $editMode = undef; |
| 114 | my $submit_button = $r->param('submit_button'); |
126 | my $submit_button = $r->param('submit_button'); |
| 115 | if ( defined($submit_button ) ) { |
127 | if ( defined($submit_button ) ) { |
| 116 | $editMode = "temporaryFile" if $submit_button eq 'Refresh'; |
128 | $editMode = "temporaryFile" if $submit_button eq 'Refresh'; |
| 117 | $editMode = 'savedFile' if $submit_button eq 'Save'; |
129 | $editMode = 'savedFile' if $submit_button eq 'Save'; |
| 118 | } |
130 | } |
|
|
131 | |
|
|
132 | #override using the source file data from the form field |
|
|
133 | $problem->source_file($override_problem_source) if defined($override_problem_source); |
|
|
134 | $problem->problem_seed($override_seed) if defined($override_seed); |
|
|
135 | |
|
|
136 | # store path to source file for title. |
|
|
137 | $self->{problem_source_name} = $problem->source_file; |
|
|
138 | $self->{edit_mode} = $editMode; |
|
|
139 | # $self->{current_problem_source} = (defined($override_problem_source) ) ? |
|
|
140 | # $override_problem_source : |
|
|
141 | # $problem->source_file; |
| 119 | # coerce form fields into CGI::Vars format |
142 | # coerce form fields into CGI::Vars format |
| 120 | my $formFields = { WeBWorK::Form->new_from_paramable($r)->Vars }; |
143 | my $formFields = { WeBWorK::Form->new_from_paramable($r)->Vars }; |
| 121 | |
144 | |
| 122 | $self->{displayMode} = $displayMode; |
145 | $self->{displayMode} = $displayMode; |
| 123 | $self->{redisplay} = $redisplay; |
146 | $self->{redisplay} = $redisplay; |
| 124 | $self->{submitAnswers} = $submitAnswers; |
147 | $self->{submitAnswers} = $submitAnswers; |
| 125 | $self->{checkAnswers} = $checkAnswers; |
148 | $self->{checkAnswers} = $checkAnswers; |
| 126 | $self->{previewAnswers} = $previewAnswers; |
149 | $self->{previewAnswers} = $previewAnswers; |
| 127 | $self->{formFields} = $formFields; |
150 | $self->{formFields} = $formFields; |
| 128 | |
151 | |
| 129 | $self->{current_problem_source} = (defined($override_problem_source) ) ? |
152 | |
| 130 | $override_problem_source : |
|
|
| 131 | $problem->source_file; |
|
|
| 132 | $self->{edit_mode} = $editMode; |
|
|
| 133 | ##### permissions ##### |
153 | ##### permissions ##### |
| 134 | |
154 | |
| 135 | # are we allowed to view this problem? |
155 | # are we allowed to view this problem? |
| 136 | $self->{isOpen} = time >= $set->open_date || $permissionLevel > 0; |
156 | $self->{isOpen} = time >= $set->open_date || $permissionLevel > 0; |
| 137 | return unless $self->{isOpen}; |
157 | return unless $self->{isOpen}; |
| … | |
… | |
| 312 | my $file_action; |
332 | my $file_action; |
| 313 | my $edit_mode = $self->{edit_mode}; |
333 | my $edit_mode = $self->{edit_mode}; |
| 314 | if ( not defined($edit_mode) ) { |
334 | if ( not defined($edit_mode) ) { |
| 315 | $file_action = ''; |
335 | $file_action = ''; |
| 316 | } elsif ( $edit_mode eq 'temporaryFile') { |
336 | } elsif ( $edit_mode eq 'temporaryFile') { |
| 317 | $file_action .= 'Editing temporary file : '. CGI::br() . $self->{current_problem_source}; |
337 | $file_action .= 'Editing temporary file : '. CGI::br() . $self->{problem_source_name}; |
| 318 | } elsif ( $edit_mode eq 'savedFile' ){ |
338 | } elsif ( $edit_mode eq 'savedFile' ){ |
| 319 | $file_action .= 'Problem saved to : '. CGI::br() . $self->{current_problem_source}; |
339 | $file_action .= 'Problem saved to : '. CGI::br() . $self->{problem_source_name}; |
| 320 | } |
340 | } |
| 321 | my $problemNumber = $self->{problem}->problem_id . " : " . $file_action; |
341 | my $problemNumber = $self->{problem}->problem_id . " : " . $file_action; |
| 322 | |
342 | |
| 323 | return "$setName : Problem $problemNumber"; |
343 | return "$setName : Problem $problemNumber"; |
| 324 | } |
344 | } |
| … | |
… | |
| 353 | ##### answer processing ##### |
373 | ##### answer processing ##### |
| 354 | |
374 | |
| 355 | # if answers were submitted: |
375 | # if answers were submitted: |
| 356 | if ($submitAnswers) { |
376 | if ($submitAnswers) { |
| 357 | # get a "pure" (unmerged) UserProblem to modify |
377 | # get a "pure" (unmerged) UserProblem to modify |
|
|
378 | # this will be undefined if the problem has not been assigned to this user |
| 358 | my $pureProblem = $db->getUserProblem($problem->user_id, $problem->set_id, $problem->problem_id); |
379 | my $pureProblem = $db->getUserProblem($problem->user_id, $problem->set_id, $problem->problem_id); |
| 359 | # store answers in DB for sticky answers |
380 | # store answers in DB for sticky answers |
| 360 | my %answersToStore; |
381 | my %answersToStore; |
| 361 | my %answerHash = %{ $pg->{answers} }; |
382 | my %answerHash = %{ $pg->{answers} }; |
| 362 | $answersToStore{$_} = $answerHash{$_}->{original_student_ans} |
383 | $answersToStore{$_} = $answerHash{$_}->{original_student_ans} |
| 363 | foreach (keys %answerHash); |
384 | foreach (keys %answerHash); |
| 364 | my $answerString = encodeAnswers(%answersToStore, |
385 | my $answerString = encodeAnswers(%answersToStore, |
| 365 | @{ $pg->{flags}->{ANSWER_ENTRY_ORDER} }); |
386 | @{ $pg->{flags}->{ANSWER_ENTRY_ORDER} }); |
| 366 | $pureProblem->last_answer($answerString); |
387 | |
| 367 | $problem->last_answer($answerString); |
388 | $problem->last_answer($answerString); |
| 368 | $db->putUserProblem($pureProblem); |
389 | # if $pureProblem is defined ( there is a user ) then record the last answer. |
| 369 | |
390 | # FIXME (we're assuming that not being able to get a pure problem is enough to determine |
| 370 | # store state in DB if it makes sense |
391 | # whether or not the problem database needs to be updated. This should be thought through |
| 371 | if ($will{recordAnswers}) { |
392 | # more carefully to be sure. |
| 372 | $problem->status($pg->{state}->{recorded_score}); |
393 | if ( defined($pureProblem) ) { |
| 373 | $problem->attempted(1); |
394 | $pureProblem->last_answer($answerString); |
| 374 | $problem->num_correct($pg->{state}->{num_of_correct_ans}); |
|
|
| 375 | $problem->num_incorrect($pg->{state}->{num_of_incorrect_ans}); |
|
|
| 376 | $pureProblem->status($pg->{state}->{recorded_score}); |
|
|
| 377 | $pureProblem->attempted(1); |
|
|
| 378 | $pureProblem->num_correct($pg->{state}->{num_of_correct_ans}); |
|
|
| 379 | $pureProblem->num_incorrect($pg->{state}->{num_of_incorrect_ans}); |
|
|
| 380 | $db->putUserProblem($pureProblem); |
395 | $db->putUserProblem($pureProblem); |
|
|
396 | #die "pureProblem = ", defined($pureProblem); |
|
|
397 | |
|
|
398 | |
|
|
399 | # store state in DB if it makes sense |
|
|
400 | if ($will{recordAnswers}) { |
|
|
401 | $problem->status($pg->{state}->{recorded_score}); |
|
|
402 | $problem->attempted(1); |
|
|
403 | $problem->num_correct($pg->{state}->{num_of_correct_ans}); |
|
|
404 | $problem->num_incorrect($pg->{state}->{num_of_incorrect_ans}); |
|
|
405 | $pureProblem->status($pg->{state}->{recorded_score}); |
|
|
406 | $pureProblem->attempted(1); |
|
|
407 | $pureProblem->num_correct($pg->{state}->{num_of_correct_ans}); |
|
|
408 | $pureProblem->num_incorrect($pg->{state}->{num_of_incorrect_ans}); |
|
|
409 | $db->putUserProblem($pureProblem); |
| 381 | # write to the transaction log, just to make sure |
410 | # write to the transaction log, just to make sure |
| 382 | writeLog($self->{ce}, "transaction", |
411 | writeLog($self->{ce}, "transaction", |
| 383 | $problem->problem_id."\t". |
412 | $problem->problem_id."\t". |
| 384 | $problem->set_id."\t". |
413 | $problem->set_id."\t". |
| 385 | $problem->user_id."\t". |
414 | $problem->user_id."\t". |
| 386 | $problem->source_file."\t". |
415 | $problem->source_file."\t". |
| 387 | $problem->value."\t". |
416 | $problem->value."\t". |
| 388 | $problem->max_attempts."\t". |
417 | $problem->max_attempts."\t". |
| 389 | $problem->problem_seed."\t". |
418 | $problem->problem_seed."\t". |
| 390 | $pureProblem->status."\t". |
419 | $pureProblem->status."\t". |
| 391 | $pureProblem->attempted."\t". |
420 | $pureProblem->attempted."\t". |
| 392 | $pureProblem->last_answer."\t". |
421 | $pureProblem->last_answer."\t". |
| 393 | $pureProblem->num_correct."\t". |
422 | $pureProblem->num_correct."\t". |
| 394 | $pureProblem->num_incorrect |
423 | $pureProblem->num_incorrect |
| 395 | ); |
424 | ); |
|
|
425 | } |
| 396 | } |
426 | } |
| 397 | } |
427 | } |
| 398 | # logging student answers |
428 | # logging student answers |
| 399 | my $pastAnswerLog = undef; |
429 | my $pastAnswerLog = undef; |
| 400 | if (defined( $self->{ce}->{webworkFiles}->{logs}->{'pastAnswerList'} )) { |
430 | if (defined( $self->{ce}->{webworkFiles}->{logs}->{'pastAnswerList'} )) { |
| … | |
… | |
| 404 | if ($submitAnswers and defined($pastAnswerLog) ) { |
434 | if ($submitAnswers and defined($pastAnswerLog) ) { |
| 405 | my $answerString = ""; |
435 | my $answerString = ""; |
| 406 | my %answerHash = %{ $pg->{answers} }; |
436 | my %answerHash = %{ $pg->{answers} }; |
| 407 | $answerString = $answerString . $answerHash{$_}->{original_student_ans}."\t" |
437 | $answerString = $answerString . $answerHash{$_}->{original_student_ans}."\t" |
| 408 | foreach (sort keys %answerHash); |
438 | foreach (sort keys %answerHash); |
|
|
439 | $answerString = '' unless defined($answerString); # insure string is defined. |
| 409 | writeLog($self->{ce}, "pastAnswerList", |
440 | writeLog($self->{ce}, "pastAnswerList", |
| 410 | '|'.$problem->user_id. |
441 | '|'.$problem->user_id. |
| 411 | '|'.$problem->set_id. |
442 | '|'.$problem->set_id. |
| 412 | '|'.$problem->problem_id.'|'."\t". |
443 | '|'.$problem->problem_id.'|'."\t". |
| 413 | time()."\t". |
444 | time()."\t". |