--- loncom/interface/loncreateuser.pm 2008/07/04 18:30:30 1.247 +++ loncom/interface/loncreateuser.pm 2008/12/06 12:49:18 1.266 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Create a user # -# $Id: loncreateuser.pm,v 1.247 2008/07/04 18:30:30 raeburn Exp $ +# $Id: loncreateuser.pm,v 1.266 2008/12/06 12:49:18 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -33,11 +33,13 @@ package Apache::loncreateuser; =head1 NAME -Apache::loncreateuser - handler to create users and custom roles +Apache::loncreateuser.pm =head1 SYNOPSIS -Apache::loncreateuser provides an Apache handler for creating users, + Handler to create users and custom roles + + Provides an Apache handler for creating users, editing their login parameters, roles, and removing roles, and also creating and assigning custom roles. @@ -833,10 +835,10 @@ ENDNOPORTPRIV $addrolesdisplay = $add_domainroles; } $r->print(&course_level_dc($env{'request.role.domain'},'Course')); - $r->print('<br /><input type="button" value="'.&mt('Modify User').'" onClick="setCourse()" />'."\n"); + $r->print('<br /><input type="button" value="'.&mt('Save').'" onClick="setCourse()" />'."\n"); } elsif ($context eq 'author') { if ($addrolesdisplay) { - $r->print('<br /><input type="button" value="'.&mt('Modify User').'"'); + $r->print('<br /><input type="button" value="'.&mt('Save').'"'); if ($newuser) { $r->print(' onClick="auth_check()" \>'."\n"); } else { @@ -848,7 +850,7 @@ ENDNOPORTPRIV } } else { $r->print(&course_level_table(%inccourses)); - $r->print('<br /><input type="button" value="'.&mt('Modify User').'" onClick="setSections(this.form)" />'."\n"); + $r->print('<br /><input type="button" value="'.&mt('Save').'" onClick="setSections(this.form)" />'."\n"); } } $r->print(&Apache::lonhtmlcommon::echo_form_input(['phase','userrole','ccdomain','prevphase','currstate','ccuname','ccdomain'])); @@ -967,7 +969,7 @@ sub display_existing_roles { if (defined($coursedata{'description'})) { $carea=$coursedata{'description'}. '<br />'.&mt('Domain').': '.$coursedom.(' 'x8). - &Apache::loncommon::syllabuswrapper('Syllabus',$coursedir,$coursedom); + &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$coursedir,$coursedom); $sortkey.="\0".$coursedata{'description'}; $class=$coursedata{'type'}; } else { @@ -1396,10 +1398,12 @@ sub modify_login_block { } sub personal_data_display { - my ($ccuname,$ccdomain,$newuser,$context,$inst_results) = @_; + my ($ccuname,$ccdomain,$newuser,$context,$inst_results,$rolesarray) = @_; my ($output,$showforceid,%userenv,%canmodify); my @userinfo = ('firstname','middlename','lastname','generation', 'permanentemail','id'); + my $rowcount = 0; + my $editable = 0; if (!$newuser) { # Get the users information %userenv = &Apache::lonnet::get('environment', @@ -1407,7 +1411,10 @@ sub personal_data_display { 'permanentemail','id'],$ccdomain,$ccuname); %canmodify = &Apache::lonuserutils::can_modify_userinfo($context,$ccdomain, - \@userinfo); + \@userinfo,$rolesarray); + } elsif ($context eq 'selfcreate') { + %canmodify = &selfcreate_canmodify($context,$ccdomain,\@userinfo, + $inst_results,$rolesarray); } my %lt=&Apache::lonlocal::texthash( 'pd' => "Personal Data", @@ -1416,7 +1423,7 @@ sub personal_data_display { 'lastname' => "Last Name", 'generation' => "Generation", 'permanentemail' => "Permanent e-mail address", - 'id' => "ID/Student Number", + 'id' => "Student/Employee ID", 'lg' => "Login Data" ); my %textboxsize = ( @@ -1432,40 +1439,93 @@ sub personal_data_display { &Apache::lonhtmlcommon::start_pick_box(); foreach my $item (@userinfo) { my $rowtitle = $lt{$item}; + my $hiderow = 0; if ($item eq 'generation') { $rowtitle = $genhelp.$rowtitle; } - $output .= &Apache::lonhtmlcommon::row_title($rowtitle,undef,'LC_oddrow_value')."\n"; + my $row = &Apache::lonhtmlcommon::row_title($rowtitle,undef,'LC_oddrow_value')."\n"; if ($newuser) { if (ref($inst_results) eq 'HASH') { if ($inst_results->{$item} ne '') { - $output .= '<input type="hidden" name="c'.$item.'" value="'.$inst_results->{$item}.'" />'.$inst_results->{$item}; + $row .= '<input type="hidden" name="c'.$item.'" value="'.$inst_results->{$item}.'" />'.$inst_results->{$item}; } else { - $output .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="" />'; + if ($context eq 'selfcreate') { + if ($canmodify{$item}) { + $row .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="" />'; + $editable ++; + } else { + $hiderow = 1; + } + } else { + $row .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="" />'; + } } } else { - $output .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="" />'; + if ($context eq 'selfcreate') { + if ($canmodify{$item}) { + $row .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="" />'; + $editable ++; + } else { + $hiderow = 1; + } + } else { + $row .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="" />'; + } } } else { if ($canmodify{$item}) { - $output .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="'.$userenv{$item}.'" />'; + $row .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="'.$userenv{$item}.'" />'; } else { - $output .= $userenv{$item}; + $row .= $userenv{$item}; } if ($item eq 'id') { $showforceid = $canmodify{$item}; } } - $output .= &Apache::lonhtmlcommon::row_closure(1); + $row .= &Apache::lonhtmlcommon::row_closure(1); + if (!$hiderow) { + $output .= $row; + $rowcount ++; + } } $output .= &Apache::lonhtmlcommon::end_pick_box(); if (wantarray) { - return ($output,$showforceid); + if ($context eq 'selfcreate') { + return($output,$rowcount,$editable); + } else { + return ($output,$showforceid); + } } else { return $output; } } +sub selfcreate_canmodify { + my ($context,$dom,$userinfo,$inst_results,$rolesarray) = @_; + if (ref($inst_results) eq 'HASH') { + my @inststatuses = &get_inststatuses($inst_results); + if (@inststatuses == 0) { + @inststatuses = ('default'); + } + $rolesarray = \@inststatuses; + } + my %canmodify = + &Apache::lonuserutils::can_modify_userinfo($context,$dom,$userinfo, + $rolesarray); + return %canmodify; +} + +sub get_inststatuses { + my ($insthashref) = @_; + my @inststatuses = (); + if (ref($insthashref) eq 'HASH') { + if (ref($insthashref->{'inststatus'}) eq 'ARRAY') { + @inststatuses = @{$insthashref->{'inststatus'}}; + } + } + return @inststatuses; +} + # ================================================================= Phase Three sub update_user_data { my ($r,$context) = @_; @@ -1789,7 +1849,7 @@ sub update_user_data { $env{'form.c'.$item} = $userenv{$item}; } } - # Check to see if we can change the ID/student number + # Check to see if we can change the Student/Employee ID my $forceid = $env{'form.forceid'}; my $recurseid = $env{'form.recurseid'}; my (%alerts,%rulematch,%idinst_results,%curr_rules,%got_rules); @@ -1800,7 +1860,10 @@ sub update_user_data { (!$forceid)) { if ($env{'form.cid'} ne $uidhash{$env{'form.ccuname'}}) { $env{'form.cid'} = $userenv{'id'}; - $no_forceid_alert = &mt('New student/employeeID does not match existing ID for this user.').'<br />'.&mt('Change is not permitted without checking the \'Force ID change\' checkbox on the previous page.').'<br />'."\n"; + $no_forceid_alert = &mt('New Student/Employee ID does not match existing ID for this user.') + .'<br />' + .&mt("Change is not permitted without checking the 'Force ID change' checkbox on the previous page.") + .'<br />'."\n"; } } if ($env{'form.cid'} ne $userenv{'id'}) { @@ -1914,7 +1977,7 @@ sub update_user_data { 'mddl' => "middle", 'lst' => "last", 'gen' => "generation", - 'id' => "ID/Student number", + 'id' => "Student/Employee ID", 'mail' => "permanent e-mail", 'disk' => "disk space allocated to portfolio files", 'prvs' => "Previous", @@ -1997,7 +2060,7 @@ END # They did not want to change the users name or quota but we can # still tell them what the name and quota are my %lt=&Apache::lonlocal::texthash( - 'id' => "ID/Student number", + 'id' => "Student/Employee ID", 'mail' => "Permanent e-mail", 'disk' => "Disk space allocated to user's portfolio files", ); @@ -2040,8 +2103,10 @@ END $r->print('<span class="LC_cusr_emph">'.$rolestr.'</span><br />'. &mt('Contact your <a href="[_1]">helpdesk</a> for more information.',"javascript:helpMenu('display')").'<br />'); } - $r->print($no_forceid_alert. - &Apache::lonuserutils::print_namespacing_alerts($env{'form.ccdomain'},\%alerts,\%curr_rules)); + $r->print('<span class="LC_warning">' + .$no_forceid_alert + .&Apache::lonuserutils::print_namespacing_alerts($env{'form.ccdomain'},\%alerts,\%curr_rules) + .'</span>'); } if ($env{'form.action'} eq 'singlestudent') { &enroll_single_student($r,$uhome,$amode,$genpwd,$now,$newuser,$context); @@ -2183,8 +2248,8 @@ sub update_roles { my $result=&Apache::lonnet::assignrole($env{'form.ccdomain'}, $env{'form.ccuname'},$url,$role,0,$now,'','', $context); - $output = &mt('Re-enabling [_1] in [_2]: <b>[_3]</b>', - $role,$url,$result).'<br />'; + $output = &mt('Re-enabling [_1] in [_2]: [_3]', + $role,$url,'<b>'.$result.'</b>').'<br />'; } $r->print($output); if (!grep(/^\Q$role\E$/,@rolechanges)) { @@ -2197,8 +2262,8 @@ sub update_roles { my $result = &Apache::lonnet::assigncustomrole( $env{'form.ccdomain'}, $env{'form.ccuname'}, $url,$rdom,$rnam,$rolename,0,$now,undef,$context); - $r->print(&mt('Re-enabling custom role [_1] by [_2]@[_3] in [_4] : <b>[_5]</b>', - $rolename,$rnam,$rdom,$url,$result).'<br />'); + $r->print(&mt('Re-enabling custom role [_1] by [_2]@[_3] in [_4] : [_5]', + $rolename,$rnam,$rdom,$url,'<b>'.$result.'</b>').'<br />'); if (!grep(/^cr$/,@rolechanges)) { push(@rolechanges,'cr'); } @@ -2542,7 +2607,7 @@ sub custom_role_editor { my @template_roles = ("cc","in","ta","ep","st"); foreach my $role (@template_roles) { $head_script .= &make_script_template($role); - $button_code .= &make_button_code($role); + $button_code .= &make_button_code($role).' '; } $head_script .= "\n".$jsback."\n".'</script>'."\n"; $r->print(&Apache::loncommon::start_page('Custom Role Editor',$head_script)); @@ -2562,10 +2627,15 @@ sub custom_role_editor { 'crl' => "Course Level", 'dml' => "Domain Level", 'ssl' => "System Level"); - $r->print(&mt('Select a Template').'<br />'); - $r->print('<form action="">'); - $r->print($button_code); - $r->print('</form>'); + + $r->print('<div>' + .'<form action=""><fieldset>' + .'<legend>'.&mt('Select a Template').'</legend>' + .$button_code + .'</fieldset></form>' + .'</div>' + ); + $r->print(<<ENDCCF); <form name="form1" method="post"> <input type="hidden" name="phase" value="set_custom_roles" /> @@ -2668,7 +2738,7 @@ sub make_script_template { sub make_button_code { my ($role) = @_; my $label = &Apache::lonnet::plaintext($role); - my $button_code = '<input type="button" onClick="set_'.$role.'()" value="'.$label.'" />'; + my $button_code = '<input type="button" onClick="set_'.$role.'()" value="'.$label.'" />'; return ($button_code); } # ---------------------------------------------------------- Call to definerole @@ -3061,102 +3131,127 @@ sub print_main_menu { listusers => 'Display Co-authors and Manage Multiple Users', }, course => { - upload => 'Upload a File of Course Users', - singleuser => 'Add/Modify a Single Course User', - listusers => 'Display Class Lists and Manage Multiple Users', + upload => 'File of Course Users', + singleuser => 'Single Course User', + listusers => 'Course User Lists', }, ); - my @menu = - ( - { text => $links{$context}{'upload'}, - help => 'Course_Create_Class_List', - action => 'upload', - permission => $permission->{'cusr'}, - }, - { text => $links{$context}{'singleuser'}, - help => 'Course_Change_Privileges', - action => 'singleuser', - permission => $permission->{'cusr'}, - }, - { text => $links{$context}{'listusers'}, - help => 'Course_View_Class_List', - action => 'listusers', - permission => ($permission->{'view'} || $permission->{'cusr'}), - }, - ); - if ($context eq 'domain' || $context eq 'course') { - my $customlink = { text => 'Edit Custom Roles', - help => 'Course_Editing_Custom_Roles', - action => 'custom', - permission => $permission->{'custom'}, - }; - push(@menu,$customlink); - } - if ($context eq 'course') { - my ($cnum,$cdom) = &Apache::lonuserutils::get_course_identity(); - my @courselinks = - ( - { text => 'Enroll a Single Student', - help => 'Course_Add_Student', - action => 'singlestudent', - permission => $permission->{'cusr'}, - }, - { text => 'Drop Students', - help => 'Course_Drop_Student', - action => 'drop', - permission => $permission->{'cusr'}, - }); - if (!exists($permission->{'cusr_section'})) { - push(@courselinks, - { text => 'Automated Enrollment Manager', - help => 'Course_Automated_Enrollment', - permission => (&Apache::lonnet::auto_run($cnum,$cdom) - && $permission->{'cusr'}), - url => '/adm/populate', - }, - { text => 'Configure User Self-enrollment', - help => 'Course_Self_Enrollment', - action => 'selfenroll', - permission => $permission->{'cusr'}, - }); - } - push(@courselinks, - { text => 'Manage Course Groups', - help => 'Course_Manage_Group', - permission => $permission->{'grp_manage'}, - url => '/adm/coursegroups?refpage=cusr', - }, - { text => 'View Change Logs', - help => 'Course_User_Logs', - action => 'changelogs', - permission => $permission->{'cusr'}, - }, - { text => 'View Log-in History', - help => 'Course_User_Logins', - action => 'logins', - permission => $permission->{'cusr'}, - }); - push(@menu,@courselinks); - } - my $menu_html = ''; - foreach my $menu_item (@menu) { - next if (! $menu_item->{'permission'}); - $menu_html.='<p>'; - if (exists($menu_item->{'help'})) { - $menu_html.= - &Apache::loncommon::help_open_topic($menu_item->{'help'}); - } - $menu_html.='<font size="+1">'; - if (exists($menu_item->{'url'})) { - $menu_html.=qq{<a href="$menu_item->{'url'}">}; - } else { - $menu_html.= - qq{<a href="/adm/createuser?action=$menu_item->{'action'}">}; - } - $menu_html.= &mt($menu_item->{'text'}).'</a></font>'; - $menu_html.='</p>'; - } - return $menu_html; + my @menu = ( {categorytitle => 'Add Users', + items => + [{ + linktext => $links{$context}{'upload'}, + icon => 'sctr.png', + #help => 'Course_Create_Class_List', + url => '/adm/createuser?action=upload', + permission => $permission->{'cusr'}, + linktitle => 'Upload a CSV or a text file containing users.', + }, + { + linktext => $links{$context}{'singleuser'}, + icon => 'edit-redo.png', + #help => 'Course_Change_Privileges', + url => '/adm/createuser?action=singleuser', + permission => $permission->{'cusr'}, + linktitle => 'Add a user with a certain role to this course.', + }]}, + {categorytitle => 'Administration', + items => + [{ + linktext => $links{$context}{'listusers'}, + icon => 'edit-find.png', + #help => 'Course_View_Class_List', + url => '/adm/createuser?action=listusers', + permission => ($permission->{'view'} || $permission->{'cusr'}), + linktitle => 'Show and manage users of this course.', + }]}, + {categorytitle => 'Configuration', + items => + [ + ]}, + ); + + if ($context eq 'domain'){ + + push(@{ $menu[1]->{items} }, + { linktext => 'Custom Roles', + icon => 'emblem-photos.png', + #help => 'Course_Editing_Custom_Roles', + url => '/adm/createuser?action=custom', + permission => $permission->{'custom'}, + linktitle => 'Configure a custom role.', + }); + + }elsif ($context eq 'course'){ + my ($cnum,$cdom) = &Apache::lonuserutils::get_course_identity(); + + push(@{ $menu[0]->{items} }, + { linktext => 'Single Student', + #help => 'Course_Add_Student', + icon => 'list-add.png', + url => '/adm/createuser?action=singlestudent', + permission => $permission->{'cusr'}, + linktitle => 'Add a user with the role student to this course.', + }); + + push(@{ $menu[1]->{items} }, + { linktext => 'Drop Students', + icon => 'edit-undo.png', + #help => 'Course_Drop_Student', + url => '/adm/createuser?action=drop', + permission => $permission->{'cusr'}, + linktitle =>'Remove a student from this course.', + }, + { linktext => 'Custom Roles', + icon => 'emblem-photos.png', + #help => 'Course_Editing_Custom_Roles', + url => '/adm/createuser?action=custom', + permission => $permission->{'custom'}, + linktitle => 'Configure a custom role.', + }); + + if (!exists($permission->{'cusr_section'})){ + + push(@{ $menu[2]->{items} }, + { linktext => 'Automated Enrollment', + icon => 'roles.png', + #help => 'Course_Automated_Enrollment', + permission => (&Apache::lonnet::auto_run($cnum,$cdom) + && $permission->{'cusr'}), + url => '/adm/populate', + linktitle => 'Automated enrollment manager.', + }, + { linktext => 'User Self-Enrollment', + icon => 'cstr.png', + #help => 'Course_Self_Enrollment', + url => '/adm/createuser?action=selfenroll', + permission => $permission->{'cusr'}, + linktitle => 'Configure user self enrollment.', + }); + + } + + push(@{ $menu[2]->{items} }, + { linktext => 'Course Groups', + icon => 'conf.png', + #help => 'Course_Manage_Group', + url => '/adm/coursegroups?refpage=cusr', + permission => $permission->{'grp_manage'}, + linktitle => 'Manage course groups.', + }, + { linktext => 'Change Logs', + icon => 'document-properties.png', + #help => 'Course_User_Logs', + url => '/adm/createuser?action=changelogs', + permission => $permission->{'cusr'}, + linktitle => 'View change log.', + }); + }; +return Apache::lonhtmlcommon::generate_menu(@menu); +# { text => 'View Log-in History', +# help => 'Course_User_Logins', +# action => 'logins', +# permission => $permission->{'cusr'}, +# }); } sub restore_prev_selections { @@ -3178,14 +3273,203 @@ sub print_selfenroll_menu { my $groupslist = &Apache::lonuserutils::get_groupslist(); my $setsec_js = &Apache::lonuserutils::setsections_javascript($formname,$groupslist); + my %alerts = &Apache::lonlocal::texthash( + acto => 'Activation of self-enrollment was selected for the following domain(s)', + butn => 'but no user types have been checked.', + wilf => "Please uncheck 'activate' or check at least one type.", + ); + my $selfenroll_js = <<"ENDSCRIPT"; +function update_types(caller,num) { + var delidx = getIndexByName('selfenroll_delete'); + var actidx = getIndexByName('selfenroll_activate'); + if (caller == 'selfenroll_all') { + var selall; + for (var i=0; i<document.$formname.selfenroll_all.length; i++) { + if (document.$formname.selfenroll_all[i].checked) { + selall = document.$formname.selfenroll_all[i].value; + } + } + if (selall == 1) { + if (delidx != -1) { + if (document.$formname.selfenroll_delete.length) { + for (var j=0; j<document.$formname.selfenroll_delete.length; j++) { + document.$formname.selfenroll_delete[j].checked = true; + } + } else { + document.$formname.elements[delidx].checked = true; + } + } + if (actidx != -1) { + if (document.$formname.selfenroll_activate.length) { + for (var j=0; j<document.$formname.selfenroll_activate.length; j++) { + document.$formname.selfenroll_activate[j].checked = false; + } + } else { + document.$formname.elements[actidx].checked = false; + } + } + document.$formname.selfenroll_newdom.selectedIndex = 0; + } + } + if (caller == 'selfenroll_activate') { + if (document.$formname.selfenroll_activate.length) { + for (var j=0; j<document.$formname.selfenroll_activate.length; j++) { + if (document.$formname.selfenroll_activate[j].value == num) { + if (document.$formname.selfenroll_activate[j].checked) { + for (var i=0; i<document.$formname.selfenroll_all.length; i++) { + if (document.$formname.selfenroll_all[i].value == '1') { + document.$formname.selfenroll_all[i].checked = false; + } + if (document.$formname.selfenroll_all[i].value == '0') { + document.$formname.selfenroll_all[i].checked = true; + } + } + } + } + } + } else { + for (var i=0; i<document.$formname.selfenroll_all.length; i++) { + if (document.$formname.selfenroll_all[i].value == '1') { + document.$formname.selfenroll_all[i].checked = false; + } + if (document.$formname.selfenroll_all[i].value == '0') { + document.$formname.selfenroll_all[i].checked = true; + } + } + } + } + if (caller == 'selfenroll_delete') { + if (document.$formname.selfenroll_delete.length) { + for (var j=0; j<document.$formname.selfenroll_delete.length; j++) { + if (document.$formname.selfenroll_delete[j].value == num) { + if (document.$formname.selfenroll_delete[j].checked) { + var delindex = getIndexByName('selfenroll_types_'+num); + if (delindex != -1) { + if (document.$formname.elements[delindex].length) { + for (var k=0; k<document.$formname.elements[delindex].length; k++) { + document.$formname.elements[delindex][k].checked = false; + } + } else { + document.$formname.elements[delindex].checked = false; + } + } + } + } + } + } else { + if (document.$formname.selfenroll_delete.checked) { + var delindex = getIndexByName('selfenroll_types_'+num); + if (delindex != -1) { + if (document.$formname.elements[delindex].length) { + for (var k=0; k<document.$formname.elements[delindex].length; k++) { + document.$formname.elements[delindex][k].checked = false; + } + } else { + document.$formname.elements[delindex].checked = false; + } + } + } + } + } + return; +} + +function validate_types(form) { + var needaction = new Array(); + var countfail = 0; + var actidx = getIndexByName('selfenroll_activate'); + if (actidx != -1) { + if (document.$formname.selfenroll_activate.length) { + for (var j=0; j<document.$formname.selfenroll_activate.length; j++) { + var num = document.$formname.selfenroll_activate[j].value; + if (document.$formname.selfenroll_activate[j].checked) { + countfail = check_types(num,countfail,needaction) + } + } + } else { + if (document.$formname.selfenroll_activate.checked) { + var num = document.enrollstudent.selfenroll_activate.value; + countfail = check_types(num,countfail,needaction) + } + } + } + if (countfail > 0) { + var msg = "$alerts{'acto'}\\n"; + var loopend = needaction.length -1; + if (loopend > 0) { + for (var m=0; m<loopend; m++) { + msg += needaction[m]+", "; + } + } + msg += needaction[loopend]+"\\n$alerts{'butn'}\\n$alerts{'wilf'}"; + alert(msg); + return; + } + setSections(form); +} + +function check_types(num,countfail,needaction) { + var typeidx = getIndexByName('selfenroll_types_'+num); + var count = 0; + if (typeidx != -1) { + if (document.$formname.elements[typeidx].length) { + for (var k=0; k<document.$formname.elements[typeidx].length; k++) { + if (document.$formname.elements[typeidx][k].checked) { + count ++; + } + } + } else { + if (document.$formname.elements[typeidx].checked) { + count ++; + } + } + if (count == 0) { + var domidx = getIndexByName('selfenroll_dom_'+num); + if (domidx != -1) { + var domname = document.$formname.elements[domidx].value; + needaction[countfail] = domname; + countfail ++; + } + } + } + return countfail; +} + +function getIndexByName(item) { + for (var i=0;i<document.$formname.elements.length;i++) { + if (document.$formname.elements[i].name == item) { + return i; + } + } + return -1; +} +ENDSCRIPT + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my $output = '<script type="text/javascript">'."\n". - $setsec_js."\n". + $setsec_js."\n".$selfenroll_js."\n". '</script>'."\n". - '<h3>'.$lt->{'selfenroll'}.'</h3>'."\n". - '<form name="'.$formname.'" method="post" action="/adm/createuser">'."\n". - &Apache::lonhtmlcommon::start_pick_box(); - my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; - my $cnum = $env{'course.'.$env{'request.course.id'},'.num'}; + '<h3>'.$lt->{'selfenroll'}.'</h3>'."\n"; + my ($visible,$cansetvis,$vismsgs,$visactions) = &visible_in_cat($cdom,$cnum); + if (ref($visactions) eq 'HASH') { + if ($visible) { + $output .= '<p>'.$visactions->{'vis'}.'</p>'; + } else { + $output .= $visactions->{'miss'}.'<br />'.$visactions->{'yous'}. + '<p>'.$visactions->{'gen'}.'<br />'.$visactions->{'coca'}; + if (ref($vismsgs) eq 'ARRAY') { + $output .= '<br />'.$visactions->{'make'}.'<ul>'; + foreach my $item (@{$vismsgs}) { + $output .= '<li>'.$visactions->{$item}.'</li>'; + } + $output .= '</ul>'; + } + $output .= '</p>'; + } + } + $output .= '<form name="'.$formname.'" method="post" action="/adm/createuser">'."\n". + &Apache::lonhtmlcommon::start_pick_box(); if (ref($row) eq 'ARRAY') { foreach my $item (@{$row}) { my $title = $item; @@ -3208,14 +3492,20 @@ sub print_selfenroll_menu { if ($curr_types eq '*') { $output .= ' checked="checked" '; } - $output .= '/>'.&mt('Yes').'</label> <input type="radio" name="selfenroll_all" value="0" '; + $output .= 'onchange="javascript:update_types('. + "'selfenroll_all'".');" />'.&mt('Yes').'</label>'. + ' <input type="radio" name="selfenroll_all" value="0" '; if ($curr_types ne '*') { $output .= ' checked="checked" '; } - $output .= '/>'.&mt('No').'</label></td>' - .&Apache::loncommon::end_data_table_row(); + $output .= ' onchange="javascript:update_types('. + "'selfenroll_all'".');"/>'.&mt('No').'</label></td>'. + &Apache::loncommon::end_data_table_row(). + &Apache::loncommon::end_data_table(). + &mt('Or').'<br />'. + &Apache::loncommon::start_data_table(); my %currdoms; - if (($curr_types eq '') && ($env{'form.selfenroll_newdom'} eq '')) { + if ($curr_types eq '') { $output .= &new_selfenroll_dom_row($cdom,'0'); } elsif ($curr_types ne '*') { my @entries = split(/;/,$curr_types); @@ -3224,33 +3514,27 @@ sub print_selfenroll_menu { my ($currdom,$typestr) = split(/:/,$entry); $currdoms{$currdom} = 1; my $domdesc = &Apache::lonnet::domain($currdom); - my @currinsttypes = split(/,/,$typestr); + my @currinsttypes = split(',',$typestr); $output .= &Apache::loncommon::start_data_table_row() .'<td valign="top"><span class="LC_nobreak">'.&mt('Domain:').'<b>' .' '.$domdesc.' ('.$currdom.')' .'</b><input type="hidden" name="selfenroll_dom_'.$num .'" value="'.$currdom.'" /></span><br />' .'<span class="LC_nobreak"><label><input type="checkbox" ' - .'name="selfenroll_delete" value="'.$num.'" />' + .'name="selfenroll_delete" value="'.$num.'" onchange="javascript:update_types('."'selfenroll_delete','$num'".');" />' .&mt('Delete').'</label></span></td>'; - $output .= '<td valign="top">'.&mt('User types:').'<br />' + $output .= '<td valign="top"> '.&mt('User types:').'<br />' .&selfenroll_inst_types($num,$currdom,\@currinsttypes).'</td>' .&Apache::loncommon::end_data_table_row(); $num ++; } } } - if ($env{'form.selfenroll_newdom'} ne '') { - if (!defined($currdoms{$env{'form.selfenroll_newdom'}})) { - $output .= &new_selfenroll_dom_row($env{'form.selfenroll_newdom'},$num); - $num ++; - } - } - my $add_domtitle = &mt('Additional domain:'); + my $add_domtitle = &mt('Users in additional domain:'); if ($curr_types eq '*') { - $add_domtitle = &mt('Specific domain:'); + $add_domtitle = &mt('Users in specific domain:'); } elsif ($curr_types eq '') { - $add_domtitle = &mt('Other domain:'); + $add_domtitle = &mt('Users in other domain:'); } $output .= &Apache::loncommon::start_data_table_row() .'<td colspan="2"><span class="LC_nobreak">'.$add_domtitle.'</span><br />' @@ -3331,12 +3615,134 @@ sub print_selfenroll_menu { } $output .= &Apache::lonhtmlcommon::end_pick_box(). '<br /><input type="button" name="selfenrollconf" value="' - .&mt('Save changes').'" onclick="setSections(this.form);" />' + .&mt('Save changes').'" onclick="validate_types(this.form);" />' .'<input type="hidden" name="action" value="selfenroll" /></form>'; $r->print($output); return; } +sub visible_in_cat { + my ($cdom,$cnum) = @_; + my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom); + my ($cathash,%settable,@vismsgs,$cansetvis); + my %visactions = &Apache::lonlocal::texthash( + vis => 'Your course currently appears in the Course Catalog for this domain.', + 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.', + miss => 'Your course does not currently appear in the Course Catalog for this domain.', + yous => 'You should remedy this if you plan to allow self-enrollment, otherwise students will have difficulty finding your course.', + 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.', + make => 'Make any changes to self-enrollment settings below, click "Save changes", then take action to include the course in the Catalog:', + take => 'Take the following action to ensure the course appears in the Catalog:', + dc_unhide => 'Ask a domain coordinator to change the "Exclude from course catalog" setting.', + dc_addinst => 'Ask a domain coordinator to enable display the catalog of "Official courses (with institutional codes)".', + dc_instcode => 'Ask a domain coordinator to assign an institutional code (if this is an official course).', + dc_catalog => 'Ask a domain coordinator to enable or create at least one course category in the domain.', + dc_categories => 'Ask a domain coordinator to create a hierarchy of categories and sub categories for courses in the domain.', + 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', + dc_addcat => 'Ask a domain coordinator to assign a category to the course.', + ); + $visactions{'unhide'} = &mt('Use [_1]Set course environment[_2] to change the "Exclude from course catalog" setting.','"<a href="/adm/parmset?action=crsenv">','</a>"'); + $visactions{'chgcat'} = &mt('Use [_1]Set course environment[_2] to change the category assigned to the course, as the one currently assigned is no longer used in the domain.','"<a href="/adm/parmset?action=crsenv">','</a>"'); + $visactions{'addcat'} = &mt('Use [_1]Set course environment[_2] to assign a category to the course.','"<a href="/adm/parmset?action=crsenv">','</a>"'); + if (ref($domconf{'coursecategories'}) eq 'HASH') { + if ($domconf{'coursecategories'}{'togglecats'} eq 'crs') { + $settable{'togglecats'} = 1; + } + if ($domconf{'coursecategories'}{'categorize'} eq 'crs') { + $settable{'categorize'} = 1; + } + $cathash = $domconf{'coursecategories'}{'cats'}; + } + if ($settable{'togglecats'} && $settable{'categorize'}) { + $cansetvis = &mt('You are able to both assign a course category and choose to exclude this course from the catalog.'); + } elsif ($settable{'togglecats'}) { + $cansetvis = &mt('You are able to choose to exclude this course from the catalog, but only a Domain Coordinator may assign a course category.'); + } elsif ($settable{'categorize'}) { + $cansetvis = &mt('You may assign a course category, but only a Domain Coordinator may choose to exclude this course from the catalog.'); + } else { + $cansetvis = &mt('Only a Domain Coordinator may assign a course category or choose to exclude this course from the catalog.'); + } + + my %currsettings = + &Apache::lonnet::get('environment',['hidefromcat','categories','internal.coursecode'], + $cdom,$cnum); + my $visible = 0; + if ($currsettings{'internal.coursecode'} ne '') { + if (ref($domconf{'coursecategories'}) eq 'HASH') { + $cathash = $domconf{'coursecategories'}{'cats'}; + if (ref($cathash) eq 'HASH') { + if ($cathash->{'instcode::0'} eq '') { + push(@vismsgs,'dc_addinst'); + } else { + $visible = 1; + } + } else { + $visible = 1; + } + } else { + $visible = 1; + } + } else { + if (ref($cathash) eq 'HASH') { + if ($cathash->{'instcode::0'} ne '') { + push(@vismsgs,'dc_instcode'); + } + } else { + push(@vismsgs,'dc_instcode'); + } + } + if ($currsettings{'categories'} ne '') { + my $cathash; + if (ref($domconf{'coursecategories'}) eq 'HASH') { + $cathash = $domconf{'coursecategories'}{'cats'}; + if (ref($cathash) eq 'HASH') { + if (keys(%{$cathash}) == 0) { + push(@vismsgs,'dc_catalog'); + } elsif ((keys(%{$cathash}) == 1) && ($cathash->{'instcode::0'} ne '')) { + push(@vismsgs,'dc_categories'); + } else { + my @currcategories = split('&',$currsettings{'categories'}); + my $matched = 0; + foreach my $cat (@currcategories) { + if ($cathash->{$cat} ne '') { + $visible = 1; + $matched = 1; + last; + } + } + if (!$matched) { + if ($settable{'categorize'}) { + push(@vismsgs,'chgcat'); + } else { + push(@vismsgs,'dc_chgcat'); + } + } + } + } + } + } else { + if (ref($cathash) eq 'HASH') { + if ((keys(%{$cathash}) > 1) || + (keys(%{$cathash}) == 1) && ($cathash->{'instcode::0'} eq '')) { + if ($settable{'categorize'}) { + push(@vismsgs,'addcat'); + } else { + push(@vismsgs,'dc_addcat'); + } + } + } + } + if ($currsettings{'hidefromcat'} eq 'yes') { + $visible = 0; + if ($settable{'togglecats'}) { + unshift(@vismsgs,'unhide'); + } else { + unshift(@vismsgs,'dc_unhide') + } + } + return ($visible,$cansetvis,\@vismsgs,\%visactions); +} + sub new_selfenroll_dom_row { my ($newdom,$num) = @_; my $domdesc = &Apache::lonnet::domain($newdom); @@ -3345,7 +3751,12 @@ sub new_selfenroll_dom_row { $output .= &Apache::loncommon::start_data_table_row() .'<td valign="top"><span class="LC_nobreak">'.&mt('Domain:').' <b>'.$domdesc .' ('.$newdom.')</b><input type="hidden" name="selfenroll_dom_'.$num - .'" value="'.$newdom.'" /></span></td>'; + .'" value="'.$newdom.'" /></span><br />' + .'<span class="LC_nobreak"><label><input type="checkbox" ' + .'name="selfenroll_activate" value="'.$num.'" ' + .'onchange="javascript:update_types(' + ."'selfenroll_activate','$num'".');" />' + .&mt('Activate').'</label></span></td>'; my @currinsttypes; $output .= '<td>'.&mt('User types:').'<br />' .&selfenroll_inst_types($num,$newdom,\@currinsttypes).'</td>' @@ -3362,7 +3773,7 @@ sub selfenroll_inst_types { my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($currdom); my $othervalue = 'any'; if ((ref($types) eq 'ARRAY') && (ref($usertypes) eq 'HASH')) { - if (@{$types} > 0) { + if (keys(%{$usertypes}) > 0) { $othervalue = 'other'; } $output .= '<table><tr>'; @@ -3371,13 +3782,18 @@ sub selfenroll_inst_types { $output .= '</tr><tr>'; } if (defined($usertypes->{$type})) { + my $esc_type = &escape($type); $output .= '<td><span class="LC_nobreak"><label><input type = "checkbox" value="'. - $type.'" '; + $esc_type.'" '; if (ref($currinsttypes) eq 'ARRAY') { if (@{$currinsttypes} > 0) { - if (grep(/^\Q$type\E$/,@{$currinsttypes})) { + if (grep(/^any$/,@{$currinsttypes})) { + $output .= 'checked="checked"'; + } elsif (grep(/^\Q$esc_type\E$/,@{$currinsttypes})) { $output .= 'checked="checked"'; } + } else { + $output .= 'checked="checked"'; } } $output .= ' name="selfenroll_types_'.$num.'" />'.$usertypes->{$type}.'</label></span></td>'; @@ -3387,13 +3803,21 @@ sub selfenroll_inst_types { if (($count > 0) && ($count%$numinrow == 0)) { $output .= '</tr><tr>'; } - $output .= '<td><span class="LC_nobreak"><label><input type = "checkbox" value="'.$othervalue.'" '; + $output .= '<td><span class="LC_nobreak"><label><input type = "checkbox" value="'.$othervalue.'"'; if (ref($currinsttypes) eq 'ARRAY') { if (@{$currinsttypes} > 0) { - if (grep(/^other$/,@{$currinsttypes})) { - $output .= 'checked="checked" '; + if (grep(/^any$/,@{$currinsttypes})) { + $output .= ' checked="checked"'; + } elsif ($othervalue eq 'other') { + if (grep(/^\Q$othervalue\E$/,@{$currinsttypes})) { + $output .= ' checked="checked"'; + } } + } else { + $output .= ' checked="checked"'; } + } else { + $output .= ' checked="checked"'; } $output .= ' name="selfenroll_types_'.$num.'" />'.$othertitle.'</label></span></td></tr></table>'; } @@ -3456,8 +3880,9 @@ sub print_userchangelogs_display { $curr{$key} = $defaults{$key}; } } - my (%whodunit,%changed); - $r->print(&role_display_filter($formname,$cdom,$cnum,\%curr)); + my (%whodunit,%changed,$version); + ($version) = ($r->dir_config('lonVersion') =~ /^([\d\.]+)\-/); + $r->print(&role_display_filter($formname,$cdom,$cnum,\%curr,$version)); my $showntablehdr = 0; my $tablehdr = &Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row(). @@ -3466,7 +3891,7 @@ sub print_userchangelogs_display { &mt('Context').'</th><th>'.&mt('Start').'</th><th>'.&mt('End').'</th>'. &Apache::loncommon::end_data_table_header_row(); my ($minshown,$maxshown); - my $minshown = 1; + $minshown = 1; my $count = 0; if ($curr{'show'} ne &mt('all')) { $maxshown = $curr{'page'} * $curr{'show'}; @@ -3574,7 +3999,7 @@ ENDSCRIPT } sub role_display_filter { - my ($formname,$cdom,$cnum,$curr) = @_; + my ($formname,$cdom,$cnum,$curr,$version) = @_; my $context = 'course'; my $nolink = 1; my $output = '<table><tr><td valign="top">'. @@ -3625,9 +4050,14 @@ sub role_display_filter { next if (!&Apache::lonnet::auto_run($cnum,$cdom)); } $output .= '<option value="'.$chgtype.'"'.$selstr.'>'.$lt{$chgtype}.'</option>'."\n"; - } + } $output .= '</select></td><td> </td><td valign="middle"><input type="submit" value="'. - &mt('Update Display').'" /></tr></table><hr noshade><br />'; + &mt('Update Display').'" /></tr></table>'. + '<span class="LC_roleslog_note">'. + &mt('[_1]Note:[_2] Only changes made from servers running LON-CAPA 2.6.99.0 or later are displayed.'); + if ($version) { + $output .= ' '.&mt('This server is version [_3].','<b>','</b>',$version); } + $output .= '</span><hr noshade><br />'; return $output; } @@ -4020,10 +4450,30 @@ sub build_search_response { &Apache::lonuserutils::can_create_user($env{'request.role.domain'},$context); if ($cancreate) { my $showdom = &display_domain_info($env{'request.role.domain'}); - $response .= '<br /><br />'.&mt("<b>To add a new user</b> (you can only create new users in your current role's domain - <span class=\"LC_cusr_emph\">[_1]</span>):",$env{'request.role.domain'}).'<ul><li>'.&mt("Set 'Domain/institution to search' to: <span class=\"LC_cusr_emph\">[_1]</span>",$showdom).'<li>'.&mt("Set 'Search criteria' to: <span class=\"LC_cusr_emph\">'username is ...... in selected LON-CAPA domain'").'</span></li><li>'.&mt('Provide the proposed username').'</li><li>'.&mt('Search').'</li></ul><br />'; + $response .= '<br /><br />' + .'<b>'.&mt('To add a new user:').'</b>' + .'<br />' + .&mt("(You can only create new users in your current role's domain - [_1])" + ,'<span class="LC_cusr_emph">'.$env{'request.role.domain'}.'</span>') + .'<ul><li>' + .&mt("Set 'Domain/institution to search' to: [_1]",'<span class="LC_cusr_emph">'.$showdom.'</span>') + .'</li><li>' + .&mt("Set 'Search criteria' to: [_1]username is ..... in selected LON-CAPA domain[_2]",'<span class="LC_cusr_emph">','</span>') + .'</li><li>' + .&mt('Provide the proposed username') + .'</li><li>' + .&mt("Click 'Search'") + .'</li></ul><br />'; } else { my $helplink = ' href="javascript:helpMenu('."'display'".')"'; - $response .= '<br /><br />'.&mt("You are not authorized to create new users in your current role's domain - <span class=\"LC_cusr_emph\">[_1]</span>.",$env{'request.role.domain'}).'<br />'.&mt('Contact the <a[_1]>helpdesk</a> if you need to create a new user.',$helplink).'<br /><br />'; + $response .= '<br /><br />' + .&mt("You are not authorized to create new users in your current role's domain - [_1]." + ,'<span class="LC_cusr_emph">'.$env{'request.role.domain'}.'</span>') + .'<br />' + .&mt('Contact the [_1]helpdesk[_2] if you need to create a new user.' + ,' <a'.$helplink.'>' + ,'</a>') + .'<br /><br />'; } } } @@ -4309,26 +4759,58 @@ sub update_selfenroll_config { } else { next; } - } elsif ($curr_types eq '') { - my @types = &Apache::loncommon::get_env_multiple('form.selfenroll_types_0'); - if (@types > 0) { - $changes{'internal.selfenroll_types'} = $env{'form.selfenroll_dom_0'}.':'.join(',',@types); - } } else { + my %currdoms; my @entries = split(/;/,$curr_types); - my $num = 0; - my @latesttypes; my @deletedoms = &Apache::loncommon::get_env_multiple('form.selfenroll_delete'); + my @activations = &Apache::loncommon::get_env_multiple('form.selfenroll_activate'); my $newnum = 0; - for (my $j=0; $j<$env{'form.selfenroll_types_total'}; $j++) { - if (!grep(/^$j$/,@deletedoms)) { - my @types = &Apache::loncommon::get_env_multiple('form.selfenroll_types_'.$j); + my @latesttypes; + foreach my $num (@activations) { + my @types = &Apache::loncommon::get_env_multiple('form.selfenroll_types_'.$num); + if (@types > 0) { @types = sort(@types); my $typestr = join(',',@types); - $latesttypes[$newnum] = $env{'form.selfenroll_dom_'.$j}.':'.$typestr; + my $typedom = $env{'form.selfenroll_dom_'.$num}; + $latesttypes[$newnum] = $typedom.':'.$typestr; + $currdoms{$typedom} = 1; $newnum ++; } } + for (my $j=0; $j<$env{'form.selfenroll_types_total'}; $j++) { if ((!grep(/^$j$/,@deletedoms)) && (!grep(/^$j$/,@activations))) { + my @types = &Apache::loncommon::get_env_multiple('form.selfenroll_types_'.$j); + if (@types > 0) { + @types = sort(@types); + my $typestr = join(',',@types); + my $typedom = $env{'form.selfenroll_dom_'.$j}; + $latesttypes[$newnum] = $typedom.':'.$typestr; + $currdoms{$typedom} = 1; + $newnum ++; + } + } + } + if ($env{'form.selfenroll_newdom'} ne '') { + my $typedom = $env{'form.selfenroll_newdom'}; + if ((!defined($currdoms{$typedom})) && + (&Apache::lonnet::domain($typedom) ne '')) { + my $typestr; + my ($othertitle,$usertypes,$types) = + &Apache::loncommon::sorted_inst_types($typedom); + my $othervalue = 'any'; + if ((ref($types) eq 'ARRAY') && (ref($usertypes) eq 'HASH')) { + if (@{$types} > 0) { + my @esc_types = map { &escape($_); } @{$types}; + $othervalue = 'other'; + $typestr = join(',',(@esc_types,$othervalue)); + } + $typestr = $othervalue; + } else { + $typestr = $othervalue; + } + $latesttypes[$newnum] = $typedom.':'.$typestr; + $newnum ++ ; + } + } my $selfenroll_types = join(';',@latesttypes); if ($selfenroll_types ne $curr_types) { $changes{'internal.selfenroll_types'} = $selfenroll_types; @@ -4436,14 +4918,26 @@ sub update_selfenroll_config { $r->print(&mt('An error occurred when saving changes to self-enrollment settings in this course.').'<br />'.&mt('The error was: [_1].',$putresult)); } } else { - $r->print(&mt('No changes were needed to the existing self-enrollment settings in this course.')); + $r->print(&mt('No changes were made to the existing self-enrollment settings in this course.')); } } else { - $r->print(&mt('No changes were needed to the existing self-enrollment settings in this course.')); - } - if ($env{'form.selfenroll_newdom'} ne '') { - &print_selfenroll_menu($r,$context,$permission); + $r->print(&mt('No changes were made to the existing self-enrollment settings in this course.')); } + my ($visible,$cansetvis,$vismsgs,$visactions) = &visible_in_cat($cdom,$cnum); + if (ref($visactions) eq 'HASH') { + if (!$visible) { + $r->print('<br />'.$visactions->{'miss'}.'<br />'.$visactions->{'yous'}. + '<br />'); + if (ref($vismsgs) eq 'ARRAY') { + $r->print('<br />'.$visactions->{'take'}.'<ul>'); + foreach my $item (@{$vismsgs}) { + $r->print('<li>'.$visactions->{$item}.'</li>'); + } + $r->print('</ul>'); + } + $r->print($cansetvis); + } + } return; } @@ -4453,8 +4947,8 @@ sub get_selfenroll_titles { types => 'Users allowed to self-enroll in this course', registered => 'Restrict self-enrollment to students officially registered for the course', enroll_dates => 'Dates self-enrollment available', - access_dates => 'Course access dates for self-enrolled users', - section => 'Section assigned to self-enrolled users', + access_dates => 'Course access dates assigned to self-enrolling users', + section => 'Section assigned to self-enrolling users', ); return (\@row,\%lt); }