![]() ![]() | ![]() |
Bug #6476: storing maxtries and random seed
1: # The LearningOnline Network with CAPA 2: # The LON-CAPA Homework handler 3: # 4: # $Id: lonhomework.pm,v 1.326 2011/06/06 16:48:39 www Exp $ 5: # 6: # Copyright Michigan State University Board of Trustees 7: # 8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA). 9: # 10: # LON-CAPA is free software; you can redistribute it and/or modify 11: # it under the terms of the GNU General Public License as published by 12: # the Free Software Foundation; either version 2 of the License, or 13: # (at your option) any later version. 14: # 15: # LON-CAPA is distributed in the hope that it will be useful, 16: # but WITHOUT ANY WARRANTY; without even the implied warranty of 17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18: # GNU General Public License for more details. 19: # 20: # You should have received a copy of the GNU General Public License 21: # along with LON-CAPA; if not, write to the Free Software 22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23: # 24: # /home/httpd/html/adm/gpl.txt 25: # 26: # http://www.lon-capa.org/ 27: 28: 29: package Apache::lonhomework; 30: use strict; 31: use Apache::style(); 32: use Apache::lonxml(); 33: use Apache::lonnet; 34: use Apache::lonplot(); 35: use Apache::inputtags(); 36: use Apache::structuretags(); 37: use Apache::randomlabel(); 38: use Apache::response(); 39: use Apache::hint(); 40: use Apache::outputtags(); 41: use Apache::caparesponse(); 42: use Apache::radiobuttonresponse(); 43: use Apache::optionresponse(); 44: use Apache::imageresponse(); 45: use Apache::essayresponse(); 46: use Apache::externalresponse(); 47: use Apache::rankresponse(); 48: use Apache::matchresponse(); 49: use Apache::chemresponse(); 50: use Apache::functionplotresponse(); 51: use Apache::drawimage(); 52: use Apache::Constants qw(:common); 53: use Apache::loncommon(); 54: use Apache::lonlocal; 55: use Time::HiRes qw( gettimeofday tv_interval ); 56: use HTML::Entities(); 57: use File::Copy(); 58: 59: # FIXME - improve commenting 60: 61: 62: BEGIN { 63: &Apache::lonxml::register_insert(); 64: } 65: 66: 67: =pod 68: 69: =item set_bubble_lines() 70: 71: Called at analysis time to set the bubble lines 72: hash for the problem.. This should be called in the 73: end_problemtype tag in analysis mode. 74: 75: We fetch the hash of part id counters from lonxml 76: and push them into analyze:{part_id.bubble_lines}. 77: 78: =cut 79: 80: sub set_bubble_lines { 81: my %bubble_counters = &Apache::lonxml::get_bubble_line_hash(); 82: 83: foreach my $key (keys(%bubble_counters)) { 84: $Apache::lonhomework::analyze{"$key.bubble_lines"} = 85: $bubble_counters{"$key"}; 86: } 87: } 88: 89: # 90: # Decides what targets to render for. 91: # Implicit inputs: 92: # Various session environment variables: 93: # request.state - published - is a /res/ resource 94: # uploaded - is a /uploaded/ resource 95: # contruct - is a /priv/ resource 96: # form.grade_target - a form parameter requesting a specific target 97: sub get_target { 98: &Apache::lonxml::debug("request.state = $env{'request.state'}"); 99: if( defined($env{'form.grade_target'})) { 100: &Apache::lonxml::debug("form.grade_target= $env{'form.grade_target'}"); 101: } else { 102: &Apache::lonxml::debug("form.grade_target <undefined>"); 103: } 104: if (($env{'request.state'} eq "published") || 105: ($env{'request.state'} eq "uploaded")) { 106: if ( defined($env{'form.grade_target'} ) 107: && ($env{'form.grade_target'} eq 'tex')) { 108: return ($env{'form.grade_target'}); 109: } elsif ( defined($env{'form.grade_target'} ) 110: && ($Apache::lonhomework::viewgrades eq 'F' )) { 111: return ($env{'form.grade_target'}); 112: } elsif ( $env{'form.grade_target'} eq 'webgrade' 113: && ($Apache::lonhomework::queuegrade eq 'F' )) { 114: return ($env{'form.grade_target'}); 115: } elsif ($env{'form.grade_target'} eq 'answer') { 116: if ($env{'form.answer_output_mode'} eq 'tex') { 117: return ($env{'form.grade_target'}); 118: } 119: } 120: if ($env{'form.webgrade'} && 121: ($Apache::lonhomework::modifygrades eq 'F' 122: || $Apache::lonhomework::queuegrade eq 'F' )) { 123: return ('grade','webgrade'); 124: } 125: if ( defined($env{'form.submitted'}) && 126: ( !defined($env{'form.newrandomization'}))) { 127: return ('grade', 'web'); 128: } else { 129: return ('web'); 130: } 131: } elsif ($env{'request.state'} eq "construct") { 132: # 133: # We are in construction space, editing and testing problems 134: # 135: if ( defined($env{'form.grade_target'}) ) { 136: return ($env{'form.grade_target'}); 137: } 138: if ( defined($env{'form.preview'})) { 139: if ( defined($env{'form.submitted'})) { 140: # 141: # We are doing a problem preview 142: # 143: return ('grade', 'web'); 144: } else { 145: return ('web'); 146: } 147: } else { 148: if ($env{'form.problemstate'} eq 'WEB_GRADE') { 149: return ('grade','webgrade','answer'); 150: } elsif ($env{'form.problemmode'} eq 'view') { 151: return ('grade','web','answer'); 152: } elsif ($env{'form.problemmode'} eq 'saveview') { 153: return ('modified','web','answer'); 154: } elsif ($env{'form.problemmode'} eq 'discard') { 155: return ('web','answer'); 156: } elsif (($env{'form.problemmode'} eq 'saveedit') || 157: ($env{'form.problemmode'} eq 'undo')) { 158: return ('modified','no_output_web','edit'); 159: } elsif ($env{'form.problemmode'} eq 'edit') { 160: return ('no_output_web','edit'); 161: } else { 162: return ('web'); 163: } 164: } 165: # 166: # End of Construction Space 167: # 168: } 169: # 170: # Huh? We are nowhere, so do nothing. 171: # 172: return (); 173: } 174: 175: sub setup_vars { 176: my ($target) = @_; 177: return ';' 178: # return ';$external::target='.$target.';'; 179: } 180: 181: sub proctor_checked_in { 182: my ($slot_name,$slot,$type)=@_; 183: my @possible_proctors=split(",",$slot->{'proctor'}); 184: 185: return 1 if (!@possible_proctors); 186: 187: my $key; 188: if ($type eq 'Task') { 189: my $version=$Apache::lonhomework::history{'resource.0.version'}; 190: $key ="resource.$version.0.checkedin"; 191: } elsif ($type eq 'problem') { 192: $key ='resource.0.checkedin'; 193: } 194: # backward compatability, used to be username@domain, 195: # now is username:domain 196: my $who = $Apache::lonhomework::history{$key}; 197: if ($who !~ /:/) { 198: $who =~ tr/@/:/; 199: } 200: foreach my $possible (@possible_proctors) { 201: if ($who eq $possible 202: && $Apache::lonhomework::history{$key.'.slot'} eq $slot_name) { 203: return 1; 204: } 205: } 206: 207: return 0; 208: } 209: 210: sub check_slot_access { 211: my ($id,$type)=@_; 212: 213: # does it pass normal muster 214: my ($status,$datemsg)=&check_access($id); 215: 216: my $useslots = &Apache::lonnet::EXT("resource.0.useslots"); 217: if ($useslots ne 'resource' && $useslots ne 'map' 218: && $useslots ne 'map_map') { 219: return ($status,$datemsg); 220: } 221: 222: if ($status eq 'SHOW_ANSWER' || 223: $status eq 'CLOSED' || 224: $status eq 'INVALID_ACCESS' || 225: $status eq 'UNAVAILABLE') { 226: return ($status,$datemsg); 227: } 228: if ($env{'request.state'} eq "construct") { 229: return ($status,$datemsg); 230: } 231: 232: if ($type eq 'Task') { 233: my $version=$Apache::lonhomework::history{'resource.version'}; 234: if ($Apache::lonhomework::history{"resource.$version.0.checkedin"} && 235: $Apache::lonhomework::history{"resource.$version.0.status"} eq 'pass') { 236: return ('SHOW_ANSWER'); 237: } 238: } 239: 240: my $availablestudent = &Apache::lonnet::EXT("resource.0.availablestudent"); 241: my $available = &Apache::lonnet::EXT("resource.0.available"); 242: my @slots= (split(':',$availablestudent),split(':',$available)); 243: 244: # if (!@slots) { 245: # return ($status,$datemsg); 246: # } 247: my $slotstatus='NOT_IN_A_SLOT'; 248: my ($returned_slot,$slot_name); 249: foreach my $slot (@slots) { 250: $slot =~ s/(^\s*|\s*$)//g; 251: &Apache::lonxml::debug("getting $slot"); 252: my %slot=&Apache::lonnet::get_slot($slot); 253: &Apache::lonhomework::showhash(%slot); 254: if ($slot{'starttime'} < time && 255: $slot{'endtime'} > time && 256: &Apache::loncommon::check_ip_acc($slot{'ip'})) { 257: &Apache::lonxml::debug("$slot is good"); 258: $slotstatus='NEEDS_CHECKIN'; 259: $returned_slot=\%slot; 260: $slot_name=$slot; 261: last; 262: } 263: } 264: if ($slotstatus eq 'NEEDS_CHECKIN' && 265: &proctor_checked_in($slot_name,$returned_slot,$type)) { 266: &Apache::lonxml::debug("proctor checked in"); 267: $slotstatus=$status; 268: } 269: 270: my ($is_correct,$got_grade,$checkedin); 271: if ($type eq 'Task') { 272: my $version=$Apache::lonhomework::history{'resource.0.version'}; 273: $got_grade = 274: ($Apache::lonhomework::history{"resource.$version.0.status"} 275: =~ /^(?:pass|fail)$/); 276: $is_correct = 277: ($Apache::lonhomework::history{"resource.$version.0.status"} eq 'pass' 278: || $Apache::lonhomework::history{"resource.0.solved"} =~ /^correct_/ ); 279: $checkedin = 280: $Apache::lonhomework::history{"resource.$version.0.checkedin"}; 281: } elsif ($type eq 'problem') { 282: $got_grade = 1; 283: $checkedin = $Apache::lonhomework::history{"resource.0.checkedin"}; 284: $is_correct = 285: ($Apache::lonhomework::history{"resource.0.solved"} =~/^correct_/); 286: } 287: 288: &Apache::lonxml::debug(" slot is $slotstatus checkedin ($checkedin) got_grade ($got_grade) is_correct ($is_correct)"); 289: 290: # no slot is currently open, and has been checked in for this version 291: # but hasn't got a grade, therefore must be awaiting a grade 292: if (!defined($slot_name) 293: && $checkedin 294: && !$got_grade) { 295: return ('WAITING_FOR_GRADE'); 296: } 297: 298: # Previously used slot is no longer open, and has been checked in for this version. 299: # However, the problem is not closed, and potentially, another slot might be 300: # used to gain access to it to work on it, until the due date is reached, and the 301: # problem then becomes CLOSED. Therefore return the slotstatus - 302: # (which will be NOT_IN_SLOT). 303: if (!defined($slot_name) 304: && $checkedin 305: && $type eq 'problem') { 306: return ($slotstatus); 307: } 308: 309: if ($slotstatus eq 'NOT_IN_A_SLOT' 310: && $checkedin ) { 311: 312: if ($got_grade) { 313: return ('SHOW_ANSWER'); 314: } else { 315: return ('WAITING_FOR_GRADE'); 316: } 317: 318: } 319: 320: if ( $is_correct) { 321: if ($type eq 'problem') { 322: return ($status); 323: } 324: return ('SHOW_ANSWER'); 325: } 326: 327: if ( $status eq 'CANNOT_ANSWER' && 328: ($slotstatus ne 'NEEDS_CHECKIN' && $slotstatus ne 'NOT_IN_A_SLOT')) { 329: return ($status,$datemsg); 330: } 331: 332: return ($slotstatus,$datemsg,$slot_name,$returned_slot); 333: } 334: 335: # JB, 9/24/2002: Any changes in this function may require a change 336: # in lonnavmaps::resource::getDateStatus. 337: sub check_access { 338: my ($id) = @_; 339: my $date =''; 340: my $status; 341: my $datemsg = ''; 342: my $lastdate = ''; 343: my $type; 344: my $passed; 345: 346: if ($env{'request.state'} eq "construct") { 347: if ($env{'form.problemstate'}) { 348: if ($env{'form.problemstate'} =~ /^CANNOT_ANSWER/) { 349: if ( ! ($env{'form.problemstate'} eq 'CANNOT_ANSWER_correct' 350: && &hide_problem_status())) { 351: return ('CANNOT_ANSWER', 352: &mt('is in this state due to author settings.')); 353: } 354: } else { 355: return ($env{'form.problemstate'}, 356: &mt('is in this state due to author settings.')); 357: } 358: } 359: &Apache::lonxml::debug("in construction ignoring dates"); 360: $status='CAN_ANSWER'; 361: $datemsg=&mt('is in under construction'); 362: # return ($status,$datemsg); 363: } 364: 365: &Apache::lonxml::debug("checking for part :$id:"); 366: &Apache::lonxml::debug("time:".time); 367: 368: my ($symb)=&Apache::lonnet::whichuser(); 369: &Apache::lonxml::debug("symb:".$symb); 370: #if ($env{'request.state'} ne "construct" && $symb ne '') { 371: if ($env{'request.state'} ne "construct") { 372: my $idacc = &Apache::lonnet::EXT("resource.$id.acc"); 373: my $allowed=&Apache::loncommon::check_ip_acc($idacc); 374: if (!$allowed && ($Apache::lonhomework::browse ne 'F')) { 375: $status='INVALID_ACCESS'; 376: $date=&mt("can not be accessed from your location."); 377: return($status,$date); 378: } 379: 380: foreach my $temp ("opendate","duedate","answerdate") { 381: $lastdate = $date; 382: if ($temp eq 'duedate') { 383: $date = &due_date($id); 384: } else { 385: $date = &Apache::lonnet::EXT("resource.$id.$temp"); 386: } 387: 388: my $thistype = &Apache::lonnet::EXT("resource.$id.$temp.type"); 389: if ($thistype =~ /^(con_lost|no_such_host)/ || 390: $date =~ /^(con_lost|no_such_host)/) { 391: $status='UNAVAILABLE'; 392: $date=&mt("may open later."); 393: return($status,$date); 394: } 395: if ($thistype eq 'date_interval') { 396: if ($temp eq 'opendate') { 397: $date=&Apache::lonnet::EXT("resource.$id.duedate")-$date; 398: } 399: if ($temp eq 'answerdate') { 400: $date=&Apache::lonnet::EXT("resource.$id.duedate")+$date; 401: } 402: } 403: &Apache::lonxml::debug("found :$date: for :$temp:"); 404: if ($date eq '') { 405: $date = &mt("an unknown date"); $passed = 0; 406: } elsif ($date eq 'con_lost') { 407: $date = &mt("an indeterminate date"); $passed = 0; 408: } else { 409: if (time < $date) { $passed = 0; } else { $passed = 1; } 410: $date = &Apache::lonlocal::locallocaltime($date); 411: } 412: if (!$passed) { $type=$temp; last; } 413: } 414: &Apache::lonxml::debug("have :$type:$passed:"); 415: if ($passed) { 416: $status='SHOW_ANSWER'; 417: $datemsg=$date; 418: } elsif ($type eq 'opendate') { 419: $status='CLOSED'; 420: $datemsg = &mt("will open on")." $date"; 421: } elsif ($type eq 'duedate') { 422: $status='CAN_ANSWER'; 423: $datemsg = &mt("is due at")." $date"; 424: } elsif ($type eq 'answerdate') { 425: $status='CLOSED'; 426: $datemsg = &mt("was due on")." $lastdate".&mt(", and answers will be available on")." $date"; 427: } 428: } 429: if ($status eq 'CAN_ANSWER' || 430: (($Apache::lonhomework::browse eq 'F') && ($status eq 'CLOSED'))) { 431: #check #tries, and if correct. 432: my $tries = $Apache::lonhomework::history{"resource.$id.tries"}; 433: my $maxtries = &Apache::lonnet::EXT("resource.$id.maxtries"); 434: if ( $tries eq '' ) { $tries = '0'; } 435: if ( $maxtries eq '' && 436: $env{'request.state'} ne 'construct') { $maxtries = '2'; } 437: $Apache::lonhomework::results{'resource.'.$id.'.maxtries'}=$maxtries; 438: if ($maxtries && $tries >= $maxtries) { $status = 'CANNOT_ANSWER'; } 439: # if (correct and show prob status) or excused then CANNOT_ANSWER 440: if(($Apache::lonhomework::history{"resource.$id.solved"}=~/^correct/ 441: && 442: &show_problem_status() 443: && 444: $Apache::lonhomework::history{"resource.$id.awarded"}==1) 445: || 446: $Apache::lonhomework::history{"resource.$id.solved"}=~/^excused/) { 447: $status = 'CANNOT_ANSWER'; 448: } 449: if ($status eq 'CANNOT_ANSWER' 450: && &show_answer_problem_status()) { 451: $status = 'SHOW_ANSWER'; 452: } 453: } 454: if ($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER') { 455: my @interval=&Apache::lonnet::EXT("resource.$id.interval"); 456: &Apache::lonxml::debug("looking for interval @interval"); 457: if ($interval[0]) { 458: my $first_access=&Apache::lonnet::get_first_access($interval[1]); 459: &Apache::lonxml::debug("looking for accesstime $first_access"); 460: if (!$first_access) { 461: $status='NOT_YET_VIEWED'; 462: my $due_date = &due_date($id); 463: my $seconds_left = $due_date - time; 464: if ($seconds_left > $interval[0] || $due_date eq '') { 465: $seconds_left = $interval[0]; 466: } 467: $datemsg=&seconds_to_human_length($seconds_left); 468: } 469: } 470: } 471: 472: #if (($status ne 'CLOSED') && ($Apache::lonhomework::type eq 'exam') && 473: # (!$Apache::lonhomework::history{"resource.0.outtoken"})) { 474: # return ('UNCHECKEDOUT','needs to be checked out'); 475: #} 476: 477: 478: &Apache::lonxml::debug("sending back :$status:$datemsg:"); 479: if (($Apache::lonhomework::browse eq 'F') && ($status eq 'CLOSED')) { 480: &Apache::lonxml::debug("should be allowed to browse a resource when closed"); 481: $status='CAN_ANSWER'; 482: $datemsg=&mt('is closed but you are allowed to view it'); 483: } 484: 485: return ($status,$datemsg); 486: } 487: # this should work exactly like the copy in lonnavmaps.pm 488: sub due_date { 489: my ($part_id,$symb,$udom,$uname)=@_; 490: my $date; 491: my @interval= &Apache::lonnet::EXT("resource.$part_id.interval",$symb, 492: $udom,$uname); 493: &Apache::lonxml::debug("looking for interval $part_id $symb @interval"); 494: my $due_date= &Apache::lonnet::EXT("resource.$part_id.duedate",$symb, 495: $udom,$uname); 496: &Apache::lonxml::debug("looking for due_date $part_id $symb $due_date"); 497: if ($interval[0] =~ /\d+/) { 498: my $first_access=&Apache::lonnet::get_first_access($interval[1],$symb); 499: &Apache::lonxml::debug("looking for first_access $first_access ($interval[1])"); 500: if (defined($first_access)) { 501: my $interval = $first_access+$interval[0]; 502: $date = (!$due_date || $interval < $due_date) ? $interval 503: : $due_date; 504: } else { 505: $date = $due_date; 506: } 507: } else { 508: $date = $due_date; 509: } 510: return $date 511: } 512: 513: sub seconds_to_human_length { 514: my ($length)=@_; 515: 516: my $seconds=$length%60; $length=int($length/60); 517: my $minutes=$length%60; $length=int($length/60); 518: my $hours=$length%24; $length=int($length/24); 519: my $days=$length; 520: 521: my $timestr; 522: if ($days > 0) { $timestr.=&mt('[quant,_1,day]',$days); } 523: if ($hours > 0) { $timestr.=($timestr?", ":""). 524: &mt('[quant,_1,hour]',$hours); } 525: if ($minutes > 0) { $timestr.=($timestr?", ":""). 526: &mt('[quant,_1,minute]',$minutes); } 527: if ($seconds > 0) { $timestr.=($timestr?", ":""). 528: &mt('[quant,_1,second]',$seconds); } 529: return $timestr; 530: } 531: 532: sub showhash { 533: my (%hash) = @_; 534: &showhashsubset(\%hash,'.'); 535: return ''; 536: } 537: 538: sub showarray { 539: my ($array)=@_; 540: my $string="("; 541: foreach my $elm (@{ $array }) { 542: if (ref($elm) eq 'ARRAY') { 543: $string.=&showarray($elm); 544: } elsif (ref($elm) eq 'HASH') { 545: $string.= "HASH --- \n<br />"; 546: $string.= &showhashsubset($elm,'.'); 547: } else { 548: $string.="$elm," 549: } 550: } 551: chop($string); 552: $string.=")"; 553: return $string; 554: } 555: 556: sub showhashsubset { 557: my ($hash,$keyre) = @_; 558: my $resultkey; 559: foreach $resultkey (sort keys %$hash) { 560: if ($resultkey !~ /$keyre/) { next; } 561: if (ref($$hash{$resultkey}) eq 'ARRAY' ) { 562: &Apache::lonxml::debug("$resultkey ---- ". 563: &showarray($$hash{$resultkey})); 564: } elsif (ref($$hash{$resultkey}) eq 'HASH' ) { 565: &Apache::lonxml::debug("$resultkey ---- $$hash{$resultkey}"); 566: &showhashsubset($$hash{$resultkey},'.'); 567: } else { 568: &Apache::lonxml::debug("$resultkey ---- $$hash{$resultkey}"); 569: } 570: } 571: &Apache::lonxml::debug("\n<br />restored values^</br>\n"); 572: return ''; 573: } 574: 575: sub setuppermissions { 576: $Apache::lonhomework::browse= &Apache::lonnet::allowed('bre',$env{'request.filename'}); 577: my $viewgrades = &Apache::lonnet::allowed('vgr',$env{'request.course.id'}); 578: if (! $viewgrades && 579: exists($env{'request.course.sec'}) && 580: $env{'request.course.sec'} !~ /^\s*$/) { 581: $viewgrades = &Apache::lonnet::allowed('vgr',$env{'request.course.id'}. 582: '/'.$env{'request.course.sec'}); 583: } 584: $Apache::lonhomework::viewgrades = $viewgrades; 585: 586: if ($Apache::lonhomework::browse eq 'F' && 587: $env{'form.devalidatecourseresdata'} eq 'on') { 588: my (undef,$courseid) = &Apache::lonnet::whichuser(); 589: &Apache::lonnet::devalidatecourseresdata($env{"course.$courseid.num"}, 590: $env{"course.$courseid.domain"}); 591: } 592: 593: my $modifygrades = &Apache::lonnet::allowed('mgr',$env{'request.course.id'}); 594: if (! $modifygrades && 595: exists($env{'request.course.sec'}) && 596: $env{'request.course.sec'} !~ /^\s*$/) { 597: $modifygrades = 598: &Apache::lonnet::allowed('mgr',$env{'request.course.id'}. 599: '/'.$env{'request.course.sec'}); 600: } 601: $Apache::lonhomework::modifygrades = $modifygrades; 602: 603: my $queuegrade = &Apache::lonnet::allowed('mqg',$env{'request.course.id'}); 604: if (! $queuegrade && 605: exists($env{'request.course.sec'}) && 606: $env{'request.course.sec'} !~ /^\s*$/) { 607: $queuegrade = 608: &Apache::lonnet::allowed('qgr',$env{'request.course.id'}. 609: '/'.$env{'request.course.sec'}); 610: } 611: $Apache::lonhomework::queuegrade = $queuegrade; 612: return ''; 613: } 614: 615: sub unset_permissions { 616: undef($Apache::lonhomework::queuegrade); 617: undef($Apache::lonhomework::modifygrades); 618: undef($Apache::lonhomework::viewgrades); 619: undef($Apache::lonhomework::browse); 620: } 621: 622: sub setupheader { 623: my $request=$_[0]; 624: &Apache::loncommon::content_type($request,'text/html'); 625: if (!$Apache::lonxml::debug && ($ENV{'REQUEST_METHOD'} eq 'GET')) { 626: &Apache::loncommon::no_cache($request); 627: } 628: # $request->set_last_modified(&Apache::lonnet::metadata($request->uri, 629: # 'lastrevisiondate')); 630: $request->send_http_header; 631: return OK if $request->header_only; 632: return '' 633: } 634: 635: sub handle_save_or_undo { 636: my ($request,$problem,$result) = @_; 637: 638: my $file = &Apache::lonnet::filelocation("",$request->uri); 639: my $filebak =$file.".bak"; 640: my $filetmp =$file.".tmp"; 641: my $error=0; 642: if (($env{'form.problemmode'} eq 'undo') || ($env{'form.problemmode'} eq 'undoxml')) { 643: my $error=0; 644: if (!&File::Copy::copy($file,$filetmp)) { $error=1; } 645: if ((!$error) && (!&File::Copy::copy($filebak,$file))) { $error=1; } 646: if ((!$error) && (!&File::Copy::move($filetmp,$filebak))) { $error=1; } 647: if (!$error) { 648: &Apache::lonxml::info("<p><b>". 649: &mt("Undid changes, Switched [_1] and [_2]", 650: '<span class="LC_filename">'.$filebak. 651: '</span>', 652: '<span class="LC_filename">'.$file. 653: '</span>')."</b></p>"); 654: } else { 655: &Apache::lonxml::info("<p><span class=\"LC_error\">". 656: &mt("Unable to undo, unable to switch [_1] and [_2]", 657: '<span class="LC_filename">'. 658: $filebak.'</span>', 659: '<span class="LC_filename">'. 660: $file.'</span>')."</span></p>"); 661: $error=1; 662: } 663: } else { 664: &Apache::lonnet::correct_line_ends($result); 665: 666: my $fs=Apache::File->new(">$filebak"); 667: if (defined($fs)) { 668: print $fs $$problem; 669: } else { 670: &Apache::lonxml::info("<span class=\"LC_error\">". 671: &mt("Unable to make backup [_1]", 672: '<span class="LC_filename">'. 673: $filebak.'</span>')."</span>"); 674: $error=2; 675: } 676: my $fh=Apache::File->new(">$file"); 677: if (defined($fh)) { 678: print $fh $$result; 679: } else { 680: &Apache::lonxml::info('<span class="LC_error">'. 681: &mt("Unable to write to [_1]", 682: '<span class="LC_filename">'. 683: $file.'</span>'). 684: '</span>'); 685: $error|=4; 686: } 687: } 688: return $error; 689: } 690: 691: sub analyze_header { 692: my ($request) = @_; 693: my $js = &Apache::structuretags::setmode_javascript(); 694: 695: # Breadcrumbs 696: my $brcrum = [{'href' => &Apache::loncommon::authorspace(), 697: 'text' => 'Construction Space'}, 698: {'href' => '', 699: 'text' => 'Problem Testing'}, 700: {'href' => '', 701: 'text' => 'Analyzing a problem'}]; 702: 703: my $result = 704: &Apache::loncommon::start_page('Analyzing a problem', 705: $js, 706: {'bread_crumbs' => $brcrum,}) 707: .&Apache::loncommon::head_subbox( 708: &Apache::loncommon::CSTR_pageheader()); 709: $result .= 710: &Apache::lonxml::message_location().' 711: <form name="lonhomework" method="post" action="'. 712: &HTML::Entities::encode($env{'request.uri'},'<>&"').'">'. 713: '<input type="hidden" name="problemmode" value="'. 714: $env{'form.problemmode'}.'" />'. 715: &Apache::structuretags::remember_problem_state().' 716: <div class="LC_edit_problem_analyze_header"> 717: <input type="button" name="submitmode" value="'.&mt("EditXML").'" '. 718: 'onclick="javascript:setmode(this.form,'."'editxml'".')" /> 719: <input type="button" name="submitmode" value="'.&mt('Edit').'" '. 720: 'onclick="javascript:setmode(this.form,'."'edit'".')" /> 721: <hr /> 722: <input type="button" name="submitmode" value="'.&mt("View").'" '. 723: 'onclick="javascript:setmode(this.form,'."'view'".')" /> 724: <hr /> 725: </div> 726: </form>'; 727: &Apache::lonxml::add_messages(\$result); 728: $request->print($result); 729: $request->rflush(); 730: } 731: 732: sub analyze_footer { 733: my ($request) = @_; 734: $request->print(&Apache::loncommon::end_page()); 735: $request->rflush(); 736: } 737: 738: sub analyze { 739: my ($request,$file) = @_; 740: &Apache::lonxml::debug("Analyze"); 741: my $result; 742: my %overall; 743: my %seedexample; 744: my %allparts; 745: my $rndseed=$env{'form.rndseed'}; 746: &analyze_header($request); 747: my %prog_state= 748: &Apache::lonhtmlcommon::Create_PrgWin($request,&mt('Analyze Progress'), 749: &mt('Getting Problem Variants'), 750: $env{'form.numtoanalyze'}, 751: 'inline',undef); 752: for(my $i=1;$i<$env{'form.numtoanalyze'}+1;$i++) { 753: &Apache::lonhtmlcommon::Increment_PrgWin($request,\%prog_state, 754: &mt('last problem')); 755: if (&Apache::loncommon::connection_aborted($request)) { return; } 756: my $thisseed=$i+$rndseed; 757: my $subresult=&Apache::lonnet::ssi($request->uri, 758: ('grade_target' => 'analyze'), 759: ('rndseed' => $thisseed)); 760: (my $garbage,$subresult)=split(/_HASH_REF__/,$subresult,2); 761: my %analyze=&Apache::lonnet::str2hash($subresult); 762: my @parts; 763: if (defined(@{ $analyze{'parts'} })) { 764: @parts=@{ $analyze{'parts'} }; 765: } 766: foreach my $part (@parts) { 767: if (!exists($allparts{$part})) {$allparts{$part}=1;}; 768: if ($analyze{$part.'.type'} eq 'numericalresponse' || 769: $analyze{$part.'.type'} eq 'stringresponse' || 770: $analyze{$part.'.type'} eq 'formularesponse' ) { 771: foreach my $name (keys(%{ $analyze{$part.'.answer'} })) { 772: my $i=0; 773: foreach my $answer_part (@{ $analyze{$part.'.answer'}{$name} }) { 774: push( @{ $overall{$part.'.answer'}[$i] }, 775: $answer_part); 776: my $concatanswer= join("\0",@{ $answer_part }); 777: if (($concatanswer eq '') || ($concatanswer=~/^\@/)) { 778: $answer_part = ['<span class="LC_error">'.&mt('Error').'</span>']; 779: } 780: $seedexample{join("\0",$part,$i,@{$answer_part})}= 781: $thisseed; 782: $i++; 783: } 784: } 785: if (!keys(%{ $analyze{$part.'.answer'} })) { 786: my $answer_part = 787: ['<span class="LC_error">'.&mt('Error').'</span>']; 788: $seedexample{join("\0",$part,0,@{$answer_part})}= 789: $thisseed; 790: push( @{ $overall{$part.'.answer'}[0] }, 791: $answer_part); 792: } 793: } 794: } 795: } 796: &Apache::lonhtmlcommon::Update_PrgWin($request,\%prog_state, 797: &mt('Analyzing Results')); 798: $request->print('<hr />' 799: .'<h3>' 800: .&mt('List of possible answers') 801: .'</h3>' 802: ); 803: foreach my $part (sort(keys(%allparts))) { 804: if (defined(@{ $overall{$part.'.answer'} })) { 805: for (my $i=0;$i<scalar(@{ $overall{$part.'.answer'} });$i++) { 806: my $num_cols=scalar(@{ $overall{$part.'.answer'}[$i][0] }); 807: $request->print(&Apache::loncommon::start_data_table() 808: .&Apache::loncommon::start_data_table_header_row() 809: .'<th colspan="'.($num_cols+1).'">' 810: .&mt('Part').' '.$part 811: ); 812: if (scalar(@{ $overall{$part.'.answer'} }) > 1) { 813: $request->print(' '.&mt('Answer [_1]',$i+1)); 814: } 815: $request->print('</th>' 816: .&Apache::loncommon::end_data_table_header_row() 817: ); 818: my %frequency; 819: foreach my $answer (sort {$a->[0] <=> $b->[0]} (@{ $overall{$part.'.answer'}[$i] })) { 820: $frequency{join("\0",@{ $answer })}++; 821: } 822: $request->print(&Apache::loncommon::start_data_table_header_row() 823: .'<th colspan="'.($num_cols).'">'.&mt('Answer').'</th>' 824: .'<th>'.&mt('Frequency').'<br />' 825: .'('.&mt('click for example').')</th>' 826: .&Apache::loncommon::end_data_table_header_row() 827: ); 828: foreach my $answer (sort {(split("\0",$a))[0] <=> (split("\0",$b))[0]} (keys(%frequency))) { 829: $request->print(&Apache::loncommon::start_data_table_row() 830: .'<td>' 831: .join('</td><td>',split("\0",$answer)) 832: .'</td>' 833: .'<td>' 834: .'<a href="'.$request->uri.'?rndseed='.$seedexample{join("\0",$part,$i,$answer)}.'">'.$frequency{$answer}.'</a>' 835: .'</td>' 836: .&Apache::loncommon::end_data_table_row() 837: ); 838: } 839: $request->print(&Apache::loncommon::end_data_table()); 840: } 841: } else { 842: $request->print('<p class="LC_warning">' 843: .&mt('Response [_1] is not analyzable at this time.',$part) 844: .'</p>' 845: ); 846: } 847: } 848: if (scalar(keys(%allparts)) == 0 ) { 849: $request->print('<p class="LC_warning">' 850: .&mt('Found no analyzable responses in this problem.' 851: .' Currently only Numerical, Formula and String response styles are supported.') 852: .'</p>' 853: ); 854: } 855: &Apache::lonhtmlcommon::Close_PrgWin($request,\%prog_state); 856: &analyze_footer($request); 857: &Apache::lonhomework::showhash(%overall); 858: return $result; 859: } 860: 861: { 862: my $show_problem_status; 863: sub reset_show_problem_status { 864: undef($show_problem_status); 865: } 866: 867: sub set_show_problem_status { 868: my ($new_status) = @_; 869: $show_problem_status = lc($new_status); 870: } 871: 872: sub hide_problem_status { 873: return ($show_problem_status eq 'no' 874: || $show_problem_status eq 'no_feedback_ever'); 875: } 876: 877: sub show_problem_status { 878: return ($show_problem_status eq 'yes' 879: || $show_problem_status eq 'answer' 880: || $show_problem_status eq ''); 881: } 882: 883: sub show_some_problem_status { 884: return ($show_problem_status eq 'no'); 885: } 886: 887: sub show_no_problem_status { 888: return ($show_problem_status eq 'no_feedback_ever'); 889: } 890: 891: sub show_answer_problem_status { 892: return ($show_problem_status eq 'answer'); 893: } 894: } 895: 896: sub editxmlmode { 897: my ($request,$file) = @_; 898: my $result; 899: my $problem=&Apache::lonnet::getfile($file); 900: if ($problem eq -1) { 901: &Apache::lonxml::error( 902: '<b> ' 903: .&mt('Unable to find [_1]', 904: '<span class="LC_filename">'.$file.'</span>') 905: .'</b>'); 906: 907: $problem=''; 908: } 909: 910: if (($env{'form.problemmode'} eq 'saveeditxml') || 911: ($env{'form.problemmode'} eq 'saveviewxml') || 912: ($env{'form.problemmode'} eq 'undoxml')) { 913: my $error=&handle_save_or_undo($request,\$problem, 914: \$env{'form.editxmltext'}); 915: if (!$error) { $problem=&Apache::lonnet::getfile($file); } 916: } 917: &Apache::lonhomework::showhashsubset(\%env,'^form'); 918: if ($env{'form.problemmode'} eq 'saveviewxml') { 919: &Apache::lonhomework::showhashsubset(\%env,'^form'); 920: $env{'form.problemmode'}='view'; 921: &renderpage($request,$file); 922: } else { 923: my ($rows,$cols) = &Apache::edit::textarea_sizes(\$problem); 924: if ($cols > 80) { $cols = 80; } 925: if ($cols < 70) { $cols = 70; } 926: if ($rows < 20) { $rows = 20; } 927: my $js = 928: &Apache::edit::js_change_detection(). 929: &Apache::loncommon::resize_textarea_js(). 930: &Apache::structuretags::setmode_javascript(). 931: &Apache::lonhtmlcommon::dragmath_js("EditMathPopup"); 932: 933: # Breadcrumbs 934: my $brcrum = [{'href' => &Apache::loncommon::authorspace(), 935: 'text' => 'Construction Space'}, 936: {'href' => '', 937: 'text' => 'Problem Editing'}]; 938: 939: my $start_page = 940: &Apache::loncommon::start_page(&mt("EditXML [_1]",$file),$js, 941: {'no_auto_mt_title' => 1, 942: 'only_body' => 0, 943: 'add_entries' => { 944: 'onresize' => q[resize_textarea('LC_editxmltext','LC_aftertextarea')], 945: 'onload' => q[resize_textarea('LC_editxmltext','LC_aftertextarea')], 946: }, 947: 'bread_crumbs' => $brcrum, 948: }); 949: 950: $result=$start_page 951: .&Apache::loncommon::head_subbox( 952: &Apache::loncommon::CSTR_pageheader()); 953: $result.=&renderpage($request,$file,['no_output_web'],1). 954: '<form '.&Apache::edit::form_change_detection().' name="lonhomework" method="post" action="'. 955: &HTML::Entities::encode($env{'request.uri'},'<>&"').'">'. 956: &Apache::structuretags::remember_problem_state().' 957: <div class="LC_edit_problem_editxml_header"> 958: <table class="LC_edit_problem_header_title"><tr><td> 959: <h2>'.&mt('Problem Editing').' '.&Apache::loncommon::help_open_topic('Problem_Editor_XML_Index').'</h2> 960: </td><td align="right"> 961: '.&Apache::loncommon::helpLatexCheatsheet('Problem_LON-CAPA_Functions','Script Functions').' 962: </td></tr> 963: </table>'; 964: 965: $result.='<input type="hidden" name="problemmode" value="saveedit" />'. 966: &Apache::structuretags::problem_edit_buttons('editxml'); 967: 968: $result.='<hr style="clear:both;" />'.&Apache::lonxml::message_location().'</div>'. 969: '<textarea '.&Apache::edit::element_change_detection(). 970: ' rows="'.$rows.'" cols="'.$cols.'" style="width:100%" '. 971: ' name="editxmltext" id="LC_editxmltext">'. 972: &HTML::Entities::encode($problem,'<>&"').'</textarea> 973: <div id="LC_aftertextarea"> 974: </div> 975: </form>'.&Apache::loncommon::end_page(); 976: &Apache::lonxml::add_messages(\$result); 977: $request->print($result); 978: } 979: return ''; 980: } 981: 982: # 983: # Render the page in whatever target desired. 984: # 985: sub renderpage { 986: my ($request,$file,$targets,$return_string) = @_; 987: 988: my @targets = @{$targets || [&get_target()]}; 989: &Apache::lonhomework::showhashsubset(\%env,'form.'); 990: &Apache::lonxml::debug("Running targets ".join(':',@targets)); 991: 992: my $overall_result; 993: foreach my $target (@targets) { 994: # FIXME need to do something intelligent when a problem goes 995: # from viewable to not viewable due to map conditions 996: #&setuppermissions(); 997: #if ( $Apache::lonhomework::browse ne '2' 998: # && $Apache::lonhomework::browse ne 'F' ) { 999: # $request->print(" You most likely shouldn't see me."); 1000: #} 1001: #my $t0 = [&gettimeofday()]; 1002: my $output=1; 1003: if ($target eq 'no_output_web') { 1004: $target = 'web'; $output=0; 1005: } 1006: my $problem=&Apache::lonnet::getfile($file); 1007: my $result; 1008: if ($problem eq -1) { 1009: $problem=''; 1010: my $filename=(split('/',$file))[-1]; 1011: my $error = 1012: "<b> ".&mt('Unable to find [_1]', 1013: '<span class="LC_filename">'.$filename.'</span>') 1014: ."</b>"; 1015: $result.= 1016: &Apache::loncommon::simple_error_page($request,'Not available', 1017: $error); 1018: return; 1019: } 1020: 1021: my %mystyle; 1022: if ($target eq 'analyze') { %Apache::lonhomework::analyze=(); } 1023: if ($target eq 'answer') { &showhash(%Apache::lonhomework::history); } 1024: if ($target eq 'web') {&Apache::lonhomework::showhashsubset(\%env,'^form');} 1025: 1026: &Apache::lonxml::debug("Should be parsing now"); 1027: $result .= &Apache::lonxml::xmlparse($request, $target, $problem, 1028: &setup_vars($target),%mystyle); 1029: &finished_parsing(); 1030: if (!$output) { $result = ''; } 1031: #$request->print("Result follows:"); 1032: if ($target eq 'modified') { 1033: &handle_save_or_undo($request,\$problem,\$result); 1034: } else { 1035: if ($target eq 'analyze') { 1036: $result=&Apache::lonnet::hashref2str(\%Apache::lonhomework::analyze); 1037: undef(%Apache::lonhomework::analyze); 1038: } 1039: #my $td=&tv_interval($t0); 1040: #if ( $Apache::lonxml::debug) { 1041: #$result =~ s:</body>::; 1042: #$result.="<br />Spent $td seconds processing target $target\n</body>"; 1043: #} 1044: # $request->print($result); 1045: $overall_result.=$result; 1046: # $request->rflush(); 1047: } 1048: #$request->print(":Result ends"); 1049: #my $td=&tv_interval($t0); 1050: } 1051: if (!$return_string) { 1052: &Apache::lonxml::add_messages(\$overall_result); 1053: $request->print($overall_result); 1054: $request->rflush(); 1055: } else { 1056: return $overall_result; 1057: } 1058: } 1059: 1060: sub finished_parsing { 1061: undef($Apache::lonhomework::parsing_a_problem); 1062: undef($Apache::lonhomework::parsing_a_task); 1063: } 1064: 1065: sub get_template_list { 1066: my ($extension) = @_; 1067: my $result; 1068: my @allnames; 1069: &Apache::lonxml::debug("Looking for :$extension:"); 1070: my $glob_extension = $extension; 1071: if ($extension eq 'survey' || $extension eq 'exam') { 1072: $glob_extension = 'problem'; 1073: } 1074: my @files = glob($Apache::lonnet::perlvar{'lonIncludes'}. 1075: '/templates/*.'.$glob_extension); 1076: @files = map {[$_,&mt(&Apache::lonnet::metadata($_, 'title')), 1077: (&Apache::lonnet::metadata($_, 'category')?&mt(&Apache::lonnet::metadata($_, 'category')):&mt('Miscellaneous')), 1078: &mt(&Apache::lonnet::metadata($_, 'help'))]} (@files); 1079: @files = sort {$a->[2].$a->[1] cmp $b->[2].$b->[1]} (@files); 1080: my ($midpoint,$seconddiv,$numfiles); 1081: $numfiles = 0; 1082: foreach my $file (@files) { 1083: next if ($file->[1] !~ /\S/); 1084: $numfiles ++; 1085: } 1086: if ($numfiles > 0) { 1087: $result = '<div class="LC_left_float">'; 1088: $midpoint = int($numfiles/2); 1089: if ($numfiles%2) { 1090: $midpoint ++; 1091: } 1092: } 1093: my $count = 0; 1094: my $currentcategory=''; 1095: my $first = 1; 1096: foreach my $file (@files) { 1097: next if ($file->[1] !~ /\S/); 1098: if ($file->[2] ne $currentcategory) { 1099: $currentcategory=$file->[2]; 1100: if ((!$seconddiv) && ($count >= $midpoint)) { 1101: $result .= '</div></div>'."\n".'<div class="LC_left_float">'."\n"; 1102: $seconddiv = 1; 1103: } elsif (!$first) { 1104: $result.='</div>'."\n"; 1105: } else { 1106: $first = 0; 1107: } 1108: $result.= '<div class="LC_Box">'."\n" 1109: .'<h3 class="LC_hcell">'.$currentcategory.'</h3>'."\n"; 1110: $count++; 1111: } 1112: $result .= 1113: '<label><input type="radio" name="template" value="'.$file->[0].'" />'. 1114: $file->[1].'</label>'; 1115: if ($file->[3]) { 1116: $result.=&Apache::loncommon::help_open_topic($file->[3]); 1117: } 1118: my $filename=$file->[0]; 1119: $filename=~s/^\/home\/httpd\/html//; 1120: $result.=' <span class="LC_fontsize_small">' 1121: .'<a href="'.$filename.'?inhibitmenu=yes" target="sample">'.&mt('Example').'</a>' 1122: .'</span><br />'."\n"; 1123: $count ++; 1124: } 1125: if ($numfiles > 0) { 1126: $result .= '</div></div>'."\n".'<div class="LC_clear_float_footer"></div>'."\n"; 1127: } 1128: return $result; 1129: } 1130: 1131: sub newproblem { 1132: my ($request) = @_; 1133: 1134: if ($env{'form.template'}) { 1135: my $file = $env{'form.template'}; 1136: my $dest = &Apache::lonnet::filelocation("",$request->uri); 1137: &File::Copy::copy($file,$dest); 1138: &renderpage($request,$dest); 1139: return; 1140: } 1141: 1142: my ($extension) = ($request->uri =~ m/\.(\w+)$/); 1143: &Apache::lonxml::debug("Looking for :$extension:"); 1144: my $templatelist=&get_template_list($extension); 1145: if ($env{'form.newfile'} && !$templatelist) { 1146: # no templates found 1147: my $templatefilename = 1148: $request->dir_config('lonIncludes').'/templates/blank.'.$extension; 1149: &Apache::lonxml::debug("$templatefilename"); 1150: my $dest = &Apache::lonnet::filelocation("",$request->uri); 1151: &File::Copy::copy($templatefilename,$dest); 1152: &renderpage($request,$dest); 1153: } else { 1154: my $url=&HTML::Entities::encode($request->uri,'<>&"'); 1155: my $shownurl=$url; 1156: $shownurl=~s-^/~-/priv/-; 1157: my $dest = &Apache::lonnet::filelocation("",$request->uri); 1158: my $errormsg; 1159: my $instructions; 1160: my $brcrum = [{'href' => &Apache::loncommon::authorspace(), 1161: 'text' => 'Construction Space'}, 1162: {'href' => '', 1163: 'text' => "Create New $extension"}]; 1164: my $start_page = 1165: &Apache::loncommon::start_page("Create New $extension", 1166: undef, 1167: {'bread_crumbs' => $brcrum,}); 1168: $request->print( 1169: $start_page 1170: .&Apache::loncommon::head_subbox( 1171: &Apache::loncommon::CSTR_pageheader()) 1172: .'<h1>'.&mt("Creating a new $extension resource.")."</h1> 1173: $errormsg 1174: ".&mt("The requested file [_1] currently does not exist.", 1175: '<span class="LC_filename">'.$shownurl.'</span>').' 1176: <p class="LC_info"> 1177: '.&mt("To create a new $extension, select a template from the". 1178: " list below. Then click on the \"Create $extension\" button.").' 1179: </p><div><form action="'.$url.'" method="post">'); 1180: 1181: if (defined($templatelist)) { 1182: $request->print($templatelist); 1183: } 1184: $request->print('<br /><input type="submit" name="newfile" value="'. 1185: &mt("Create $extension").'" />'); 1186: $request->print('</form></div>'.&Apache::loncommon::end_page()); 1187: } 1188: return; 1189: } 1190: 1191: sub update_construct_style { 1192: if ($env{'request.state'} eq "construct" 1193: && $env{'form.problemmode'} eq 'view' 1194: && defined($env{'form.submitted'}) 1195: && !defined($env{'form.resetdata'}) 1196: && !defined($env{'form.newrandomization'})) { 1197: if ((!$env{'form.style_file'} && $env{'construct.style'}) 1198: ||$env{'form.clear_style_file'}) { 1199: &Apache::lonnet::delenv('construct.style'); 1200: } elsif ($env{'form.style_file'} 1201: && $env{'construct.style'} ne $env{'form.style_file'}) { 1202: &Apache::lonnet::appenv({'construct.style' => 1203: $env{'form.style_file'}}); 1204: } 1205: } 1206: } 1207: 1208: 1209: sub handler { 1210: #my $t0 = [&gettimeofday()]; 1211: my $request=$_[0]; 1212: $Apache::lonxml::request=$request; 1213: $Apache::lonxml::debug=$env{'user.debug'}; 1214: $env{'request.uri'}=$request->uri; 1215: &setuppermissions(); 1216: 1217: my $file=&Apache::lonnet::filelocation("",$request->uri); 1218: 1219: #check if we know where we are 1220: if ($env{'request.course.fn'} && !&Apache::lonnet::symbread()) { 1221: # if we are browsing we might not be able to know where we are 1222: if ($Apache::lonhomework::browse ne 'F' && 1223: $env{'request.state'} ne "construct") { 1224: #should know where we are, so ask 1225: &unset_permissions(); 1226: $request->internal_redirect('/adm/ambiguous'); 1227: return OK; 1228: } 1229: } 1230: if (&setupheader($request)) { 1231: &unset_permissions(); 1232: return OK; 1233: } 1234: &Apache::lonxml::debug("Permissions:$Apache::lonhomework::browse:$Apache::lonhomework::viewgrades:$Apache::lonhomework::modifygrades:$Apache::lonhomework::queuegrade"); 1235: &Apache::lonxml::debug("Problem Mode ".$env{'form.problemmode'}); 1236: my ($symb) = &Apache::lonnet::whichuser(); 1237: &Apache::lonxml::debug('symb is '.$symb); 1238: if ($env{'request.state'} eq "construct") { 1239: if ( -e $file ) { 1240: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, 1241: ['problemmode']); 1242: if (!(defined $env{'form.problemmode'})) { 1243: #first visit to problem in construction space 1244: $env{'form.problemmode'}= 'view'; 1245: &renderpage($request,$file); 1246: } elsif (($env{'form.problemmode'} eq 'editxml') || 1247: ($env{'form.problemmode'} eq 'saveeditxml') || 1248: ($env{'form.problemmode'} eq 'saveviewxml') || 1249: ($env{'form.problemmode'} eq 'undoxml')) { 1250: &editxmlmode($request,$file); 1251: } elsif ($env{'form.problemmode'} eq 'calcanswers') { 1252: &analyze($request,$file); 1253: } else { 1254: &update_construct_style(); 1255: &renderpage($request,$file); 1256: } 1257: } else { 1258: # requested file doesn't exist in contruction space 1259: &newproblem($request); 1260: } 1261: } else { 1262: # just render the page normally outside of construction space 1263: &Apache::lonxml::debug("not construct"); 1264: &renderpage($request,$file); 1265: } 1266: #my $td=&tv_interval($t0); 1267: #&Apache::lonxml::debug("Spent $td seconds processing"); 1268: # always turn off debug messages 1269: $Apache::lonxml::debug=0; 1270: &unset_permissions(); 1271: return OK; 1272: 1273: } 1274: 1275: 1; 1276: __END__