Annotation of loncom/interface/loncreateuser.pm, revision 1.366

1.20      harris41    1: # The LearningOnline Network with CAPA
1.1       www         2: # Create a user
                      3: #
1.366   ! bisitz      4: # $Id: loncreateuser.pm,v 1.365 2012/08/21 15:43:27 raeburn Exp $
1.22      albertel    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: #
1.20      harris41   28: ###
                     29: 
1.1       www        30: package Apache::loncreateuser;
1.66      bowersj2   31: 
                     32: =pod
                     33: 
                     34: =head1 NAME
                     35: 
1.263     jms        36: Apache::loncreateuser.pm
1.66      bowersj2   37: 
                     38: =head1 SYNOPSIS
                     39: 
1.263     jms        40:     Handler to create users and custom roles
                     41: 
                     42:     Provides an Apache handler for creating users,
1.66      bowersj2   43:     editing their login parameters, roles, and removing roles, and
                     44:     also creating and assigning custom roles.
                     45: 
                     46: =head1 OVERVIEW
                     47: 
                     48: =head2 Custom Roles
                     49: 
                     50: In LON-CAPA, roles are actually collections of privileges. "Teaching
                     51: Assistant", "Course Coordinator", and other such roles are really just
                     52: collection of privileges that are useful in many circumstances.
                     53: 
1.324     raeburn    54: Custom roles can be defined by a Domain Coordinator, Course Coordinator
                     55: or Community Coordinator via the Manage User functionality.
                     56: The custom role editor screen will show all privileges which can be
                     57: assigned to users. For a complete list of privileges, please see 
                     58: C</home/httpd/lonTabs/rolesplain.tab>.
1.66      bowersj2   59: 
1.324     raeburn    60: Custom role definitions are stored in the C<roles.db> file of the creator
                     61: of the role.
1.66      bowersj2   62: 
                     63: =cut
1.1       www        64: 
                     65: use strict;
                     66: use Apache::Constants qw(:common :http);
                     67: use Apache::lonnet;
1.54      bowersj2   68: use Apache::loncommon;
1.68      www        69: use Apache::lonlocal;
1.117     raeburn    70: use Apache::longroup;
1.190     raeburn    71: use Apache::lonuserutils;
1.307     raeburn    72: use Apache::loncoursequeueadmin;
1.139     albertel   73: use LONCAPA qw(:DEFAULT :match);
1.1       www        74: 
1.20      harris41   75: my $loginscript; # piece of javascript used in two separate instances
                     76: my $authformnop;
                     77: my $authformkrb;
                     78: my $authformint;
                     79: my $authformfsys;
                     80: my $authformloc;
                     81: 
1.94      matthew    82: sub initialize_authen_forms {
1.227     raeburn    83:     my ($dom,$formname,$curr_authtype,$mode) = @_;
                     84:     my ($krbdef,$krbdefdom) = &Apache::loncommon::get_kerberos_defaults($dom);
                     85:     my %param = ( formname => $formname,
1.187     raeburn    86:                   kerb_def_dom => $krbdefdom,
1.227     raeburn    87:                   kerb_def_auth => $krbdef,
1.187     raeburn    88:                   domain => $dom,
                     89:                 );
1.188     raeburn    90:     my %abv_auth = &auth_abbrev();
1.227     raeburn    91:     if ($curr_authtype =~ /^(krb4|krb5|internal|localauth|unix):(.*)$/) {
1.188     raeburn    92:         my $long_auth = $1;
1.227     raeburn    93:         my $curr_autharg = $2;
1.188     raeburn    94:         my %abv_auth = &auth_abbrev();
                     95:         $param{'curr_authtype'} = $abv_auth{$long_auth};
                     96:         if ($long_auth =~ /^krb(4|5)$/) {
                     97:             $param{'curr_kerb_ver'} = $1;
1.227     raeburn    98:             $param{'curr_autharg'} = $curr_autharg;
1.188     raeburn    99:         }
1.205     raeburn   100:         if ($mode eq 'modifyuser') {
                    101:             $param{'mode'} = $mode;
                    102:         }
1.187     raeburn   103:     }
1.227     raeburn   104:     $loginscript  = &Apache::loncommon::authform_header(%param);
                    105:     $authformkrb  = &Apache::loncommon::authform_kerberos(%param);
1.31      matthew   106:     $authformnop  = &Apache::loncommon::authform_nochange(%param);
                    107:     $authformint  = &Apache::loncommon::authform_internal(%param);
                    108:     $authformfsys = &Apache::loncommon::authform_filesystem(%param);
                    109:     $authformloc  = &Apache::loncommon::authform_local(%param);
1.20      harris41  110: }
                    111: 
1.188     raeburn   112: sub auth_abbrev {
                    113:     my %abv_auth = (
1.311     raeburn   114:                      krb5     => 'krb',
1.188     raeburn   115:                      krb4     => 'krb',
                    116:                      internal => 'int',
                    117:                      localuth => 'loc',
                    118:                      unix     => 'fsys',
                    119:                    );
                    120:     return %abv_auth;
                    121: }
1.43      www       122: 
1.134     raeburn   123: # ====================================================
                    124: 
                    125: sub portfolio_quota {
                    126:     my ($ccuname,$ccdomain) = @_;
                    127:     my %lt = &Apache::lonlocal::texthash(
1.267     raeburn   128:                    'usrt'      => "User Tools",
                    129:                    'disk'      => "Disk space allocated to user's portfolio files",
                    130:                    'cuqu'      => "Current quota",
                    131:                    'cust'      => "Custom quota",
                    132:                    'defa'      => "Default",
                    133:                    'chqu'      => "Change quota",
1.134     raeburn   134:     );
1.149     raeburn   135:     my ($currquota,$quotatype,$inststatus,$defquota) = 
                    136:         &Apache::loncommon::get_user_quota($ccuname,$ccdomain);
                    137:     my ($usertypes,$order) = &Apache::lonnet::retrieve_inst_usertypes($ccdomain);
                    138:     my ($longinsttype,$showquota,$custom_on,$custom_off,$defaultinfo);
                    139:     if ($inststatus ne '') {
                    140:         if ($usertypes->{$inststatus} ne '') {
                    141:             $longinsttype = $usertypes->{$inststatus};
                    142:         }
                    143:     }
                    144:     $custom_on = ' ';
                    145:     $custom_off = ' checked="checked" ';
                    146:     my $quota_javascript = <<"END_SCRIPT";
                    147: <script type="text/javascript">
1.301     bisitz    148: // <![CDATA[
1.149     raeburn   149: function quota_changes(caller) {
                    150:     if (caller == "custom") {
                    151:         if (document.cu.customquota[0].checked) {
                    152:             document.cu.portfolioquota.value = "";
                    153:         }
                    154:     }
                    155:     if (caller == "quota") {
                    156:         document.cu.customquota[1].checked = true;
                    157:     }
                    158: }
1.301     bisitz    159: // ]]>
1.149     raeburn   160: </script>
                    161: END_SCRIPT
                    162:     if ($quotatype eq 'custom') {
                    163:         $custom_on = $custom_off;
                    164:         $custom_off = ' ';
                    165:         $showquota = $currquota;
                    166:         if ($longinsttype eq '') {
1.230     bisitz    167:             $defaultinfo = &mt('For this user, the default quota would be [_1]'
                    168:                             .' Mb.',$defquota);
1.149     raeburn   169:         } else {
1.231     raeburn   170:             $defaultinfo = &mt("For this user, the default quota would be [_1]".
                    171:                                " Mb, as determined by the user's institutional".
                    172:                                " affiliation ([_2]).",$defquota,$longinsttype);
1.149     raeburn   173:         }
                    174:     } else {
                    175:         if ($longinsttype eq '') {
1.230     bisitz    176:             $defaultinfo = &mt('For this user, the default quota is [_1]'
                    177:                             .' Mb.',$defquota);
1.149     raeburn   178:         } else {
1.231     raeburn   179:             $defaultinfo = &mt("For this user, the default quota of [_1]".
                    180:                                " Mb, is determined by the user's institutional".
                    181:                                " affiliation ([_2]).",$defquota,$longinsttype);
1.149     raeburn   182:         }
                    183:     }
1.267     raeburn   184: 
                    185:     my $output = $quota_javascript."\n".
                    186:                  '<h3>'.$lt{'usrt'}.'</h3>'."\n".
                    187:                  &Apache::loncommon::start_data_table();
                    188: 
                    189:     if (&Apache::lonnet::allowed('mut',$ccdomain)) {
1.275     raeburn   190:         $output .= &build_tools_display($ccuname,$ccdomain,'tools');
1.267     raeburn   191:     }
                    192:     if (&Apache::lonnet::allowed('mpq',$ccdomain)) {
                    193:         $output .= '<tr class="LC_info_row">'."\n".
                    194:                    '    <td>'.$lt{'disk'}.'</td>'."\n".
                    195:                    '  </tr>'."\n".
                    196:                    &Apache::loncommon::start_data_table_row()."\n".
                    197:                    '  <td>'.$lt{'cuqu'}.': '.
                    198:                    $currquota.'&nbsp;Mb.&nbsp;&nbsp;'.
                    199:                    $defaultinfo.'</td>'."\n".
                    200:                    &Apache::loncommon::end_data_table_row()."\n".
                    201:                    &Apache::loncommon::start_data_table_row()."\n".
                    202:                    '  <td><span class="LC_nobreak">'.$lt{'chqu'}.
                    203:                    ': <label>'.
                    204:                    '<input type="radio" name="customquota" value="0" '.
                    205:                    $custom_off.' onchange="javascript:quota_changes('."'custom'".')"'.
                    206:                    ' />'.$lt{'defa'}.'&nbsp;('.$defquota.' Mb).</label>&nbsp;'.
                    207:                    '&nbsp;<label><input type="radio" name="customquota" value="1" '. 
                    208:                    $custom_on.'  onchange="javascript:quota_changes('."'custom'".')" />'.
                    209:                    $lt{'cust'}.':</label>&nbsp;'.
                    210:                    '<input type="text" name="portfolioquota" size ="5" value="'.
                    211:                    $showquota.'" onfocus="javascript:quota_changes('."'quota'".')" '.
                    212:                    '/>&nbsp;Mb</span></td>'."\n".
                    213:                    &Apache::loncommon::end_data_table_row()."\n";
                    214:     }  
                    215:     $output .= &Apache::loncommon::end_data_table();
1.134     raeburn   216:     return $output;
                    217: }
                    218: 
1.275     raeburn   219: sub build_tools_display {
                    220:     my ($ccuname,$ccdomain,$context) = @_;
1.306     raeburn   221:     my (@usertools,%userenv,$output,@options,%validations,%reqtitles,%reqdisplay,
1.332     raeburn   222:         $colspan,$isadv,%domconfig);
1.275     raeburn   223:     my %lt = &Apache::lonlocal::texthash (
                    224:                    'blog'       => "Personal User Blog",
                    225:                    'aboutme'    => "Personal Information Page",
1.361     raeburn   226:                    'webdav'     => "WebDAV access to authoring spaces (if SSL and author/co-author)",
1.275     raeburn   227:                    'portfolio'  => "Personal User Portfolio",
                    228:                    'avai'       => "Available",
                    229:                    'cusa'       => "availability",
                    230:                    'chse'       => "Change setting",
                    231:                    'usde'       => "Use default",
                    232:                    'uscu'       => "Use custom",
                    233:                    'official'   => 'Can request creation of official courses',
1.299     raeburn   234:                    'unofficial' => 'Can request creation of unofficial courses',
                    235:                    'community'  => 'Can request creation of communities',
1.362     raeburn   236:                    'requestauthor'  => 'Can request author space',
1.275     raeburn   237:     );
1.279     raeburn   238:     if ($context eq 'requestcourses') {
1.275     raeburn   239:         %userenv = &Apache::lonnet::userenvironment($ccdomain,$ccuname,
1.299     raeburn   240:                       'requestcourses.official','requestcourses.unofficial',
                    241:                       'requestcourses.community');
                    242:         @usertools = ('official','unofficial','community');
1.309     raeburn   243:         @options =('norequest','approval','autolimit','validate');
1.306     raeburn   244:         %validations = &Apache::lonnet::auto_courserequest_checks($ccdomain);
                    245:         %reqtitles = &courserequest_titles();
                    246:         %reqdisplay = &courserequest_display();
                    247:         $colspan = ' colspan="2"';
1.332     raeburn   248:         %domconfig =
                    249:             &Apache::lonnet::get_dom('configuration',['requestcourses'],$ccdomain);
                    250:         $isadv = &Apache::lonnet::is_advanced_user($ccuname,$ccdomain);
1.362     raeburn   251:     } elsif ($context eq 'requestauthor') {
                    252:         %userenv = &Apache::lonnet::userenvironment($ccdomain,$ccuname,
                    253:                                                     'requestauthor');
                    254:         @usertools = ('requestauthor');
                    255:         @options =('norequest','approval','automatic');
                    256:         %reqtitles = &requestauthor_titles();
                    257:         %reqdisplay = &requestauthor_display();
                    258:         $colspan = ' colspan="2"';
                    259:         %domconfig =
                    260:             &Apache::lonnet::get_dom('configuration',['requestauthor'],$ccdomain);
1.275     raeburn   261:     } else {
                    262:         %userenv = &Apache::lonnet::userenvironment($ccdomain,$ccuname,
1.361     raeburn   263:                           'tools.aboutme','tools.portfolio','tools.blog',
                    264:                           'tools.webdav');
                    265:         @usertools = ('aboutme','blog','webdav','portfolio');
1.275     raeburn   266:     }
                    267:     foreach my $item (@usertools) {
1.306     raeburn   268:         my ($custom_access,$curr_access,$cust_on,$cust_off,$tool_on,$tool_off,
                    269:             $currdisp,$custdisp,$custradio);
1.275     raeburn   270:         $cust_off = 'checked="checked" ';
                    271:         $tool_on = 'checked="checked" ';
                    272:         $curr_access =  
                    273:             &Apache::lonnet::usertools_access($ccuname,$ccdomain,$item,undef,
                    274:                                               $context);
1.362     raeburn   275:         if ($context eq 'requestauthor') {
                    276:             if ($userenv{$context} ne '') {
                    277:                 $cust_on = ' checked="checked" ';
                    278:                 $cust_off = '';
                    279:             }  
                    280:         } elsif ($userenv{$context.'.'.$item} ne '') {
1.306     raeburn   281:             $cust_on = ' checked="checked" ';
                    282:             $cust_off = '';
                    283:         }
                    284:         if ($context eq 'requestcourses') {
                    285:             if ($userenv{$context.'.'.$item} eq '') {
1.314     raeburn   286:                 $custom_access = &mt('Currently from default setting.');
1.306     raeburn   287:             } else {
                    288:                 $custom_access = &mt('Currently from custom setting.');
1.275     raeburn   289:             }
1.362     raeburn   290:         } elsif ($context eq 'requestauthor') {
                    291:             if ($userenv{$context} eq '') {
                    292:                 $custom_access = &mt('Currently from default setting.');
                    293:             } else {
                    294:                 $custom_access = &mt('Currently from custom setting.');
                    295:             }
1.275     raeburn   296:         } else {
1.306     raeburn   297:             if ($userenv{$context.'.'.$item} eq '') {
1.314     raeburn   298:                 $custom_access =
1.306     raeburn   299:                     &mt('Availability determined currently from default setting.');
                    300:                 if (!$curr_access) {
                    301:                     $tool_off = 'checked="checked" ';
                    302:                     $tool_on = '';
                    303:                 }
                    304:             } else {
1.314     raeburn   305:                 $custom_access =
1.306     raeburn   306:                     &mt('Availability determined currently from custom setting.');
                    307:                 if ($userenv{$context.'.'.$item} == 0) {
                    308:                     $tool_off = 'checked="checked" ';
                    309:                     $tool_on = '';
                    310:                 }
1.275     raeburn   311:             }
                    312:         }
                    313:         $output .= '  <tr class="LC_info_row">'."\n".
1.306     raeburn   314:                    '   <td'.$colspan.'>'.$lt{$item}.'</td>'."\n".
1.275     raeburn   315:                    '  </tr>'."\n".
1.306     raeburn   316:                    &Apache::loncommon::start_data_table_row()."\n";
1.362     raeburn   317:         if (($context eq 'requestcourses') || ($context eq 'requestauthor')) {
1.306     raeburn   318:             my ($curroption,$currlimit);
1.362     raeburn   319:             my $envkey = $context.'.'.$item;
                    320:             if ($context eq 'requestauthor') {
                    321:                 $envkey = $context;
                    322:             }
                    323:             if ($userenv{$envkey} ne '') {
                    324:                 $curroption = $userenv{$envkey};
1.332     raeburn   325:             } else {
                    326:                 my (@inststatuses);
1.362     raeburn   327:                 if ($context eq 'requestcourses') {
                    328:                     $curroption =
                    329:                         &Apache::loncoursequeueadmin::get_processtype('course',$ccuname,$ccdomain,
                    330:                                                                       $isadv,$ccdomain,$item,
                    331:                                                                       \@inststatuses,\%domconfig);
                    332:                 } else {
                    333:                      $curroption = 
                    334:                          &Apache::loncoursequeueadmin::get_processtype('requestauthor',$ccuname,$ccdomain,
                    335:                                                                        $isadv,$ccdomain,undef,
                    336:                                                                        \@inststatuses,\%domconfig);
                    337:                 }
1.332     raeburn   338:             }
1.306     raeburn   339:             if (!$curroption) {
                    340:                 $curroption = 'norequest';
                    341:             }
                    342:             if ($curroption =~ /^autolimit=(\d*)$/) {
                    343:                 $currlimit = $1;
1.314     raeburn   344:                 if ($currlimit eq '') {
                    345:                     $currdisp = &mt('Yes, automatic creation');
                    346:                 } else {
                    347:                     $currdisp = &mt('Yes, up to [quant,_1,request]/user',$currlimit);
                    348:                 }
1.306     raeburn   349:             } else {
                    350:                 $currdisp = $reqdisplay{$curroption};
                    351:             }
                    352:             $custdisp = '<table>';
                    353:             foreach my $option (@options) {
                    354:                 my $val = $option;
                    355:                 if ($option eq 'norequest') {
                    356:                     $val = 0;
                    357:                 }
                    358:                 if ($option eq 'validate') {
                    359:                     my $canvalidate = 0;
                    360:                     if (ref($validations{$item}) eq 'HASH') {
                    361:                         if ($validations{$item}{'_custom_'}) {
                    362:                             $canvalidate = 1;
                    363:                         }
                    364:                     }
                    365:                     next if (!$canvalidate);
                    366:                 }
                    367:                 my $checked = '';
                    368:                 if ($option eq $curroption) {
                    369:                     $checked = ' checked="checked"';
                    370:                 } elsif ($option eq 'autolimit') {
                    371:                     if ($curroption =~ /^autolimit/) {
                    372:                         $checked = ' checked="checked"';
                    373:                     }
                    374:                 }
1.362     raeburn   375:                 my $name = 'crsreq_'.$item;
                    376:                 if ($context eq 'requestauthor') {
                    377:                     $name = $item;
                    378:                 }
1.306     raeburn   379:                 $custdisp .= '<tr><td><span class="LC_nobreak"><label>'.
1.362     raeburn   380:                              '<input type="radio" name="'.$name.'" '.
                    381:                              'value="'.$val.'"'.$checked.' />'.
1.306     raeburn   382:                              $reqtitles{$option}.'</label>&nbsp;';
                    383:                 if ($option eq 'autolimit') {
1.362     raeburn   384:                     $custdisp .= '<input type="text" name="'.$name.
                    385:                                  '_limit" size="1" '.
1.314     raeburn   386:                                  'value="'.$currlimit.'" /></span><br />'.
                    387:                                  $reqtitles{'unlimited'};
1.362     raeburn   388:                 } else {
                    389:                     $custdisp .= '</span>';
                    390:                 }
                    391:                 $custdisp .= '</td></tr>';
1.306     raeburn   392:             }
                    393:             $custdisp .= '</table>';
                    394:             $custradio = '</span></td><td>'.&mt('Custom setting').'<br />'.$custdisp;
                    395:         } else {
                    396:             $currdisp = ($curr_access?&mt('Yes'):&mt('No'));
1.362     raeburn   397:             my $name = $context.'_'.$item;
                    398:             if ($context eq 'requestauthor') {
                    399:                 $name = $context;
                    400:             }
1.306     raeburn   401:             $custdisp = '<span class="LC_nobreak"><label>'.
1.362     raeburn   402:                         '<input type="radio" name="'.$name.'"'.
1.361     raeburn   403:                         ' value="1" '.$tool_on.'/>'.&mt('On').'</label>&nbsp;<label>'.
1.362     raeburn   404:                         '<input type="radio" name="'.$name.'" value="0" '.
1.306     raeburn   405:                         $tool_off.'/>'.&mt('Off').'</label></span>';
                    406:             $custradio = ('&nbsp;'x2).'--'.$lt{'cusa'}.':&nbsp;'.$custdisp.
                    407:                           '</span>';
                    408:         }
                    409:         $output .= '  <td'.$colspan.'>'.$custom_access.('&nbsp;'x4).
                    410:                    $lt{'avai'}.': '.$currdisp.'</td>'."\n".
1.275     raeburn   411:                    &Apache::loncommon::end_data_table_row()."\n".
                    412:                    &Apache::loncommon::start_data_table_row()."\n".
1.306     raeburn   413:                    '  <td style="vertical-align:top;"><span class="LC_nobreak">'.
                    414:                    $lt{'chse'}.': <label>'.
1.275     raeburn   415:                    '<input type="radio" name="custom'.$item.'" value="0" '.
1.306     raeburn   416:                    $cust_off.'/>'.$lt{'usde'}.'</label>'.('&nbsp;' x3).
                    417:                    '<label><input type="radio" name="custom'.$item.'" value="1" '.
                    418:                    $cust_on.'/>'.$lt{'uscu'}.'</label>'.$custradio.'</td>'.
1.275     raeburn   419:                    &Apache::loncommon::end_data_table_row()."\n";
                    420:     }
                    421:     return $output;
                    422: }
                    423: 
1.300     raeburn   424: sub coursereq_externaluser {
                    425:     my ($ccuname,$ccdomain,$cdom) = @_;
1.306     raeburn   426:     my (@usertools,@options,%validations,%userenv,$output);
1.300     raeburn   427:     my %lt = &Apache::lonlocal::texthash (
                    428:                    'official'   => 'Can request creation of official courses',
                    429:                    'unofficial' => 'Can request creation of unofficial courses',
                    430:                    'community'  => 'Can request creation of communities',
                    431:     );
                    432: 
                    433:     %userenv = &Apache::lonnet::userenvironment($ccdomain,$ccuname,
                    434:                       'reqcrsotherdom.official','reqcrsotherdom.unofficial',
                    435:                       'reqcrsotherdom.community');
                    436:     @usertools = ('official','unofficial','community');
1.309     raeburn   437:     @options = ('approval','validate','autolimit');
1.306     raeburn   438:     %validations = &Apache::lonnet::auto_courserequest_checks($cdom);
                    439:     my $optregex = join('|',@options);
                    440:     my %reqtitles = &courserequest_titles();
1.300     raeburn   441:     foreach my $item (@usertools) {
1.306     raeburn   442:         my ($curroption,$currlimit,$tooloff);
1.300     raeburn   443:         if ($userenv{'reqcrsotherdom.'.$item} ne '') {
                    444:             my @curr = split(',',$userenv{'reqcrsotherdom.'.$item});
1.314     raeburn   445:             foreach my $req (@curr) {
                    446:                 if ($req =~ /^\Q$cdom\E\:($optregex)=?(\d*)$/) {
                    447:                     $curroption = $1;
                    448:                     $currlimit = $2;
                    449:                     last;
1.306     raeburn   450:                 }
                    451:             }
1.314     raeburn   452:             if (!$curroption) {
                    453:                 $curroption = 'norequest';
                    454:                 $tooloff = ' checked="checked"';
                    455:             }
1.306     raeburn   456:         } else {
                    457:             $curroption = 'norequest';
                    458:             $tooloff = ' checked="checked"';
                    459:         }
                    460:         $output.= &Apache::loncommon::start_data_table_row()."\n".
1.314     raeburn   461:                   '  <td><span class="LC_nobreak">'.$lt{$item}.': </span></td><td>'.
                    462:                   '<table><tr><td valign="top">'."\n".
1.306     raeburn   463:                   '<label><input type="radio" name="reqcrsotherdom_'.$item.
1.314     raeburn   464:                   '" value=""'.$tooloff.' />'.$reqtitles{'norequest'}.
                    465:                   '</label></td>';
1.306     raeburn   466:         foreach my $option (@options) {
                    467:             if ($option eq 'validate') {
                    468:                 my $canvalidate = 0;
                    469:                 if (ref($validations{$item}) eq 'HASH') {
                    470:                     if ($validations{$item}{'_external_'}) {
                    471:                         $canvalidate = 1;
                    472:                     }
                    473:                 }
                    474:                 next if (!$canvalidate);
                    475:             }
                    476:             my $checked = '';
                    477:             if ($option eq $curroption) {
                    478:                 $checked = ' checked="checked"';
                    479:             }
1.314     raeburn   480:             $output .= '<td valign="top"><span class="LC_nobreak"><label>'.
1.306     raeburn   481:                        '<input type="radio" name="reqcrsotherdom_'.$item.
                    482:                        '" value="'.$option.'"'.$checked.' />'.
1.314     raeburn   483:                        $reqtitles{$option}.'</label>';
1.306     raeburn   484:             if ($option eq 'autolimit') {
1.314     raeburn   485:                 $output .= '&nbsp;<input type="text" name="reqcrsotherdom_'.
1.306     raeburn   486:                            $item.'_limit" size="1" '.
1.314     raeburn   487:                            'value="'.$currlimit.'" /></span>'.
                    488:                            '<br />'.$reqtitles{'unlimited'};
                    489:             } else {
                    490:                 $output .= '</span>';
1.300     raeburn   491:             }
1.314     raeburn   492:             $output .= '</td>';
1.300     raeburn   493:         }
1.314     raeburn   494:         $output .= '</td></tr></table></td>'."\n".
1.300     raeburn   495:                    &Apache::loncommon::end_data_table_row()."\n";
                    496:     }
                    497:     return $output;
                    498: }
                    499: 
1.362     raeburn   500: sub domainrole_req {
                    501:     my ($ccuname,$ccdomain) = @_;
                    502:     return '<br /><h3>'.
                    503:            &mt('User Can Request Assignment of Domain Roles?').
                    504:            '</h3>'."\n".
                    505:            &Apache::loncommon::start_data_table().
                    506:            &build_tools_display($ccuname,$ccdomain,
                    507:                                 'requestauthor').
                    508:            &Apache::loncommon::end_data_table();
                    509: }
                    510: 
1.306     raeburn   511: sub courserequest_titles {
                    512:     my %titles = &Apache::lonlocal::texthash (
                    513:                                    official   => 'Official',
                    514:                                    unofficial => 'Unofficial',
                    515:                                    community  => 'Communities',
                    516:                                    norequest  => 'Not allowed',
1.309     raeburn   517:                                    approval   => 'Approval by Dom. Coord.',
1.306     raeburn   518:                                    validate   => 'With validation',
                    519:                                    autolimit  => 'Numerical limit',
1.314     raeburn   520:                                    unlimited  => '(blank for unlimited)',
1.306     raeburn   521:                  );
                    522:     return %titles;
                    523: }
                    524: 
                    525: sub courserequest_display {
                    526:     my %titles = &Apache::lonlocal::texthash (
1.309     raeburn   527:                                    approval   => 'Yes, need approval',
1.306     raeburn   528:                                    validate   => 'Yes, with validation',
                    529:                                    norequest  => 'No',
                    530:    );
                    531:    return %titles;
                    532: }
                    533: 
1.362     raeburn   534: sub requestauthor_titles {
                    535:     my %titles = &Apache::lonlocal::texthash (
                    536:                                    norequest  => 'Not allowed',
                    537:                                    approval   => 'Approval by Dom. Coord.',
                    538:                                    automatic  => 'Automatic approval',
                    539:                  );
                    540:     return %titles;
                    541: 
                    542: }
                    543: 
                    544: sub requestauthor_display {
                    545:     my %titles = &Apache::lonlocal::texthash (
                    546:                                    approval   => 'Yes, need approval',
                    547:                                    automatic  => 'Yes, automatic approval',
                    548:                                    norequest  => 'No',
                    549:    );
                    550:    return %titles;
                    551: }
                    552: 
                    553: sub curr_requestauthor {
                    554:     my ($uname,$udom,$isadv,$inststatuses,$domconfig) = @_;
                    555:     return unless ((ref($inststatuses) eq 'ARRAY') && (ref($domconfig) eq 'HASH'));
                    556:     if ($uname eq '' || $udom eq '') {
                    557:         $uname = $env{'user.name'};
                    558:         $udom = $env{'user.domain'};
                    559:         $isadv = $env{'user.adv'};
                    560:     }
                    561:     my (%userenv,%settings,$val);
                    562:     my @options = ('automatic','approval');
                    563:     %userenv =
                    564:         &Apache::lonnet::userenvironment($udom,$uname,'requestauthor','inststatus');
                    565:     if ($userenv{'requestauthor'}) {
                    566:         $val = $userenv{'requestauthor'};
                    567:         @{$inststatuses} = ('_custom_');
                    568:     } else {
                    569:         my %alltasks;
                    570:         if (ref($domconfig->{'requestauthor'}) eq 'HASH') {
                    571:             %settings = %{$domconfig->{'requestauthor'}};
                    572:             if (($isadv) && ($settings{'_LC_adv'} ne '')) {
                    573:                 $val = $settings{'_LC_adv'};
                    574:                 @{$inststatuses} = ('_LC_adv_');
                    575:             } else {
                    576:                 if ($userenv{'inststatus'} ne '') {
                    577:                     @{$inststatuses} = split(',',$userenv{'inststatus'});
                    578:                 } else {
                    579:                     @{$inststatuses} = ('default');
                    580:                 }
                    581:                 foreach my $status (@{$inststatuses}) {
                    582:                     if (exists($settings{$status})) {
                    583:                         my $value = $settings{$status};
                    584:                         next unless ($value);
                    585:                         unless (exists($alltasks{$value})) {
                    586:                             if (ref($alltasks{$value}) eq 'ARRAY') {
                    587:                                 unless(grep(/^\Q$status\E$/,@{$alltasks{$value}})) {
                    588:                                     push(@{$alltasks{$value}},$status);
                    589:                                 }
                    590:                             } else {
                    591:                                 @{$alltasks{$value}} = ($status);
                    592:                             }
                    593:                         }
                    594:                     }
                    595:                 }
                    596:                 foreach my $option (@options) {
                    597:                     if ($alltasks{$option}) {
                    598:                         $val = $option;
                    599:                         last;
                    600:                     }
                    601:                 }
                    602:             }
                    603:         }
                    604:     }
                    605:     return $val;
                    606: }
                    607: 
1.2       www       608: # =================================================================== Phase one
1.1       www       609: 
1.42      matthew   610: sub print_username_entry_form {
1.351     raeburn   611:     my ($r,$context,$response,$srch,$forcenewuser,$crstype,$brcrum) = @_;
1.101     albertel  612:     my $defdom=$env{'request.role.domain'};
1.160     raeburn   613:     my $formtoset = 'crtuser';
                    614:     if (exists($env{'form.startrolename'})) {
                    615:         $formtoset = 'docustom';
                    616:         $env{'form.rolename'} = $env{'form.startrolename'};
1.207     raeburn   617:     } elsif ($env{'form.origform'} eq 'crtusername') {
                    618:         $formtoset =  $env{'form.origform'};
1.160     raeburn   619:     }
                    620: 
                    621:     my ($jsback,$elements) = &crumb_utilities();
                    622: 
                    623:     my $jscript = &Apache::loncommon::studentbrowser_javascript()."\n".
1.165     albertel  624:         '<script type="text/javascript">'."\n".
1.301     bisitz    625:         '// <![CDATA['."\n".
                    626:         &Apache::lonhtmlcommon::set_form_elements($elements->{$formtoset})."\n".
                    627:         '// ]]>'."\n".
1.162     raeburn   628:         '</script>'."\n";
1.160     raeburn   629: 
1.324     raeburn   630:     my %existingroles=&Apache::lonuserutils::my_custom_roles($crstype);
                    631:     if (($env{'form.action'} eq 'custom') && (keys(%existingroles) > 0)
                    632:         && (&Apache::lonnet::allowed('mcr','/'))) {
                    633:         $jscript .= &customrole_javascript();
                    634:     }
1.224     raeburn   635:     my $helpitem = 'Course_Change_Privileges';
                    636:     if ($env{'form.action'} eq 'custom') {
                    637:         $helpitem = 'Course_Editing_Custom_Roles';
                    638:     } elsif ($env{'form.action'} eq 'singlestudent') {
                    639:         $helpitem = 'Course_Add_Student';
                    640:     }
1.351     raeburn   641:     my %breadcrumb_text = &singleuser_breadcrumb($crstype);
                    642:     if ($env{'form.action'} eq 'custom') {
                    643:         push(@{$brcrum},
                    644:                  {href=>"javascript:backPage(document.crtuser)",       
                    645:                   text=>"Pick custom role",
                    646:                   help => $helpitem,}
                    647:                  );
                    648:     } else {
                    649:         push (@{$brcrum},
                    650:                   {href => "javascript:backPage(document.crtuser)",
                    651:                    text => $breadcrumb_text{'search'},
                    652:                    help => $helpitem,
                    653:                    faq  => 282,
                    654:                    bug  => 'Instructor Interface',}
                    655:                   );
                    656:     }
                    657:     my %loaditems = (
                    658:                 'onload' => "javascript:setFormElements(document.$formtoset)",
                    659:                     );
                    660:     my $args = {bread_crumbs           => $brcrum,
                    661:                 bread_crumbs_component => 'User Management',
                    662:                 add_entries            => \%loaditems,};
                    663:     $r->print(&Apache::loncommon::start_page('User Management',$jscript,$args));
                    664: 
1.71      sakharuk  665:     my %lt=&Apache::lonlocal::texthash(
1.229     raeburn   666:                     'srst' => 'Search for a user and enroll as a student',
1.318     raeburn   667:                     'srme' => 'Search for a user and enroll as a member',
1.229     raeburn   668:                     'srad' => 'Search for a user and modify/add user information or roles',
1.71      sakharuk  669: 		    'usr'  => "Username",
                    670:                     'dom'  => "Domain",
1.324     raeburn   671:                     'ecrp' => "Define or Edit Custom Role",
                    672:                     'nr'   => "role name",
1.282     schafran  673:                     'cre'  => "Next",
1.71      sakharuk  674: 				       );
1.351     raeburn   675: 
1.214     raeburn   676:     if ($env{'form.action'} eq 'custom') {
1.190     raeburn   677:         if (&Apache::lonnet::allowed('mcr','/')) {
1.324     raeburn   678:             my $newroletext = &mt('Define new custom role:');
                    679:             $r->print('<form action="/adm/createuser" method="post" name="docustom">'.
                    680:                       '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />'.
                    681:                       '<input type="hidden" name="phase" value="selected_custom_edit" />'.
                    682:                       '<h3>'.$lt{'ecrp'}.'</h3>'.
                    683:                       &Apache::loncommon::start_data_table().
                    684:                       &Apache::loncommon::start_data_table_row().
                    685:                       '<td>');
                    686:             if (keys(%existingroles) > 0) {
                    687:                 $r->print('<br /><label><input type="radio" name="customroleaction" value="new" checked="checked" onclick="setCustomFields();" /><b>'.$newroletext.'</b></label>');
                    688:             } else {
                    689:                 $r->print('<br /><input type="hidden" name="customroleaction" value="new" /><b>'.$newroletext.'</b>');
                    690:             }
                    691:             $r->print('</td><td align="center">'.$lt{'nr'}.'<br /><input type="text" size="15" name="newrolename" onfocus="setCustomAction('."'new'".');" /></td>'.
                    692:                       &Apache::loncommon::end_data_table_row());
                    693:             if (keys(%existingroles) > 0) {
                    694:                 $r->print(&Apache::loncommon::start_data_table_row().'<td><br />'.
                    695:                           '<label><input type="radio" name="customroleaction" value="edit" onclick="setCustomFields();"/><b>'.
                    696:                           &mt('View/Modify existing role:').'</b></label></td>'.
                    697:                           '<td align="center"><br />'.
                    698:                           '<select name="rolename" onchange="setCustomAction('."'edit'".');">'.
1.326     raeburn   699:                           '<option value="" selected="selected">'.
1.324     raeburn   700:                           &mt('Select'));
                    701:                 foreach my $role (sort(keys(%existingroles))) {
1.326     raeburn   702:                     $r->print('<option value="'.$role.'">'.$role.'</option>');
1.324     raeburn   703:                 }
                    704:                 $r->print('</select>'.
                    705:                           '</td>'.
                    706:                           &Apache::loncommon::end_data_table_row());
                    707:             }
                    708:             $r->print(&Apache::loncommon::end_data_table().'<p>'.
                    709:                       '<input name="customeditor" type="submit" value="'.
                    710:                       $lt{'cre'}.'" /></p>'.
                    711:                       '</form>');
1.190     raeburn   712:         }
1.213     raeburn   713:     } else {
1.229     raeburn   714:         my $actiontext = $lt{'srad'};
1.213     raeburn   715:         if ($env{'form.action'} eq 'singlestudent') {
1.318     raeburn   716:             if ($crstype eq 'Community') {
                    717:                 $actiontext = $lt{'srme'};
                    718:             } else {
                    719:                 $actiontext = $lt{'srst'};
                    720:             }
1.213     raeburn   721:         }
1.324     raeburn   722:         $r->print("<h3>$actiontext</h3>");
1.213     raeburn   723:         if ($env{'form.origform'} ne 'crtusername') {
                    724:             $r->print("\n".$response);
                    725:         }
1.318     raeburn   726:         $r->print(&entry_form($defdom,$srch,$forcenewuser,$context,$response,$crstype));
1.107     www       727:     }
1.110     albertel  728: }
                    729: 
1.324     raeburn   730: sub customrole_javascript {
                    731:     my $js = <<"END";
                    732: <script type="text/javascript">
                    733: // <![CDATA[
                    734: 
                    735: function setCustomFields() {
                    736:     if (document.docustom.customroleaction.length > 0) {
                    737:         for (var i=0; i<document.docustom.customroleaction.length; i++) {
                    738:             if (document.docustom.customroleaction[i].checked) {
                    739:                 if (document.docustom.customroleaction[i].value == 'new') {
                    740:                     document.docustom.rolename.selectedIndex = 0;
                    741:                 } else {
                    742:                     document.docustom.newrolename.value = '';
                    743:                 }
                    744:             }
                    745:         }
                    746:     }
                    747:     return;
                    748: }
                    749: 
                    750: function setCustomAction(caller) {
                    751:     if (document.docustom.customroleaction.length > 0) {
                    752:         for (var i=0; i<document.docustom.customroleaction.length; i++) {
                    753:             if (document.docustom.customroleaction[i].value == caller) {
                    754:                 document.docustom.customroleaction[i].checked = true;
                    755:             }
                    756:         }
                    757:     }
                    758:     setCustomFields();
                    759:     return;
                    760: }
                    761: 
                    762: // ]]>
                    763: </script>
                    764: END
                    765:     return $js;
                    766: }
                    767: 
1.160     raeburn   768: sub entry_form {
1.318     raeburn   769:     my ($dom,$srch,$forcenewuser,$context,$responsemsg,$crstype) = @_;
1.229     raeburn   770:     my ($usertype,$inexact);
1.214     raeburn   771:     if (ref($srch) eq 'HASH') {
                    772:         if (($srch->{'srchin'} eq 'dom') &&
                    773:             ($srch->{'srchby'} eq 'uname') &&
                    774:             ($srch->{'srchtype'} eq 'exact') &&
                    775:             ($srch->{'srchdomain'} ne '') &&
                    776:             ($srch->{'srchterm'} ne '')) {
1.353     raeburn   777:             my (%curr_rules,%got_rules);
1.214     raeburn   778:             my ($rules,$ruleorder) =
                    779:                 &Apache::lonnet::inst_userrules($srch->{'srchdomain'},'username');
1.353     raeburn   780:             $usertype = &Apache::lonuserutils::check_usertype($srch->{'srchdomain'},$srch->{'srchterm'},$rules,\%curr_rules,\%got_rules);
1.229     raeburn   781:         } else {
                    782:             $inexact = 1;
1.214     raeburn   783:         }
1.207     raeburn   784:     }
1.214     raeburn   785:     my $cancreate =
                    786:         &Apache::lonuserutils::can_create_user($dom,$context,$usertype);
1.160     raeburn   787:     my $userpicker = 
1.179     raeburn   788:        &Apache::loncommon::user_picker($dom,$srch,$forcenewuser,
1.214     raeburn   789:                                        'document.crtuser',$cancreate,$usertype);
1.160     raeburn   790:     my $srchbutton = &mt('Search');
1.229     raeburn   791:     if ($env{'form.action'} eq 'singlestudent') {
                    792:         $srchbutton = &mt('Search and Enroll');
                    793:     } elsif ($cancreate && $responsemsg ne '' && $inexact) {
                    794:         $srchbutton = &mt('Search or Add New User');
                    795:     }
1.207     raeburn   796:     my $output = <<"ENDBLOCK";
1.160     raeburn   797: <form action="/adm/createuser" method="post" name="crtuser">
1.190     raeburn   798: <input type="hidden" name="action" value="$env{'form.action'}" />
1.160     raeburn   799: <input type="hidden" name="phase" value="get_user_info" />
                    800: $userpicker
1.179     raeburn   801: <input name="userrole" type="button" value="$srchbutton" onclick="javascript:validateEntry(document.crtuser)" />
1.160     raeburn   802: </form>
1.207     raeburn   803: ENDBLOCK
1.229     raeburn   804:     if ($env{'form.phase'} eq '') {
1.207     raeburn   805:         my $defdom=$env{'request.role.domain'};
                    806:         my $domform = &Apache::loncommon::select_dom_form($defdom,'srchdomain');
                    807:         my %lt=&Apache::lonlocal::texthash(
1.229     raeburn   808:                   'enro' => 'Enroll one student',
1.318     raeburn   809:                   'enrm' => 'Enroll one member',
1.229     raeburn   810:                   'admo' => 'Add/modify a single user',
                    811:                   'crea' => 'create new user if required',
                    812:                   'uskn' => "username is known",
1.207     raeburn   813:                   'crnu' => 'Create a new user',
                    814:                   'usr'  => 'Username',
                    815:                   'dom'  => 'in domain',
1.229     raeburn   816:                   'enrl' => 'Enroll',
                    817:                   'cram'  => 'Create/Modify user',
1.207     raeburn   818:         );
1.229     raeburn   819:         my $sellink=&Apache::loncommon::selectstudent_link('crtusername','srchterm','srchdomain');
                    820:         my ($title,$buttontext,$showresponse);
1.318     raeburn   821:         if ($env{'form.action'} eq 'singlestudent') {
                    822:             if ($crstype eq 'Community') {
                    823:                 $title = $lt{'enrm'};
                    824:             } else {
                    825:                 $title = $lt{'enro'};
                    826:             }
1.229     raeburn   827:             $buttontext = $lt{'enrl'};
                    828:         } else {
                    829:             $title = $lt{'admo'};
                    830:             $buttontext = $lt{'cram'};
                    831:         }
                    832:         if ($cancreate) {
                    833:             $title .= ' <span class="LC_cusr_subheading">('.$lt{'crea'}.')</span>';
                    834:         } else {
                    835:             $title .= ' <span class="LC_cusr_subheading">('.$lt{'uskn'}.')</span>';
                    836:         }
                    837:         if ($env{'form.origform'} eq 'crtusername') {
                    838:             $showresponse = $responsemsg;
                    839:         }
1.207     raeburn   840:         $output .= <<"ENDDOCUMENT";
1.229     raeburn   841: <br />
1.207     raeburn   842: <form action="/adm/createuser" method="post" name="crtusername">
                    843: <input type="hidden" name="action" value="$env{'form.action'}" />
                    844: <input type="hidden" name="phase" value="createnewuser" />
                    845: <input type="hidden" name="srchtype" value="exact" />
1.233     raeburn   846: <input type="hidden" name="srchby" value="uname" />
1.207     raeburn   847: <input type="hidden" name="srchin" value="dom" />
                    848: <input type="hidden" name="forcenewuser" value="1" />
                    849: <input type="hidden" name="origform" value="crtusername" />
1.229     raeburn   850: <h3>$title</h3>
                    851: $showresponse
1.207     raeburn   852: <table>
                    853:  <tr>
                    854:   <td>$lt{'usr'}:</td>
                    855:   <td><input type="text" size="15" name="srchterm" /></td>
                    856:   <td>&nbsp;$lt{'dom'}:</td><td>$domform</td>
1.229     raeburn   857:   <td>&nbsp;$sellink&nbsp;</td>
                    858:   <td>&nbsp;<input name="userrole" type="submit" value="$buttontext" /></td>
1.207     raeburn   859:  </tr>
                    860: </table>
                    861: </form>
1.160     raeburn   862: ENDDOCUMENT
1.207     raeburn   863:     }
1.160     raeburn   864:     return $output;
                    865: }
1.110     albertel  866: 
                    867: sub user_modification_js {
1.113     raeburn   868:     my ($pjump_def,$dc_setcourse_code,$nondc_setsection_code,$groupslist)=@_;
                    869:     
1.110     albertel  870:     return <<END;
                    871: <script type="text/javascript" language="Javascript">
1.301     bisitz    872: // <![CDATA[
1.314     raeburn   873: 
1.110     albertel  874:     $pjump_def
                    875:     $dc_setcourse_code
                    876: 
                    877:     function dateset() {
                    878:         eval("document.cu."+document.cu.pres_marker.value+
                    879:             ".value=document.cu.pres_value.value");
1.359     www       880:         modalWindow.close();
1.110     albertel  881:     }
                    882: 
1.113     raeburn   883:     $nondc_setsection_code
1.301     bisitz    884: // ]]>
1.110     albertel  885: </script>
                    886: END
1.2       www       887: }
                    888: 
                    889: # =================================================================== Phase two
1.160     raeburn   890: sub print_user_selection_page {
1.351     raeburn   891:     my ($r,$response,$srch,$srch_results,$srcharray,$context,$opener_elements,$crstype,$brcrum) = @_;
1.160     raeburn   892:     my @fields = ('username','domain','lastname','firstname','permanentemail');
                    893:     my $sortby = $env{'form.sortby'};
                    894: 
                    895:     if (!grep(/^\Q$sortby\E$/,@fields)) {
                    896:         $sortby = 'lastname';
                    897:     }
                    898: 
                    899:     my ($jsback,$elements) = &crumb_utilities();
                    900: 
                    901:     my $jscript = (<<ENDSCRIPT);
                    902: <script type="text/javascript">
1.301     bisitz    903: // <![CDATA[
1.160     raeburn   904: function pickuser(uname,udom) {
                    905:     document.usersrchform.seluname.value=uname;
                    906:     document.usersrchform.seludom.value=udom;
                    907:     document.usersrchform.phase.value="userpicked";
                    908:     document.usersrchform.submit();
                    909: }
                    910: 
                    911: $jsback
1.301     bisitz    912: // ]]>
1.160     raeburn   913: </script>
                    914: ENDSCRIPT
                    915: 
                    916:     my %lt=&Apache::lonlocal::texthash(
1.179     raeburn   917:                                        'usrch'          => "User Search to add/modify roles",
                    918:                                        'stusrch'        => "User Search to enroll student",
1.318     raeburn   919:                                        'memsrch'        => "User Search to enroll member",
1.179     raeburn   920:                                        'usel'           => "Select a user to add/modify roles",
1.318     raeburn   921:                                        'stusel'         => "Select a user to enroll as a student",
                    922:                                        'memsel'         => "Select a user to enroll as a member",
1.160     raeburn   923:                                        'username'       => "username",
                    924:                                        'domain'         => "domain",
                    925:                                        'lastname'       => "last name",
                    926:                                        'firstname'      => "first name",
                    927:                                        'permanentemail' => "permanent e-mail",
                    928:                                       );
1.302     raeburn   929:     if ($context eq 'requestcrs') {
                    930:         $r->print('<div>');
                    931:     } else {
1.318     raeburn   932:         my %breadcrumb_text = &singleuser_breadcrumb($crstype);
1.351     raeburn   933:         my $helpitem;
                    934:         if ($env{'form.action'} eq 'singleuser') {
                    935:             $helpitem = 'Course_Change_Privileges';
                    936:         } elsif ($env{'form.action'} eq 'singlestudent') {
                    937:             $helpitem = 'Course_Add_Student';
                    938:         }
                    939:         push (@{$brcrum},
                    940:                   {href => "javascript:backPage(document.usersrchform,'','')",
                    941:                    text => $breadcrumb_text{'search'},
                    942:                    faq  => 282,
                    943:                    bug  => 'Instructor Interface',},
                    944:                   {href => "javascript:backPage(document.usersrchform,'get_user_info','select')",
                    945:                    text => $breadcrumb_text{'userpicked'},
                    946:                    faq  => 282,
                    947:                    bug  => 'Instructor Interface',
                    948:                    help => $helpitem}
                    949:                   );
                    950:         $r->print(&Apache::loncommon::start_page('User Management',$jscript,{bread_crumbs => $brcrum}));
1.302     raeburn   951:         if ($env{'form.action'} eq 'singleuser') {
                    952:             $r->print("<b>$lt{'usrch'}</b><br />");
1.318     raeburn   953:             $r->print(&entry_form($srch->{'srchdomain'},$srch,undef,$context,undef,$crstype));
1.302     raeburn   954:             $r->print('<h3>'.$lt{'usel'}.'</h3>');
                    955:         } elsif ($env{'form.action'} eq 'singlestudent') {
1.318     raeburn   956:             $r->print($jscript."<b>");
                    957:             if ($crstype eq 'Community') {
                    958:                 $r->print($lt{'memsrch'});
                    959:             } else {
                    960:                 $r->print($lt{'stusrch'});
                    961:             }
                    962:             $r->print("</b><br />");
                    963:             $r->print(&entry_form($srch->{'srchdomain'},$srch,undef,$context,undef,$crstype));
                    964:             $r->print('</form><h3>');
                    965:             if ($crstype eq 'Community') {
                    966:                 $r->print($lt{'memsel'});
                    967:             } else {
                    968:                 $r->print($lt{'stusel'});
                    969:             }
                    970:             $r->print('</h3>');
1.302     raeburn   971:         }
1.179     raeburn   972:     }
1.160     raeburn   973:     $r->print('<form name="usersrchform" method="post">'.
                    974:               &Apache::loncommon::start_data_table()."\n".
                    975:               &Apache::loncommon::start_data_table_header_row()."\n".
                    976:               ' <th> </th>'."\n");
                    977:     foreach my $field (@fields) {
                    978:         $r->print(' <th><a href="javascript:document.usersrchform.sortby.value='.
                    979:                   "'".$field."'".';document.usersrchform.submit();">'.
                    980:                   $lt{$field}.'</a></th>'."\n");
                    981:     }
                    982:     $r->print(&Apache::loncommon::end_data_table_header_row());
                    983: 
                    984:     my @sorted_users = sort {
1.167     albertel  985:         lc($srch_results->{$a}->{$sortby})   cmp lc($srch_results->{$b}->{$sortby})
1.160     raeburn   986:             ||
1.167     albertel  987:         lc($srch_results->{$a}->{lastname})  cmp lc($srch_results->{$b}->{lastname})
1.160     raeburn   988:             ||
                    989:         lc($srch_results->{$a}->{firstname}) cmp lc($srch_results->{$b}->{firstname})
1.167     albertel  990: 	    ||
                    991: 	lc($a) cmp lc($b)
1.160     raeburn   992:         } (keys(%$srch_results));
                    993: 
                    994:     foreach my $user (@sorted_users) {
                    995:         my ($uname,$udom) = split(/:/,$user);
1.302     raeburn   996:         my $onclick;
                    997:         if ($context eq 'requestcrs') {
1.314     raeburn   998:             $onclick =
1.302     raeburn   999:                 'onclick="javascript:gochoose('."'$uname','$udom',".
                   1000:                                                "'$srch_results->{$user}->{firstname}',".
                   1001:                                                "'$srch_results->{$user}->{lastname}',".
                   1002:                                                "'$srch_results->{$user}->{permanentemail}'".');"';
                   1003:         } else {
1.314     raeburn  1004:             $onclick =
1.302     raeburn  1005:                 ' onclick="javascript:pickuser('."'".$uname."'".','."'".$udom."'".');"';
                   1006:         }
1.160     raeburn  1007:         $r->print(&Apache::loncommon::start_data_table_row().
1.302     raeburn  1008:                   '<td><input type="button" name="seluser" value="'.&mt('Select').'" '.
                   1009:                   $onclick.' /></td>'.
1.160     raeburn  1010:                   '<td><tt>'.$uname.'</tt></td>'.
                   1011:                   '<td><tt>'.$udom.'</tt></td>');
                   1012:         foreach my $field ('lastname','firstname','permanentemail') {
                   1013:             $r->print('<td>'.$srch_results->{$user}->{$field}.'</td>');
                   1014:         }
                   1015:         $r->print(&Apache::loncommon::end_data_table_row());
                   1016:     }
                   1017:     $r->print(&Apache::loncommon::end_data_table().'<br /><br />');
1.179     raeburn  1018:     if (ref($srcharray) eq 'ARRAY') {
                   1019:         foreach my $item (@{$srcharray}) {
                   1020:             $r->print('<input type="hidden" name="'.$item.'" value="'.$env{'form.'.$item}.'" />'."\n");
                   1021:         }
                   1022:     }
1.160     raeburn  1023:     $r->print(' <input type="hidden" name="sortby" value="'.$sortby.'" />'."\n".
                   1024:               ' <input type="hidden" name="seluname" value="" />'."\n".
                   1025:               ' <input type="hidden" name="seludom" value="" />'."\n".
1.179     raeburn  1026:               ' <input type="hidden" name="currstate" value="select" />'."\n".
1.190     raeburn  1027:               ' <input type="hidden" name="phase" value="get_user_info" />'."\n".
1.214     raeburn  1028:               ' <input type="hidden" name="action" value="'.$env{'form.action'}.'" />'."\n");
1.302     raeburn  1029:     if ($context eq 'requestcrs') {
                   1030:         $r->print($opener_elements.'</form></div>');
                   1031:     } else {
1.351     raeburn  1032:         $r->print($response.'</form>');
1.302     raeburn  1033:     }
1.160     raeburn  1034: }
                   1035: 
                   1036: sub print_user_query_page {
1.351     raeburn  1037:     my ($r,$caller,$brcrum) = @_;
1.160     raeburn  1038: # FIXME - this is for a network-wide name search (similar to catalog search)
                   1039: # To use frames with similar behavior to catalog/portfolio search.
                   1040: # To be implemented. 
                   1041:     return;
                   1042: }
                   1043: 
1.42      matthew  1044: sub print_user_modification_page {
1.351     raeburn  1045:     my ($r,$ccuname,$ccdomain,$srch,$response,$context,$permission,$crstype,$brcrum) = @_;
1.185     raeburn  1046:     if (($ccuname eq '') || ($ccdomain eq '')) {
1.215     raeburn  1047:         my $usermsg = &mt('No username and/or domain provided.');
                   1048:         $env{'form.phase'} = '';
1.351     raeburn  1049: 	&print_username_entry_form($r,$context,$usermsg,'','',$crstype,$brcrum);
1.58      www      1050:         return;
                   1051:     }
1.213     raeburn  1052:     my ($form,$formname);
                   1053:     if ($env{'form.action'} eq 'singlestudent') {
                   1054:         $form = 'document.enrollstudent';
                   1055:         $formname = 'enrollstudent';
                   1056:     } else {
                   1057:         $form = 'document.cu';
                   1058:         $formname = 'cu';
                   1059:     }
1.188     raeburn  1060:     my %abv_auth = &auth_abbrev();
1.227     raeburn  1061:     my (%rulematch,%inst_results,$newuser,%alerts,%curr_rules,%got_rules);
1.185     raeburn  1062:     my $uhome=&Apache::lonnet::homeserver($ccuname,$ccdomain);
                   1063:     if ($uhome eq 'no_host') {
1.215     raeburn  1064:         my $usertype;
                   1065:         my ($rules,$ruleorder) =
                   1066:             &Apache::lonnet::inst_userrules($ccdomain,'username');
                   1067:             $usertype =
1.353     raeburn  1068:                 &Apache::lonuserutils::check_usertype($ccdomain,$ccuname,$rules,
1.362     raeburn  1069:                                                       \%curr_rules,\%got_rules);
1.215     raeburn  1070:         my $cancreate =
                   1071:             &Apache::lonuserutils::can_create_user($ccdomain,$context,
                   1072:                                                    $usertype);
                   1073:         if (!$cancreate) {
1.292     bisitz   1074:             my $helplink = 'javascript:helpMenu('."'display'".')';
1.215     raeburn  1075:             my %usertypetext = (
                   1076:                 official   => 'institutional',
                   1077:                 unofficial => 'non-institutional',
                   1078:             );
                   1079:             my $response;
                   1080:             if ($env{'form.origform'} eq 'crtusername') {
1.362     raeburn  1081:                 $response = '<span class="LC_warning">'.
                   1082:                             &mt('No match found for the username [_1] in LON-CAPA domain: [_2]',
                   1083:                                 '<b>'.$ccuname.'</b>',$ccdomain).
1.215     raeburn  1084:                             '</span><br />';
                   1085:             }
1.292     bisitz   1086:             $response .= '<p class="LC_warning">'
                   1087:                         .&mt("You are not authorized to create new $usertypetext{$usertype} users in this domain.")
                   1088:                         .' '
                   1089:                         .&mt('Please contact the [_1]helpdesk[_2] for assistance.'
                   1090:                             ,'<a href="'.$helplink.'">','</a>')
                   1091:                         .'</p><br />';
1.215     raeburn  1092:             $env{'form.phase'} = '';
1.351     raeburn  1093:             &print_username_entry_form($r,$context,$response,undef,undef,$crstype,$brcrum);
1.215     raeburn  1094:             return;
                   1095:         }
1.188     raeburn  1096:         $newuser = 1;
1.193     raeburn  1097:         my $checkhash;
                   1098:         my $checks = { 'username' => 1 };
1.196     raeburn  1099:         $checkhash->{$ccuname.':'.$ccdomain} = { 'newuser' => $newuser };
1.193     raeburn  1100:         &Apache::loncommon::user_rule_check($checkhash,$checks,
1.196     raeburn  1101:             \%alerts,\%rulematch,\%inst_results,\%curr_rules,\%got_rules);
                   1102:         if (ref($alerts{'username'}) eq 'HASH') {
                   1103:             if (ref($alerts{'username'}{$ccdomain}) eq 'HASH') {
                   1104:                 my $domdesc =
1.193     raeburn  1105:                     &Apache::lonnet::domain($ccdomain,'description');
1.196     raeburn  1106:                 if ($alerts{'username'}{$ccdomain}{$ccuname}) {
                   1107:                     my $userchkmsg;
                   1108:                     if (ref($curr_rules{$ccdomain}) eq 'HASH') {  
                   1109:                         $userchkmsg = 
                   1110:                             &Apache::loncommon::instrule_disallow_msg('username',
1.193     raeburn  1111:                                                                  $domdesc,1).
                   1112:                         &Apache::loncommon::user_rule_formats($ccdomain,
                   1113:                             $domdesc,$curr_rules{$ccdomain}{'username'},
                   1114:                             'username');
1.196     raeburn  1115:                     }
1.215     raeburn  1116:                     $env{'form.phase'} = '';
1.351     raeburn  1117:                     &print_username_entry_form($r,$context,$userchkmsg,undef,undef,$crstype,$brcrum);
1.196     raeburn  1118:                     return;
1.215     raeburn  1119:                 }
1.193     raeburn  1120:             }
1.185     raeburn  1121:         }
1.187     raeburn  1122:     } else {
1.188     raeburn  1123:         $newuser = 0;
1.185     raeburn  1124:     }
1.160     raeburn  1125:     if ($response) {
1.215     raeburn  1126:         $response = '<br />'.$response;
1.160     raeburn  1127:     }
1.149     raeburn  1128: 
1.52      matthew  1129:     my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();
1.88      raeburn  1130:     my $dc_setcourse_code = '';
1.119     raeburn  1131:     my $nondc_setsection_code = '';                                        
1.112     albertel 1132:     my %loaditem;
1.114     albertel 1133: 
1.216     raeburn  1134:     my $groupslist = &Apache::lonuserutils::get_groupslist();
1.88      raeburn  1135: 
1.216     raeburn  1136:     my $js = &validation_javascript($context,$ccdomain,$pjump_def,
                   1137:                                $groupslist,$newuser,$formname,\%loaditem);
1.318     raeburn  1138:     my %breadcrumb_text = &singleuser_breadcrumb($crstype);
1.224     raeburn  1139:     my $helpitem = 'Course_Change_Privileges';
                   1140:     if ($env{'form.action'} eq 'singlestudent') {
                   1141:         $helpitem = 'Course_Add_Student';
                   1142:     }
1.351     raeburn  1143:     push (@{$brcrum},
                   1144:         {href => "javascript:backPage($form)",
                   1145:          text => $breadcrumb_text{'search'},
                   1146:          faq  => 282,
                   1147:          bug  => 'Instructor Interface',});
                   1148:     if ($env{'form.phase'} eq 'userpicked') {
                   1149:        push(@{$brcrum},
                   1150:               {href => "javascript:backPage($form,'get_user_info','select')",
                   1151:                text => $breadcrumb_text{'userpicked'},
                   1152:                faq  => 282,
                   1153:                bug  => 'Instructor Interface',});
                   1154:     }
                   1155:     push(@{$brcrum},
                   1156:             {href => "javascript:backPage($form,'$env{'form.phase'}','modify')",
                   1157:              text => $breadcrumb_text{'modify'},
                   1158:              faq  => 282,
                   1159:              bug  => 'Instructor Interface',
                   1160:              help => $helpitem});
                   1161:     my $args = {'add_entries'           => \%loaditem,
                   1162:                 'bread_crumbs'          => $brcrum,
                   1163:                 'bread_crumbs_component' => 'User Management'};
                   1164:     if ($env{'form.popup'}) {
                   1165:         $args->{'no_nav_bar'} = 1;
                   1166:     }
                   1167:     my $start_page =
                   1168:         &Apache::loncommon::start_page('User Management',$js,$args);
1.3       www      1169: 
1.25      matthew  1170:     my $forminfo =<<"ENDFORMINFO";
1.216     raeburn  1171: <form action="/adm/createuser" method="post" name="$formname">
1.190     raeburn  1172: <input type="hidden" name="phase" value="update_user_data" />
1.188     raeburn  1173: <input type="hidden" name="ccuname" value="$ccuname" />
                   1174: <input type="hidden" name="ccdomain" value="$ccdomain" />
1.157     albertel 1175: <input type="hidden" name="pres_value"  value="" />
                   1176: <input type="hidden" name="pres_type"   value="" />
                   1177: <input type="hidden" name="pres_marker" value="" />
1.25      matthew  1178: ENDFORMINFO
1.329     raeburn  1179:     my (%inccourses,$roledom);
                   1180:     if ($context eq 'course') {
                   1181:         $inccourses{$env{'request.course.id'}}=1;
                   1182:         $roledom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   1183:     } elsif ($context eq 'author') {
                   1184:         $roledom = $env{'request.role.domain'};
                   1185:     } elsif ($context eq 'domain') {
                   1186:         foreach my $key (keys(%env)) {
                   1187:             $roledom = $env{'request.role.domain'};
                   1188:             if ($key=~/^user\.priv\.cm\.\/($roledom)\/($match_username)/) {
                   1189:                 $inccourses{$1.'_'.$2}=1;
                   1190:             }
                   1191:         }
                   1192:     } else {
                   1193:         foreach my $key (keys(%env)) {
                   1194: 	    if ($key=~/^user\.priv\.cm\.\/($match_domain)\/($match_username)/) {
                   1195: 	        $inccourses{$1.'_'.$2}=1;
                   1196:             }
1.2       www      1197:         }
1.24      matthew  1198:     }
1.216     raeburn  1199:     if ($newuser) {
1.362     raeburn  1200:         my ($portfolioform,$domroleform);
1.267     raeburn  1201:         if ((&Apache::lonnet::allowed('mpq',$env{'request.role.domain'})) ||
                   1202:             (&Apache::lonnet::allowed('mut',$env{'request.role.domain'}))) {
                   1203:             # Current user has quota or user tools modification privileges
1.188     raeburn  1204:             $portfolioform = '<br />'.&portfolio_quota($ccuname,$ccdomain);
1.134     raeburn  1205:         }
1.362     raeburn  1206:         if (&Apache::lonnet::allowed('cau',$env{'request.role.domain'})) {
                   1207:             $domroleform = '<br />'.&domainrole_req($ccuname,$ccdomain);
                   1208:         }
1.227     raeburn  1209:         &initialize_authen_forms($ccdomain,$formname);
1.188     raeburn  1210:         my %lt=&Apache::lonlocal::texthash(
                   1211:                 'cnu'            => 'Create New User',
1.213     raeburn  1212:                 'ast'            => 'as a student',
1.318     raeburn  1213:                 'ame'            => 'as a member',
1.188     raeburn  1214:                 'ind'            => 'in domain',
                   1215:                 'lg'             => 'Login Data',
1.190     raeburn  1216:                 'hs'             => "Home Server",
1.188     raeburn  1217:         );
1.185     raeburn  1218: 	$r->print(<<ENDTITLE);
1.110     albertel 1219: $start_page
1.160     raeburn  1220: $response
1.25      matthew  1221: $forminfo
1.31      matthew  1222: <script type="text/javascript" language="Javascript">
1.301     bisitz   1223: // <![CDATA[
1.20      harris41 1224: $loginscript
1.301     bisitz   1225: // ]]>
1.31      matthew  1226: </script>
1.20      harris41 1227: <input type='hidden' name='makeuser' value='1' />
1.216     raeburn  1228: <h2>$lt{'cnu'} "$ccuname" $lt{'ind'} $ccdomain
1.185     raeburn  1229: ENDTITLE
1.213     raeburn  1230:         if ($env{'form.action'} eq 'singlestudent') {
1.318     raeburn  1231:             if ($crstype eq 'Community') {
                   1232:                 $r->print(' ('.$lt{'ame'}.')');
                   1233:             } else {
                   1234:                 $r->print(' ('.$lt{'ast'}.')');
                   1235:             }
1.213     raeburn  1236:         }
                   1237:         $r->print('</h2>'."\n".'<div class="LC_left_float">');
1.206     raeburn  1238:         my $personal_table = 
1.210     raeburn  1239:             &personal_data_display($ccuname,$ccdomain,$newuser,$context,
                   1240:                                    $inst_results{$ccuname.':'.$ccdomain});
1.206     raeburn  1241:         $r->print($personal_table);
1.187     raeburn  1242:         my ($home_server_pick,$numlib) = 
                   1243:             &Apache::loncommon::home_server_form_item($ccdomain,'hserver',
                   1244:                                                       'default','hide');
                   1245:         if ($numlib > 1) {
                   1246:             $r->print("
1.185     raeburn  1247: <br />
1.187     raeburn  1248: $lt{'hs'}: $home_server_pick
                   1249: <br />");
                   1250:         } else {
                   1251:             $r->print($home_server_pick);
                   1252:         }
1.304     raeburn  1253:         if (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'})) {
1.362     raeburn  1254:             $r->print('<br /><h3>'.
                   1255:                       &mt('User Can Request Creation of Courses/Communities in this Domain?').'</h3>'.
1.304     raeburn  1256:                       &Apache::loncommon::start_data_table().
                   1257:                       &build_tools_display($ccuname,$ccdomain,
                   1258:                                            'requestcourses').
                   1259:                       &Apache::loncommon::end_data_table());
                   1260:         }
1.188     raeburn  1261:         $r->print('</div>'."\n".'<div class="LC_left_float"><h3>'.
                   1262:                   $lt{'lg'}.'</h3>');
1.185     raeburn  1263:         my ($fixedauth,$varauth,$authmsg); 
1.193     raeburn  1264:         if (ref($rulematch{$ccuname.':'.$ccdomain}) eq 'HASH') {
                   1265:             my $matchedrule = $rulematch{$ccuname.':'.$ccdomain}{'username'};
                   1266:             my ($rules,$ruleorder) = 
                   1267:                 &Apache::lonnet::inst_userrules($ccdomain,'username');
1.185     raeburn  1268:             if (ref($rules) eq 'HASH') {
1.193     raeburn  1269:                 if (ref($rules->{$matchedrule}) eq 'HASH') {
                   1270:                     my $authtype = $rules->{$matchedrule}{'authtype'};
1.185     raeburn  1271:                     if ($authtype !~ /^(krb4|krb5|int|fsys|loc)$/) {
1.190     raeburn  1272:                         $r->print(&Apache::lonuserutils::set_login($ccdomain,$authformkrb,$authformint,$authformloc));
1.275     raeburn  1273:                     } else { 
1.193     raeburn  1274:                         my $authparm = $rules->{$matchedrule}{'authparm'};
1.273     raeburn  1275:                         $authmsg = $rules->{$matchedrule}{'authmsg'};
1.185     raeburn  1276:                         if ($authtype =~ /^krb(4|5)$/) {
                   1277:                             my $ver = $1;
                   1278:                             if ($authparm ne '') {
                   1279:                                 $fixedauth = <<"KERB"; 
                   1280: <input type="hidden" name="login" value="krb" />
                   1281: <input type="hidden" name="krbver" value="$ver" />
                   1282: <input type="hidden" name="krbarg" value="$authparm" />
                   1283: KERB
                   1284:                             }
                   1285:                         } else {
                   1286:                             $fixedauth = 
                   1287: '<input type="hidden" name="login" value="'.$authtype.'" />'."\n";
1.193     raeburn  1288:                             if ($rules->{$matchedrule}{'authparmfixed'}) {
1.185     raeburn  1289:                                 $fixedauth .=    
                   1290: '<input type="hidden" name="'.$authtype.'arg" value="'.$authparm.'" />'."\n";
                   1291:                             } else {
1.273     raeburn  1292:                                 if ($authtype eq 'int') {
                   1293:                                     $varauth = '<br />'.
1.301     bisitz   1294: &mt('[_1] Internally authenticated (with initial password [_2])','','<input type="password" size="10" name="intarg" value="" />')."<label><input type=\"checkbox\" name=\"visible\" onclick='if (this.checked) { this.form.intarg.type=\"text\" } else { this.form.intarg.type=\"password\" }' />".&mt('Visible input').'</label>';
1.273     raeburn  1295:                                 } elsif ($authtype eq 'loc') {
                   1296:                                     $varauth = '<br />'.
                   1297: &mt('[_1] Local Authentication with argument [_2]','','<input type="text" name="'.$authtype.'arg" value="" />')."\n";
                   1298:                                 } else {
                   1299:                                     $varauth =
1.185     raeburn  1300: '<input type="text" name="'.$authtype.'arg" value="" />'."\n";
1.273     raeburn  1301:                                 }
1.185     raeburn  1302:                             }
                   1303:                         }
                   1304:                     }
                   1305:                 } else {
1.190     raeburn  1306:                     $r->print(&Apache::lonuserutils::set_login($ccdomain,$authformkrb,$authformint,$authformloc));
1.185     raeburn  1307:                 }
                   1308:             }
                   1309:             if ($authmsg) {
                   1310:                 $r->print(<<ENDAUTH);
                   1311: $fixedauth
                   1312: $authmsg
                   1313: $varauth
                   1314: ENDAUTH
                   1315:             }
                   1316:         } else {
1.190     raeburn  1317:             $r->print(&Apache::lonuserutils::set_login($ccdomain,$authformkrb,$authformint,$authformloc)); 
1.187     raeburn  1318:         }
1.362     raeburn  1319:         $r->print($portfolioform.$domroleform);
1.215     raeburn  1320:         if ($env{'form.action'} eq 'singlestudent') {
                   1321:             $r->print(&date_sections_select($context,$newuser,$formname,
                   1322:                                             $permission));
                   1323:         }
                   1324:         $r->print('</div><div class="LC_clear_float_footer"></div>');
1.216     raeburn  1325:     } else { # user already exists
1.79      albertel 1326: 	my %lt=&Apache::lonlocal::texthash(
1.191     raeburn  1327:                     'cup'  => "Modify existing user: ",
1.213     raeburn  1328:                     'ens'  => "Enroll one student: ",
1.318     raeburn  1329:                     'enm'  => "Enroll one member: ",
1.72      sakharuk 1330:                     'id'   => "in domain",
                   1331: 				       );
1.26      matthew  1332: 	$r->print(<<ENDCHANGEUSER);
1.110     albertel 1333: $start_page
1.25      matthew  1334: $forminfo
1.213     raeburn  1335: <h2>
1.26      matthew  1336: ENDCHANGEUSER
1.213     raeburn  1337:         if ($env{'form.action'} eq 'singlestudent') {
1.318     raeburn  1338:             if ($crstype eq 'Community') {
                   1339:                 $r->print($lt{'enm'});
                   1340:             } else {
                   1341:                 $r->print($lt{'ens'});
                   1342:             }
1.213     raeburn  1343:         } else {
                   1344:             $r->print($lt{'cup'});
                   1345:         }
                   1346:         $r->print(' "'.$ccuname.'" '.$lt{'id'}.' "'.$ccdomain.'"</h2>'.
                   1347:                   "\n".'<div class="LC_left_float">');
1.206     raeburn  1348:         my ($personal_table,$showforceid) = 
1.210     raeburn  1349:             &personal_data_display($ccuname,$ccdomain,$newuser,$context,
                   1350:                                    $inst_results{$ccuname.':'.$ccdomain});
1.206     raeburn  1351:         $r->print($personal_table);
                   1352:         if ($showforceid) {
1.362     raeburn  1353:             $r->print('<table>'.&Apache::lonuserutils::forceid_change($context).'</table>');
1.199     raeburn  1354:         }
1.275     raeburn  1355:         if (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'})) {
1.362     raeburn  1356:             $r->print('<br /><h3>'.&mt('User Can Request Creation of Courses/Communities in this Domain?').'</h3>'.
1.300     raeburn  1357:                       &Apache::loncommon::start_data_table());
1.314     raeburn  1358:             if ($env{'request.role.domain'} eq $ccdomain) {
1.300     raeburn  1359:                 $r->print(&build_tools_display($ccuname,$ccdomain,'requestcourses'));
                   1360:             } else {
                   1361:                 $r->print(&coursereq_externaluser($ccuname,$ccdomain,
                   1362:                                                   $env{'request.role.domain'}));
                   1363:             }
                   1364:             $r->print(&Apache::loncommon::end_data_table());
1.275     raeburn  1365:         }
1.199     raeburn  1366:         $r->print('</div>');
1.362     raeburn  1367:         my @order = ('auth','quota','tools','requestauthor');
                   1368:         my %user_text;
                   1369:         my ($isadv,$isauthor) = 
                   1370:             &Apache::lonnet::is_advanced_user($ccuname,$ccdomain);
                   1371:         if ((!$isauthor) && 
                   1372:             (&Apache::lonnet::allowed('cau',$env{'request.role.domain'}))) {
                   1373:             $user_text{'requestauthor'} = &domainrole_req($ccuname,$ccdomain);
                   1374:         }
                   1375:         $user_text{'auth'} =  &user_authentication($ccuname,$ccdomain,$formname);
1.267     raeburn  1376:         if ((&Apache::lonnet::allowed('mpq',$ccdomain)) ||
                   1377:             (&Apache::lonnet::allowed('mut',$ccdomain))) {
1.188     raeburn  1378:             # Current user has quota modification privileges
1.362     raeburn  1379:             $user_text{'quota'} = &portfolio_quota($ccuname,$ccdomain);
1.267     raeburn  1380:         }
                   1381:         if (!&Apache::lonnet::allowed('mpq',$ccdomain)) {
                   1382:             if (&Apache::lonnet::allowed('mpq',$env{'request.role.domain'})) {
                   1383:                 # Get the user's portfolio information
                   1384:                 my %portq = &Apache::lonnet::get('environment',['portfolioquota'],
                   1385:                                                  $ccdomain,$ccuname);
                   1386:                 my %lt=&Apache::lonlocal::texthash(
                   1387:                     'dska'  => "Disk space allocated to user's portfolio files",
                   1388:                     'youd'  => "You do not have privileges to modify the portfolio quota for this user.",
                   1389:                     'ichr'  => "If a change is required, contact a domain coordinator for the domain",
                   1390:                 );
1.362     raeburn  1391:                 $user_text{'quota'} = <<ENDNOPORTPRIV;
1.188     raeburn  1392: <h3>$lt{'dska'}</h3>
                   1393: $lt{'youd'} $lt{'ichr'}: $ccdomain
                   1394: ENDNOPORTPRIV
1.267     raeburn  1395:             }
                   1396:         }
                   1397:         if (!&Apache::lonnet::allowed('mut',$ccdomain)) {
                   1398:             if (&Apache::lonnet::allowed('mut',$env{'request.role.domain'})) {
                   1399:                 my %lt=&Apache::lonlocal::texthash(
                   1400:                     'utav'  => "User Tools Availability",
1.361     raeburn  1401:                     'yodo'  => "You do not have privileges to modify Portfolio, Blog, WebDAV, or Personal Information Page settings for this user.",
1.267     raeburn  1402:                     'ifch'  => "If a change is required, contact a domain coordinator for the domain",
                   1403:                 );
1.362     raeburn  1404:                 $user_text{'tools'} = <<ENDNOTOOLSPRIV;
1.267     raeburn  1405: <h3>$lt{'utav'}</h3>
                   1406: $lt{'yodo'} $lt{'ifch'}: $ccdomain
                   1407: ENDNOTOOLSPRIV
                   1408:             }
1.188     raeburn  1409:         }
1.362     raeburn  1410:         my $gotdiv = 0; 
                   1411:         foreach my $item (@order) {
                   1412:             if ($user_text{$item} ne '') {
                   1413:                 unless ($gotdiv) {
                   1414:                     $r->print('<div class="LC_left_float">');
                   1415:                     $gotdiv = 1;
                   1416:                 }
                   1417:                 $r->print('<br />'.$user_text{$item});
                   1418:             }
                   1419:         }
                   1420:         if ($env{'form.action'} eq 'singlestudent') {
                   1421:             unless ($gotdiv) {
                   1422:                 $r->print('<div class="LC_left_float">');
1.213     raeburn  1423:             }
1.362     raeburn  1424:             $r->print(&date_sections_select($context,$newuser,$formname));
                   1425:         } 
                   1426:         if ($gotdiv) {
                   1427:             $r->print('</div><div class="LC_clear_float_footer"></div>');
1.188     raeburn  1428:         }
1.217     raeburn  1429:         if ($env{'form.action'} ne 'singlestudent') {
1.329     raeburn  1430:             &display_existing_roles($r,$ccuname,$ccdomain,\%inccourses,$context,
                   1431:                                     $roledom,$crstype);
1.217     raeburn  1432:         }
1.25      matthew  1433:     } ## End of new user/old user logic
1.218     raeburn  1434:     if ($env{'form.action'} eq 'singlestudent') {
1.318     raeburn  1435:         my $btntxt;
                   1436:         if ($crstype eq 'Community') {
                   1437:             $btntxt = &mt('Enroll Member');
                   1438:         } else {
                   1439:             $btntxt = &mt('Enroll Student');
                   1440:         }
                   1441:         $r->print('<br /><input type="button" value="'.$btntxt.'" onclick="setSections(this.form)" />'."\n");
1.218     raeburn  1442:     } else {
                   1443:         $r->print('<h3>'.&mt('Add Roles').'</h3>');
                   1444:         my $addrolesdisplay = 0;
                   1445:         if ($context eq 'domain' || $context eq 'author') {
                   1446:             $addrolesdisplay = &new_coauthor_roles($r,$ccuname,$ccdomain);
                   1447:         }
                   1448:         if ($context eq 'domain') {
1.357     raeburn  1449:             my $add_domainroles = &new_domain_roles($r,$ccdomain);
1.218     raeburn  1450:             if (!$addrolesdisplay) {
                   1451:                 $addrolesdisplay = $add_domainroles;
1.2       www      1452:             }
1.218     raeburn  1453:             $r->print(&course_level_dc($env{'request.role.domain'},'Course'));
1.301     bisitz   1454:             $r->print('<br /><input type="button" value="'.&mt('Save').'" onclick="setCourse()" />'."\n");
1.218     raeburn  1455:         } elsif ($context eq 'author') {
                   1456:             if ($addrolesdisplay) {
1.262     schafran 1457:                 $r->print('<br /><input type="button" value="'.&mt('Save').'"');
1.218     raeburn  1458:                 if ($newuser) {
1.301     bisitz   1459:                     $r->print(' onclick="auth_check()" \>'."\n");
1.218     raeburn  1460:                 } else {
1.301     bisitz   1461:                     $r->print('onclick="this.form.submit()" \>'."\n");
1.218     raeburn  1462:                 }
1.188     raeburn  1463:             } else {
1.218     raeburn  1464:                 $r->print('<br /><a href="javascript:backPage(document.cu)">'.
                   1465:                           &mt('Back to previous page').'</a>');
1.188     raeburn  1466:             }
                   1467:         } else {
1.218     raeburn  1468:             $r->print(&course_level_table(%inccourses));
1.301     bisitz   1469:             $r->print('<br /><input type="button" value="'.&mt('Save').'" onclick="setSections(this.form)" />'."\n");
1.188     raeburn  1470:         }
1.88      raeburn  1471:     }
1.188     raeburn  1472:     $r->print(&Apache::lonhtmlcommon::echo_form_input(['phase','userrole','ccdomain','prevphase','currstate','ccuname','ccdomain']));
1.179     raeburn  1473:     $r->print('<input type="hidden" name="currstate" value="" />');
1.352     raeburn  1474:     $r->print('<input type="hidden" name="prevphase" value="'.$env{'form.phase'}.'" /></form>');
1.218     raeburn  1475:     return;
1.2       www      1476: }
1.1       www      1477: 
1.213     raeburn  1478: sub singleuser_breadcrumb {
1.318     raeburn  1479:     my ($crstype) = @_;
1.213     raeburn  1480:     my %breadcrumb_text;
                   1481:     if ($env{'form.action'} eq 'singlestudent') {
1.318     raeburn  1482:         if ($crstype eq 'Community') {
                   1483:             $breadcrumb_text{'search'} = 'Enroll a member';
                   1484:         } else {
                   1485:             $breadcrumb_text{'search'} = 'Enroll a student';
                   1486:         }
1.213     raeburn  1487:         $breadcrumb_text{'userpicked'} = 'Select a user',
                   1488:         $breadcrumb_text{'modify'} = 'Set section/dates',
                   1489:     } else {
1.229     raeburn  1490:         $breadcrumb_text{'search'} = 'Create/modify a user';
1.213     raeburn  1491:         $breadcrumb_text{'userpicked'} = 'Select a user',
                   1492:         $breadcrumb_text{'modify'} = 'Set user role',
                   1493:     }
                   1494:     return %breadcrumb_text;
                   1495: }
                   1496: 
                   1497: sub date_sections_select {
                   1498:     my ($context,$newuser,$formname,$permission) = @_;
                   1499:     my $cid = $env{'request.course.id'};
                   1500:     my ($cnum,$cdom) = &Apache::lonuserutils::get_course_identity($cid);
                   1501:     my $date_table = '<h3>'.&mt('Starting and Ending Dates').'</h3>'."\n".
                   1502:         &Apache::lonuserutils::date_setting_table(undef,undef,$context,
                   1503:                                                   undef,$formname,$permission);
                   1504:     my $rowtitle = 'Section';
                   1505:     my $secbox = '<h3>'.&mt('Section').'</h3>'."\n".
                   1506:         &Apache::lonuserutils::section_picker($cdom,$cnum,'st',$rowtitle,
                   1507:                                               $permission);
                   1508:     my $output = $date_table.$secbox;
                   1509:     return $output;
                   1510: }
                   1511: 
1.216     raeburn  1512: sub validation_javascript {
                   1513:     my ($context,$ccdomain,$pjump_def,$groupslist,$newuser,$formname,
                   1514:         $loaditem) = @_;
                   1515:     my $dc_setcourse_code = '';
                   1516:     my $nondc_setsection_code = '';
                   1517:     if ($context eq 'domain') {
                   1518:         my $dcdom = $env{'request.role.domain'};
                   1519:         $loaditem->{'onload'} = "document.cu.coursedesc.value='';";
1.227     raeburn  1520:         $dc_setcourse_code = 
                   1521:             &Apache::lonuserutils::dc_setcourse_js('cu','singleuser',$context);
1.216     raeburn  1522:     } else {
1.227     raeburn  1523:         my $checkauth; 
                   1524:         if (($newuser) || (&Apache::lonnet::allowed('mau',$ccdomain))) {
                   1525:             $checkauth = 1;
                   1526:         }
                   1527:         if ($context eq 'course') {
                   1528:             $nondc_setsection_code =
                   1529:                 &Apache::lonuserutils::setsections_javascript($formname,$groupslist,
                   1530:                                                               undef,$checkauth);
                   1531:         }
                   1532:         if ($checkauth) {
                   1533:             $nondc_setsection_code .= 
                   1534:                 &Apache::lonuserutils::verify_authen($formname,$context);
                   1535:         }
1.216     raeburn  1536:     }
                   1537:     my $js = &user_modification_js($pjump_def,$dc_setcourse_code,
                   1538:                                    $nondc_setsection_code,$groupslist);
                   1539:     my ($jsback,$elements) = &crumb_utilities();
                   1540:     $js .= "\n".
1.301     bisitz   1541:            '<script type="text/javascript">'."\n".
                   1542:            '// <![CDATA['."\n".
                   1543:            $jsback."\n".
                   1544:            '// ]]>'."\n".
                   1545:            '</script>'."\n";
1.216     raeburn  1546:     return $js;
                   1547: }
                   1548: 
1.217     raeburn  1549: sub display_existing_roles {
1.329     raeburn  1550:     my ($r,$ccuname,$ccdomain,$inccourses,$context,$roledom,$crstype) = @_;
                   1551:     my $now=time;
                   1552:     my %lt=&Apache::lonlocal::texthash(
1.217     raeburn  1553:                     'rer'  => "Existing Roles",
                   1554:                     'rev'  => "Revoke",
                   1555:                     'del'  => "Delete",
                   1556:                     'ren'  => "Re-Enable",
                   1557:                     'rol'  => "Role",
                   1558:                     'ext'  => "Extent",
                   1559:                     'sta'  => "Start",
                   1560:                     'end'  => "End",
                   1561:                                        );
1.329     raeburn  1562:     my (%rolesdump,%roletext,%sortrole,%roleclass,%rolepriv);
                   1563:     if ($context eq 'course' || $context eq 'author') {
                   1564:         my @roles = &Apache::lonuserutils::roles_by_context($context,1,$crstype);
                   1565:         my %roleshash = 
                   1566:             &Apache::lonnet::get_my_roles($ccuname,$ccdomain,'userroles',
                   1567:                               ['active','previous','future'],\@roles,$roledom,1);
                   1568:         foreach my $key (keys(%roleshash)) {
                   1569:             my ($start,$end) = split(':',$roleshash{$key});
                   1570:             next if ($start eq '-1' || $end eq '-1');
                   1571:             my ($rnum,$rdom,$role,$sec) = split(':',$key);
                   1572:             if ($context eq 'course') {
                   1573:                 next unless (($rnum eq $env{'course.'.$env{'request.course.id'}.'.num'})
                   1574:                              && ($rdom eq $env{'course.'.$env{'request.course.id'}.'.domain'}));
                   1575:             } elsif ($context eq 'author') {
                   1576:                 next unless (($rnum eq $env{'user.name'}) && ($rdom eq $env{'request.role.domain'}));
                   1577:             }
                   1578:             my ($newkey,$newvalue,$newrole);
                   1579:             $newkey = '/'.$rdom.'/'.$rnum;
                   1580:             if ($sec ne '') {
                   1581:                 $newkey .= '/'.$sec;
                   1582:             }
                   1583:             $newvalue = $role;
                   1584:             if ($role =~ /^cr/) {
                   1585:                 $newrole = 'cr';
                   1586:             } else {
                   1587:                 $newrole = $role;
                   1588:             }
                   1589:             $newkey .= '_'.$newrole;
                   1590:             if ($start ne '' && $end ne '') {
                   1591:                 $newvalue .= '_'.$end.'_'.$start;
1.335     raeburn  1592:             } elsif ($end ne '') {
                   1593:                 $newvalue .= '_'.$end;
1.329     raeburn  1594:             }
                   1595:             $rolesdump{$newkey} = $newvalue;
                   1596:         }
                   1597:     } else {
1.360     raeburn  1598:         %rolesdump=&Apache::lonnet::dump('roles',$ccdomain,$ccuname);
1.329     raeburn  1599:     }
                   1600:     # Build up table of user roles to allow revocation and re-enabling of roles.
                   1601:     my ($tmp) = keys(%rolesdump);
                   1602:     return if ($tmp =~ /^(con_lost|error)/i);
                   1603:     foreach my $area (sort { my $a1=join('_',(split('_',$a))[1,0]);
                   1604:                                 my $b1=join('_',(split('_',$b))[1,0]);
                   1605:                                 return $a1 cmp $b1;
                   1606:                             } keys(%rolesdump)) {
                   1607:         next if ($area =~ /^rolesdef/);
                   1608:         my $envkey=$area;
                   1609:         my $role = $rolesdump{$area};
                   1610:         my $thisrole=$area;
                   1611:         $area =~ s/\_\w\w$//;
                   1612:         my ($role_code,$role_end_time,$role_start_time) =
                   1613:             split(/_/,$role);
1.217     raeburn  1614: # Is this a custom role? Get role owner and title.
1.329     raeburn  1615:         my ($croleudom,$croleuname,$croletitle)=
                   1616:             ($role_code=~m{^cr/($match_domain)/($match_username)/(\w+)$});
                   1617:         my $allowed=0;
                   1618:         my $delallowed=0;
                   1619:         my $sortkey=$role_code;
                   1620:         my $class='Unknown';
                   1621:         if ($area =~ m{^/($match_domain)/($match_courseid)} ) {
                   1622:             $class='Course';
                   1623:             my ($coursedom,$coursedir) = ($1,$2);
                   1624:             my $cid = $1.'_'.$2;
                   1625:             # $1.'_'.$2 is the course id (eg. 103_12345abcef103l3).
                   1626:             my %coursedata=
                   1627:                 &Apache::lonnet::coursedescription($cid);
                   1628:             if ($coursedir =~ /^$match_community$/) {
                   1629:                 $class='Community';
                   1630:             }
                   1631:             $sortkey.="\0$coursedom";
                   1632:             my $carea;
                   1633:             if (defined($coursedata{'description'})) {
                   1634:                 $carea=$coursedata{'description'}.
                   1635:                     '<br />'.&mt('Domain').': '.$coursedom.('&nbsp;'x8).
                   1636:     &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$coursedir,$coursedom);
                   1637:                 $sortkey.="\0".$coursedata{'description'};
                   1638:             } else {
                   1639:                 if ($class eq 'Community') {
                   1640:                     $carea=&mt('Unavailable community').': '.$area;
                   1641:                     $sortkey.="\0".&mt('Unavailable community').': '.$area;
1.217     raeburn  1642:                 } else {
                   1643:                     $carea=&mt('Unavailable course').': '.$area;
                   1644:                     $sortkey.="\0".&mt('Unavailable course').': '.$area;
                   1645:                 }
1.329     raeburn  1646:             }
                   1647:             $sortkey.="\0$coursedir";
                   1648:             $inccourses->{$cid}=1;
                   1649:             if ((&Apache::lonnet::allowed('c'.$role_code,$coursedom.'/'.$coursedir)) ||
                   1650:                 (&Apache::lonnet::allowed('c'.$role_code,$ccdomain))) {
                   1651:                 $allowed=1;
                   1652:             }
                   1653:             unless ($allowed) {
1.365     raeburn  1654:                 my $isowner = &Apache::lonuserutils::is_courseowner($cid,$coursedata{'internal.courseowner'});
1.329     raeburn  1655:                 if ($isowner) {
                   1656:                     if (($role_code eq 'co') && ($class eq 'Community')) {
                   1657:                         $allowed = 1;
                   1658:                     } elsif (($role_code eq 'cc') && ($class eq 'Course')) {
                   1659:                         $allowed = 1;
                   1660:                     }
1.217     raeburn  1661:                 }
1.329     raeburn  1662:             } 
                   1663:             if ((&Apache::lonnet::allowed('dro',$coursedom)) ||
                   1664:                 (&Apache::lonnet::allowed('dro',$ccdomain))) {
                   1665:                 $delallowed=1;
                   1666:             }
1.217     raeburn  1667: # - custom role. Needs more info, too
1.329     raeburn  1668:             if ($croletitle) {
                   1669:                 if (&Apache::lonnet::allowed('ccr',$coursedom.'/'.$coursedir)) {
                   1670:                     $allowed=1;
                   1671:                     $thisrole.='.'.$role_code;
1.217     raeburn  1672:                 }
1.329     raeburn  1673:             }
                   1674:             if ($area=~m{^/($match_domain)/($match_courseid)/(\w+)}) {
                   1675:                 $carea.='<br />Section: '.$3;
                   1676:                 $sortkey.="\0$3";
                   1677:                 if (!$allowed) {
                   1678:                     if ($env{'request.course.sec'} eq $3) {
                   1679:                         if (&Apache::lonnet::allowed('c'.$role_code,$1.'/'.$2.'/'.$3)) {
                   1680:                             $allowed = 1;
1.217     raeburn  1681:                         }
                   1682:                     }
                   1683:                 }
1.329     raeburn  1684:             }
                   1685:             $area=$carea;
                   1686:         } else {
                   1687:             $sortkey.="\0".$area;
                   1688:             # Determine if current user is able to revoke privileges
                   1689:             if ($area=~m{^/($match_domain)/}) {
                   1690:                 if ((&Apache::lonnet::allowed('c'.$role_code,$1)) ||
                   1691:                    (&Apache::lonnet::allowed('c'.$role_code,$ccdomain))) {
                   1692:                    $allowed=1;
1.217     raeburn  1693:                 }
1.329     raeburn  1694:                 if (((&Apache::lonnet::allowed('dro',$1))  ||
                   1695:                     (&Apache::lonnet::allowed('dro',$ccdomain))) &&
                   1696:                     ($role_code ne 'dc')) {
                   1697:                     $delallowed=1;
1.217     raeburn  1698:                 }
1.329     raeburn  1699:             } else {
                   1700:                 if (&Apache::lonnet::allowed('c'.$role_code,'/')) {
1.217     raeburn  1701:                     $allowed=1;
                   1702:                 }
                   1703:             }
1.363     raeburn  1704:             if ($role_code eq 'ca' || $role_code eq 'au' || $role_code eq 'aa') {
1.329     raeburn  1705:                 $class='Construction Space';
                   1706:             } elsif ($role_code eq 'su') {
                   1707:                 $class='System';
1.217     raeburn  1708:             } else {
1.329     raeburn  1709:                 $class='Domain';
1.217     raeburn  1710:             }
1.329     raeburn  1711:         }
                   1712:         if (($role_code eq 'ca') || ($role_code eq 'aa')) {
                   1713:             $area=~m{/($match_domain)/($match_username)};
                   1714:             if (&Apache::lonuserutils::authorpriv($2,$1)) {
                   1715:                 $allowed=1;
1.217     raeburn  1716:             } else {
1.329     raeburn  1717:                 $allowed=0;
1.217     raeburn  1718:             }
1.329     raeburn  1719:         }
                   1720:         my $row = '';
                   1721:         $row.= '<td>';
                   1722:         my $active=1;
                   1723:         $active=0 if (($role_end_time) && ($now>$role_end_time));
                   1724:         if (($active) && ($allowed)) {
                   1725:             $row.= '<input type="checkbox" name="rev:'.$thisrole.'" />';
                   1726:         } else {
                   1727:             if ($active) {
                   1728:                $row.='&nbsp;';
1.217     raeburn  1729:             } else {
1.329     raeburn  1730:                $row.=&mt('expired or revoked');
1.217     raeburn  1731:             }
1.329     raeburn  1732:         }
                   1733:         $row.='</td><td>';
                   1734:         if ($allowed && !$active) {
                   1735:             $row.= '<input type="checkbox" name="ren:'.$thisrole.'" />';
                   1736:         } else {
                   1737:             $row.='&nbsp;';
                   1738:         }
                   1739:         $row.='</td><td>';
                   1740:         if ($delallowed) {
                   1741:             $row.= '<input type="checkbox" name="del:'.$thisrole.'" />';
                   1742:         } else {
                   1743:             $row.='&nbsp;';
                   1744:         }
                   1745:         my $plaintext='';
                   1746:         if (!$croletitle) {
                   1747:             $plaintext=&Apache::lonnet::plaintext($role_code,$class)
                   1748:         } else {
                   1749:             $plaintext=
1.346     bisitz   1750:                 &mt('Customrole [_1][_2]defined by [_3]',
                   1751:                         '"'.$croletitle.'"',
                   1752:                         '<br />',
                   1753:                         $croleuname.':'.$croleudom);
1.329     raeburn  1754:         }
                   1755:         $row.= '</td><td>'.$plaintext.
                   1756:                '</td><td>'.$area.
                   1757:                '</td><td>'.($role_start_time?&Apache::lonlocal::locallocaltime($role_start_time)
                   1758:                                             : '&nbsp;' ).
                   1759:                '</td><td>'.($role_end_time  ?&Apache::lonlocal::locallocaltime($role_end_time)
                   1760:                                             : '&nbsp;' )
                   1761:                ."</td>";
                   1762:         $sortrole{$sortkey}=$envkey;
                   1763:         $roletext{$envkey}=$row;
                   1764:         $roleclass{$envkey}=$class;
                   1765:         $rolepriv{$envkey}=$allowed;
                   1766:     } # end of foreach        (table building loop)
                   1767: 
                   1768:     my $rolesdisplay = 0;
                   1769:     my %output = ();
                   1770:     foreach my $type ('Construction Space','Course','Community','Domain','System','Unknown') {
                   1771:         $output{$type} = '';
                   1772:         foreach my $which (sort {uc($a) cmp uc($b)} (keys(%sortrole))) {
                   1773:             if ( ($roleclass{$sortrole{$which}} =~ /^\Q$type\E/ ) && ($rolepriv{$sortrole{$which}}) ) {
                   1774:                  $output{$type}.=
                   1775:                       &Apache::loncommon::start_data_table_row().
                   1776:                       $roletext{$sortrole{$which}}.
                   1777:                       &Apache::loncommon::end_data_table_row();
1.217     raeburn  1778:             }
1.329     raeburn  1779:         }
                   1780:         unless($output{$type} eq '') {
                   1781:             $output{$type} = '<tr class="LC_info_row">'.
                   1782:                       "<td align='center' colspan='7'>".&mt($type)."</td></tr>".
                   1783:                       $output{$type};
                   1784:             $rolesdisplay = 1;
                   1785:         }
                   1786:     }
                   1787:     if ($rolesdisplay == 1) {
                   1788:         my $contextrole='';
                   1789:         if ($env{'request.course.id'}) {
                   1790:             if (&Apache::loncommon::course_type() eq 'Community') {
                   1791:                 $contextrole = &mt('Existing Roles in this Community');
1.290     bisitz   1792:             } else {
1.329     raeburn  1793:                 $contextrole = &mt('Existing Roles in this Course');
1.290     bisitz   1794:             }
1.329     raeburn  1795:         } elsif ($env{'request.role'} =~ /^au\./) {
                   1796:             $contextrole = &mt('Existing Co-Author Roles in your Construction Space');
                   1797:         } else {
                   1798:             $contextrole = &mt('Existing Roles in this Domain');
                   1799:         }
                   1800:         $r->print('
1.217     raeburn  1801: <h3>'.$lt{'rer'}.'</h3>'.
1.329     raeburn  1802: '<div>'.$contextrole.'</div>'.
1.217     raeburn  1803: &Apache::loncommon::start_data_table("LC_createuser").
                   1804: &Apache::loncommon::start_data_table_header_row().
                   1805: '<th>'.$lt{'rev'}.'</th><th>'.$lt{'ren'}.'</th><th>'.$lt{'del'}.
                   1806: '</th><th>'.$lt{'rol'}.'</th><th>'.$lt{'ext'}.
                   1807: '</th><th>'.$lt{'sta'}.'</th><th>'.$lt{'end'}.'</th>'.
                   1808: &Apache::loncommon::end_data_table_header_row());
1.329     raeburn  1809:         foreach my $type ('Construction Space','Course','Community','Domain','System','Unknown') {
                   1810:             if ($output{$type}) {
                   1811:                 $r->print($output{$type}."\n");
1.217     raeburn  1812:             }
                   1813:         }
1.329     raeburn  1814:         $r->print(&Apache::loncommon::end_data_table());
                   1815:     }
1.217     raeburn  1816:     return;
                   1817: }
                   1818: 
1.218     raeburn  1819: sub new_coauthor_roles {
                   1820:     my ($r,$ccuname,$ccdomain) = @_;
                   1821:     my $addrolesdisplay = 0;
                   1822:     #
                   1823:     # Co-Author
                   1824:     #
                   1825:     if (&Apache::lonuserutils::authorpriv($env{'user.name'},
                   1826:                                           $env{'request.role.domain'}) &&
                   1827:         ($env{'user.name'} ne $ccuname || $env{'user.domain'} ne $ccdomain)) {
                   1828:         # No sense in assigning co-author role to yourself
                   1829:         $addrolesdisplay = 1;
                   1830:         my $cuname=$env{'user.name'};
                   1831:         my $cudom=$env{'request.role.domain'};
                   1832:         my %lt=&Apache::lonlocal::texthash(
                   1833:                     'cs'   => "Construction Space",
                   1834:                     'act'  => "Activate",
                   1835:                     'rol'  => "Role",
                   1836:                     'ext'  => "Extent",
                   1837:                     'sta'  => "Start",
                   1838:                     'end'  => "End",
                   1839:                     'cau'  => "Co-Author",
                   1840:                     'caa'  => "Assistant Co-Author",
                   1841:                     'ssd'  => "Set Start Date",
                   1842:                     'sed'  => "Set End Date"
                   1843:                                        );
                   1844:         $r->print('<h4>'.$lt{'cs'}.'</h4>'."\n".
                   1845:                   &Apache::loncommon::start_data_table()."\n".
                   1846:                   &Apache::loncommon::start_data_table_header_row()."\n".
                   1847:                   '<th>'.$lt{'act'}.'</th><th>'.$lt{'rol'}.'</th>'.
                   1848:                   '<th>'.$lt{'ext'}.'</th><th>'.$lt{'sta'}.'</th>'.
                   1849:                   '<th>'.$lt{'end'}.'</th>'."\n".
                   1850:                   &Apache::loncommon::end_data_table_header_row()."\n".
                   1851:                   &Apache::loncommon::start_data_table_row().'
                   1852:            <td>
1.291     bisitz   1853:             <input type="checkbox" name="act_'.$cudom.'_'.$cuname.'_ca" />
1.218     raeburn  1854:            </td>
                   1855:            <td>'.$lt{'cau'}.'</td>
                   1856:            <td>'.$cudom.'_'.$cuname.'</td>
                   1857:            <td><input type="hidden" name="start_'.$cudom.'_'.$cuname.'_ca" value="" />
                   1858:              <a href=
                   1859: "javascript:pjump('."'date_start','Start Date Co-Author',document.cu.start_$cudom\_$cuname\_ca.value,'start_$cudom\_$cuname\_ca','cu.pres','dateset'".')">'.$lt{'ssd'}.'</a></td>
                   1860: <td><input type="hidden" name="end_'.$cudom.'_'.$cuname.'_ca" value="" />
                   1861: <a href=
                   1862: "javascript:pjump('."'date_end','End Date Co-Author',document.cu.end_$cudom\_$cuname\_ca.value,'end_$cudom\_$cuname\_ca','cu.pres','dateset'".')">'.$lt{'sed'}.'</a></td>'."\n".
                   1863:               &Apache::loncommon::end_data_table_row()."\n".
                   1864:               &Apache::loncommon::start_data_table_row()."\n".
1.291     bisitz   1865: '<td><input type="checkbox" name="act_'.$cudom.'_'.$cuname.'_aa" /></td>
1.218     raeburn  1866: <td>'.$lt{'caa'}.'</td>
                   1867: <td>'.$cudom.'_'.$cuname.'</td>
                   1868: <td><input type="hidden" name="start_'.$cudom.'_'.$cuname.'_aa" value="" />
                   1869: <a href=
                   1870: "javascript:pjump('."'date_start','Start Date Assistant Co-Author',document.cu.start_$cudom\_$cuname\_aa.value,'start_$cudom\_$cuname\_aa','cu.pres','dateset'".')">'.$lt{'ssd'}.'</a></td>
                   1871: <td><input type="hidden" name="end_'.$cudom.'_'.$cuname.'_aa" value="" />
                   1872: <a href=
                   1873: "javascript:pjump('."'date_end','End Date Assistant Co-Author',document.cu.end_$cudom\_$cuname\_aa.value,'end_$cudom\_$cuname\_aa','cu.pres','dateset'".')">'.$lt{'sed'}.'</a></td>'."\n".
                   1874:              &Apache::loncommon::end_data_table_row()."\n".
                   1875:              &Apache::loncommon::end_data_table());
                   1876:     } elsif ($env{'request.role'} =~ /^au\./) {
                   1877:         if (!(&Apache::lonuserutils::authorpriv($env{'user.name'},
                   1878:                                                 $env{'request.role.domain'}))) {
                   1879:             $r->print('<span class="LC_error">'.
                   1880:                       &mt('You do not have privileges to assign co-author roles.').
                   1881:                       '</span>');
                   1882:         } elsif (($env{'user.name'} eq $ccuname) &&
                   1883:              ($env{'user.domain'} eq $ccdomain)) {
                   1884:             $r->print(&mt('Assigning yourself a co-author or assistant co-author role in your own author area in Construction Space is not permitted'));
                   1885:         }
                   1886:     }
                   1887:     return $addrolesdisplay;;
                   1888: }
                   1889: 
                   1890: sub new_domain_roles {
1.357     raeburn  1891:     my ($r,$ccdomain) = @_;
1.218     raeburn  1892:     my $addrolesdisplay = 0;
                   1893:     #
                   1894:     # Domain level
                   1895:     #
                   1896:     my $num_domain_level = 0;
                   1897:     my $domaintext =
                   1898:     '<h4>'.&mt('Domain Level').'</h4>'.
                   1899:     &Apache::loncommon::start_data_table().
                   1900:     &Apache::loncommon::start_data_table_header_row().
                   1901:     '<th>'.&mt('Activate').'</th><th>'.&mt('Role').'</th><th>'.
                   1902:     &mt('Extent').'</th>'.
                   1903:     '<th>'.&mt('Start').'</th><th>'.&mt('End').'</th>'.
                   1904:     &Apache::loncommon::end_data_table_header_row();
1.312     raeburn  1905:     my @allroles = &Apache::lonuserutils::roles_by_context('domain');
1.218     raeburn  1906:     foreach my $thisdomain (sort(&Apache::lonnet::all_domains())) {
1.312     raeburn  1907:         foreach my $role (@allroles) {
                   1908:             next if ($role eq 'ad');
1.357     raeburn  1909:             next if (($role eq 'au') && ($ccdomain ne $thisdomain));
1.218     raeburn  1910:             if (&Apache::lonnet::allowed('c'.$role,$thisdomain)) {
                   1911:                my $plrole=&Apache::lonnet::plaintext($role);
                   1912:                my %lt=&Apache::lonlocal::texthash(
                   1913:                     'ssd'  => "Set Start Date",
                   1914:                     'sed'  => "Set End Date"
                   1915:                                        );
                   1916:                $num_domain_level ++;
                   1917:                $domaintext .=
                   1918: &Apache::loncommon::start_data_table_row().
1.291     bisitz   1919: '<td><input type="checkbox" name="act_'.$thisdomain.'_'.$role.'" /></td>
1.218     raeburn  1920: <td>'.$plrole.'</td>
                   1921: <td>'.$thisdomain.'</td>
                   1922: <td><input type="hidden" name="start_'.$thisdomain.'_'.$role.'" value="" />
                   1923: <a href=
                   1924: "javascript:pjump('."'date_start','Start Date $plrole',document.cu.start_$thisdomain\_$role.value,'start_$thisdomain\_$role','cu.pres','dateset'".')">'.$lt{'ssd'}.'</a></td>
                   1925: <td><input type="hidden" name="end_'.$thisdomain.'_'.$role.'" value="" />
                   1926: <a href=
                   1927: "javascript:pjump('."'date_end','End Date $plrole',document.cu.end_$thisdomain\_$role.value,'end_$thisdomain\_$role','cu.pres','dateset'".')">'.$lt{'sed'}.'</a></td>'.
                   1928: &Apache::loncommon::end_data_table_row();
                   1929:             }
                   1930:         }
                   1931:     }
                   1932:     $domaintext.= &Apache::loncommon::end_data_table();
                   1933:     if ($num_domain_level > 0) {
                   1934:         $r->print($domaintext);
                   1935:         $addrolesdisplay = 1;
                   1936:     }
                   1937:     return $addrolesdisplay;
                   1938: }
                   1939: 
1.188     raeburn  1940: sub user_authentication {
1.227     raeburn  1941:     my ($ccuname,$ccdomain,$formname) = @_;
1.188     raeburn  1942:     my $currentauth=&Apache::lonnet::queryauthenticate($ccuname,$ccdomain);
1.227     raeburn  1943:     my $outcome;
1.188     raeburn  1944:     # Check for a bad authentication type
                   1945:     if ($currentauth !~ /^(krb4|krb5|unix|internal|localauth):/) {
                   1946:         # bad authentication scheme
                   1947:         my %lt=&Apache::lonlocal::texthash(
                   1948:                        'err'   => "ERROR",
                   1949:                        'uuas'  => "This user has an unrecognized authentication scheme",
                   1950:                        'adcs'  => "Please alert a domain coordinator of this situation",
                   1951:                        'sldb'  => "Please specify login data below",
                   1952:                        'ld'    => "Login Data"
                   1953:         );
                   1954:         if (&Apache::lonnet::allowed('mau',$ccdomain)) {
1.227     raeburn  1955:             &initialize_authen_forms($ccdomain,$formname);
                   1956: 
1.190     raeburn  1957:             my $choices = &Apache::lonuserutils::set_login($ccdomain,$authformkrb,$authformint,$authformloc);
1.188     raeburn  1958:             $outcome = <<ENDBADAUTH;
                   1959: <script type="text/javascript" language="Javascript">
1.301     bisitz   1960: // <![CDATA[
1.188     raeburn  1961: $loginscript
1.301     bisitz   1962: // ]]>
1.188     raeburn  1963: </script>
                   1964: <span class="LC_error">$lt{'err'}:
                   1965: $lt{'uuas'} ($currentauth). $lt{'sldb'}.</span>
                   1966: <h3>$lt{'ld'}</h3>
                   1967: $choices
                   1968: ENDBADAUTH
                   1969:         } else {
                   1970:             # This user is not allowed to modify the user's
                   1971:             # authentication scheme, so just notify them of the problem
                   1972:             $outcome = <<ENDBADAUTH;
                   1973: <span class="LC_error"> $lt{'err'}: 
                   1974: $lt{'uuas'} ($currentauth). $lt{'adcs'}.
                   1975: </span>
                   1976: ENDBADAUTH
                   1977:         }
                   1978:     } else { # Authentication type is valid
1.227     raeburn  1979:         &initialize_authen_forms($ccdomain,$formname,$currentauth,'modifyuser');
1.205     raeburn  1980:         my ($authformcurrent,$can_modify,@authform_others) =
1.188     raeburn  1981:             &modify_login_block($ccdomain,$currentauth);
                   1982:         if (&Apache::lonnet::allowed('mau',$ccdomain)) {
                   1983:             # Current user has login modification privileges
                   1984:             my %lt=&Apache::lonlocal::texthash (
                   1985:                            'ld'    => "Login Data",
                   1986:                            'ccld'  => "Change Current Login Data",
                   1987:                            'enld'  => "Enter New Login Data"
                   1988:                                                );
                   1989:             $outcome =
                   1990:                        '<script type="text/javascript" language="Javascript">'."\n".
1.301     bisitz   1991:                        '// <![CDATA['."\n".
1.188     raeburn  1992:                        $loginscript."\n".
1.301     bisitz   1993:                        '// ]]>'."\n".
1.188     raeburn  1994:                        '</script>'."\n".
                   1995:                        '<h3>'.$lt{'ld'}.'</h3>'.
                   1996:                        &Apache::loncommon::start_data_table().
1.205     raeburn  1997:                        &Apache::loncommon::start_data_table_row().
1.188     raeburn  1998:                        '<td>'.$authformnop;
                   1999:             if ($can_modify) {
                   2000:                 $outcome .= '</td>'."\n".
                   2001:                             &Apache::loncommon::end_data_table_row().
                   2002:                             &Apache::loncommon::start_data_table_row().
                   2003:                             '<td>'.$authformcurrent.'</td>'.
                   2004:                             &Apache::loncommon::end_data_table_row()."\n";
                   2005:             } else {
1.200     raeburn  2006:                 $outcome .= '&nbsp;('.$authformcurrent.')</td>'.
                   2007:                             &Apache::loncommon::end_data_table_row()."\n";
1.188     raeburn  2008:             }
1.205     raeburn  2009:             foreach my $item (@authform_others) { 
                   2010:                 $outcome .= &Apache::loncommon::start_data_table_row().
                   2011:                             '<td>'.$item.'</td>'.
                   2012:                             &Apache::loncommon::end_data_table_row()."\n";
1.188     raeburn  2013:             }
1.205     raeburn  2014:             $outcome .= &Apache::loncommon::end_data_table();
1.188     raeburn  2015:         } else {
                   2016:             if (&Apache::lonnet::allowed('mau',$env{'request.role.domain'})) {
                   2017:                 my %lt=&Apache::lonlocal::texthash(
                   2018:                            'ccld'  => "Change Current Login Data",
                   2019:                            'yodo'  => "You do not have privileges to modify the authentication configuration for this user.",
                   2020:                            'ifch'  => "If a change is required, contact a domain coordinator for the domain",
                   2021:                 );
                   2022:                 $outcome .= <<ENDNOPRIV;
                   2023: <h3>$lt{'ccld'}</h3>
                   2024: $lt{'yodo'} $lt{'ifch'}: $ccdomain
1.235     raeburn  2025: <input type="hidden" name="login" value="nochange" />
1.188     raeburn  2026: ENDNOPRIV
                   2027:             }
                   2028:         }
                   2029:     }  ## End of "check for bad authentication type" logic
                   2030:     return $outcome;
                   2031: }
                   2032: 
1.187     raeburn  2033: sub modify_login_block {
                   2034:     my ($dom,$currentauth) = @_;
                   2035:     my %domconfig = &Apache::lonnet::get_dom('configuration',['usercreation'],$dom);
                   2036:     my ($authnum,%can_assign) =
                   2037:         &Apache::loncommon::get_assignable_auth($dom);
1.205     raeburn  2038:     my ($authformcurrent,@authform_others,$show_override_msg);
1.187     raeburn  2039:     if ($currentauth=~/^krb(4|5):/) {
                   2040:         $authformcurrent=$authformkrb;
                   2041:         if ($can_assign{'int'}) {
1.205     raeburn  2042:             push(@authform_others,$authformint);
1.187     raeburn  2043:         }
                   2044:         if ($can_assign{'loc'}) {
1.205     raeburn  2045:             push(@authform_others,$authformloc);
1.187     raeburn  2046:         }
                   2047:         if (($can_assign{'krb4'}) || ($can_assign{'krb5'})) {
                   2048:             $show_override_msg = 1;
                   2049:         }
                   2050:     } elsif ($currentauth=~/^internal:/) {
                   2051:         $authformcurrent=$authformint;
                   2052:         if (($can_assign{'krb4'}) || ($can_assign{'krb5'})) {
1.205     raeburn  2053:             push(@authform_others,$authformkrb);
1.187     raeburn  2054:         }
                   2055:         if ($can_assign{'loc'}) {
1.205     raeburn  2056:             push(@authform_others,$authformloc);
1.187     raeburn  2057:         }
                   2058:         if ($can_assign{'int'}) {
                   2059:             $show_override_msg = 1;
                   2060:         }
                   2061:     } elsif ($currentauth=~/^unix:/) {
                   2062:         $authformcurrent=$authformfsys;
                   2063:         if (($can_assign{'krb4'}) || ($can_assign{'krb5'})) {
1.205     raeburn  2064:             push(@authform_others,$authformkrb);
1.187     raeburn  2065:         }
                   2066:         if ($can_assign{'int'}) {
1.205     raeburn  2067:             push(@authform_others,$authformint);
1.187     raeburn  2068:         }
                   2069:         if ($can_assign{'loc'}) {
1.205     raeburn  2070:             push(@authform_others,$authformloc);
1.187     raeburn  2071:         }
                   2072:         if ($can_assign{'fsys'}) {
                   2073:             $show_override_msg = 1;
                   2074:         }
                   2075:     } elsif ($currentauth=~/^localauth:/) {
                   2076:         $authformcurrent=$authformloc;
                   2077:         if (($can_assign{'krb4'}) || ($can_assign{'krb5'})) {
1.205     raeburn  2078:             push(@authform_others,$authformkrb);
1.187     raeburn  2079:         }
                   2080:         if ($can_assign{'int'}) {
1.205     raeburn  2081:             push(@authform_others,$authformint);
1.187     raeburn  2082:         }
                   2083:         if ($can_assign{'loc'}) {
                   2084:             $show_override_msg = 1;
                   2085:         }
                   2086:     }
                   2087:     if ($show_override_msg) {
1.205     raeburn  2088:         $authformcurrent = '<table><tr><td colspan="3">'.$authformcurrent.
                   2089:                            '</td></tr>'."\n".
                   2090:                            '<tr><td>&nbsp;&nbsp;&nbsp;</td>'.
                   2091:                            '<td><b>'.&mt('Currently in use').'</b></td>'.
                   2092:                            '<td align="right"><span class="LC_cusr_emph">'.
1.187     raeburn  2093:                             &mt('will override current values').
1.205     raeburn  2094:                             '</span></td></tr></table>';
1.187     raeburn  2095:     }
1.205     raeburn  2096:     return ($authformcurrent,$show_override_msg,@authform_others); 
1.187     raeburn  2097: }
                   2098: 
1.188     raeburn  2099: sub personal_data_display {
1.252     raeburn  2100:     my ($ccuname,$ccdomain,$newuser,$context,$inst_results,$rolesarray) = @_;
1.286     raeburn  2101:     my ($output,$showforceid,%userenv,%canmodify,%canmodify_status);
1.219     raeburn  2102:     my @userinfo = ('firstname','middlename','lastname','generation',
                   2103:                     'permanentemail','id');
1.252     raeburn  2104:     my $rowcount = 0;
                   2105:     my $editable = 0;
1.286     raeburn  2106:     %canmodify_status = 
                   2107:         &Apache::lonuserutils::can_modify_userinfo($context,$ccdomain,
                   2108:                                                    ['inststatus'],$rolesarray);
1.253     raeburn  2109:     if (!$newuser) {
1.188     raeburn  2110:         # Get the users information
                   2111:         %userenv = &Apache::lonnet::get('environment',
                   2112:                    ['firstname','middlename','lastname','generation',
1.286     raeburn  2113:                     'permanentemail','id','inststatus'],$ccdomain,$ccuname);
1.219     raeburn  2114:         %canmodify =
                   2115:             &Apache::lonuserutils::can_modify_userinfo($context,$ccdomain,
1.252     raeburn  2116:                                                        \@userinfo,$rolesarray);
1.257     raeburn  2117:     } elsif ($context eq 'selfcreate') {
                   2118:         %canmodify = &selfcreate_canmodify($context,$ccdomain,\@userinfo,
                   2119:                                            $inst_results,$rolesarray);
1.188     raeburn  2120:     }
                   2121:     my %lt=&Apache::lonlocal::texthash(
                   2122:                 'pd'             => "Personal Data",
                   2123:                 'firstname'      => "First Name",
                   2124:                 'middlename'     => "Middle Name",
                   2125:                 'lastname'       => "Last Name",
                   2126:                 'generation'     => "Generation",
                   2127:                 'permanentemail' => "Permanent e-mail address",
1.259     bisitz   2128:                 'id'             => "Student/Employee ID",
1.286     raeburn  2129:                 'lg'             => "Login Data",
                   2130:                 'inststatus'     => "Affiliation",
1.188     raeburn  2131:     );
                   2132:     my %textboxsize = (
                   2133:                        firstname      => '15',
                   2134:                        middlename     => '15',
                   2135:                        lastname       => '15',
                   2136:                        generation     => '5',
                   2137:                        permanentemail => '25',
                   2138:                        id             => '15',
                   2139:                       );
                   2140:     my $genhelp=&Apache::loncommon::help_open_topic('Generation');
                   2141:     $output = '<h3>'.$lt{'pd'}.'</h3>'.
                   2142:               &Apache::lonhtmlcommon::start_pick_box();
                   2143:     foreach my $item (@userinfo) {
                   2144:         my $rowtitle = $lt{$item};
1.252     raeburn  2145:         my $hiderow = 0;
1.188     raeburn  2146:         if ($item eq 'generation') {
                   2147:             $rowtitle = $genhelp.$rowtitle;
                   2148:         }
1.252     raeburn  2149:         my $row = &Apache::lonhtmlcommon::row_title($rowtitle,undef,'LC_oddrow_value')."\n";
1.188     raeburn  2150:         if ($newuser) {
1.210     raeburn  2151:             if (ref($inst_results) eq 'HASH') {
                   2152:                 if ($inst_results->{$item} ne '') {
1.252     raeburn  2153:                     $row .= '<input type="hidden" name="c'.$item.'" value="'.$inst_results->{$item}.'" />'.$inst_results->{$item};
1.210     raeburn  2154:                 } else {
1.252     raeburn  2155:                     if ($context eq 'selfcreate') {
                   2156:                         if ($canmodify{$item}) { 
                   2157:                             $row .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="" />';
                   2158:                             $editable ++;
                   2159:                         } else {
                   2160:                             $hiderow = 1;
                   2161:                         }
1.253     raeburn  2162:                     } else {
                   2163:                         $row .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="" />';
1.252     raeburn  2164:                     }
1.210     raeburn  2165:                 }
1.188     raeburn  2166:             } else {
1.252     raeburn  2167:                 if ($context eq 'selfcreate') {
1.287     raeburn  2168:                     if (($item eq 'permanentemail') && ($newuser eq 'email')) {
                   2169:                         $row .= $ccuname;
1.252     raeburn  2170:                     } else {
1.287     raeburn  2171:                         if ($canmodify{$item}) {
                   2172:                             $row .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="" />';
                   2173:                             $editable ++;
                   2174:                         } else {
                   2175:                             $hiderow = 1;
                   2176:                         }
1.252     raeburn  2177:                     }
1.253     raeburn  2178:                 } else {
                   2179:                     $row .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="" />';
1.252     raeburn  2180:                 }
1.188     raeburn  2181:             }
                   2182:         } else {
1.219     raeburn  2183:             if ($canmodify{$item}) {
1.252     raeburn  2184:                 $row .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="'.$userenv{$item}.'" />';
1.188     raeburn  2185:             } else {
1.252     raeburn  2186:                 $row .= $userenv{$item};
1.188     raeburn  2187:             }
1.206     raeburn  2188:             if ($item eq 'id') {
1.219     raeburn  2189:                 $showforceid = $canmodify{$item};
                   2190:             }
1.188     raeburn  2191:         }
1.252     raeburn  2192:         $row .= &Apache::lonhtmlcommon::row_closure(1);
                   2193:         if (!$hiderow) {
                   2194:             $output .= $row;
                   2195:             $rowcount ++;
                   2196:         }
1.188     raeburn  2197:     }
1.286     raeburn  2198:     if (($canmodify_status{'inststatus'}) || ($context ne 'selfcreate')) {
                   2199:         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($ccdomain);
                   2200:         if (ref($types) eq 'ARRAY') {
                   2201:             if (@{$types} > 0) {
                   2202:                 my ($hiderow,$shown);
                   2203:                 if ($canmodify_status{'inststatus'}) {
                   2204:                     $shown = &pick_inst_statuses($userenv{'inststatus'},$usertypes,$types);
                   2205:                 } else {
                   2206:                     if ($userenv{'inststatus'} eq '') {
                   2207:                         $hiderow = 1;
1.334     raeburn  2208:                     } else {
                   2209:                         my @showitems;
                   2210:                         foreach my $item ( map { &unescape($_); } split(':',$userenv{'inststatus'})) {
                   2211:                             if (exists($usertypes->{$item})) {
                   2212:                                 push(@showitems,$usertypes->{$item});
                   2213:                             } else {
                   2214:                                 push(@showitems,$item);
                   2215:                             }
                   2216:                         }
                   2217:                         if (@showitems) {
                   2218:                             $shown = join(', ',@showitems);
                   2219:                         } else {
                   2220:                             $hiderow = 1;
                   2221:                         }
1.286     raeburn  2222:                     }
                   2223:                 }
                   2224:                 if (!$hiderow) {
                   2225:                     my $row = &Apache::lonhtmlcommon::row_title(&mt('Affliations'),undef,'LC_oddrow_value')."\n".
                   2226:                               $shown.&Apache::lonhtmlcommon::row_closure(1); 
                   2227:                     if ($context eq 'selfcreate') {
                   2228:                         $rowcount ++;
                   2229:                     }
                   2230:                     $output .= $row;
                   2231:                 }
                   2232:             }
                   2233:         }
                   2234:     }
1.188     raeburn  2235:     $output .= &Apache::lonhtmlcommon::end_pick_box();
1.206     raeburn  2236:     if (wantarray) {
1.252     raeburn  2237:         if ($context eq 'selfcreate') {
                   2238:             return($output,$rowcount,$editable);
                   2239:         } else {
                   2240:             return ($output,$showforceid);
                   2241:         }
1.206     raeburn  2242:     } else {
                   2243:         return $output;
                   2244:     }
1.188     raeburn  2245: }
                   2246: 
1.286     raeburn  2247: sub pick_inst_statuses {
                   2248:     my ($curr,$usertypes,$types) = @_;
                   2249:     my ($output,$rem,@currtypes);
                   2250:     if ($curr ne '') {
                   2251:         @currtypes = map { &unescape($_); } split(/:/,$curr);
                   2252:     }
                   2253:     my $numinrow = 2;
                   2254:     if (ref($types) eq 'ARRAY') {
                   2255:         $output = '<table>';
                   2256:         my $lastcolspan; 
                   2257:         for (my $i=0; $i<@{$types}; $i++) {
                   2258:             if (defined($usertypes->{$types->[$i]})) {
                   2259:                 my $rem = $i%($numinrow);
                   2260:                 if ($rem == 0) {
                   2261:                     if ($i<@{$types}-1) {
                   2262:                         if ($i > 0) { 
                   2263:                             $output .= '</tr>';
                   2264:                         }
                   2265:                         $output .= '<tr>';
                   2266:                     }
                   2267:                 } elsif ($i==@{$types}-1) {
                   2268:                     my $colsleft = $numinrow - $rem;
                   2269:                     if ($colsleft > 1) {
                   2270:                         $lastcolspan = ' colspan="'.$colsleft.'"';
                   2271:                     }
                   2272:                 }
                   2273:                 my $check = ' ';
                   2274:                 if (grep(/^\Q$types->[$i]\E$/,@currtypes)) {
                   2275:                     $check = ' checked="checked" ';
                   2276:                 }
                   2277:                 $output .= '<td class="LC_left_item"'.$lastcolspan.'>'.
                   2278:                            '<span class="LC_nobreak"><label>'.
                   2279:                            '<input type="checkbox" name="inststatus" '.
                   2280:                            'value="'.$types->[$i].'"'.$check.'/>'.
                   2281:                            $usertypes->{$types->[$i]}.'</label></span></td>';
                   2282:             }
                   2283:         }
                   2284:         $output .= '</tr></table>';
                   2285:     }
                   2286:     return $output;
                   2287: }
                   2288: 
1.257     raeburn  2289: sub selfcreate_canmodify {
                   2290:     my ($context,$dom,$userinfo,$inst_results,$rolesarray) = @_;
                   2291:     if (ref($inst_results) eq 'HASH') {
                   2292:         my @inststatuses = &get_inststatuses($inst_results);
                   2293:         if (@inststatuses == 0) {
                   2294:             @inststatuses = ('default');
                   2295:         }
                   2296:         $rolesarray = \@inststatuses;
                   2297:     }
                   2298:     my %canmodify =
                   2299:         &Apache::lonuserutils::can_modify_userinfo($context,$dom,$userinfo,
                   2300:                                                    $rolesarray);
                   2301:     return %canmodify;
                   2302: }
                   2303: 
1.252     raeburn  2304: sub get_inststatuses {
                   2305:     my ($insthashref) = @_;
                   2306:     my @inststatuses = ();
                   2307:     if (ref($insthashref) eq 'HASH') {
                   2308:         if (ref($insthashref->{'inststatus'}) eq 'ARRAY') {
                   2309:             @inststatuses = @{$insthashref->{'inststatus'}};
                   2310:         }
                   2311:     }
                   2312:     return @inststatuses;
                   2313: }
                   2314: 
1.4       www      2315: # ================================================================= Phase Three
1.42      matthew  2316: sub update_user_data {
1.351     raeburn  2317:     my ($r,$context,$crstype,$brcrum) = @_; 
1.101     albertel 2318:     my $uhome=&Apache::lonnet::homeserver($env{'form.ccuname'},
                   2319:                                           $env{'form.ccdomain'});
1.27      matthew  2320:     # Error messages
1.188     raeburn  2321:     my $error     = '<span class="LC_error">'.&mt('Error').': ';
1.193     raeburn  2322:     my $end       = '</span><br /><br />';
                   2323:     my $rtnlink   = '<a href="javascript:backPage(document.userupdate,'.
1.188     raeburn  2324:                     "'$env{'form.prevphase'}','modify')".'" />'.
1.219     raeburn  2325:                     &mt('Return to previous page').'</a>'.
                   2326:                     &Apache::loncommon::end_page();
                   2327:     my $now = time;
1.40      www      2328:     my $title;
1.101     albertel 2329:     if (exists($env{'form.makeuser'})) {
1.40      www      2330: 	$title='Set Privileges for New User';
                   2331:     } else {
                   2332:         $title='Modify User Privileges';
                   2333:     }
1.213     raeburn  2334:     my $newuser = 0;
1.160     raeburn  2335:     my ($jsback,$elements) = &crumb_utilities();
                   2336:     my $jscript = '<script type="text/javascript">'."\n".
1.301     bisitz   2337:                   '// <![CDATA['."\n".
                   2338:                   $jsback."\n".
                   2339:                   '// ]]>'."\n".
                   2340:                   '</script>'."\n";
1.318     raeburn  2341:     my %breadcrumb_text = &singleuser_breadcrumb($crstype);
1.351     raeburn  2342:     push (@{$brcrum},
                   2343:              {href => "javascript:backPage(document.userupdate)",
                   2344:               text => $breadcrumb_text{'search'},
                   2345:               faq  => 282,
                   2346:               bug  => 'Instructor Interface',}
                   2347:              );
                   2348:     if ($env{'form.prevphase'} eq 'userpicked') {
                   2349:         push(@{$brcrum},
                   2350:                {href => "javascript:backPage(document.userupdate,'get_user_info','select')",
                   2351:                 text => $breadcrumb_text{'userpicked'},
                   2352:                 faq  => 282,
                   2353:                 bug  => 'Instructor Interface',});
1.233     raeburn  2354:     }
1.224     raeburn  2355:     my $helpitem = 'Course_Change_Privileges';
                   2356:     if ($env{'form.action'} eq 'singlestudent') {
                   2357:         $helpitem = 'Course_Add_Student';
                   2358:     }
1.351     raeburn  2359:     push(@{$brcrum}, 
                   2360:             {href => "javascript:backPage(document.userupdate,'$env{'form.prevphase'}','modify')",
                   2361:              text => $breadcrumb_text{'modify'},
                   2362:              faq  => 282,
                   2363:              bug  => 'Instructor Interface',},
                   2364:             {href => "/adm/createuser",
                   2365:              text => "Result",
                   2366:              faq  => 282,
                   2367:              bug  => 'Instructor Interface',
                   2368:              help => $helpitem});
                   2369:     my $args = {bread_crumbs          => $brcrum,
                   2370:                 bread_crumbs_component => 'User Management'};
                   2371:     if ($env{'form.popup'}) {
                   2372:         $args->{'no_nav_bar'} = 1;
                   2373:     }
                   2374:     $r->print(&Apache::loncommon::start_page($title,$jscript,$args));
1.188     raeburn  2375:     $r->print(&update_result_form($uhome));
1.27      matthew  2376:     # Check Inputs
1.101     albertel 2377:     if (! $env{'form.ccuname'} ) {
1.193     raeburn  2378: 	$r->print($error.&mt('No login name specified').'.'.$end.$rtnlink);
1.27      matthew  2379: 	return;
                   2380:     }
1.138     albertel 2381:     if (  $env{'form.ccuname'} ne 
                   2382: 	  &LONCAPA::clean_username($env{'form.ccuname'}) ) {
1.281     bisitz   2383: 	$r->print($error.&mt('Invalid login name.').'  '.
                   2384: 		  &mt('Only letters, numbers, periods, dashes, @, and underscores are valid.').
1.193     raeburn  2385: 		  $end.$rtnlink);
1.27      matthew  2386: 	return;
                   2387:     }
1.101     albertel 2388:     if (! $env{'form.ccdomain'}       ) {
1.193     raeburn  2389: 	$r->print($error.&mt('No domain specified').'.'.$end.$rtnlink);
1.27      matthew  2390: 	return;
                   2391:     }
1.138     albertel 2392:     if (  $env{'form.ccdomain'} ne
                   2393: 	  &LONCAPA::clean_domain($env{'form.ccdomain'}) ) {
1.281     bisitz   2394: 	$r->print($error.&mt('Invalid domain name.').'  '.
                   2395: 		  &mt('Only letters, numbers, periods, dashes, and underscores are valid.').
1.193     raeburn  2396: 		  $end.$rtnlink);
1.27      matthew  2397: 	return;
                   2398:     }
1.219     raeburn  2399:     if ($uhome eq 'no_host') {
                   2400:         $newuser = 1;
                   2401:     }
1.101     albertel 2402:     if (! exists($env{'form.makeuser'})) {
1.29      matthew  2403:         # Modifying an existing user, so check the validity of the name
                   2404:         if ($uhome eq 'no_host') {
1.73      sakharuk 2405:             $r->print($error.&mt('Unable to determine home server for ').
1.101     albertel 2406:                       $env{'form.ccuname'}.&mt(' in domain ').
                   2407:                       $env{'form.ccdomain'}.'.');
1.29      matthew  2408:             return;
                   2409:         }
                   2410:     }
1.27      matthew  2411:     # Determine authentication method and password for the user being modified
                   2412:     my $amode='';
                   2413:     my $genpwd='';
1.101     albertel 2414:     if ($env{'form.login'} eq 'krb') {
1.41      albertel 2415: 	$amode='krb';
1.101     albertel 2416: 	$amode.=$env{'form.krbver'};
                   2417: 	$genpwd=$env{'form.krbarg'};
                   2418:     } elsif ($env{'form.login'} eq 'int') {
1.27      matthew  2419: 	$amode='internal';
1.101     albertel 2420: 	$genpwd=$env{'form.intarg'};
                   2421:     } elsif ($env{'form.login'} eq 'fsys') {
1.27      matthew  2422: 	$amode='unix';
1.101     albertel 2423: 	$genpwd=$env{'form.fsysarg'};
                   2424:     } elsif ($env{'form.login'} eq 'loc') {
1.27      matthew  2425: 	$amode='localauth';
1.101     albertel 2426: 	$genpwd=$env{'form.locarg'};
1.27      matthew  2427: 	$genpwd=" " if (!$genpwd);
1.101     albertel 2428:     } elsif (($env{'form.login'} eq 'nochange') ||
                   2429:              ($env{'form.login'} eq ''        )) { 
1.34      matthew  2430:         # There is no need to tell the user we did not change what they
                   2431:         # did not ask us to change.
1.35      matthew  2432:         # If they are creating a new user but have not specified login
                   2433:         # information this will be caught below.
1.30      matthew  2434:     } else {
1.193     raeburn  2435: 	    $r->print($error.&mt('Invalid login mode or password').$end.$rtnlink);    
1.30      matthew  2436: 	    return;
1.27      matthew  2437:     }
1.164     albertel 2438: 
1.188     raeburn  2439:     $r->print('<h3>'.&mt('User [_1] in domain [_2]',
                   2440: 			 $env{'form.ccuname'}, $env{'form.ccdomain'}).'</h3>');
1.344     bisitz   2441:     $r->print('<p class="LC_info">'.&mt('Please be patient').'</p>');
                   2442: 
1.193     raeburn  2443:     my (%alerts,%rulematch,%inst_results,%curr_rules);
1.334     raeburn  2444:     my @userinfo = ('firstname','middlename','lastname','generation','permanentemail','id');
1.361     raeburn  2445:     my @usertools = ('aboutme','blog','webdav','portfolio');
1.299     raeburn  2446:     my @requestcourses = ('official','unofficial','community');
1.362     raeburn  2447:     my @requestauthor = ('requestauthor');
1.286     raeburn  2448:     my ($othertitle,$usertypes,$types) = 
                   2449:         &Apache::loncommon::sorted_inst_types($env{'form.ccdomain'});
1.334     raeburn  2450:     my %canmodify_status =
                   2451:         &Apache::lonuserutils::can_modify_userinfo($context,$env{'form.ccdomain'},
                   2452:                                                    ['inststatus']);
1.101     albertel 2453:     if ($env{'form.makeuser'}) {
1.164     albertel 2454: 	$r->print('<h3>'.&mt('Creating new account.').'</h3>');
1.27      matthew  2455:         # Check for the authentication mode and password
                   2456:         if (! $amode || ! $genpwd) {
1.193     raeburn  2457: 	    $r->print($error.&mt('Invalid login mode or password').$end.$rtnlink);    
1.27      matthew  2458: 	    return;
1.18      albertel 2459: 	}
1.29      matthew  2460:         # Determine desired host
1.101     albertel 2461:         my $desiredhost = $env{'form.hserver'};
1.29      matthew  2462:         if (lc($desiredhost) eq 'default') {
                   2463:             $desiredhost = undef;
                   2464:         } else {
1.147     albertel 2465:             my %home_servers = 
                   2466: 		&Apache::lonnet::get_servers($env{'form.ccdomain'},'library');
1.29      matthew  2467:             if (! exists($home_servers{$desiredhost})) {
1.193     raeburn  2468:                 $r->print($error.&mt('Invalid home server specified').$end.$rtnlink);
                   2469:                 return;
                   2470:             }
                   2471:         }
                   2472:         # Check ID format
                   2473:         my %checkhash;
                   2474:         my %checks = ('id' => 1);
                   2475:         %{$checkhash{$env{'form.ccuname'}.':'.$env{'form.ccdomain'}}} = (
1.219     raeburn  2476:             'newuser' => $newuser, 
1.196     raeburn  2477:             'id' => $env{'form.cid'},
1.193     raeburn  2478:         );
1.196     raeburn  2479:         if ($env{'form.cid'} ne '') {
                   2480:             &Apache::loncommon::user_rule_check(\%checkhash,\%checks,\%alerts,
                   2481:                                           \%rulematch,\%inst_results,\%curr_rules);
                   2482:             if (ref($alerts{'id'}) eq 'HASH') {
                   2483:                 if (ref($alerts{'id'}{$env{'form.ccdomain'}}) eq 'HASH') {
                   2484:                     my $domdesc =
                   2485:                         &Apache::lonnet::domain($env{'form.ccdomain'},'description');
                   2486:                     if ($alerts{'id'}{$env{'form.ccdomain'}}{$env{'form.cid'}}) {
                   2487:                         my $userchkmsg;
                   2488:                         if (ref($curr_rules{$env{'form.ccdomain'}}) eq 'HASH') {
                   2489:                             $userchkmsg  = 
                   2490:                                 &Apache::loncommon::instrule_disallow_msg('id',
                   2491:                                                                     $domdesc,1).
                   2492:                                 &Apache::loncommon::user_rule_formats($env{'form.ccdomain'},
                   2493:                                     $domdesc,$curr_rules{$env{'form.ccdomain'}}{'id'},'id');
                   2494:                         }
                   2495:                         $r->print($error.&mt('Invalid ID format').$end.
                   2496:                                   $userchkmsg.$rtnlink);
                   2497:                         return;
                   2498:                     }
                   2499:                 }
1.29      matthew  2500:             }
                   2501:         }
1.27      matthew  2502: 	# Call modifyuser
                   2503: 	my $result = &Apache::lonnet::modifyuser
1.193     raeburn  2504: 	    ($env{'form.ccdomain'},$env{'form.ccuname'},$env{'form.cid'},
1.188     raeburn  2505:              $amode,$genpwd,$env{'form.cfirstname'},
                   2506:              $env{'form.cmiddlename'},$env{'form.clastname'},
                   2507:              $env{'form.cgeneration'},undef,$desiredhost,
                   2508:              $env{'form.cpermanentemail'});
1.77      www      2509: 	$r->print(&mt('Generating user').': '.$result);
1.219     raeburn  2510:         $uhome = &Apache::lonnet::homeserver($env{'form.ccuname'},
1.101     albertel 2511:                                                $env{'form.ccdomain'});
1.334     raeburn  2512:         my (%changeHash,%newcustom,%changed,%changedinfo);
1.267     raeburn  2513:         if ($uhome ne 'no_host') {
1.334     raeburn  2514:             if ($context eq 'domain') {
                   2515:                 if ($env{'form.customquota'} == 1) {
                   2516:                     if ($env{'form.portfolioquota'} eq '') {
                   2517:                         $newcustom{'quota'} = 0;
                   2518:                     } else {
                   2519:                         $newcustom{'quota'} = $env{'form.portfolioquota'};
                   2520:                         $newcustom{'quota'} =~ s/[^\d\.]//g;
                   2521:                     }
                   2522:                     $changed{'quota'} = &quota_admin($newcustom{'quota'},\%changeHash);
                   2523:                 }
                   2524:                 foreach my $item (@usertools) {
                   2525:                     if ($env{'form.custom'.$item} == 1) {
                   2526:                         $newcustom{$item} = $env{'form.tools_'.$item};
                   2527:                         $changed{$item} = &tool_admin($item,$newcustom{$item},
                   2528:                                                      \%changeHash,'tools');
                   2529:                     }
1.267     raeburn  2530:                 }
1.334     raeburn  2531:                 foreach my $item (@requestcourses) {
1.341     raeburn  2532:                     if ($env{'form.custom'.$item} == 1) {
                   2533:                         $newcustom{$item} = $env{'form.crsreq_'.$item};
                   2534:                         if ($env{'form.crsreq_'.$item} eq 'autolimit') {
                   2535:                             $newcustom{$item} .= '=';
                   2536:                             unless ($env{'form.crsreq_'.$item.'_limit'} =~ /\D/) {
                   2537:                                 $newcustom{$item} .= $env{'form.crsreq_'.$item.'_limit'};
                   2538:                             }
1.334     raeburn  2539:                         }
1.341     raeburn  2540:                         $changed{$item} = &tool_admin($item,$newcustom{$item},
                   2541:                                                       \%changeHash,'requestcourses');
1.334     raeburn  2542:                     }
1.275     raeburn  2543:                 }
1.362     raeburn  2544:                 if ($env{'form.customrequestauthor'} == 1) {
                   2545:                     $newcustom{'requestauthor'} = $env{'form.requestauthor'};
                   2546:                     $changed{'requestauthor'} = &tool_admin('requestauthor',
                   2547:                                                     $newcustom{'requestauthor'},
                   2548:                                                     \%changeHash,'requestauthor');
                   2549:                 }
1.275     raeburn  2550:             }
1.334     raeburn  2551:             if ($canmodify_status{'inststatus'}) {
                   2552:                 if (exists($env{'form.inststatus'})) {
                   2553:                     my @inststatuses = &Apache::loncommon::get_env_multiple('form.inststatus');
                   2554:                     if (@inststatuses > 0) {
                   2555:                         $changeHash{'inststatus'} = join(',',@inststatuses);
                   2556:                         $changed{'inststatus'} = $changeHash{'inststatus'};
1.306     raeburn  2557:                     }
                   2558:                 }
1.232     raeburn  2559:             }
1.334     raeburn  2560:             if (keys(%changed)) {
                   2561:                 foreach my $item (@userinfo) {
                   2562:                     $changeHash{$item}  = $env{'form.c'.$item};
1.286     raeburn  2563:                 }
1.267     raeburn  2564:                 my $chgresult =
                   2565:                      &Apache::lonnet::put('environment',\%changeHash,
                   2566:                                           $env{'form.ccdomain'},$env{'form.ccuname'});
                   2567:             } 
1.232     raeburn  2568:         }
1.219     raeburn  2569:         $r->print('<br />'.&mt('Home server').': '.$uhome.' '.
                   2570:                   &Apache::lonnet::hostname($uhome));
1.101     albertel 2571:     } elsif (($env{'form.login'} ne 'nochange') &&
                   2572:              ($env{'form.login'} ne ''        )) {
1.27      matthew  2573: 	# Modify user privileges
                   2574:         if (! $amode || ! $genpwd) {
1.193     raeburn  2575: 	    $r->print($error.'Invalid login mode or password'.$end.$rtnlink);    
1.27      matthew  2576: 	    return;
1.20      harris41 2577: 	}
1.27      matthew  2578: 	# Only allow authentification modification if the person has authority
1.101     albertel 2579: 	if (&Apache::lonnet::allowed('mau',$env{'form.ccdomain'})) {
1.20      harris41 2580: 	    $r->print('Modifying authentication: '.
1.31      matthew  2581:                       &Apache::lonnet::modifyuserauth(
1.101     albertel 2582: 		       $env{'form.ccdomain'},$env{'form.ccuname'},
1.21      harris41 2583:                        $amode,$genpwd));
1.102     albertel 2584:             $r->print('<br />'.&mt('Home server').': '.&Apache::lonnet::homeserver
1.101     albertel 2585: 		  ($env{'form.ccuname'},$env{'form.ccdomain'}));
1.4       www      2586: 	} else {
1.27      matthew  2587: 	    # Okay, this is a non-fatal error.
1.193     raeburn  2588: 	    $r->print($error.&mt('You do not have the authority to modify this users authentification information').'.'.$end);    
1.27      matthew  2589: 	}
1.28      matthew  2590:     }
1.344     bisitz   2591: 
                   2592:     $r->rflush(); # Finish display of header before time consuming actions start
                   2593: 
1.28      matthew  2594:     ##
1.343     raeburn  2595:     my (@userroles,%userupdate,$cnum,$cdom,%namechanged);
1.213     raeburn  2596:     if ($context eq 'course') {
                   2597:         ($cnum,$cdom) = &Apache::lonuserutils::get_course_identity();
1.318     raeburn  2598:         $crstype = &Apache::loncommon::course_type($cdom.'_'.$cnum);
1.213     raeburn  2599:     }
1.101     albertel 2600:     if (! $env{'form.makeuser'} ) {
1.28      matthew  2601:         # Check for need to change
                   2602:         my %userenv = &Apache::lonnet::get
1.134     raeburn  2603:             ('environment',['firstname','middlename','lastname','generation',
1.267     raeburn  2604:              'id','permanentemail','portfolioquota','inststatus','tools.aboutme',
1.361     raeburn  2605:              'tools.blog','tools.webdav','tools.portfolio',
                   2606:              'requestcourses.official','requestcourses.unofficial',
                   2607:              'requestcourses.community','reqcrsotherdom.official',
1.362     raeburn  2608:              'reqcrsotherdom.unofficial','reqcrsotherdom.community',
                   2609:              'requestauthor'],
1.160     raeburn  2610:               $env{'form.ccdomain'},$env{'form.ccuname'});
1.28      matthew  2611:         my ($tmp) = keys(%userenv);
                   2612:         if ($tmp =~ /^(con_lost|error)/i) { 
                   2613:             %userenv = ();
                   2614:         }
1.206     raeburn  2615:         my $no_forceid_alert;
                   2616:         # Check to see if user information can be changed
                   2617:         my %domconfig =
                   2618:             &Apache::lonnet::get_dom('configuration',['usermodification'],
                   2619:                                      $env{'form.ccdomain'});
1.213     raeburn  2620:         my @statuses = ('active','future');
                   2621:         my %roles = &Apache::lonnet::get_my_roles($env{'form.ccuname'},$env{'form.ccdomain'},'userroles',\@statuses,undef,$env{'request.role.domain'});
                   2622:         my ($auname,$audom);
1.220     raeburn  2623:         if ($context eq 'author') {
1.206     raeburn  2624:             $auname = $env{'user.name'};
                   2625:             $audom = $env{'user.domain'};     
                   2626:         }
                   2627:         foreach my $item (keys(%roles)) {
1.220     raeburn  2628:             my ($rolenum,$roledom,$role) = split(/:/,$item,-1);
1.206     raeburn  2629:             if ($context eq 'course') {
                   2630:                 if ($cnum ne '' && $cdom ne '') {
                   2631:                     if ($rolenum eq $cnum && $roledom eq $cdom) {
                   2632:                         if (!grep(/^\Q$role\E$/,@userroles)) {
                   2633:                             push(@userroles,$role);
                   2634:                         }
                   2635:                     }
                   2636:                 }
                   2637:             } elsif ($context eq 'author') {
                   2638:                 if ($rolenum eq $auname && $roledom eq $audom) {
                   2639:                     if (!grep(/^\Q$role\E$/,@userroles)) { 
                   2640:                         push(@userroles,$role);
                   2641:                     }
                   2642:                 }
                   2643:             }
                   2644:         }
1.220     raeburn  2645:         if ($env{'form.action'} eq 'singlestudent') {
                   2646:             if (!grep(/^st$/,@userroles)) {
                   2647:                 push(@userroles,'st');
                   2648:             }
                   2649:         } else {
                   2650:             # Check for course or co-author roles being activated or re-enabled
                   2651:             if ($context eq 'author' || $context eq 'course') {
                   2652:                 foreach my $key (keys(%env)) {
                   2653:                     if ($context eq 'author') {
                   2654:                         if ($key=~/^form\.act_\Q$audom\E_\Q$auname\E_([^_]+)/) {
                   2655:                             if (!grep(/^\Q$1\E$/,@userroles)) {
                   2656:                                 push(@userroles,$1);
                   2657:                             }
                   2658:                         } elsif ($key =~/^form\.ren\:\Q$audom\E\/\Q$auname\E_([^_]+)/) {
                   2659:                             if (!grep(/^\Q$1\E$/,@userroles)) {
                   2660:                                 push(@userroles,$1);
                   2661:                             }
1.206     raeburn  2662:                         }
1.220     raeburn  2663:                     } elsif ($context eq 'course') {
                   2664:                         if ($key=~/^form\.act_\Q$cdom\E_\Q$cnum\E_([^_]+)/) {
                   2665:                             if (!grep(/^\Q$1\E$/,@userroles)) {
                   2666:                                 push(@userroles,$1);
                   2667:                             }
                   2668:                         } elsif ($key =~/^form\.ren\:\Q$cdom\E\/\Q$cnum\E(\/?\w*)_([^_]+)/) {
                   2669:                             if (!grep(/^\Q$1\E$/,@userroles)) {
                   2670:                                 push(@userroles,$1);
                   2671:                             }
1.206     raeburn  2672:                         }
                   2673:                     }
                   2674:                 }
                   2675:             }
                   2676:         }
                   2677:         #Check to see if we can change personal data for the user 
                   2678:         my (@mod_disallowed,@longroles);
                   2679:         foreach my $role (@userroles) {
                   2680:             if ($role eq 'cr') {
                   2681:                 push(@longroles,'Custom');
                   2682:             } else {
1.318     raeburn  2683:                 push(@longroles,&Apache::lonnet::plaintext($role,$crstype)); 
1.206     raeburn  2684:             }
                   2685:         }
1.219     raeburn  2686:         my %canmodify = &Apache::lonuserutils::can_modify_userinfo($context,$env{'form.ccdomain'},\@userinfo,\@userroles);
                   2687:         foreach my $item (@userinfo) {
1.28      matthew  2688:             # Strip leading and trailing whitespace
1.203     raeburn  2689:             $env{'form.c'.$item} =~ s/(\s+$|^\s+)//g;
1.219     raeburn  2690:             if (!$canmodify{$item}) {
1.207     raeburn  2691:                 if (defined($env{'form.c'.$item})) {
                   2692:                     if ($env{'form.c'.$item} ne $userenv{$item}) {
                   2693:                         push(@mod_disallowed,$item);
                   2694:                     }
1.206     raeburn  2695:                 }
                   2696:                 $env{'form.c'.$item} = $userenv{$item};
                   2697:             }
1.28      matthew  2698:         }
1.259     bisitz   2699:         # Check to see if we can change the Student/Employee ID
1.196     raeburn  2700:         my $forceid = $env{'form.forceid'};
                   2701:         my $recurseid = $env{'form.recurseid'};
                   2702:         my (%alerts,%rulematch,%idinst_results,%curr_rules,%got_rules);
1.203     raeburn  2703:         my %uidhash = &Apache::lonnet::idrget($env{'form.ccdomain'},
                   2704:                                             $env{'form.ccuname'});
                   2705:         if (($uidhash{$env{'form.ccuname'}}) && 
                   2706:             ($uidhash{$env{'form.ccuname'}}!~/error\:/) && 
                   2707:             (!$forceid)) {
                   2708:             if ($env{'form.cid'} ne $uidhash{$env{'form.ccuname'}}) {
                   2709:                 $env{'form.cid'} = $userenv{'id'};
1.293     bisitz   2710:                 $no_forceid_alert = &mt('New student/employee ID does not match existing ID for this user.')
1.259     bisitz   2711:                                    .'<br />'
                   2712:                                    .&mt("Change is not permitted without checking the 'Force ID change' checkbox on the previous page.")
                   2713:                                    .'<br />'."\n";
1.203     raeburn  2714:             }
                   2715:         }
                   2716:         if ($env{'form.cid'} ne $userenv{'id'}) {
1.196     raeburn  2717:             my $checkhash;
                   2718:             my $checks = { 'id' => 1 };
                   2719:             $checkhash->{$env{'form.ccuname'}.':'.$env{'form.ccdomain'}} = 
                   2720:                    { 'newuser' => $newuser,
                   2721:                      'id'  => $env{'form.cid'}, 
                   2722:                    };
                   2723:             &Apache::loncommon::user_rule_check($checkhash,$checks,
                   2724:                 \%alerts,\%rulematch,\%idinst_results,\%curr_rules,\%got_rules);
                   2725:             if (ref($alerts{'id'}) eq 'HASH') {
                   2726:                 if (ref($alerts{'id'}{$env{'form.ccdomain'}}) eq 'HASH') {
1.203     raeburn  2727:                    $env{'form.cid'} = $userenv{'id'};
1.196     raeburn  2728:                 }
                   2729:             }
                   2730:         }
1.286     raeburn  2731:         my ($quotachanged,$oldportfolioquota,$newportfolioquota,$oldinststatus,
1.334     raeburn  2732:             $newinststatus,$oldisdefault,$newisdefault,%oldsettings,
1.339     raeburn  2733:             %oldsettingstext,%newsettings,%newsettingstext,@disporder,
                   2734:             $olddefquota,$oldsettingstatus,$newdefquota,$newsettingstatus);
1.334     raeburn  2735:         @disporder = ('inststatus');
                   2736:         if ($env{'request.role.domain'} eq $env{'form.ccdomain'}) {
1.362     raeburn  2737:             push(@disporder,'requestcourses','requestauthor');
1.334     raeburn  2738:         } else {
                   2739:             push(@disporder,'reqcrsotherdom');
                   2740:         }
                   2741:         push(@disporder,('quota','tools'));
1.338     raeburn  2742:         $oldinststatus = $userenv{'inststatus'};
1.339     raeburn  2743:         ($olddefquota,$oldsettingstatus) = 
1.334     raeburn  2744:             &Apache::loncommon::default_quota($env{'form.ccdomain'},$oldinststatus);
1.339     raeburn  2745:         ($newdefquota,$newsettingstatus) = ($olddefquota,$oldsettingstatus);
1.334     raeburn  2746:         my %canshow;
1.220     raeburn  2747:         if (&Apache::lonnet::allowed('mpq',$env{'form.ccdomain'})) {
1.334     raeburn  2748:             $canshow{'quota'} = 1;
1.220     raeburn  2749:         }
1.267     raeburn  2750:         if (&Apache::lonnet::allowed('mut',$env{'form.ccdomain'})) {
1.334     raeburn  2751:             $canshow{'tools'} = 1;
1.267     raeburn  2752:         }
1.275     raeburn  2753:         if (&Apache::lonnet::allowed('ccc',$env{'form.ccdomain'})) {
1.334     raeburn  2754:             $canshow{'requestcourses'} = 1;
1.300     raeburn  2755:         } elsif (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'})) {
1.334     raeburn  2756:             $canshow{'reqcrsotherdom'} = 1;
1.275     raeburn  2757:         }
1.286     raeburn  2758:         if (&Apache::lonnet::allowed('mau',$env{'form.ccdomain'})) {
1.334     raeburn  2759:             $canshow{'inststatus'} = 1;
1.286     raeburn  2760:         }
1.362     raeburn  2761:         if (&Apache::lonnet::allowed('cau',$env{'form.ccdomain'})) {
                   2762:             $canshow{'requestauthor'} = 1;
                   2763:         }
1.267     raeburn  2764:         my (%changeHash,%changed);
1.286     raeburn  2765:         if ($oldinststatus eq '') {
1.334     raeburn  2766:             $oldsettings{'inststatus'} = $othertitle; 
1.286     raeburn  2767:         } else {
                   2768:             if (ref($usertypes) eq 'HASH') {
1.334     raeburn  2769:                 $oldsettings{'inststatus'} = join(', ',map{ $usertypes->{ &unescape($_) }; } (split(/:/,$userenv{'inststatus'})));
1.286     raeburn  2770:             } else {
1.334     raeburn  2771:                 $oldsettings{'inststatus'} = join(', ',map{ &unescape($_); } (split(/:/,$userenv{'inststatus'})));
1.286     raeburn  2772:             }
                   2773:         }
                   2774:         $changeHash{'inststatus'} = $userenv{'inststatus'};
1.334     raeburn  2775:         if ($canmodify_status{'inststatus'}) {
                   2776:             $canshow{'inststatus'} = 1;
1.286     raeburn  2777:             if (exists($env{'form.inststatus'})) {
                   2778:                 my @inststatuses = &Apache::loncommon::get_env_multiple('form.inststatus');
                   2779:                 if (@inststatuses > 0) {
                   2780:                     $newinststatus = join(':',map { &escape($_); } @inststatuses);
                   2781:                     $changeHash{'inststatus'} = $newinststatus;
                   2782:                     if ($newinststatus ne $oldinststatus) {
                   2783:                         $changed{'inststatus'} = $newinststatus;
1.339     raeburn  2784:                         ($newdefquota,$newsettingstatus) =
                   2785:                             &Apache::loncommon::default_quota($env{'form.ccdomain'},$newinststatus);
1.286     raeburn  2786:                     }
                   2787:                     if (ref($usertypes) eq 'HASH') {
1.334     raeburn  2788:                         $newsettings{'inststatus'} = join(', ',map{ $usertypes->{$_}; } (@inststatuses)); 
1.286     raeburn  2789:                     } else {
1.337     raeburn  2790:                         $newsettings{'inststatus'} = join(', ',@inststatuses);
1.286     raeburn  2791:                     }
1.334     raeburn  2792:                 }
                   2793:             } else {
                   2794:                 $newinststatus = '';
                   2795:                 $changeHash{'inststatus'} = $newinststatus;
                   2796:                 $newsettings{'inststatus'} = $othertitle;
                   2797:                 if ($newinststatus ne $oldinststatus) {
                   2798:                     $changed{'inststatus'} = $changeHash{'inststatus'};
1.339     raeburn  2799:                     ($newdefquota,$newsettingstatus) =
                   2800:                         &Apache::loncommon::default_quota($env{'form.ccdomain'},$newinststatus);
1.286     raeburn  2801:                 }
                   2802:             }
1.334     raeburn  2803:         } elsif ($context ne 'selfcreate') {
                   2804:             $canshow{'inststatus'} = 1;
1.337     raeburn  2805:             $newsettings{'inststatus'} = $oldsettings{'inststatus'};
1.286     raeburn  2806:         }
1.204     raeburn  2807:         $changeHash{'portfolioquota'} = $userenv{'portfolioquota'};
1.334     raeburn  2808:         if ($context eq 'domain') {
                   2809:             if ($userenv{'portfolioquota'} ne '') {
                   2810:                 $oldportfolioquota = $userenv{'portfolioquota'};
                   2811:                 if ($env{'form.customquota'} == 1) {
                   2812:                     if ($env{'form.portfolioquota'} eq '') {
                   2813:                         $newportfolioquota = 0;
                   2814:                     } else {
                   2815:                         $newportfolioquota = $env{'form.portfolioquota'};
                   2816:                         $newportfolioquota =~ s/[^\d\.]//g;
                   2817:                     }
                   2818:                     if ($newportfolioquota != $oldportfolioquota) {
                   2819:                         $changed{'quota'} = &quota_admin($newportfolioquota,\%changeHash);
                   2820:                     }
1.149     raeburn  2821:                 } else {
1.334     raeburn  2822:                     $changed{'quota'} = &quota_admin('',\%changeHash);
1.339     raeburn  2823:                     $newportfolioquota = $newdefquota;
1.334     raeburn  2824:                     $newisdefault = 1;
1.149     raeburn  2825:                 }
1.334     raeburn  2826:             } else {
                   2827:                 $oldisdefault = 1;
1.339     raeburn  2828:                 $oldportfolioquota = $olddefquota;
1.334     raeburn  2829:                 if ($env{'form.customquota'} == 1) {
                   2830:                     if ($env{'form.portfolioquota'} eq '') {
                   2831:                         $newportfolioquota = 0;
                   2832:                     } else {
                   2833:                         $newportfolioquota = $env{'form.portfolioquota'};
                   2834:                         $newportfolioquota =~ s/[^\d\.]//g;
                   2835:                     }
1.267     raeburn  2836:                     $changed{'quota'} = &quota_admin($newportfolioquota,\%changeHash);
1.334     raeburn  2837:                 } else {
1.339     raeburn  2838:                     $newportfolioquota = $newdefquota;
1.334     raeburn  2839:                     $newisdefault = 1;
1.134     raeburn  2840:                 }
                   2841:             }
1.334     raeburn  2842:             if ($oldisdefault) {
1.339     raeburn  2843:                 $oldsettingstext{'quota'} = &get_defaultquota_text($oldsettingstatus);
1.334     raeburn  2844:             }
                   2845:             if ($newisdefault) {
1.339     raeburn  2846:                 $newsettingstext{'quota'} = &get_defaultquota_text($newsettingstatus);
1.334     raeburn  2847:             }
                   2848:             &tool_changes('tools',\@usertools,\%oldsettings,\%oldsettingstext,\%userenv,
                   2849:                           \%changeHash,\%changed,\%newsettings,\%newsettingstext);
                   2850:             if ($env{'form.ccdomain'} eq $env{'request.role.domain'}) {
                   2851:                 &tool_changes('requestcourses',\@requestcourses,\%oldsettings,\%oldsettingstext,
                   2852:                               \%userenv,\%changeHash,\%changed,\%newsettings,\%newsettingstext);
1.362     raeburn  2853:                 &tool_changes('requestauthor',\@requestauthor,\%oldsettings,\%oldsettingstext,\%userenv,\%changeHash,\%changed,\%newsettings,\%newsettingstext);
1.149     raeburn  2854:             } else {
1.334     raeburn  2855:                 &tool_changes('reqcrsotherdom',\@requestcourses,\%oldsettings,\%oldsettingstext,
                   2856:                               \%userenv,\%changeHash,\%changed,\%newsettings,\%newsettingstext);
1.149     raeburn  2857:             }
                   2858:         }
1.334     raeburn  2859:         foreach my $item (@userinfo) {
                   2860:             if ($env{'form.c'.$item} ne $userenv{$item}) {
                   2861:                 $namechanged{$item} = 1;
                   2862:             }
1.204     raeburn  2863:         }
1.334     raeburn  2864:         $oldsettings{'quota'} = $oldportfolioquota.' Mb';
                   2865:         $newsettings{'quota'} = $newportfolioquota.' Mb';
                   2866:         if ((keys(%namechanged) > 0) || (keys(%changed) > 0)) {
1.267     raeburn  2867:             my ($chgresult,$namechgresult);
                   2868:             if (keys(%changed) > 0) {
                   2869:                 $chgresult = 
1.204     raeburn  2870:                     &Apache::lonnet::put('environment',\%changeHash,
                   2871:                                   $env{'form.ccdomain'},$env{'form.ccuname'});
1.267     raeburn  2872:                 if ($chgresult eq 'ok') {
                   2873:                     if (($env{'user.name'} eq $env{'form.ccuname'}) &&
                   2874:                         ($env{'user.domain'} eq $env{'form.ccdomain'})) {
1.270     raeburn  2875:                         my %newenvhash;
                   2876:                         foreach my $key (keys(%changed)) {
1.299     raeburn  2877:                             if (($key eq 'official') || ($key eq 'unofficial')
                   2878:                                 || ($key eq 'community')) {
1.279     raeburn  2879:                                 $newenvhash{'environment.requestcourses.'.$key} =
                   2880:                                     $changeHash{'requestcourses.'.$key};
1.362     raeburn  2881:                                 if ($changeHash{'requestcourses.'.$key}) {
1.332     raeburn  2882:                                     $newenvhash{'environment.canrequest.'.$key} = 1;
1.279     raeburn  2883:                                 } else {
                   2884:                                     $newenvhash{'environment.canrequest.'.$key} =
                   2885:           &Apache::lonnet::usertools_access($env{'user.name'},$env{'user.domain'},
                   2886:                                             $key,'reload','requestcourses');
                   2887:                                 }
1.362     raeburn  2888:                             } elsif ($key eq 'requestauthor') {
                   2889:                                 $newenvhash{'environment.'.$key} = $changeHash{$key};
                   2890:                                 if ($changeHash{$key}) {
                   2891:                                     $newenvhash{'environment.canrequest.author'} = 1;
                   2892:                                 } else {
                   2893:                                     $newenvhash{'environment.canrequest.author'} =
                   2894:           &Apache::lonnet::usertools_access($env{'user.name'},$env{'user.domain'},
                   2895:                                             $key,'reload','requestauthor');
                   2896:                                 }
1.275     raeburn  2897:                             } elsif ($key ne 'quota') {
1.270     raeburn  2898:                                 $newenvhash{'environment.tools.'.$key} = 
                   2899:                                     $changeHash{'tools.'.$key};
1.279     raeburn  2900:                                 if ($changeHash{'tools.'.$key} ne '') {
                   2901:                                     $newenvhash{'environment.availabletools.'.$key} =
                   2902:                                         $changeHash{'tools.'.$key};
                   2903:                                 } else {
                   2904:                                     $newenvhash{'environment.availabletools.'.$key} =
                   2905:           &Apache::lonnet::usertools_access($env{'user.name'},$env{'user.domain'},                                            $key,'reload','tools');
                   2906:                                 }
1.270     raeburn  2907:                             }
                   2908:                         }
1.271     raeburn  2909:                         if (keys(%newenvhash)) {
                   2910:                             &Apache::lonnet::appenv(\%newenvhash);
                   2911:                         }
1.267     raeburn  2912:                     }
                   2913:                 }
1.204     raeburn  2914:             }
1.334     raeburn  2915:             if (keys(%namechanged) > 0) {
1.337     raeburn  2916:                 foreach my $field (@userinfo) {
                   2917:                     $changeHash{$field}  = $env{'form.c'.$field};
                   2918:                 }
                   2919: # Make the change
1.204     raeburn  2920:                 $namechgresult =
                   2921:                     &Apache::lonnet::modifyuser($env{'form.ccdomain'},
                   2922:                         $env{'form.ccuname'},$changeHash{'id'},undef,undef,
                   2923:                         $changeHash{'firstname'},$changeHash{'middlename'},
                   2924:                         $changeHash{'lastname'},$changeHash{'generation'},
1.337     raeburn  2925:                         $changeHash{'id'},undef,$changeHash{'permanentemail'},undef,\@userinfo);
1.220     raeburn  2926:                 %userupdate = (
                   2927:                                lastname   => $env{'form.clastname'},
                   2928:                                middlename => $env{'form.cmiddlename'},
                   2929:                                firstname  => $env{'form.cfirstname'},
                   2930:                                generation => $env{'form.cgeneration'},
                   2931:                                id         => $env{'form.cid'},
                   2932:                              );
1.204     raeburn  2933:             }
1.334     raeburn  2934:             if (((keys(%namechanged) > 0) && $namechgresult eq 'ok') || 
1.267     raeburn  2935:                 ((keys(%changed) > 0) && $chgresult eq 'ok')) {
1.28      matthew  2936:             # Tell the user we changed the name
1.334     raeburn  2937:                 &display_userinfo($r,1,\@disporder,\%canshow,\@requestcourses,
1.362     raeburn  2938:                                   \@usertools,\@requestauthor,\%userenv,\%changed,\%namechanged,
1.334     raeburn  2939:                                   \%oldsettings, \%oldsettingstext,\%newsettings,
                   2940:                                   \%newsettingstext);
1.203     raeburn  2941:                 if ($env{'form.cid'} ne $userenv{'id'}) {
                   2942:                     &Apache::lonnet::idput($env{'form.ccdomain'},
                   2943:                          ($env{'form.ccuname'} => $env{'form.cid'}));
                   2944:                     if (($recurseid) &&
                   2945:                         (&Apache::lonnet::allowed('mau',$env{'form.ccdomain'}))) {
                   2946:                         my $idresult = 
                   2947:                             &Apache::lonuserutils::propagate_id_change(
                   2948:                                 $env{'form.ccuname'},$env{'form.ccdomain'},
                   2949:                                 \%userupdate);
                   2950:                         $r->print('<br />'.$idresult.'<br />');
                   2951:                     }
1.196     raeburn  2952:                 }
1.149     raeburn  2953:                 if (($env{'form.ccdomain'} eq $env{'user.domain'}) && 
                   2954:                     ($env{'form.ccuname'} eq $env{'user.name'})) {
                   2955:                     my %newenvhash;
                   2956:                     foreach my $key (keys(%changeHash)) {
                   2957:                         $newenvhash{'environment.'.$key} = $changeHash{$key};
                   2958:                     }
1.238     raeburn  2959:                     &Apache::lonnet::appenv(\%newenvhash);
1.149     raeburn  2960:                 }
1.28      matthew  2961:             } else { # error occurred
1.188     raeburn  2962:                 $r->print('<span class="LC_error">'.&mt('Unable to successfully change environment for').' '.
                   2963:                       $env{'form.ccuname'}.' '.&mt('in domain').' '.
1.206     raeburn  2964:                       $env{'form.ccdomain'}.'</span><br />');
1.28      matthew  2965:             }
1.334     raeburn  2966:         } else { # End of if ($env ... ) logic
1.275     raeburn  2967:             # They did not want to change the users name, quota, tool availability,
                   2968:             # or ability to request creation of courses, 
1.267     raeburn  2969:             # but we can still tell them what the name and quota and availabilities are  
1.334     raeburn  2970:             &display_userinfo($r,undef,\@disporder,\%canshow,\@requestcourses,
1.362     raeburn  2971:                               \@usertools,\@requestauthor,\%userenv,\%changed,\%namechanged,\%oldsettings,
1.334     raeburn  2972:                               \%oldsettingstext,\%newsettings,\%newsettingstext);
1.28      matthew  2973:         }
1.206     raeburn  2974:         if (@mod_disallowed) {
                   2975:             my ($rolestr,$contextname);
                   2976:             if (@longroles > 0) {
                   2977:                 $rolestr = join(', ',@longroles);
                   2978:             } else {
                   2979:                 $rolestr = &mt('No roles');
                   2980:             }
                   2981:             if ($context eq 'course') {
                   2982:                 $contextname = &mt('course');
                   2983:             } elsif ($context eq 'author') {
                   2984:                 $contextname = &mt('co-author');
                   2985:             }
                   2986:             $r->print(&mt('The following fields were not updated: ').'<ul>');
                   2987:             my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
                   2988:             foreach my $field (@mod_disallowed) {
                   2989:                 $r->print('<li>'.$fieldtitles{$field}.'</li>'."\n"); 
                   2990:             }
1.207     raeburn  2991:             $r->print('</ul>');
                   2992:             if (@mod_disallowed == 1) {
                   2993:                 $r->print(&mt("You do not have the authority to change this field given the user's current set of active/future [_1] roles:",$contextname));
                   2994:             } else {
                   2995:                 $r->print(&mt("You do not have the authority to change these fields given the user's current set of active/future [_1] roles:",$contextname));
                   2996:             }
1.292     bisitz   2997:             my $helplink = 'javascript:helpMenu('."'display'".')';
                   2998:             $r->print('<span class="LC_cusr_emph">'.$rolestr.'</span><br />'
                   2999:                      .&mt('Please contact your [_1]helpdesk[_2] for more information.'
                   3000:                          ,'<a href="'.$helplink.'">','</a>')
                   3001:                       .'<br />');
1.206     raeburn  3002:         }
1.259     bisitz   3003:         $r->print('<span class="LC_warning">'
                   3004:                   .$no_forceid_alert
                   3005:                   .&Apache::lonuserutils::print_namespacing_alerts($env{'form.ccdomain'},\%alerts,\%curr_rules)
                   3006:                   .'</span>');
1.4       www      3007:     }
1.220     raeburn  3008:     if ($env{'form.action'} eq 'singlestudent') {
1.318     raeburn  3009:         &enroll_single_student($r,$uhome,$amode,$genpwd,$now,$newuser,$context,$crstype);
                   3010:         $r->print('<p><a href="javascript:backPage(document.userupdate)">');
                   3011:         if ($crstype eq 'Community') {
                   3012:             $r->print(&mt('Enroll Another Member'));
                   3013:         } else {
                   3014:             $r->print(&mt('Enroll Another Student'));
                   3015:         }
                   3016:         $r->print('</a></p>');
1.220     raeburn  3017:     } else {
1.239     raeburn  3018:         my @rolechanges = &update_roles($r,$context);
1.334     raeburn  3019:         if (keys(%namechanged) > 0) {
1.220     raeburn  3020:             if ($context eq 'course') {
                   3021:                 if (@userroles > 0) {
1.225     raeburn  3022:                     if ((@rolechanges == 0) || 
                   3023:                         (!(grep(/^st$/,@rolechanges)))) {
                   3024:                         if (grep(/^st$/,@userroles)) {
                   3025:                             my $classlistupdated =
                   3026:                                 &Apache::lonuserutils::update_classlist($cdom,
1.220     raeburn  3027:                                               $cnum,$env{'form.ccdomain'},
                   3028:                                        $env{'form.ccuname'},\%userupdate);
1.225     raeburn  3029:                         }
1.220     raeburn  3030:                     }
                   3031:                 }
                   3032:             }
                   3033:         }
1.226     raeburn  3034:         my $userinfo = &Apache::loncommon::plainname($env{'form.ccuname'},
1.233     raeburn  3035:                                                      $env{'form.ccdomain'});
                   3036:         if ($env{'form.popup'}) {
                   3037:             $r->print('<p><a href="javascript:window.close()">'.&mt('Close window').'</a></p>');
                   3038:         } else {
1.246     bisitz   3039:             $r->print('<p><a href="javascript:backPage(document.userupdate,'."'$env{'form.prevphase'}','modify'".')">'
                   3040:                      .&mt('Modify this user: [_1]','<span class="LC_cusr_emph">'.$env{'form.ccuname'}.':'.$env{'form.ccdomain'}.' ('.$userinfo.')</span>').'</a>'
                   3041:                      .('&nbsp;'x5).'<a href="javascript:backPage(document.userupdate)">'
                   3042:                      .&mt('Create/Modify Another User').'</a></p>');
1.233     raeburn  3043:         }
1.220     raeburn  3044:     }
                   3045: }
                   3046: 
1.334     raeburn  3047: sub display_userinfo {
1.362     raeburn  3048:     my ($r,$changed,$order,$canshow,$requestcourses,$usertools,$requestauthor,
                   3049:         $userenv,$changedhash,$namechangedhash,$oldsetting,$oldsettingtext,
1.334     raeburn  3050:         $newsetting,$newsettingtext) = @_;
                   3051:     return unless (ref($order) eq 'ARRAY' &&
                   3052:                    ref($canshow) eq 'HASH' && 
                   3053:                    ref($requestcourses) eq 'ARRAY' && 
1.362     raeburn  3054:                    ref($requestauthor) eq 'ARRAY' &&
1.334     raeburn  3055:                    ref($usertools) eq 'ARRAY' && 
                   3056:                    ref($userenv) eq 'HASH' &&
                   3057:                    ref($changedhash) eq 'HASH' &&
                   3058:                    ref($oldsetting) eq 'HASH' &&
                   3059:                    ref($oldsettingtext) eq 'HASH' &&
                   3060:                    ref($newsetting) eq 'HASH' &&
                   3061:                    ref($newsettingtext) eq 'HASH');
                   3062:     my %lt=&Apache::lonlocal::texthash(
                   3063:          'ui'             => 'User Information (unchanged)',
                   3064:          'uic'            => 'User Information Changed',
                   3065:          'firstname'      => 'First Name',
                   3066:          'middlename'     => 'Middle Name',
                   3067:          'lastname'       => 'Last Name',
                   3068:          'generation'     => 'Generation',
                   3069:          'id'             => 'Student/Employee ID',
                   3070:          'permanentemail' => 'Permanent e-mail address',
                   3071:          'quota'          => 'Disk space allocated to portfolio files',
                   3072:          'blog'           => 'Blog Availability',
1.361     raeburn  3073:          'webdav'         => 'WebDAV Availability',
1.334     raeburn  3074:          'aboutme'        => 'Personal Information Page Availability',
                   3075:          'portfolio'      => 'Portfolio Availability',
                   3076:          'official'       => 'Can Request Official Courses',
                   3077:          'unofficial'     => 'Can Request Unofficial Courses',
                   3078:          'community'      => 'Can Request Communities',
1.362     raeburn  3079:          'requestauthor'  => 'Can Request Author Role',
1.334     raeburn  3080:          'inststatus'     => "Affiliation",
                   3081:          'prvs'           => 'Previous Value:',
                   3082:          'chto'           => 'Changed To:'
                   3083:     );
                   3084:     my $title = $lt{'ui'}; 
                   3085:     if ($changed) {
                   3086:         $title = $lt{'uic'};
                   3087:     }
                   3088:     $r->print('<h4>'.$title.'</h4>'.
                   3089:               &Apache::loncommon::start_data_table().
                   3090:               &Apache::loncommon::start_data_table_header_row());
                   3091:     if ($changed) {
                   3092:         $r->print("<th>&nbsp;</th>\n");
                   3093:     }
                   3094:     my @userinfo = ('firstname','middlename','lastname','generation','permanentemail','id');
                   3095:     foreach my $item (@userinfo) {
                   3096:         $r->print("<th>$lt{$item}</th>\n");
                   3097:     }
                   3098:     foreach my $entry (@{$order}) {
                   3099:         if ($canshow->{$entry}) {
                   3100:             if (($entry eq 'requestcourses') || ($entry eq 'reqcrsotherdom')) {
                   3101:                 foreach my $item (@{$requestcourses}) {
                   3102:                     $r->print("<th>$lt{$item}</th>\n");
                   3103:                 }
                   3104:             } elsif ($entry eq 'tools') {
                   3105:                 foreach my $item (@{$usertools}) {
                   3106:                     $r->print("<th>$lt{$item}</th>\n");
                   3107:                 }
                   3108:             } else {
                   3109:                 $r->print("<th>$lt{$entry}</th>\n");
                   3110:             }
                   3111:         }
                   3112:     }
                   3113:     $r->print(&Apache::loncommon::end_data_table_header_row().
                   3114:              &Apache::loncommon::start_data_table_row());
                   3115:     if ($changed) {
                   3116:         $r->print('<td><b>'.$lt{'prvs'}.'</b></td>'."\n");
                   3117:     }
                   3118:     foreach my $item (@userinfo) {
                   3119:         $r->print('<td>'.$userenv->{$item}.' </td>'."\n");
                   3120:     }
                   3121:     foreach my $entry (@{$order}) {
                   3122:         if ($canshow->{$entry}) {
                   3123:             if (($entry eq 'requestcourses') || ($entry eq 'reqcrsotherdom')) {
                   3124:                 foreach my $item (@{$requestcourses}) {
                   3125:                     $r->print("<td>$oldsetting->{$item} $oldsettingtext->{$item}</td>\n");
                   3126:                 }
                   3127:             } elsif ($entry eq 'tools') {
                   3128:                 foreach my $item (@{$usertools}) {
                   3129:                     $r->print("<td>$oldsetting->{$item} $oldsettingtext->{$item}</td>\n");
                   3130:                 }
                   3131:             } else {
                   3132:                 $r->print("<td>$oldsetting->{$entry} $oldsettingtext->{$entry} </td>\n");
                   3133:             }
                   3134:         }
                   3135:     }
                   3136:     $r->print(&Apache::loncommon::end_data_table_row());
                   3137:     if ($changed) {
                   3138:         $r->print(&Apache::loncommon::start_data_table_row().
                   3139:                   '<td><span class="LC_nobreak"><b>'.$lt{'chto'}.'</b></span></td>'."\n");
                   3140:         foreach my $item (@userinfo) {
                   3141:             my $value = $env{'form.c'.$item};
                   3142:             if ($namechangedhash->{$item}) {
                   3143:                 $value = '<span class="LC_cusr_emph">'.$value.'</span>';
                   3144:             }
                   3145:             $r->print("<td>$value </td>\n");
                   3146:         }
                   3147:         foreach my $entry (@{$order}) {
                   3148:             if ($canshow->{$entry}) {
                   3149:                 if (($entry eq 'requestcourses') || ($entry eq 'reqcrsotherdom')) {
                   3150:                     foreach my $item (@{$requestcourses}) {
                   3151:                         my $value = $newsetting->{$item}.' '.$newsettingtext->{$item};
                   3152:                         if ($changedhash->{$item}) {
                   3153:                             $value = '<span class="LC_cusr_emph">'.$value.'</span>';
                   3154:                         }
                   3155:                         $r->print("<td>$value </td>\n");
                   3156:                     }
                   3157:                 } elsif ($entry eq 'tools') {
                   3158:                     foreach my $item (@{$usertools}) {
                   3159:                         my $value = $newsetting->{$item}.' '.$newsettingtext->{$item};
                   3160:                         if ($changedhash->{$item}) {
                   3161:                             $value = '<span class="LC_cusr_emph">'.$value.'</span>';
                   3162:                         }
                   3163:                         $r->print("<td>$value </td>\n");
                   3164:                     }
                   3165:                 } else {
                   3166:                     my $value = $newsetting->{$entry}.' '.$newsettingtext->{$entry};
                   3167:                     if ($changedhash->{$entry}) {
                   3168:                         $value = '<span class="LC_cusr_emph">'.$value.'</span>';
                   3169:                     }
                   3170:                     $r->print("<td>$value </td>\n");
                   3171:                 }
                   3172:             }
                   3173:         }
                   3174:         $r->print(&Apache::loncommon::end_data_table_row());
                   3175:     }
                   3176:     $r->print(&Apache::loncommon::end_data_table().'<br />');
                   3177:     return;
                   3178: }
                   3179: 
1.275     raeburn  3180: sub tool_changes {
                   3181:     my ($context,$usertools,$oldaccess,$oldaccesstext,$userenv,$changeHash,
                   3182:         $changed,$newaccess,$newaccesstext) = @_;
                   3183:     if (!((ref($usertools) eq 'ARRAY') && (ref($oldaccess) eq 'HASH') &&
                   3184:           (ref($oldaccesstext) eq 'HASH') && (ref($userenv) eq 'HASH') &&
                   3185:           (ref($changeHash) eq 'HASH') && (ref($changed) eq 'HASH') &&
                   3186:           (ref($newaccess) eq 'HASH') && (ref($newaccesstext) eq 'HASH'))) {
                   3187:         return;
                   3188:     }
1.300     raeburn  3189:     if ($context eq 'reqcrsotherdom') {
1.309     raeburn  3190:         my @options = ('approval','validate','autolimit');
1.306     raeburn  3191:         my $optregex = join('|',@options);
                   3192:         my %reqdisplay = &courserequest_display();
1.300     raeburn  3193:         my $cdom = $env{'request.role.domain'};
                   3194:         foreach my $tool (@{$usertools}) {
1.314     raeburn  3195:             $oldaccesstext->{$tool} = &mt('No');
                   3196:             $newaccesstext->{$tool} = $oldaccesstext->{$tool};
1.300     raeburn  3197:             $changeHash->{$context.'.'.$tool} = $userenv->{$context.'.'.$tool};
1.314     raeburn  3198:             my $newop;
                   3199:             if ($env{'form.'.$context.'_'.$tool}) {
                   3200:                 $newop = $env{'form.'.$context.'_'.$tool};
                   3201:                 if ($newop eq 'autolimit') {
                   3202:                     my $limit = $env{'form.'.$context.'_'.$tool.'_limit'};
                   3203:                     $limit =~ s/\D+//g;
                   3204:                     $newop .= '='.$limit;
                   3205:                 }
                   3206:             }
1.300     raeburn  3207:             if ($userenv->{$context.'.'.$tool} eq '') {
1.314     raeburn  3208:                 if ($newop) {
                   3209:                     $changed->{$tool}=&tool_admin($tool,$cdom.':'.$newop,
1.300     raeburn  3210:                                                   $changeHash,$context);
                   3211:                     if ($changed->{$tool}) {
1.314     raeburn  3212:                         $newaccesstext->{$tool} = &mt('Yes');
1.300     raeburn  3213:                     } else {
                   3214:                         $newaccesstext->{$tool} = $oldaccesstext->{$tool};
                   3215:                     }
                   3216:                 }
                   3217:             } else {
                   3218:                 my @curr = split(',',$userenv->{$context.'.'.$tool});
                   3219:                 my @new;
                   3220:                 my $changedoms;
1.314     raeburn  3221:                 foreach my $req (@curr) {
                   3222:                     if ($req =~ /^\Q$cdom\E\:($optregex\=?\d*)$/) {
                   3223:                         $oldaccesstext->{$tool} = &mt('Yes');
                   3224:                         my $oldop = $1;
                   3225:                         if ($oldop ne $newop) {
                   3226:                             $changedoms = 1;
                   3227:                             foreach my $item (@curr) {
                   3228:                                 my ($reqdom,$option) = split(':',$item);
                   3229:                                 unless ($reqdom eq $cdom) {
                   3230:                                     push(@new,$item);
                   3231:                                 }
                   3232:                             }
                   3233:                             if ($newop) {
                   3234:                                 push(@new,$cdom.':'.$newop);
1.300     raeburn  3235:                             }
1.314     raeburn  3236:                             @new = sort(@new);
1.300     raeburn  3237:                         }
1.314     raeburn  3238:                         last;
1.300     raeburn  3239:                     }
1.314     raeburn  3240:                 }
                   3241:                 if ((!$changedoms) && ($newop)) {
1.300     raeburn  3242:                     $changedoms = 1;
1.306     raeburn  3243:                     @new = sort(@curr,$cdom.':'.$newop);
1.300     raeburn  3244:                 }
                   3245:                 if ($changedoms) {
1.314     raeburn  3246:                     my $newdomstr;
1.300     raeburn  3247:                     if (@new) {
                   3248:                         $newdomstr = join(',',@new);
                   3249:                     }
                   3250:                     $changed->{$tool}=&tool_admin($tool,$newdomstr,$changeHash,
                   3251:                                                   $context);
                   3252:                     if ($changed->{$tool}) {
                   3253:                         if ($env{'form.'.$context.'_'.$tool}) {
1.306     raeburn  3254:                             if ($env{'form.'.$context.'_'.$tool} eq 'autolimit') {
1.314     raeburn  3255:                                 my $limit = $env{'form.'.$context.'_'.$tool.'_limit'};
                   3256:                                 $limit =~ s/\D+//g;
                   3257:                                 if ($limit) {
                   3258:                                     $newaccesstext->{$tool} = &mt('Yes, up to limit of [quant,_1,request] per user.',$limit);
                   3259:                                 } else {
1.306     raeburn  3260:                                     $newaccesstext->{$tool} = &mt('Yes, processed automatically');
                   3261:                                 }
1.314     raeburn  3262:                             } else {
1.306     raeburn  3263:                                 $newaccesstext->{$tool} = $reqdisplay{$env{'form.'.$context.'_'.$tool}};
                   3264:                             }
1.300     raeburn  3265:                         } else {
1.306     raeburn  3266:                             $newaccesstext->{$tool} = &mt('No');
1.300     raeburn  3267:                         }
                   3268:                     }
                   3269:                 }
                   3270:             }
                   3271:         }
                   3272:         return;
                   3273:     }
1.275     raeburn  3274:     foreach my $tool (@{$usertools}) {
1.362     raeburn  3275:         my ($newval,$envkey);
                   3276:         $envkey = $context.'.'.$tool;
1.306     raeburn  3277:         if ($context eq 'requestcourses') {
                   3278:             $newval = $env{'form.crsreq_'.$tool};
                   3279:             if ($newval eq 'autolimit') {
                   3280:                 $newval .= '='.$env{'form.crsreq_'.$tool.'_limit'};
                   3281:             }
1.362     raeburn  3282:         } elsif ($context eq 'requestauthor') {
                   3283:             $newval = $env{'form.'.$context};
                   3284:             $envkey = $context;
1.314     raeburn  3285:         } else {
1.306     raeburn  3286:             $newval = $env{'form.'.$context.'_'.$tool};
                   3287:         }
1.362     raeburn  3288:         if ($userenv->{$envkey} ne '') {
1.275     raeburn  3289:             $oldaccess->{$tool} = &mt('custom');
1.362     raeburn  3290:             if ($userenv->{$envkey}) {
1.275     raeburn  3291:                 $oldaccesstext->{$tool} = &mt("availability set to 'on'");
                   3292:             } else {
                   3293:                 $oldaccesstext->{$tool} = &mt("availability set to 'off'");
                   3294:             }
1.362     raeburn  3295:             $changeHash->{$envkey} = $userenv->{$envkey};
1.275     raeburn  3296:             if ($env{'form.custom'.$tool} == 1) {
1.362     raeburn  3297:                 if ($newval ne $userenv->{$envkey}) {
1.306     raeburn  3298:                     $changed->{$tool} = &tool_admin($tool,$newval,$changeHash,
                   3299:                                                     $context);
1.275     raeburn  3300:                     if ($changed->{$tool}) {
                   3301:                         $newaccess->{$tool} = &mt('custom');
1.306     raeburn  3302:                         if ($newval) {
1.275     raeburn  3303:                             $newaccesstext->{$tool} = &mt("availability set to 'on'");
                   3304:                         } else {
                   3305:                             $newaccesstext->{$tool} = &mt("availability set to 'off'");
                   3306:                         }
                   3307:                     } else {
                   3308:                         $newaccess->{$tool} = $oldaccess->{$tool};
                   3309:                         if ($userenv->{$context.'.'.$tool}) {
                   3310:                             $newaccesstext->{$tool} = &mt("availability set to 'on'");
                   3311:                         } else {
                   3312:                             $newaccesstext->{$tool} = &mt("availability set to 'off'");
                   3313:                         }
                   3314:                     }
                   3315:                 } else {
                   3316:                     $newaccess->{$tool} = $oldaccess->{$tool};
                   3317:                     $newaccesstext->{$tool} = $oldaccesstext->{$tool};
                   3318:                 }
                   3319:             } else {
                   3320:                 $changed->{$tool} = &tool_admin($tool,'',$changeHash,$context);
                   3321:                 if ($changed->{$tool}) {
                   3322:                     $newaccess->{$tool} = &mt('default');
                   3323:                 } else {
                   3324:                     $newaccess->{$tool} = $oldaccess->{$tool};
                   3325:                     if ($userenv->{$context.'.'.$tool}) {
1.300     raeburn  3326:                         $newaccesstext->{$tool} = &mt("availability set to 'on'");
1.275     raeburn  3327:                     } else {
1.300     raeburn  3328:                         $newaccesstext->{$tool} = &mt("availability set to 'off'");
1.275     raeburn  3329:                     }
                   3330:                 }
                   3331:             }
                   3332:         } else {
                   3333:             $oldaccess->{$tool} = &mt('default');
                   3334:             if ($env{'form.custom'.$tool} == 1) {
1.306     raeburn  3335:                 $changed->{$tool} = &tool_admin($tool,$newval,$changeHash,
                   3336:                                                 $context);
1.275     raeburn  3337:                 if ($changed->{$tool}) {
                   3338:                     $newaccess->{$tool} = &mt('custom');
1.306     raeburn  3339:                     if ($newval) {
1.275     raeburn  3340:                         $newaccesstext->{$tool} = &mt("availability set to 'on'");
                   3341:                     } else {
                   3342:                         $newaccesstext->{$tool} = &mt("availability set to 'off'");
                   3343:                     }
                   3344:                 } else {
                   3345:                     $newaccess->{$tool} = $oldaccess->{$tool};
                   3346:                 }
                   3347:             } else {
                   3348:                 $newaccess->{$tool} = $oldaccess->{$tool};
                   3349:             }
                   3350:         }
                   3351:     }
                   3352:     return;
                   3353: }
                   3354: 
1.220     raeburn  3355: sub update_roles {
1.239     raeburn  3356:     my ($r,$context) = @_;
1.4       www      3357:     my $now=time;
1.225     raeburn  3358:     my @rolechanges;
1.220     raeburn  3359:     my %disallowed;
1.73      sakharuk 3360:     $r->print('<h3>'.&mt('Modifying Roles').'</h3>');
1.135     raeburn  3361:     foreach my $key (keys (%env)) {
                   3362: 	next if (! $env{$key});
1.190     raeburn  3363:         next if ($key eq 'form.action');
1.27      matthew  3364: 	# Revoke roles
1.135     raeburn  3365: 	if ($key=~/^form\.rev/) {
                   3366: 	    if ($key=~/^form\.rev\:([^\_]+)\_([^\_\.]+)$/) {
1.64      www      3367: # Revoke standard role
1.170     albertel 3368: 		my ($scope,$role) = ($1,$2);
                   3369: 		my $result =
                   3370: 		    &Apache::lonnet::revokerole($env{'form.ccdomain'},
                   3371: 						$env{'form.ccuname'},
1.239     raeburn  3372: 						$scope,$role,'','',$context);
1.170     albertel 3373: 	        $r->print(&mt('Revoking [_1] in [_2]: [_3]',
                   3374: 			      $role,$scope,'<b>'.$result.'</b>').'<br />');
                   3375: 		if ($role eq 'st') {
1.202     raeburn  3376: 		    my $result = 
1.198     raeburn  3377:                         &Apache::lonuserutils::classlist_drop($scope,
                   3378:                             $env{'form.ccuname'},$env{'form.ccdomain'},
1.202     raeburn  3379: 			    $now);
1.170     albertel 3380: 		    $r->print($result);
1.53      www      3381: 		}
1.225     raeburn  3382:                 if (!grep(/^\Q$role\E$/,@rolechanges)) {
                   3383:                     push(@rolechanges,$role);
                   3384:                 }
1.196     raeburn  3385: 	    }
1.195     raeburn  3386: 	    if ($key=~m{^form\.rev\:([^_]+)_cr\.cr/($match_domain)/($match_username)/(\w+)$}s) {
1.64      www      3387: # Revoke custom role
1.113     raeburn  3388: 		$r->print(&mt('Revoking custom role:').
1.139     albertel 3389:                       ' '.$4.' by '.$3.':'.$2.' in '.$1.': <b>'.
1.101     albertel 3390:                       &Apache::lonnet::revokecustomrole($env{'form.ccdomain'},
1.239     raeburn  3391: 				  $env{'form.ccuname'},$1,$2,$3,$4,'','',$context).
1.102     albertel 3392: 		'</b><br />');
1.225     raeburn  3393:                 if (!grep(/^cr$/,@rolechanges)) {
                   3394:                     push(@rolechanges,'cr');
                   3395:                 }
1.64      www      3396: 	    }
1.135     raeburn  3397: 	} elsif ($key=~/^form\.del/) {
                   3398: 	    if ($key=~/^form\.del\:([^\_]+)\_([^\_\.]+)$/) {
1.116     raeburn  3399: # Delete standard role
1.170     albertel 3400: 		my ($scope,$role) = ($1,$2);
                   3401: 		my $result =
                   3402: 		    &Apache::lonnet::assignrole($env{'form.ccdomain'},
                   3403: 						$env{'form.ccuname'},
1.239     raeburn  3404: 						$scope,$role,$now,0,1,'',
                   3405:                                                 $context);
1.170     albertel 3406: 	        $r->print(&mt('Deleting [_1] in [_2]: [_3]',$role,$scope,
                   3407: 			      '<b>'.$result.'</b>').'<br />');
                   3408: 		if ($role eq 'st') {
1.202     raeburn  3409: 		    my $result = 
1.198     raeburn  3410:                         &Apache::lonuserutils::classlist_drop($scope,
                   3411:                             $env{'form.ccuname'},$env{'form.ccdomain'},
1.202     raeburn  3412: 			    $now);
1.170     albertel 3413: 		    $r->print($result);
1.81      albertel 3414: 		}
1.225     raeburn  3415:                 if (!grep(/^\Q$role\E$/,@rolechanges)) {
                   3416:                     push(@rolechanges,$role);
                   3417:                 }
1.116     raeburn  3418:             }
1.139     albertel 3419: 	    if ($key=~m{^form\.del\:([^_]+)_cr\.cr/($match_domain)/($match_username)/(\w+)$}) {
1.116     raeburn  3420:                 my ($url,$rdom,$rnam,$rolename) = ($1,$2,$3,$4);
                   3421: # Delete custom role
1.294     bisitz   3422:                 $r->print(&mt('Deleting custom role [_1] by [_2] in [_3]',
                   3423:                       $rolename,$rnam.':'.$rdom,$url).': <b>'.
1.116     raeburn  3424:                       &Apache::lonnet::assigncustomrole($env{'form.ccdomain'},
                   3425:                          $env{'form.ccuname'},$url,$rdom,$rnam,$rolename,$now,
1.240     raeburn  3426:                          0,1,$context).'</b><br />');
1.225     raeburn  3427:                 if (!grep(/^cr$/,@rolechanges)) {
                   3428:                     push(@rolechanges,'cr');
                   3429:                 }
1.116     raeburn  3430:             }
1.135     raeburn  3431: 	} elsif ($key=~/^form\.ren/) {
1.101     albertel 3432:             my $udom = $env{'form.ccdomain'};
                   3433:             my $uname = $env{'form.ccuname'};
1.116     raeburn  3434: # Re-enable standard role
1.135     raeburn  3435: 	    if ($key=~/^form\.ren\:([^\_]+)\_([^\_\.]+)$/) {
1.89      raeburn  3436:                 my $url = $1;
                   3437:                 my $role = $2;
                   3438:                 my $logmsg;
                   3439:                 my $output;
                   3440:                 if ($role eq 'st') {
1.141     albertel 3441:                     if ($url =~ m-^/($match_domain)/($match_courseid)/?(\w*)$-) {
1.129     albertel 3442:                         my $result = &Apache::loncommon::commit_studentrole(\$logmsg,$udom,$uname,$url,$role,$now,0,$1,$2,$3);
1.220     raeburn  3443:                         if (($result =~ /^error/) || ($result eq 'not_in_class') || ($result eq 'unknown_course') || ($result eq 'refused')) {
1.223     raeburn  3444:                             if ($result eq 'refused' && $logmsg) {
                   3445:                                 $output = $logmsg;
                   3446:                             } else { 
                   3447:                                 $output = "Error: $result\n";
                   3448:                             }
1.89      raeburn  3449:                         } else {
                   3450:                             $output = &mt('Assigning').' '.$role.' in '.$url.
                   3451:                                       &mt('starting').' '.localtime($now).
                   3452:                                       ': <br />'.$logmsg.'<br />'.
                   3453:                                       &mt('Add to classlist').': <b>ok</b><br />';
                   3454:                         }
                   3455:                     }
                   3456:                 } else {
1.101     albertel 3457: 		    my $result=&Apache::lonnet::assignrole($env{'form.ccdomain'},
1.239     raeburn  3458:                                $env{'form.ccuname'},$url,$role,0,$now,'','',
                   3459:                                $context);
1.266     bisitz   3460: 		    $output = &mt('Re-enabling [_1] in [_2]: [_3]',
                   3461: 			      $role,$url,'<b>'.$result.'</b>').'<br />';
1.27      matthew  3462: 		}
1.89      raeburn  3463:                 $r->print($output);
1.225     raeburn  3464:                 if (!grep(/^\Q$role\E$/,@rolechanges)) {
                   3465:                     push(@rolechanges,$role);
                   3466:                 }
1.113     raeburn  3467: 	    }
1.116     raeburn  3468: # Re-enable custom role
1.139     albertel 3469: 	    if ($key=~m{^form\.ren\:([^_]+)_cr\.cr/($match_domain)/($match_username)/(\w+)$}) {
1.116     raeburn  3470:                 my ($url,$rdom,$rnam,$rolename) = ($1,$2,$3,$4);
                   3471:                 my $result = &Apache::lonnet::assigncustomrole(
                   3472:                                $env{'form.ccdomain'}, $env{'form.ccuname'},
1.240     raeburn  3473:                                $url,$rdom,$rnam,$rolename,0,$now,undef,$context);
1.294     bisitz   3474:                 $r->print(&mt('Re-enabling custom role [_1] by [_2] in [_3]: [_4]',
                   3475:                           $rolename,$rnam.':'.$rdom,$url,'<b>'.$result.'</b>').'<br />');
1.225     raeburn  3476:                 if (!grep(/^cr$/,@rolechanges)) {
                   3477:                     push(@rolechanges,'cr');
                   3478:                 }
1.116     raeburn  3479:             }
1.135     raeburn  3480: 	} elsif ($key=~/^form\.act/) {
1.101     albertel 3481:             my $udom = $env{'form.ccdomain'};
                   3482:             my $uname = $env{'form.ccuname'};
1.141     albertel 3483: 	    if ($key=~/^form\.act\_($match_domain)\_($match_courseid)\_cr_cr_($match_domain)_($match_username)_([^\_]+)$/) {
1.65      www      3484:                 # Activate a custom role
1.83      albertel 3485: 		my ($one,$two,$three,$four,$five)=($1,$2,$3,$4,$5);
                   3486: 		my $url='/'.$one.'/'.$two;
                   3487: 		my $full=$one.'_'.$two.'_cr_cr_'.$three.'_'.$four.'_'.$five;
1.65      www      3488: 
1.101     albertel 3489:                 my $start = ( $env{'form.start_'.$full} ?
                   3490:                               $env{'form.start_'.$full} :
1.88      raeburn  3491:                               $now );
1.101     albertel 3492:                 my $end   = ( $env{'form.end_'.$full} ?
                   3493:                               $env{'form.end_'.$full} :
1.88      raeburn  3494:                               0 );
                   3495:                                                                                      
                   3496:                 # split multiple sections
                   3497:                 my %sections = ();
1.101     albertel 3498:                 my $num_sections = &build_roles($env{'form.sec_'.$full},\%sections,$5);
1.88      raeburn  3499:                 if ($num_sections == 0) {
1.240     raeburn  3500:                     $r->print(&Apache::loncommon::commit_customrole($udom,$uname,$url,$three,$four,$five,$start,$end,$context));
1.88      raeburn  3501:                 } else {
1.114     albertel 3502: 		    my %curr_groups =
1.117     raeburn  3503: 			&Apache::longroup::coursegroups($one,$two);
1.113     raeburn  3504:                     foreach my $sec (sort {$a cmp $b} keys %sections) {
                   3505:                         if (($sec eq 'none') || ($sec eq 'all') || 
                   3506:                             exists($curr_groups{$sec})) {
                   3507:                             $disallowed{$sec} = $url;
                   3508:                             next;
                   3509:                         }
                   3510:                         my $securl = $url.'/'.$sec;
1.240     raeburn  3511: 		        $r->print(&Apache::loncommon::commit_customrole($udom,$uname,$securl,$three,$four,$five,$start,$end,$context));
1.88      raeburn  3512:                     }
                   3513:                 }
1.225     raeburn  3514:                 if (!grep(/^cr$/,@rolechanges)) {
                   3515:                     push(@rolechanges,'cr');
                   3516:                 }
1.142     raeburn  3517: 	    } elsif ($key=~/^form\.act\_($match_domain)\_($match_name)\_([^\_]+)$/) {
1.27      matthew  3518: 		# Activate roles for sections with 3 id numbers
                   3519: 		# set start, end times, and the url for the class
1.83      albertel 3520: 		my ($one,$two,$three)=($1,$2,$3);
1.101     albertel 3521: 		my $start = ( $env{'form.start_'.$one.'_'.$two.'_'.$three} ? 
                   3522: 			      $env{'form.start_'.$one.'_'.$two.'_'.$three} : 
1.27      matthew  3523: 			      $now );
1.101     albertel 3524: 		my $end   = ( $env{'form.end_'.$one.'_'.$two.'_'.$three} ? 
                   3525: 			      $env{'form.end_'.$one.'_'.$two.'_'.$three} :
1.27      matthew  3526: 			      0 );
1.83      albertel 3527: 		my $url='/'.$one.'/'.$two;
1.88      raeburn  3528:                 my $type = 'three';
                   3529:                 # split multiple sections
                   3530:                 my %sections = ();
1.101     albertel 3531:                 my $num_sections = &build_roles($env{'form.sec_'.$one.'_'.$two.'_'.$three},\%sections,$three);
1.88      raeburn  3532:                 if ($num_sections == 0) {
1.240     raeburn  3533:                     $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$three,$start,$end,$one,$two,'',$context));
1.88      raeburn  3534:                 } else {
1.114     albertel 3535:                     my %curr_groups = 
1.117     raeburn  3536: 			&Apache::longroup::coursegroups($one,$two);
1.88      raeburn  3537:                     my $emptysec = 0;
                   3538:                     foreach my $sec (sort {$a cmp $b} keys %sections) {
                   3539:                         $sec =~ s/\W//g;
1.113     raeburn  3540:                         if ($sec ne '') {
                   3541:                             if (($sec eq 'none') || ($sec eq 'all') || 
                   3542:                                 exists($curr_groups{$sec})) {
                   3543:                                 $disallowed{$sec} = $url;
                   3544:                                 next;
                   3545:                             }
1.88      raeburn  3546:                             my $securl = $url.'/'.$sec;
1.240     raeburn  3547:                             $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$securl,$three,$start,$end,$one,$two,$sec,$context));
1.88      raeburn  3548:                         } else {
                   3549:                             $emptysec = 1;
                   3550:                         }
                   3551:                     }
                   3552:                     if ($emptysec) {
1.240     raeburn  3553:                         $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$three,$start,$end,$one,$two,'',$context));
1.88      raeburn  3554:                     }
1.225     raeburn  3555:                 }
                   3556:                 if (!grep(/^\Q$three\E$/,@rolechanges)) {
                   3557:                     push(@rolechanges,$three);
                   3558:                 }
1.135     raeburn  3559: 	    } elsif ($key=~/^form\.act\_([^\_]+)\_([^\_]+)$/) {
1.27      matthew  3560: 		# Activate roles for sections with two id numbers
                   3561: 		# set start, end times, and the url for the class
1.101     albertel 3562: 		my $start = ( $env{'form.start_'.$1.'_'.$2} ? 
                   3563: 			      $env{'form.start_'.$1.'_'.$2} : 
1.27      matthew  3564: 			      $now );
1.101     albertel 3565: 		my $end   = ( $env{'form.end_'.$1.'_'.$2} ? 
                   3566: 			      $env{'form.end_'.$1.'_'.$2} :
1.27      matthew  3567: 			      0 );
1.225     raeburn  3568:                 my $one = $1;
                   3569:                 my $two = $2;
                   3570: 		my $url='/'.$one.'/';
1.88      raeburn  3571:                 # split multiple sections
                   3572:                 my %sections = ();
1.225     raeburn  3573:                 my $num_sections = &build_roles($env{'form.sec_'.$one.'_'.$two},\%sections,$two);
1.88      raeburn  3574:                 if ($num_sections == 0) {
1.240     raeburn  3575:                     $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$two,$start,$end,$one,undef,'',$context));
1.88      raeburn  3576:                 } else {
                   3577:                     my $emptysec = 0;
                   3578:                     foreach my $sec (sort {$a cmp $b} keys %sections) {
                   3579:                         if ($sec ne '') {
                   3580:                             my $securl = $url.'/'.$sec;
1.240     raeburn  3581:                             $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$securl,$two,$start,$end,$one,undef,$sec,$context));
1.88      raeburn  3582:                         } else {
                   3583:                             $emptysec = 1;
                   3584:                         }
                   3585:                     }
                   3586:                     if ($emptysec) {
1.240     raeburn  3587:                         $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$two,$start,$end,$one,undef,'',$context));
1.88      raeburn  3588:                     }
                   3589:                 }
1.225     raeburn  3590:                 if (!grep(/^\Q$two\E$/,@rolechanges)) {
                   3591:                     push(@rolechanges,$two);
                   3592:                 }
1.64      www      3593: 	    } else {
1.190     raeburn  3594: 		$r->print('<p><span class="LC_error">'.&mt('ERROR').': '.&mt('Unknown command').' <tt>'.$key.'</tt></span></p><br />');
1.64      www      3595:             }
1.113     raeburn  3596:             foreach my $key (sort(keys(%disallowed))) {
1.274     bisitz   3597:                 $r->print('<p class="LC_warning">');
1.113     raeburn  3598:                 if (($key eq 'none') || ($key eq 'all')) {  
1.274     bisitz   3599:                     $r->print(&mt('[_1] may not be used as the name for a section, as it is a reserved word.','<tt>'.$key.'</tt>'));
1.113     raeburn  3600:                 } else {
1.274     bisitz   3601:                     $r->print(&mt('[_1] may not be used as the name for a section, as it is the name of a course group.','<tt>'.$key.'</tt>'));
1.113     raeburn  3602:                 }
1.274     bisitz   3603:                 $r->print('</p><p>'
                   3604:                          .&mt('Please [_1]go back[_2] and choose a different section name.'
                   3605:                              ,'<a href="javascript:history.go(-1)'
                   3606:                              ,'</a>')
                   3607:                          .'</p><br />'
                   3608:                 );
1.113     raeburn  3609:             }
                   3610: 	}
1.101     albertel 3611:     } # End of foreach (keys(%env))
1.75      www      3612: # Flush the course logs so reverse user roles immediately updated
1.349     raeburn  3613:     $r->register_cleanup(\&Apache::lonnet::flushcourselogs);
1.225     raeburn  3614:     if (@rolechanges == 0) {
1.193     raeburn  3615:         $r->print(&mt('No roles to modify'));
                   3616:     }
1.225     raeburn  3617:     return @rolechanges;
1.220     raeburn  3618: }
                   3619: 
                   3620: sub enroll_single_student {
1.318     raeburn  3621:     my ($r,$uhome,$amode,$genpwd,$now,$newuser,$context,$crstype) = @_;
                   3622:     $r->print('<h3>');
                   3623:     if ($crstype eq 'Community') {
                   3624:         $r->print(&mt('Enrolling Member'));
                   3625:     } else {
                   3626:         $r->print(&mt('Enrolling Student'));
                   3627:     }
                   3628:     $r->print('</h3>');
1.220     raeburn  3629: 
                   3630:     # Remove non alphanumeric values from section
                   3631:     $env{'form.sections'}=~s/\W//g;
                   3632: 
                   3633:     # Clean out any old student roles the user has in this class.
                   3634:     &Apache::lonuserutils::modifystudent($env{'form.ccdomain'},
                   3635:          $env{'form.ccuname'},$env{'request.course.id'},undef,$uhome);
                   3636:     my ($startdate,$enddate) = &Apache::lonuserutils::get_dates_from_form();
                   3637:     my $enroll_result =
                   3638:         &Apache::lonnet::modify_student_enrollment($env{'form.ccdomain'},
                   3639:             $env{'form.ccuname'},$env{'form.cid'},$env{'form.cfirstname'},
                   3640:             $env{'form.cmiddlename'},$env{'form.clastname'},
                   3641:             $env{'form.generation'},$env{'form.sections'},$enddate,
1.239     raeburn  3642:             $startdate,'manual',undef,$env{'request.course.id'},'',$context);
1.220     raeburn  3643:     if ($enroll_result =~ /^ok/) {
                   3644:         $r->print(&mt('<b>[_1]</b> enrolled',$env{'form.ccuname'}.':'.$env{'form.ccdomain'}));
                   3645:         if ($env{'form.sections'} ne '') {
                   3646:             $r->print(' '.&mt('in section [_1]',$env{'form.sections'}));
                   3647:         }
                   3648:         my ($showstart,$showend);
                   3649:         if ($startdate <= $now) {
                   3650:             $showstart = &mt('Access starts immediately');
                   3651:         } else {
                   3652:             $showstart = &mt('Access starts: ').&Apache::lonlocal::locallocaltime($startdate);
                   3653:         }
                   3654:         if ($enddate == 0) {
                   3655:             $showend = &mt('ends: no ending date');
                   3656:         } else {
                   3657:             $showend = &mt('ends: ').&Apache::lonlocal::locallocaltime($enddate);
                   3658:         }
                   3659:         $r->print('.<br />'.$showstart.'; '.$showend);
                   3660:         if ($startdate <= $now && !$newuser) {
1.318     raeburn  3661:             $r->print('<p> ');
                   3662:             if ($crstype eq 'Community') {
                   3663:                 $r->print(&mt('If the member is currently logged-in to LON-CAPA, the new role will be available when the member next logs in.'));
                   3664:             } else {
                   3665:                 $r->print(&mt('If the student is currently logged-in to LON-CAPA, the new role will be available when the student next logs in.'));
                   3666:            }
                   3667:            $r->print('</p>');
1.220     raeburn  3668:         }
                   3669:     } else {
                   3670:         $r->print(&mt('unable to enroll').": ".$enroll_result);
                   3671:     }
                   3672:     return;
1.188     raeburn  3673: }
                   3674: 
1.204     raeburn  3675: sub get_defaultquota_text {
                   3676:     my ($settingstatus) = @_;
                   3677:     my $defquotatext; 
                   3678:     if ($settingstatus eq '') {
                   3679:         $defquotatext = &mt('(default)');
                   3680:     } else {
                   3681:         my ($usertypes,$order) =
                   3682:             &Apache::lonnet::retrieve_inst_usertypes($env{'form.ccdomain'});
                   3683:         if ($usertypes->{$settingstatus} eq '') {
                   3684:             $defquotatext = &mt('(default)');
                   3685:         } else {
                   3686:             $defquotatext = &mt('(default for [_1])',$usertypes->{$settingstatus});
                   3687:         }
                   3688:     }
                   3689:     return $defquotatext;
                   3690: }
                   3691: 
1.188     raeburn  3692: sub update_result_form {
                   3693:     my ($uhome) = @_;
                   3694:     my $outcome = 
                   3695:     '<form name="userupdate" method="post" />'."\n";
1.160     raeburn  3696:     foreach my $item ('srchby','srchin','srchtype','srchterm','srchdomain','ccuname','ccdomain') {
1.188     raeburn  3697:         $outcome .= '<input type="hidden" name="'.$item.'" value="'.$env{'form.'.$item}.'" />'."\n";
1.160     raeburn  3698:     }
1.207     raeburn  3699:     if ($env{'form.origname'} ne '') {
                   3700:         $outcome .= '<input type="hidden" name="origname" value="'.$env{'form.origname'}.'" />'."\n";
                   3701:     }
1.160     raeburn  3702:     foreach my $item ('sortby','seluname','seludom') {
                   3703:         if (exists($env{'form.'.$item})) {
1.188     raeburn  3704:             $outcome .= '<input type="hidden" name="'.$item.'" value="'.$env{'form.'.$item}.'" />'."\n";
1.160     raeburn  3705:         }
                   3706:     }
1.188     raeburn  3707:     if ($uhome eq 'no_host') {
                   3708:         $outcome .= '<input type="hidden" name="forcenewuser" value="1" />'."\n";
                   3709:     }
                   3710:     $outcome .= '<input type="hidden" name="phase" value="" />'."\n".
                   3711:                 '<input type ="hidden" name="currstate" value="" />'."\n".
1.220     raeburn  3712:                 '<input type ="hidden" name="action" value="'.$env{'form.action'}.'" />'."\n".
1.188     raeburn  3713:                 '</form>';
                   3714:     return $outcome;
1.4       www      3715: }
                   3716: 
1.149     raeburn  3717: sub quota_admin {
                   3718:     my ($setquota,$changeHash) = @_;
                   3719:     my $quotachanged;
                   3720:     if (&Apache::lonnet::allowed('mpq',$env{'form.ccdomain'})) {
                   3721:         # Current user has quota modification privileges
1.267     raeburn  3722:         if (ref($changeHash) eq 'HASH') {
                   3723:             $quotachanged = 1;
                   3724:             $changeHash->{'portfolioquota'} = $setquota;
                   3725:         }
1.149     raeburn  3726:     }
                   3727:     return $quotachanged;
                   3728: }
                   3729: 
1.267     raeburn  3730: sub tool_admin {
1.275     raeburn  3731:     my ($tool,$settool,$changeHash,$context) = @_;
                   3732:     my $canchange = 0; 
1.279     raeburn  3733:     if ($context eq 'requestcourses') {
1.275     raeburn  3734:         if (&Apache::lonnet::allowed('ccc',$env{'form.ccdomain'})) {
                   3735:             $canchange = 1;
                   3736:         }
1.300     raeburn  3737:     } elsif ($context eq 'reqcrsotherdom') {
                   3738:         if (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'})) {
                   3739:             $canchange = 1;
                   3740:         }
1.362     raeburn  3741:     } elsif ($context eq 'requestauthor') {
                   3742:         if (&Apache::lonnet::allowed('cau',$env{'request.role.domain'})) {
                   3743:             $canchange = 1;
                   3744:         }
1.275     raeburn  3745:     } elsif (&Apache::lonnet::allowed('mut',$env{'form.ccdomain'})) {
                   3746:         # Current user has quota modification privileges
                   3747:         $canchange = 1;
                   3748:     }
1.267     raeburn  3749:     my $toolchanged;
1.275     raeburn  3750:     if ($canchange) {
1.267     raeburn  3751:         if (ref($changeHash) eq 'HASH') {
                   3752:             $toolchanged = 1;
1.362     raeburn  3753:             if ($tool eq 'requestauthor') {
                   3754:                 $changeHash->{$context} = $settool;
                   3755:             } else {
                   3756:                 $changeHash->{$context.'.'.$tool} = $settool;
                   3757:             }
1.267     raeburn  3758:         }
                   3759:     }
                   3760:     return $toolchanged;
                   3761: }
                   3762: 
1.88      raeburn  3763: sub build_roles {
1.89      raeburn  3764:     my ($sectionstr,$sections,$role) = @_;
1.88      raeburn  3765:     my $num_sections = 0;
                   3766:     if ($sectionstr=~ /,/) {
                   3767:         my @secnums = split/,/,$sectionstr;
1.89      raeburn  3768:         if ($role eq 'st') {
                   3769:             $secnums[0] =~ s/\W//g;
                   3770:             $$sections{$secnums[0]} = 1;
                   3771:             $num_sections = 1;
                   3772:         } else {
                   3773:             foreach my $sec (@secnums) {
                   3774:                 $sec =~ ~s/\W//g;
1.150     banghart 3775:                 if (!($sec eq "")) {
1.89      raeburn  3776:                     if (exists($$sections{$sec})) {
                   3777:                         $$sections{$sec} ++;
                   3778:                     } else {
                   3779:                         $$sections{$sec} = 1;
                   3780:                         $num_sections ++;
                   3781:                     }
1.88      raeburn  3782:                 }
                   3783:             }
                   3784:         }
                   3785:     } else {
                   3786:         $sectionstr=~s/\W//g;
                   3787:         unless ($sectionstr eq '') {
                   3788:             $$sections{$sectionstr} = 1;
                   3789:             $num_sections ++;
                   3790:         }
                   3791:     }
1.129     albertel 3792: 
1.88      raeburn  3793:     return $num_sections;
                   3794: }
                   3795: 
1.58      www      3796: # ========================================================== Custom Role Editor
                   3797: 
                   3798: sub custom_role_editor {
1.351     raeburn  3799:     my ($r,$brcrum) = @_;
1.324     raeburn  3800:     my $action = $env{'form.customroleaction'};
                   3801:     my $rolename; 
                   3802:     if ($action eq 'new') {
                   3803:         $rolename=$env{'form.newrolename'};
                   3804:     } else {
                   3805:         $rolename=$env{'form.rolename'};
1.59      www      3806:     }
                   3807: 
1.324     raeburn  3808:     my ($crstype,$context);
                   3809:     if ($env{'request.course.id'}) {
                   3810:         $crstype = &Apache::loncommon::course_type();
                   3811:         $context = 'course';
                   3812:     } else {
                   3813:         $context = 'domain';
                   3814:         $crstype = $env{'form.templatecrstype'};
                   3815:     }
1.351     raeburn  3816: 
                   3817:     $rolename=~s/[^A-Za-z0-9]//gs;
                   3818:     if (!$rolename || $env{'form.phase'} eq 'pickrole') {
                   3819: 	&print_username_entry_form($r,undef,undef,undef,undef,$crstype,$brcrum);
                   3820:         return;
                   3821:     }
                   3822: 
1.153     banghart 3823: # ------------------------------------------------------- What can be assigned?
                   3824:     my %full=();
                   3825:     my %courselevel=();
                   3826:     my %courselevelcurrent=();
1.61      www      3827:     my $syspriv='';
                   3828:     my $dompriv='';
                   3829:     my $coursepriv='';
1.153     banghart 3830:     my $body_top;
1.59      www      3831:     my ($rdummy,$roledef)=
                   3832: 			 &Apache::lonnet::get('roles',["rolesdef_$rolename"]);
1.60      www      3833: # ------------------------------------------------------- Does this role exist?
1.153     banghart 3834:     $body_top .= '<h2>';
1.59      www      3835:     if (($rdummy ne 'con_lost') && ($roledef ne '')) {
1.153     banghart 3836: 	$body_top .= &mt('Existing Role').' "';
1.61      www      3837: # ------------------------------------------------- Get current role privileges
                   3838: 	($syspriv,$dompriv,$coursepriv)=split(/\_/,$roledef);
1.324     raeburn  3839:         if ($crstype eq 'Community') {
                   3840:             $syspriv =~ s/bre\&S//;   
                   3841:         }
1.59      www      3842:     } else {
1.153     banghart 3843: 	$body_top .= &mt('New Role').' "';
1.59      www      3844: 	$roledef='';
                   3845:     }
1.153     banghart 3846:     $body_top .= $rolename.'"</h2>';
1.135     raeburn  3847:     foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:c'})) {
                   3848: 	my ($priv,$restrict)=split(/\&/,$item);
1.150     banghart 3849:         if (!$restrict) { $restrict='F'; }
1.60      www      3850:         $courselevel{$priv}=$restrict;
1.61      www      3851:         if ($coursepriv=~/\:$priv/) {
                   3852: 	    $courselevelcurrent{$priv}=1;
                   3853: 	}
1.60      www      3854: 	$full{$priv}=1;
                   3855:     }
                   3856:     my %domainlevel=();
1.61      www      3857:     my %domainlevelcurrent=();
1.135     raeburn  3858:     foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:d'})) {
                   3859: 	my ($priv,$restrict)=split(/\&/,$item);
1.150     banghart 3860:         if (!$restrict) { $restrict='F'; }
1.60      www      3861:         $domainlevel{$priv}=$restrict;
1.61      www      3862:         if ($dompriv=~/\:$priv/) {
                   3863: 	    $domainlevelcurrent{$priv}=1;
                   3864: 	}
1.60      www      3865: 	$full{$priv}=1;
                   3866:     }
1.61      www      3867:     my %systemlevel=();
                   3868:     my %systemlevelcurrent=();
1.135     raeburn  3869:     foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:s'})) {
                   3870: 	my ($priv,$restrict)=split(/\&/,$item);
1.150     banghart 3871:         if (!$restrict) { $restrict='F'; }
1.61      www      3872:         $systemlevel{$priv}=$restrict;
                   3873:         if ($syspriv=~/\:$priv/) {
                   3874: 	    $systemlevelcurrent{$priv}=1;
                   3875: 	}
                   3876: 	$full{$priv}=1;
                   3877:     }
1.160     raeburn  3878:     my ($jsback,$elements) = &crumb_utilities();
1.154     banghart 3879:     my $button_code = "\n";
1.153     banghart 3880:     my $head_script = "\n";
1.301     bisitz   3881:     $head_script .= '<script type="text/javascript">'."\n"
                   3882:                    .'// <![CDATA['."\n";
1.324     raeburn  3883:     my @template_roles = ("in","ta","ep");
                   3884:     if ($context eq 'domain') {
                   3885:         push(@template_roles,"ad");
1.318     raeburn  3886:     }
1.324     raeburn  3887:     push(@template_roles,"st");
1.318     raeburn  3888:     if ($crstype eq 'Community') {
                   3889:         unshift(@template_roles,'co');
                   3890:     } else {
                   3891:         unshift(@template_roles,'cc');
                   3892:     }
1.154     banghart 3893:     foreach my $role (@template_roles) {
1.324     raeburn  3894:         $head_script .= &make_script_template($role,$crstype);
1.318     raeburn  3895:         $button_code .= &make_button_code($role,$crstype).' ';
1.154     banghart 3896:     }
1.324     raeburn  3897:     my $context_code;
                   3898:     if ($context eq 'domain') {
                   3899:         my $checkedCommunity = '';
                   3900:         my $checkedCourse = ' checked="checked"';
                   3901:         if ($env{'form.templatecrstype'} eq 'Community') {
                   3902:             $checkedCommunity = $checkedCourse;
                   3903:             $checkedCourse = '';
                   3904:         }
                   3905:         $context_code = '<label>'.
                   3906:                         '<input type="radio" name="templatecrstype" value="Course"'.$checkedCourse.' onclick="this.form.submit();">'.
                   3907:                         &mt('Course').
                   3908:                         '</label>'.('&nbsp;' x2).
                   3909:                         '<label>'.
                   3910:                         '<input type="radio" name="templatecrstype" value="Community"'.$checkedCommunity.' onclick="this.form.submit();">'.
                   3911:                         &mt('Community').
                   3912:                         '</label>'.
                   3913:                         '</fieldset>'.
                   3914:                         '<input type="hidden" name="customroleaction" value="'.
                   3915:                         $action.'" />';
                   3916:         if ($env{'form.customroleaction'} eq 'new') {
                   3917:             $context_code .= '<input type="hidden" name="newrolename" value="'.
                   3918:                              $rolename.'" />';
                   3919:         } else {
                   3920:             $context_code .= '<input type="hidden" name="rolename" value="'.
                   3921:                              $rolename.'" />';
                   3922:         }
                   3923:         $context_code .= '<input type="hidden" name="action" value="custom" />'.
                   3924:                          '<input type="hidden" name="phase" value="selected_custom_edit" />';
                   3925:     }
                   3926: 
1.301     bisitz   3927:     $head_script .= "\n".$jsback."\n"
                   3928:                    .'// ]]>'."\n"
                   3929:                    .'</script>'."\n";
1.351     raeburn  3930:     push (@{$brcrum},
                   3931:               {href => "javascript:backPage(document.form1,'pickrole','')",
                   3932:                text => "Pick custom role",
                   3933:                faq  => 282,bug=>'Instructor Interface',},
                   3934:               {href => "javascript:backPage(document.form1,'','')",
                   3935:                text => "Edit custom role",
                   3936:                faq  => 282,
                   3937:                bug  => 'Instructor Interface',
                   3938:                help => 'Course_Editing_Custom_Roles'}
                   3939:               );
                   3940:     my $args = { bread_crumbs          => $brcrum,
                   3941:                  bread_crumbs_component => 'User Management'};
                   3942:  
                   3943:     $r->print(&Apache::loncommon::start_page('Custom Role Editor',
                   3944:                                              $head_script,$args).
                   3945:               $body_top);
1.73      sakharuk 3946:     my %lt=&Apache::lonlocal::texthash(
                   3947: 		    'prv'  => "Privilege",
1.131     raeburn  3948: 		    'crl'  => "Course Level",
1.73      sakharuk 3949:                     'dml'  => "Domain Level",
1.150     banghart 3950:                     'ssl'  => "System Level");
1.264     bisitz   3951: 
1.324     raeburn  3952:     $r->print('<div class="LC_left_float">'
1.264     bisitz   3953:              .'<form action=""><fieldset>'
                   3954:              .'<legend>'.&mt('Select a Template').'</legend>'
                   3955:              .$button_code
1.324     raeburn  3956:              .'</fieldset></form></div>');
                   3957:     if ($context_code) {
                   3958:         $r->print('<div class="LC_left_float">'
                   3959:                  .'<form action="/adm/createuser" method="post"><fieldset>'
                   3960:                  .'<legend>'.&mt('Context').'</legend>'
                   3961:                  .$context_code
                   3962:                  .'</form>'
                   3963:                  .'</div>'
                   3964:         );
                   3965:     }
                   3966:     $r->print('<br clear="all" />');
1.264     bisitz   3967: 
1.61      www      3968:     $r->print(<<ENDCCF);
1.160     raeburn  3969: <form name="form1" method="post">
1.61      www      3970: <input type="hidden" name="phase" value="set_custom_roles" />
                   3971: <input type="hidden" name="rolename" value="$rolename" />
                   3972: ENDCCF
1.135     raeburn  3973:     $r->print(&Apache::loncommon::start_data_table().
                   3974:               &Apache::loncommon::start_data_table_header_row(). 
                   3975: '<th>'.$lt{'prv'}.'</th><th>'.$lt{'crl'}.'</th><th>'.$lt{'dml'}.
                   3976: '</th><th>'.$lt{'ssl'}.'</th>'.
                   3977:               &Apache::loncommon::end_data_table_header_row());
1.324     raeburn  3978:     foreach my $priv (sort(keys(%full))) {
1.318     raeburn  3979:         my $privtext = &Apache::lonnet::plaintext($priv,$crstype);
1.135     raeburn  3980:         $r->print(&Apache::loncommon::start_data_table_row().
                   3981: 	          '<td>'.$privtext.'</td><td>'.
1.288     bisitz   3982:     ($courselevel{$priv}?'<input type="checkbox" name="'.$priv.'_c"'.
                   3983:     ($courselevelcurrent{$priv}?' checked="checked"':'').' />':'&nbsp;').
1.61      www      3984:     '</td><td>'.
1.288     bisitz   3985:     ($domainlevel{$priv}?'<input type="checkbox" name="'.$priv.'_d"'.
                   3986:     ($domainlevelcurrent{$priv}?' checked="checked"':'').' />':'&nbsp;').
1.324     raeburn  3987:     '</td><td>');
                   3988:         if ($priv eq 'bre' && $crstype eq 'Community') {
                   3989:             $r->print('&nbsp;');  
                   3990:         } else {
                   3991:             $r->print($systemlevel{$priv}?'<input type="checkbox" name="'.$priv.'_s"'.
                   3992:                       ($systemlevelcurrent{$priv}?' checked="checked"':'').' />':'&nbsp;');
                   3993:         }
                   3994:         $r->print('</td>'.
                   3995:                   &Apache::loncommon::end_data_table_row());
1.60      www      3996:     }
1.135     raeburn  3997:     $r->print(&Apache::loncommon::end_data_table().
1.190     raeburn  3998:    '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />'.
1.160     raeburn  3999:    '<input type="hidden" name="startrolename" value="'.$env{'form.rolename'}.
1.179     raeburn  4000:    '" />'."\n".'<input type="hidden" name="currstate" value="" />'."\n".   
1.160     raeburn  4001:    '<input type="reset" value="'.&mt("Reset").'" />'."\n".
1.351     raeburn  4002:    '<input type="submit" value="'.&mt('Save').'" /></form>');
1.61      www      4003: }
1.153     banghart 4004: # --------------------------------------------------------
                   4005: sub make_script_template {
1.324     raeburn  4006:     my ($role,$crstype) = @_;
1.153     banghart 4007:     my %full_c=();
                   4008:     my %full_d=();
                   4009:     my %full_s=();
                   4010:     my $return_script;
                   4011:     foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:c'})) {
                   4012:         my ($priv,$restrict)=split(/\&/,$item);
                   4013:         $full_c{$priv}=1;
                   4014:     }
                   4015:     foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:d'})) {
                   4016:         my ($priv,$restrict)=split(/\&/,$item);
                   4017:         $full_d{$priv}=1;
                   4018:     }
1.154     banghart 4019:     foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:s'})) {
1.324     raeburn  4020:         next if (($crstype eq 'Community') && ($item eq 'bre&S'));
1.153     banghart 4021:         my ($priv,$restrict)=split(/\&/,$item);
                   4022:         $full_s{$priv}=1;
                   4023:     }
                   4024:     $return_script .= 'function set_'.$role.'() {'."\n";
                   4025:     my @temp = split(/:/,$Apache::lonnet::pr{$role.':c'});
                   4026:     my %role_c;
1.155     banghart 4027:     foreach my $priv (@temp) {
1.153     banghart 4028:         my ($priv_item, $dummy) = split(/\&/,$priv);
                   4029:         $role_c{$priv_item} = 1;
                   4030:     }
1.269     raeburn  4031:     my %role_d;
                   4032:     @temp = split(/:/,$Apache::lonnet::pr{$role.':d'});
                   4033:     foreach my $priv(@temp) {
                   4034:         my ($priv_item, $dummy) = split(/\&/,$priv);
                   4035:         $role_d{$priv_item} = 1;
                   4036:     }
                   4037:     my %role_s;
                   4038:     @temp = split(/:/,$Apache::lonnet::pr{$role.':s'});
                   4039:     foreach my $priv(@temp) {
                   4040:         my ($priv_item, $dummy) = split(/\&/,$priv);
                   4041:         $role_s{$priv_item} = 1;
                   4042:     }
1.153     banghart 4043:     foreach my $priv_item (keys(%full_c)) {
                   4044:         my ($priv, $dummy) = split(/\&/,$priv_item);
1.269     raeburn  4045:         if ((exists($role_c{$priv})) || (exists($role_d{$priv})) || 
                   4046:             (exists($role_s{$priv}))) {
1.153     banghart 4047:             $return_script .= "document.form1.$priv"."_c.checked = true;\n";
                   4048:         } else {
                   4049:             $return_script .= "document.form1.$priv"."_c.checked = false;\n";
                   4050:         }
                   4051:     }
1.154     banghart 4052:     foreach my $priv_item (keys(%full_d)) {
                   4053:         my ($priv, $dummy) = split(/\&/,$priv_item);
1.269     raeburn  4054:         if ((exists($role_d{$priv})) || (exists($role_s{$priv}))) {
1.154     banghart 4055:             $return_script .= "document.form1.$priv"."_d.checked = true;\n";
                   4056:         } else {
                   4057:             $return_script .= "document.form1.$priv"."_d.checked = false;\n";
                   4058:         }
                   4059:     }
                   4060:     foreach my $priv_item (keys(%full_s)) {
1.153     banghart 4061:         my ($priv, $dummy) = split(/\&/,$priv_item);
1.154     banghart 4062:         if (exists($role_s{$priv})) {
                   4063:             $return_script .= "document.form1.$priv"."_s.checked = true;\n";
                   4064:         } else {
                   4065:             $return_script .= "document.form1.$priv"."_s.checked = false;\n";
                   4066:         }
1.153     banghart 4067:     }
                   4068:     $return_script .= '}'."\n";
1.154     banghart 4069:     return ($return_script);
                   4070: }
                   4071: # ----------------------------------------------------------
                   4072: sub make_button_code {
1.318     raeburn  4073:     my ($role,$crstype) = @_;
                   4074:     my $label = &Apache::lonnet::plaintext($role,$crstype);
1.301     bisitz   4075:     my $button_code = '<input type="button" onclick="set_'.$role.'()" value="'.$label.'" />';
1.154     banghart 4076:     return ($button_code);
1.153     banghart 4077: }
1.61      www      4078: # ---------------------------------------------------------- Call to definerole
                   4079: sub set_custom_role {
1.351     raeburn  4080:     my ($r,$context,$brcrum) = @_;
1.101     albertel 4081:     my $rolename=$env{'form.rolename'};
1.63      www      4082:     $rolename=~s/[^A-Za-z0-9]//gs;
1.150     banghart 4083:     if (!$rolename) {
1.351     raeburn  4084: 	&custom_role_editor($r,$brcrum);
1.61      www      4085:         return;
                   4086:     }
1.160     raeburn  4087:     my ($jsback,$elements) = &crumb_utilities();
1.301     bisitz   4088:     my $jscript = '<script type="text/javascript">'
                   4089:                  .'// <![CDATA['."\n"
                   4090:                  .$jsback."\n"
                   4091:                  .'// ]]>'."\n"
                   4092:                  .'</script>'."\n";
1.352     raeburn  4093:     push(@{$brcrum},
                   4094:         {href => "javascript:backPage(document.customresult,'pickrole','')",
                   4095:          text => "Pick custom role",
                   4096:          faq  => 282,
                   4097:          bug  => 'Instructor Interface',},
                   4098:         {href => "javascript:backPage(document.customresult,'selected_custom_edit','')",
                   4099:          text => "Edit custom role",
                   4100:          faq  => 282,
                   4101:          bug  => 'Instructor Interface',},
                   4102:         {href => "javascript:backPage(document.customresult,'set_custom_roles','')",
                   4103:          text => "Result",
                   4104:          faq  => 282,
                   4105:          bug  => 'Instructor Interface',
                   4106:          help => 'Course_Editing_Custom_Roles'},
                   4107:         );
                   4108:     my $args = { bread_crumbs           => $brcrum,
1.351     raeburn  4109:                  bread_crumbs_component => 'User Management'}; 
                   4110:     $r->print(&Apache::loncommon::start_page('Save Custom Role',$jscript,$args));
1.160     raeburn  4111: 
1.61      www      4112:     my ($rdummy,$roledef)=
1.110     albertel 4113: 	&Apache::lonnet::get('roles',["rolesdef_$rolename"]);
                   4114: 
1.61      www      4115: # ------------------------------------------------------- Does this role exist?
1.188     raeburn  4116:     $r->print('<h3>');
1.61      www      4117:     if (($rdummy ne 'con_lost') && ($roledef ne '')) {
1.73      sakharuk 4118: 	$r->print(&mt('Existing Role').' "');
1.61      www      4119:     } else {
1.73      sakharuk 4120: 	$r->print(&mt('New Role').' "');
1.61      www      4121: 	$roledef='';
                   4122:     }
1.188     raeburn  4123:     $r->print($rolename.'"</h3>');
1.61      www      4124: # ------------------------------------------------------- What can be assigned?
                   4125:     my $sysrole='';
                   4126:     my $domrole='';
                   4127:     my $courole='';
                   4128: 
1.135     raeburn  4129:     foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:c'})) {
                   4130: 	my ($priv,$restrict)=split(/\&/,$item);
1.150     banghart 4131:         if (!$restrict) { $restrict=''; }
                   4132:         if ($env{'form.'.$priv.'_c'}) {
1.135     raeburn  4133: 	    $courole.=':'.$item;
1.61      www      4134: 	}
                   4135:     }
                   4136: 
1.135     raeburn  4137:     foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:d'})) {
                   4138: 	my ($priv,$restrict)=split(/\&/,$item);
1.150     banghart 4139:         if (!$restrict) { $restrict=''; }
                   4140:         if ($env{'form.'.$priv.'_d'}) {
1.135     raeburn  4141: 	    $domrole.=':'.$item;
1.61      www      4142: 	}
                   4143:     }
                   4144: 
1.135     raeburn  4145:     foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:s'})) {
                   4146: 	my ($priv,$restrict)=split(/\&/,$item);
1.150     banghart 4147:         if (!$restrict) { $restrict=''; }
                   4148:         if ($env{'form.'.$priv.'_s'}) {
1.135     raeburn  4149: 	    $sysrole.=':'.$item;
1.61      www      4150: 	}
                   4151:     }
1.63      www      4152:     $r->print('<br />Defining Role: '.
1.61      www      4153: 	   &Apache::lonnet::definerole($rolename,$sysrole,$domrole,$courole));
1.101     albertel 4154:     if ($env{'request.course.id'}) {
                   4155:         my $url='/'.$env{'request.course.id'};
1.63      www      4156:         $url=~s/\_/\//g;
1.73      sakharuk 4157: 	$r->print('<br />'.&mt('Assigning Role to Self').': '.
1.101     albertel 4158: 	      &Apache::lonnet::assigncustomrole($env{'user.domain'},
                   4159: 						$env{'user.name'},
1.63      www      4160: 						$url,
1.101     albertel 4161: 						$env{'user.domain'},
                   4162: 						$env{'user.name'},
1.240     raeburn  4163: 						$rolename,undef,undef,undef,$context));
1.63      www      4164:     }
1.190     raeburn  4165:     $r->print('<p><a href="javascript:backPage(document.customresult,'."'pickrole'".')">'.&mt('Create or edit another custom role').'</a></p><form name="customresult" method="post">');
1.160     raeburn  4166:     $r->print(&Apache::lonhtmlcommon::echo_form_input([]).'</form>');
1.58      www      4167: }
                   4168: 
1.2       www      4169: # ================================================================ Main Handler
                   4170: sub handler {
                   4171:     my $r = shift;
                   4172:     if ($r->header_only) {
1.68      www      4173:        &Apache::loncommon::content_type($r,'text/html');
1.2       www      4174:        $r->send_http_header;
                   4175:        return OK;
                   4176:     }
1.318     raeburn  4177:     my ($context,$crstype);
1.190     raeburn  4178:     if ($env{'request.course.id'}) {
                   4179:         $context = 'course';
1.318     raeburn  4180:         $crstype = &Apache::loncommon::course_type();
1.190     raeburn  4181:     } elsif ($env{'request.role'} =~ /^au\./) {
1.206     raeburn  4182:         $context = 'author';
1.190     raeburn  4183:     } else {
                   4184:         $context = 'domain';
                   4185:     }
                   4186:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.233     raeburn  4187:         ['action','state','callingform','roletype','showrole','bulkaction','popup','phase',
                   4188:          'username','domain','srchterm','srchdomain','srchin','srchby','srchtype']);
1.190     raeburn  4189:     &Apache::lonhtmlcommon::clear_breadcrumbs();
1.351     raeburn  4190:     my $args;
                   4191:     my $brcrum = [];
                   4192:     my $bread_crumbs_component = 'User Management';
1.202     raeburn  4193:     if ($env{'form.action'} ne 'dateselect') {
1.351     raeburn  4194:         $brcrum = [{href=>"/adm/createuser",
                   4195:                     text=>"User Management",
                   4196:                     help=>'Course_Create_Class_List,Course_Change_Privileges,Course_View_Class_List,Course_Editing_Custom_Roles,Course_Add_Student,Course_Drop_Student,Course_Automated_Enrollment,Course_Self_Enrollment,Course_Manage_Group'}
                   4197:                   ];
1.202     raeburn  4198:     }
1.289     droeschl 4199:     #SD Following files not added to help, because the corresponding .tex-files seem to
                   4200:     #be missing: Course_Approve_Selfenroll,Course_User_Logs,
1.209     raeburn  4201:     my ($permission,$allowed) = 
1.318     raeburn  4202:         &Apache::lonuserutils::get_permission($context,$crstype);
1.190     raeburn  4203:     if (!$allowed) {
1.358     raeburn  4204:         if ($context eq 'course') {
                   4205:             $r->internal_redirect('/adm/viewclasslist');
                   4206:             return OK;
                   4207:         }
1.190     raeburn  4208:         $env{'user.error.msg'}=
                   4209:             "/adm/createuser:cst:0:0:Cannot create/modify user data ".
                   4210:                                  "or view user status.";
                   4211:         return HTTP_NOT_ACCEPTABLE;
                   4212:     }
                   4213: 
                   4214:     &Apache::loncommon::content_type($r,'text/html');
                   4215:     $r->send_http_header;
                   4216: 
                   4217:     # Main switch on form.action and form.state, as appropriate
                   4218:     if (! exists($env{'form.action'})) {
1.351     raeburn  4219:         $args = {bread_crumbs => $brcrum,
                   4220:                  bread_crumbs_component => $bread_crumbs_component}; 
                   4221:         $r->print(&header(undef,$args));
1.318     raeburn  4222:         $r->print(&print_main_menu($permission,$context,$crstype));
1.190     raeburn  4223:     } elsif ($env{'form.action'} eq 'upload' && $permission->{'cusr'}) {
1.351     raeburn  4224:         push(@{$brcrum},
                   4225:               { href => '/adm/createuser?action=upload&state=',
                   4226:                 text => 'Upload Users List',
                   4227:                 help => 'Course_Create_Class_List',
                   4228:               });
                   4229:         $bread_crumbs_component = 'Upload Users List';
                   4230:         $args = {bread_crumbs           => $brcrum,
                   4231:                  bread_crumbs_component => $bread_crumbs_component};
                   4232:         $r->print(&header(undef,$args));
1.190     raeburn  4233:         $r->print('<form name="studentform" method="post" '.
                   4234:                   'enctype="multipart/form-data" '.
                   4235:                   ' action="/adm/createuser">'."\n");
                   4236:         if (! exists($env{'form.state'})) {
                   4237:             &Apache::lonuserutils::print_first_users_upload_form($r,$context);
                   4238:         } elsif ($env{'form.state'} eq 'got_file') {
1.221     raeburn  4239:             &Apache::lonuserutils::print_upload_manager_form($r,$context,
1.318     raeburn  4240:                                                              $permission,$crstype);
1.190     raeburn  4241:         } elsif ($env{'form.state'} eq 'enrolling') {
                   4242:             if ($env{'form.datatoken'}) {
1.221     raeburn  4243:                 &Apache::lonuserutils::upfile_drop_add($r,$context,$permission);
1.190     raeburn  4244:             }
                   4245:         } else {
                   4246:             &Apache::lonuserutils::print_first_users_upload_form($r,$context);
                   4247:         }
1.213     raeburn  4248:     } elsif ((($env{'form.action'} eq 'singleuser') || ($env{'form.action'}
                   4249:              eq 'singlestudent')) && ($permission->{'cusr'})) {
1.190     raeburn  4250:         my $phase = $env{'form.phase'};
                   4251:         my @search = ('srchterm','srchby','srchin','srchtype','srchdomain');
1.192     albertel 4252: 	&Apache::loncreateuser::restore_prev_selections();
                   4253: 	my $srch;
                   4254: 	foreach my $item (@search) {
                   4255: 	    $srch->{$item} = $env{'form.'.$item};
                   4256: 	}
1.207     raeburn  4257:         if (($phase eq 'get_user_info') || ($phase eq 'userpicked') ||
                   4258:             ($phase eq 'createnewuser')) {
                   4259:             if ($env{'form.phase'} eq 'createnewuser') {
                   4260:                 my $response;
                   4261:                 if ($env{'form.srchterm'} !~ /^$match_username$/) {
1.366   ! bisitz   4262:                     my $response =
        !          4263:                         '<span class="LC_warning">'
        !          4264:                        .&mt('You must specify a valid username. Only the following are allowed:'
        !          4265:                            .' letters numbers - . @')
        !          4266:                        .'</span>';
1.221     raeburn  4267:                     $env{'form.phase'} = '';
1.351     raeburn  4268:                     &print_username_entry_form($r,$context,$response,$srch,undef,$crstype,$brcrum);
1.207     raeburn  4269:                 } else {
                   4270:                     my $ccuname =&LONCAPA::clean_username($srch->{'srchterm'});
                   4271:                     my $ccdomain=&LONCAPA::clean_domain($srch->{'srchdomain'});
                   4272:                     &print_user_modification_page($r,$ccuname,$ccdomain,
1.221     raeburn  4273:                                                   $srch,$response,$context,
1.351     raeburn  4274:                                                   $permission,$crstype,$brcrum);
1.207     raeburn  4275:                 }
                   4276:             } elsif ($env{'form.phase'} eq 'get_user_info') {
1.190     raeburn  4277:                 my ($currstate,$response,$forcenewuser,$results) = 
1.221     raeburn  4278:                     &user_search_result($context,$srch);
1.190     raeburn  4279:                 if ($env{'form.currstate'} eq 'modify') {
                   4280:                     $currstate = $env{'form.currstate'};
                   4281:                 }
                   4282:                 if ($currstate eq 'select') {
                   4283:                     &print_user_selection_page($r,$response,$srch,$results,
1.351     raeburn  4284:                                                \@search,$context,undef,$crstype,
                   4285:                                                $brcrum);
1.190     raeburn  4286:                 } elsif ($currstate eq 'modify') {
                   4287:                     my ($ccuname,$ccdomain);
                   4288:                     if (($srch->{'srchby'} eq 'uname') && 
                   4289:                         ($srch->{'srchtype'} eq 'exact')) {
                   4290:                         $ccuname = $srch->{'srchterm'};
                   4291:                         $ccdomain= $srch->{'srchdomain'};
                   4292:                     } else {
                   4293:                         my @matchedunames = keys(%{$results});
                   4294:                         ($ccuname,$ccdomain) = split(/:/,$matchedunames[0]);
                   4295:                     }
                   4296:                     $ccuname =&LONCAPA::clean_username($ccuname);
                   4297:                     $ccdomain=&LONCAPA::clean_domain($ccdomain);
                   4298:                     if ($env{'form.forcenewuser'}) {
                   4299:                         $response = '';
                   4300:                     }
                   4301:                     &print_user_modification_page($r,$ccuname,$ccdomain,
1.221     raeburn  4302:                                                   $srch,$response,$context,
1.351     raeburn  4303:                                                   $permission,$crstype,$brcrum);
1.190     raeburn  4304:                 } elsif ($currstate eq 'query') {
1.351     raeburn  4305:                     &print_user_query_page($r,'createuser',$brcrum);
1.190     raeburn  4306:                 } else {
1.229     raeburn  4307:                     $env{'form.phase'} = '';
1.207     raeburn  4308:                     &print_username_entry_form($r,$context,$response,$srch,
1.351     raeburn  4309:                                                $forcenewuser,$crstype,$brcrum);
1.190     raeburn  4310:                 }
                   4311:             } elsif ($env{'form.phase'} eq 'userpicked') {
                   4312:                 my $ccuname = &LONCAPA::clean_username($env{'form.seluname'});
                   4313:                 my $ccdomain = &LONCAPA::clean_domain($env{'form.seludom'});
1.196     raeburn  4314:                 &print_user_modification_page($r,$ccuname,$ccdomain,$srch,'',
1.351     raeburn  4315:                                               $context,$permission,$crstype,
                   4316:                                               $brcrum);
1.190     raeburn  4317:             }
                   4318:         } elsif ($env{'form.phase'} eq 'update_user_data') {
1.351     raeburn  4319:             &update_user_data($r,$context,$crstype,$brcrum);
1.190     raeburn  4320:         } else {
1.351     raeburn  4321:             &print_username_entry_form($r,$context,undef,$srch,undef,$crstype,
                   4322:                                        $brcrum);
1.190     raeburn  4323:         }
                   4324:     } elsif ($env{'form.action'} eq 'custom' && $permission->{'custom'}) {
                   4325:         if ($env{'form.phase'} eq 'set_custom_roles') {
1.351     raeburn  4326:             &set_custom_role($r,$context,$brcrum);
1.190     raeburn  4327:         } else {
1.351     raeburn  4328:             &custom_role_editor($r,$brcrum);
1.190     raeburn  4329:         }
1.362     raeburn  4330:     } elsif (($env{'form.action'} eq 'processauthorreq') &&
                   4331:              ($permission->{'cusr'}) && 
                   4332:              (&Apache::lonnet::allowed('cau',$env{'request.role.domain'}))) {
                   4333:         push(@{$brcrum},
                   4334:                  {href => '/adm/createuser?action=processauthorreq',
                   4335:                   text => 'Authoring space requests',
                   4336:                   help => 'Domain_Role_Approvals'});
                   4337:         $bread_crumbs_component = 'Authoring requests';
                   4338:         if ($env{'form.state'} eq 'done') {
                   4339:             push(@{$brcrum},
                   4340:                      {href => '/adm/createuser?action=authorreqqueue',
                   4341:                       text => 'Result',
                   4342:                       help => 'Domain_Role_Approvals'});
                   4343:             $bread_crumbs_component = 'Authoring request result';
                   4344:         }
                   4345:         $args = { bread_crumbs           => $brcrum,
                   4346:                   bread_crumbs_component => $bread_crumbs_component};
                   4347:         $r->print(&header(undef,$args));
                   4348:         if (!exists($env{'form.state'})) {
                   4349:             $r->print(&Apache::loncoursequeueadmin::display_queued_requests('requestauthor',
                   4350:                                                                             $env{'request.role.domain'}));
                   4351:         } elsif ($env{'form.state'} eq 'done') {
                   4352:             $r->print('<h3>'.&mt('Authoring request processing').'</h3>'."\n");
                   4353:             $r->print(&Apache::loncoursequeueadmin::update_request_queue('requestauthor',
                   4354:                                                                          $env{'request.role.domain'}));
                   4355:         }
1.207     raeburn  4356:     } elsif (($env{'form.action'} eq 'listusers') && 
                   4357:              ($permission->{'view'} || $permission->{'cusr'})) {
1.202     raeburn  4358:         if ($env{'form.phase'} eq 'bulkchange') {
1.351     raeburn  4359:             push(@{$brcrum},
                   4360:                     {href => '/adm/createuser?action=listusers',
                   4361:                      text => "List Users"},
                   4362:                     {href => "/adm/createuser",
                   4363:                      text => "Result",
                   4364:                      help => 'Course_View_Class_List'});
                   4365:             $bread_crumbs_component = 'Update Users';
                   4366:             $args = {bread_crumbs           => $brcrum,
                   4367:                      bread_crumbs_component => $bread_crumbs_component};
                   4368:             $r->print(&header(undef,$args));
1.202     raeburn  4369:             my $setting = $env{'form.roletype'};
                   4370:             my $choice = $env{'form.bulkaction'};
                   4371:             if ($permission->{'cusr'}) {
1.336     raeburn  4372:                 &Apache::lonuserutils::update_user_list($r,$context,$setting,$choice,$crstype);
1.221     raeburn  4373:             } else {
                   4374:                 $r->print(&mt('You are not authorized to make bulk changes to user roles'));
1.223     raeburn  4375:                 $r->print('<p><a href="/adm/createuser?action=listusers">'.&mt('Display User Lists').'</a>');
1.202     raeburn  4376:             }
                   4377:         } else {
1.351     raeburn  4378:             push(@{$brcrum},
                   4379:                     {href => '/adm/createuser?action=listusers',
                   4380:                      text => "List Users",
                   4381:                      help => 'Course_View_Class_List'});
                   4382:             $bread_crumbs_component = 'List Users';
                   4383:             $args = {bread_crumbs           => $brcrum,
                   4384:                      bread_crumbs_component => $bread_crumbs_component};
1.202     raeburn  4385:             my ($cb_jscript,$jscript,$totcodes,$codetitles,$idlist,$idlist_titles);
                   4386:             my $formname = 'studentform';
1.364     raeburn  4387:             my $hidecall = "hide_searching();";
1.321     raeburn  4388:             if (($context eq 'domain') && (($env{'form.roletype'} eq 'course') ||
                   4389:                 ($env{'form.roletype'} eq 'community'))) {
                   4390:                 if ($env{'form.roletype'} eq 'course') {
                   4391:                     ($cb_jscript,$jscript,$totcodes,$codetitles,$idlist,$idlist_titles) = 
                   4392:                         &Apache::lonuserutils::courses_selector($env{'request.role.domain'},
                   4393:                                                                 $formname);
                   4394:                 } elsif ($env{'form.roletype'} eq 'community') {
                   4395:                     $cb_jscript = 
                   4396:                         &Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'});
                   4397:                     my %elements = (
                   4398:                                       coursepick => 'radio',
                   4399:                                       coursetotal => 'text',
                   4400:                                       courselist => 'text',
                   4401:                                    );
                   4402:                     $jscript = &Apache::lonhtmlcommon::set_form_elements(\%elements);
                   4403:                 }
1.364     raeburn  4404:                 $jscript .= &verify_user_display($context)."\n".
                   4405:                             &Apache::loncommon::check_uncheck_jscript();
1.202     raeburn  4406:                 my $js = &add_script($jscript).$cb_jscript;
                   4407:                 my $loadcode = 
                   4408:                     &Apache::lonuserutils::course_selector_loadcode($formname);
                   4409:                 if ($loadcode ne '') {
1.364     raeburn  4410:                     $args->{add_entries} = {onload => "$loadcode;$hidecall"};
                   4411:                 } else {
                   4412:                     $args->{add_entries} = {onload => $hidecall};
1.202     raeburn  4413:                 }
1.351     raeburn  4414:                 $r->print(&header($js,$args));
1.191     raeburn  4415:             } else {
1.364     raeburn  4416:                 $args->{add_entries} = {onload => $hidecall};
                   4417:                 $jscript = &verify_user_display($context).
                   4418:                            &Apache::loncommon::check_uncheck_jscript(); 
                   4419:                 $r->print(&header(&add_script($jscript),$args));
1.191     raeburn  4420:             }
1.202     raeburn  4421:             &Apache::lonuserutils::print_userlist($r,undef,$permission,$context,
                   4422:                          $formname,$totcodes,$codetitles,$idlist,$idlist_titles);
1.191     raeburn  4423:         }
1.213     raeburn  4424:     } elsif ($env{'form.action'} eq 'drop' && $permission->{'cusr'}) {
1.318     raeburn  4425:         my $brtext;
                   4426:         if ($crstype eq 'Community') {
                   4427:             $brtext = 'Drop Members';
                   4428:         } else {
                   4429:             $brtext = 'Drop Students';
                   4430:         }
1.351     raeburn  4431:         push(@{$brcrum},
                   4432:                 {href => '/adm/createuser?action=drop',
                   4433:                  text => $brtext,
                   4434:                  help => 'Course_Drop_Student'});
                   4435:         if ($env{'form.state'} eq 'done') {
                   4436:             push(@{$brcrum},
                   4437:                      {href=>'/adm/createuser?action=drop',
                   4438:                       text=>"Result"});
                   4439:         }
                   4440:         $bread_crumbs_component = $brtext;
                   4441:         $args = {bread_crumbs           => $brcrum,
                   4442:                  bread_crumbs_component => $bread_crumbs_component}; 
                   4443:         $r->print(&header(undef,$args));
1.213     raeburn  4444:         if (!exists($env{'form.state'})) {
1.318     raeburn  4445:             &Apache::lonuserutils::print_drop_menu($r,$context,$permission,$crstype);
1.213     raeburn  4446:         } elsif ($env{'form.state'} eq 'done') {
                   4447:             &Apache::lonuserutils::update_user_list($r,$context,undef,
                   4448:                                                     $env{'form.action'});
                   4449:         }
1.202     raeburn  4450:     } elsif ($env{'form.action'} eq 'dateselect') {
                   4451:         if ($permission->{'cusr'}) {
1.351     raeburn  4452:             $r->print(&header(undef,{'no_nav_bar' => 1}).
1.221     raeburn  4453:                       &Apache::lonuserutils::date_section_selector($context,
1.351     raeburn  4454:                                                                    $permission,$crstype));
1.202     raeburn  4455:         } else {
1.351     raeburn  4456:             $r->print(&header(undef,{'no_nav_bar' => 1}).
                   4457:                      '<span class="LC_error">'.&mt('You do not have permission to modify dates or sections for users').'</span>'); 
1.202     raeburn  4458:         }
1.237     raeburn  4459:     } elsif ($env{'form.action'} eq 'selfenroll') {
1.351     raeburn  4460:         push(@{$brcrum},
                   4461:                 {href => '/adm/createuser?action=selfenroll',
                   4462:                  text => "Configure Self-enrollment",
                   4463:                  help => 'Course_Self_Enrollment'});
1.237     raeburn  4464:         if (!exists($env{'form.state'})) {
1.351     raeburn  4465:             $args = { bread_crumbs           => $brcrum,
                   4466:                       bread_crumbs_component => 'Configure Self-enrollment'};
                   4467:             $r->print(&header(undef,$args));
1.241     raeburn  4468:             $r->print('<h3>'.&mt('Self-enrollment with a student role').'</h3>'."\n");
1.237     raeburn  4469:             &print_selfenroll_menu($r,$context,$permission);
                   4470:         } elsif ($env{'form.state'} eq 'done') {
1.351     raeburn  4471:             push (@{$brcrum},
                   4472:                       {href=>'/adm/createuser?action=selfenroll',
                   4473:                        text=>"Result"});
                   4474:             $args = { bread_crumbs           => $brcrum,
                   4475:                       bread_crumbs_component => 'Self-enrollment result'};
                   4476:             $r->print(&header(undef,$args));
1.241     raeburn  4477:             $r->print('<h3>'.&mt('Self-enrollment with a student role').'</h3>'."\n");
                   4478:             &update_selfenroll_config($r,$context,$permission);
1.237     raeburn  4479:         }
1.277     raeburn  4480:     } elsif ($env{'form.action'} eq 'selfenrollqueue') {
1.351     raeburn  4481:         push(@{$brcrum},
                   4482:                  {href => '/adm/createuser?action=selfenrollqueue',
                   4483:                   text => 'Enrollment requests',
                   4484:                   help => 'Course_Self_Enrollment'});
                   4485:         $bread_crumbs_component = 'Enrollment requests';
                   4486:         if ($env{'form.state'} eq 'done') {
                   4487:             push(@{$brcrum},
                   4488:                      {href => '/adm/createuser?action=selfenrollqueue',
                   4489:                       text => 'Result',
                   4490:                       help => 'Course_Self_Enrollment'});
                   4491:             $bread_crumbs_component = 'Enrollment result';
                   4492:         }
                   4493:         $args = { bread_crumbs           => $brcrum,
                   4494:                   bread_crumbs_component => $bread_crumbs_component};
                   4495:         $r->print(&header(undef,$args));
1.277     raeburn  4496:         my $cid = $env{'request.course.id'};
                   4497:         my $cdom = $env{'course.'.$cid.'.domain'};
                   4498:         my $cnum = $env{'course.'.$cid.'.num'};
1.307     raeburn  4499:         my $coursedesc = $env{'course.'.$cid.'.description'};
1.277     raeburn  4500:         if (!exists($env{'form.state'})) {
                   4501:             $r->print('<h3>'.&mt('Pending enrollment requests').'</h3>'."\n");
1.307     raeburn  4502:             $r->print(&Apache::loncoursequeueadmin::display_queued_requests($context,
                   4503:                                                                        $cdom,$cnum));
1.277     raeburn  4504:         } elsif ($env{'form.state'} eq 'done') {
                   4505:             $r->print('<h3>'.&mt('Enrollment request processing').'</h3>'."\n");
1.307     raeburn  4506:             $r->print(&Apache::loncoursequeueadmin::update_request_queue($context,
                   4507:                           $cdom,$cnum,$coursedesc));
1.277     raeburn  4508:         }
1.239     raeburn  4509:     } elsif ($env{'form.action'} eq 'changelogs') {
1.363     raeburn  4510:         my $helpitem;
                   4511:         if ($context eq 'course') {
                   4512:             $helpitem = 'Course_User_Logs';
                   4513:         }
1.351     raeburn  4514:         push (@{$brcrum},
                   4515:                  {href => '/adm/createuser?action=changelogs',
                   4516:                   text => 'User Management Logs',
1.363     raeburn  4517:                   help => $helpitem});
1.351     raeburn  4518:         $bread_crumbs_component = 'User Changes';
                   4519:         $args = { bread_crumbs           => $brcrum,
                   4520:                   bread_crumbs_component => $bread_crumbs_component};
                   4521:         $r->print(&header(undef,$args));
                   4522:         &print_userchangelogs_display($r,$context,$permission);
1.190     raeburn  4523:     } else {
1.351     raeburn  4524:         $bread_crumbs_component = 'User Management';
                   4525:         $args = { bread_crumbs           => $brcrum,
                   4526:                   bread_crumbs_component => $bread_crumbs_component};
                   4527:         $r->print(&header(undef,$args));
1.318     raeburn  4528:         $r->print(&print_main_menu($permission,$context,$crstype));
1.190     raeburn  4529:     }
1.351     raeburn  4530:     $r->print(&Apache::loncommon::end_page());
1.190     raeburn  4531:     return OK;
                   4532: }
                   4533: 
                   4534: sub header {
1.351     raeburn  4535:     my ($jscript,$args) = @_;
1.190     raeburn  4536:     my $start_page;
1.351     raeburn  4537:     if (ref($args) eq 'HASH') {
                   4538:         $start_page=&Apache::loncommon::start_page('User Management',$jscript,$args);
1.190     raeburn  4539:     } else {
1.351     raeburn  4540:         $start_page=&Apache::loncommon::start_page('User Management',$jscript);
1.190     raeburn  4541:     }
                   4542:     return $start_page;
                   4543: }
1.2       www      4544: 
1.191     raeburn  4545: sub add_script {
                   4546:     my ($js) = @_;
1.301     bisitz   4547:     return '<script type="text/javascript">'."\n"
                   4548:           .'// <![CDATA['."\n"
                   4549:           .$js."\n"
                   4550:           .'// ]]>'."\n"
                   4551:           .'</script>'."\n";
1.191     raeburn  4552: }
                   4553: 
1.202     raeburn  4554: sub verify_user_display {
1.364     raeburn  4555:     my ($context) = @_;
                   4556:     my $photos;
                   4557:     if (($context eq 'course') && $env{'request.course.id'}) {
                   4558:         $photos = $env{'course.'.$env{'request.course.id'}.'.internal.showphoto'};
                   4559:     }
1.202     raeburn  4560:     my $output = <<"END";
                   4561: 
1.364     raeburn  4562: function hide_searching() {
                   4563:     if (document.getElementById('searching')) {
                   4564:         document.getElementById('searching').style.display = 'none';
                   4565:     }
                   4566:     return;
                   4567: }
                   4568: 
1.202     raeburn  4569: function display_update() {
                   4570:     document.studentform.action.value = 'listusers';
                   4571:     document.studentform.phase.value = 'display';
                   4572:     document.studentform.submit();
                   4573: }
                   4574: 
1.364     raeburn  4575: function updateCols(caller) {
                   4576:     var context = '$context';
                   4577:     var photos = '$photos';
                   4578:     if (caller == 'Status') {
                   4579:         if (document.studentform.Status.options[document.studentform.Status.selectedIndex].value == 'Any') {
                   4580:             document.getElementById('showcolstatus').checked = true;
                   4581:             document.getElementById('showcolstatus').disabled = '';
                   4582:             document.getElementById('showcolstart').checked = true;
                   4583:             document.getElementById('showcolend').checked = true;
                   4584:         } else {
                   4585:             document.getElementById('showcolstatus').checked = false;
                   4586:             document.getElementById('showcolstatus').disabled = 'disabled';
                   4587:             document.getElementById('showcolstart').checked = false;
                   4588:             document.getElementById('showcolend').checked = false;
                   4589:         }
                   4590:     }
                   4591:     if (caller == 'output') {
                   4592:         if (photos == 1) {
                   4593:             if (document.getElementById('showcolphoto')) {
                   4594:                 var photoitem = document.getElementById('showcolphoto');
                   4595:                 if (document.studentform.output.options[document.studentform.output.selectedIndex].value == 'html') {
                   4596:                     photoitem.checked = true;
                   4597:                     photoitem.disabled = '';
                   4598:                 } else {
                   4599:                     photoitem.checked = false;
                   4600:                     photoitem.disabled = 'disabled';
                   4601:                 }
                   4602:             }
                   4603:         }
                   4604:     }
                   4605:     if (caller == 'showrole') {
                   4606:         if (document.studentform.showrole.options[document.studentform.showrole.selectedIndex].value == 'Any') {
                   4607:             document.getElementById('showcolrole').checked = true;
                   4608:             document.getElementById('showcolrole').disabled = '';
                   4609:         } else {
                   4610:             document.getElementById('showcolrole').checked = false;
                   4611:             document.getElementById('showcolrole').disabled = 'disabled';
                   4612:         }
                   4613:     }
                   4614:     return;
                   4615: }
                   4616: 
1.202     raeburn  4617: END
                   4618:     return $output;
                   4619: 
                   4620: }
                   4621: 
1.190     raeburn  4622: ###############################################################
                   4623: ###############################################################
                   4624: #  Menu Phase One
                   4625: sub print_main_menu {
1.318     raeburn  4626:     my ($permission,$context,$crstype) = @_;
                   4627:     my $linkcontext = $context;
                   4628:     my $stuterm = lc(&Apache::lonnet::plaintext('st',$crstype));
                   4629:     if (($context eq 'course') && ($crstype eq 'Community')) {
                   4630:         $linkcontext = lc($crstype);
                   4631:         $stuterm = 'Members';
                   4632:     }
1.208     raeburn  4633:     my %links = (
1.298     droeschl 4634:                 domain => {
                   4635:                             upload     => 'Upload a File of Users',
                   4636:                             singleuser => 'Add/Modify a User',
                   4637:                             listusers  => 'Manage Users',
                   4638:                             },
                   4639:                 author => {
                   4640:                             upload     => 'Upload a File of Co-authors',
                   4641:                             singleuser => 'Add/Modify a Co-author',
                   4642:                             listusers  => 'Manage Co-authors',
                   4643:                             },
                   4644:                 course => {
                   4645:                             upload     => 'Upload a File of Course Users',
                   4646:                             singleuser => 'Add/Modify a Course User',
1.354     www      4647:                             listusers  => 'List and Modify Multiple Course Users',
1.298     droeschl 4648:                             },
1.318     raeburn  4649:                 community => {
                   4650:                             upload     => 'Upload a File of Community Users',
                   4651:                             singleuser => 'Add/Modify a Community User',
1.354     www      4652:                             listusers  => 'List and Modify Multiple Community Users',
1.318     raeburn  4653:                            },
                   4654:                 );
                   4655:      my %linktitles = (
                   4656:                 domain => {
                   4657:                             singleuser => 'Add a user to the domain, and/or a course or community in the domain.',
                   4658:                             listusers  => 'Show and manage users in this domain.',
                   4659:                             },
                   4660:                 author => {
                   4661:                             singleuser => 'Add a user with a co- or assistant author role.',
                   4662:                             listusers  => 'Show and manage co- or assistant authors.',
                   4663:                             },
                   4664:                 course => {
                   4665:                             singleuser => 'Add a user with a certain role to this course.',
                   4666:                             listusers  => 'Show and manage users in this course.',
                   4667:                             },
                   4668:                 community => {
                   4669:                             singleuser => 'Add a user with a certain role to this community.',
                   4670:                             listusers  => 'Show and manage users in this community.',
                   4671:                            },
1.298     droeschl 4672:                 );
                   4673:   my @menu = ( {categorytitle => 'Single Users', 
                   4674:          items =>
                   4675:          [
                   4676:             {
1.318     raeburn  4677:              linktext => $links{$linkcontext}{'singleuser'},
1.298     droeschl 4678:              icon => 'edit-redo.png',
                   4679:              #help => 'Course_Change_Privileges',
                   4680:              url => '/adm/createuser?action=singleuser',
                   4681:              permission => $permission->{'cusr'},
1.318     raeburn  4682:              linktitle => $linktitles{$linkcontext}{'singleuser'},
1.298     droeschl 4683:             },
                   4684:          ]},
                   4685: 
                   4686:          {categorytitle => 'Multiple Users',
                   4687:          items => 
                   4688:          [
                   4689:             {
1.318     raeburn  4690:              linktext => $links{$linkcontext}{'upload'},
1.340     wenzelju 4691:              icon => 'uplusr.png',
1.298     droeschl 4692:              #help => 'Course_Create_Class_List',
                   4693:              url => '/adm/createuser?action=upload',
                   4694:              permission => $permission->{'cusr'},
                   4695:              linktitle => 'Upload a CSV or a text file containing users.',
                   4696:             },
                   4697:             {
1.318     raeburn  4698:              linktext => $links{$linkcontext}{'listusers'},
1.340     wenzelju 4699:              icon => 'mngcu.png',
1.298     droeschl 4700:              #help => 'Course_View_Class_List',
                   4701:              url => '/adm/createuser?action=listusers',
                   4702:              permission => ($permission->{'view'} || $permission->{'cusr'}),
1.318     raeburn  4703:              linktitle => $linktitles{$linkcontext}{'listusers'}, 
1.298     droeschl 4704:             },
                   4705: 
                   4706:          ]},
                   4707: 
                   4708:          {categorytitle => 'Administration',
                   4709:          items => [ ]},
                   4710:        );
                   4711:             
1.265     mielkec  4712:     if ($context eq 'domain'){
1.298     droeschl 4713:         
                   4714:         push(@{ $menu[2]->{items} }, #Category: Administration
                   4715:             {
                   4716:              linktext => 'Custom Roles',
                   4717:              icon => 'emblem-photos.png',
                   4718:              #help => 'Course_Editing_Custom_Roles',
                   4719:              url => '/adm/createuser?action=custom',
                   4720:              permission => $permission->{'custom'},
                   4721:              linktitle => 'Configure a custom role.',
                   4722:             },
1.362     raeburn  4723:             {
                   4724:              linktext => 'Authoring Space Requests',
                   4725:              icon => 'selfenrl-queue.png',
                   4726:              #help => 'Domain_Role_Approvals',
                   4727:              url => '/adm/createuser?action=processauthorreq',
                   4728:              permission => $permission->{'cusr'},
                   4729:              linktitle => 'Approve or reject author role requests',
                   4730:             },
1.363     raeburn  4731:             {
                   4732:              linktext => 'Change Log',
                   4733:              icon => 'document-properties.png',
                   4734:              #help => 'Course_User_Logs',
                   4735:              url => '/adm/createuser?action=changelogs',
                   4736:              permission => $permission->{'cusr'},
                   4737:              linktitle => 'View change log.',
                   4738:             },
1.298     droeschl 4739:         );
                   4740:         
1.265     mielkec  4741:     }elsif ($context eq 'course'){
1.298     droeschl 4742:         my ($cnum,$cdom) = &Apache::lonuserutils::get_course_identity();
1.318     raeburn  4743: 
                   4744:         my %linktext = (
                   4745:                          'Course'    => {
                   4746:                                           single => 'Add/Modify a Student', 
                   4747:                                           drop   => 'Drop Students',
                   4748:                                           groups => 'Course Groups',
                   4749:                                         },
                   4750:                          'Community' => {
                   4751:                                           single => 'Add/Modify a Member', 
                   4752:                                           drop   => 'Drop Members',
                   4753:                                           groups => 'Community Groups',
                   4754:                                         },
                   4755:                        );
                   4756: 
                   4757:         my %linktitle = (
                   4758:             'Course' => {
                   4759:                   single => 'Add a user with the role of student to this course',
                   4760:                   drop   => 'Remove a student from this course.',
                   4761:                   groups => 'Manage course groups',
                   4762:                         },
                   4763:             'Community' => {
                   4764:                   single => 'Add a user with the role of member to this community',
                   4765:                   drop   => 'Remove a member from this community.',
                   4766:                   groups => 'Manage community groups',
                   4767:                            },
                   4768:         );
                   4769: 
1.298     droeschl 4770:         push(@{ $menu[0]->{items} }, #Category: Single Users
                   4771:             {   
1.318     raeburn  4772:              linktext => $linktext{$crstype}{'single'},
1.298     droeschl 4773:              #help => 'Course_Add_Student',
                   4774:              icon => 'list-add.png',
                   4775:              url => '/adm/createuser?action=singlestudent',
                   4776:              permission => $permission->{'cusr'},
1.318     raeburn  4777:              linktitle => $linktitle{$crstype}{'single'},
1.298     droeschl 4778:             },
                   4779:         );
                   4780:         
                   4781:         push(@{ $menu[1]->{items} }, #Category: Multiple Users 
                   4782:             {
1.318     raeburn  4783:              linktext => $linktext{$crstype}{'drop'},
1.298     droeschl 4784:              icon => 'edit-undo.png',
                   4785:              #help => 'Course_Drop_Student',
                   4786:              url => '/adm/createuser?action=drop',
                   4787:              permission => $permission->{'cusr'},
1.318     raeburn  4788:              linktitle => $linktitle{$crstype}{'drop'},
1.298     droeschl 4789:             },
                   4790:         );
                   4791:         push(@{ $menu[2]->{items} }, #Category: Administration
                   4792:             {    
                   4793:              linktext => 'Custom Roles',
                   4794:              icon => 'emblem-photos.png',
                   4795:              #help => 'Course_Editing_Custom_Roles',
                   4796:              url => '/adm/createuser?action=custom',
                   4797:              permission => $permission->{'custom'},
                   4798:              linktitle => 'Configure a custom role.',
                   4799:             },
                   4800:             {
1.318     raeburn  4801:              linktext => $linktext{$crstype}{'groups'},
1.333     wenzelju 4802:              icon => 'grps.png',
1.298     droeschl 4803:              #help => 'Course_Manage_Group',
                   4804:              url => '/adm/coursegroups?refpage=cusr',
                   4805:              permission => $permission->{'grp_manage'},
1.318     raeburn  4806:              linktitle => $linktitle{$crstype}{'groups'},
1.298     droeschl 4807:             },
                   4808:             {
1.328     wenzelju 4809:              linktext => 'Change Log',
1.298     droeschl 4810:              icon => 'document-properties.png',
                   4811:              #help => 'Course_User_Logs',
                   4812:              url => '/adm/createuser?action=changelogs',
                   4813:              permission => $permission->{'cusr'},
                   4814:              linktitle => 'View change log.',
                   4815:             },
                   4816:         );
1.277     raeburn  4817:         if ($env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_approval'}) {
1.298     droeschl 4818:             push(@{ $menu[2]->{items} },
                   4819:                     {   
                   4820:                      linktext => 'Enrollment Requests',
                   4821:                      icon => 'selfenrl-queue.png',
                   4822:                      #help => 'Course_Approve_Selfenroll',
                   4823:                      url => '/adm/createuser?action=selfenrollqueue',
                   4824:                      permission => $permission->{'cusr'},
                   4825:                      linktitle =>'Approve or reject enrollment requests.',
                   4826:                     },
                   4827:             );
1.277     raeburn  4828:         }
1.298     droeschl 4829:         
1.265     mielkec  4830:         if (!exists($permission->{'cusr_section'})){
1.320     raeburn  4831:             if ($crstype ne 'Community') {
                   4832:                 push(@{ $menu[2]->{items} },
                   4833:                     {
                   4834:                      linktext => 'Automated Enrollment',
                   4835:                      icon => 'roles.png',
                   4836:                      #help => 'Course_Automated_Enrollment',
                   4837:                      permission => (&Apache::lonnet::auto_run($cnum,$cdom)
                   4838:                                          && $permission->{'cusr'}),
                   4839:                      url  => '/adm/populate',
                   4840:                      linktitle => 'Automated enrollment manager.',
                   4841:                     }
                   4842:                 );
                   4843:             }
                   4844:             push(@{ $menu[2]->{items} }, 
1.298     droeschl 4845:                 {
                   4846:                  linktext => 'User Self-Enrollment',
1.342     wenzelju 4847:                  icon => 'self_enroll.png',
1.298     droeschl 4848:                  #help => 'Course_Self_Enrollment',
                   4849:                  url => '/adm/createuser?action=selfenroll',
                   4850:                  permission => $permission->{'cusr'},
1.317     bisitz   4851:                  linktitle => 'Configure user self-enrollment.',
1.298     droeschl 4852:                 },
                   4853:             );
                   4854:         }
1.363     raeburn  4855:     } elsif ($context eq 'author') {
                   4856:             {
                   4857:              linktext => 'Change Log',
                   4858:              icon => 'document-properties.png',
                   4859:              #help => 'Course_User_Logs',
                   4860:              url => '/adm/createuser?action=changelogs',
                   4861:              permission => $permission->{'cusr'},
                   4862:              linktitle => 'View change log.',
                   4863:             },
                   4864:     }
                   4865:     return Apache::lonhtmlcommon::generate_menu(@menu);
1.250     raeburn  4866: #               { text => 'View Log-in History',
                   4867: #                 help => 'Course_User_Logins',
                   4868: #                 action => 'logins',
                   4869: #                 permission => $permission->{'cusr'},
                   4870: #               });
1.190     raeburn  4871: }
                   4872: 
1.189     albertel 4873: sub restore_prev_selections {
                   4874:     my %saveable_parameters = ('srchby'   => 'scalar',
                   4875: 			       'srchin'   => 'scalar',
                   4876: 			       'srchtype' => 'scalar',
                   4877: 			       );
                   4878:     &Apache::loncommon::store_settings('user','user_picker',
                   4879: 				       \%saveable_parameters);
                   4880:     &Apache::loncommon::restore_settings('user','user_picker',
                   4881: 					 \%saveable_parameters);
                   4882: }
                   4883: 
1.237     raeburn  4884: sub print_selfenroll_menu {
                   4885:     my ($r,$context,$permission) = @_;
1.322     raeburn  4886:     my $crstype = &Apache::loncommon::course_type();
1.237     raeburn  4887:     my $formname = 'enrollstudent';
                   4888:     my $nolink = 1;
                   4889:     my ($row,$lt) = &get_selfenroll_titles();
                   4890:     my $groupslist = &Apache::lonuserutils::get_groupslist();
                   4891:     my $setsec_js = 
                   4892:         &Apache::lonuserutils::setsections_javascript($formname,$groupslist);
1.249     raeburn  4893:     my %alerts = &Apache::lonlocal::texthash(
                   4894:         acto => 'Activation of self-enrollment was selected for the following domain(s)',
                   4895:         butn => 'but no user types have been checked.',
                   4896:         wilf => "Please uncheck 'activate' or check at least one type.",
                   4897:     );
                   4898:     my $selfenroll_js = <<"ENDSCRIPT";
                   4899: function update_types(caller,num) {
                   4900:     var delidx = getIndexByName('selfenroll_delete');
                   4901:     var actidx = getIndexByName('selfenroll_activate');
                   4902:     if (caller == 'selfenroll_all') {
                   4903:         var selall;
                   4904:         for (var i=0; i<document.$formname.selfenroll_all.length; i++) {
                   4905:             if (document.$formname.selfenroll_all[i].checked) {
                   4906:                 selall = document.$formname.selfenroll_all[i].value;
                   4907:             }
                   4908:         }
                   4909:         if (selall == 1) {
                   4910:             if (delidx != -1) {
                   4911:                 if (document.$formname.selfenroll_delete.length) {
                   4912:                     for (var j=0; j<document.$formname.selfenroll_delete.length; j++) {
                   4913:                         document.$formname.selfenroll_delete[j].checked = true;
                   4914:                     }
                   4915:                 } else {
                   4916:                     document.$formname.elements[delidx].checked = true;
                   4917:                 }
                   4918:             }
                   4919:             if (actidx != -1) {
                   4920:                 if (document.$formname.selfenroll_activate.length) {
                   4921:                     for (var j=0; j<document.$formname.selfenroll_activate.length; j++) {
                   4922:                         document.$formname.selfenroll_activate[j].checked = false;
                   4923:                     }
                   4924:                 } else {
                   4925:                     document.$formname.elements[actidx].checked = false;
                   4926:                 }
                   4927:             }
                   4928:             document.$formname.selfenroll_newdom.selectedIndex = 0; 
                   4929:         }
                   4930:     }
                   4931:     if (caller == 'selfenroll_activate') {
                   4932:         if (document.$formname.selfenroll_activate.length) {
                   4933:             for (var j=0; j<document.$formname.selfenroll_activate.length; j++) {
                   4934:                 if (document.$formname.selfenroll_activate[j].value == num) {
                   4935:                     if (document.$formname.selfenroll_activate[j].checked) {
                   4936:                         for (var i=0; i<document.$formname.selfenroll_all.length; i++) {
                   4937:                             if (document.$formname.selfenroll_all[i].value == '1') {
                   4938:                                 document.$formname.selfenroll_all[i].checked = false;
                   4939:                             }
                   4940:                             if (document.$formname.selfenroll_all[i].value == '0') {
                   4941:                                 document.$formname.selfenroll_all[i].checked = true;
                   4942:                             }
                   4943:                         }
                   4944:                     }
                   4945:                 }
                   4946:             }
                   4947:         } else {
                   4948:             for (var i=0; i<document.$formname.selfenroll_all.length; i++) {
                   4949:                 if (document.$formname.selfenroll_all[i].value == '1') {
                   4950:                     document.$formname.selfenroll_all[i].checked = false;
                   4951:                 }
                   4952:                 if (document.$formname.selfenroll_all[i].value == '0') {
                   4953:                     document.$formname.selfenroll_all[i].checked = true;
                   4954:                 }
                   4955:             }
                   4956:         }
                   4957:     }
                   4958:     if (caller == 'selfenroll_delete') {
                   4959:         if (document.$formname.selfenroll_delete.length) {
                   4960:             for (var j=0; j<document.$formname.selfenroll_delete.length; j++) {
                   4961:                 if (document.$formname.selfenroll_delete[j].value == num) {
                   4962:                     if (document.$formname.selfenroll_delete[j].checked) {
                   4963:                         var delindex = getIndexByName('selfenroll_types_'+num);
                   4964:                         if (delindex != -1) { 
                   4965:                             if (document.$formname.elements[delindex].length) {
                   4966:                                 for (var k=0; k<document.$formname.elements[delindex].length; k++) {
                   4967:                                     document.$formname.elements[delindex][k].checked = false;
                   4968:                                 }
                   4969:                             } else {
                   4970:                                 document.$formname.elements[delindex].checked = false;
                   4971:                             }
                   4972:                         }
                   4973:                     }
                   4974:                 }
                   4975:             }
                   4976:         } else {
                   4977:             if (document.$formname.selfenroll_delete.checked) {
                   4978:                 var delindex = getIndexByName('selfenroll_types_'+num);
                   4979:                 if (delindex != -1) {
                   4980:                     if (document.$formname.elements[delindex].length) {
                   4981:                         for (var k=0; k<document.$formname.elements[delindex].length; k++) {
                   4982:                             document.$formname.elements[delindex][k].checked = false;
                   4983:                         }
                   4984:                     } else {
                   4985:                         document.$formname.elements[delindex].checked = false;
                   4986:                     }
                   4987:                 }
                   4988:             }
                   4989:         }
                   4990:     }
                   4991:     return;
                   4992: }
                   4993: 
                   4994: function validate_types(form) {
                   4995:     var needaction = new Array();
                   4996:     var countfail = 0;
                   4997:     var actidx = getIndexByName('selfenroll_activate');
                   4998:     if (actidx != -1) {
                   4999:         if (document.$formname.selfenroll_activate.length) {
                   5000:             for (var j=0; j<document.$formname.selfenroll_activate.length; j++) {
                   5001:                 var num = document.$formname.selfenroll_activate[j].value;
                   5002:                 if (document.$formname.selfenroll_activate[j].checked) {
                   5003:                     countfail = check_types(num,countfail,needaction)
                   5004:                 }
                   5005:             }
                   5006:         } else {
                   5007:             if (document.$formname.selfenroll_activate.checked) {
                   5008:                 var num = document.enrollstudent.selfenroll_activate.value;
                   5009:                 countfail = check_types(num,countfail,needaction)
                   5010:             }
                   5011:         }
                   5012:     }
                   5013:     if (countfail > 0) {
                   5014:         var msg = "$alerts{'acto'}\\n";
                   5015:         var loopend = needaction.length -1;
                   5016:         if (loopend > 0) {
                   5017:             for (var m=0; m<loopend; m++) {
                   5018:                 msg += needaction[m]+", ";
                   5019:             }
                   5020:         }
                   5021:         msg += needaction[loopend]+"\\n$alerts{'butn'}\\n$alerts{'wilf'}";
                   5022:         alert(msg);
                   5023:         return; 
                   5024:     }
                   5025:     setSections(form);
                   5026: }
                   5027: 
                   5028: function check_types(num,countfail,needaction) {
                   5029:     var typeidx = getIndexByName('selfenroll_types_'+num);
                   5030:     var count = 0;
                   5031:     if (typeidx != -1) {
                   5032:         if (document.$formname.elements[typeidx].length) {
                   5033:             for (var k=0; k<document.$formname.elements[typeidx].length; k++) {
                   5034:                 if (document.$formname.elements[typeidx][k].checked) {
                   5035:                     count ++;
                   5036:                 }
                   5037:             }
                   5038:         } else {
                   5039:             if (document.$formname.elements[typeidx].checked) {
                   5040:                 count ++;
                   5041:             }
                   5042:         }
                   5043:         if (count == 0) {
                   5044:             var domidx = getIndexByName('selfenroll_dom_'+num);
                   5045:             if (domidx != -1) {
                   5046:                 var domname = document.$formname.elements[domidx].value;
                   5047:                 needaction[countfail] = domname;
                   5048:                 countfail ++;
                   5049:             }
                   5050:         }
                   5051:     }
                   5052:     return countfail;
                   5053: }
                   5054: 
                   5055: function getIndexByName(item) {
                   5056:     for (var i=0;i<document.$formname.elements.length;i++) {
                   5057:         if (document.$formname.elements[i].name == item) {
                   5058:             return i;
                   5059:         }
                   5060:     }
                   5061:     return -1;
                   5062: }
                   5063: ENDSCRIPT
1.256     raeburn  5064:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   5065:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   5066: 
1.237     raeburn  5067:     my $output = '<script type="text/javascript">'."\n".
1.301     bisitz   5068:                  '// <![CDATA['."\n".
1.249     raeburn  5069:                  $setsec_js."\n".$selfenroll_js."\n".
1.301     bisitz   5070:                  '// ]]>'."\n".
1.237     raeburn  5071:                  '</script>'."\n".
1.256     raeburn  5072:                  '<h3>'.$lt->{'selfenroll'}.'</h3>'."\n";
                   5073:     my ($visible,$cansetvis,$vismsgs,$visactions) = &visible_in_cat($cdom,$cnum);
                   5074:     if (ref($visactions) eq 'HASH') {
                   5075:         if ($visible) {
1.283     bisitz   5076:             $output .= '<p class="LC_info">'.$visactions->{'vis'}.'</p>';
1.256     raeburn  5077:         } else {
1.283     bisitz   5078:             $output .= '<p class="LC_warning">'.$visactions->{'miss'}.'</p>'
                   5079:                       .$visactions->{'yous'}.
1.256     raeburn  5080:                        '<p>'.$visactions->{'gen'}.'<br />'.$visactions->{'coca'};
                   5081:             if (ref($vismsgs) eq 'ARRAY') {
                   5082:                 $output .= '<br />'.$visactions->{'make'}.'<ul>';
                   5083:                 foreach my $item (@{$vismsgs}) {
                   5084:                     $output .= '<li>'.$visactions->{$item}.'</li>';
                   5085:                 }
                   5086:                 $output .= '</ul>';
                   5087:             }
                   5088:             $output .= '</p>';
                   5089:         }
                   5090:     }
                   5091:     $output .= '<form name="'.$formname.'" method="post" action="/adm/createuser">'."\n".
                   5092:                &Apache::lonhtmlcommon::start_pick_box();
1.237     raeburn  5093:     if (ref($row) eq 'ARRAY') {
                   5094:         foreach my $item (@{$row}) {
                   5095:             my $title = $item; 
                   5096:             if (ref($lt) eq 'HASH') {
                   5097:                 $title = $lt->{$item};
                   5098:             }
1.297     bisitz   5099:             $output .= &Apache::lonhtmlcommon::row_title($title);
1.237     raeburn  5100:             if ($item eq 'types') {
                   5101:                 my $curr_types = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_types'};
1.241     raeburn  5102:                 my $showdomdesc = 1;
                   5103:                 my $includeempty = 1;
                   5104:                 my $num = 0;
                   5105:                 $output .= &Apache::loncommon::start_data_table().
                   5106:                            &Apache::loncommon::start_data_table_row()
                   5107:                            .'<td colspan="2"><span class="LC_nobreak"><label>'
                   5108:                            .&mt('Any user in any domain:')
                   5109:                            .'&nbsp;<input type="radio" name="selfenroll_all" value="1" ';
                   5110:                 if ($curr_types eq '*') {
                   5111:                     $output .= ' checked="checked" '; 
                   5112:                 }
1.249     raeburn  5113:                 $output .= 'onchange="javascript:update_types('.
                   5114:                            "'selfenroll_all'".');" />'.&mt('Yes').'</label>'.
                   5115:                            '&nbsp;&nbsp;<input type="radio" name="selfenroll_all" value="0" ';
1.241     raeburn  5116:                 if ($curr_types ne '*') {
                   5117:                     $output .= ' checked="checked" ';
                   5118:                 }
1.249     raeburn  5119:                 $output .= ' onchange="javascript:update_types('.
                   5120:                            "'selfenroll_all'".');"/>'.&mt('No').'</label></td>'.
                   5121:                            &Apache::loncommon::end_data_table_row().
                   5122:                            &Apache::loncommon::end_data_table().
                   5123:                            &mt('Or').'<br />'.
                   5124:                            &Apache::loncommon::start_data_table();
1.241     raeburn  5125:                 my %currdoms;
1.249     raeburn  5126:                 if ($curr_types eq '') {
1.241     raeburn  5127:                     $output .= &new_selfenroll_dom_row($cdom,'0');
                   5128:                 } elsif ($curr_types ne '*') {
                   5129:                     my @entries = split(/;/,$curr_types);
                   5130:                     if (@entries > 0) {
                   5131:                         foreach my $entry (@entries) {
                   5132:                             my ($currdom,$typestr) = split(/:/,$entry);
                   5133:                             $currdoms{$currdom} = 1;
                   5134:                             my $domdesc = &Apache::lonnet::domain($currdom);
1.249     raeburn  5135:                             my @currinsttypes = split(',',$typestr);
1.241     raeburn  5136:                             $output .= &Apache::loncommon::start_data_table_row()
                   5137:                                        .'<td valign="top"><span class="LC_nobreak">'.&mt('Domain:').'<b>'
                   5138:                                        .'&nbsp;'.$domdesc.' ('.$currdom.')'
                   5139:                                        .'</b><input type="hidden" name="selfenroll_dom_'.$num
                   5140:                                        .'" value="'.$currdom.'" /></span><br />'
                   5141:                                        .'<span class="LC_nobreak"><label><input type="checkbox" '
1.249     raeburn  5142:                                        .'name="selfenroll_delete" value="'.$num.'" onchange="javascript:update_types('."'selfenroll_delete','$num'".');" />'
1.241     raeburn  5143:                                        .&mt('Delete').'</label></span></td>';
1.249     raeburn  5144:                             $output .= '<td valign="top">&nbsp;&nbsp;'.&mt('User types:').'<br />'
1.241     raeburn  5145:                                        .&selfenroll_inst_types($num,$currdom,\@currinsttypes).'</td>'
                   5146:                                        .&Apache::loncommon::end_data_table_row();
                   5147:                             $num ++;
                   5148:                         }
                   5149:                     }
                   5150:                 }
1.249     raeburn  5151:                 my $add_domtitle = &mt('Users in additional domain:');
1.241     raeburn  5152:                 if ($curr_types eq '*') { 
1.249     raeburn  5153:                     $add_domtitle = &mt('Users in specific domain:');
1.241     raeburn  5154:                 } elsif ($curr_types eq '') {
1.249     raeburn  5155:                     $add_domtitle = &mt('Users in other domain:');
1.241     raeburn  5156:                 }
                   5157:                 $output .= &Apache::loncommon::start_data_table_row()
                   5158:                            .'<td colspan="2"><span class="LC_nobreak">'.$add_domtitle.'</span><br />'
                   5159:                            .&Apache::loncommon::select_dom_form('','selfenroll_newdom',
                   5160:                                                                 $includeempty,$showdomdesc)
                   5161:                            .'<input type="hidden" name="selfenroll_types_total" value="'.$num.'" />'
                   5162:                            .'</td>'.&Apache::loncommon::end_data_table_row()
                   5163:                            .&Apache::loncommon::end_data_table();
1.237     raeburn  5164:             } elsif ($item eq 'registered') {
                   5165:                 my ($regon,$regoff);
                   5166:                 if ($env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_registered'}) {
                   5167:                     $regon = ' checked="checked" ';
                   5168:                     $regoff = ' ';
                   5169:                 } else {
                   5170:                     $regon = ' ';
                   5171:                     $regoff = ' checked="checked" ';
                   5172:                 }
                   5173:                 $output .= '<label>'.
1.245     raeburn  5174:                            '<input type="radio" name="selfenroll_registered" value="1"'.$regon.'/>'.
1.244     bisitz   5175:                            &mt('Yes').'</label>&nbsp;&nbsp;<label>'.
1.245     raeburn  5176:                            '<input type="radio" name="selfenroll_registered" value="0"'.$regoff.'/>'.
1.244     bisitz   5177:                            &mt('No').'</label>';
1.237     raeburn  5178:             } elsif ($item eq 'enroll_dates') {
                   5179:                 my $starttime = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_start_date'};
                   5180:                 my $endtime = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_end_date'};
                   5181:                 if ($starttime eq '') {
                   5182:                     $starttime = $env{'course.'.$env{'request.course.id'}.'.default_enrollment_start_date'};
                   5183:                 }
                   5184:                 if ($endtime eq '') {
                   5185:                     $endtime = $env{'course.'.$env{'request.course.id'}.'.default_enrollment_end_date'};
                   5186:                 }
                   5187:                 my $startform =
                   5188:                     &Apache::lonhtmlcommon::date_setter($formname,'selfenroll_start_date',$starttime,
                   5189:                                       undef,undef,undef,undef,undef,undef,undef,$nolink);
                   5190:                 my $endform =
                   5191:                     &Apache::lonhtmlcommon::date_setter($formname,'selfenroll_end_date',$endtime,
                   5192:                                       undef,undef,undef,undef,undef,undef,undef,$nolink);
                   5193:                 $output .= &selfenroll_date_forms($startform,$endform);
                   5194:             } elsif ($item eq 'access_dates') {
                   5195:                 my $starttime = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_start_access'};
                   5196:                 my $endtime = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_end_access'};
                   5197:                 if ($starttime eq '') {
                   5198:                     $starttime = $env{'course.'.$env{'request.course.id'}.'.default_enrollment_start_date'};
                   5199:                 }
                   5200:                 if ($endtime eq '') {
                   5201:                     $endtime = $env{'course.'.$env{'request.course.id'}.'.default_enrollment_end_date'};
                   5202:                 }
                   5203:                 my $startform =
                   5204:                     &Apache::lonhtmlcommon::date_setter($formname,'selfenroll_start_access',$starttime,
                   5205:                                       undef,undef,undef,undef,undef,undef,undef,$nolink);
                   5206:                 my $endform =
                   5207:                     &Apache::lonhtmlcommon::date_setter($formname,'selfenroll_end_access',$endtime,
                   5208:                                       undef,undef,undef,undef,undef,undef,undef,$nolink);
                   5209:                 $output .= &selfenroll_date_forms($startform,$endform);
                   5210:             } elsif ($item eq 'section') {
                   5211:                 my $currsec = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_section'}; 
                   5212:                 my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum);
                   5213:                 my $newsecval;
                   5214:                 if ($currsec ne 'none' && $currsec ne '') {
                   5215:                     if (!defined($sections_count{$currsec})) {
                   5216:                         $newsecval = $currsec;
                   5217:                     }
                   5218:                 }
                   5219:                 my $sections_select = 
                   5220:                     &Apache::lonuserutils::course_sections(\%sections_count,'st',$currsec);
                   5221:                 $output .= '<table class="LC_createuser">'."\n".
                   5222:                            '<tr class="LC_section_row">'."\n".
                   5223:                            '<td align="center">'.&mt('Existing sections')."\n".
                   5224:                            '<br />'.$sections_select.'</td><td align="center">'.
                   5225:                            &mt('New section').'<br />'."\n".
                   5226:                            '<input type="text" name="newsec" size="15" value="'.$newsecval.'" />'."\n".
                   5227:                            '<input type="hidden" name="sections" value="" />'."\n".
                   5228:                            '<input type="hidden" name="state" value="done" />'."\n".
                   5229:                            '</td></tr></table>'."\n";
1.276     raeburn  5230:             } elsif ($item eq 'approval') {
                   5231:                 my ($appon,$appoff);
                   5232:                 my $cid = $env{'request.course.id'};
                   5233:                 my $currnotified = $env{'course.'.$cid.'.internal.selfenroll_notifylist'};
                   5234:                 if ($env{'course.'.$cid.'.internal.selfenroll_approval'}) {
                   5235:                     $appon = ' checked="checked" ';
                   5236:                     $appoff = ' ';
                   5237:                 } else {
                   5238:                     $appon = ' ';
                   5239:                     $appoff = ' checked="checked" ';
                   5240:                 }
                   5241:                 $output .= '<label>'.
                   5242:                            '<input type="radio" name="selfenroll_approval" value="1"'.$appon.'/>'.
                   5243:                            &mt('Yes').'</label>&nbsp;&nbsp;<label>'.
                   5244:                            '<input type="radio" name="selfenroll_approval" value="0"'.$appoff.'/>'.
                   5245:                            &mt('No').'</label>';
                   5246:                 my %advhash = &Apache::lonnet::get_course_adv_roles($cid,1);
                   5247:                 my (@ccs,%notified);
1.322     raeburn  5248:                 my $ccrole = 'cc';
                   5249:                 if ($crstype eq 'Community') {
                   5250:                     $ccrole = 'co';
                   5251:                 }
                   5252:                 if ($advhash{$ccrole}) {
                   5253:                     @ccs = split(/,/,$advhash{$ccrole});
1.276     raeburn  5254:                 }
                   5255:                 if ($currnotified) {
                   5256:                     foreach my $current (split(/,/,$currnotified)) {
                   5257:                         $notified{$current} = 1;
                   5258:                         if (!grep(/^\Q$current\E$/,@ccs)) {
                   5259:                             push(@ccs,$current);
                   5260:                         }
                   5261:                     }
                   5262:                 }
                   5263:                 if (@ccs) {
1.277     raeburn  5264:                     $output .= '<br />'.&mt('Personnel to be notified when an enrollment request needs approval, or has been approved:').'&nbsp;'.&Apache::loncommon::start_data_table().
1.276     raeburn  5265:                                &Apache::loncommon::start_data_table_row();
                   5266:                     my $count = 0;
                   5267:                     my $numcols = 4;
                   5268:                     foreach my $cc (sort(@ccs)) {
                   5269:                         my $notifyon;
                   5270:                         my ($ccuname,$ccudom) = split(/:/,$cc);
                   5271:                         if ($notified{$cc}) {
                   5272:                             $notifyon = ' checked="checked" ';
                   5273:                         }
                   5274:                         if ($count && !$count%$numcols) {
                   5275:                             $output .= &Apache::loncommon::end_data_table_row().
                   5276:                                        &Apache::loncommon::start_data_table_row()
                   5277:                         }
                   5278:                         $output .= '<td><span class="LC_nobreak"><label>'.
                   5279:                                    '<input type="checkbox" name="selfenroll_notify"'.$notifyon.' value="'.$cc.'" />'.
                   5280:                                    &Apache::loncommon::plainname($ccuname,$ccudom).
                   5281:                                    '</label></span></td>';
1.343     raeburn  5282:                         $count ++;
1.276     raeburn  5283:                     }
                   5284:                     my $rem = $count%$numcols;
                   5285:                     if ($rem) {
                   5286:                         my $emptycols = $numcols - $rem;
                   5287:                         for (my $i=0; $i<$emptycols; $i++) { 
                   5288:                             $output .= '<td>&nbsp;</td>';
                   5289:                         }
                   5290:                     }
                   5291:                     $output .= &Apache::loncommon::end_data_table_row().
                   5292:                                &Apache::loncommon::end_data_table();
                   5293:                 }
                   5294:             } elsif ($item eq 'limit') {
                   5295:                 my ($crslimit,$selflimit,$nolimit);
                   5296:                 my $cid = $env{'request.course.id'};
                   5297:                 my $currlim = $env{'course.'.$cid.'.internal.selfenroll_limit'};
                   5298:                 my $currcap = $env{'course.'.$cid.'.internal.selfenroll_cap'};
1.343     raeburn  5299:                 $nolimit = ' checked="checked" ';
1.276     raeburn  5300:                 if ($currlim eq 'allstudents') {
                   5301:                     $crslimit = ' checked="checked" ';
                   5302:                     $selflimit = ' ';
                   5303:                     $nolimit = ' ';
                   5304:                 } elsif ($currlim eq 'selfenrolled') {
                   5305:                     $crslimit = ' ';
                   5306:                     $selflimit = ' checked="checked" ';
                   5307:                     $nolimit = ' '; 
                   5308:                 } else {
                   5309:                     $crslimit = ' ';
                   5310:                     $selflimit = ' ';
                   5311:                 }
                   5312:                 $output .= '<table><tr><td><label>'.
1.278     raeburn  5313:                            '<input type="radio" name="selfenroll_limit" value="none"'.$nolimit.'/>'.
1.276     raeburn  5314:                            &mt('No limit').'</label></td><td><label>'.
                   5315:                            '<input type="radio" name="selfenroll_limit" value="allstudents"'.$crslimit.'/>'.
                   5316:                            &mt('Limit by total students').'</label></td><td><label>'.
                   5317:                            '<input type="radio" name="selfenroll_limit" value="selfenrolled"'.$selflimit.'/>'.
                   5318:                            &mt('Limit by total self-enrolled students').
                   5319:                            '</td></tr><tr>'.
                   5320:                            '<td>&nbsp;</td><td colspan="2"><span class="LC_nobreak">'.
                   5321:                            ('&nbsp;'x3).&mt('Maximum number allowed: ').
                   5322:                            '<input type="text" name="selfenroll_cap" size = "5" value="'.$currcap.'" /></td></tr></table>';
1.237     raeburn  5323:             }
                   5324:             $output .= &Apache::lonhtmlcommon::row_closure(1);
                   5325:         }
                   5326:     }
                   5327:     $output .= &Apache::lonhtmlcommon::end_pick_box().
1.241     raeburn  5328:                '<br /><input type="button" name="selfenrollconf" value="'
1.282     schafran 5329:                .&mt('Save').'" onclick="validate_types(this.form);" />'
1.241     raeburn  5330:                .'<input type="hidden" name="action" value="selfenroll" /></form>';
1.237     raeburn  5331:     $r->print($output);
                   5332:     return;
                   5333: }
                   5334: 
1.256     raeburn  5335: sub visible_in_cat {
                   5336:     my ($cdom,$cnum) = @_;
                   5337:     my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom);
                   5338:     my ($cathash,%settable,@vismsgs,$cansetvis);
                   5339:     my %visactions = &Apache::lonlocal::texthash(
1.316     bisitz   5340:                    vis => 'Your course/community currently appears in the Course/Community Catalog for this domain.',
1.256     raeburn  5341:                    gen => 'Courses can be both self-cataloging, based on an institutional code (e.g., fs08phy231), or can be assigned categories from a hierarchy defined for the domain.',
1.316     bisitz   5342:                    miss => 'Your course/community does not currently appear in the Course/Community Catalog for this domain.',
1.256     raeburn  5343:                    yous => 'You should remedy this if you plan to allow self-enrollment, otherwise students will have difficulty finding your course.',
                   5344:                    coca => 'Courses can be absent from the Catalog, because they do not have an institutional code, have no assigned category, or have been specifically excluded.',
1.282     schafran 5345:                    make => 'Make any changes to self-enrollment settings below, click "Save", then take action to include the course in the Catalog:',
1.256     raeburn  5346:                    take => 'Take the following action to ensure the course appears in the Catalog:',
                   5347:                    dc_unhide  => 'Ask a domain coordinator to change the "Exclude from course catalog" setting.',
                   5348:                    dc_addinst => 'Ask a domain coordinator to enable display the catalog of "Official courses (with institutional codes)".',
                   5349:                    dc_instcode => 'Ask a domain coordinator to assign an institutional code (if this is an official course).',
                   5350:                    dc_catalog  => 'Ask a domain coordinator to enable or create at least one course category in the domain.',
                   5351:                    dc_categories => 'Ask a domain coordinator to create a hierarchy of categories and sub categories for courses in the domain.',
                   5352:                    dc_chgcat => 'Ask a domain coordinator to change the category assigned to the course, as the one currently assigned is no longer used in the domain',
                   5353:                    dc_addcat => 'Ask a domain coordinator to assign a category to the course.',
                   5354:     );
1.347     raeburn  5355:     $visactions{'unhide'} = &mt('Use [_1]Categorize course[_2] to change the "Exclude from course catalog" setting.','<a href="/adm/courseprefs?phase=display&actions=courseinfo">','</a>"');
                   5356:     $visactions{'chgcat'} = &mt('Use [_1]Categorize course[_2] to change the category assigned to the course, as the one currently assigned is no longer used in the domain.','"<a href="/adm/courseprefs?phase=display&actions=courseinfo">','</a>"');
                   5357:     $visactions{'addcat'} = &mt('Use [_1]Categorize course[_2] to assign a category to the course.','"<a href="/adm/courseprefs?phase=display&actions=courseinfo">','</a>"');
1.256     raeburn  5358:     if (ref($domconf{'coursecategories'}) eq 'HASH') {
                   5359:         if ($domconf{'coursecategories'}{'togglecats'} eq 'crs') {
                   5360:             $settable{'togglecats'} = 1;
                   5361:         }
                   5362:         if ($domconf{'coursecategories'}{'categorize'} eq 'crs') {
                   5363:             $settable{'categorize'} = 1;
                   5364:         }
                   5365:         $cathash = $domconf{'coursecategories'}{'cats'};
                   5366:     }
1.260     raeburn  5367:     if ($settable{'togglecats'} && $settable{'categorize'}) {
1.256     raeburn  5368:         $cansetvis = &mt('You are able to both assign a course category and choose to exclude this course from the catalog.');   
                   5369:     } elsif ($settable{'togglecats'}) {
                   5370:         $cansetvis = &mt('You are able to choose to exclude this course from the catalog, but only a Domain Coordinator may assign a course category.'); 
1.260     raeburn  5371:     } elsif ($settable{'categorize'}) {
1.256     raeburn  5372:         $cansetvis = &mt('You may assign a course category, but only a Domain Coordinator may choose to exclude this course from the catalog.');  
                   5373:     } else {
                   5374:         $cansetvis = &mt('Only a Domain Coordinator may assign a course category or choose to exclude this course from the catalog.'); 
                   5375:     }
                   5376:      
                   5377:     my %currsettings =
                   5378:         &Apache::lonnet::get('environment',['hidefromcat','categories','internal.coursecode'],
                   5379:                              $cdom,$cnum);
                   5380:     my $visible = 0;
                   5381:     if ($currsettings{'internal.coursecode'} ne '') {
                   5382:         if (ref($domconf{'coursecategories'}) eq 'HASH') {
                   5383:             $cathash = $domconf{'coursecategories'}{'cats'};
                   5384:             if (ref($cathash) eq 'HASH') {
                   5385:                 if ($cathash->{'instcode::0'} eq '') {
                   5386:                     push(@vismsgs,'dc_addinst'); 
                   5387:                 } else {
                   5388:                     $visible = 1;
                   5389:                 }
                   5390:             } else {
                   5391:                 $visible = 1;
                   5392:             }
                   5393:         } else {
                   5394:             $visible = 1;
                   5395:         }
                   5396:     } else {
                   5397:         if (ref($cathash) eq 'HASH') {
                   5398:             if ($cathash->{'instcode::0'} ne '') {
                   5399:                 push(@vismsgs,'dc_instcode');
                   5400:             }
                   5401:         } else {
                   5402:             push(@vismsgs,'dc_instcode');
                   5403:         }
                   5404:     }
                   5405:     if ($currsettings{'categories'} ne '') {
                   5406:         my $cathash;
                   5407:         if (ref($domconf{'coursecategories'}) eq 'HASH') {
                   5408:             $cathash = $domconf{'coursecategories'}{'cats'};
                   5409:             if (ref($cathash) eq 'HASH') {
                   5410:                 if (keys(%{$cathash}) == 0) {
                   5411:                     push(@vismsgs,'dc_catalog');
                   5412:                 } elsif ((keys(%{$cathash}) == 1) && ($cathash->{'instcode::0'} ne '')) {
                   5413:                     push(@vismsgs,'dc_categories');
                   5414:                 } else {
                   5415:                     my @currcategories = split('&',$currsettings{'categories'});
                   5416:                     my $matched = 0;
                   5417:                     foreach my $cat (@currcategories) {
                   5418:                         if ($cathash->{$cat} ne '') {
                   5419:                             $visible = 1;
                   5420:                             $matched = 1;
                   5421:                             last;
                   5422:                         }
                   5423:                     }
                   5424:                     if (!$matched) {
1.260     raeburn  5425:                         if ($settable{'categorize'}) { 
1.256     raeburn  5426:                             push(@vismsgs,'chgcat');
                   5427:                         } else {
                   5428:                             push(@vismsgs,'dc_chgcat');
                   5429:                         }
                   5430:                     }
                   5431:                 }
                   5432:             }
                   5433:         }
                   5434:     } else {
                   5435:         if (ref($cathash) eq 'HASH') {
                   5436:             if ((keys(%{$cathash}) > 1) || 
                   5437:                 (keys(%{$cathash}) == 1) && ($cathash->{'instcode::0'} eq '')) {
1.260     raeburn  5438:                 if ($settable{'categorize'}) {
1.256     raeburn  5439:                     push(@vismsgs,'addcat');
                   5440:                 } else {
                   5441:                     push(@vismsgs,'dc_addcat');
                   5442:                 }
                   5443:             }
                   5444:         }
                   5445:     }
                   5446:     if ($currsettings{'hidefromcat'} eq 'yes') {
                   5447:         $visible = 0;
                   5448:         if ($settable{'togglecats'}) {
                   5449:             unshift(@vismsgs,'unhide');
                   5450:         } else {
                   5451:             unshift(@vismsgs,'dc_unhide')
                   5452:         }
                   5453:     }
                   5454:     return ($visible,$cansetvis,\@vismsgs,\%visactions);
                   5455: }
                   5456: 
1.241     raeburn  5457: sub new_selfenroll_dom_row {
                   5458:     my ($newdom,$num) = @_;
                   5459:     my $domdesc = &Apache::lonnet::domain($newdom);
                   5460:     my $output;
                   5461:     if ($domdesc ne '') {
                   5462:         $output .= &Apache::loncommon::start_data_table_row()
                   5463:                    .'<td valign="top"><span class="LC_nobreak">'.&mt('Domain:').'&nbsp;<b>'.$domdesc
                   5464:                    .' ('.$newdom.')</b><input type="hidden" name="selfenroll_dom_'.$num
1.249     raeburn  5465:                    .'" value="'.$newdom.'" /></span><br />'
                   5466:                    .'<span class="LC_nobreak"><label><input type="checkbox" '
                   5467:                    .'name="selfenroll_activate" value="'.$num.'" '
                   5468:                    .'onchange="javascript:update_types('
                   5469:                    ."'selfenroll_activate','$num'".');" />'
                   5470:                    .&mt('Activate').'</label></span></td>';
1.241     raeburn  5471:         my @currinsttypes;
                   5472:         $output .= '<td>'.&mt('User types:').'<br />'
                   5473:                    .&selfenroll_inst_types($num,$newdom,\@currinsttypes).'</td>'
                   5474:                    .&Apache::loncommon::end_data_table_row();
                   5475:     }
                   5476:     return $output;
                   5477: }
                   5478: 
                   5479: sub selfenroll_inst_types {
                   5480:     my ($num,$currdom,$currinsttypes) = @_;
                   5481:     my $output;
                   5482:     my $numinrow = 4;
                   5483:     my $count = 0;
                   5484:     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($currdom);
1.247     raeburn  5485:     my $othervalue = 'any';
1.241     raeburn  5486:     if ((ref($types) eq 'ARRAY') && (ref($usertypes) eq 'HASH')) {
1.251     raeburn  5487:         if (keys(%{$usertypes}) > 0) {
1.247     raeburn  5488:             $othervalue = 'other';
                   5489:         }
1.241     raeburn  5490:         $output .= '<table><tr>';
                   5491:         foreach my $type (@{$types}) {
                   5492:             if (($count > 0) && ($count%$numinrow == 0)) {
                   5493:                 $output .= '</tr><tr>';
                   5494:             }
                   5495:             if (defined($usertypes->{$type})) {
1.257     raeburn  5496:                 my $esc_type = &escape($type);
1.241     raeburn  5497:                 $output .= '<td><span class="LC_nobreak"><label><input type = "checkbox" value="'.
1.257     raeburn  5498:                            $esc_type.'" ';
1.241     raeburn  5499:                 if (ref($currinsttypes) eq 'ARRAY') {
                   5500:                     if (@{$currinsttypes} > 0) {
1.249     raeburn  5501:                         if (grep(/^any$/,@{$currinsttypes})) {
                   5502:                             $output .= 'checked="checked"';
1.257     raeburn  5503:                         } elsif (grep(/^\Q$esc_type\E$/,@{$currinsttypes})) {
1.241     raeburn  5504:                             $output .= 'checked="checked"';
                   5505:                         }
1.249     raeburn  5506:                     } else {
                   5507:                         $output .= 'checked="checked"';
1.241     raeburn  5508:                     }
                   5509:                 }
                   5510:                 $output .= ' name="selfenroll_types_'.$num.'" />'.$usertypes->{$type}.'</label></span></td>';
                   5511:             }
                   5512:             $count ++;
                   5513:         }
                   5514:         if (($count > 0) && ($count%$numinrow == 0)) {
                   5515:             $output .= '</tr><tr>';
                   5516:         }
1.249     raeburn  5517:         $output .= '<td><span class="LC_nobreak"><label><input type = "checkbox" value="'.$othervalue.'"';
1.241     raeburn  5518:         if (ref($currinsttypes) eq 'ARRAY') {
                   5519:             if (@{$currinsttypes} > 0) {
1.249     raeburn  5520:                 if (grep(/^any$/,@{$currinsttypes})) { 
                   5521:                     $output .= ' checked="checked"';
                   5522:                 } elsif ($othervalue eq 'other') {
                   5523:                     if (grep(/^\Q$othervalue\E$/,@{$currinsttypes})) {
                   5524:                         $output .= ' checked="checked"';
                   5525:                     }
1.241     raeburn  5526:                 }
1.249     raeburn  5527:             } else {
                   5528:                 $output .= ' checked="checked"';
1.241     raeburn  5529:             }
1.249     raeburn  5530:         } else {
                   5531:             $output .= ' checked="checked"';
1.241     raeburn  5532:         }
                   5533:         $output .= ' name="selfenroll_types_'.$num.'" />'.$othertitle.'</label></span></td></tr></table>';
                   5534:     }
                   5535:     return $output;
                   5536: }
                   5537: 
1.237     raeburn  5538: sub selfenroll_date_forms {
                   5539:     my ($startform,$endform) = @_;
                   5540:     my $output .= &Apache::lonhtmlcommon::start_pick_box()."\n".
1.244     bisitz   5541:                   &Apache::lonhtmlcommon::row_title(&mt('Start date'),
1.237     raeburn  5542:                                                     'LC_oddrow_value')."\n".
                   5543:                   $startform."\n".
                   5544:                   &Apache::lonhtmlcommon::row_closure(1).
1.244     bisitz   5545:                   &Apache::lonhtmlcommon::row_title(&mt('End date'),
1.237     raeburn  5546:                                                    'LC_oddrow_value')."\n".
                   5547:                   $endform."\n".
                   5548:                   &Apache::lonhtmlcommon::row_closure(1).
                   5549:                   &Apache::lonhtmlcommon::end_pick_box();
                   5550:     return $output;
                   5551: }
                   5552: 
1.239     raeburn  5553: sub print_userchangelogs_display {
                   5554:     my ($r,$context,$permission) = @_;
1.363     raeburn  5555:     my $formname = 'rolelog';
                   5556:     my ($username,$domain,$crstype,%roleslog);
                   5557:     if ($context eq 'domain') {
                   5558:         $domain = $env{'request.role.domain'};
                   5559:         %roleslog=&Apache::lonnet::dump_dom('nohist_rolelog',$domain);
                   5560:     } else {
                   5561:         if ($context eq 'course') { 
                   5562:             $domain = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   5563:             $username = $env{'course.'.$env{'request.course.id'}.'.num'};
                   5564:             $crstype = &Apache::loncommon::course_type();
                   5565:             my %saveable_parameters = ('show' => 'scalar',);
                   5566:             &Apache::loncommon::store_course_settings('roles_log',
                   5567:                                                       \%saveable_parameters);
                   5568:             &Apache::loncommon::restore_course_settings('roles_log',
                   5569:                                                         \%saveable_parameters);
                   5570:         } elsif ($context eq 'author') {
                   5571:             $domain = $env{'user.domain'}; 
                   5572:             if ($env{'request.role'} =~ m{^au\./\Q$domain\E/$}) {
                   5573:                 $username = $env{'user.name'};
                   5574:             } else {
                   5575:                 undef($domain);
                   5576:             }
                   5577:         }
                   5578:         if ($domain ne '' && $username ne '') { 
                   5579:             %roleslog=&Apache::lonnet::dump('nohist_rolelog',$domain,$username);
                   5580:         }
                   5581:     }
1.239     raeburn  5582:     if ((keys(%roleslog))[0]=~/^error\:/) { undef(%roleslog); }
                   5583: 
                   5584:     # set defaults
                   5585:     my $now = time();
                   5586:     my $defstart = $now - (7*24*3600); #7 days ago 
                   5587:     my %defaults = (
                   5588:                      page               => '1',
                   5589:                      show               => '10',
                   5590:                      role               => 'any',
                   5591:                      chgcontext         => 'any',
                   5592:                      rolelog_start_date => $defstart,
                   5593:                      rolelog_end_date   => $now,
                   5594:                    );
                   5595:     my $more_records = 0;
                   5596: 
                   5597:     # set current
                   5598:     my %curr;
                   5599:     foreach my $item ('show','page','role','chgcontext') {
                   5600:         $curr{$item} = $env{'form.'.$item};
                   5601:     }
                   5602:     my ($startdate,$enddate) = 
                   5603:         &Apache::lonuserutils::get_dates_from_form('rolelog_start_date','rolelog_end_date');
                   5604:     $curr{'rolelog_start_date'} = $startdate;
                   5605:     $curr{'rolelog_end_date'} = $enddate;
                   5606:     foreach my $key (keys(%defaults)) {
                   5607:         if ($curr{$key} eq '') {
                   5608:             $curr{$key} = $defaults{$key};
                   5609:         }
                   5610:     }
1.248     raeburn  5611:     my (%whodunit,%changed,$version);
                   5612:     ($version) = ($r->dir_config('lonVersion') =~ /^([\d\.]+)\-/);
1.239     raeburn  5613:     my ($minshown,$maxshown);
1.255     raeburn  5614:     $minshown = 1;
1.239     raeburn  5615:     my $count = 0;
                   5616:     if ($curr{'show'} ne &mt('all')) { 
                   5617:         $maxshown = $curr{'page'} * $curr{'show'};
                   5618:         if ($curr{'page'} > 1) {
                   5619:             $minshown = 1 + ($curr{'page'} - 1) * $curr{'show'};
                   5620:         }
                   5621:     }
1.301     bisitz   5622: 
1.327     raeburn  5623:     # Form Header
                   5624:     $r->print('<form action="/adm/createuser" method="post" name="'.$formname.'">'.
1.363     raeburn  5625:               &role_display_filter($context,$formname,$domain,$username,\%curr,
                   5626:                                    $version,$crstype));
1.327     raeburn  5627: 
                   5628:     # Create navigation
                   5629:     my ($nav_script,$nav_links) = &userlogdisplay_nav($formname,\%curr,$more_records);
                   5630:     my $showntableheader = 0;
                   5631: 
                   5632:     # Table Header
                   5633:     my $tableheader = 
                   5634:         &Apache::loncommon::start_data_table_header_row()
                   5635:        .'<th>&nbsp;</th>'
                   5636:        .'<th>'.&mt('When').'</th>'
                   5637:        .'<th>'.&mt('Who made the change').'</th>'
                   5638:        .'<th>'.&mt('Changed User').'</th>'
1.363     raeburn  5639:        .'<th>'.&mt('Role').'</th>';
                   5640: 
                   5641:     if ($context eq 'course') {
                   5642:         $tableheader .= '<th>'.&mt('Section').'</th>';
                   5643:     }
                   5644:     $tableheader .=
                   5645:         '<th>'.&mt('Context').'</th>'
1.327     raeburn  5646:        .'<th>'.&mt('Start').'</th>'
                   5647:        .'<th>'.&mt('End').'</th>'
                   5648:        .&Apache::loncommon::end_data_table_header_row();
                   5649: 
                   5650:     # Display user change log data
1.239     raeburn  5651:     foreach my $id (sort { $roleslog{$b}{'exe_time'}<=>$roleslog{$a}{'exe_time'} } (keys(%roleslog))) {
                   5652:         next if (($roleslog{$id}{'exe_time'} < $curr{'rolelog_start_date'}) ||
                   5653:                  ($roleslog{$id}{'exe_time'} > $curr{'rolelog_end_date'}));
                   5654:         if ($curr{'show'} ne &mt('all')) {
                   5655:             if ($count >= $curr{'page'} * $curr{'show'}) {
                   5656:                 $more_records = 1;
                   5657:                 last;
                   5658:             }
                   5659:         }
                   5660:         if ($curr{'role'} ne 'any') {
                   5661:             next if ($roleslog{$id}{'logentry'}{'role'} ne $curr{'role'}); 
                   5662:         }
                   5663:         if ($curr{'chgcontext'} ne 'any') {
                   5664:             if ($curr{'chgcontext'} eq 'selfenroll') {
                   5665:                 next if (!$roleslog{$id}{'logentry'}{'selfenroll'});
                   5666:             } else {
                   5667:                 next if ($roleslog{$id}{'logentry'}{'context'} ne $curr{'chgcontext'});
                   5668:             }
                   5669:         }
                   5670:         $count ++;
                   5671:         next if ($count < $minshown);
1.327     raeburn  5672:         unless ($showntableheader) {
                   5673:             $r->print($nav_script
                   5674:                      .$nav_links
                   5675:                      .&Apache::loncommon::start_data_table()
                   5676:                      .$tableheader);
                   5677:             $r->rflush();
                   5678:             $showntableheader = 1;
                   5679:         }
1.239     raeburn  5680:         if ($whodunit{$roleslog{$id}{'exe_uname'}.':'.$roleslog{$id}{'exe_udom'}} eq '') {
                   5681:             $whodunit{$roleslog{$id}{'exe_uname'}.':'.$roleslog{$id}{'exe_udom'}} =
                   5682:                 &Apache::loncommon::plainname($roleslog{$id}{'exe_uname'},$roleslog{$id}{'exe_udom'});
                   5683:         }
                   5684:         if ($changed{$roleslog{$id}{'uname'}.':'.$roleslog{$id}{'udom'}} eq '') {
                   5685:             $changed{$roleslog{$id}{'uname'}.':'.$roleslog{$id}{'udom'}} =
                   5686:                 &Apache::loncommon::plainname($roleslog{$id}{'uname'},$roleslog{$id}{'udom'});
                   5687:         }
                   5688:         my $sec = $roleslog{$id}{'logentry'}{'section'};
                   5689:         if ($sec eq '') {
                   5690:             $sec = &mt('None');
                   5691:         }
                   5692:         my ($rolestart,$roleend);
                   5693:         if ($roleslog{$id}{'delflag'}) {
                   5694:             $rolestart = &mt('deleted');
                   5695:             $roleend = &mt('deleted');
                   5696:         } else {
                   5697:             $rolestart = $roleslog{$id}{'logentry'}{'start'};
                   5698:             $roleend = $roleslog{$id}{'logentry'}{'end'};
                   5699:             if ($rolestart eq '' || $rolestart == 0) {
                   5700:                 $rolestart = &mt('No start date'); 
                   5701:             } else {
                   5702:                 $rolestart = &Apache::lonlocal::locallocaltime($rolestart);
                   5703:             }
                   5704:             if ($roleend eq '' || $roleend == 0) { 
                   5705:                 $roleend = &mt('No end date');
                   5706:             } else {
                   5707:                 $roleend = &Apache::lonlocal::locallocaltime($roleend);
                   5708:             }
                   5709:         }
                   5710:         my $chgcontext = $roleslog{$id}{'logentry'}{'context'};
                   5711:         if ($roleslog{$id}{'logentry'}{'selfenroll'}) {
                   5712:             $chgcontext = 'selfenroll';
                   5713:         }
1.363     raeburn  5714:         my %lt = &rolechg_contexts($context,$crstype);
1.239     raeburn  5715:         if ($chgcontext ne '' && $lt{$chgcontext} ne '') {
                   5716:             $chgcontext = $lt{$chgcontext};
                   5717:         }
1.327     raeburn  5718:         $r->print(
1.301     bisitz   5719:             &Apache::loncommon::start_data_table_row()
                   5720:            .'<td>'.$count.'</td>'
                   5721:            .'<td>'.&Apache::lonlocal::locallocaltime($roleslog{$id}{'exe_time'}).'</td>'
                   5722:            .'<td>'.$whodunit{$roleslog{$id}{'exe_uname'}.':'.$roleslog{$id}{'exe_udom'}}.'</td>'
                   5723:            .'<td>'.$changed{$roleslog{$id}{'uname'}.':'.$roleslog{$id}{'udom'}}.'</td>'
1.363     raeburn  5724:            .'<td>'.&Apache::lonnet::plaintext($roleslog{$id}{'logentry'}{'role'},$crstype).'</td>');
                   5725:         if ($context eq 'course') { 
                   5726:             $r->print('<td>'.$sec.'</td>');
                   5727:         }
                   5728:         $r->print(
                   5729:             '<td>'.$chgcontext.'</td>'
1.301     bisitz   5730:            .'<td>'.$rolestart.'</td>'
                   5731:            .'<td>'.$roleend.'</td>'
1.327     raeburn  5732:            .&Apache::loncommon::end_data_table_row()."\n");
1.301     bisitz   5733:     }
                   5734: 
1.327     raeburn  5735:     if ($showntableheader) { # Table footer, if content displayed above
                   5736:         $r->print(&Apache::loncommon::end_data_table()
                   5737:                  .$nav_links);
                   5738:     } else { # No content displayed above
1.301     bisitz   5739:         $r->print('<p class="LC_info">'
                   5740:                  .&mt('There are no records to display.')
                   5741:                  .'</p>'
                   5742:         );
1.239     raeburn  5743:     }
1.301     bisitz   5744: 
1.327     raeburn  5745:     # Form Footer
                   5746:     $r->print( 
                   5747:         '<input type="hidden" name="page" value="'.$curr{'page'}.'" />'
                   5748:        .'<input type="hidden" name="action" value="changelogs" />'
                   5749:        .'</form>');
                   5750:     return;
                   5751: }
1.301     bisitz   5752: 
1.327     raeburn  5753: sub userlogdisplay_nav {
                   5754:     my ($formname,$curr,$more_records) = @_;
                   5755:     my ($nav_script,$nav_links);
                   5756:     if (ref($curr) eq 'HASH') {
                   5757:         # Create Navigation:
                   5758:         # Navigation Script
                   5759:         $nav_script = <<"ENDSCRIPT";
1.239     raeburn  5760: <script type="text/javascript">
1.301     bisitz   5761: // <![CDATA[
1.239     raeburn  5762: function chgPage(caller) {
                   5763:     if (caller == 'previous') {
                   5764:         document.$formname.page.value --;
                   5765:     }
                   5766:     if (caller == 'next') {
                   5767:         document.$formname.page.value ++;
                   5768:     }
1.327     raeburn  5769:     document.$formname.submit();
1.239     raeburn  5770:     return;
                   5771: }
1.301     bisitz   5772: // ]]>
1.239     raeburn  5773: </script>
                   5774: ENDSCRIPT
1.327     raeburn  5775:         # Navigation Buttons
                   5776:         $nav_links = '<p>';
                   5777:         if (($curr->{'page'} > 1) || ($more_records)) {
                   5778:             if ($curr->{'page'} > 1) {
                   5779:                 $nav_links .= '<input type="button"'
                   5780:                              .' onclick="javascript:chgPage('."'previous'".');"'
                   5781:                              .' value="'.&mt('Previous [_1] changes',$curr->{'show'})
                   5782:                              .'" /> ';
                   5783:             }
                   5784:             if ($more_records) {
                   5785:                 $nav_links .= '<input type="button"'
                   5786:                              .' onclick="javascript:chgPage('."'next'".');"'
                   5787:                              .' value="'.&mt('Next [_1] changes',$curr->{'show'})
                   5788:                              .'" />';
                   5789:             }
1.301     bisitz   5790:         }
1.327     raeburn  5791:         $nav_links .= '</p>';
1.301     bisitz   5792:     }
1.327     raeburn  5793:     return ($nav_script,$nav_links);
1.239     raeburn  5794: }
                   5795: 
                   5796: sub role_display_filter {
1.363     raeburn  5797:     my ($context,$formname,$cdom,$cnum,$curr,$version,$crstype) = @_;
                   5798:     my $lctype;
                   5799:     if ($context eq 'course') {
                   5800:         $lctype = lc($crstype);
                   5801:     }
1.239     raeburn  5802:     my $nolink = 1;
                   5803:     my $output = '<table><tr><td valign="top">'.
1.301     bisitz   5804:                  '<span class="LC_nobreak"><b>'.&mt('Changes/page:').'</b></span><br />'.
1.239     raeburn  5805:                  &Apache::lonmeta::selectbox('show',$curr->{'show'},undef,
                   5806:                                               (&mt('all'),5,10,20,50,100,1000,10000)).
                   5807:                  '</td><td>&nbsp;&nbsp;</td>';
                   5808:     my $startform =
                   5809:         &Apache::lonhtmlcommon::date_setter($formname,'rolelog_start_date',
                   5810:                                             $curr->{'rolelog_start_date'},undef,
                   5811:                                             undef,undef,undef,undef,undef,undef,$nolink);
                   5812:     my $endform =
                   5813:         &Apache::lonhtmlcommon::date_setter($formname,'rolelog_end_date',
                   5814:                                             $curr->{'rolelog_end_date'},undef,
                   5815:                                             undef,undef,undef,undef,undef,undef,$nolink);
1.363     raeburn  5816:     my %lt = &rolechg_contexts($context,$crstype);
1.301     bisitz   5817:     $output .= '<td valign="top"><b>'.&mt('Window during which changes occurred:').'</b><br />'.
                   5818:                '<table><tr><td>'.&mt('After:').
                   5819:                '</td><td>'.$startform.'</td></tr>'.
                   5820:                '<tr><td>'.&mt('Before:').'</td>'.
                   5821:                '<td>'.$endform.'</td></tr></table>'.
                   5822:                '</td>'.
                   5823:                '<td>&nbsp;&nbsp;</td>'.
1.239     raeburn  5824:                '<td valign="top"><b>'.&mt('Role:').'</b><br />'.
                   5825:                '<select name="role"><option value="any"';
                   5826:     if ($curr->{'role'} eq 'any') {
                   5827:         $output .= ' selected="selected"';
                   5828:     }
                   5829:     $output .=  '>'.&mt('Any').'</option>'."\n";
1.363     raeburn  5830:     my @roles = &Apache::lonuserutils::roles_by_context($context,1,$crstype);
1.239     raeburn  5831:     foreach my $role (@roles) {
                   5832:         my $plrole;
                   5833:         if ($role eq 'cr') {
                   5834:             $plrole = &mt('Custom Role');
                   5835:         } else {
1.318     raeburn  5836:             $plrole=&Apache::lonnet::plaintext($role,$crstype);
1.239     raeburn  5837:         }
                   5838:         my $selstr = '';
                   5839:         if ($role eq $curr->{'role'}) {
                   5840:             $selstr = ' selected="selected"';
                   5841:         }
                   5842:         $output .= '  <option value="'.$role.'"'.$selstr.'>'.$plrole.'</option>';
                   5843:     }
1.301     bisitz   5844:     $output .= '</select></td>'.
                   5845:                '<td>&nbsp;&nbsp;</td>'.
                   5846:                '<td valign="top"><b>'.
1.239     raeburn  5847:                &mt('Context:').'</b><br /><select name="chgcontext">';
1.363     raeburn  5848:     my @posscontexts;
                   5849:     if ($context eq 'course') {
                   5850:         @posscontexts = ('any','auto','updatenow','createcourse','course','domain','selfenroll','requestcourses');
                   5851:     } elsif ($context eq 'domain') {
                   5852:         @posscontexts = ('any','domain','requestauthor','domconfig','server');
                   5853:     } else {
                   5854:         @posscontexts = ('any','author','domain');
                   5855:     } 
                   5856:     foreach my $chgtype (@posscontexts) {
1.239     raeburn  5857:         my $selstr = '';
                   5858:         if ($curr->{'chgcontext'} eq $chgtype) {
1.301     bisitz   5859:             $selstr = ' selected="selected"';
1.239     raeburn  5860:         }
1.363     raeburn  5861:         if ($context eq 'course') {
                   5862:             if (($chgtype eq 'auto') || ($chgtype eq 'updatenow')) {
                   5863:                 next if (!&Apache::lonnet::auto_run($cnum,$cdom));
                   5864:             }
1.239     raeburn  5865:         }
                   5866:         $output .= '<option value="'.$chgtype.'"'.$selstr.'>'.$lt{$chgtype}.'</option>'."\n";
1.248     raeburn  5867:     }
1.303     bisitz   5868:     $output .= '</select></td>'
                   5869:               .'</tr></table>';
                   5870: 
                   5871:     # Update Display button
                   5872:     $output .= '<p>'
                   5873:               .'<input type="submit" value="'.&mt('Update Display').'" />'
                   5874:               .'</p>';
                   5875: 
                   5876:     # Server version info
1.363     raeburn  5877:     my $needsrev = '2.11.0';
                   5878:     if ($context eq 'course') {
                   5879:         $needsrev = '2.7.0';
                   5880:     }
                   5881:     
1.303     bisitz   5882:     $output .= '<p class="LC_info">'
                   5883:               .&mt('Only changes made from servers running LON-CAPA [_1] or later are displayed.'
1.363     raeburn  5884:                   ,$needsrev);
1.248     raeburn  5885:     if ($version) {
1.303     bisitz   5886:         $output .= ' '.&mt('This LON-CAPA server is version [_1]',$version);
                   5887:     }
                   5888:     $output .= '</p><hr />';
1.239     raeburn  5889:     return $output;
                   5890: }
                   5891: 
                   5892: sub rolechg_contexts {
1.363     raeburn  5893:     my ($context,$crstype) = @_;
                   5894:     my %lt;
                   5895:     if ($context eq 'course') {
                   5896:         %lt = &Apache::lonlocal::texthash (
1.239     raeburn  5897:                                              any          => 'Any',
                   5898:                                              auto         => 'Automated enrollment',
                   5899:                                              updatenow    => 'Roster Update',
                   5900:                                              createcourse => 'Course Creation',
                   5901:                                              course       => 'User Management in course',
                   5902:                                              domain       => 'User Management in domain',
1.313     raeburn  5903:                                              selfenroll   => 'Self-enrolled',
1.318     raeburn  5904:                                              requestcourses => 'Course Request',
1.239     raeburn  5905:                                          );
1.363     raeburn  5906:         if ($crstype eq 'Community') {
                   5907:             $lt{'createcourse'} = &mt('Community Creation');
                   5908:             $lt{'course'} = &mt('User Management in community');
                   5909:             $lt{'requestcourses'} = &mt('Community Request');
                   5910:         }
                   5911:     } elsif ($context eq 'domain') {
                   5912:         %lt = &Apache::lonlocal::texthash (
                   5913:                                              any           => 'Any',
                   5914:                                              domain        => 'User Management in domain',
                   5915:                                              requestauthor => 'Authoring Request',
                   5916:                                              server        => 'Command line script (DC role)',
                   5917:                                              domconfig     => 'Self-enrolled',
                   5918:                                          );
                   5919:     } else {
                   5920:         %lt = &Apache::lonlocal::texthash (
                   5921:                                              any    => 'Any',
                   5922:                                              domain => 'User Management in domain',
                   5923:                                              author => 'User Management by author',
                   5924:                                          );
                   5925:     } 
1.239     raeburn  5926:     return %lt;
                   5927: }
                   5928: 
1.27      matthew  5929: #-------------------------------------------------- functions for &phase_two
1.160     raeburn  5930: sub user_search_result {
1.221     raeburn  5931:     my ($context,$srch) = @_;
1.160     raeburn  5932:     my %allhomes;
                   5933:     my %inst_matches;
                   5934:     my %srch_results;
1.181     raeburn  5935:     my ($response,$currstate,$forcenewuser,$dirsrchres);
1.183     raeburn  5936:     $srch->{'srchterm'} =~ s/\s+/ /g;
1.176     raeburn  5937:     if ($srch->{'srchby'} !~ /^(uname|lastname|lastfirst)$/) {
1.160     raeburn  5938:         $response = &mt('Invalid search.');
                   5939:     }
                   5940:     if ($srch->{'srchin'} !~ /^(crs|dom|alc|instd)$/) {
                   5941:         $response = &mt('Invalid search.');
                   5942:     }
1.177     raeburn  5943:     if ($srch->{'srchtype'} !~ /^(exact|contains|begins)$/) {
1.160     raeburn  5944:         $response = &mt('Invalid search.');
                   5945:     }
                   5946:     if ($srch->{'srchterm'} eq '') {
                   5947:         $response = &mt('You must enter a search term.');
                   5948:     }
1.183     raeburn  5949:     if ($srch->{'srchterm'} =~ /^\s+$/) {
                   5950:         $response = &mt('Your search term must contain more than just spaces.');
                   5951:     }
1.160     raeburn  5952:     if (($srch->{'srchin'} eq 'dom') || ($srch->{'srchin'} eq 'instd')) {
                   5953:         if (($srch->{'srchdomain'} eq '') || 
1.163     albertel 5954: 	    ! (&Apache::lonnet::domain($srch->{'srchdomain'}))) {
1.160     raeburn  5955:             $response = &mt('You must specify a valid domain when searching in a domain or institutional directory.')
                   5956:         }
                   5957:     }
                   5958:     if (($srch->{'srchin'} eq 'dom') || ($srch->{'srchin'} eq 'crs') ||
                   5959:         ($srch->{'srchin'} eq 'alc')) {
1.176     raeburn  5960:         if ($srch->{'srchby'} eq 'uname') {
1.243     raeburn  5961:             my $unamecheck = $srch->{'srchterm'};
                   5962:             if ($srch->{'srchtype'} eq 'contains') {
                   5963:                 if ($unamecheck !~ /^\w/) {
                   5964:                     $unamecheck = 'a'.$unamecheck; 
                   5965:                 }
                   5966:             }
                   5967:             if ($unamecheck !~ /^$match_username$/) {
1.176     raeburn  5968:                 $response = &mt('You must specify a valid username. Only the following are allowed: letters numbers - . @');
                   5969:             }
1.160     raeburn  5970:         }
                   5971:     }
1.180     raeburn  5972:     if ($response ne '') {
                   5973:         $response = '<span class="LC_warning">'.$response.'</span>';
                   5974:     }
1.160     raeburn  5975:     if ($srch->{'srchin'} eq 'instd') {
                   5976:         my $instd_chk = &directorysrch_check($srch);
                   5977:         if ($instd_chk ne 'ok') {
1.180     raeburn  5978:             $response = '<span class="LC_warning">'.$instd_chk.'</span>'.
                   5979:                         '<br />'.&mt('You may want to search in the LON-CAPA domain instead of the institutional directory.').'<br /><br />';
1.160     raeburn  5980:         }
                   5981:     }
                   5982:     if ($response ne '') {
1.180     raeburn  5983:         return ($currstate,$response);
1.160     raeburn  5984:     }
                   5985:     if ($srch->{'srchby'} eq 'uname') {
                   5986:         if (($srch->{'srchin'} eq 'dom') || ($srch->{'srchin'} eq 'crs')) {
                   5987:             if ($env{'form.forcenew'}) {
                   5988:                 if ($srch->{'srchdomain'} ne $env{'request.role.domain'}) {
                   5989:                     my $uhome=&Apache::lonnet::homeserver($srch->{'srchterm'},$srch->{'srchdomain'});
                   5990:                     if ($uhome eq 'no_host') {
                   5991:                         my $domdesc = &Apache::lonnet::domain($env{'request.role.domain'},'description');
1.180     raeburn  5992:                         my $showdom = &display_domain_info($env{'request.role.domain'});
                   5993:                         $response = &mt('New users can only be created in the domain to which your current role belongs - [_1].',$showdom);
1.160     raeburn  5994:                     } else {
1.179     raeburn  5995:                         $currstate = 'modify';
1.160     raeburn  5996:                     }
                   5997:                 } else {
1.179     raeburn  5998:                     $currstate = 'modify';
1.160     raeburn  5999:                 }
                   6000:             } else {
                   6001:                 if ($srch->{'srchin'} eq 'dom') {
1.162     raeburn  6002:                     if ($srch->{'srchtype'} eq 'exact') {
                   6003:                         my $uhome=&Apache::lonnet::homeserver($srch->{'srchterm'},$srch->{'srchdomain'});
                   6004:                         if ($uhome eq 'no_host') {
1.179     raeburn  6005:                             ($currstate,$response,$forcenewuser) =
1.221     raeburn  6006:                                 &build_search_response($context,$srch,%srch_results);
1.162     raeburn  6007:                         } else {
1.179     raeburn  6008:                             $currstate = 'modify';
1.310     raeburn  6009:                             my $uname = $srch->{'srchterm'};
                   6010:                             my $udom = $srch->{'srchdomain'};
                   6011:                             $srch_results{$uname.':'.$udom} =
                   6012:                                 { &Apache::lonnet::get('environment',
                   6013:                                                        ['firstname',
                   6014:                                                         'lastname',
                   6015:                                                         'permanentemail'],
                   6016:                                                          $udom,$uname)
                   6017:                                 };
1.162     raeburn  6018:                         }
                   6019:                     } else {
                   6020:                         %srch_results = &Apache::lonnet::usersearch($srch);
1.179     raeburn  6021:                         ($currstate,$response,$forcenewuser) =
1.221     raeburn  6022:                             &build_search_response($context,$srch,%srch_results);
1.160     raeburn  6023:                     }
                   6024:                 } else {
1.167     albertel 6025:                     my $courseusers = &get_courseusers();
1.162     raeburn  6026:                     if ($srch->{'srchtype'} eq 'exact') {
1.167     albertel 6027:                         if (exists($courseusers->{$srch->{'srchterm'}.':'.$srch->{'srchdomain'}})) {
1.179     raeburn  6028:                             $currstate = 'modify';
1.162     raeburn  6029:                         } else {
1.179     raeburn  6030:                             ($currstate,$response,$forcenewuser) =
1.221     raeburn  6031:                                 &build_search_response($context,$srch,%srch_results);
1.162     raeburn  6032:                         }
1.160     raeburn  6033:                     } else {
1.167     albertel 6034:                         foreach my $user (keys(%$courseusers)) {
1.162     raeburn  6035:                             my ($cuname,$cudomain) = split(/:/,$user);
                   6036:                             if ($cudomain eq $srch->{'srchdomain'}) {
1.177     raeburn  6037:                                 my $matched = 0;
                   6038:                                 if ($srch->{'srchtype'} eq 'begins') {
                   6039:                                     if ($cuname =~ /^\Q$srch->{'srchterm'}\E/i) {
                   6040:                                         $matched = 1;
                   6041:                                     }
                   6042:                                 } else {
                   6043:                                     if ($cuname =~ /\Q$srch->{'srchterm'}\E/i) {
                   6044:                                         $matched = 1;
                   6045:                                     }
                   6046:                                 }
                   6047:                                 if ($matched) {
1.167     albertel 6048:                                     $srch_results{$user} = 
                   6049: 					{&Apache::lonnet::get('environment',
                   6050: 							     ['firstname',
                   6051: 							      'lastname',
1.194     albertel 6052: 							      'permanentemail'],
                   6053: 							      $cudomain,$cuname)};
1.162     raeburn  6054:                                 }
                   6055:                             }
                   6056:                         }
1.179     raeburn  6057:                         ($currstate,$response,$forcenewuser) =
1.221     raeburn  6058:                             &build_search_response($context,$srch,%srch_results);
1.160     raeburn  6059:                     }
                   6060:                 }
                   6061:             }
                   6062:         } elsif ($srch->{'srchin'} eq 'alc') {
1.179     raeburn  6063:             $currstate = 'query';
1.160     raeburn  6064:         } elsif ($srch->{'srchin'} eq 'instd') {
1.181     raeburn  6065:             ($dirsrchres,%srch_results) = &Apache::lonnet::inst_directory_query($srch);
                   6066:             if ($dirsrchres eq 'ok') {
                   6067:                 ($currstate,$response,$forcenewuser) = 
1.221     raeburn  6068:                     &build_search_response($context,$srch,%srch_results);
1.181     raeburn  6069:             } else {
                   6070:                 my $showdom = &display_domain_info($srch->{'srchdomain'});
                   6071:                 $response = '<span class="LC_warning">'.
                   6072:                     &mt('Institutional directory search is not available in domain: [_1]',$showdom).
                   6073:                     '</span><br />'.
                   6074:                     &mt('You may want to search in the LON-CAPA domain instead of the institutional directory.').
                   6075:                     '<br /><br />'; 
                   6076:             }
1.160     raeburn  6077:         }
                   6078:     } else {
                   6079:         if ($srch->{'srchin'} eq 'dom') {
                   6080:             %srch_results = &Apache::lonnet::usersearch($srch);
1.179     raeburn  6081:             ($currstate,$response,$forcenewuser) = 
1.221     raeburn  6082:                 &build_search_response($context,$srch,%srch_results); 
1.160     raeburn  6083:         } elsif ($srch->{'srchin'} eq 'crs') {
1.167     albertel 6084:             my $courseusers = &get_courseusers(); 
                   6085:             foreach my $user (keys(%$courseusers)) {
1.160     raeburn  6086:                 my ($uname,$udom) = split(/:/,$user);
                   6087:                 my %names = &Apache::loncommon::getnames($uname,$udom);
                   6088:                 my %emails = &Apache::loncommon::getemails($uname,$udom);
                   6089:                 if ($srch->{'srchby'} eq 'lastname') {
                   6090:                     if ((($srch->{'srchtype'} eq 'exact') && 
                   6091:                          ($names{'lastname'} eq $srch->{'srchterm'})) || 
1.177     raeburn  6092:                         (($srch->{'srchtype'} eq 'begins') &&
                   6093:                          ($names{'lastname'} =~ /^\Q$srch->{'srchterm'}\E/i)) ||
1.160     raeburn  6094:                         (($srch->{'srchtype'} eq 'contains') &&
                   6095:                          ($names{'lastname'} =~ /\Q$srch->{'srchterm'}\E/i))) {
                   6096:                         $srch_results{$user} = {firstname => $names{'firstname'},
                   6097:                                             lastname => $names{'lastname'},
                   6098:                                             permanentemail => $emails{'permanentemail'},
                   6099:                                            };
                   6100:                     }
                   6101:                 } elsif ($srch->{'srchby'} eq 'lastfirst') {
                   6102:                     my ($srchlast,$srchfirst) = split(/,/,$srch->{'srchterm'});
1.177     raeburn  6103:                     $srchlast =~ s/\s+$//;
                   6104:                     $srchfirst =~ s/^\s+//;
1.160     raeburn  6105:                     if ($srch->{'srchtype'} eq 'exact') {
                   6106:                         if (($names{'lastname'} eq $srchlast) &&
                   6107:                             ($names{'firstname'} eq $srchfirst)) {
                   6108:                             $srch_results{$user} = {firstname => $names{'firstname'},
                   6109:                                                 lastname => $names{'lastname'},
                   6110:                                                 permanentemail => $emails{'permanentemail'},
                   6111: 
                   6112:                                            };
                   6113:                         }
1.177     raeburn  6114:                     } elsif ($srch->{'srchtype'} eq 'begins') {
                   6115:                         if (($names{'lastname'} =~ /^\Q$srchlast\E/i) &&
                   6116:                             ($names{'firstname'} =~ /^\Q$srchfirst\E/i)) {
                   6117:                             $srch_results{$user} = {firstname => $names{'firstname'},
                   6118:                                                 lastname => $names{'lastname'},
                   6119:                                                 permanentemail => $emails{'permanentemail'},
                   6120:                                                };
                   6121:                         }
                   6122:                     } else {
1.160     raeburn  6123:                         if (($names{'lastname'} =~ /\Q$srchlast\E/i) && 
                   6124:                             ($names{'firstname'} =~ /\Q$srchfirst\E/i)) {
                   6125:                             $srch_results{$user} = {firstname => $names{'firstname'},
                   6126:                                                 lastname => $names{'lastname'},
                   6127:                                                 permanentemail => $emails{'permanentemail'},
                   6128:                                                };
                   6129:                         }
                   6130:                     }
                   6131:                 }
                   6132:             }
1.179     raeburn  6133:             ($currstate,$response,$forcenewuser) = 
1.221     raeburn  6134:                 &build_search_response($context,$srch,%srch_results); 
1.160     raeburn  6135:         } elsif ($srch->{'srchin'} eq 'alc') {
1.179     raeburn  6136:             $currstate = 'query';
1.160     raeburn  6137:         } elsif ($srch->{'srchin'} eq 'instd') {
1.181     raeburn  6138:             ($dirsrchres,%srch_results) = &Apache::lonnet::inst_directory_query($srch); 
                   6139:             if ($dirsrchres eq 'ok') {
                   6140:                 ($currstate,$response,$forcenewuser) = 
1.221     raeburn  6141:                     &build_search_response($context,$srch,%srch_results);
1.181     raeburn  6142:             } else {
                   6143:                 my $showdom = &display_domain_info($srch->{'srchdomain'});                $response = '<span class="LC_warning">'.
                   6144:                     &mt('Institutional directory search is not available in domain: [_1]',$showdom).
                   6145:                     '</span><br />'.
                   6146:                     &mt('You may want to search in the LON-CAPA domain instead of the institutional directory.').
                   6147:                     '<br /><br />';
                   6148:             }
1.160     raeburn  6149:         }
                   6150:     }
1.179     raeburn  6151:     return ($currstate,$response,$forcenewuser,\%srch_results);
1.160     raeburn  6152: }
                   6153: 
                   6154: sub directorysrch_check {
                   6155:     my ($srch) = @_;
                   6156:     my $can_search = 0;
                   6157:     my $response;
                   6158:     my %dom_inst_srch = &Apache::lonnet::get_dom('configuration',
                   6159:                                              ['directorysrch'],$srch->{'srchdomain'});
1.180     raeburn  6160:     my $showdom = &display_domain_info($srch->{'srchdomain'});
1.160     raeburn  6161:     if (ref($dom_inst_srch{'directorysrch'}) eq 'HASH') {
                   6162:         if (!$dom_inst_srch{'directorysrch'}{'available'}) {
1.180     raeburn  6163:             return &mt('Institutional directory search is not available in domain: [_1]',$showdom); 
1.160     raeburn  6164:         }
                   6165:         if ($dom_inst_srch{'directorysrch'}{'localonly'}) {
                   6166:             if ($env{'request.role.domain'} ne $srch->{'srchdomain'}) {
1.180     raeburn  6167:                 return &mt('Institutional directory search in domain: [_1] is only allowed for users with a current role in the domain.',$showdom); 
1.160     raeburn  6168:             }
                   6169:             my @usertypes = split(/:/,$env{'environment.inststatus'});
                   6170:             if (!@usertypes) {
                   6171:                 push(@usertypes,'default');
                   6172:             }
                   6173:             if (ref($dom_inst_srch{'directorysrch'}{'cansearch'}) eq 'ARRAY') {
                   6174:                 foreach my $type (@usertypes) {
                   6175:                     if (grep(/^\Q$type\E$/,@{$dom_inst_srch{'directorysrch'}{'cansearch'}})) {
                   6176:                         $can_search = 1;
                   6177:                         last;
                   6178:                     }
                   6179:                 }
                   6180:             }
                   6181:             if (!$can_search) {
                   6182:                 my ($insttypes,$order) = &Apache::lonnet::retrieve_inst_usertypes($srch->{'srchdomain'});
                   6183:                 my @longtypes; 
                   6184:                 foreach my $item (@usertypes) {
1.229     raeburn  6185:                     if (defined($insttypes->{$item})) { 
                   6186:                         push (@longtypes,$insttypes->{$item});
                   6187:                     } elsif ($item eq 'default') {
                   6188:                         push (@longtypes,&mt('other')); 
                   6189:                     }
1.160     raeburn  6190:                 }
                   6191:                 my $insttype_str = join(', ',@longtypes); 
1.180     raeburn  6192:                 return &mt('Institutional directory search in domain: [_1] is not available to your user type: ',$showdom).$insttype_str;
1.229     raeburn  6193:             }
1.160     raeburn  6194:         } else {
                   6195:             $can_search = 1;
                   6196:         }
                   6197:     } else {
1.180     raeburn  6198:         return &mt('Institutional directory search has not been configured for domain: [_1]',$showdom);
1.160     raeburn  6199:     }
                   6200:     my %longtext = &Apache::lonlocal::texthash (
1.167     albertel 6201:                        uname     => 'username',
1.160     raeburn  6202:                        lastfirst => 'last name, first name',
1.167     albertel 6203:                        lastname  => 'last name',
1.172     raeburn  6204:                        contains  => 'contains',
1.178     raeburn  6205:                        exact     => 'as exact match to',
                   6206:                        begins    => 'begins with',
1.160     raeburn  6207:                    );
                   6208:     if ($can_search) {
                   6209:         if (ref($dom_inst_srch{'directorysrch'}{'searchby'}) eq 'ARRAY') {
                   6210:             if (!grep(/^\Q$srch->{'srchby'}\E$/,@{$dom_inst_srch{'directorysrch'}{'searchby'}})) {
1.180     raeburn  6211:                 return &mt('Institutional directory search in domain: [_1] is not available for searching by "[_2]"',$showdom,$longtext{$srch->{'srchby'}});
1.160     raeburn  6212:             }
                   6213:         } else {
1.180     raeburn  6214:             return &mt('Institutional directory search in domain: [_1] is not available.', $showdom);
1.160     raeburn  6215:         }
                   6216:     }
                   6217:     if ($can_search) {
1.178     raeburn  6218:         if (ref($dom_inst_srch{'directorysrch'}{'searchtypes'}) eq 'ARRAY') {
                   6219:             if (grep(/^\Q$srch->{'srchtype'}\E/,@{$dom_inst_srch{'directorysrch'}{'searchtypes'}})) {
                   6220:                 return 'ok';
                   6221:             } else {
1.180     raeburn  6222:                 return &mt('Institutional directory search in domain [_1] is not available for the requested search type: "[_2]"',$showdom,$longtext{$srch->{'srchtype'}});
1.178     raeburn  6223:             }
                   6224:         } else {
                   6225:             if ((($dom_inst_srch{'directorysrch'}{'searchtypes'} eq 'specify') &&
                   6226:                  ($srch->{'srchtype'} eq 'exact' || $srch->{'srchtype'} eq 'contains')) ||
                   6227:                 ($dom_inst_srch{'directorysrch'}{'searchtypes'} eq $srch->{'srchtype'})) {
                   6228:                 return 'ok';
                   6229:             } else {
1.180     raeburn  6230:                 return &mt('Institutional directory search in domain [_1] is not available for the requested search type: "[_2]"',$showdom,$longtext{$srch->{'srchtype'}});
1.178     raeburn  6231:             }
1.160     raeburn  6232:         }
                   6233:     }
                   6234: }
                   6235: 
                   6236: sub get_courseusers {
                   6237:     my %advhash;
1.167     albertel 6238:     my $classlist = &Apache::loncoursedata::get_classlist();
1.160     raeburn  6239:     my %coursepersonnel=&Apache::lonnet::get_course_adv_roles();
                   6240:     foreach my $role (sort(keys(%coursepersonnel))) {
                   6241:         foreach my $user (split(/\,/,$coursepersonnel{$role})) {
1.167     albertel 6242: 	    if (!exists($classlist->{$user})) {
                   6243: 		$classlist->{$user} = [];
                   6244: 	    }
1.160     raeburn  6245:         }
                   6246:     }
1.167     albertel 6247:     return $classlist;
1.160     raeburn  6248: }
                   6249: 
                   6250: sub build_search_response {
1.221     raeburn  6251:     my ($context,$srch,%srch_results) = @_;
1.179     raeburn  6252:     my ($currstate,$response,$forcenewuser);
1.160     raeburn  6253:     my %names = (
1.330     bisitz   6254:           'uname'     => 'username',
                   6255:           'lastname'  => 'last name',
1.160     raeburn  6256:           'lastfirst' => 'last name, first name',
1.330     bisitz   6257:           'crs'       => 'this course',
                   6258:           'dom'       => 'LON-CAPA domain',
                   6259:           'instd'     => 'the institutional directory for domain',
1.160     raeburn  6260:     );
                   6261: 
                   6262:     my %single = (
1.180     raeburn  6263:                    begins   => 'A match',
1.160     raeburn  6264:                    contains => 'A match',
1.180     raeburn  6265:                    exact    => 'An exact match',
1.160     raeburn  6266:                  );
                   6267:     my %nomatch = (
1.180     raeburn  6268:                    begins   => 'No match',
1.160     raeburn  6269:                    contains => 'No match',
1.180     raeburn  6270:                    exact    => 'No exact match',
1.160     raeburn  6271:                   );
                   6272:     if (keys(%srch_results) > 1) {
1.179     raeburn  6273:         $currstate = 'select';
1.160     raeburn  6274:     } else {
                   6275:         if (keys(%srch_results) == 1) {
1.179     raeburn  6276:             $currstate = 'modify';
1.180     raeburn  6277:             $response = &mt("$single{$srch->{'srchtype'}} was found for the $names{$srch->{'srchby'}} ([_1]) in $names{$srch->{'srchin'}}.",$srch->{'srchterm'});
                   6278:             if ($srch->{'srchin'} eq 'dom' || $srch->{'srchin'} eq 'instd') {
1.330     bisitz   6279:                 $response .= ': '.&display_domain_info($srch->{'srchdomain'});
1.180     raeburn  6280:             }
1.330     bisitz   6281:         } else { # Search has nothing found. Prepare message to user.
                   6282:             $response = '<span class="LC_warning">';
1.180     raeburn  6283:             if ($srch->{'srchin'} eq 'dom' || $srch->{'srchin'} eq 'instd') {
1.330     bisitz   6284:                 $response .= &mt("$nomatch{$srch->{'srchtype'}} found for the $names{$srch->{'srchby'}} [_1] in $names{$srch->{'srchin'}}: [_2]",
                   6285:                                  '<b>'.$srch->{'srchterm'}.'</b>',
                   6286:                                  &display_domain_info($srch->{'srchdomain'}));
                   6287:             } else {
                   6288:                 $response .= &mt("$nomatch{$srch->{'srchtype'}} found for the $names{$srch->{'srchby'}} [_1] in $names{$srch->{'srchin'}}.",
                   6289:                                  '<b>'.$srch->{'srchterm'}.'</b>');
1.180     raeburn  6290:             }
                   6291:             $response .= '</span>';
1.330     bisitz   6292: 
1.160     raeburn  6293:             if ($srch->{'srchin'} ne 'alc') {
                   6294:                 $forcenewuser = 1;
                   6295:                 my $cansrchinst = 0; 
                   6296:                 if ($srch->{'srchdomain'}) {
                   6297:                     my %domconfig = &Apache::lonnet::get_dom('configuration',['directorysrch'],$srch->{'srchdomain'});
                   6298:                     if (ref($domconfig{'directorysrch'}) eq 'HASH') {
                   6299:                         if ($domconfig{'directorysrch'}{'available'}) {
                   6300:                             $cansrchinst = 1;
                   6301:                         } 
                   6302:                     }
                   6303:                 }
1.180     raeburn  6304:                 if ((($srch->{'srchby'} eq 'lastfirst') || 
                   6305:                      ($srch->{'srchby'} eq 'lastname')) &&
                   6306:                     ($srch->{'srchin'} eq 'dom')) {
                   6307:                     if ($cansrchinst) {
                   6308:                         $response .= '<br />'.&mt('You may want to broaden your search to a search of the institutional directory for the domain.');
1.160     raeburn  6309:                     }
                   6310:                 }
1.180     raeburn  6311:                 if ($srch->{'srchin'} eq 'crs') {
                   6312:                     $response .= '<br />'.&mt('You may want to broaden your search to the selected LON-CAPA domain.');
                   6313:                 }
                   6314:             }
1.305     raeburn  6315:             my $createdom = $env{'request.role.domain'};
                   6316:             if ($context eq 'requestcrs') {
                   6317:                 if ($env{'form.coursedom'} ne '') {
                   6318:                     $createdom = $env{'form.coursedom'};
                   6319:                 }
                   6320:             }
                   6321:             if (!($srch->{'srchby'} eq 'uname' && $srch->{'srchin'} eq 'dom' && $srch->{'srchtype'} eq 'exact' && $srch->{'srchdomain'} eq $createdom)) {
1.221     raeburn  6322:                 my $cancreate =
1.305     raeburn  6323:                     &Apache::lonuserutils::can_create_user($createdom,$context);
                   6324:                 my $targetdom = '<span class="LC_cusr_emph">'.$createdom.'</span>';
1.221     raeburn  6325:                 if ($cancreate) {
1.305     raeburn  6326:                     my $showdom = &display_domain_info($createdom); 
1.266     bisitz   6327:                     $response .= '<br /><br />'
                   6328:                                 .'<b>'.&mt('To add a new user:').'</b>'
1.305     raeburn  6329:                                 .'<br />';
                   6330:                     if ($context eq 'requestcrs') {
                   6331:                         $response .= &mt("(You can only define new users in the new course's domain - [_1])",$targetdom);
                   6332:                     } else {
                   6333:                         $response .= &mt("(You can only create new users in your current role's domain - [_1])",$targetdom);
                   6334:                     }
                   6335:                     $response .='<ul><li>'
1.266     bisitz   6336:                                 .&mt("Set 'Domain/institution to search' to: [_1]",'<span class="LC_cusr_emph">'.$showdom.'</span>')
                   6337:                                 .'</li><li>'
                   6338:                                 .&mt("Set 'Search criteria' to: [_1]username is ..... in selected LON-CAPA domain[_2]",'<span class="LC_cusr_emph">','</span>')
                   6339:                                 .'</li><li>'
                   6340:                                 .&mt('Provide the proposed username')
                   6341:                                 .'</li><li>'
                   6342:                                 .&mt("Click 'Search'")
                   6343:                                 .'</li></ul><br />';
1.221     raeburn  6344:                 } else {
                   6345:                     my $helplink = ' href="javascript:helpMenu('."'display'".')"';
1.305     raeburn  6346:                     $response .= '<br /><br />';
                   6347:                     if ($context eq 'requestcrs') {
1.314     raeburn  6348:                         $response .= &mt("You are not authorized to define new users in the new course's domain - [_1].",$targetdom);
1.305     raeburn  6349:                     } else {
                   6350:                         $response .= &mt("You are not authorized to create new users in your current role's domain - [_1].",$targetdom);
                   6351:                     }
                   6352:                     $response .= '<br />'
                   6353:                                  .&mt('Please contact the [_1]helpdesk[_2] if you need to create a new user.'
1.266     bisitz   6354:                                     ,' <a'.$helplink.'>'
                   6355:                                     ,'</a>')
1.305     raeburn  6356:                                  .'<br /><br />';
1.221     raeburn  6357:                 }
1.160     raeburn  6358:             }
                   6359:         }
                   6360:     }
1.179     raeburn  6361:     return ($currstate,$response,$forcenewuser);
1.160     raeburn  6362: }
                   6363: 
1.180     raeburn  6364: sub display_domain_info {
                   6365:     my ($dom) = @_;
                   6366:     my $output = $dom;
                   6367:     if ($dom ne '') { 
                   6368:         my $domdesc = &Apache::lonnet::domain($dom,'description');
                   6369:         if ($domdesc ne '') {
                   6370:             $output .= ' <span class="LC_cusr_emph">('.$domdesc.')</span>';
                   6371:         }
                   6372:     }
                   6373:     return $output;
                   6374: }
                   6375: 
1.160     raeburn  6376: sub crumb_utilities {
                   6377:     my %elements = (
                   6378:        crtuser => {
                   6379:            srchterm => 'text',
1.172     raeburn  6380:            srchin => 'selectbox',
1.160     raeburn  6381:            srchby => 'selectbox',
                   6382:            srchtype => 'selectbox',
                   6383:            srchdomain => 'selectbox',
                   6384:        },
1.207     raeburn  6385:        crtusername => {
                   6386:            srchterm => 'text',
                   6387:            srchdomain => 'selectbox',
                   6388:        },
1.160     raeburn  6389:        docustom => {
                   6390:            rolename => 'selectbox',
                   6391:            newrolename => 'textbox',
                   6392:        },
1.179     raeburn  6393:        studentform => {
                   6394:            srchterm => 'text',
                   6395:            srchin => 'selectbox',
                   6396:            srchby => 'selectbox',
                   6397:            srchtype => 'selectbox',
                   6398:            srchdomain => 'selectbox',
                   6399:        },
1.160     raeburn  6400:     );
                   6401: 
                   6402:     my $jsback .= qq|
                   6403: function backPage(formname,prevphase,prevstate) {
1.211     raeburn  6404:     if (typeof prevphase == 'undefined') {
                   6405:         formname.phase.value = '';
                   6406:     }
                   6407:     else {  
                   6408:         formname.phase.value = prevphase;
                   6409:     }
                   6410:     if (typeof prevstate == 'undefined') {
                   6411:         formname.currstate.value = '';
                   6412:     }
                   6413:     else {
                   6414:         formname.currstate.value = prevstate;
                   6415:     }
1.160     raeburn  6416:     formname.submit();
                   6417: }
                   6418: |;
                   6419:     return ($jsback,\%elements);
                   6420: }
                   6421: 
1.26      matthew  6422: sub course_level_table {
1.89      raeburn  6423:     my (%inccourses) = @_;
1.26      matthew  6424:     my $table = '';
1.62      www      6425: # Custom Roles?
                   6426: 
1.190     raeburn  6427:     my %customroles=&Apache::lonuserutils::my_custom_roles();
1.89      raeburn  6428:     my %lt=&Apache::lonlocal::texthash(
                   6429:             'exs'  => "Existing sections",
                   6430:             'new'  => "Define new section",
                   6431:             'ssd'  => "Set Start Date",
                   6432:             'sed'  => "Set End Date",
1.131     raeburn  6433:             'crl'  => "Course Level",
1.89      raeburn  6434:             'act'  => "Activate",
                   6435:             'rol'  => "Role",
                   6436:             'ext'  => "Extent",
1.113     raeburn  6437:             'grs'  => "Section",
1.89      raeburn  6438:             'sta'  => "Start",
                   6439:             'end'  => "End"
                   6440:     );
1.62      www      6441: 
1.329     raeburn  6442:     foreach my $protectedcourse (sort(keys(%inccourses))) {
1.135     raeburn  6443: 	my $thiscourse=$protectedcourse;
1.26      matthew  6444: 	$thiscourse=~s:_:/:g;
                   6445: 	my %coursedata=&Apache::lonnet::coursedescription($thiscourse);
1.365     raeburn  6446:         my $isowner = &Apache::lonuserutils::is_courseowner($protectedcourse,$coursedata{'internal.courseowner'});
1.26      matthew  6447: 	my $area=$coursedata{'description'};
1.321     raeburn  6448:         my $crstype=$coursedata{'type'};
1.135     raeburn  6449: 	if (!defined($area)) { $area=&mt('Unavailable course').': '.$protectedcourse; }
1.89      raeburn  6450: 	my ($domain,$cnum)=split(/\//,$thiscourse);
1.115     albertel 6451:         my %sections_count;
1.101     albertel 6452:         if (defined($env{'request.course.id'})) {
                   6453:             if ($env{'request.course.id'} eq $domain.'_'.$cnum) {
1.115     albertel 6454:                 %sections_count = 
                   6455: 		    &Apache::loncommon::get_sections($domain,$cnum);
1.92      raeburn  6456:             }
                   6457:         }
1.321     raeburn  6458:         my @roles = &Apache::lonuserutils::roles_by_context('course','',$crstype);
1.213     raeburn  6459: 	foreach my $role (@roles) {
1.321     raeburn  6460:             my $plrole=&Apache::lonnet::plaintext($role,$crstype);
1.329     raeburn  6461: 	    if ((&Apache::lonnet::allowed('c'.$role,$thiscourse)) ||
                   6462:                 ((($role eq 'cc') || ($role eq 'co')) && ($isowner))) {
1.221     raeburn  6463:                 $table .= &course_level_row($protectedcourse,$role,$area,$domain,
1.329     raeburn  6464:                                             $plrole,\%sections_count,\%lt);
1.221     raeburn  6465:             } elsif ($env{'request.course.sec'} ne '') {
                   6466:                 if (&Apache::lonnet::allowed('c'.$role,$thiscourse.'/'.
                   6467:                                              $env{'request.course.sec'})) {
                   6468:                     $table .= &course_level_row($protectedcourse,$role,$area,$domain,
                   6469:                                                 $plrole,\%sections_count,\%lt);
1.26      matthew  6470:                 }
                   6471:             }
                   6472:         }
1.221     raeburn  6473:         if (&Apache::lonnet::allowed('ccr',$thiscourse)) {
1.324     raeburn  6474:             foreach my $cust (sort(keys(%customroles))) {
                   6475:                 next if ($crstype eq 'Community' && $customroles{$cust} =~ /bre\&S/);
1.221     raeburn  6476:                 my $role = 'cr_cr_'.$env{'user.domain'}.'_'.$env{'user.name'}.'_'.$cust;
                   6477:                 $table .= &course_level_row($protectedcourse,$role,$area,$domain,
                   6478:                                             $cust,\%sections_count,\%lt);
                   6479:             }
1.62      www      6480: 	}
1.26      matthew  6481:     }
                   6482:     return '' if ($table eq ''); # return nothing if there is nothing 
                   6483:                                  # in the table
1.188     raeburn  6484:     my $result;
                   6485:     if (!$env{'request.course.id'}) {
                   6486:         $result = '<h4>'.$lt{'crl'}.'</h4>'."\n";
                   6487:     }
                   6488:     $result .= 
1.136     raeburn  6489: &Apache::loncommon::start_data_table().
                   6490: &Apache::loncommon::start_data_table_header_row().
                   6491: '<th>'.$lt{'act'}.'</th><th>'.$lt{'rol'}.'</th><th>'.$lt{'ext'}.'</th>
                   6492: <th>'.$lt{'grs'}.'</th><th>'.$lt{'sta'}.'</th><th>'.$lt{'end'}.'</th>'.
                   6493: &Apache::loncommon::end_data_table_header_row().
                   6494: $table.
                   6495: &Apache::loncommon::end_data_table();
1.26      matthew  6496:     return $result;
                   6497: }
1.88      raeburn  6498: 
1.221     raeburn  6499: sub course_level_row {
                   6500:     my ($protectedcourse,$role,$area,$domain,$plrole,$sections_count,$lt) = @_;
1.222     raeburn  6501:     my $row = &Apache::loncommon::start_data_table_row().
                   6502:               ' <td><input type="checkbox" name="act_'.
                   6503:               $protectedcourse.'_'.$role.'" /></td>'."\n".
                   6504:               ' <td>'.$plrole.'</td>'."\n".
                   6505:               ' <td>'.$area.'<br />Domain: '.$domain.'</td>'."\n";
1.322     raeburn  6506:     if (($role eq 'cc') || ($role eq 'co')) {
1.222     raeburn  6507:         $row .= '<td>&nbsp;</td>';
1.221     raeburn  6508:     } elsif ($env{'request.course.sec'} ne '') {
1.222     raeburn  6509:         $row .= ' <td><input type="hidden" value="'.
                   6510:                 $env{'request.course.sec'}.'" '.
                   6511:                 'name="sec_'.$protectedcourse.'_'.$role.'" />'.
                   6512:                 $env{'request.course.sec'}.'</td>';
1.221     raeburn  6513:     } else {
                   6514:         if (ref($sections_count) eq 'HASH') {
                   6515:             my $currsec = 
                   6516:                 &Apache::lonuserutils::course_sections($sections_count,
                   6517:                                                        $protectedcourse.'_'.$role);
1.222     raeburn  6518:             $row .= '<td><table class="LC_createuser">'."\n".
                   6519:                     '<tr class="LC_section_row">'."\n".
                   6520:                     ' <td valign="top">'.$lt->{'exs'}.'<br />'.
                   6521:                        $currsec.'</td>'."\n".
                   6522:                      ' <td>&nbsp;&nbsp;</td>'."\n".
                   6523:                      ' <td valign="top">&nbsp;'.$lt->{'new'}.'<br />'.
1.221     raeburn  6524:                      '<input type="text" name="newsec_'.$protectedcourse.'_'.$role.
                   6525:                      '" value="" />'.
                   6526:                      '<input type="hidden" '.
                   6527:                      'name="sec_'.$protectedcourse.'_'.$role.'" /></td>'."\n".
1.222     raeburn  6528:                      '</tr></table></td>'."\n";
1.221     raeburn  6529:         } else {
1.222     raeburn  6530:             $row .= '<td><input type="text" size="10" '.
                   6531:                       'name="sec_'.$protectedcourse.'_'.$role.'" /></td>'."\n";
1.221     raeburn  6532:         }
                   6533:     }
1.222     raeburn  6534:     $row .= <<ENDTIMEENTRY;
                   6535: <td><input type="hidden" name="start_$protectedcourse\_$role" value="" />
1.221     raeburn  6536: <a href=
                   6537: "javascript:pjump('date_start','Start Date $plrole',document.cu.start_$protectedcourse\_$role.value,'start_$protectedcourse\_$role','cu.pres','dateset')">$lt->{'ssd'}</a></td>
1.222     raeburn  6538: <td><input type="hidden" name="end_$protectedcourse\_$role" value="" />
1.221     raeburn  6539: <a href=
                   6540: "javascript:pjump('date_end','End Date $plrole',document.cu.end_$protectedcourse\_$role.value,'end_$protectedcourse\_$role','cu.pres','dateset')">$lt->{'sed'}</a></td>
                   6541: ENDTIMEENTRY
1.222     raeburn  6542:     $row .= &Apache::loncommon::end_data_table_row();
                   6543:     return $row;
1.221     raeburn  6544: }
                   6545: 
1.88      raeburn  6546: sub course_level_dc {
                   6547:     my ($dcdom) = @_;
1.190     raeburn  6548:     my %customroles=&Apache::lonuserutils::my_custom_roles();
1.213     raeburn  6549:     my @roles = &Apache::lonuserutils::roles_by_context('course');
1.88      raeburn  6550:     my $hiddenitems = '<input type="hidden" name="dcdomain" value="'.$dcdom.'" />'.
                   6551:                       '<input type="hidden" name="origdom" value="'.$dcdom.'" />'.
1.133     raeburn  6552:                       '<input type="hidden" name="dccourse" value="" />';
1.355     www      6553:     my $courseform=&Apache::loncommon::selectcourse_link
1.356     raeburn  6554:             ('cu','dccourse','dcdomain','coursedesc',undef,undef,'Select','crstype');
1.323     raeburn  6555:     my $cb_jscript = &Apache::loncommon::coursebrowser_javascript($dcdom,'currsec','cu','role','Course/Community Browser');
1.88      raeburn  6556:     my %lt=&Apache::lonlocal::texthash(
                   6557:                     'rol'  => "Role",
1.113     raeburn  6558:                     'grs'  => "Section",
1.88      raeburn  6559:                     'exs'  => "Existing sections",
                   6560:                     'new'  => "Define new section", 
                   6561:                     'sta'  => "Start",
                   6562:                     'end'  => "End",
                   6563:                     'ssd'  => "Set Start Date",
1.355     www      6564:                     'sed'  => "Set End Date",
                   6565:                     'scc'  => "Course/Community"
1.88      raeburn  6566:                   );
1.323     raeburn  6567:     my $header = '<h4>'.&mt('Course/Community Level').'</h4>'.
1.136     raeburn  6568:                  &Apache::loncommon::start_data_table().
                   6569:                  &Apache::loncommon::start_data_table_header_row().
1.355     www      6570:                  '<th>'.$lt{'scc'}.'</th><th>'.$lt{'rol'}.'</th><th>'.$lt{'grs'}.'</th><th>'.$lt{'sta'}.'</th><th>'.$lt{'end'}.'</th>'.
1.136     raeburn  6571:                  &Apache::loncommon::end_data_table_header_row();
1.143     raeburn  6572:     my $otheritems = &Apache::loncommon::start_data_table_row()."\n".
1.356     raeburn  6573:                      '<td><br /><span class="LC_nobreak"><input type="text" name="coursedesc" value="" onfocus="this.blur();opencrsbrowser('."'cu','dccourse','dcdomain','coursedesc','','','','crstype'".')" />'.
                   6574:                      $courseform.('&nbsp;' x4).'</span></td>'."\n".
1.323     raeburn  6575:                      '<td valign><br /><select name="role">'."\n";
1.213     raeburn  6576:     foreach my $role (@roles) {
1.135     raeburn  6577:         my $plrole=&Apache::lonnet::plaintext($role);
                   6578:         $otheritems .= '  <option value="'.$role.'">'.$plrole;
1.88      raeburn  6579:     }
                   6580:     if ( keys %customroles > 0) {
1.135     raeburn  6581:         foreach my $cust (sort keys %customroles) {
1.101     albertel 6582:             my $custrole='cr_cr_'.$env{'user.domain'}.
1.135     raeburn  6583:                     '_'.$env{'user.name'}.'_'.$cust;
                   6584:             $otheritems .= '  <option value="'.$custrole.'">'.$cust;
1.88      raeburn  6585:         }
                   6586:     }
                   6587:     $otheritems .= '</select></td><td>'.
                   6588:                      '<table border="0" cellspacing="0" cellpadding="0">'.
                   6589:                      '<tr><td valign="top"><b>'.$lt{'exs'}.'</b><br /><select name="currsec">'.
                   6590:                      ' <option value=""><--'.&mt('Pick course first').'</select></td>'.
                   6591:                      '<td>&nbsp;&nbsp;</td>'.
                   6592:                      '<td valign="top">&nbsp;<b>'.$lt{'new'}.'</b><br />'.
1.113     raeburn  6593:                      '<input type="text" name="newsec" value="" />'.
1.237     raeburn  6594:                      '<input type="hidden" name="section" value="" />'.
1.323     raeburn  6595:                      '<input type="hidden" name="groups" value="" />'.
                   6596:                      '<input type="hidden" name="crstype" value="" /></td>'.
1.88      raeburn  6597:                      '</tr></table></td>';
                   6598:     $otheritems .= <<ENDTIMEENTRY;
1.323     raeburn  6599: <td><br /><input type="hidden" name="start" value='' />
1.88      raeburn  6600: <a href=
                   6601: "javascript:pjump('date_start','Start Date',document.cu.start.value,'start','cu.pres','dateset')">$lt{'ssd'}</a></td>
1.323     raeburn  6602: <td><br /><input type="hidden" name="end" value='' />
1.88      raeburn  6603: <a href=
                   6604: "javascript:pjump('date_end','End Date',document.cu.end.value,'end','cu.pres','dateset')">$lt{'sed'}</a></td>
                   6605: ENDTIMEENTRY
1.136     raeburn  6606:     $otheritems .= &Apache::loncommon::end_data_table_row().
                   6607:                    &Apache::loncommon::end_data_table()."\n";
1.88      raeburn  6608:     return $cb_jscript.$header.$hiddenitems.$otheritems;
                   6609: }
                   6610: 
1.237     raeburn  6611: sub update_selfenroll_config {
1.241     raeburn  6612:     my ($r,$context,$permission) = @_;
1.237     raeburn  6613:     my ($row,$lt) = &get_selfenroll_titles();
1.241     raeburn  6614:     my %curr_groups = &Apache::longroup::coursegroups();
1.237     raeburn  6615:     my (%changes,%warning);
                   6616:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   6617:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.241     raeburn  6618:     my $curr_types;
1.237     raeburn  6619:     if (ref($row) eq 'ARRAY') {
                   6620:         foreach my $item (@{$row}) {
                   6621:             if ($item eq 'enroll_dates') {
                   6622:                 my (%currenrolldate,%newenrolldate);
                   6623:                 foreach my $type ('start','end') {
                   6624:                     $currenrolldate{$type} = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_'.$type.'_date'};
                   6625:                     $newenrolldate{$type} = &Apache::lonhtmlcommon::get_date_from_form('selfenroll_'.$type.'_date');
                   6626:                     if ($newenrolldate{$type} ne $currenrolldate{$type}) {
                   6627:                         $changes{'internal.selfenroll_'.$type.'_date'} = $newenrolldate{$type};
                   6628:                     }
                   6629:                 }
                   6630:             } elsif ($item eq 'access_dates') {
                   6631:                 my (%currdate,%newdate);
                   6632:                 foreach my $type ('start','end') {
                   6633:                     $currdate{$type} = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_'.$type.'_access'};
                   6634:                     $newdate{$type} = &Apache::lonhtmlcommon::get_date_from_form('selfenroll_'.$type.'_access');
                   6635:                     if ($newdate{$type} ne $currdate{$type}) {
                   6636:                         $changes{'internal.selfenroll_'.$type.'_access'} = $newdate{$type};
                   6637:                     }
                   6638:                 }
1.241     raeburn  6639:             } elsif ($item eq 'types') {
                   6640:                 $curr_types =
                   6641:                     $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_'.$item};
                   6642:                 if ($env{'form.selfenroll_all'}) {
                   6643:                     if ($curr_types ne '*') {
                   6644:                         $changes{'internal.selfenroll_types'} = '*';
                   6645:                     } else {
                   6646:                         next;
                   6647:                     }
                   6648:                 } else {
1.249     raeburn  6649:                     my %currdoms;
1.241     raeburn  6650:                     my @entries = split(/;/,$curr_types);
                   6651:                     my @deletedoms = &Apache::loncommon::get_env_multiple('form.selfenroll_delete');
1.249     raeburn  6652:                     my @activations = &Apache::loncommon::get_env_multiple('form.selfenroll_activate');
1.241     raeburn  6653:                     my $newnum = 0;
1.249     raeburn  6654:                     my @latesttypes;
                   6655:                     foreach my $num (@activations) {
                   6656:                         my @types = &Apache::loncommon::get_env_multiple('form.selfenroll_types_'.$num);
                   6657:                         if (@types > 0) {
1.241     raeburn  6658:                             @types = sort(@types);
                   6659:                             my $typestr = join(',',@types);
1.249     raeburn  6660:                             my $typedom = $env{'form.selfenroll_dom_'.$num};
                   6661:                             $latesttypes[$newnum] = $typedom.':'.$typestr;
                   6662:                             $currdoms{$typedom} = 1;
1.241     raeburn  6663:                             $newnum ++;
                   6664:                         }
                   6665:                     }
1.338     raeburn  6666:                     for (my $j=0; $j<$env{'form.selfenroll_types_total'}; $j++) {
                   6667:                         if ((!grep(/^$j$/,@deletedoms)) && (!grep(/^$j$/,@activations))) {
1.249     raeburn  6668:                             my @types = &Apache::loncommon::get_env_multiple('form.selfenroll_types_'.$j);
                   6669:                             if (@types > 0) {
                   6670:                                 @types = sort(@types);
                   6671:                                 my $typestr = join(',',@types);
                   6672:                                 my $typedom = $env{'form.selfenroll_dom_'.$j};
                   6673:                                 $latesttypes[$newnum] = $typedom.':'.$typestr;
                   6674:                                 $currdoms{$typedom} = 1;
                   6675:                                 $newnum ++;
                   6676:                             }
                   6677:                         }
                   6678:                     }
                   6679:                     if ($env{'form.selfenroll_newdom'} ne '') {
                   6680:                         my $typedom = $env{'form.selfenroll_newdom'};
                   6681:                         if ((!defined($currdoms{$typedom})) && 
                   6682:                             (&Apache::lonnet::domain($typedom) ne '')) {
                   6683:                             my $typestr;
                   6684:                             my ($othertitle,$usertypes,$types) = 
                   6685:                                 &Apache::loncommon::sorted_inst_types($typedom);
                   6686:                             my $othervalue = 'any';
                   6687:                             if ((ref($types) eq 'ARRAY') && (ref($usertypes) eq 'HASH')) {
                   6688:                                 if (@{$types} > 0) {
1.257     raeburn  6689:                                     my @esc_types = map { &escape($_); } @{$types};
1.249     raeburn  6690:                                     $othervalue = 'other';
1.258     raeburn  6691:                                     $typestr = join(',',(@esc_types,$othervalue));
1.249     raeburn  6692:                                 }
                   6693:                                 $typestr = $othervalue;
                   6694:                             } else {
                   6695:                                 $typestr = $othervalue;
                   6696:                             } 
                   6697:                             $latesttypes[$newnum] = $typedom.':'.$typestr;
                   6698:                             $newnum ++ ;
                   6699:                         }
                   6700:                     }
1.241     raeburn  6701:                     my $selfenroll_types = join(';',@latesttypes);
                   6702:                     if ($selfenroll_types ne $curr_types) {
                   6703:                         $changes{'internal.selfenroll_types'} = $selfenroll_types;
                   6704:                     }
                   6705:                 }
1.276     raeburn  6706:             } elsif ($item eq 'limit') {
                   6707:                 my $newlimit = $env{'form.selfenroll_limit'};
                   6708:                 my $newcap = $env{'form.selfenroll_cap'};
                   6709:                 $newcap =~s/\s+//g;
                   6710:                 my $currlimit =  $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_limit'};
                   6711:                 $currlimit = 'none' if ($currlimit eq '');
                   6712:                 my $currcap = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_cap'};
                   6713:                 if ($newlimit ne $currlimit) {
                   6714:                     if ($newlimit ne 'none') {
                   6715:                         if ($newcap =~ /^\d+$/) {
                   6716:                             if ($newcap ne $currcap) {
                   6717:                                 $changes{'internal.selfenroll_cap'} = $newcap;
                   6718:                             }
                   6719:                             $changes{'internal.selfenroll_limit'} = $newlimit;
                   6720:                         } else {
                   6721:                             $warning{$item} = &mt('Maximum enrollment setting unchanged.').'<br />'.&mt('The value provided was invalid - it must be a positive integer if enrollment is being limited.'); 
                   6722:                         }
                   6723:                     } elsif ($currcap ne '') {
                   6724:                         $changes{'internal.selfenroll_cap'} = '';
                   6725:                         $changes{'internal.selfenroll_limit'} = $newlimit; 
                   6726:                     }
                   6727:                 } elsif ($currlimit ne 'none') {
                   6728:                     if ($newcap =~ /^\d+$/) {
                   6729:                         if ($newcap ne $currcap) {
                   6730:                             $changes{'internal.selfenroll_cap'} = $newcap;
                   6731:                         }
                   6732:                     } else {
                   6733:                         $warning{$item} = &mt('Maximum enrollment setting unchanged.').'<br />'.&mt('The value provided was invalid - it must be a positive integer if enrollment is being limited.');
                   6734:                     }
                   6735:                 }
                   6736:             } elsif ($item eq 'approval') {
                   6737:                 my (@currnotified,@newnotified);
                   6738:                 my $currapproval = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_approval'};
                   6739:                 my $currnotifylist = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_notifylist'};
                   6740:                 if ($currnotifylist ne '') {
                   6741:                     @currnotified = split(/,/,$currnotifylist);
                   6742:                     @currnotified = sort(@currnotified);
                   6743:                 }
                   6744:                 my $newapproval = $env{'form.selfenroll_approval'};
                   6745:                 @newnotified = &Apache::loncommon::get_env_multiple('form.selfenroll_notify');
                   6746:                 @newnotified = sort(@newnotified);
                   6747:                 if ($newapproval ne $currapproval) {
                   6748:                     $changes{'internal.selfenroll_approval'} = $newapproval;
                   6749:                     if (!$newapproval) {
                   6750:                         if ($currnotifylist ne '') {
                   6751:                             $changes{'internal.selfenroll_notifylist'} = '';
                   6752:                         }
                   6753:                     } else {
                   6754:                         my @differences =  
1.295     raeburn  6755:                             &Apache::loncommon::compare_arrays(\@currnotified,\@newnotified);
1.276     raeburn  6756:                         if (@differences > 0) {
                   6757:                             if (@newnotified > 0) {
                   6758:                                 $changes{'internal.selfenroll_notifylist'} = join(',',@newnotified);
                   6759:                             } else {
                   6760:                                 $changes{'internal.selfenroll_notifylist'} = join(',',@newnotified);
                   6761:                             }
                   6762:                         }
                   6763:                     }
                   6764:                 } else {
1.295     raeburn  6765:                     my @differences = &Apache::loncommon::compare_arrays(\@currnotified,\@newnotified);
1.276     raeburn  6766:                     if (@differences > 0) {
                   6767:                         if (@newnotified > 0) {
                   6768:                             $changes{'internal.selfenroll_notifylist'} = join(',',@newnotified);
                   6769:                         } else {
                   6770:                             $changes{'internal.selfenroll_notifylist'} = '';
                   6771:                         }
                   6772:                     }
                   6773:                 }
1.237     raeburn  6774:             } else {
                   6775:                 my $curr_val = 
                   6776:                     $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_'.$item};
                   6777:                 my $newval = $env{'form.selfenroll_'.$item};
                   6778:                 if ($item eq 'section') {
                   6779:                     $newval = $env{'form.sections'};
1.241     raeburn  6780:                     if (defined($curr_groups{$newval})) {
1.237     raeburn  6781:                         $newval = $curr_val;
                   6782:                         $warning{$item} = &mt('Section for self-enrolled users unchanged as the proposed section is a group').'<br />'.&mt('Group names and section names must be distinct');
                   6783:                     } elsif ($newval eq 'all') {
                   6784:                         $newval = $curr_val;
1.274     bisitz   6785:                         $warning{$item} = &mt('Section for self-enrolled users unchanged, as "all" is a reserved section name.');
1.237     raeburn  6786:                     }
                   6787:                     if ($newval eq '') {
                   6788:                         $newval = 'none';
                   6789:                     }
                   6790:                 }
                   6791:                 if ($newval ne $curr_val) {
                   6792:                     $changes{'internal.selfenroll_'.$item} = $newval;
                   6793:                 }
1.241     raeburn  6794:             }
1.237     raeburn  6795:         }
                   6796:         if (keys(%warning) > 0) {
                   6797:             foreach my $item (@{$row}) {
                   6798:                 if (exists($warning{$item})) {
                   6799:                     $r->print($warning{$item}.'<br />');
                   6800:                 }
                   6801:             } 
                   6802:         }
                   6803:         if (keys(%changes) > 0) {
                   6804:             my $putresult = &Apache::lonnet::put('environment',\%changes,$cdom,$cnum);
                   6805:             if ($putresult eq 'ok') {
                   6806:                 if ((exists($changes{'internal.selfenroll_types'})) ||
                   6807:                     (exists($changes{'internal.selfenroll_start_date'}))  ||
                   6808:                     (exists($changes{'internal.selfenroll_end_date'}))) {
                   6809:                     my %crsinfo = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.',
                   6810:                                                                 $cnum,undef,undef,'Course');
                   6811:                     my $chome = &Apache::lonnet::homeserver($cnum,$cdom);
                   6812:                     if (ref($crsinfo{$env{'request.course.id'}}) eq 'HASH') {
                   6813:                         foreach my $item ('selfenroll_types','selfenroll_start_date','selfenroll_end_date') {
                   6814:                             if (exists($changes{'internal.'.$item})) {
                   6815:                                 $crsinfo{$env{'request.course.id'}}{$item} = 
                   6816:                                     $changes{'internal.'.$item};
                   6817:                             }
                   6818:                         }
                   6819:                         my $crsputresult =
                   6820:                             &Apache::lonnet::courseidput($cdom,\%crsinfo,
                   6821:                                                          $chome,'notime');
                   6822:                     }
                   6823:                 }
                   6824:                 $r->print(&mt('The following changes were made to self-enrollment settings:').'<ul>');
                   6825:                 foreach my $item (@{$row}) {
                   6826:                     my $title = $item;
                   6827:                     if (ref($lt) eq 'HASH') {
                   6828:                         $title = $lt->{$item};
                   6829:                     }
                   6830:                     if ($item eq 'enroll_dates') {
                   6831:                         foreach my $type ('start','end') {
                   6832:                             if (exists($changes{'internal.selfenroll_'.$type.'_date'})) {
                   6833:                                 my $newdate = &Apache::lonlocal::locallocaltime($changes{'internal.selfenroll_'.$type.'_date'});
1.244     bisitz   6834:                                 $r->print('<li>'.&mt('[_1]: "[_2]" set to "[_3]".',
1.237     raeburn  6835:                                           $title,$type,$newdate).'</li>');
                   6836:                             }
                   6837:                         }
                   6838:                     } elsif ($item eq 'access_dates') {
                   6839:                         foreach my $type ('start','end') {
                   6840:                             if (exists($changes{'internal.selfenroll_'.$type.'_access'})) {
                   6841:                                 my $newdate = &Apache::lonlocal::locallocaltime($changes{'internal.selfenroll_'.$type.'_access'});
1.244     bisitz   6842:                                 $r->print('<li>'.&mt('[_1]: "[_2]" set to "[_3]".',
1.237     raeburn  6843:                                           $title,$type,$newdate).'</li>');
                   6844:                             }
                   6845:                         }
1.276     raeburn  6846:                     } elsif ($item eq 'limit') {
                   6847:                         if ((exists($changes{'internal.selfenroll_limit'})) ||
                   6848:                             (exists($changes{'internal.selfenroll_cap'}))) {
                   6849:                             my ($newval,$newcap);
                   6850:                             if ($changes{'internal.selfenroll_cap'} ne '') {
                   6851:                                 $newcap = $changes{'internal.selfenroll_cap'}
                   6852:                             } else {
                   6853:                                 $newcap = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_cap'};
                   6854:                             }
                   6855:                             if ($changes{'internal.selfenroll_limit'} eq 'none') {
                   6856:                                 $newval = &mt('No limit');
                   6857:                             } elsif ($changes{'internal.selfenroll_limit'} eq 
                   6858:                                      'allstudents') {
                   6859:                                 $newval = &mt('New self-enrollment no longer allowed when total (all students) reaches [_1].',$newcap);
                   6860:                             } elsif ($changes{'internal.selfenroll_limit'} eq 'selfenrolled') {
                   6861:                                 $newval = &mt('New self-enrollment no longer allowed when total number of self-enrolled students reaches [_1].',$newcap);
                   6862:                             } else {
                   6863:                                 my $currlimit =  $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_limit'};
                   6864:                                 if ($currlimit eq 'allstudents') {
                   6865:                                     $newval = &mt('New self-enrollment no longer allowed when total (all students) reaches [_1].',$newcap);
                   6866:                                 } elsif ($changes{'internal.selfenroll_limit'} eq 'selfenrolled') {
1.308     raeburn  6867:                                     $newval =  &mt('New self-enrollment no longer allowed when total number of self-enrolled students reaches [_1].',$newcap);
1.276     raeburn  6868:                                 }
                   6869:                             }
                   6870:                             $r->print('<li>'.&mt('"[_1]" set to "[_2]".',$title,$newval).'</li>'."\n");
                   6871:                         }
                   6872:                     } elsif ($item eq 'approval') {
                   6873:                         if ((exists($changes{'internal.selfenroll_approval'})) ||
                   6874:                             (exists($changes{'internal.selfenroll_notifylist'}))) {
                   6875:                             my ($newval,$newnotify);
                   6876:                             if (exists($changes{'internal.selfenroll_notifylist'})) {
                   6877:                                 $newnotify = $changes{'internal.selfenroll_notifylist'};
                   6878:                             } else {   
                   6879:                                 $newnotify = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_notifylist'};
                   6880:                             }
                   6881:                             if ($changes{'internal.selfenroll_approval'}) {
                   6882:                                 $newval = &mt('Yes');
                   6883:                             } elsif ($changes{'internal.selfenroll_approval'} eq '0') {
                   6884:                                 $newval = &mt('No');
                   6885:                             } else {
                   6886:                                 my $currapproval = 
                   6887:                                     $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_approval'};
                   6888:                                 if ($currapproval) {
                   6889:                                     $newval = &mt('Yes');
                   6890:                                 } else {
                   6891:                                     $newval = &mt('No');
                   6892:                                 }
                   6893:                             }
                   6894:                             $r->print('<li>'.&mt('"[_1]" set to "[_2]".',$title,$newval));
                   6895:                             if ($newnotify) {
1.277     raeburn  6896:                                 $r->print('<br />'.&mt('The following will be notified when an enrollment request needs approval, or has been approved: [_1].',$newnotify));
1.276     raeburn  6897:                             } else {
1.277     raeburn  6898:                                 $r->print('<br />'.&mt('No notifications sent when an enrollment request needs approval, or has been approved.'));
1.276     raeburn  6899:                             }
                   6900:                             $r->print('</li>'."\n");
                   6901:                         }
1.237     raeburn  6902:                     } else {
                   6903:                         if (exists($changes{'internal.selfenroll_'.$item})) {
1.241     raeburn  6904:                             my $newval = $changes{'internal.selfenroll_'.$item};
                   6905:                             if ($item eq 'types') {
                   6906:                                 if ($newval eq '') {
                   6907:                                     $newval = &mt('None');
                   6908:                                 } elsif ($newval eq '*') {
                   6909:                                     $newval = &mt('Any user in any domain');
                   6910:                                 }
1.245     raeburn  6911:                             } elsif ($item eq 'registered') {
                   6912:                                 if ($newval eq '1') {
                   6913:                                     $newval = &mt('Yes');
                   6914:                                 } elsif ($newval eq '0') {
                   6915:                                     $newval = &mt('No');
                   6916:                                 }
1.241     raeburn  6917:                             }
1.244     bisitz   6918:                             $r->print('<li>'.&mt('"[_1]" set to "[_2]".',$title,$newval).'</li>'."\n");
1.237     raeburn  6919:                         }
                   6920:                     }
                   6921:                 }
                   6922:                 $r->print('</ul>');
                   6923:                 my %newenvhash;
                   6924:                 foreach my $key (keys(%changes)) {
                   6925:                     $newenvhash{'course.'.$env{'request.course.id'}.'.'.$key} = $changes{$key};
                   6926:                 }
1.238     raeburn  6927:                 &Apache::lonnet::appenv(\%newenvhash);
1.237     raeburn  6928:             } else {
                   6929:                 $r->print(&mt('An error occurred when saving changes to self-enrollment settings in this course.').'<br />'.&mt('The error was: [_1].',$putresult));
                   6930:             }
                   6931:         } else {
1.249     raeburn  6932:             $r->print(&mt('No changes were made to the existing self-enrollment settings in this course.'));
1.237     raeburn  6933:         }
                   6934:     } else {
1.249     raeburn  6935:         $r->print(&mt('No changes were made to the existing self-enrollment settings in this course.'));
1.241     raeburn  6936:     }
1.256     raeburn  6937:     my ($visible,$cansetvis,$vismsgs,$visactions) = &visible_in_cat($cdom,$cnum);
                   6938:     if (ref($visactions) eq 'HASH') {
                   6939:         if (!$visible) {
1.366   ! bisitz   6940:             $r->print('<br /><span class="LC_warning">'.$visactions->{'miss'}.'</span><br />'.$visactions->{'yous'}.
1.256     raeburn  6941:                       '<br />');
                   6942:             if (ref($vismsgs) eq 'ARRAY') {
                   6943:                 $r->print('<br />'.$visactions->{'take'}.'<ul>');
                   6944:                 foreach my $item (@{$vismsgs}) {
                   6945:                     $r->print('<li>'.$visactions->{$item}.'</li>');
                   6946:                 }
                   6947:                 $r->print('</ul>');
                   6948:             }
                   6949:             $r->print($cansetvis);
                   6950:         }
                   6951:     } 
1.237     raeburn  6952:     return;
                   6953: }
                   6954: 
                   6955: sub get_selfenroll_titles {
1.276     raeburn  6956:     my @row = ('types','registered','enroll_dates','access_dates','section',
                   6957:                'approval','limit');
1.237     raeburn  6958:     my %lt = &Apache::lonlocal::texthash (
                   6959:                 types        => 'Users allowed to self-enroll in this course',
1.245     raeburn  6960:                 registered   => 'Restrict self-enrollment to students officially registered for the course',
1.237     raeburn  6961:                 enroll_dates => 'Dates self-enrollment available',
1.256     raeburn  6962:                 access_dates => 'Course access dates assigned to self-enrolling users',
                   6963:                 section      => 'Section assigned to self-enrolling users',
1.276     raeburn  6964:                 approval     => 'Self-enrollment requests need approval?',
                   6965:                 limit        => 'Enrollment limit',
1.237     raeburn  6966:              );
                   6967:     return (\@row,\%lt);
                   6968: }
                   6969: 
1.27      matthew  6970: #---------------------------------------------- end functions for &phase_two
1.29      matthew  6971: 
                   6972: #--------------------------------- functions for &phase_two and &phase_three
                   6973: 
                   6974: #--------------------------end of functions for &phase_two and &phase_three
1.1       www      6975: 
                   6976: 1;
                   6977: __END__
1.2       www      6978: 
                   6979: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.