--- loncom/interface/loncreateuser.pm	2014/04/28 22:20:13	1.400
+++ loncom/interface/loncreateuser.pm	2016/09/27 21:47:48	1.413
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Create a user
 #
-# $Id: loncreateuser.pm,v 1.400 2014/04/28 22:20:13 raeburn Exp $
+# $Id: loncreateuser.pm,v 1.413 2016/09/27 21:47:48 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -251,13 +251,15 @@ sub build_tools_display {
                    'unofficial' => 'Can request creation of unofficial courses',
                    'community'  => 'Can request creation of communities',
                    'textbook'   => 'Can request creation of textbook courses',
+                   'placement'  => 'Can request creation of placement tests',
                    'requestauthor'  => 'Can request author space',
     );
     if ($context eq 'requestcourses') {
         %userenv = &Apache::lonnet::userenvironment($ccdomain,$ccuname,
                       'requestcourses.official','requestcourses.unofficial',
-                      'requestcourses.community','requestcourses.textbook');
-        @usertools = ('official','unofficial','community','textbook');
+                      'requestcourses.community','requestcourses.textbook',
+                      'requestcourses.placement');
+        @usertools = ('official','unofficial','community','textbook','placement');
         @options =('norequest','approval','autolimit','validate');
         %validations = &Apache::lonnet::auto_courserequest_checks($ccdomain);
         %reqtitles = &courserequest_titles();
@@ -447,12 +449,14 @@ sub coursereq_externaluser {
                    'unofficial' => 'Can request creation of unofficial courses',
                    'community'  => 'Can request creation of communities',
                    'textbook'   => 'Can request creation of textbook courses',
+                   'placement'  => 'Can request creation of placement tests',
     );
 
     %userenv = &Apache::lonnet::userenvironment($ccdomain,$ccuname,
                       'reqcrsotherdom.official','reqcrsotherdom.unofficial',
-                      'reqcrsotherdom.community','reqcrsotherdom.textbook');
-    @usertools = ('official','unofficial','community','textbook');
+                      'reqcrsotherdom.community','reqcrsotherdom.textbook',
+                      'reqcrsotherdom.placement');
+    @usertools = ('official','unofficial','community','textbook','placement');
     @options = ('approval','validate','autolimit');
     %validations = &Apache::lonnet::auto_courserequest_checks($cdom);
     my $optregex = join('|',@options);
@@ -533,6 +537,7 @@ sub courserequest_titles {
                                    unofficial => 'Unofficial',
                                    community  => 'Communities',
                                    textbook   => 'Textbook',
+                                   placement  => 'Placement Tests',
                                    norequest  => 'Not allowed',
                                    approval   => 'Approval by Dom. Coord.',
                                    validate   => 'With validation',
@@ -813,7 +818,7 @@ sub entry_form {
     }
     my $cancreate =
         &Apache::lonuserutils::can_create_user($dom,$context,$usertype);
-    my $userpicker = 
+    my ($userpicker,$cansearch) = 
        &Apache::loncommon::user_picker($dom,$srch,$forcenewuser,
                                        'document.crtuser',$cancreate,$usertype);
     my $srchbutton = &mt('Search');
@@ -822,7 +827,9 @@ sub entry_form {
     } elsif ($cancreate && $responsemsg ne '' && $inexact) {
         $srchbutton = &mt('Search or Add New User');
     }
-    my $output = <<"ENDBLOCK";
+    my $output;
+    if ($cansearch) {
+        $output = <<"ENDBLOCK";
 <form action="/adm/createuser" method="post" name="crtuser">
 <input type="hidden" name="action" value="$env{'form.action'}" />
 <input type="hidden" name="phase" value="get_user_info" />
@@ -830,6 +837,9 @@ $userpicker
 <input name="userrole" type="button" value="$srchbutton" onclick="javascript:validateEntry(document.crtuser)" />
 </form>
 ENDBLOCK
+    } else {
+        $output = '<p>'.$userpicker.'</p>';
+    }
     if ($env{'form.phase'} eq '') {
         my $defdom=$env{'request.role.domain'};
         my $domform = &Apache::loncommon::select_dom_form($defdom,'srchdomain');
@@ -2244,8 +2254,8 @@ sub personal_data_display {
                    '<input type="text" name="uname" size="25" value="" autocomplete="off" />';
         $rowcount ++;
         $output .= &Apache::lonhtmlcommon::row_closure(1);
-        my $upassone = '<input type="password" name="upass'.$now.'" size="10" autocomplete="off" />';
-        my $upasstwo = '<input type="password" name="upasscheck'.$now.'" size="10" autocomplete="off" />';
+        my $upassone = '<input type="password" name="upass'.$now.'" size="20" autocomplete="off" />';
+        my $upasstwo = '<input type="password" name="upasscheck'.$now.'" size="20" autocomplete="off" />';
         $output .= &Apache::lonhtmlcommon::row_title(&mt('Password').'<b>*</b>',
                                                     'LC_pick_box_title',
                                                     'LC_oddrow_value')."\n".
@@ -2282,19 +2292,15 @@ sub personal_data_display {
                 }
             } else {
                 if ($context eq 'selfcreate') {
-                    if (($item eq 'permanentemail') && ($newuser eq 'email')) {
-                        $row .= $ccuname;
-                    } else {
-                        if ($canmodify{$item}) {
-                            if ($newuser eq 'email') {
-                                $row .= '<input type="text" name="'.$item.'" size="'.$textboxsize{$item}.'" value="" autocomplete="off" />';
-                            } else {
-                                $row .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="" autocomplete="off" />';
-                            }
-                            $editable ++;
+                    if ($canmodify{$item}) {
+                        if ($newuser eq 'email') {
+                            $row .= '<input type="text" name="'.$item.'" size="'.$textboxsize{$item}.'" value="" autocomplete="off" />';
                         } else {
-                            $hiderow = 1;
+                            $row .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="" autocomplete="off" />';
                         }
+                        $editable ++;
+                    } else {
+                        $hiderow = 1;
                     }
                 } else {
                     $row .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="" />';
@@ -2355,7 +2361,7 @@ sub personal_data_display {
     }
     if (($context eq 'selfcreate') && ($newuser eq 'email')) {
         if ($captchaform) {
-            $output .= &Apache::lonhtmlcommon::row_title($lt{'valid'},
+            $output .= &Apache::lonhtmlcommon::row_title($lt{'valid'}.'*',
                                                          'LC_pick_box_title')."\n".
                        $captchaform."\n".'<br /><br />'.
                        &Apache::lonhtmlcommon::row_closure(1); 
@@ -2583,7 +2589,7 @@ sub update_user_data {
     my (%alerts,%rulematch,%inst_results,%curr_rules);
     my @userinfo = ('firstname','middlename','lastname','generation','permanentemail','id');
     my @usertools = ('aboutme','blog','webdav','portfolio');
-    my @requestcourses = ('official','unofficial','community','textbook');
+    my @requestcourses = ('official','unofficial','community','textbook','placement');
     my @requestauthor = ('requestauthor');
     my ($othertitle,$usertypes,$types) = 
         &Apache::loncommon::sorted_inst_types($env{'form.ccdomain'});
@@ -2756,7 +2762,7 @@ sub update_user_data {
              'requestcourses.community','requestcourses.textbook',
              'reqcrsotherdom.official','reqcrsotherdom.unofficial',
              'reqcrsotherdom.community','reqcrsotherdom.textbook',
-             'requestauthor'],
+             'reqcrsotherdom.placement','requestauthor'],
               $env{'form.ccdomain'},$env{'form.ccuname'});
         my ($tmp) = keys(%userenv);
         if ($tmp =~ /^(con_lost|error)/i) { 
@@ -3047,8 +3053,9 @@ sub update_user_data {
                         ($env{'user.domain'} eq $env{'form.ccdomain'})) {
                         my %newenvhash;
                         foreach my $key (keys(%changed)) {
-                            if (($key eq 'official') || ($key eq 'unofficial')
-                                || ($key eq 'community')) {
+                            if (($key eq 'official') || ($key eq 'unofficial') ||
+                                ($key eq 'community') || ($key eq 'textbook') ||
+                                ($key eq 'placement')) {
                                 $newenvhash{'environment.requestcourses.'.$key} =
                                     $changeHash{'requestcourses.'.$key};
                                 if ($changeHash{'requestcourses.'.$key}) {
@@ -3114,7 +3121,7 @@ sub update_user_data {
                                   \%newsettingstext);
                 if ($env{'form.cid'} ne $userenv{'id'}) {
                     &Apache::lonnet::idput($env{'form.ccdomain'},
-                         ($env{'form.ccuname'} => $env{'form.cid'}));
+                         {$env{'form.ccuname'} => $env{'form.cid'}},$uhome,'ids');
                     if (($recurseid) &&
                         (&Apache::lonnet::allowed('mau',$env{'form.ccdomain'}))) {
                         my $idresult = 
@@ -3257,6 +3264,7 @@ sub display_userinfo {
          'unofficial'     => 'Can Request Unofficial Courses',
          'community'      => 'Can Request Communities',
          'textbook'       => 'Can Request Textbook Courses',
+         'placement'      => 'Can Request Placement Tests',
          'requestauthor'  => 'Can Request Author Role',
          'inststatus'     => "Affiliation",
          'prvs'           => 'Previous Value:',
@@ -3629,7 +3637,7 @@ sub update_roles {
     my @rolechanges;
     my %disallowed;
     $r->print('<h3>'.&mt('Modifying Roles').'</h3>');
-    foreach my $key (keys (%env)) {
+    foreach my $key (keys(%env)) {
 	next if (! $env{$key});
         next if ($key eq 'form.action');
 	# Revoke roles
@@ -3811,7 +3819,7 @@ sub update_roles {
                 } else {
 		    my %curr_groups =
 			&Apache::longroup::coursegroups($one,$two);
-                    foreach my $sec (sort {$a cmp $b} keys %sections) {
+                    foreach my $sec (sort {$a cmp $b} keys(%sections)) {
                         if (($sec eq 'none') || ($sec eq 'all') || 
                             exists($curr_groups{$sec})) {
                             $disallowed{$sec} = $url;
@@ -3857,7 +3865,7 @@ sub update_roles {
                     my %curr_groups = 
 			&Apache::longroup::coursegroups($one,$two);
                     my $emptysec = 0;
-                    foreach my $sec (sort {$a cmp $b} keys %sections) {
+                    foreach my $sec (sort {$a cmp $b} keys(%sections)) {
                         $sec =~ s/\W//g;
                         if ($sec ne '') {
                             if (($sec eq 'none') || ($sec eq 'all') || 
@@ -3897,7 +3905,7 @@ sub update_roles {
                     $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$two,$start,$end,$one,undef,'',$context));
                 } else {
                     my $emptysec = 0;
-                    foreach my $sec (sort {$a cmp $b} keys %sections) {
+                    foreach my $sec (sort {$a cmp $b} keys(%sections)) {
                         if ($sec ne '') {
                             my $securl = $url.'/'.$sec;
                             $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$securl,$two,$start,$end,$one,undef,$sec,$context));
@@ -5404,6 +5412,7 @@ sub print_main_menu {
                                           groups => 'Community Groups',
                                         },
                        );
+        $linktext{'Placement'} = $linktext{'Course'};
 
         my %linktitle = (
             'Course' => {
@@ -5418,6 +5427,8 @@ sub print_main_menu {
                            },
         );
 
+        $linktitle{'Placement'} = $linktitle{'Course'};
+
         push(@{ $menu[0]->{items} }, #Category: Single Users
             {   
              linktext => $linktext{$crstype}{'single'},
@@ -5548,6 +5559,7 @@ sub print_selfenroll_menu {
         butn => 'but no user types have been checked.',
         wilf => "Please uncheck 'activate' or check at least one type.",
     );
+    &js_escape(\%alerts);
     my $selfenroll_js = <<"ENDSCRIPT";
 function update_types(caller,num) {
     var delidx = getIndexByName('selfenroll_delete');
@@ -5749,6 +5761,12 @@ ENDSCRIPT
         $cathash = $domconfig{'coursecategories'}{'cats'};
         $cattype{'auth'} = $domconfig{'coursecategories'}{'auth'};
         $cattype{'unauth'} = $domconfig{'coursecategories'}{'unauth'};
+        if ($cattype{'auth'} eq '') {
+            $cattype{'auth'} = 'std';
+        }
+        if ($cattype{'unauth'} eq '') {
+            $cattype{'unauth'} = 'std';
+        }
     } else {
         $cathash = {};
         $cattype{'auth'} = 'std';
@@ -6820,13 +6838,29 @@ sub user_search_result {
         }
     }
     if ($response ne '') {
-        $response = '<span class="LC_warning">'.$response.'</span>';
+        $response = '<span class="LC_warning">'.$response.'</span><br />';
     }
     if ($srch->{'srchin'} eq 'instd') {
-        my $instd_chk = &directorysrch_check($srch);
+        my $instd_chk = &instdirectorysrch_check($srch);
         if ($instd_chk ne 'ok') {
-            $response = '<span class="LC_warning">'.$instd_chk.'</span>'.
-                        '<br />'.&mt('You may want to search in the LON-CAPA domain instead of the institutional directory.').'<br /><br />';
+            my $domd_chk = &domdirectorysrch_check($srch);
+            $response .= '<span class="LC_warning">'.$instd_chk.'</span><br />';
+            if ($domd_chk eq 'ok') {
+                $response .= &mt('You may want to search in the LON-CAPA domain instead of the institutional directory.');
+            }
+            $response .= '<br /><br />';
+        }
+    } else {
+        unless (($context eq 'requestcrs') && ($srch->{'srchtype'} eq 'exact')) { 
+            my $domd_chk = &domdirectorysrch_check($srch);
+            if ($domd_chk ne 'ok') {
+                my $instd_chk = &instdirectorysrch_check($srch);
+                $response .= '<span class="LC_warning">'.$domd_chk.'</span><br />';
+                if ($instd_chk eq 'ok') {
+                    $response .= &mt('You may want to search in the institutional directory instead of the LON-CAPA domain.');
+                }
+                $response .= '<br /><br />';
+            }
         }
     }
     if ($response ne '') {
@@ -6990,7 +7024,8 @@ sub user_search_result {
                 ($currstate,$response,$forcenewuser) = 
                     &build_search_response($context,$srch,%srch_results);
             } else {
-                my $showdom = &display_domain_info($srch->{'srchdomain'});                $response = '<span class="LC_warning">'.
+                my $showdom = &display_domain_info($srch->{'srchdomain'});
+                $response = '<span class="LC_warning">'.
                     &mt('Institutional directory search is not available in domain: [_1]',$showdom).
                     '</span><br />'.
                     &mt('You may want to search in the LON-CAPA domain instead of the institutional directory.').
@@ -7001,7 +7036,26 @@ sub user_search_result {
     return ($currstate,$response,$forcenewuser,\%srch_results);
 }
 
-sub directorysrch_check {
+sub domdirectorysrch_check {
+    my ($srch) = @_;
+    my $response;
+    my %dom_inst_srch = &Apache::lonnet::get_dom('configuration',
+                                             ['directorysrch'],$srch->{'srchdomain'});
+    my $showdom = &display_domain_info($srch->{'srchdomain'});
+    if (ref($dom_inst_srch{'directorysrch'}) eq 'HASH') {
+        if ($dom_inst_srch{'directorysrch'}{'lcavailable'} eq '0') {
+            return &mt('LON-CAPA directory search is not available in domain: [_1]',$showdom);
+        }
+        if ($dom_inst_srch{'directorysrch'}{'lclocalonly'}) {
+            if ($env{'request.role.domain'} ne $srch->{'srchdomain'}) {
+                return &mt('LON-CAPA directory search in domain: [_1] is only allowed for users with a current role in the domain.',$showdom);
+            }
+        }
+    }
+    return 'ok';
+}
+
+sub instdirectorysrch_check {
     my ($srch) = @_;
     my $can_search = 0;
     my $response;
@@ -7314,13 +7368,13 @@ sub course_level_table {
                 ((($role eq 'cc') || ($role eq 'co')) && ($isowner))) {
                 $table .= &course_level_row($protectedcourse,$role,$area,$domain,
                                             $plrole,\%sections_count,\%lt,
-                                            $defaultcredits,$crstype);
+                                            $showcredits,$defaultcredits,$crstype);
             } elsif ($env{'request.course.sec'} ne '') {
                 if (&Apache::lonnet::allowed('c'.$role,$thiscourse.'/'.
                                              $env{'request.course.sec'})) {
                     $table .= &course_level_row($protectedcourse,$role,$area,$domain,
                                                 $plrole,\%sections_count,\%lt,
-                                                $defaultcredits,$crstype);
+                                                $showcredits,$defaultcredits,$crstype);
                 }
             }
         }
@@ -7329,7 +7383,8 @@ sub course_level_table {
                 next if ($crstype eq 'Community' && $customroles{$cust} =~ /bre\&S/);
                 my $role = 'cr_cr_'.$env{'user.domain'}.'_'.$env{'user.name'}.'_'.$cust;
                 $table .= &course_level_row($protectedcourse,$role,$area,$domain,
-                                            $cust,\%sections_count,\%lt);
+                                            $cust,\%sections_count,\%lt,
+                                            $showcredits,$defaultcredits,$crstype);
             }
 	}
     }
@@ -7343,7 +7398,11 @@ sub course_level_table {
 &Apache::loncommon::start_data_table().
 &Apache::loncommon::start_data_table_header_row().
 '<th>'.$lt{'act'}.'</th><th>'.$lt{'rol'}.'</th>'."\n".
-'<th>'.$lt{'ext'}.'</th><th>'.$lt{'crd'}.'</th>'."\n".
+'<th>'.$lt{'ext'}.'</th><th>'."\n";
+    if ($showcredits) {
+        $result .= $lt{'crd'}.'</th>';
+    }
+    $result .=
 '<th>'.$lt{'grs'}.'</th><th>'.$lt{'sta'}.'</th>'."\n".
 '<th>'.$lt{'end'}.'</th>'.
 &Apache::loncommon::end_data_table_header_row().
@@ -7354,14 +7413,14 @@ $table.
 
 sub course_level_row {
     my ($protectedcourse,$role,$area,$domain,$plrole,$sections_count,
-        $lt,$defaultcredits,$crstype) = @_;
+        $lt,$showcredits,$defaultcredits,$crstype) = @_;
     my $creditem;
     my $row = &Apache::loncommon::start_data_table_row().
               ' <td><input type="checkbox" name="act_'.
               $protectedcourse.'_'.$role.'" /></td>'."\n".
               ' <td>'.$plrole.'</td>'."\n".
               ' <td>'.$area.'<br />Domain: '.$domain.'</td>'."\n";
-    if (($role eq 'st') && ($crstype eq 'Course')) {
+    if (($showcredits) && ($role eq 'st') && ($crstype eq 'Course')) {
         $row .= 
             '<td><input type="text" name="credits_'.$protectedcourse.'_'.
             $role.'" size="3" value="'.$defaultcredits.'" /></td>';
@@ -7450,8 +7509,8 @@ sub course_level_dc {
         my $plrole=&Apache::lonnet::plaintext($role);
         $otheritems .= '  <option value="'.$role.'">'.$plrole.'</option>';
     }
-    if ( keys %customroles > 0) {
-        foreach my $cust (sort keys %customroles) {
+    if ( keys(%customroles) > 0) {
+        foreach my $cust (sort(keys(%customroles))) {
             my $custrole='cr_cr_'.$env{'user.domain'}.
                     '_'.$env{'user.name'}.'_'.$cust;
             $otheritems .= '  <option value="'.$custrole.'">'.$cust.'</option>';