File:  [LON-CAPA] / loncom / interface / lonrequestcourse.pm
Revision 1.1: download - view: text, annotated - select for diffs
Mon Jul 27 22:58:24 2009 UTC (14 years, 10 months ago) by raeburn
Branches: MAIN
CVS tags: HEAD
- Ability to make course requests.
- Saving my work.

    1: # The LearningOnline Network
    2: # Request a course
    3: #
    4: # $Id: lonrequestcourse.pm,v 1.1 2009/07/27 22:58:24 raeburn 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: 
   30: =head1 NAME
   31: 
   32: Apache::lonrequestcourse.pm
   33: 
   34: =head1 SYNOPSIS
   35: 
   36: Allows users to request creation of new courses.
   37: 
   38: This is part of the LearningOnline Network with CAPA project
   39: described at http://www.lon-capa.org.
   40: 
   41: =head1 SUBROUTINES
   42: 
   43: =over
   44: 
   45: =item handler()
   46: 
   47: =back
   48: 
   49: =cut
   50: 
   51: package Apache::lonrequestcourse;
   52: 
   53: use strict;
   54: use Apache::Constants qw(:common :http);
   55: use Apache::lonnet;
   56: use Apache::loncommon;
   57: use Apache::lonlocal;
   58: use LONCAPA;
   59: 
   60: sub handler {
   61:     my ($r) = @_;
   62:     if ($r->header_only) {
   63:         &Apache::loncommon::content_type($r,'text/html');
   64:         $r->send_http_header;
   65:         return OK;
   66:     }
   67:     &Apache::loncommon::content_type($r,'text/html');
   68:     $r->send_http_header;
   69: 
   70:     my $action = $env{'form.action'};
   71:     my $state = $env{'form.state'};
   72:     my $dom = &get_course_dom();
   73:     my %can_request;
   74:     my $canreq = &check_can_request($dom,\%can_request);
   75:     if ($action eq 'new') {
   76:         if ($canreq) {
   77:             if ($state eq 'crstype') {
   78:                 &print_main_menu($r,\%can_request,$dom);
   79:             } else {
   80:                 &request_administration($r,$action,$state,$dom);
   81:             }
   82:         } else {
   83:             $r->print(&Apache::loncommon::start_page('Course Requests').
   84:                       '<div class="LC_warning">'.
   85:                       &mt('You do not have privileges to request creation of courses.').
   86:                       '</div>'.
   87:                       &Apache::loncommon::end_page());
   88:         }
   89:     } elsif ($action eq 'view') {
   90:         &print_request_status();
   91:     } elsif ($action eq 'log') {
   92:         &print_request_logs();
   93:     } else {
   94:         &print_main_menu($r,\%can_request,$dom);
   95:     }
   96:     return OK;
   97: }
   98: 
   99: sub check_can_request {
  100:     my ($dom,$can_request) = @_;
  101:     my $canreq = 0;
  102:     if (ref($can_request) eq 'HASH') {
  103:         foreach my $type ('official','unofficial','community') {
  104:             if (&Apache::lonnet::usertools_access($env{'user.name'},
  105:                                                   $env{'user.domain'},
  106:                                                   $type,undef,'requestcourses')) {
  107:                 $canreq ++;
  108:                 if ($dom eq $env{'user.domain'}) {
  109:                     $can_request->{$type} = 1;
  110:                 }
  111:             }
  112:             if ($env{'environment.reqcrsotherdom.'.$type} ne '') {
  113:                 my @curr = split(',',$env{'environment.reqcrsotherdom.'.$type});
  114:                 if (@curr > 0) {
  115:                     $canreq ++;
  116:                     unless ($dom eq $env{'user.domain'}) {
  117:                         if (grep(/^\Q$dom\E$/,@curr)) {
  118:                             $can_request->{$type} = 1;
  119:                         }
  120:                     }
  121:                 }
  122:             }
  123:         }
  124:     }
  125:     return $canreq;
  126: }
  127: 
  128: sub print_main_menu {
  129:     my ($r,$can_request,$dom) = @_;
  130:     my $onchange;
  131:     unless ($env{'form.interface'} eq 'textual') {
  132:         $onchange = 1;
  133:     }
  134: 
  135:     &Apache::lonhtmlcommon::clear_breadcrumbs();
  136: 
  137:     my $js = <<END;
  138: <script type="text/javascript">
  139: 
  140: function nextPage(formname,nextstate) {
  141:     if (check_can_request() == true) {
  142:         formname.state.value= nextstate;
  143:         formname.submit();
  144:     }
  145:     return;
  146: }
  147: 
  148: function backPage(formname,prevstate) {
  149:     formname.state.value = prevstate;
  150:     formname.submit();
  151: }
  152: 
  153: function check_can_request() {
  154:     var official = '';
  155:     var unofficial = '';
  156:     var community = '';    
  157: END
  158: 
  159:     foreach my $item (keys(%{$can_request})) {
  160:             $js .= " 
  161:         $item = 1;
  162: ";
  163:     }
  164:     my %lt = &Apache::lonlocal::texthash(
  165:         official => 'You are not permitted to request creation of an official course in this domain.',
  166:         unofficial => 'You are not permitted to request creation of an unofficial course in this domain.',
  167:         community => 'You are not permitted to request creation of a community this domain.',
  168:         all => 'You must choose a specific course type when making a new course request.\\nAll types is not allowed.',
  169:     ); 
  170:     $js .= <<END;
  171:     var crschoice = document.requestform.crstype.value;
  172:     if (crschoice == 'official') {
  173:         if (official != 1) {
  174:             alert("$lt{'official'}");
  175:             return false;
  176:         }
  177:     } else {
  178:         if (crschoice == 'unofficial') {
  179:             if (unofficial != 1) {
  180:                 alert("$lt{'unofficial'}");
  181:                 return false;
  182:             }
  183:         } else {
  184:             if (crschoice == 'community') {
  185:                 if (community != 1) {
  186:                     alert("$lt{'community'}");
  187:                     return false;
  188:                 }
  189:             } else {
  190:                 var actionchoice = document.requestform.action.value;     
  191:                 if (actionchoice == 'new') {
  192:                     alert("$lt{'all'}");
  193:                     return false;
  194:                 }               
  195:             }
  196:         }
  197:     }
  198:     return true;
  199: }
  200: </script>
  201: 
  202: END
  203: 
  204:     my $formname = 'requestform';
  205:     $r->print(&Apache::loncommon::start_page('Course Requests',$js).
  206:               '<p><div>'.
  207:               '<form name="domforcourse" method="post" action="/adm/requestcourse">'.
  208:               &Apache::lonhtmlcommon::start_pick_box().
  209:               &Apache::lonhtmlcommon::row_title('Domain').
  210:               &Apache::loncommon::select_dom_form($dom,'showdom','',1,$onchange));
  211:     if (!$onchange) {
  212:         $r->print('&nbsp;<input type="submit" name="godom" value="'.
  213:                    &mt('Change').'" />');
  214:     }
  215:     $r->print(&Apache::lonhtmlcommon::row_closure(1).
  216:               &Apache::lonhtmlcommon::end_pick_box().'</form></div>');
  217: 
  218:     my $formname = 'requestform';
  219:     my $next = 'codepick';
  220:     my $nexttext = &mt('Next');
  221:     $r->print('<div><form name="'.$formname.'" method="post" action="/adm/requestcourse">'.
  222:               &Apache::lonhtmlcommon::start_pick_box().
  223:               &Apache::lonhtmlcommon::row_title('Action').'
  224: <input type="hidden" name="showdom" value="'.$dom.'" />
  225: <select size="1" name="action" >
  226:  <option value="new">'.&mt('New course request').'</option>
  227:  <option value="view">'.&mt('View/Modify/Cancel pending requests').'</option>
  228:  <option value="log">'.&mt('View request history').'</option>
  229: </select>'.
  230:               &Apache::lonhtmlcommon::row_closure().
  231:               &Apache::lonhtmlcommon::row_title('Course Type').'
  232: <select size="1" name="crstype">
  233:  <option value="any">'.&mt('All types').'</option>
  234:  <option value="official">'.&mt('Official course').'</option>
  235:  <option value="unofficial">'.&mt('Unofficial course').'</option>
  236:  <option value="community">'.&mt('Community').'</option>
  237: </select>
  238: <input type="hidden" name="state" value="crstype" />'.
  239:               &Apache::lonhtmlcommon::row_closure(1).
  240:               &Apache::lonhtmlcommon::end_pick_box().'<br />
  241: <input type="button" name="next" value="'.$nexttext.'" onclick="javascript:nextPage(document.'.$formname.','."'".$next."'".')" />
  242: </form></div>');
  243:     $r->print(&Apache::loncommon::end_page());
  244:     return;
  245: }
  246: 
  247: sub request_administration {
  248:     my ($r,$action,$state,$dom) = @_;
  249:     if ($action eq 'new') {
  250:         my $js =  <<END;
  251: <script type="text/javascript">
  252: 
  253: function nextPage(formname,nextstate) {
  254:     formname.state.value= nextstate;
  255:     formname.submit();
  256: }
  257: function backPage(formname,prevstate) {
  258:     formname.state.value = prevstate;
  259:     formname.submit();
  260: }
  261: 
  262: </script>
  263: 
  264: END
  265: 
  266:         unless (($state eq 'review') || ($state eq 'process')) {
  267:             $js .= "\n".&Apache::loncommon::coursebrowser_javascript($dom);
  268:         }
  269:         my $start_page =
  270:             &Apache::loncommon::start_page('Request a course',$js);
  271:         $r->print($start_page);
  272:         if ($state eq 'review') {
  273:             &print_review($r,$state,$dom);
  274:         } elsif ($state eq 'process') {
  275:             &print_request_outcome($r,$state,$dom);
  276:         } else {
  277:             &print_request_form($r,$state,$dom);
  278:         }
  279:         $r->print(&Apache::loncommon::end_page());
  280:     } elsif ($action eq 'log') {
  281:         $r->print(&coursereq_log());       
  282:     }
  283:     return;
  284: }
  285: 
  286: sub print_request_form {
  287:     my ($r,$state,$dom) = @_;
  288:     my $formname = 'requestcrs';
  289:     my ($next,$prev,$message,$output,$codepicker);
  290:     my $prev = 'crstype';
  291:     $r->print('<form name="'.$formname.'" method="post" action="/adm/requestcourse">');
  292:     my $crstype = $env{'form.crstype'};
  293:     my $xlist = 0;
  294:     if ($crstype eq 'official') {
  295:         my (@codetitles,%cat_titles,%cat_order,@code_order);
  296:         &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles,
  297:                                                  \%cat_order,\@code_order);
  298:         if ($state eq 'courseinfo') {
  299:             my $instcode;
  300:             if (@code_order > 0) {
  301:                 foreach my $item (@code_order) {
  302:                     $instcode .= $env{'form.instcode_'.$item};  
  303:                 }
  304:             }
  305:             if ($instcode ne '') {
  306:                 my $code_chk = &Apache::lonnet::auto_validate_instcode('',$dom,$instcode);
  307:                 if ($code_chk eq 'ok') {
  308:                     $message = '<div class="LC_info">'.
  309:                                &mt('The chosen course category [_1] is valid.','<b>'.
  310:                                $instcode.'</b>').'</div>';  
  311:                     my @sections = &Apache::lonnet::auto_get_sections(undef,$dom,
  312:                                                                       $instcode);
  313:                     if (@sections) {
  314:                         $output .= &inst_section_selector(\@sections);
  315:                     }
  316:                     $output .= &coursecode_form($dom,'crosslist',\@codetitles,
  317:                                                 \%cat_titles,\%cat_order,$xlist);
  318:                     $prev = 'codepick';
  319:                 } else {
  320:                     $message = '<div class="LC_warning">'.
  321:                                &mt('No course was found matching your choice of institutional course category.');
  322:                     if ($code_chk ne '') {
  323:                         $message .= '<br />'.$code_chk;
  324:                     }
  325:                     $message .= '</div>';
  326:                 }
  327:             }
  328:         }
  329:         unless ($prev eq 'codepick') {
  330:             $codepicker = &coursecode_form($dom,'instcode',\@codetitles,
  331:                                            \%cat_titles,\%cat_order);
  332:         }
  333:     }
  334:     $r->print($message.'<div>'.&Apache::lonhtmlcommon::start_pick_box());
  335:     if ($output ne '') {
  336:         $r->print($output);
  337:     }
  338:     if ($codepicker) {
  339:         $r->print($codepicker);
  340:         $state = 'codepick';
  341:         $next = 'courseinfo';
  342:     } else {
  343:         $r->print(&courseinfo_form());
  344:         $state = 'courseinfo';
  345:         $next = 'review';
  346:     }
  347:     $r->print(&Apache::lonhtmlcommon::end_pick_box().'</div>'."\n");
  348:     unless ($codepicker) {
  349:         $r->print('<div>'.&clone_form($dom,$formname,$crstype).'</div>'."\n");
  350:     }
  351:     $r->print('<input type="hidden" name="state" value="'.$state.'" />'.
  352:               &Apache::lonhtmlcommon::echo_form_input(['state']).'</form>');
  353:     &display_navbuttons($r,$formname,$prev,'Previous',$next,'Next');
  354:     return;
  355: }
  356: 
  357: sub inst_section_selector {
  358:     my ($sections,$selected) = @_;
  359:     my $output;
  360:     if (ref($sections) eq 'ARRAY') {
  361:         $output = &Apache::lonhtmlcommon::row_title('Sections').
  362:                   &Apache::loncommon::start_data_table().
  363:                   &Apache::loncommon::start_data_table_row().
  364:                   '<th>'.&mt('Institutional Section').'</th>'.
  365:                   '<th>'.&mt('LON-CAPA section ID').'</th>'.
  366:                   '<th>'.&mt('Include in course?').'</th>'.
  367:                   &Apache::loncommon::end_data_table_row();
  368:         for (my $i=0; $i<@{$sections}; $i++) {
  369:             my $colflag = $i%2;
  370:             $output .= &Apache::loncommon::start_data_table_row().
  371:                        '<td>'.$sections->[$i].
  372:                        '<input type="hidden" name="secnum_'.$i.'" value="'.
  373:                        $sections->[$i].'" /></td>'.
  374:                        '<td><input type="text" size="10" name="loncapasec_'.$i.
  375:                        '" value="'.$sections->[$i].'" /></td>'.
  376:                        '<td><input type="checkbox" name="sec_'.$i. 
  377:                        '" checked="checked" /></td>'.
  378:                        &Apache::loncommon::end_data_table_row();
  379:         }
  380:         $output .= &Apache::loncommon::end_data_table();
  381:     }
  382:     return $output;
  383: }
  384: 
  385: sub print_request_status {
  386:     return;
  387: }
  388: 
  389: sub print_request_logs {
  390:     return;
  391: }
  392: 
  393: sub print_review {
  394:     my ($r,$state,$dom) = @_;
  395:     return;
  396: }
  397: 
  398: sub courseinfo_form {
  399:     my $output = &Apache::lonhtmlcommon::row_title('Course Description').
  400:                  '<input type="text" size="40" name="description" />';
  401:     return $output;
  402: }
  403: 
  404: sub clone_form {
  405:     my ($dom,$formname,$crstype) = @_;
  406:     my $type = 'Course';
  407:     if ($crstype eq 'community') {
  408:         $type = 'Community';
  409:     }
  410:     my $cloneform = &Apache::loncommon::select_dom_form($dom,'clonedomain').
  411:                     &Apache::loncommon::selectcourse_link($formname,'clonecourse',
  412:                                                          'clonedomain','','','',$type);
  413:     my %lt = &Apache::lonlocal::texthash(
  414:                     'cid'  => 'Course ID',
  415:                     'dmn'  => 'Domain',
  416:                     'dsh'  => 'Date Shift',
  417:                     'ncd'  => 'Do not clone date parameters',
  418:                     'prd'  => 'Clone date parameters as-is',
  419:                     'shd'  => 'Shift date parameters by number of days',
  420:     );
  421:     my $output .= &Apache::lonhtmlcommon::start_pick_box(). 
  422:                   &Apache::lonhtmlcommon::row_title($lt{'cid'}).
  423:                   '<label><input type="text" size="25" name="clonecourse" value="" />'.
  424:                   '</label>'.&Apache::lonhtmlcommon::row_closure(1).'<label>'.
  425:                   &Apache::lonhtmlcommon::row_title($lt{'dmn'}).'</label>'.
  426:                   $cloneform.'</label>'.&Apache::lonhtmlcommon::row_closure().
  427:                   &Apache::lonhtmlcommon::row_title($lt{'dsh'}).'<label>'.
  428:                   '<input type="radio" name="datemode" value="delete" /> '.$lt{'ncd'}.
  429:                   '</label><br /><label>'.
  430:                   '<input type="radio" name="datemode" value="preserve" /> '.$lt{'prd'}.
  431:                   '</label><br /><label>'.
  432:                   '<input type="radio" name="datemode" value="shift" checked="checked" /> '.
  433:                   $lt{'shd'}.'</label>'.
  434:                   '<input type="text" size="5" name="dateshift" value="365" />'.
  435:                   &Apache::lonhtmlcommon::row_closure(1).
  436:                   &Apache::lonhtmlcommon::end_pick_box();
  437:     return $output;
  438: }
  439: 
  440: sub coursecode_form {
  441:     my ($dom,$context,$codetitles,$cat_titles,$cat_order,$count) = @_;
  442:     my $output;
  443:     if ((ref($codetitles) eq 'ARRAY') && (ref($cat_titles) eq 'HASH') && 
  444:         (ref($cat_order))) {
  445:         if (@{$codetitles} > 0) {
  446:             my $lastitem = pop(@{$codetitles});
  447:             my $sel = $context;
  448:             if ($context eq 'crosslist') {
  449:                 $sel .= '_'.$count;
  450:             }
  451:             my $lastinput = '<input type="text" size="5" name="'.$sel.'_'.                                    $lastitem.'" />';
  452:             my %rowtitle = (
  453:                              instcode  => 'Course Category',
  454:                              crosslist => 'Cross Listed Course',
  455:                            );
  456:             if (@{$codetitles} > 0) {
  457:                 my $sel = $context;
  458:                 if ($context eq 'crosslist') {
  459:                     $sel .= '_'.$count;
  460:                 }
  461:                 $output = &Apache::lonhtmlcommon::row_title($rowtitle{$context}).
  462:                           '<table><tr>';
  463:                 foreach my $title (@{$codetitles}) {
  464:                     if (ref($cat_order->{$title}) eq 'ARRAY') {
  465:                         if (@{$cat_order->{$title}} > 0) {
  466:                             $output .= '<td align="center">'.$title.'<br />'."\n".
  467:                                        '<select name="'.$sel.'_'.$title.'">'."\n".
  468:                                        ' <option value="" selected="selected">'.
  469:                                        &mt('Select').'</option>'."\n";
  470:                             foreach my $item (@{$cat_order->{$title}}) {
  471:                                 my $longitem = $item;
  472:                                 if (ref($cat_titles->{$title}) eq 'HASH') {
  473:                                     if ($cat_titles->{$title}{$item} ne '') {
  474:                                         $longitem = $cat_titles->{$title}{$item};
  475:                                     }
  476:                                 }
  477:                                 $output .= '<option value="'.$item.'">'.$longitem.
  478:                                            '</option>'."\n";
  479:                             }
  480:                         }
  481:                         $output .= '</select></td>'."\n";
  482:                     }
  483:                 }
  484:                 if ($context eq 'crosslist') {
  485:                     $output .= '<td align="center">'.$lastitem.'<br />'."\n".
  486:                                $lastinput.'</td></tr></table>';
  487:                 } else {
  488:                     $output .= '</tr></table>'.
  489:                                &Apache::lonhtmlcommon::row_closure().
  490:                                &Apache::lonhtmlcommon::row_title('Course '.$lastitem).
  491:                                $lastinput;
  492:                 }
  493:             } else {
  494:                 if ($context eq 'crosslist') {
  495:                     $output .= &Apache::lonhtmlcommon::row_title($rowtitle{$context}).
  496:                                $lastitem.'<br />';
  497:                 } else { 
  498:                     $output .= &Apache::lonhtmlcommon::row_title('Course '.$lastitem).
  499:                                $lastinput;
  500:                 }
  501:                 $output .=  $lastinput.&Apache::lonhtmlcommon::row_closure(1);
  502:             }
  503:         }
  504:     }
  505:     return $output;
  506: }
  507: 
  508: sub get_course_dom {
  509:     my $codedom = &Apache::lonnet::default_login_domain();
  510:     if (($env{'user.domain'} ne '') && ($env{'user.domain'} ne 'public')) {
  511:         $codedom = $env{'user.domain'};
  512:         if ($env{'request.role.domain'} ne '') {
  513:             $codedom = $env{'request.role.domain'};
  514:         }
  515:     }
  516:     if ($env{'form.showdom'} ne '') {
  517:         if (&Apache::lonnet::domain($env{'form.showdom'}) ne '') {
  518:             $codedom = $env{'form.showdom'};
  519:         }
  520:     }
  521:     return $codedom;
  522: }
  523: 
  524: sub display_navbuttons {
  525:     my ($r,$formname,$prev,$prevtext,$next,$nexttext) = @_;
  526:     $r->print('<div class="LC_navbuttons">');
  527:     if ($prev) {
  528:         $r->print('
  529:       <input type="button" name="previous" value = "'.$prevtext.'"
  530:     onclick="javascript:backPage(document.'.$formname.','."'".$prev."'".')"/>
  531:    &nbsp;&nbsp;&nbsp;');
  532:     } elsif ($prevtext) {
  533:         $r->print('
  534:       <input type="button" name="previous" value = "'.$prevtext.'"
  535:     onclick="javascript:history.back()"/>
  536:    &nbsp;&nbsp;&nbsp;');
  537:     }
  538:     if ($next) {
  539:         $r->print('
  540:       <input type="button" name="next" value="'.$nexttext.'"
  541:  onclick="javascript:nextPage(document.'.$formname.','."'".$next."'".')" />');
  542:     }
  543:     $r->print('</div>');
  544: }
  545: 
  546: sub print_request_outcome {
  547:     return;
  548: }
  549: 
  550: 1;
  551: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>