Annotation of loncom/interface/lonpickcourse.pm, revision 1.123

1.1       www         1: # The LearningOnline Network
                      2: # Pick a course
                      3: #
1.123   ! raeburn     4: # $Id: lonpickcourse.pm,v 1.122 2016/11/02 22:41:18 raeburn Exp $
1.1       www         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::lonpickcourse;
                     30: 
                     31: use strict;
                     32: use Apache::Constants qw(:common);
                     33: use Apache::loncommon;
1.106     raeburn    34: use Apache::lonhtmlcommon;
1.1       www        35: use Apache::loncoursedata;
                     36: use Apache::lonnet;
1.8       www        37: use Apache::lonlocal;
1.46      raeburn    38: use Apache::longroup;
1.85      raeburn    39: use LONCAPA qw(:DEFAULT :match);
1.123   ! raeburn    40: use JSON::DWIW;
1.1       www        41: 
                     42: sub handler {
                     43:     my $r = shift;
1.123   ! raeburn    44:     if ($env{'form.context'} eq 'adhoc') {
        !            45:         &Apache::loncommon::content_type($r,'application/json');
        !            46:         $r->send_http_header;
        !            47:         my ($possroles,$description) = &Apache::lonnet::get_my_adhocroles($env{'form.cid'});
        !            48:         if ((ref($possroles) eq 'ARRAY') && (ref($description) eq 'HASH')) {
        !            49:             my $response = [];
        !            50:             if (@{$possroles}) {
        !            51:                 foreach my $role (@{$possroles}) {
        !            52:                     push(@{$response},
        !            53:                                       { name => $role,
        !            54:                                         desc => $description->{$role},
        !            55:                                       });
        !            56:                 }
        !            57:             }
        !            58:             $r->print(JSON::DWIW->to_json({roles => $response}));
        !            59:         }
        !            60:         return OK;
        !            61:     }
1.8       www        62:     &Apache::loncommon::content_type($r,'text/html');
1.1       www        63:     $r->send_http_header;
                     64:     return OK if $r->header_only;
1.123   ! raeburn    65:     
1.1       www        66: # ------------------------------------------------------------ Print the screen
1.40      albertel   67: 
1.55      raeburn    68:     # Get parameters from query string
1.1       www        69:     &Apache::loncommon::get_unprocessed_cgi
1.55      raeburn    70:         ($ENV{'QUERY_STRING'},['domainfilter','form','cnumelement',
1.19      raeburn    71: 			       'cdomelement','cnameelement','roleelement',
1.116     raeburn    72:                                'multiple','type','setroles','fixeddom','cloner',
                     73:                                'crscode','crsdom']);
1.90      raeburn    74:     my ($type,$title,$jscript,$multelement,$multiple,$roleelement,$typeelement,
1.123   ! raeburn    75:         $lastaction,$autosubmit,$submitopener,$cloneruname,$clonerudom,$crscode,
        !            76:         $crsdom,$rolechooser);
1.55      raeburn    77: 
1.117     raeburn    78:     # Get course type - Course, Community or Placement.
1.54      raeburn    79:     $type = $env{'form.type'};
                     80:     if (!defined($env{'form.type'})) {
                     81:         $type = 'Course';
                     82:     }
1.82      bisitz     83:     $title = 'Selecting a '.$type;
1.54      raeburn    84: 
                     85:     # Setup for multiple course selections, if flag for multiples set.
1.55      raeburn    86:     $multiple = $env{'form.multiple'};
                     87:     if ($multiple) {
                     88:         ($jscript,$multelement) = &multiples_tag();
1.82      bisitz     89:         $title = 'Selecting '.$type.'(s)';
1.54      raeburn    90:     }
                     91: 
1.120     raeburn    92:     # if called when a DC or DH is selecting a course 
                     93:     my ($roledom,$rolename) = split(/:/,$env{'form.roleelement'});
1.54      raeburn    94:     if ($roledom) {
1.120     raeburn    95:         $roleelement = '<input type="hidden" name="roleelement" value="'.$env{'form.roleelement'}.'" />';
1.66      raeburn    96:         $submitopener = &processpick();
1.120     raeburn    97:         $autosubmit = 'process_pick("'.$roledom.'","'.$rolename.'")';
1.123   ! raeburn    98:         if ($rolename eq 'dh') {
        !            99:             my %lt = &Apache::lonlocal::texthash(
        !           100:                      title    => 'Ad hoc role selection',
        !           101:                      preamble => 'Please choose an ad hoc role in the course.',
        !           102:                      cancel   => 'Click "OK" to enter the course, or "Cancel" to choose a different course.',
        !           103:             );
        !           104: 
        !           105:             $rolechooser = <<"END";
        !           106: <div id="LC_adhocrole_chooser" title="$lt{'title'}">
        !           107:   <p>$lt{'preamble'}</p>
        !           108:   <form name="LChelpdeskadhoc" id="LChelpdeskpicker" action="">
        !           109:     <div id="LC_choose_adhoc">
        !           110:     </div>
        !           111:     <input type="submit" tabindex="-1" style="position:absolute; top:-1000px" />
        !           112:   </form>
        !           113:   <p>$lt{'cancel'}</p>
        !           114: </div>
        !           115: END
        !           116:         }
1.54      raeburn   117:     }
1.90      raeburn   118:     if ($env{'form.typeelement'} ne '') {
                    119:         $typeelement = '<input type="hidden" name="typeelement" value="'.$env{'form.typeelement'}.'" />';
                    120:     }
1.54      raeburn   121: 
1.92      raeburn   122:     # if called when a DC is creating a course for another user.
1.85      raeburn   123:     if ($env{'form.form'} eq 'ccrs') {
                    124:         ($cloneruname,$clonerudom) = ($env{'form.cloner'} =~ /^($match_username):($match_domain)$/);
1.116     raeburn   125:         $crscode = $env{'form.crscode'};
                    126:         $crsdom = $env{'request.role.domain'};
1.85      raeburn   127:     }
                    128: 
                    129:     # if called when requesting a course
                    130:     if ($env{'form.form'} eq 'requestcrs') {
                    131:         $cloneruname = $env{'user.name'};
                    132:         $clonerudom =  $env{'user.domain'};
1.116     raeburn   133:         $crscode = $env{'form.crscode'};
                    134:         $crsdom = $env{'form.crsdom'};
1.85      raeburn   135:     }
                    136: 
1.54      raeburn   137:     my $onlyown = 0;
1.55      raeburn   138:     # if called to assign course-based portfolio access control
1.59      raeburn   139:     if ((($env{'form.form'} eq 'portform') && (!$env{'user.adv'}))) {
1.54      raeburn   140:         $onlyown = 1;
1.49      raeburn   141:     }
1.55      raeburn   142: 
                    143:     my %loaditem;
1.84      raeburn   144:     if (($env{'form.type'} eq 'Course') && ($env{'form.numtitles'})) {
                    145:         if (($env{'form.official'} eq 'on') && ($env{'form.state'} eq 'listing')) {
                    146:             $loaditem{'onload'} = 'setElements(document.filterpicker); ';
                    147:         }
1.78      raeburn   148:     }
                    149: 
1.66      raeburn   150:     if ((($env{'form.form'} eq 'cu') || ($env{'form.form'} eq 'studentform')) && 
                    151:         ($env{'form.pickedcourse'})) {
1.115     raeburn   152:         if ($type ne 'Community') {
                    153:             my %coursedescription =
                    154:                 &Apache::lonnet::coursedescription($env{'form.pickedcourse'},
                    155:                                                    {'one_time' => '1'});
                    156:             my $cdom = $coursedescription{'domain'};
                    157:             my %domdefs = &Apache::lonnet::get_domain_defaults($cdom);
                    158:             if (($domdefs{'officialcredits'} || $domdefs{'unofficialcredits'} || $domdefs{'textbookcredits'})) {
                    159:                 $loaditem{'onload'} .= 'setDefaultCredits();';
                    160:             }
                    161:         }
                    162:         $loaditem{'onload'} .= 'setRoles();setSections();';
1.30      raeburn   163:     }
1.113     raeburn   164:     if ((($env{'form.gosearch'}) && ($env{'form.updater'} eq '')) && (!$onlyown)) {
                    165:         $loaditem{'onload'} .=  'hideSearching(); ';
                    166:     }
1.112     raeburn   167:     my $js = &Apache::loncommon::js_changer();
1.107     raeburn   168:     $r->print(&Apache::loncommon::start_page($title,$js,
1.42      albertel  169: 					     {'add_entries' => \%loaditem,
1.41      albertel  170: 					      'no_nav_bar'  => 1, }));
1.55      raeburn   171: 
                    172:     if ($env{'form.form'} eq 'portform') {
                    173:         $lastaction = 'document.courselist.submit()';
1.67      raeburn   174:     } elsif ($env{'form.form'} eq 'cu' || ($env{'form.form'} eq 'studentform' &&
                    175:         !$multiple)) {
1.55      raeburn   176:         $lastaction = 
                    177:              'document.courselist.pickedcourse.value = cdom+"_"+cname;'."\n".
                    178:              'document.courselist.submit();';
1.34      albertel  179:     } else {
1.55      raeburn   180:         $lastaction = 'self.close()';
1.1       www       181:     }
1.19      raeburn   182: 
1.55      raeburn   183:     # if called to assign a role in a course to a user via CUSR
1.66      raeburn   184:     if ($env{'form.form'} eq 'cu' || $env{'form.form'} eq 'studentform') {
1.68      raeburn   185:         $r->print(&create_user_javascript($type));
1.55      raeburn   186:     }
1.54      raeburn   187: 
1.55      raeburn   188:     # print javascript functions for choosing a course 
1.85      raeburn   189:     if ((($env{'form.gosearch'}) && ($env{'form.updater'} eq '')) || 
                    190:         $onlyown) {
1.123   ! raeburn   191:         $r->print(&gochoose_javascript($type,$multiple,$autosubmit,$lastaction,
        !           192:                                        $rolename,$rolechooser));
1.55      raeburn   193:     }
1.105     bisitz    194:     $r->print(&Apache::lonhtmlcommon::scripttag($jscript));
1.55      raeburn   195:     $r->print($submitopener);
1.54      raeburn   196: 
1.55      raeburn   197: # ------------------------------------------ Display of filters to limit search
1.57      raeburn   198:     my $filter = {};
                    199:     my $action = '/adm/pickcourse';
1.99      raeburn   200:     my ($numtitles,$showroles,$nohost,@codetitles);
1.112     raeburn   201:     unless ($onlyown) {
1.111     raeburn   202:         my $filterlist = ['domainfilter','sincefilter'];
1.94      raeburn   203:         # created filter for DCs only
                    204:         if ($env{'user.adv'} && $env{'form.domainfilter'} &&
1.95      raeburn   205:             exists($env{'user.role.dc./'.$env{'form.domainfilter'}.'/'})
                    206:             && $env{'form.form'} ne 'portform') {
1.94      raeburn   207:             my $loncaparev = &Apache::lonnet::get_server_loncaparev($env{'form.domainfilter'});
                    208:             if ($loncaparev ne 'unknown_cmd') {
                    209:                 push(@{$filterlist},'createdfilter');
                    210:             }
                    211:         }
                    212:         push(@{$filterlist},('descriptfilter','instcodefilter'));
1.79      raeburn   213:         if ($env{'form.form'} eq 'rules') {
1.111     raeburn   214:             push(@{$filterlist},('personfilter','persondomfilter'));
                    215:             if ($env{'form.persondomfilter'} eq '') {
                    216:                 unless ($env{'form.gosearch'}) {
                    217:                     $filter->{'persondomfilter'} = $env{'request.role.domain'};
                    218:                 }
                    219:             } else {
                    220:                 $filter->{'persondomfilter'} =
                    221:                     &LONCAPA::clean_domain($env{'form.persondomfilter'});
                    222:             }
1.79      raeburn   223:             if (($env{'form.personfilter'} ne '') && ($env{'form.persondomfilter'} ne '')) {
                    224:                 if (&Apache::lonnet::homeserver($env{'form.personfilter'},
                    225:                                                  $env{'form.persondomfilter'}) eq 'no_host') {
                    226:                     $nohost = 1;
                    227:                 } else {
                    228:                     $showroles = 1;
                    229:                 } 
                    230:             }
                    231:         } else {
1.111     raeburn   232:             push(@{$filterlist},('ownerfilter','ownerdomfilter'));
1.79      raeburn   233:         }
1.55      raeburn   234:         # course ID filter for DCs only
                    235:         if ($env{'user.adv'} && $env{'form.domainfilter'} &&
                    236:             exists($env{'user.role.dc./'.$env{'form.domainfilter'}.'/'})) {
                    237:             push(@{$filterlist},'coursefilter');
                    238:         }
1.85      raeburn   239:         if ($cloneruname ne '' && $clonerudom ne '') {
                    240:             push(@{$filterlist},'cloneableonly');
                    241:         }
1.111     raeburn   242:         if ((ref($filterlist) eq 'ARRAY') && (ref($filter) eq 'HASH')) {
                    243:             foreach my $item (@{$filterlist}) {
                    244:                 $filter->{$item} = $env{'form.'.$item};
                    245:             }
                    246:         }
                    247:         if ($env{'form.form'} eq 'portform') {
                    248:             $filter->{'domainfilter'} ||= $env{'user.domain'};
                    249:         } elsif ($env{'form.form'} eq 'studentform') {
                    250:             $filter->{'domainfilter'} ||= $env{'request.role.domain'};
                    251:         }
                    252:         my $codedom;
                    253:         if ($env{'form.fixeddom'}) {
                    254:             $codedom = $env{'request.role.domain'};
                    255:         } else {
                    256:             $codedom = $filter->{'domainfilter'};
                    257:         }
                    258:         my ($clonetext,$clonewarning);
                    259:         if (($env{'form.form'} eq 'ccrs') || ($env{'form.form'} eq 'requestcrs')) {
                    260:             (my $coord_cloneable,$clonewarning) =
                    261:                 &get_coordinator_cloneable($cloneruname,$clonerudom,$type);
                    262:             if ($env{'form.form'} eq 'ccrs') {
                    263:                 $clonetext = '<input type="hidden" name="cloner" value="'.$env{'form.cloner'}.'" />'."\n";
                    264:             }
                    265:             if ($coord_cloneable) {
                    266:                 $clonetext .= '<input type="hidden" name="cc_clone" value="'.$coord_cloneable.'" />';
                    267:             }
1.116     raeburn   268:             if ($crscode ne '') {
                    269:                 $clonetext .= '<input type="hidden" name="crscode" value="'.$crscode.'" />';
                    270:             }
                    271:             if ($crsdom ne '') {
                    272:                 $clonetext .= '<input type="hidden" name="crsdom" value="'.$crsdom.'" />';
                    273:             }
1.111     raeburn   274:         }
                    275:         $r->print(&Apache::loncommon::build_filters($filterlist,$type,$roleelement,$multelement,
                    276:                                                     $filter,$action,\$numtitles,undef,$cloneruname,
                    277:                                                     $clonerudom,$typeelement,\@codetitles,$codedom,
                    278:                                                     $env{'form.form'},$env{'form.fixeddom'},
                    279:                                                     $env{'form.prevphase'},$env{'form.cnameelement'},
                    280:                                                     $env{'form.cnumelement'},$env{'form.cdomelement'},
                    281:                                                     $env{'form.setroles'},$clonetext,$clonewarning));
1.55      raeburn   282:     }
1.54      raeburn   283: 
                    284: # ---------------------------------------------------------------- Get the data
1.85      raeburn   285:     if ((($env{'form.gosearch'}) && ($env{'form.updater'} eq '')) || 
                    286:          $onlyown) {
1.98      raeburn   287:         my $domcloner;
                    288:         if ($env{'form.form'} eq 'ccrs') {
                    289:             if (($env{'request.role.domain'} eq $env{'form.domainfilter'}) &&
                    290:                 (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'}))) {
                    291:                 $domcloner = 1;
                    292:             }
                    293:         }
1.112     raeburn   294:         my %courses;
                    295:         if (!$onlyown) {
                    296:             $r->print('<div id="searching">'.&mt('Searching ...').'</div>');
                    297:             $r->rflush();
                    298:             my $srchdom = $filter->{'domainfilter'};
                    299:             %courses = &Apache::loncommon::search_courses($srchdom,$type,$filter,$numtitles,
                    300:                                                           $cloneruname,$clonerudom,$domcloner,
1.116     raeburn   301:                                                           \@codetitles,$env{'form.cc_clone'},
                    302:                                                           $crsdom,$crscode);
1.112     raeburn   303:         } else {
                    304:             $r->print('<br />');
                    305:             my %coursehash = &Apache::loncommon::findallcourses();
                    306:             foreach my $cid (sort(keys(%coursehash))) {
                    307:                 $courses{$cid}{'description'} = $env{'course.'.$cid.'.description'};
                    308:             }
                    309:         }
1.79      raeburn   310:         if ($nohost) {
                    311:             $r->print ('<span class="LC_warning">'.
                    312:                        &mt('User does not exist - username: [_1], domain: [_2].',
                    313:                            '<b>'.$filter->{'personfilter'}.'</b>',
                    314:                            '<b>'.$filter->{'persondomfilter'}.'</b>').'</span>');
                    315:         } else {
1.85      raeburn   316:             &display_matched_courses($r,$type,$multiple,$action,$showroles,$cloneruname,
1.116     raeburn   317:                                      $clonerudom,$crsdom,$crscode,%courses);
1.79      raeburn   318:         }
1.54      raeburn   319:     }
                    320:     $r->print(&Apache::loncommon::end_page());
                    321:     return OK;
                    322: }
                    323: 
1.66      raeburn   324: sub processpick {
                    325:     my $openerform = 'rolechoice';
                    326:     if ($env{'form.form'} eq 'studentform') {
                    327:         $openerform = $env{'form.form'};
                    328:     }
                    329:     my $process_pick = <<"ENDONE";
                    330: <script type="text/javascript">
1.120     raeburn   331: function process_pick(dom,rolename) {
1.66      raeburn   332:     var pickedCourse=opener.document.$openerform.$env{'form.cnumelement'}.value;
                    333:     var pickedDomain=opener.document.$openerform.$env{'form.cdomelement'}.value;
                    334:     var okDomain = 0;
                    335: ENDONE
                    336:     if ($openerform eq 'rolechoice') {
                    337:         $process_pick .= <<"ENDTWO";
                    338:     if (pickedDomain == dom) {
                    339:         if (pickedCourse != '') {
1.120     raeburn   340:             var courseTarget; 
                    341:             if (rolename == 'cc') {
                    342:                 var ccrole = "cc";
                    343:                 var pickedType = "$env{'form.type'}";
                    344:                 if (pickedType == "Community") {
                    345:                     ccrole = "co";
                    346:                 }
                    347:                 courseTarget = ccrole+"./"+pickedDomain+"/"+pickedCourse;
                    348:             } else {
                    349:                 if (!/\\W/.test(rolename)) {
                    350:                     courseTarget = "cr/"+pickedDomain+"/"+pickedDomain+"-domainconfig/"+rolename+"./"+pickedDomain+"/"+pickedCourse;
                    351:                 }
                    352:             }
                    353:             if ((courseTarget != '') && (courseTarget != undefined)) { 
                    354:                 opener.document.title='Role selected. Please stand by.';
                    355:                 opener.status='Role selected. Please stand by.';
                    356:                 opener.document.rolechoice.newrole.value=courseTarget;
                    357:                 opener.document.rolechoice.submit();
                    358:             } else {
                    359:                 alert("Invalid role selection");
                    360:                 return;
                    361:             }
1.66      raeburn   362:         }
1.120     raeburn   363:     }
1.66      raeburn   364:     else {
                    365:         alert("You may only use this screen to select courses in the current domain: "+dom+"\\nPlease return to the roles page window and click the 'Select Course' link for domain: "+pickedDomain+",\\n if you are a Domain Coordinator in that domain, and wish to become a Course Coordinator in a course in the domain");
                    366:     }
                    367: ENDTWO
                    368:     } else {
                    369:         $process_pick .= <<"ENDTHREE";
                    370:     if (pickedDomain != dom) {
                    371:         alert("You may only use this screen to select courses in the current domain: "+dom+"\\nPlease return to the roles page window and click the 'Select Course' link for domain: "+pickedDomain+",\\n if you are a Domain Coordinator in that domain, and wish to become a Course Coordinator in a course in the domain");
                    372:         return;
                    373:     }
                    374: ENDTHREE
                    375:     }
                    376:     $process_pick .= "
                    377: }
                    378: 
                    379: </script>
                    380: ";
                    381:     return $process_pick;
                    382: }
                    383: 
1.55      raeburn   384: sub create_user_javascript {
                    385:     my ($type) = @_;
                    386:     my $output;
                    387:     #javascript for reporting sections and groups then closing
                    388:     if ($env{'form.pickedcourse'}) {
1.87      raeburn   389:         my %coursedescription = 
                    390:             &Apache::lonnet::coursedescription($env{'form.pickedcourse'},
                    391:                                                {'one_time' => '1'});
                    392:         my $cdom = $coursedescription{'domain'};
                    393:         my $cnum = $coursedescription{'num'};
                    394:         my $crstype = $coursedescription{'type'};
1.106     raeburn   395:         my %domdefs = &Apache::lonnet::get_domain_defaults($cdom);
                    396:         my ($showcredits,$credits);
                    397:         if (($crstype ne 'Community') &&
1.109     raeburn   398:             (($domdefs{'officialcredits'} || $domdefs{'unofficialcredits'} || $domdefs{'textbookcredits'}))) {
1.106     raeburn   399:             $showcredits = 1; 
                    400:             $credits = $coursedescription{'internal.defaultcredits'};
                    401:         }
1.55      raeburn   402:         my $sec_element = 'currsec';
                    403:         my $grplist_element = 'groups';
                    404:         my ($sections,$groups) =
                    405:           &Apache::loncommon::get_secgrprole_info($cdom,$cnum,'',$type);
                    406:         my $num_sections = scalar(@{$sections});
                    407:         my $seclist = join(',',@{$sections});
                    408:         my $num_groups = scalar(@{$groups});
                    409:         my $groupslist = join(',',@{$groups});
                    410:         $output = qq|
                    411: <script type="text/javascript">
1.106     raeburn   412: // <![CDATA[
1.55      raeburn   413: function setSections() {
                    414:     opener.document.$env{"form.form"}.$grplist_element.value='$groupslist';
                    415:     window.opener.setSect('$seclist');
1.87      raeburn   416:     self.close();
                    417: }
                    418: function setRoles() {
                    419:     window.opener.setRole('$crstype');
1.55      raeburn   420: }
1.106     raeburn   421: |;
                    422:         if ($showcredits) {
                    423:             $output .= qq|
                    424: function setDefaultCredits() {
                    425:     window.opener.setCredits('$credits');
                    426: }
                    427: |;
                    428:         }
                    429:         $output .= qq|
                    430: // ]]>
1.55      raeburn   431: </script>
                    432: |;
                    433:     }
                    434:     return $output;
                    435: }
                    436: 
1.54      raeburn   437: sub display_matched_courses {
1.116     raeburn   438:     my ($r,$type,$multiple,$action,$showroles,$cloneruname,$clonerudom,$crsdom,$crscode,%courses) = @_;
1.55      raeburn   439:     if ($env{'form.form'} eq 'portform') {
                    440:         $action = '/adm/portfolio';
                    441:     }
1.68      raeburn   442:     my $numcourses = keys(%courses);
1.55      raeburn   443:     $r->print('<form name="courselist" method="post" action="'.$action.'">');
1.68      raeburn   444:     if ($env{'form.form'} eq 'modifycourse') {
                    445:         if ($numcourses > 0) {
1.89      raeburn   446:             my $ccrole = 'cc';
                    447:             if ($type eq 'Community') {
                    448:                 $ccrole = 'co';
                    449:             }
                    450:             my $cctitle = &Apache::lonnet::plaintext($ccrole,$type);
1.68      raeburn   451:             my $dctitle = &Apache::lonnet::plaintext('dc');
1.93      raeburn   452:             my $ccrolechk = ' ';
1.122     raeburn   453:             my $possrole;
1.93      raeburn   454:             my $menuchk = ' checked="checked" ';
1.68      raeburn   455:             $r->print(
1.106     raeburn   456:                 '<div class="LC_left_float">'
                    457:                .'<fieldset>'
1.122     raeburn   458:                .'<legend>'.&mt('Pick action').'</legend>');
                    459:             my $roleradio = '<span class="LC_nobreak"><label>'.
                    460:                             '<input type="radio" name="phase" value="adhocrole"'.$ccrolechk.'/>'.'&nbsp;';
1.119     raeburn   461:             if (&Apache::lonnet::allowed('ccc',$crsdom)) {
1.122     raeburn   462:                 $possrole = 1;
                    463:                 $r->print($roleradio);
1.119     raeburn   464:                 if ($type eq 'Community') {
                    465:                     $r->print(&mt('Enter the community with the role of [_1].',$cctitle));
                    466:                 } elsif ($type eq 'Placement') {
                    467:                     $r->print(&mt('Enter the placement test with the role of [_1].',$cctitle));
                    468:                 } else {
                    469:                     $r->print(&mt('Enter the course with the role of [_1].',$cctitle));
                    470:                 }
                    471:             } elsif (&Apache::lonnet::allowed('rar',$crsdom)) {
                    472:                 my %adhocroles = &Apache::lonnet::userenvironment($env{'user.domain'},$env{'user.name'},
                    473:                                                                   'adhocroles.'.$crsdom);
1.122     raeburn   474:                 if ($adhocroles{'adhocroles.'.$crsdom} ne '') {
                    475:                     $possrole = 1;
                    476:                     $r->print($roleradio);
1.119     raeburn   477:                     my @adhoc = split(/,/,$adhocroles{'adhocroles.'.$crsdom});
                    478:                     if (@adhoc > 1) {
                    479:                         my %adhochash;
                    480:                         map { $adhochash{$_} = $_; } @adhoc; 
                    481:                         my $selector = &Apache::loncommon::select_form($adhoc[0],'adhocrole',\%adhochash);
                    482:                         if ($type eq 'Community') {
                    483:                             $r->print(&mt('Enter the community with one of the available ad hoc roles: [_1].',
                    484:                                           $selector)); 
                    485:                         } elsif ($type eq 'Placement') {
                    486:                             $r->print(&mt('Enter the placement test with one of the available ad hoc roles: [_1].',
                    487:                                           $selector));
                    488:                         } else {
                    489:                             $r->print(&mt('Enter the course with one of the available ad hoc roles: [_1].',
                    490:                                           $selector));
                    491:                         }
                    492:                     } else {
                    493:                         if ($type eq 'Community') {
                    494:                             $r->print(&mt('Enter the community with the ad hoc role of: [_1]',$adhoc[0]));
                    495:                         } elsif ($type eq 'Placement') {
                    496:                             $r->print(&mt('Enter the placement test with the ad hoc role of: [_1]',$adhoc[0]));
                    497:                         } else {
                    498:                             $r->print(&mt('Enter the course with the ad hoc role of: [_1]',$adhoc[0]));
                    499:                         }
1.121     raeburn   500:                         $r->print('<input type="hidden" name="adhocrole" value="'.$adhoc[0].'" />');
1.119     raeburn   501:                     }
                    502:                 }
1.89      raeburn   503:             }
1.122     raeburn   504:             if ($possrole) { 
                    505:                 $r->print('</label></span><br />');
                    506:             }
                    507:             $r->print('<span class="LC_nobreak"><label>'
                    508:                      .'<input type="radio" name="phase" value="menu"'.$menuchk.'/>&nbsp;');
1.119     raeburn   509:             if (&Apache::lonnet::allowed('ccc',$crsdom)) {
                    510:                 if ($type eq 'Community') {
                    511:                     $r->print(&mt('View or modify community settings which only a [_1] may modify.',$dctitle));
                    512:                 } elsif ($type eq 'Placement') {
                    513:                     $r->print(&mt('View or modify placement test settings which only a [_1] may modify.',$dctitle));
                    514:                 } else {
                    515:                     $r->print(&mt('View or modify course settings which only a [_1] may modify.',$dctitle));
                    516:                 }
                    517:             } elsif (&Apache::lonnet::allowed('rar',$crsdom)) {
                    518:                 if ($type eq 'Community') {
                    519:                     $r->print(&mt('View community settings which only a [_1] may modify.',$dctitle));
                    520:                 } elsif ($type eq 'Placement') {
                    521:                     $r->print(&mt('View placement test settings which only a [_1] may modify.',$dctitle));
                    522:                 } else {
                    523:                     $r->print(&mt('View course settings which only a [_1] may modify.',$dctitle));
                    524:                 }
1.89      raeburn   525:             }
1.106     raeburn   526:             $r->print('</label></span>'
1.119     raeburn   527:                      .'</fieldset></div>'
                    528:                      .'<br clear="all" />'
                    529:                      );
1.68      raeburn   530:         }
                    531:     }
1.54      raeburn   532:     my %by_descrip;
                    533:     foreach my $course (keys(%courses)) {
                    534:         my $descr;
1.64      raeburn   535:         if (ref($courses{$course}) eq 'HASH') {
1.65      raeburn   536:             $descr = $courses{$course}{'description'};
1.64      raeburn   537:         } elsif ($courses{$course} =~ m/^([^:]*):/i) {
1.54      raeburn   538:             $descr = &unescape($1);
1.34      albertel  539:         } else {
1.54      raeburn   540:             $descr = &unescape($courses{$course});
                    541:         }
                    542:         my $description = $descr;
                    543:         push (@{$by_descrip{$description}}, $course);
                    544:     }
1.71      bisitz    545:  
1.54      raeburn   546:     if ($numcourses > 1 && $multiple) {
1.104     bisitz    547:         $r->print('<input type="button" value="'.&mt('check all').'"
1.54      raeburn   548:                   onclick="javascript:checkAll(document.courselist.course_id)" />
1.104     bisitz    549:                   &nbsp;&nbsp;<input type="button" value="'.&mt('uncheck all').'"
1.54      raeburn   550:                   onclick="javascript:uncheckAll(document.courselist.course_id)" />
                    551:                   <br /><br />');
                    552:     }
1.71      bisitz    553: 
                    554:     if (%courses) {
                    555:         $r->print(&Apache::loncommon::start_data_table());
                    556:         $r->print(&Apache::loncommon::start_data_table_header_row());
1.89      raeburn   557:         my $titlehdr = &mt('Course Title');
                    558:         if ($type eq 'Community') {
                    559:             $titlehdr = &mt('Community Title');
                    560:         }
1.71      bisitz    561:         $r->print('<th>'.&mt('Select').'</th>'
1.89      raeburn   562:                  .'<th>'.$titlehdr.'</th>'
                    563:                  .'<th>'.&mt('Domain').'</th>');
1.117     raeburn   564:         unless (($type eq 'Community') || ($type eq 'Placement')) {
1.89      raeburn   565:             $r->print('<th>'.&mt('Course Code').'</th>');
                    566:         }
                    567:         $r->print('<th>'.&mt('Owner/Co-owner(s)').'</th>');
1.79      raeburn   568:         if ($showroles) {
                    569:             $r->print('<th>'.&mt("Role(s) for [_1]",
                    570:                 &Apache::loncommon::plainname($env{'form.personfilter'},
                    571:                                               $env{'form.persondomfilter'},'firstname')).'</th>');
                    572:         }
1.71      bisitz    573:         $r->print(&Apache::loncommon::end_data_table_header_row());
                    574:     }
1.92      raeburn   575:     my %cc_cloneable;
                    576:     if (($env{'form.form'} eq 'ccrs') || ($env{'form.form'} eq 'requestcrs')) {
                    577:         my ($coord_cloneable,$warning) =
                    578:             &get_coordinator_cloneable($cloneruname,$clonerudom,$type);
                    579:         if ($coord_cloneable) {
                    580:             map {$cc_cloneable{$_} = 1;} split('&',$coord_cloneable);
                    581:         }
                    582:     }
1.116     raeburn   583:     my (%gotdomdefaults,%gotcodedefaults);
1.54      raeburn   584:     foreach my $description (sort { lc($a) cmp lc($b) } (keys(%by_descrip))) {
                    585:         foreach my $course (@{$by_descrip{$description}}) {
1.72      raeburn   586:             $r->print(&Apache::loncommon::start_data_table_row());
1.54      raeburn   587:             my $cleandesc=&HTML::Entities::encode($description,'<>&"');
                    588:             $cleandesc=~s/'/\\'/g;
                    589:             my ($cdom,$cnum)=split(/\_/,$course);
1.85      raeburn   590:             my ($descr,$instcode,$ttype,$canclone,@owners);
1.64      raeburn   591:             if (ref($courses{$course}) eq 'HASH') {
                    592:                 $descr = $courses{$course}{'description'};
1.85      raeburn   593:                 $instcode = $courses{$course}{'inst_code'};
                    594:                 $ttype = $courses{$course}{'type'};
                    595:                 if (($env{'form.form'} eq 'ccrs') || ($env{'form.form'} eq 'requestcrs')) {
1.98      raeburn   596:                     if ($env{'form.form'} eq 'ccrs') {
                    597:                         if (($env{'request.role.domain'} eq $cdom) &&
                    598:                             (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'}))) {
                    599:                             $canclone = 1;
                    600:                         }
                    601:                     }
                    602:                     unless ($canclone) { 
                    603:                         if ($cc_cloneable{$cnum.':'.$cdom}) {
                    604:                             $canclone = 1;
                    605:                         }
1.92      raeburn   606:                     }
                    607:                     unless ($canclone) {
                    608:                         my $cloners = $courses{$course}{'cloners'};
1.116     raeburn   609:                         if ($cloners ne '') {
1.92      raeburn   610:                             my @cloneable = split(',',$cloners);
                    611:                             if (grep(/^\*$/,@cloneable)) {
                    612:                                 $canclone = 1;
                    613:                             }
1.97      raeburn   614:                             if (grep(/^\*:\Q$clonerudom\E$/,@cloneable)) {
1.92      raeburn   615:                                 $canclone = 1;
                    616:                             }
                    617:                             if (grep(/^\Q$cloneruname\E:\Q$clonerudom\E$/,@cloneable)) {
                    618:                                 $canclone = 1;
                    619:                             }
1.116     raeburn   620:                             unless ($canclone) {
                    621:                                 if (($instcode) && ($crscode) && ($cdom eq $crsdom)) {
                    622:                                     foreach my $cloner (@cloneable) {
                    623:                                         if (($cloner ne '*') && ($cloner !~ /^\*\:$match_domain$/) &&
                    624:                                             ($cloner !~ /^$match_username\:$match_domain$/) && ($cloner ne '')) {
                    625:                                             if ($cloner =~ /\=/) {
                    626:                                                 my (%codedefaults,@code_order);
                    627:                                                 if (ref($gotcodedefaults{$cdom}) eq 'HASH') {
                    628:                                                     if (ref($gotcodedefaults{$cdom}{'defaults'}) eq 'HASH') {
                    629:                                                         %codedefaults = %{$gotcodedefaults{$cdom}{'defaults'}};
                    630:                                                     }
                    631:                                                     if (ref($gotcodedefaults{$cdom}{'order'}) eq 'ARRAY') {
                    632:                                                         @code_order = @{$gotcodedefaults{$cdom}{'order'}};
                    633:                                                     }
                    634:                                                 } else {
                    635:                                                     &Apache::lonnet::auto_instcode_defaults($cdom,
                    636:                                                                                             \%codedefaults,
                    637:                                                                                             \@code_order);
                    638:                                                     $gotcodedefaults{$cdom}{'defaults'} = \%codedefaults;
                    639:                                                     $gotcodedefaults{$cdom}{'order'} = \@code_order;
                    640:                                                 }
                    641:                                                 if (@code_order > 0) {
                    642:                                                     if (&Apache::lonnet::check_instcode_cloning(\%codedefaults,\@code_order,
                    643:                                                                                                 $cloner,$instcode,$crscode)) {
                    644:                                                         $canclone = 1;
                    645:                                                         last;
                    646:                                                     }
                    647:                                                 }
                    648:                                             }
                    649:                                         }
                    650:                                     }
                    651:                                 }
                    652:                             }
                    653:                         } else {
                    654:                             my %domdefs;
                    655:                             if (ref($gotdomdefaults{$cdom}) eq 'HASH') {
                    656:                                 %domdefs = %{$gotdomdefaults{$cdom}};
                    657:                             } else {
                    658:                                 %domdefs = &Apache::lonnet::get_domain_defaults($cdom);
                    659:                                 $gotdomdefaults{$cdom} = \%domdefs;
                    660:                             }
                    661:                             if ($domdefs{'canclone'}) {
                    662:                                 unless ($domdefs{'canclone'} eq 'none') {
                    663:                                     if ($domdefs{'canclone'} eq 'domain') {
                    664:                                         if ($clonerudom eq $cdom) {
                    665:                                             $canclone = 1;
                    666:                                         }
                    667:                                     } elsif (($instcode) && ($crscode) &&
                    668:                                              ($cdom eq $crsdom)) {
                    669:                                         my (%codedefaults,@code_order); 
                    670:                                         if (ref($gotcodedefaults{$cdom}) eq 'HASH') {
                    671:                                             if (ref($gotcodedefaults{$cdom}{'defaults'}) eq 'HASH') {
                    672:                                                 %codedefaults = %{$gotcodedefaults{$cdom}{'defaults'}};
                    673:                                             }
                    674:                                             if (ref($gotcodedefaults{$cdom}{'order'}) eq 'ARRAY') {
                    675:                                                 @code_order = @{$gotcodedefaults{$cdom}{'order'}};
                    676:                                             }
                    677:                                         } else {
                    678:                                             &Apache::lonnet::auto_instcode_defaults($cdom,
                    679:                                                                                     \%codedefaults,
                    680:                                                                                     \@code_order);
                    681:                                             $gotcodedefaults{$cdom}{'defaults'} = \%codedefaults;
                    682:                                             $gotcodedefaults{$cdom}{'order'} = \@code_order;
                    683:                                         }
                    684:                                         if (@code_order > 0) {
                    685:                                             if (&Apache::lonnet::default_instcode_cloning($cdom,$domdefs{'canclone'},
                    686:                                                                                           $instcode,$crscode,\%codedefaults,
                    687:                                                                                           \@code_order)) {
                    688:                                                 $canclone = 1;
                    689:                                             }
                    690:                                         }
                    691:                                     }
                    692:                                 }
                    693:                             }
1.85      raeburn   694:                         }
                    695:                     }
                    696:                 }
1.101     raeburn   697:                 push(@owners,$courses{$course}{'owner'});
                    698:                 if ($courses{$course}{'co-owners'} ne '') {
                    699:                     foreach my $item (split(/,/,$courses{$course}{'co-owners'})) {
                    700:                         push(@owners,$item);
1.64      raeburn   701:                     }
                    702:                 }
                    703:             } else {
                    704:                 my $singleowner; 
                    705:                 ($descr,$instcode,$singleowner,$ttype)=split(/:/,$courses{$course});
                    706:                 push(@owners,&unescape($singleowner));
                    707:             }
1.93      raeburn   708:             my $ownerstr = join(', ',map { &Apache::loncommon::plainname(split(':',$_)); } @owners);
1.85      raeburn   709:             $r->print('<td>'.&course_chooser($multiple,$cdom,$cnum,$cleandesc,$canclone).'</td>');
1.71      bisitz    710:             $r->print('<td>'.$description.'</td>');
                    711:             $r->print('<td>');
                    712:             $r->print(&Apache::lonnet::domain($cdom,'description')?
                    713:                       $cdom.' ('.&Apache::lonnet::domain($cdom,'description').')':$cdom);
                    714:             $r->print('</td>');
1.117     raeburn   715:             unless (($type eq 'Community') || ($type eq 'Placement')) { 
1.89      raeburn   716:                 $r->print('<td>');
                    717:                 if ($instcode ne '') {
                    718:                     $r->print(&unescape($instcode));
                    719:                 } else {
                    720:                     $r->print('&nbsp;');
                    721:                 }
                    722:                 $r->print('</td>');
1.54      raeburn   723:             }
1.72      raeburn   724:             $r->print('<td>'.$ownerstr.'</td>');
1.79      raeburn   725:             if ($showroles) {
                    726:                 $r->print('<td>');
                    727:                 my $rolestr;
                    728:                 if (ref($courses{$course}{'roles'}) eq 'ARRAY') {
                    729:                     my @roles = sort(@{$courses{$course}{'roles'}});
                    730:                     foreach my $role (@roles) {
                    731:                         if ($role =~ /^cr/) {
                    732:                             my (undef,$crdom,$crname,$crtitle) = split('/',$role);
                    733:                             $rolestr .= $crtitle.', ';
                    734:                         } else {
1.89      raeburn   735:                             $rolestr .= &Apache::lonnet::plaintext($role,$type).', ';
1.79      raeburn   736:                         }
                    737:                     }
                    738:                     $rolestr =~ s/\, $//;
                    739:                 }
                    740:                 $r->print($rolestr.'</td>');
                    741:             }
1.54      raeburn   742:             if ($multiple) { $r->print("</label>\n"); }
1.72      raeburn   743:             $r->print(&Apache::loncommon::end_data_table_row());
1.71      bisitz    744:             # $r->print("<br />\n");
1.19      raeburn   745:         }
                    746:     }
1.72      raeburn   747:     if (%courses) {
                    748:         $r->print(&Apache::loncommon::end_data_table());
                    749:     }
1.71      bisitz    750: 
1.54      raeburn   751:     if (!%courses) {
1.104     bisitz    752:         $r->print('<p class="LC_info">'.&mt('None found').'</p>');
1.54      raeburn   753:     } elsif ($multiple) {
1.108     bisitz    754:         $r->print('<input type="button" value="'.&mt('Submit').'" onclick="gochoose('."'','','')".'" />');
1.54      raeburn   755:     }
                    756:     $r->print('<input type="hidden" name="form" value="'.$env{'form.form'}.'" />'.
                    757:               "\n".'<input type="hidden" name="pickedcourse" value="" />'."\n".
                    758:               '<input type="hidden" name="type" value="'.$type.'" />'."\n");
                    759:     if ((exists($env{'form.roleelement'})) && ($env{'form.form'} eq 'rolechoice')) {
                    760:         $r->print('<input type="hidden" name="roleelement" value="'.
                    761:                   $env{'form.roleelement'}.'" />'."\n");
                    762:     }
1.55      raeburn   763:     if ($env{'form.form'} eq 'portform') {
                    764:         $r->print('<input type="hidden" name="cnum" value="" />');
                    765:         $r->print('<input type="hidden" name="cdom" value="" />');
                    766:         $r->print('<input type="hidden" name="setroles" value="'.$env{'form.setroles'}.'" />');
                    767:         $r->print('<input type="hidden" name="action" value="rolepicker" />');
1.57      raeburn   768:     } elsif ($env{'form.form'} eq 'modifycourse') {
1.85      raeburn   769:         $r->print(&Apache::lonhtmlcommon::echo_form_input(['phase','pickedcourse','type','form','numtitles','state']));
1.57      raeburn   770:     } else {
                    771:         $r->print('<input type="hidden" name="cnumelement" value="'.
                    772:                   $env{'form.cnumelement'}.'" />'."\n".  
                    773:                   '<input type="hidden" name="cdomelement" value="'.
                    774:                   $env{'form.cdomelement'}.'" />'."\n");
1.90      raeburn   775:         if ($env{'form.typeelement'} ne '') {
                    776:             $r->print('<input type="hidden" name="typeelement" value="'.
                    777:                       $env{'form.typeelement'}.'" />'."\n");
                    778: 
                    779:         }
1.55      raeburn   780:     }
1.78      raeburn   781:     if ((exists($env{'form.fixeddom'})) && ($env{'form.form'} eq 'rules')) {
                    782:         $r->print('<input type="hidden" name="fixeddom" value="'.
                    783:                   $env{'form.fixeddom'}.'" />');
                    784:     }
                    785:     if ($env{'form.numtitles'}) {
                    786:         $r->print('<input type="hidden" name="numtitles" value="'.
                    787:                   $env{'form.numtitles'}.'" />');
                    788:     }
1.54      raeburn   789:     $r->print("</form>\n");
                    790:     return;
                    791: }
                    792: 
                    793: sub multiples_tag {
1.55      raeburn   794:     my $jscript = &Apache::loncommon::check_uncheck_jscript();
                    795:     my $multelement = '<input type="hidden" name="multiple" value="1" />';
                    796:     return ($jscript,$multelement);
1.1       www       797: }
1.30      raeburn   798: 
1.92      raeburn   799: sub get_coordinator_cloneable {
                    800:     my ($cloneruname,$clonerudom,$type) = @_;
1.100     www       801:     if (($cloneruname!~/\w/) || ($clonerudom!~/\w/)) {
                    802:         my $warning = '<div class="LC_warning">'.&mt('Intended course owner not specified').
                    803:                    '</div>';
                    804:         return ('',$warning);
                    805:     } elsif (&Apache::lonnet::homeserver($cloneruname,$clonerudom) eq 'no_host') {
1.92      raeburn   806:         my $warning = '<div class="LC_error">'.&mt('Intended course owner does not exist').
                    807:                    '</div>';
                    808:         return ('',$warning);
                    809:     } else {
                    810:         my ($cc_clone,$ccrole);
                    811:         if ($type eq 'Community') {
                    812:             $ccrole = 'co';
1.117     raeburn   813:         } else {
1.92      raeburn   814:             $ccrole = 'cc';
                    815:         }
                    816:         my %ccroles = &Apache::lonnet::get_my_roles($cloneruname,$clonerudom,
                    817:                                                     'userroles',['active'], [$ccrole]);
                    818:         foreach my $key (sort(keys(%ccroles))) {
                    819:             my ($cnum,$cdom,$role) = split(':',$key);
                    820:             $cc_clone .= $cdom.':'.$cnum.'&';
                    821:         }
                    822:         $cc_clone =~ s/\&$//;
                    823:         return ($cc_clone);
                    824:     }
                    825: }
                    826: 
1.30      raeburn   827: sub course_chooser {
1.85      raeburn   828:     my ($multiple,$cdom,$cnum,$cleandesc,$canclone) = @_;
1.30      raeburn   829:     my $output; 
1.35      raeburn   830:     if ($multiple) {
1.32      albertel  831:         $output = '<label><input type="checkbox" name="course_id" value="'.$cdom.'_'.$cnum.'" />'."\n";
1.85      raeburn   832:     } elsif ((($env{'form.form'} eq 'ccrs') || ($env{'form.form'} eq 'requestcrs')) && (!$canclone))  {
                    833:         if ($env{'form.form'} eq 'ccrs') {
1.114     bisitz    834:             $output = &mt('No cloning for [_1]',$env{'form.cloner'})."\n";
1.85      raeburn   835:         } else {
                    836:             $output = &mt('No rights to clone')."\n";
                    837:         }
1.30      raeburn   838:     } else {
1.108     bisitz    839:         $output = '<input type="button" value="'.&mt('Select').'" onclick="gochoose('.
1.30      raeburn   840:                   "'".$cnum."','".$cdom."','".$cleandesc."')".'" />'."\n";
                    841:     }
                    842:     return $output;
1.49      raeburn   843: }
                    844: 
1.55      raeburn   845: sub gochoose_javascript {
1.123   ! raeburn   846:     my ($type,$multiple,$autosubmit,$lastaction,$rolename,$rolechooser) = @_;
1.55      raeburn   847:     my %elements = (
                    848:                      'Course' => {
                    849:                                  name  => 'coursepick',
                    850:                                  total => 'coursetotal',
                    851:                                  list  => 'courselist',
                    852:                                  },
1.83      raeburn   853:                      'Community' => {
1.88      raeburn   854:                                  name  => 'coursepick',
                    855:                                  total => 'coursetotal',
                    856:                                  list  => 'courselist',
1.55      raeburn   857:                               },
1.117     raeburn   858:                      'Placement' => {
                    859:                                  name  => 'coursepick',
                    860:                                  total => 'coursetotal',
                    861:                                  list  => 'courselist',
                    862:                                  },
1.55      raeburn   863:                     );
1.123   ! raeburn   864: 
        !           865:     my %lt = &Apache::lonlocal::texthash (
        !           866:         none => 'You are not eligible to use an ad hoc role for the selected course',
        !           867:         ok => 'OK',
        !           868:         exit => 'Cancel',       
        !           869:     );
        !           870:     &js_escape(\%lt);
        !           871: 
        !           872:     my $output;
        !           873:     if ($rolechooser) {
        !           874:         $output .= qq|
        !           875: \$( "#LC_adhocrole_chooser" ).dialog({ autoOpen: false });
        !           876: |;
        !           877:     }
        !           878:     $output .= qq|
1.57      raeburn   879: function gochoose(cname,cdom,cdesc) {
1.55      raeburn   880:     var openerForm = "$env{'form.form'}";
1.123   ! raeburn   881:     var openerRole = "$rolename";
1.55      raeburn   882:     courseCount = 0;
                    883:     var courses = '';
1.57      raeburn   884: |;
                    885:     if ($multiple) {
                    886:         $output .= <<"ENDSCRIPT";
                    887:     courseCount = 0;
                    888:     var courses = '';
                    889:     if (typeof(document.courselist.course_id.length) == 'undefined') {
                    890:         // only 1 course checkbox was created
                    891:         if (document.courselist.course_id.checked) {
                    892:             courses = courses + document.courselist.course_id.value + "&&";
                    893:             courseCount ++;
                    894:         }
                    895:     } else {
                    896:         for (var j=0; j<document.courselist.course_id.length; j++) {
                    897:             if (document.courselist.course_id[j].checked) {
                    898:                 courses = courses + document.courselist.course_id[j].value + "&&";
1.55      raeburn   899:                 courseCount ++;
                    900:             }
1.57      raeburn   901:         }
                    902:     }
                    903:     opener.document.$env{'form.form'}.$elements{$type}{'total'}.value = courseCount;
                    904:     if (typeof(opener.document.$env{'form.form'}.$elements{$type}{'name'}.length) ==
                    905:         'undefined') {
                    906:         if (opener.document.$env{'form.form'}.$elements{$type}{'name'}.value == 'specific') {
                    907:             opener.document.$env{'form.form'}.$elements{$type}{'name'}.checked = true;
1.55      raeburn   908:         } else {
1.57      raeburn   909:             opener.document.$env{'form.form'}.$elements{$type}{'name'}.checked = false;
1.55      raeburn   910:         }
1.57      raeburn   911:     } else {
                    912:         for (var j=0; j<opener.document.$env{'form.form'}.$elements{$type}{'name'}.length; j++) {
                    913:             if (opener.document.$env{'form.form'}.$elements{$type}{'name'}\[j].value == 'specific') {
                    914:                 opener.document.$env{'form.form'}.$elements{$type}{'name'}\[j].checked = true;
1.55      raeburn   915:             } else {
1.57      raeburn   916:                 opener.document.$env{'form.form'}.$elements{$type}{'name'}\[j].checked = false;
1.54      raeburn   917:             }
1.55      raeburn   918:         }
1.57      raeburn   919:     }
                    920:     if (courseCount > 0) {
                    921:         courses = courses.substr(0,courses.length-2);
                    922:         opener.document.$env{'form.form'}.$elements{$type}{'list'}.value = courses;
                    923:     }
                    924: ENDSCRIPT
                    925:     } else {
1.90      raeburn   926:         my ($name_code,$type_code);
1.57      raeburn   927:         if ($env{'form.cnameelement'} ne '') {
1.103     raeburn   928:             $name_code = <<ENDNAMECODE;  
                    929: var showcdesc = cdesc;
                    930: if (cdesc.length > 25) {
                    931:     showcdesc = cdesc.substr(0,25)+' ...'; 
                    932: }
                    933: opener.document.$env{'form.form'}.$env{'form.cnameelement'}.value=showcdesc;
                    934: ENDNAMECODE
1.55      raeburn   935:         }
1.90      raeburn   936:         if ($env{'form.typeelement'} ne '') {
                    937:             $type_code = 'opener.document.'.$env{'form.form'}.'.'.
                    938:                           $env{'form.typeelement'}.'.value=document.courselist.type;';
                    939:         }
                    940: 
1.57      raeburn   941:         $output .= qq|
1.55      raeburn   942:         $name_code
1.90      raeburn   943:         $type_code
1.55      raeburn   944:         opener.document.$env{'form.form'}.$env{'form.cnumelement'}.value=cname;
                    945:         var slct=opener.document.$env{'form.form'}.$env{'form.cdomelement'};
                    946:         if (slct.options == undefined) {
                    947:             opener.document.$env{'form.form'}.$env{'form.cdomelement'}.value=cdom;
                    948:         }
                    949:         else {
                    950:             var i;
                    951:             for (i=0;i<slct.length;i++) {
                    952:                 if (slct.options[i].value==cdom) { slct.selectedIndex=i; }
1.54      raeburn   953:             }
                    954:         }
1.57      raeburn   955: |;
1.54      raeburn   956:     }
1.123   ! raeburn   957:     $output .= <<ENDJS;
1.55      raeburn   958:     if (openerForm == 'portform') {
                    959:         document.courselist.cnum.value = cname;
                    960:         document.courselist.cdom.value = cdom;
                    961:     }
1.123   ! raeburn   962:     if ((openerForm == 'rolechoice') && (openerRole == 'dh')) {
        !           963: \$("#LC_choose_adhoc").empty();
        !           964: var http = new XMLHttpRequest();
        !           965: var url = "/adm/pickcourse";
        !           966: var params = "cid="+cdom+"_"+cname+"&context=adhoc";
        !           967: http.open("POST", url, true);
        !           968: http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        !           969: http.onreadystatechange = function() {
        !           970:     if(http.readyState == 4 && http.status == 200) {
        !           971:         var data = \$.parseJSON(http.responseText);
        !           972:         var len = data.roles.length;
        !           973:         if (len == '' || len == null || len == 0) {
        !           974:             alert('$lt{none}');  
        !           975:         } else {
        !           976:             if (len == 1) {
        !           977:                 process_pick(cdom,data.roles[0].name);
        !           978:                 $lastaction;
        !           979:             } else {
        !           980:                 var str = '';
        !           981:                 for (var i=0; i<data.roles.length; i++) { 
        !           982:                     \$("<label><input type='radio' value='"+data.roles[i].name+"' name='LC_get_role' id='LC_get_role_"+i+"' />"+data.roles[i].desc+"</label><span>&nbsp;&nbsp;</span>")
        !           983:                     .appendTo("#LC_choose_adhoc");
        !           984:                 }
        !           985:                 \$( "#LC_get_role_0").prop("checked", true);
        !           986:                 \$( "#LC_adhocrole_chooser" ).dialog({ autoOpen: false });
        !           987:                 \$( "#LC_adhocrole_chooser" ).dialog("open");
        !           988:                 \$( "#LC_adhocrole_chooser" ).dialog({
        !           989:                  height: 400,
        !           990:                  width: 500,
        !           991:                  modal: true,
        !           992:                  resizable: false,
        !           993:                  buttons: [
        !           994:                        {
        !           995:                          text: "$lt{'ok'}",
        !           996:                          click: function() {
        !           997:                                      var rolename = \$('input[name=LC_get_role]:checked', '#LChelpdeskpicker').val();
        !           998:                                      process_pick(cdom,rolename);
        !           999:                                      \$("#LC_adhocrole_chooser").dialog( "close" );
        !          1000:                                      $lastaction;
        !          1001:                                 } 
        !          1002:                        },
        !          1003:                        {
        !          1004:                          text: "$lt{'exit'}",
        !          1005:                          click: function() {
        !          1006:                                      \$("#LC_adhocrole_chooser").dialog( "close" );
        !          1007:                                 }
        !          1008:                        }
        !          1009:                      ],
        !          1010:                 });
        !          1011:                 \$( "#LC_adhocrole_chooser" ).find( "form" ).on( "submit", function( event ) {
        !          1012:                    event.preventDefault();
        !          1013:                    var rolename = \$('input[name=LC_get_role]:checked', '#LChelpdeskpicker').val()
        !          1014:                    process_pick(cdom,rolename);
        !          1015:                    \$("#LC_adhocrole_chooser").dialog( "close" );
        !          1016:                    $lastaction;
        !          1017:                    });
        !          1018:             }
        !          1019:         }
        !          1020:     }
1.54      raeburn  1021: }
1.123   ! raeburn  1022: http.send(params);
        !          1023:     } else {
        !          1024:         $autosubmit
        !          1025:         $lastaction
        !          1026:     }
        !          1027: }
        !          1028: 
        !          1029: ENDJS
        !          1030:     return $rolechooser.&Apache::lonhtmlcommon::scripttag($output);
        !          1031: }
        !          1032: 
        !          1033: sub get_my_adhocroles {
        !          1034:     my (@okroles,%description);
        !          1035:     if ($env{'form.cid'} =~ /^($match_domain)_($match_courseid)$/) {
        !          1036:         my $cdom = $1;
        !          1037:         my $cnum = $2;
        !          1038:         if ($env{"user.role.dh./$cdom/"}) {
        !          1039:             my $then=$env{'user.login.time'};
        !          1040:             my $update=$env{'user.update.time'};
        !          1041:             my $liverole = 1;
        !          1042:             my ($tstart,$tend)=split(/\./,$env{'user.role.dh./'.$cdom});
        !          1043:             my $limit = $update;
        !          1044:             if ($env{'request.role'} eq 'dh./'.$cdom.'/') {
        !          1045:                 $limit = $then;
        !          1046:             }
        !          1047:             if ($tstart && $tstart>$limit) { $liverole = 0; }
        !          1048:             if ($tend   && $tend  <$limit) { $liverole = 0; }
        !          1049:             if ($liverole) {
        !          1050:                 if (&Apache::lonnet::homeserver($cnum,$cdom) ne 'no_host') {
        !          1051:                     my %domdefaults = &Apache::lonnet::get_domain_defaults($cdom);
        !          1052:                     if (ref($domdefaults{'adhocroles'}) eq 'HASH') {
        !          1053:                         my $count = 0;
        !          1054:                         my %domcurrent = %{$domdefaults{'adhocroles'}};
        !          1055:                         my (%ordered,%access_in_dom);
        !          1056:                         foreach my $role (sort(keys(%{$domdefaults{'adhocroles'}}))) {
        !          1057:                             my ($order,$desc,$access_in_dom);
        !          1058:                             if (ref($domcurrent{$role}) eq 'HASH') {
        !          1059:                                 $order = $domcurrent{$role}{'order'};
        !          1060:                                 $desc = $domcurrent{$role}{'desc'};
        !          1061:                                 $access_in_dom{$role} = $domcurrent{$role}{'access'};
        !          1062:                             }
        !          1063:                             if ($order eq '') {
        !          1064:                                 $order = $count;
        !          1065:                             }
        !          1066:                             $ordered{$order} = $role;
        !          1067:                             if ($desc ne '') {
        !          1068:                                 $description{$role} = $desc;
        !          1069:                             } else {
        !          1070:                                 $description{$role}= $role;
        !          1071:                             }
        !          1072:                             $count++;
        !          1073:                         }
        !          1074:                         my @roles_by_num = ();
        !          1075:                         foreach my $item (sort {$a <=> $b } (keys(%ordered))) {
        !          1076:                             push(@roles_by_num,$ordered{$item});
        !          1077:                         }
        !          1078:                         if (@roles_by_num) {
        !          1079:                             my %settings = &Apache::lonnet::dump('environment',$cdom,$cnum,'internal\.adhoc');
        !          1080:                             my %setincrs;
        !          1081:                             if ($settings{'internal.adhocaccess'}) {
        !          1082:                                 map { $setincrs{$_} = 1; } split(/,/,$settings{'internal.adhocaccess'});
        !          1083:                             }
        !          1084:                             my @statuses;
        !          1085:                             if ($env{'environment.inststatus'}) {
        !          1086:                                 @statuses = split(/,/,$env{'environment.inststatus'});
        !          1087:                             }
        !          1088:                             my $user = $env{'user.name'}.':'.$env{'user.domain'};
        !          1089:                             foreach my $role (@roles_by_num) {
        !          1090:                                 my ($curraccess,@okstatus,@personnel);
        !          1091:                                 if ($setincrs{$role}) {
        !          1092:                                     ($curraccess,my $rest) = split(/=/,$settings{'internal.adhoc.'.$role});
        !          1093:                                     if ($curraccess eq 'none') {
        !          1094:                                         next;
        !          1095:                                     } elsif ($curraccess eq 'all') {
        !          1096:                                         push(@okroles,$role);
        !          1097:                                     } elsif ($curraccess eq 'status') {
        !          1098:                                         @okstatus = split(/\&/,$rest);
        !          1099:                                     } elsif (($curraccess eq 'exc') || ($curraccess eq 'inc')) {
        !          1100:                                         @personnel = split(/\&/,$rest);
        !          1101:                                     }
        !          1102:                                 } else {
        !          1103:                                     $curraccess = $access_in_dom{$role};
        !          1104:                                     if ($curraccess eq 'status') {
        !          1105:                                         if (ref($domcurrent{$role}{$curraccess}) eq 'ARRAY') {
        !          1106:                                             @okstatus = @{$domcurrent{$role}{$curraccess}};
        !          1107:                                         }
        !          1108:                                     } elsif (($curraccess eq 'exc') || ($curraccess eq 'inc')) {
        !          1109:                                         if (ref($domcurrent{$role}{$curraccess}) eq 'ARRAY') {
        !          1110:                                             @personnel = @{$domcurrent{$role}{$curraccess}};
        !          1111:                                         }
        !          1112:                                     }
        !          1113:                                 }
        !          1114:                                 if ($curraccess eq 'none') {
        !          1115:                                     next;
        !          1116:                                 } elsif ($curraccess eq 'all') {
        !          1117:                                     push(@okroles,$role);
        !          1118:                                 } elsif ($curraccess eq 'status') {
        !          1119:                                     if (@okstatus) {
        !          1120:                                         if (!@statuses) {
        !          1121:                                             if (grep(/^default$/,@okstatus)) {
        !          1122:                                                 push(@okroles,$role);
        !          1123:                                             }
        !          1124:                                         } else {
        !          1125:                                             foreach my $status (@okstatus) {
        !          1126:                                                 if (grep(/^\Q$status\E$/,@statuses)) {
        !          1127:                                                     push(@okroles,$role);
        !          1128:                                                     last;
        !          1129:                                                 }
        !          1130:                                             }
        !          1131:                                         }
        !          1132:                                     }
        !          1133:                                 } elsif (($curraccess eq 'exc') || ($curraccess eq 'inc')) {
        !          1134:                                     if (grep(/^\Q$user\E$/,@personnel)) {
        !          1135:                                         if ($curraccess eq 'exc') {
        !          1136:                                             push(@okroles,$role);
        !          1137:                                         }
        !          1138:                                     } elsif ($curraccess eq 'inc') {
        !          1139:                                         push(@okroles,$role);
        !          1140:                                     }
        !          1141:                                 }
        !          1142:                             }
        !          1143:                         }
        !          1144:                     }
        !          1145:                 }
        !          1146:             }
        !          1147:         }
        !          1148:     }
        !          1149: 
        !          1150:     my $response = [];
        !          1151:     if (@okroles) {
        !          1152:         foreach my $role (@okroles) {
        !          1153:             push(@{$response},
        !          1154:                               { name => $role,
        !          1155:                                 desc => $description{$role},
        !          1156:                               });
        !          1157:         }
        !          1158:     }
        !          1159:     my $json = JSON::DWIW->to_json({roles => $response});
        !          1160:     return $json;
1.54      raeburn  1161: }
                   1162: 
1.55      raeburn  1163: 1;
                   1164: __END__
                   1165: 
                   1166: =pod
                   1167: 
                   1168: =head1 NAME
                   1169: 
                   1170: Apache::lonpickcourse - Search for course(s) based on user-specified criteria.   
                   1171: 
                   1172: =head1 SYNOPSIS
                   1173: 
                   1174: Invoked by other LON-CAPA modules, when course(s) need to be selected by the user. 
                   1175: 
                   1176: =head1 OVERVIEW
                   1177: 
                   1178: Two screens are typically displayed to the user.  The first is a set of criteria which are used to constrain the search for courses.
                   1179: 
                   1180: =head2 Search Criteria (Screen One)
                   1181: 
                   1182: =head3 Criteria:
                   1183: 
                   1184: =over 4
                   1185: 
                   1186: =item *
                   1187: Course Activity - how recently was course last visited by anyone.
                   1188: 
                   1189: =item *
                   1190: Course Domain - the domain of the course
                   1191: 
                   1192: =item *
1.117     raeburn  1193: Type - Course, Community or Placement
1.55      raeburn  1194: 
                   1195: =item *
                   1196: Course Institutional Code - the institutional identifier assigned to the course
                   1197: 
                   1198: =item * 
                   1199: Course Owner's Username - the username of the owner of the course (assigned by the Domain Coordinator and/or when the course was created).
                   1200: 
                   1201: =item *
                   1202: Course Owner's Domain - the domain of the owner of the course
                   1203: 
                   1204: =item * 
1.76      bisitz   1205: Course Title - text which appears in the Course Title, as set in the Course Parameters.
1.55      raeburn  1206: 
                   1207: =item *
                   1208: Course ID - the internal course number (course ID part after initial 'domain_') used by LON-CAPA (this criterion is only displayed to Domain Coordinators selecting a course in the same domain as their DC role).
                   1209: 
                   1210: =back
                   1211: 
                   1212: The criteria setting screen is not displayed if course picking is done by a user who does not have advanced privileges (as defined by $env{'user.adv'}).
                   1213: 
                   1214: =head2 Course Display (Screen Two)
                   1215: 
                   1216: A list of courses matching the search criteria is displayed.  If the user is not an advanced user, screen one will have been skipped and the courses displayed will be all courses in which the user has currently active roles. The information displayed for each course is:
                   1217: 
                   1218: =over 4
                   1219: 
                   1220: =item *
                   1221: Course description
                   1222: 
                   1223: =item *
                   1224: Domain description of course domain
                   1225: 
                   1226: =item *
                   1227: Course institutional code
                   1228: 
                   1229: =item * 
                   1230: Course owner (username:domain)   
                   1231:  
                   1232: =back
                   1233: 
                   1234: Depending on context, the display may include a single select box for each course, allowing selection of only a single course, or may include checkboxes allowing selection of more than one course.
                   1235: 
                   1236: Following selection, and/or submission, the course description, number and domain are transferred to the browser window from which the course picker window was opened.  In most cases, the child window containing the course picker screens will be closed.  However, in some cases closure will be delayed until a third screen has been displayed (e.g., setting of course-based conditional access controls for portfolio files).  In this case the page is generated via /adm/portfolio and the page features select boxes to allow the user to select roles, access types, sections and groups.
                   1237: 
                   1238: =head1 SUBROUTINES
                   1239: 
                   1240: =over 4
                   1241: 
                   1242: =item *
                   1243: X<create_user_javascript()>
                   1244: B<create_user_javascript($type)>:
                   1245: 
1.117     raeburn  1246: Input: 1 - $type  - the course type - Course, Community, or Placement
1.55      raeburn  1247: 
                   1248: Output: 1 - $output - javascript wrapped in E<lt>scriptE<gt>E<lt>/scriptE<gt> tags 
                   1249: 
                   1250: Side Effects: None 
                   1251: 
                   1252: javascript code for reporting selected sections (as a string of comma separated sections) and groups in the selected course (as a comma separated list) then calling setSect() javscript function in the opener window (to populate section select box) then closing current window.
                   1253: 
                   1254: 
                   1255: =item *
                   1256: X<display_matched_courses()>
1.116     raeburn  1257: B<display_matched_courses($r,$type,$multiple,$action,$showroles,$cloneruname,$clonerudom,$crsdom,$crscode,%courses)>:
1.55      raeburn  1258: 
1.116     raeburn  1259: Input: 8 - request object, course type, multiple (0 or 1), form action, whether to show roles (for course personnel filter), username of new course owner, domain of new course owner, domain of new course, institutional code of new course, hash of courses.
1.55      raeburn  1260: 
                   1261: Output: 0
                   1262: 
                   1263: Side Effects: prints select buttons (multiple = 0) or checkboxes (multiple = 1) and hidden form elements for selection of one or more courses which met search criteria.
                   1264: 
                   1265: =item *
                   1266: X<multiples_tag()>
                   1267: B<multiples_tag()>:
                   1268: 
                   1269: 
                   1270: Input: 0
                   1271: 
                   1272: Output: 2 - $jscript - javascript for check all/uncheck all checkboxes; $multelement - hidden form element with multiple set to 1.
                   1273: 
                   1274: Side Effects: None
                   1275: 
                   1276: 
                   1277: =item *
                   1278: X<course_chooser()>
1.85      raeburn  1279: B<course_chooser($multiple,$cdom,$cnum,$cleandesc,$canclone)>:
1.55      raeburn  1280: 
1.85      raeburn  1281: Input: 5 - single (0) or multiple (1) courses; course domain, course number; course description; can clone course (1 if new course owner has cloning rights). 
1.55      raeburn  1282: 
1.85      raeburn  1283: Output: 1 - HTML for either checkbox (multiple=1) or select button (multiple=0) for user to indicate course selection.
1.55      raeburn  1284: 
                   1285: Side Effects: None
                   1286: 
                   1287: 
                   1288: =item *
                   1289: X<gochoose_javascript()>
1.123   ! raeburn  1290: B<gochoose_javascript($type,$multiple,$autosubmit,$lastaction,$rolename)>:
1.55      raeburn  1291: 
1.123   ! raeburn  1292: Input: 5 - course type; single (0) or multiple courses (1); in context of DC selecting a CC role in a course: javascript code from &processpick(); final action to take after user chooses course(s):  either close window, or submit form for display of next page etc.; rolename (e.g., dh) of user's current role.
1.55      raeburn  1293: 
                   1294: Output: 1  $output - javascript wrapped in E<lt>scriptE<gt>E<lt>/scriptE<gt> tags
                   1295: 
                   1296: Side Effects: None
                   1297: 
                   1298: javascript functions used when user selects a course(s). Different behavior depending on context:
                   1299: 
                   1300: =back
                   1301: 
                   1302: =over 8
                   1303: 
                   1304: =item
                   1305: 
                   1306: (a) Domain Coordinator using MAIL to select recipients of broadcast e-mail - && separated list of selected courses written to hidden form element in opener window. Child window closes.
                   1307: 
                   1308: =item
                   1309: 
                   1310: (b) Domain Coordinator choosing a course for adoption of a CC role from roles screen - write course identifying information to hidden form elements in opener window and automatically submit role selection form in opener window. Child window closes.
                   1311: 
                   1312: =item
                   1313: 
                   1314: (c) Domain Coordinator creating a course, and selecting a course to clone - course number and domain written to visible form elements in opener window. Child window closes.
                   1315: 
                   1316: =item
1.54      raeburn  1317: 
1.55      raeburn  1318: (d) User selecting a course for course-based conditional access control for a portfolio file - form is submitted, and new page is displayed for selection of roles, access types, sections and groups to be used in conditional ACL. New page is generated by /adm/portfolio. 
1.54      raeburn  1319: 
1.55      raeburn  1320: =item
1.54      raeburn  1321: 
1.55      raeburn  1322: (e) Domain Coordinator assigning a role to a user - form is submitted, and new page does an onload call to a javascript function to (a) write lists of sections and groups to hidden elements in opener window, (b) call function in opener window to dynamically populate select box showing current sections.
1.54      raeburn  1323: 
1.55      raeburn  1324: =item
1.54      raeburn  1325: 
1.55      raeburn  1326: (f) Author modifying a rights entry in a .rights file - selected course number and domain are witten to visible form elements in opener window.  Child window closes. 
1.54      raeburn  1327: 
1.55      raeburn  1328: =item
1.49      raeburn  1329: 
1.102     bisitz   1330: (g) Bubblesheet Scanning Operator uploading a bubblesheet file to a course - course number is written to visible form element in opener window. Child window closes.
1.30      raeburn  1331: 
1.84      raeburn  1332: =item
                   1333: 
                   1334: (h) User requesting creation of a course, and selecting a course to clone - course number and domain written to visible form elements in opener window. Child window closes.
                   1335: 
1.55      raeburn  1336: =back
                   1337:      
                   1338: =cut

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