![]() ![]() | ![]() |
- Self-enroll request approval link needed.
1: # The LearningOnline Network with CAPA 2: # Create a user 3: # 4: # $Id: loncreateuser.pm,v 1.295.2.2 2009/05/23 12:37:51 raeburn Exp $ 5: # 6: # Copyright Michigan State University Board of Trustees 7: # 8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA). 9: # 10: # LON-CAPA is free software; you can redistribute it and/or modify 11: # it under the terms of the GNU General Public License as published by 12: # the Free Software Foundation; either version 2 of the License, or 13: # (at your option) any later version. 14: # 15: # LON-CAPA is distributed in the hope that it will be useful, 16: # but WITHOUT ANY WARRANTY; without even the implied warranty of 17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18: # GNU General Public License for more details. 19: # 20: # You should have received a copy of the GNU General Public License 21: # along with LON-CAPA; if not, write to the Free Software 22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23: # 24: # /home/httpd/html/adm/gpl.txt 25: # 26: # http://www.lon-capa.org/ 27: # 28: ### 29: 30: package Apache::loncreateuser; 31: 32: =pod 33: 34: =head1 NAME 35: 36: Apache::loncreateuser.pm 37: 38: =head1 SYNOPSIS 39: 40: Handler to create users and custom roles 41: 42: Provides an Apache handler for creating users, 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: 54: Creating custom roles can be done by the Domain Coordinator through 55: the Create User functionality. That screen will show all privileges 56: that can be assigned to users. For a complete list of privileges, 57: please see C</home/httpd/lonTabs/rolesplain.tab>. 58: 59: Custom role definitions are stored in the C<roles.db> file of the role 60: author. 61: 62: =cut 63: 64: use strict; 65: use Apache::Constants qw(:common :http); 66: use Apache::lonnet; 67: use Apache::loncommon; 68: use Apache::lonlocal; 69: use Apache::longroup; 70: use Apache::lonuserutils; 71: use Apache::selfenroll(); 72: use LONCAPA qw(:DEFAULT :match); 73: 74: my $loginscript; # piece of javascript used in two separate instances 75: my $authformnop; 76: my $authformkrb; 77: my $authformint; 78: my $authformfsys; 79: my $authformloc; 80: 81: sub initialize_authen_forms { 82: my ($dom,$formname,$curr_authtype,$mode) = @_; 83: my ($krbdef,$krbdefdom) = &Apache::loncommon::get_kerberos_defaults($dom); 84: my %param = ( formname => $formname, 85: kerb_def_dom => $krbdefdom, 86: kerb_def_auth => $krbdef, 87: domain => $dom, 88: ); 89: my %abv_auth = &auth_abbrev(); 90: if ($curr_authtype =~ /^(krb4|krb5|internal|localauth|unix):(.*)$/) { 91: my $long_auth = $1; 92: my $curr_autharg = $2; 93: my %abv_auth = &auth_abbrev(); 94: $param{'curr_authtype'} = $abv_auth{$long_auth}; 95: if ($long_auth =~ /^krb(4|5)$/) { 96: $param{'curr_kerb_ver'} = $1; 97: $param{'curr_autharg'} = $curr_autharg; 98: } 99: if ($mode eq 'modifyuser') { 100: $param{'mode'} = $mode; 101: } 102: } 103: $loginscript = &Apache::loncommon::authform_header(%param); 104: $authformkrb = &Apache::loncommon::authform_kerberos(%param); 105: $authformnop = &Apache::loncommon::authform_nochange(%param); 106: $authformint = &Apache::loncommon::authform_internal(%param); 107: $authformfsys = &Apache::loncommon::authform_filesystem(%param); 108: $authformloc = &Apache::loncommon::authform_local(%param); 109: } 110: 111: sub auth_abbrev { 112: my %abv_auth = ( 113: krb4 => 'krb', 114: internal => 'int', 115: localuth => 'loc', 116: unix => 'fsys', 117: ); 118: return %abv_auth; 119: } 120: 121: # ==================================================== 122: 123: sub portfolio_quota { 124: my ($ccuname,$ccdomain) = @_; 125: my %lt = &Apache::lonlocal::texthash( 126: 'usrt' => "User Tools", 127: 'disk' => "Disk space allocated to user's portfolio files", 128: 'cuqu' => "Current quota", 129: 'cust' => "Custom quota", 130: 'defa' => "Default", 131: 'chqu' => "Change quota", 132: ); 133: my ($currquota,$quotatype,$inststatus,$defquota) = 134: &Apache::loncommon::get_user_quota($ccuname,$ccdomain); 135: my ($usertypes,$order) = &Apache::lonnet::retrieve_inst_usertypes($ccdomain); 136: my ($longinsttype,$showquota,$custom_on,$custom_off,$defaultinfo); 137: if ($inststatus ne '') { 138: if ($usertypes->{$inststatus} ne '') { 139: $longinsttype = $usertypes->{$inststatus}; 140: } 141: } 142: $custom_on = ' '; 143: $custom_off = ' checked="checked" '; 144: my $quota_javascript = <<"END_SCRIPT"; 145: <script type="text/javascript"> 146: function quota_changes(caller) { 147: if (caller == "custom") { 148: if (document.cu.customquota[0].checked) { 149: document.cu.portfolioquota.value = ""; 150: } 151: } 152: if (caller == "quota") { 153: document.cu.customquota[1].checked = true; 154: } 155: } 156: </script> 157: END_SCRIPT 158: if ($quotatype eq 'custom') { 159: $custom_on = $custom_off; 160: $custom_off = ' '; 161: $showquota = $currquota; 162: if ($longinsttype eq '') { 163: $defaultinfo = &mt('For this user, the default quota would be [_1]' 164: .' Mb.',$defquota); 165: } else { 166: $defaultinfo = &mt("For this user, the default quota would be [_1]". 167: " Mb, as determined by the user's institutional". 168: " affiliation ([_2]).",$defquota,$longinsttype); 169: } 170: } else { 171: if ($longinsttype eq '') { 172: $defaultinfo = &mt('For this user, the default quota is [_1]' 173: .' Mb.',$defquota); 174: } else { 175: $defaultinfo = &mt("For this user, the default quota of [_1]". 176: " Mb, is determined by the user's institutional". 177: " affiliation ([_2]).",$defquota,$longinsttype); 178: } 179: } 180: 181: my $output = $quota_javascript."\n". 182: '<h3>'.$lt{'usrt'}.'</h3>'."\n". 183: &Apache::loncommon::start_data_table(); 184: 185: if (&Apache::lonnet::allowed('mut',$ccdomain)) { 186: $output .= &build_tools_display($ccuname,$ccdomain,'tools'); 187: } 188: if (&Apache::lonnet::allowed('mpq',$ccdomain)) { 189: $output .= '<tr class="LC_info_row">'."\n". 190: ' <td>'.$lt{'disk'}.'</td>'."\n". 191: ' </tr>'."\n". 192: &Apache::loncommon::start_data_table_row()."\n". 193: ' <td>'.$lt{'cuqu'}.': '. 194: $currquota.' Mb. '. 195: $defaultinfo.'</td>'."\n". 196: &Apache::loncommon::end_data_table_row()."\n". 197: &Apache::loncommon::start_data_table_row()."\n". 198: ' <td><span class="LC_nobreak">'.$lt{'chqu'}. 199: ': <label>'. 200: '<input type="radio" name="customquota" value="0" '. 201: $custom_off.' onchange="javascript:quota_changes('."'custom'".')"'. 202: ' />'.$lt{'defa'}.' ('.$defquota.' Mb).</label> '. 203: ' <label><input type="radio" name="customquota" value="1" '. 204: $custom_on.' onchange="javascript:quota_changes('."'custom'".')" />'. 205: $lt{'cust'}.':</label> '. 206: '<input type="text" name="portfolioquota" size ="5" value="'. 207: $showquota.'" onfocus="javascript:quota_changes('."'quota'".')" '. 208: '/> Mb</span></td>'."\n". 209: &Apache::loncommon::end_data_table_row()."\n"; 210: } 211: $output .= &Apache::loncommon::end_data_table(); 212: return $output; 213: } 214: 215: sub build_tools_display { 216: my ($ccuname,$ccdomain,$context) = @_; 217: my (@usertools,%userenv,$output); 218: my %lt = &Apache::lonlocal::texthash ( 219: 'blog' => "Personal User Blog", 220: 'aboutme' => "Personal Information Page", 221: 'portfolio' => "Personal User Portfolio", 222: 'avai' => "Available", 223: 'cusa' => "availability", 224: 'chse' => "Change setting", 225: 'usde' => "Use default", 226: 'uscu' => "Use custom", 227: 'official' => 'Can request creation of official courses', 228: 'unofficial' => 'Can request creation of unofficial courses', 229: ); 230: if ($context eq 'requestcourses') { 231: %userenv = &Apache::lonnet::userenvironment($ccdomain,$ccuname, 232: 'requestcourses.official','requestcourses.unofficial'); 233: @usertools = ('official','unofficial'); 234: } else { 235: %userenv = &Apache::lonnet::userenvironment($ccdomain,$ccuname, 236: 'tools.aboutme','tools.portfolio','tools.blog'); 237: @usertools = ('aboutme','blog','portfolio'); 238: } 239: foreach my $item (@usertools) { 240: my ($custom_access,$curr_access,$cust_on,$cust_off,$tool_on,$tool_off); 241: $cust_off = 'checked="checked" '; 242: $tool_on = 'checked="checked" '; 243: $curr_access = 244: &Apache::lonnet::usertools_access($ccuname,$ccdomain,$item,undef, 245: $context); 246: if ($userenv{$context.'.'.$item} eq '') { 247: $custom_access = 'default'; 248: if (!$curr_access) { 249: $tool_off = 'checked="checked" '; 250: $tool_on = ''; 251: } 252: } else { 253: $custom_access = 'custom'; 254: $cust_on = ' checked="checked" '; 255: $cust_off = ''; 256: if ($userenv{$context.'.'.$item} == 0) { 257: $tool_off = 'checked="checked" '; 258: $tool_on = ''; 259: } 260: } 261: $output .= ' <tr class="LC_info_row">'."\n". 262: ' <td>'.$lt{$item}.'</td>'."\n". 263: ' </tr>'."\n". 264: &Apache::loncommon::start_data_table_row()."\n". 265: ' <td>'.&mt('Availability determined currently from [_1] setting.',$custom_access). 266: ' '.$lt{'avai'}.': '. 267: ($curr_access?&mt('Yes'):&mt('No')).'</td>'."\n". 268: &Apache::loncommon::end_data_table_row()."\n". 269: &Apache::loncommon::start_data_table_row()."\n". 270: ' <td><span class="LC_nobreak">'.$lt{'chse'}.': <label>'. 271: '<input type="radio" name="custom'.$item.'" value="0" '. 272: $cust_off.'/>'.$lt{'usde'}.'</label> '. 273: '<label><input type="radio" name="custom'.$item.'" value="1" '. 274: $cust_on.'/>'.$lt{'uscu'}.'</label> -- '. 275: $lt{'cusa'}.': <label>'. 276: '<input type="radio" name="'.$context.'_'.$item.'" value="1" '. 277: $tool_on.'/>'.&mt('On').'</label> <label>'. 278: '<input type="radio" name="'.$context.'_'.$item.'" value="0" '. 279: $tool_off.'/>'.&mt('Off').'</label></span></td>'."\n". 280: &Apache::loncommon::end_data_table_row()."\n"; 281: } 282: return $output; 283: } 284: 285: # =================================================================== Phase one 286: 287: sub print_username_entry_form { 288: my ($r,$context,$response,$srch,$forcenewuser) = @_; 289: my $defdom=$env{'request.role.domain'}; 290: my $formtoset = 'crtuser'; 291: if (exists($env{'form.startrolename'})) { 292: $formtoset = 'docustom'; 293: $env{'form.rolename'} = $env{'form.startrolename'}; 294: } elsif ($env{'form.origform'} eq 'crtusername') { 295: $formtoset = $env{'form.origform'}; 296: } 297: 298: my ($jsback,$elements) = &crumb_utilities(); 299: 300: my $jscript = &Apache::loncommon::studentbrowser_javascript()."\n". 301: '<script type="text/javascript">'."\n". 302: &Apache::lonhtmlcommon::set_form_elements($elements->{$formtoset}). 303: '</script>'."\n"; 304: 305: my %loaditems = ( 306: 'onload' => "javascript:setFormElements(document.$formtoset)", 307: ); 308: my %breadcrumb_text = &singleuser_breadcrumb(); 309: my $start_page = 310: &Apache::loncommon::start_page('User Management', 311: $jscript,{'add_entries' => \%loaditems,}); 312: if ($env{'form.action'} eq 'custom') { 313: &Apache::lonhtmlcommon::add_breadcrumb 314: ({href=>"javascript:backPage(document.crtuser)", 315: text=>"Pick custom role",}); 316: } else { 317: &Apache::lonhtmlcommon::add_breadcrumb 318: ({href=>"javascript:backPage(document.crtuser)", 319: text=>$breadcrumb_text{'search'}, 320: faq=>282,bug=>'Instructor Interface',}); 321: } 322: my $helpitem = 'Course_Change_Privileges'; 323: if ($env{'form.action'} eq 'custom') { 324: $helpitem = 'Course_Editing_Custom_Roles'; 325: } elsif ($env{'form.action'} eq 'singlestudent') { 326: $helpitem = 'Course_Add_Student'; 327: } 328: my $crumbs = &Apache::lonhtmlcommon::breadcrumbs('User Management', 329: $helpitem); 330: my %existingroles=&Apache::lonuserutils::my_custom_roles(); 331: my $choice=&Apache::loncommon::select_form('make new role','rolename', 332: ('make new role' => 'Generate new role ...',%existingroles)); 333: my %lt=&Apache::lonlocal::texthash( 334: 'srst' => 'Search for a user and enroll as a student', 335: 'srad' => 'Search for a user and modify/add user information or roles', 336: 'usr' => "Username", 337: 'dom' => "Domain", 338: 'ecrp' => "Edit Custom Role Privileges", 339: 'nr' => "Name of Role", 340: 'cre' => "Next", 341: ); 342: $r->print($start_page."\n".$crumbs); 343: if ($env{'form.action'} eq 'custom') { 344: if (&Apache::lonnet::allowed('mcr','/')) { 345: $r->print(<<ENDCUSTOM); 346: <form action="/adm/createuser" method="post" name="docustom"> 347: <input type="hidden" name="action" value="$env{'form.action'}" /> 348: <input type="hidden" name="phase" value="selected_custom_edit" /> 349: <h3>$lt{'ecrp'}</h3> 350: $choice $lt{'nr'}: <input type="text" size="15" name="newrolename" /><br /> 351: <input name="customeditor" type="submit" value="$lt{'cre'}" /> 352: </form> 353: ENDCUSTOM 354: } 355: } else { 356: my $actiontext = $lt{'srad'}; 357: if ($env{'form.action'} eq 'singlestudent') { 358: $actiontext = $lt{'srst'}; 359: } 360: $r->print(" 361: <h3>$actiontext</h3>"); 362: if ($env{'form.origform'} ne 'crtusername') { 363: $r->print("\n".$response); 364: } 365: $r->print(&entry_form($defdom,$srch,$forcenewuser,$context,$response)); 366: } 367: $r->print(&Apache::loncommon::end_page()); 368: } 369: 370: sub entry_form { 371: my ($dom,$srch,$forcenewuser,$context,$responsemsg) = @_; 372: my %domconf = &Apache::lonnet::get_dom('configuration',['usercreation'],$dom); 373: my ($usertype,$inexact); 374: if (ref($srch) eq 'HASH') { 375: if (($srch->{'srchin'} eq 'dom') && 376: ($srch->{'srchby'} eq 'uname') && 377: ($srch->{'srchtype'} eq 'exact') && 378: ($srch->{'srchdomain'} ne '') && 379: ($srch->{'srchterm'} ne '')) { 380: my ($rules,$ruleorder) = 381: &Apache::lonnet::inst_userrules($srch->{'srchdomain'},'username'); 382: $usertype = &Apache::lonuserutils::check_usertype($srch->{'srchdomain'},$srch->{'srchterm'},$rules); 383: } else { 384: $inexact = 1; 385: } 386: } 387: my $cancreate = 388: &Apache::lonuserutils::can_create_user($dom,$context,$usertype); 389: my $userpicker = 390: &Apache::loncommon::user_picker($dom,$srch,$forcenewuser, 391: 'document.crtuser',$cancreate,$usertype); 392: my $srchbutton = &mt('Search'); 393: if ($env{'form.action'} eq 'singlestudent') { 394: $srchbutton = &mt('Search and Enroll'); 395: } elsif ($cancreate && $responsemsg ne '' && $inexact) { 396: $srchbutton = &mt('Search or Add New User'); 397: } 398: my $output = <<"ENDBLOCK"; 399: <form action="/adm/createuser" method="post" name="crtuser"> 400: <input type="hidden" name="action" value="$env{'form.action'}" /> 401: <input type="hidden" name="phase" value="get_user_info" /> 402: $userpicker 403: <input name="userrole" type="button" value="$srchbutton" onclick="javascript:validateEntry(document.crtuser)" /> 404: </form> 405: ENDBLOCK 406: if ($env{'form.phase'} eq '') { 407: my $defdom=$env{'request.role.domain'}; 408: my $domform = &Apache::loncommon::select_dom_form($defdom,'srchdomain'); 409: my %lt=&Apache::lonlocal::texthash( 410: 'enro' => 'Enroll one student', 411: 'admo' => 'Add/modify a single user', 412: 'crea' => 'create new user if required', 413: 'uskn' => "username is known", 414: 'crnu' => 'Create a new user', 415: 'usr' => 'Username', 416: 'dom' => 'in domain', 417: 'enrl' => 'Enroll', 418: 'cram' => 'Create/Modify user', 419: ); 420: my $sellink=&Apache::loncommon::selectstudent_link('crtusername','srchterm','srchdomain'); 421: my ($title,$buttontext,$showresponse); 422: if ($env{'form.action'} eq 'singlestudent') { 423: $title = $lt{'enro'}; 424: $buttontext = $lt{'enrl'}; 425: } else { 426: $title = $lt{'admo'}; 427: $buttontext = $lt{'cram'}; 428: } 429: if ($cancreate) { 430: $title .= ' <span class="LC_cusr_subheading">('.$lt{'crea'}.')</span>'; 431: } else { 432: $title .= ' <span class="LC_cusr_subheading">('.$lt{'uskn'}.')</span>'; 433: } 434: if ($env{'form.origform'} eq 'crtusername') { 435: $showresponse = $responsemsg; 436: } 437: $output .= <<"ENDDOCUMENT"; 438: <br /> 439: <form action="/adm/createuser" method="post" name="crtusername"> 440: <input type="hidden" name="action" value="$env{'form.action'}" /> 441: <input type="hidden" name="phase" value="createnewuser" /> 442: <input type="hidden" name="srchtype" value="exact" /> 443: <input type="hidden" name="srchby" value="uname" /> 444: <input type="hidden" name="srchin" value="dom" /> 445: <input type="hidden" name="forcenewuser" value="1" /> 446: <input type="hidden" name="origform" value="crtusername" /> 447: <h3>$title</h3> 448: $showresponse 449: <table> 450: <tr> 451: <td>$lt{'usr'}:</td> 452: <td><input type="text" size="15" name="srchterm" /></td> 453: <td> $lt{'dom'}:</td><td>$domform</td> 454: <td> $sellink </td> 455: <td> <input name="userrole" type="submit" value="$buttontext" /></td> 456: </tr> 457: </table> 458: </form> 459: ENDDOCUMENT 460: } 461: return $output; 462: } 463: 464: sub user_modification_js { 465: my ($pjump_def,$dc_setcourse_code,$nondc_setsection_code,$groupslist)=@_; 466: 467: return <<END; 468: <script type="text/javascript" language="Javascript"> 469: 470: function pclose() { 471: parmwin=window.open("/adm/rat/empty.html","LONCAPAparms", 472: "height=350,width=350,scrollbars=no,menubar=no"); 473: parmwin.close(); 474: } 475: 476: $pjump_def 477: $dc_setcourse_code 478: 479: function dateset() { 480: eval("document.cu."+document.cu.pres_marker.value+ 481: ".value=document.cu.pres_value.value"); 482: pclose(); 483: } 484: 485: $nondc_setsection_code 486: 487: </script> 488: END 489: } 490: 491: # =================================================================== Phase two 492: sub print_user_selection_page { 493: my ($r,$response,$srch,$srch_results,$srcharray,$context) = @_; 494: my @fields = ('username','domain','lastname','firstname','permanentemail'); 495: my $sortby = $env{'form.sortby'}; 496: 497: if (!grep(/^\Q$sortby\E$/,@fields)) { 498: $sortby = 'lastname'; 499: } 500: 501: my ($jsback,$elements) = &crumb_utilities(); 502: 503: my $jscript = (<<ENDSCRIPT); 504: <script type="text/javascript"> 505: function pickuser(uname,udom) { 506: document.usersrchform.seluname.value=uname; 507: document.usersrchform.seludom.value=udom; 508: document.usersrchform.phase.value="userpicked"; 509: document.usersrchform.submit(); 510: } 511: 512: $jsback 513: </script> 514: ENDSCRIPT 515: 516: my %lt=&Apache::lonlocal::texthash( 517: 'usrch' => "User Search to add/modify roles", 518: 'stusrch' => "User Search to enroll student", 519: 'usel' => "Select a user to add/modify roles", 520: 'stusel' => "Select a user to enroll as a student", 521: 'username' => "username", 522: 'domain' => "domain", 523: 'lastname' => "last name", 524: 'firstname' => "first name", 525: 'permanentemail' => "permanent e-mail", 526: ); 527: $r->print(&Apache::loncommon::start_page('User Management',$jscript)); 528: 529: my %breadcrumb_text = &singleuser_breadcrumb(); 530: &Apache::lonhtmlcommon::add_breadcrumb 531: ({href=>"javascript:backPage(document.usersrchform,'','')", 532: text=>$breadcrumb_text{'search'}, 533: faq=>282,bug=>'Instructor Interface',}, 534: {href=>"javascript:backPage(document.usersrchform,'get_user_info','select')", 535: text=>$breadcrumb_text{'userpicked'}, 536: faq=>282,bug=>'Instructor Interface',}); 537: if ($env{'form.action'} eq 'singleuser') { 538: $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management', 539: 'Course_Change_Privileges')); 540: $r->print("<b>$lt{'usrch'}</b><br />"); 541: $r->print(&entry_form($srch->{'srchdomain'},$srch,undef,$context)); 542: $r->print('<h3>'.$lt{'usel'}.'</h3>'); 543: } elsif ($env{'form.action'} eq 'singlestudent') { 544: $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management', 545: 'Course_Add_Student')); 546: $r->print($jscript."<b>$lt{'stusrch'}</b><br />"); 547: $r->print(&entry_form($srch->{'srchdomain'},$srch,undef,$context)); 548: $r->print('</form><h3>'.$lt{'stusel'}.'</h3>'); 549: } 550: $r->print('<form name="usersrchform" method="post">'. 551: &Apache::loncommon::start_data_table()."\n". 552: &Apache::loncommon::start_data_table_header_row()."\n". 553: ' <th> </th>'."\n"); 554: foreach my $field (@fields) { 555: $r->print(' <th><a href="javascript:document.usersrchform.sortby.value='. 556: "'".$field."'".';document.usersrchform.submit();">'. 557: $lt{$field}.'</a></th>'."\n"); 558: } 559: $r->print(&Apache::loncommon::end_data_table_header_row()); 560: 561: my @sorted_users = sort { 562: lc($srch_results->{$a}->{$sortby}) cmp lc($srch_results->{$b}->{$sortby}) 563: || 564: lc($srch_results->{$a}->{lastname}) cmp lc($srch_results->{$b}->{lastname}) 565: || 566: lc($srch_results->{$a}->{firstname}) cmp lc($srch_results->{$b}->{firstname}) 567: || 568: lc($a) cmp lc($b) 569: } (keys(%$srch_results)); 570: 571: foreach my $user (@sorted_users) { 572: my ($uname,$udom) = split(/:/,$user); 573: $r->print(&Apache::loncommon::start_data_table_row(). 574: '<td><input type="button" name="seluser" value="'.&mt('Select').'" onclick="javascript:pickuser('."'".$uname."'".','."'".$udom."'".')" /></td>'. 575: '<td><tt>'.$uname.'</tt></td>'. 576: '<td><tt>'.$udom.'</tt></td>'); 577: foreach my $field ('lastname','firstname','permanentemail') { 578: $r->print('<td>'.$srch_results->{$user}->{$field}.'</td>'); 579: } 580: $r->print(&Apache::loncommon::end_data_table_row()); 581: } 582: $r->print(&Apache::loncommon::end_data_table().'<br /><br />'); 583: if (ref($srcharray) eq 'ARRAY') { 584: foreach my $item (@{$srcharray}) { 585: $r->print('<input type="hidden" name="'.$item.'" value="'.$env{'form.'.$item}.'" />'."\n"); 586: } 587: } 588: $r->print(' <input type="hidden" name="sortby" value="'.$sortby.'" />'."\n". 589: ' <input type="hidden" name="seluname" value="" />'."\n". 590: ' <input type="hidden" name="seludom" value="" />'."\n". 591: ' <input type="hidden" name="currstate" value="select" />'."\n". 592: ' <input type="hidden" name="phase" value="get_user_info" />'."\n". 593: ' <input type="hidden" name="action" value="'.$env{'form.action'}.'" />'."\n"); 594: $r->print($response.'</form>'.&Apache::loncommon::end_page()); 595: } 596: 597: sub print_user_query_page { 598: my ($r,$caller) = @_; 599: # FIXME - this is for a network-wide name search (similar to catalog search) 600: # To use frames with similar behavior to catalog/portfolio search. 601: # To be implemented. 602: return; 603: } 604: 605: sub print_user_modification_page { 606: my ($r,$ccuname,$ccdomain,$srch,$response,$context,$permission) = @_; 607: if (($ccuname eq '') || ($ccdomain eq '')) { 608: my $usermsg = &mt('No username and/or domain provided.'); 609: $env{'form.phase'} = ''; 610: &print_username_entry_form($r,$context,$usermsg); 611: return; 612: } 613: my ($form,$formname); 614: if ($env{'form.action'} eq 'singlestudent') { 615: $form = 'document.enrollstudent'; 616: $formname = 'enrollstudent'; 617: } else { 618: $form = 'document.cu'; 619: $formname = 'cu'; 620: } 621: my %abv_auth = &auth_abbrev(); 622: my (%rulematch,%inst_results,$newuser,%alerts,%curr_rules,%got_rules); 623: my $uhome=&Apache::lonnet::homeserver($ccuname,$ccdomain); 624: if ($uhome eq 'no_host') { 625: my $usertype; 626: my ($rules,$ruleorder) = 627: &Apache::lonnet::inst_userrules($ccdomain,'username'); 628: $usertype = 629: &Apache::lonuserutils::check_usertype($ccdomain,$ccuname,$rules); 630: my $cancreate = 631: &Apache::lonuserutils::can_create_user($ccdomain,$context, 632: $usertype); 633: if (!$cancreate) { 634: my $helplink = 'javascript:helpMenu('."'display'".')'; 635: my %usertypetext = ( 636: official => 'institutional', 637: unofficial => 'non-institutional', 638: ); 639: my $response; 640: if ($env{'form.origform'} eq 'crtusername') { 641: $response = '<span class="LC_warning">'.&mt('No match was found for the username ([_1]) in LON-CAPA domain: [_2]',$ccuname,$ccdomain). 642: '</span><br />'; 643: } 644: $response .= '<p class="LC_warning">' 645: .&mt("You are not authorized to create new $usertypetext{$usertype} users in this domain.") 646: .' ' 647: .&mt('Please contact the [_1]helpdesk[_2] for assistance.' 648: ,'<a href="'.$helplink.'">','</a>') 649: .'</p><br />'; 650: $env{'form.phase'} = ''; 651: &print_username_entry_form($r,$context,$response); 652: return; 653: } 654: $newuser = 1; 655: my $checkhash; 656: my $checks = { 'username' => 1 }; 657: $checkhash->{$ccuname.':'.$ccdomain} = { 'newuser' => $newuser }; 658: &Apache::loncommon::user_rule_check($checkhash,$checks, 659: \%alerts,\%rulematch,\%inst_results,\%curr_rules,\%got_rules); 660: if (ref($alerts{'username'}) eq 'HASH') { 661: if (ref($alerts{'username'}{$ccdomain}) eq 'HASH') { 662: my $domdesc = 663: &Apache::lonnet::domain($ccdomain,'description'); 664: if ($alerts{'username'}{$ccdomain}{$ccuname}) { 665: my $userchkmsg; 666: if (ref($curr_rules{$ccdomain}) eq 'HASH') { 667: $userchkmsg = 668: &Apache::loncommon::instrule_disallow_msg('username', 669: $domdesc,1). 670: &Apache::loncommon::user_rule_formats($ccdomain, 671: $domdesc,$curr_rules{$ccdomain}{'username'}, 672: 'username'); 673: } 674: $env{'form.phase'} = ''; 675: &print_username_entry_form($r,$context,$userchkmsg); 676: return; 677: } 678: } 679: } 680: } else { 681: $newuser = 0; 682: } 683: if ($response) { 684: $response = '<br />'.$response; 685: } 686: 687: my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition(); 688: my $dc_setcourse_code = ''; 689: my $nondc_setsection_code = ''; 690: my %loaditem; 691: 692: my $groupslist = &Apache::lonuserutils::get_groupslist(); 693: 694: my $js = &validation_javascript($context,$ccdomain,$pjump_def, 695: $groupslist,$newuser,$formname,\%loaditem); 696: my $args = {'add_entries' => \%loaditem}; 697: if ($env{'form.popup'}) { 698: $args->{'no_nav_bar'} = 1; 699: } 700: my $start_page = 701: &Apache::loncommon::start_page('User Management',$js,$args); 702: my %breadcrumb_text = &singleuser_breadcrumb(); 703: &Apache::lonhtmlcommon::add_breadcrumb 704: ({href=>"javascript:backPage($form)", 705: text=>$breadcrumb_text{'search'}, 706: faq=>282,bug=>'Instructor Interface',}); 707: 708: if ($env{'form.phase'} eq 'userpicked') { 709: &Apache::lonhtmlcommon::add_breadcrumb 710: ({href=>"javascript:backPage($form,'get_user_info','select')", 711: text=>$breadcrumb_text{'userpicked'}, 712: faq=>282,bug=>'Instructor Interface',}); 713: } 714: &Apache::lonhtmlcommon::add_breadcrumb 715: ({href=>"javascript:backPage($form,'$env{'form.phase'}','modify')", 716: text=>$breadcrumb_text{'modify'}, 717: faq=>282,bug=>'Instructor Interface',}); 718: my $helpitem = 'Course_Change_Privileges'; 719: if ($env{'form.action'} eq 'singlestudent') { 720: $helpitem = 'Course_Add_Student'; 721: } 722: my $crumbs = &Apache::lonhtmlcommon::breadcrumbs('User Management', 723: $helpitem); 724: 725: my $forminfo =<<"ENDFORMINFO"; 726: <form action="/adm/createuser" method="post" name="$formname"> 727: <input type="hidden" name="phase" value="update_user_data" /> 728: <input type="hidden" name="ccuname" value="$ccuname" /> 729: <input type="hidden" name="ccdomain" value="$ccdomain" /> 730: <input type="hidden" name="pres_value" value="" /> 731: <input type="hidden" name="pres_type" value="" /> 732: <input type="hidden" name="pres_marker" value="" /> 733: ENDFORMINFO 734: my %inccourses; 735: foreach my $key (keys(%env)) { 736: if ($key=~/^user\.priv\.cm\.\/($match_domain)\/($match_username)/) { 737: $inccourses{$1.'_'.$2}=1; 738: } 739: } 740: if ($newuser) { 741: my $portfolioform; 742: if ((&Apache::lonnet::allowed('mpq',$env{'request.role.domain'})) || 743: (&Apache::lonnet::allowed('mut',$env{'request.role.domain'}))) { 744: # Current user has quota or user tools modification privileges 745: $portfolioform = '<br />'.&portfolio_quota($ccuname,$ccdomain); 746: } 747: &initialize_authen_forms($ccdomain,$formname); 748: my %lt=&Apache::lonlocal::texthash( 749: 'cnu' => 'Create New User', 750: 'ast' => 'as a student', 751: 'ind' => 'in domain', 752: 'lg' => 'Login Data', 753: 'hs' => "Home Server", 754: ); 755: $r->print(<<ENDTITLE); 756: $start_page 757: $crumbs 758: $response 759: $forminfo 760: <script type="text/javascript" language="Javascript"> 761: $loginscript 762: </script> 763: <input type='hidden' name='makeuser' value='1' /> 764: <h2>$lt{'cnu'} "$ccuname" $lt{'ind'} $ccdomain 765: ENDTITLE 766: if ($env{'form.action'} eq 'singlestudent') { 767: $r->print(' ('.$lt{'ast'}.')'); 768: } 769: $r->print('</h2>'."\n".'<div class="LC_left_float">'); 770: my $personal_table = 771: &personal_data_display($ccuname,$ccdomain,$newuser,$context, 772: $inst_results{$ccuname.':'.$ccdomain}); 773: $r->print($personal_table); 774: my ($home_server_pick,$numlib) = 775: &Apache::loncommon::home_server_form_item($ccdomain,'hserver', 776: 'default','hide'); 777: if ($numlib > 1) { 778: $r->print(" 779: <br /> 780: $lt{'hs'}: $home_server_pick 781: <br />"); 782: } else { 783: $r->print($home_server_pick); 784: } 785: $r->print('</div>'."\n".'<div class="LC_left_float"><h3>'. 786: $lt{'lg'}.'</h3>'); 787: my ($fixedauth,$varauth,$authmsg); 788: if (ref($rulematch{$ccuname.':'.$ccdomain}) eq 'HASH') { 789: my $matchedrule = $rulematch{$ccuname.':'.$ccdomain}{'username'}; 790: my ($rules,$ruleorder) = 791: &Apache::lonnet::inst_userrules($ccdomain,'username'); 792: if (ref($rules) eq 'HASH') { 793: if (ref($rules->{$matchedrule}) eq 'HASH') { 794: my $authtype = $rules->{$matchedrule}{'authtype'}; 795: if ($authtype !~ /^(krb4|krb5|int|fsys|loc)$/) { 796: $r->print(&Apache::lonuserutils::set_login($ccdomain,$authformkrb,$authformint,$authformloc)); 797: } else { 798: my $authparm = $rules->{$matchedrule}{'authparm'}; 799: $authmsg = $rules->{$matchedrule}{'authmsg'}; 800: if ($authtype =~ /^krb(4|5)$/) { 801: my $ver = $1; 802: if ($authparm ne '') { 803: $fixedauth = <<"KERB"; 804: <input type="hidden" name="login" value="krb" /> 805: <input type="hidden" name="krbver" value="$ver" /> 806: <input type="hidden" name="krbarg" value="$authparm" /> 807: KERB 808: } 809: } else { 810: $fixedauth = 811: '<input type="hidden" name="login" value="'.$authtype.'" />'."\n"; 812: if ($rules->{$matchedrule}{'authparmfixed'}) { 813: $fixedauth .= 814: '<input type="hidden" name="'.$authtype.'arg" value="'.$authparm.'" />'."\n"; 815: } else { 816: if ($authtype eq 'int') { 817: $varauth = '<br />'. 818: &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>'; 819: } elsif ($authtype eq 'loc') { 820: $varauth = '<br />'. 821: &mt('[_1] Local Authentication with argument [_2]','','<input type="text" name="'.$authtype.'arg" value="" />')."\n"; 822: } else { 823: $varauth = 824: '<input type="text" name="'.$authtype.'arg" value="" />'."\n"; 825: } 826: } 827: } 828: } 829: } else { 830: $r->print(&Apache::lonuserutils::set_login($ccdomain,$authformkrb,$authformint,$authformloc)); 831: } 832: } 833: if ($authmsg) { 834: $r->print(<<ENDAUTH); 835: $fixedauth 836: $authmsg 837: $varauth 838: ENDAUTH 839: } 840: } else { 841: $r->print(&Apache::lonuserutils::set_login($ccdomain,$authformkrb,$authformint,$authformloc)); 842: } 843: $r->print($portfolioform); 844: if ($env{'form.action'} eq 'singlestudent') { 845: $r->print(&date_sections_select($context,$newuser,$formname, 846: $permission)); 847: } 848: $r->print('</div><div class="LC_clear_float_footer"></div>'); 849: } else { # user already exists 850: my %lt=&Apache::lonlocal::texthash( 851: 'cup' => "Modify existing user: ", 852: 'ens' => "Enroll one student: ", 853: 'id' => "in domain", 854: ); 855: $r->print(<<ENDCHANGEUSER); 856: $start_page 857: $crumbs 858: $forminfo 859: <h2> 860: ENDCHANGEUSER 861: if ($env{'form.action'} eq 'singlestudent') { 862: $r->print($lt{'ens'}); 863: } else { 864: $r->print($lt{'cup'}); 865: } 866: $r->print(' "'.$ccuname.'" '.$lt{'id'}.' "'.$ccdomain.'"</h2>'. 867: "\n".'<div class="LC_left_float">'); 868: my ($personal_table,$showforceid) = 869: &personal_data_display($ccuname,$ccdomain,$newuser,$context, 870: $inst_results{$ccuname.':'.$ccdomain}); 871: $r->print($personal_table); 872: if ($showforceid) { 873: $r->print(&Apache::lonuserutils::forceid_change($context)); 874: } 875: if (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'})) { 876: $r->print('<h3>'.&mt('User Can Request Creation of Courses?').'</h3>'. 877: &Apache::loncommon::start_data_table(). 878: &build_tools_display($ccuname,$ccdomain,'requestcourses'). 879: &Apache::loncommon::end_data_table()); 880: } 881: $r->print('</div>'); 882: my $user_auth_text = &user_authentication($ccuname,$ccdomain,$formname); 883: my ($user_quota_text,$user_tools_text,$user_reqcrs_text); 884: if ((&Apache::lonnet::allowed('mpq',$ccdomain)) || 885: (&Apache::lonnet::allowed('mut',$ccdomain))) { 886: # Current user has quota modification privileges 887: $user_quota_text = &portfolio_quota($ccuname,$ccdomain); 888: } 889: if (!&Apache::lonnet::allowed('mpq',$ccdomain)) { 890: if (&Apache::lonnet::allowed('mpq',$env{'request.role.domain'})) { 891: # Get the user's portfolio information 892: my %portq = &Apache::lonnet::get('environment',['portfolioquota'], 893: $ccdomain,$ccuname); 894: my %lt=&Apache::lonlocal::texthash( 895: 'dska' => "Disk space allocated to user's portfolio files", 896: 'youd' => "You do not have privileges to modify the portfolio quota for this user.", 897: 'ichr' => "If a change is required, contact a domain coordinator for the domain", 898: ); 899: $user_quota_text = <<ENDNOPORTPRIV; 900: <h3>$lt{'dska'}</h3> 901: $lt{'youd'} $lt{'ichr'}: $ccdomain 902: ENDNOPORTPRIV 903: } 904: } 905: if (!&Apache::lonnet::allowed('mut',$ccdomain)) { 906: if (&Apache::lonnet::allowed('mut',$env{'request.role.domain'})) { 907: my %lt=&Apache::lonlocal::texthash( 908: 'utav' => "User Tools Availability", 909: 'yodo' => "You do not have privileges to modify Portfolio, Blog or Personal Information Page settings for this user.", 910: 'ifch' => "If a change is required, contact a domain coordinator for the domain", 911: ); 912: $user_tools_text = <<ENDNOTOOLSPRIV; 913: <h3>$lt{'utav'}</h3> 914: $lt{'yodo'} $lt{'ifch'}: $ccdomain 915: ENDNOTOOLSPRIV 916: } 917: } 918: if ($user_auth_text ne '') { 919: $r->print('<div class="LC_left_float">'.$user_auth_text); 920: if ($user_quota_text ne '') { 921: $r->print($user_quota_text); 922: } 923: if ($user_tools_text ne '') { 924: $r->print($user_tools_text); 925: } 926: if ($env{'form.action'} eq 'singlestudent') { 927: $r->print(&date_sections_select($context,$newuser,$formname)); 928: } 929: } elsif ($user_quota_text ne '') { 930: $r->print('<div class="LC_left_float">'.$user_quota_text); 931: if ($user_tools_text ne '') { 932: $r->print($user_tools_text); 933: } 934: if ($env{'form.action'} eq 'singlestudent') { 935: $r->print(&date_sections_select($context,$newuser,$formname)); 936: } 937: } elsif ($user_tools_text ne '') { 938: $r->print('<div class="LC_left_float">'.$user_tools_text); 939: if ($env{'form.action'} eq 'singlestudent') { 940: $r->print(&date_sections_select($context,$newuser,$formname)); 941: } 942: } else { 943: if ($env{'form.action'} eq 'singlestudent') { 944: $r->print('<div class="LC_left_float">'. 945: &date_sections_select($context,$newuser,$formname)); 946: } 947: } 948: $r->print('</div><div class="LC_clear_float_footer"></div>'); 949: if ($env{'form.action'} ne 'singlestudent') { 950: &display_existing_roles($r,$ccuname,$ccdomain,\%inccourses); 951: } 952: } ## End of new user/old user logic 953: 954: if ($env{'form.action'} eq 'singlestudent') { 955: $r->print('<br /><input type="button" value="'.&mt('Enroll Student').'" onClick="setSections(this.form)" />'."\n"); 956: } else { 957: $r->print('<h3>'.&mt('Add Roles').'</h3>'); 958: my $addrolesdisplay = 0; 959: if ($context eq 'domain' || $context eq 'author') { 960: $addrolesdisplay = &new_coauthor_roles($r,$ccuname,$ccdomain); 961: } 962: if ($context eq 'domain') { 963: my $add_domainroles = &new_domain_roles($r); 964: if (!$addrolesdisplay) { 965: $addrolesdisplay = $add_domainroles; 966: } 967: $r->print(&course_level_dc($env{'request.role.domain'},'Course')); 968: $r->print('<br /><input type="button" value="'.&mt('Save').'" onClick="setCourse()" />'."\n"); 969: } elsif ($context eq 'author') { 970: if ($addrolesdisplay) { 971: $r->print('<br /><input type="button" value="'.&mt('Save').'"'); 972: if ($newuser) { 973: $r->print(' onClick="auth_check()" \>'."\n"); 974: } else { 975: $r->print('onClick="this.form.submit()" \>'."\n"); 976: } 977: } else { 978: $r->print('<br /><a href="javascript:backPage(document.cu)">'. 979: &mt('Back to previous page').'</a>'); 980: } 981: } else { 982: $r->print(&course_level_table(%inccourses)); 983: $r->print('<br /><input type="button" value="'.&mt('Save').'" onClick="setSections(this.form)" />'."\n"); 984: } 985: } 986: $r->print(&Apache::lonhtmlcommon::echo_form_input(['phase','userrole','ccdomain','prevphase','currstate','ccuname','ccdomain'])); 987: $r->print('<input type="hidden" name="currstate" value="" />'); 988: $r->print('<input type="hidden" name="prevphase" value="'.$env{'form.phase'}.'" />'); 989: $r->print("</form>".&Apache::loncommon::end_page()); 990: return; 991: } 992: 993: sub singleuser_breadcrumb { 994: my %breadcrumb_text; 995: if ($env{'form.action'} eq 'singlestudent') { 996: $breadcrumb_text{'search'} = 'Enroll a student'; 997: $breadcrumb_text{'userpicked'} = 'Select a user', 998: $breadcrumb_text{'modify'} = 'Set section/dates', 999: } else { 1000: $breadcrumb_text{'search'} = 'Create/modify a user'; 1001: $breadcrumb_text{'userpicked'} = 'Select a user', 1002: $breadcrumb_text{'modify'} = 'Set user role', 1003: } 1004: return %breadcrumb_text; 1005: } 1006: 1007: sub date_sections_select { 1008: my ($context,$newuser,$formname,$permission) = @_; 1009: my $cid = $env{'request.course.id'}; 1010: my ($cnum,$cdom) = &Apache::lonuserutils::get_course_identity($cid); 1011: my $date_table = '<h3>'.&mt('Starting and Ending Dates').'</h3>'."\n". 1012: &Apache::lonuserutils::date_setting_table(undef,undef,$context, 1013: undef,$formname,$permission); 1014: my $rowtitle = 'Section'; 1015: my $secbox = '<h3>'.&mt('Section').'</h3>'."\n". 1016: &Apache::lonuserutils::section_picker($cdom,$cnum,'st',$rowtitle, 1017: $permission); 1018: my $output = $date_table.$secbox; 1019: return $output; 1020: } 1021: 1022: sub validation_javascript { 1023: my ($context,$ccdomain,$pjump_def,$groupslist,$newuser,$formname, 1024: $loaditem) = @_; 1025: my $dc_setcourse_code = ''; 1026: my $nondc_setsection_code = ''; 1027: if ($context eq 'domain') { 1028: my $dcdom = $env{'request.role.domain'}; 1029: $loaditem->{'onload'} = "document.cu.coursedesc.value='';"; 1030: $dc_setcourse_code = 1031: &Apache::lonuserutils::dc_setcourse_js('cu','singleuser',$context); 1032: } else { 1033: my $checkauth; 1034: if (($newuser) || (&Apache::lonnet::allowed('mau',$ccdomain))) { 1035: $checkauth = 1; 1036: } 1037: if ($context eq 'course') { 1038: $nondc_setsection_code = 1039: &Apache::lonuserutils::setsections_javascript($formname,$groupslist, 1040: undef,$checkauth); 1041: } 1042: if ($checkauth) { 1043: $nondc_setsection_code .= 1044: &Apache::lonuserutils::verify_authen($formname,$context); 1045: } 1046: } 1047: my $js = &user_modification_js($pjump_def,$dc_setcourse_code, 1048: $nondc_setsection_code,$groupslist); 1049: my ($jsback,$elements) = &crumb_utilities(); 1050: $js .= "\n". 1051: '<script type="text/javascript">'."\n".$jsback."\n".'</script>'; 1052: return $js; 1053: } 1054: 1055: sub display_existing_roles { 1056: my ($r,$ccuname,$ccdomain,$inccourses) = @_; 1057: my %rolesdump=&Apache::lonnet::dump('roles',$ccdomain,$ccuname); 1058: # Build up table of user roles to allow revocation and re-enabling of roles. 1059: my ($tmp) = keys(%rolesdump); 1060: if ($tmp !~ /^(con_lost|error)/i) { 1061: my $now=time; 1062: my %lt=&Apache::lonlocal::texthash( 1063: 'rer' => "Existing Roles", 1064: 'rev' => "Revoke", 1065: 'del' => "Delete", 1066: 'ren' => "Re-Enable", 1067: 'rol' => "Role", 1068: 'ext' => "Extent", 1069: 'sta' => "Start", 1070: 'end' => "End", 1071: ); 1072: my (%roletext,%sortrole,%roleclass,%rolepriv); 1073: foreach my $area (sort { my $a1=join('_',(split('_',$a))[1,0]); 1074: my $b1=join('_',(split('_',$b))[1,0]); 1075: return $a1 cmp $b1; 1076: } keys(%rolesdump)) { 1077: next if ($area =~ /^rolesdef/); 1078: my $envkey=$area; 1079: my $role = $rolesdump{$area}; 1080: my $thisrole=$area; 1081: $area =~ s/\_\w\w$//; 1082: my ($role_code,$role_end_time,$role_start_time) = 1083: split(/_/,$role); 1084: # Is this a custom role? Get role owner and title. 1085: my ($croleudom,$croleuname,$croletitle)= 1086: ($role_code=~m{^cr/($match_domain)/($match_username)/(\w+)$}); 1087: my $allowed=0; 1088: my $delallowed=0; 1089: my $sortkey=$role_code; 1090: my $class='Unknown'; 1091: if ($area =~ m{^/($match_domain)/($match_courseid)} ) { 1092: $class='Course'; 1093: my ($coursedom,$coursedir) = ($1,$2); 1094: $sortkey.="\0$coursedom"; 1095: # $1.'_'.$2 is the course id (eg. 103_12345abcef103l3). 1096: my %coursedata= 1097: &Apache::lonnet::coursedescription($1.'_'.$2); 1098: my $carea; 1099: if (defined($coursedata{'description'})) { 1100: $carea=$coursedata{'description'}. 1101: '<br />'.&mt('Domain').': '.$coursedom.(' 'x8). 1102: &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$coursedir,$coursedom); 1103: $sortkey.="\0".$coursedata{'description'}; 1104: $class=$coursedata{'type'}; 1105: } else { 1106: $carea=&mt('Unavailable course').': '.$area; 1107: $sortkey.="\0".&mt('Unavailable course').': '.$area; 1108: } 1109: $sortkey.="\0$coursedir"; 1110: $inccourses->{$1.'_'.$2}=1; 1111: if ((&Apache::lonnet::allowed('c'.$role_code,$1.'/'.$2)) || 1112: (&Apache::lonnet::allowed('c'.$role_code,$ccdomain))) { 1113: $allowed=1; 1114: } 1115: if ((&Apache::lonnet::allowed('dro',$1)) || 1116: (&Apache::lonnet::allowed('dro',$ccdomain))) { 1117: $delallowed=1; 1118: } 1119: # - custom role. Needs more info, too 1120: if ($croletitle) { 1121: if (&Apache::lonnet::allowed('ccr',$1.'/'.$2)) { 1122: $allowed=1; 1123: $thisrole.='.'.$role_code; 1124: } 1125: } 1126: # Compute the background color based on $area 1127: if ($area=~m{^/($match_domain)/($match_courseid)/(\w+)}) { 1128: $carea.='<br />Section: '.$3; 1129: $sortkey.="\0$3"; 1130: if (!$allowed) { 1131: if ($env{'request.course.sec'} eq $3) { 1132: if (&Apache::lonnet::allowed('c'.$role_code,$1.'/'.$2.'/'.$3)) { 1133: $allowed = 1; 1134: } 1135: } 1136: } 1137: } 1138: $area=$carea; 1139: } else { 1140: $sortkey.="\0".$area; 1141: # Determine if current user is able to revoke privileges 1142: if ($area=~m{^/($match_domain)/}) { 1143: if ((&Apache::lonnet::allowed('c'.$role_code,$1)) || 1144: (&Apache::lonnet::allowed('c'.$role_code,$ccdomain))) { 1145: $allowed=1; 1146: } 1147: if (((&Apache::lonnet::allowed('dro',$1)) || 1148: (&Apache::lonnet::allowed('dro',$ccdomain))) && 1149: ($role_code ne 'dc')) { 1150: $delallowed=1; 1151: } 1152: } else { 1153: if (&Apache::lonnet::allowed('c'.$role_code,'/')) { 1154: $allowed=1; 1155: } 1156: } 1157: if ($role_code eq 'ca' || $role_code eq 'au') { 1158: $class='Construction Space'; 1159: } elsif ($role_code eq 'su') { 1160: $class='System'; 1161: } else { 1162: $class='Domain'; 1163: } 1164: } 1165: if (($role_code eq 'ca') || ($role_code eq 'aa')) { 1166: $area=~m{/($match_domain)/($match_username)}; 1167: if (&Apache::lonuserutils::authorpriv($2,$1)) { 1168: $allowed=1; 1169: } else { 1170: $allowed=0; 1171: } 1172: } 1173: my $row = ''; 1174: $row.= '<td>'; 1175: my $active=1; 1176: $active=0 if (($role_end_time) && ($now>$role_end_time)); 1177: if (($active) && ($allowed)) { 1178: $row.= '<input type="checkbox" name="rev:'.$thisrole.'" />'; 1179: } else { 1180: if ($active) { 1181: $row.=' '; 1182: } else { 1183: $row.=&mt('expired or revoked'); 1184: } 1185: } 1186: $row.='</td><td>'; 1187: if ($allowed && !$active) { 1188: $row.= '<input type="checkbox" name="ren:'.$thisrole.'" />'; 1189: } else { 1190: $row.=' '; 1191: } 1192: $row.='</td><td>'; 1193: if ($delallowed) { 1194: $row.= '<input type="checkbox" name="del:'.$thisrole.'" />'; 1195: } else { 1196: $row.=' '; 1197: } 1198: my $plaintext=''; 1199: if (!$croletitle) { 1200: $plaintext=&Apache::lonnet::plaintext($role_code,$class) 1201: } else { 1202: $plaintext= 1203: "Customrole '$croletitle'<br />defined by $croleuname\@$croleudom"; 1204: } 1205: $row.= '</td><td>'.$plaintext. 1206: '</td><td>'.$area. 1207: '</td><td>'.($role_start_time?localtime($role_start_time) 1208: : ' ' ). 1209: '</td><td>'.($role_end_time ?localtime($role_end_time) 1210: : ' ' ) 1211: ."</td>"; 1212: $sortrole{$sortkey}=$envkey; 1213: $roletext{$envkey}=$row; 1214: $roleclass{$envkey}=$class; 1215: $rolepriv{$envkey}=$allowed; 1216: #$r->print($row); 1217: } # end of foreach (table building loop) 1218: my $rolesdisplay = 0; 1219: my %output = (); 1220: foreach my $type ('Construction Space','Course','Group','Domain','System','Unknown') { 1221: $output{$type} = ''; 1222: foreach my $which (sort {uc($a) cmp uc($b)} (keys(%sortrole))) { 1223: if ( ($roleclass{$sortrole{$which}} =~ /^\Q$type\E/ ) && ($rolepriv{$sortrole{$which}}) ) { 1224: $output{$type}.= 1225: &Apache::loncommon::start_data_table_row(). 1226: $roletext{$sortrole{$which}}. 1227: &Apache::loncommon::end_data_table_row(); 1228: } 1229: } 1230: unless($output{$type} eq '') { 1231: $output{$type} = '<tr class="LC_info_row">'. 1232: "<td align='center' colspan='7'>".&mt($type)."</td></tr>". 1233: $output{$type}; 1234: $rolesdisplay = 1; 1235: } 1236: } 1237: if ($rolesdisplay == 1) { 1238: my $contextrole=''; 1239: if ($env{'request.course.id'}) { 1240: $contextrole = 'Existing Roles in this Course'; 1241: } elsif ($env{'request.role'} =~ /^au\./) { 1242: $contextrole = 'Existing Co-Author Roles in your Construction Space'; 1243: } else { 1244: $contextrole = 'Existing Roles in this Domain'; 1245: } 1246: $r->print(' 1247: <h3>'.$lt{'rer'}.'</h3>'. 1248: '<div>'.&mt($contextrole).'</div>'. 1249: &Apache::loncommon::start_data_table("LC_createuser"). 1250: &Apache::loncommon::start_data_table_header_row(). 1251: '<th>'.$lt{'rev'}.'</th><th>'.$lt{'ren'}.'</th><th>'.$lt{'del'}. 1252: '</th><th>'.$lt{'rol'}.'</th><th>'.$lt{'ext'}. 1253: '</th><th>'.$lt{'sta'}.'</th><th>'.$lt{'end'}.'</th>'. 1254: &Apache::loncommon::end_data_table_header_row()); 1255: foreach my $type ('Construction Space','Course','Group','Domain','System','Unknown') { 1256: if ($output{$type}) { 1257: $r->print($output{$type}."\n"); 1258: } 1259: } 1260: $r->print(&Apache::loncommon::end_data_table()); 1261: } 1262: } # End of check for keys in rolesdump 1263: return; 1264: } 1265: 1266: sub new_coauthor_roles { 1267: my ($r,$ccuname,$ccdomain) = @_; 1268: my $addrolesdisplay = 0; 1269: # 1270: # Co-Author 1271: # 1272: if (&Apache::lonuserutils::authorpriv($env{'user.name'}, 1273: $env{'request.role.domain'}) && 1274: ($env{'user.name'} ne $ccuname || $env{'user.domain'} ne $ccdomain)) { 1275: # No sense in assigning co-author role to yourself 1276: $addrolesdisplay = 1; 1277: my $cuname=$env{'user.name'}; 1278: my $cudom=$env{'request.role.domain'}; 1279: my %lt=&Apache::lonlocal::texthash( 1280: 'cs' => "Construction Space", 1281: 'act' => "Activate", 1282: 'rol' => "Role", 1283: 'ext' => "Extent", 1284: 'sta' => "Start", 1285: 'end' => "End", 1286: 'cau' => "Co-Author", 1287: 'caa' => "Assistant Co-Author", 1288: 'ssd' => "Set Start Date", 1289: 'sed' => "Set End Date" 1290: ); 1291: $r->print('<h4>'.$lt{'cs'}.'</h4>'."\n". 1292: &Apache::loncommon::start_data_table()."\n". 1293: &Apache::loncommon::start_data_table_header_row()."\n". 1294: '<th>'.$lt{'act'}.'</th><th>'.$lt{'rol'}.'</th>'. 1295: '<th>'.$lt{'ext'}.'</th><th>'.$lt{'sta'}.'</th>'. 1296: '<th>'.$lt{'end'}.'</th>'."\n". 1297: &Apache::loncommon::end_data_table_header_row()."\n". 1298: &Apache::loncommon::start_data_table_row().' 1299: <td> 1300: <input type="checkbox" name="act_'.$cudom.'_'.$cuname.'_ca" /> 1301: </td> 1302: <td>'.$lt{'cau'}.'</td> 1303: <td>'.$cudom.'_'.$cuname.'</td> 1304: <td><input type="hidden" name="start_'.$cudom.'_'.$cuname.'_ca" value="" /> 1305: <a href= 1306: "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> 1307: <td><input type="hidden" name="end_'.$cudom.'_'.$cuname.'_ca" value="" /> 1308: <a href= 1309: "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". 1310: &Apache::loncommon::end_data_table_row()."\n". 1311: &Apache::loncommon::start_data_table_row()."\n". 1312: '<td><input type="checkbox" name="act_'.$cudom.'_'.$cuname.'_aa" /></td> 1313: <td>'.$lt{'caa'}.'</td> 1314: <td>'.$cudom.'_'.$cuname.'</td> 1315: <td><input type="hidden" name="start_'.$cudom.'_'.$cuname.'_aa" value="" /> 1316: <a href= 1317: "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> 1318: <td><input type="hidden" name="end_'.$cudom.'_'.$cuname.'_aa" value="" /> 1319: <a href= 1320: "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". 1321: &Apache::loncommon::end_data_table_row()."\n". 1322: &Apache::loncommon::end_data_table()); 1323: } elsif ($env{'request.role'} =~ /^au\./) { 1324: if (!(&Apache::lonuserutils::authorpriv($env{'user.name'}, 1325: $env{'request.role.domain'}))) { 1326: $r->print('<span class="LC_error">'. 1327: &mt('You do not have privileges to assign co-author roles.'). 1328: '</span>'); 1329: } elsif (($env{'user.name'} eq $ccuname) && 1330: ($env{'user.domain'} eq $ccdomain)) { 1331: $r->print(&mt('Assigning yourself a co-author or assistant co-author role in your own author area in Construction Space is not permitted')); 1332: } 1333: } 1334: return $addrolesdisplay;; 1335: } 1336: 1337: sub new_domain_roles { 1338: my ($r) = @_; 1339: my $addrolesdisplay = 0; 1340: # 1341: # Domain level 1342: # 1343: my $num_domain_level = 0; 1344: my $domaintext = 1345: '<h4>'.&mt('Domain Level').'</h4>'. 1346: &Apache::loncommon::start_data_table(). 1347: &Apache::loncommon::start_data_table_header_row(). 1348: '<th>'.&mt('Activate').'</th><th>'.&mt('Role').'</th><th>'. 1349: &mt('Extent').'</th>'. 1350: '<th>'.&mt('Start').'</th><th>'.&mt('End').'</th>'. 1351: &Apache::loncommon::end_data_table_header_row(); 1352: foreach my $thisdomain (sort(&Apache::lonnet::all_domains())) { 1353: foreach my $role ('dc','li','dg','au','sc') { 1354: if (&Apache::lonnet::allowed('c'.$role,$thisdomain)) { 1355: my $plrole=&Apache::lonnet::plaintext($role); 1356: my %lt=&Apache::lonlocal::texthash( 1357: 'ssd' => "Set Start Date", 1358: 'sed' => "Set End Date" 1359: ); 1360: $num_domain_level ++; 1361: $domaintext .= 1362: &Apache::loncommon::start_data_table_row(). 1363: '<td><input type="checkbox" name="act_'.$thisdomain.'_'.$role.'" /></td> 1364: <td>'.$plrole.'</td> 1365: <td>'.$thisdomain.'</td> 1366: <td><input type="hidden" name="start_'.$thisdomain.'_'.$role.'" value="" /> 1367: <a href= 1368: "javascript:pjump('."'date_start','Start Date $plrole',document.cu.start_$thisdomain\_$role.value,'start_$thisdomain\_$role','cu.pres','dateset'".')">'.$lt{'ssd'}.'</a></td> 1369: <td><input type="hidden" name="end_'.$thisdomain.'_'.$role.'" value="" /> 1370: <a href= 1371: "javascript:pjump('."'date_end','End Date $plrole',document.cu.end_$thisdomain\_$role.value,'end_$thisdomain\_$role','cu.pres','dateset'".')">'.$lt{'sed'}.'</a></td>'. 1372: &Apache::loncommon::end_data_table_row(); 1373: } 1374: } 1375: } 1376: $domaintext.= &Apache::loncommon::end_data_table(); 1377: if ($num_domain_level > 0) { 1378: $r->print($domaintext); 1379: $addrolesdisplay = 1; 1380: } 1381: return $addrolesdisplay; 1382: } 1383: 1384: sub user_authentication { 1385: my ($ccuname,$ccdomain,$formname) = @_; 1386: my $currentauth=&Apache::lonnet::queryauthenticate($ccuname,$ccdomain); 1387: my $outcome; 1388: # Check for a bad authentication type 1389: if ($currentauth !~ /^(krb4|krb5|unix|internal|localauth):/) { 1390: # bad authentication scheme 1391: my %lt=&Apache::lonlocal::texthash( 1392: 'err' => "ERROR", 1393: 'uuas' => "This user has an unrecognized authentication scheme", 1394: 'adcs' => "Please alert a domain coordinator of this situation", 1395: 'sldb' => "Please specify login data below", 1396: 'ld' => "Login Data" 1397: ); 1398: if (&Apache::lonnet::allowed('mau',$ccdomain)) { 1399: &initialize_authen_forms($ccdomain,$formname); 1400: 1401: my $choices = &Apache::lonuserutils::set_login($ccdomain,$authformkrb,$authformint,$authformloc); 1402: $outcome = <<ENDBADAUTH; 1403: <script type="text/javascript" language="Javascript"> 1404: $loginscript 1405: </script> 1406: <span class="LC_error">$lt{'err'}: 1407: $lt{'uuas'} ($currentauth). $lt{'sldb'}.</span> 1408: <h3>$lt{'ld'}</h3> 1409: $choices 1410: ENDBADAUTH 1411: } else { 1412: # This user is not allowed to modify the user's 1413: # authentication scheme, so just notify them of the problem 1414: $outcome = <<ENDBADAUTH; 1415: <span class="LC_error"> $lt{'err'}: 1416: $lt{'uuas'} ($currentauth). $lt{'adcs'}. 1417: </span> 1418: ENDBADAUTH 1419: } 1420: } else { # Authentication type is valid 1421: &initialize_authen_forms($ccdomain,$formname,$currentauth,'modifyuser'); 1422: my ($authformcurrent,$can_modify,@authform_others) = 1423: &modify_login_block($ccdomain,$currentauth); 1424: if (&Apache::lonnet::allowed('mau',$ccdomain)) { 1425: # Current user has login modification privileges 1426: my %lt=&Apache::lonlocal::texthash ( 1427: 'ld' => "Login Data", 1428: 'ccld' => "Change Current Login Data", 1429: 'enld' => "Enter New Login Data" 1430: ); 1431: $outcome = 1432: '<script type="text/javascript" language="Javascript">'."\n". 1433: $loginscript."\n". 1434: '</script>'."\n". 1435: '<h3>'.$lt{'ld'}.'</h3>'. 1436: &Apache::loncommon::start_data_table(). 1437: &Apache::loncommon::start_data_table_row(). 1438: '<td>'.$authformnop; 1439: if ($can_modify) { 1440: $outcome .= '</td>'."\n". 1441: &Apache::loncommon::end_data_table_row(). 1442: &Apache::loncommon::start_data_table_row(). 1443: '<td>'.$authformcurrent.'</td>'. 1444: &Apache::loncommon::end_data_table_row()."\n"; 1445: } else { 1446: $outcome .= ' ('.$authformcurrent.')</td>'. 1447: &Apache::loncommon::end_data_table_row()."\n"; 1448: } 1449: foreach my $item (@authform_others) { 1450: $outcome .= &Apache::loncommon::start_data_table_row(). 1451: '<td>'.$item.'</td>'. 1452: &Apache::loncommon::end_data_table_row()."\n"; 1453: } 1454: $outcome .= &Apache::loncommon::end_data_table(); 1455: } else { 1456: if (&Apache::lonnet::allowed('mau',$env{'request.role.domain'})) { 1457: my %lt=&Apache::lonlocal::texthash( 1458: 'ccld' => "Change Current Login Data", 1459: 'yodo' => "You do not have privileges to modify the authentication configuration for this user.", 1460: 'ifch' => "If a change is required, contact a domain coordinator for the domain", 1461: ); 1462: $outcome .= <<ENDNOPRIV; 1463: <h3>$lt{'ccld'}</h3> 1464: $lt{'yodo'} $lt{'ifch'}: $ccdomain 1465: <input type="hidden" name="login" value="nochange" /> 1466: ENDNOPRIV 1467: } 1468: } 1469: } ## End of "check for bad authentication type" logic 1470: return $outcome; 1471: } 1472: 1473: sub modify_login_block { 1474: my ($dom,$currentauth) = @_; 1475: my %domconfig = &Apache::lonnet::get_dom('configuration',['usercreation'],$dom); 1476: my ($authnum,%can_assign) = 1477: &Apache::loncommon::get_assignable_auth($dom); 1478: my ($authformcurrent,@authform_others,$show_override_msg); 1479: if ($currentauth=~/^krb(4|5):/) { 1480: $authformcurrent=$authformkrb; 1481: if ($can_assign{'int'}) { 1482: push(@authform_others,$authformint); 1483: } 1484: if ($can_assign{'loc'}) { 1485: push(@authform_others,$authformloc); 1486: } 1487: if (($can_assign{'krb4'}) || ($can_assign{'krb5'})) { 1488: $show_override_msg = 1; 1489: } 1490: } elsif ($currentauth=~/^internal:/) { 1491: $authformcurrent=$authformint; 1492: if (($can_assign{'krb4'}) || ($can_assign{'krb5'})) { 1493: push(@authform_others,$authformkrb); 1494: } 1495: if ($can_assign{'loc'}) { 1496: push(@authform_others,$authformloc); 1497: } 1498: if ($can_assign{'int'}) { 1499: $show_override_msg = 1; 1500: } 1501: } elsif ($currentauth=~/^unix:/) { 1502: $authformcurrent=$authformfsys; 1503: if (($can_assign{'krb4'}) || ($can_assign{'krb5'})) { 1504: push(@authform_others,$authformkrb); 1505: } 1506: if ($can_assign{'int'}) { 1507: push(@authform_others,$authformint); 1508: } 1509: if ($can_assign{'loc'}) { 1510: push(@authform_others,$authformloc); 1511: } 1512: if ($can_assign{'fsys'}) { 1513: $show_override_msg = 1; 1514: } 1515: } elsif ($currentauth=~/^localauth:/) { 1516: $authformcurrent=$authformloc; 1517: if (($can_assign{'krb4'}) || ($can_assign{'krb5'})) { 1518: push(@authform_others,$authformkrb); 1519: } 1520: if ($can_assign{'int'}) { 1521: push(@authform_others,$authformint); 1522: } 1523: if ($can_assign{'loc'}) { 1524: $show_override_msg = 1; 1525: } 1526: } 1527: if ($show_override_msg) { 1528: $authformcurrent = '<table><tr><td colspan="3">'.$authformcurrent. 1529: '</td></tr>'."\n". 1530: '<tr><td> </td>'. 1531: '<td><b>'.&mt('Currently in use').'</b></td>'. 1532: '<td align="right"><span class="LC_cusr_emph">'. 1533: &mt('will override current values'). 1534: '</span></td></tr></table>'; 1535: } 1536: return ($authformcurrent,$show_override_msg,@authform_others); 1537: } 1538: 1539: sub personal_data_display { 1540: my ($ccuname,$ccdomain,$newuser,$context,$inst_results,$rolesarray) = @_; 1541: my ($output,$showforceid,%userenv,%canmodify,%canmodify_status); 1542: my @userinfo = ('firstname','middlename','lastname','generation', 1543: 'permanentemail','id'); 1544: my $rowcount = 0; 1545: my $editable = 0; 1546: %canmodify_status = 1547: &Apache::lonuserutils::can_modify_userinfo($context,$ccdomain, 1548: ['inststatus'],$rolesarray); 1549: if (!$newuser) { 1550: # Get the users information 1551: %userenv = &Apache::lonnet::get('environment', 1552: ['firstname','middlename','lastname','generation', 1553: 'permanentemail','id','inststatus'],$ccdomain,$ccuname); 1554: %canmodify = 1555: &Apache::lonuserutils::can_modify_userinfo($context,$ccdomain, 1556: \@userinfo,$rolesarray); 1557: } elsif ($context eq 'selfcreate') { 1558: %canmodify = &selfcreate_canmodify($context,$ccdomain,\@userinfo, 1559: $inst_results,$rolesarray); 1560: } 1561: my %lt=&Apache::lonlocal::texthash( 1562: 'pd' => "Personal Data", 1563: 'firstname' => "First Name", 1564: 'middlename' => "Middle Name", 1565: 'lastname' => "Last Name", 1566: 'generation' => "Generation", 1567: 'permanentemail' => "Permanent e-mail address", 1568: 'id' => "Student/Employee ID", 1569: 'lg' => "Login Data", 1570: 'inststatus' => "Affiliation", 1571: ); 1572: my %textboxsize = ( 1573: firstname => '15', 1574: middlename => '15', 1575: lastname => '15', 1576: generation => '5', 1577: permanentemail => '25', 1578: id => '15', 1579: ); 1580: my $genhelp=&Apache::loncommon::help_open_topic('Generation'); 1581: $output = '<h3>'.$lt{'pd'}.'</h3>'. 1582: &Apache::lonhtmlcommon::start_pick_box(); 1583: foreach my $item (@userinfo) { 1584: my $rowtitle = $lt{$item}; 1585: my $hiderow = 0; 1586: if ($item eq 'generation') { 1587: $rowtitle = $genhelp.$rowtitle; 1588: } 1589: my $row = &Apache::lonhtmlcommon::row_title($rowtitle,undef,'LC_oddrow_value')."\n"; 1590: if ($newuser) { 1591: if (ref($inst_results) eq 'HASH') { 1592: if ($inst_results->{$item} ne '') { 1593: $row .= '<input type="hidden" name="c'.$item.'" value="'.$inst_results->{$item}.'" />'.$inst_results->{$item}; 1594: } else { 1595: if ($context eq 'selfcreate') { 1596: if ($canmodify{$item}) { 1597: $row .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="" />'; 1598: $editable ++; 1599: } else { 1600: $hiderow = 1; 1601: } 1602: } else { 1603: $row .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="" />'; 1604: } 1605: } 1606: } else { 1607: if ($context eq 'selfcreate') { 1608: if (($item eq 'permanentemail') && ($newuser eq 'email')) { 1609: $row .= $ccuname; 1610: } else { 1611: if ($canmodify{$item}) { 1612: $row .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="" />'; 1613: $editable ++; 1614: } else { 1615: $hiderow = 1; 1616: } 1617: } 1618: } else { 1619: $row .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="" />'; 1620: } 1621: } 1622: } else { 1623: if ($canmodify{$item}) { 1624: $row .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="'.$userenv{$item}.'" />'; 1625: } else { 1626: $row .= $userenv{$item}; 1627: } 1628: if ($item eq 'id') { 1629: $showforceid = $canmodify{$item}; 1630: } 1631: } 1632: $row .= &Apache::lonhtmlcommon::row_closure(1); 1633: if (!$hiderow) { 1634: $output .= $row; 1635: $rowcount ++; 1636: } 1637: } 1638: if (($canmodify_status{'inststatus'}) || ($context ne 'selfcreate')) { 1639: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($ccdomain); 1640: if (ref($types) eq 'ARRAY') { 1641: if (@{$types} > 0) { 1642: my ($hiderow,$shown); 1643: if ($canmodify_status{'inststatus'}) { 1644: $shown = &pick_inst_statuses($userenv{'inststatus'},$usertypes,$types); 1645: } else { 1646: $shown .= $userenv{'inststatus'}; 1647: if ($userenv{'inststatus'} eq '') { 1648: $hiderow = 1; 1649: } 1650: } 1651: if (!$hiderow) { 1652: my $row = &Apache::lonhtmlcommon::row_title(&mt('Affliations'),undef,'LC_oddrow_value')."\n". 1653: $shown.&Apache::lonhtmlcommon::row_closure(1); 1654: if ($context eq 'selfcreate') { 1655: $rowcount ++; 1656: } 1657: $output .= $row; 1658: } 1659: } 1660: } 1661: } 1662: $output .= &Apache::lonhtmlcommon::end_pick_box(); 1663: if (wantarray) { 1664: if ($context eq 'selfcreate') { 1665: return($output,$rowcount,$editable); 1666: } else { 1667: return ($output,$showforceid); 1668: } 1669: } else { 1670: return $output; 1671: } 1672: } 1673: 1674: sub pick_inst_statuses { 1675: my ($curr,$usertypes,$types) = @_; 1676: my ($output,$rem,@currtypes); 1677: if ($curr ne '') { 1678: @currtypes = map { &unescape($_); } split(/:/,$curr); 1679: } 1680: my $numinrow = 2; 1681: if (ref($types) eq 'ARRAY') { 1682: $output = '<table>'; 1683: my $lastcolspan; 1684: for (my $i=0; $i<@{$types}; $i++) { 1685: if (defined($usertypes->{$types->[$i]})) { 1686: my $rem = $i%($numinrow); 1687: if ($rem == 0) { 1688: if ($i<@{$types}-1) { 1689: if ($i > 0) { 1690: $output .= '</tr>'; 1691: } 1692: $output .= '<tr>'; 1693: } 1694: } elsif ($i==@{$types}-1) { 1695: my $colsleft = $numinrow - $rem; 1696: if ($colsleft > 1) { 1697: $lastcolspan = ' colspan="'.$colsleft.'"'; 1698: } 1699: } 1700: my $check = ' '; 1701: if (grep(/^\Q$types->[$i]\E$/,@currtypes)) { 1702: $check = ' checked="checked" '; 1703: } 1704: $output .= '<td class="LC_left_item"'.$lastcolspan.'>'. 1705: '<span class="LC_nobreak"><label>'. 1706: '<input type="checkbox" name="inststatus" '. 1707: 'value="'.$types->[$i].'"'.$check.'/>'. 1708: $usertypes->{$types->[$i]}.'</label></span></td>'; 1709: } 1710: } 1711: $output .= '</tr></table>'; 1712: } 1713: return $output; 1714: } 1715: 1716: sub selfcreate_canmodify { 1717: my ($context,$dom,$userinfo,$inst_results,$rolesarray) = @_; 1718: if (ref($inst_results) eq 'HASH') { 1719: my @inststatuses = &get_inststatuses($inst_results); 1720: if (@inststatuses == 0) { 1721: @inststatuses = ('default'); 1722: } 1723: $rolesarray = \@inststatuses; 1724: } 1725: my %canmodify = 1726: &Apache::lonuserutils::can_modify_userinfo($context,$dom,$userinfo, 1727: $rolesarray); 1728: return %canmodify; 1729: } 1730: 1731: sub get_inststatuses { 1732: my ($insthashref) = @_; 1733: my @inststatuses = (); 1734: if (ref($insthashref) eq 'HASH') { 1735: if (ref($insthashref->{'inststatus'}) eq 'ARRAY') { 1736: @inststatuses = @{$insthashref->{'inststatus'}}; 1737: } 1738: } 1739: return @inststatuses; 1740: } 1741: 1742: # ================================================================= Phase Three 1743: sub update_user_data { 1744: my ($r,$context) = @_; 1745: my $uhome=&Apache::lonnet::homeserver($env{'form.ccuname'}, 1746: $env{'form.ccdomain'}); 1747: # Error messages 1748: my $error = '<span class="LC_error">'.&mt('Error').': '; 1749: my $end = '</span><br /><br />'; 1750: my $rtnlink = '<a href="javascript:backPage(document.userupdate,'. 1751: "'$env{'form.prevphase'}','modify')".'" />'. 1752: &mt('Return to previous page').'</a>'. 1753: &Apache::loncommon::end_page(); 1754: my $now = time; 1755: my $title; 1756: if (exists($env{'form.makeuser'})) { 1757: $title='Set Privileges for New User'; 1758: } else { 1759: $title='Modify User Privileges'; 1760: } 1761: my $newuser = 0; 1762: my ($jsback,$elements) = &crumb_utilities(); 1763: my $jscript = '<script type="text/javascript">'."\n". 1764: $jsback."\n".'</script>'."\n"; 1765: my %breadcrumb_text = &singleuser_breadcrumb(); 1766: my $args; 1767: if ($env{'form.popup'}) { 1768: $args->{'no_nav_bar'} = 1; 1769: } else { 1770: $args = undef; 1771: } 1772: $r->print(&Apache::loncommon::start_page($title,$jscript,$args)); 1773: &Apache::lonhtmlcommon::add_breadcrumb 1774: ({href=>"javascript:backPage(document.userupdate)", 1775: text=>$breadcrumb_text{'search'}, 1776: faq=>282,bug=>'Instructor Interface',}); 1777: if ($env{'form.prevphase'} eq 'userpicked') { 1778: &Apache::lonhtmlcommon::add_breadcrumb 1779: ({href=>"javascript:backPage(document.userupdate,'get_user_info','select')", 1780: text=>$breadcrumb_text{'userpicked'}, 1781: faq=>282,bug=>'Instructor Interface',}); 1782: } 1783: &Apache::lonhtmlcommon::add_breadcrumb 1784: ({href=>"javascript:backPage(document.userupdate,'$env{'form.prevphase'}','modify')", 1785: text=>$breadcrumb_text{'modify'}, 1786: faq=>282,bug=>'Instructor Interface',}, 1787: {href=>"/adm/createuser", 1788: text=>"Result", 1789: faq=>282,bug=>'Instructor Interface',}); 1790: my $helpitem = 'Course_Change_Privileges'; 1791: if ($env{'form.action'} eq 'singlestudent') { 1792: $helpitem = 'Course_Add_Student'; 1793: } 1794: $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management', 1795: $helpitem)); 1796: $r->print(&update_result_form($uhome)); 1797: # Check Inputs 1798: if (! $env{'form.ccuname'} ) { 1799: $r->print($error.&mt('No login name specified').'.'.$end.$rtnlink); 1800: return; 1801: } 1802: if ( $env{'form.ccuname'} ne 1803: &LONCAPA::clean_username($env{'form.ccuname'}) ) { 1804: $r->print($error.&mt('Invalid login name.').' '. 1805: &mt('Only letters, numbers, periods, dashes, @, and underscores are valid.'). 1806: $end.$rtnlink); 1807: return; 1808: } 1809: if (! $env{'form.ccdomain'} ) { 1810: $r->print($error.&mt('No domain specified').'.'.$end.$rtnlink); 1811: return; 1812: } 1813: if ( $env{'form.ccdomain'} ne 1814: &LONCAPA::clean_domain($env{'form.ccdomain'}) ) { 1815: $r->print($error.&mt('Invalid domain name.').' '. 1816: &mt('Only letters, numbers, periods, dashes, and underscores are valid.'). 1817: $end.$rtnlink); 1818: return; 1819: } 1820: if ($uhome eq 'no_host') { 1821: $newuser = 1; 1822: } 1823: if (! exists($env{'form.makeuser'})) { 1824: # Modifying an existing user, so check the validity of the name 1825: if ($uhome eq 'no_host') { 1826: $r->print($error.&mt('Unable to determine home server for '). 1827: $env{'form.ccuname'}.&mt(' in domain '). 1828: $env{'form.ccdomain'}.'.'); 1829: return; 1830: } 1831: } 1832: # Determine authentication method and password for the user being modified 1833: my $amode=''; 1834: my $genpwd=''; 1835: if ($env{'form.login'} eq 'krb') { 1836: $amode='krb'; 1837: $amode.=$env{'form.krbver'}; 1838: $genpwd=$env{'form.krbarg'}; 1839: } elsif ($env{'form.login'} eq 'int') { 1840: $amode='internal'; 1841: $genpwd=$env{'form.intarg'}; 1842: } elsif ($env{'form.login'} eq 'fsys') { 1843: $amode='unix'; 1844: $genpwd=$env{'form.fsysarg'}; 1845: } elsif ($env{'form.login'} eq 'loc') { 1846: $amode='localauth'; 1847: $genpwd=$env{'form.locarg'}; 1848: $genpwd=" " if (!$genpwd); 1849: } elsif (($env{'form.login'} eq 'nochange') || 1850: ($env{'form.login'} eq '' )) { 1851: # There is no need to tell the user we did not change what they 1852: # did not ask us to change. 1853: # If they are creating a new user but have not specified login 1854: # information this will be caught below. 1855: } else { 1856: $r->print($error.&mt('Invalid login mode or password').$end.$rtnlink); 1857: return; 1858: } 1859: 1860: $r->print('<h3>'.&mt('User [_1] in domain [_2]', 1861: $env{'form.ccuname'}, $env{'form.ccdomain'}).'</h3>'); 1862: my (%alerts,%rulematch,%inst_results,%curr_rules); 1863: my @usertools = ('aboutme','blog','portfolio'); 1864: my @requestcourses = ('official','unofficial'); 1865: my ($othertitle,$usertypes,$types) = 1866: &Apache::loncommon::sorted_inst_types($env{'form.ccdomain'}); 1867: if ($env{'form.makeuser'}) { 1868: $r->print('<h3>'.&mt('Creating new account.').'</h3>'); 1869: # Check for the authentication mode and password 1870: if (! $amode || ! $genpwd) { 1871: $r->print($error.&mt('Invalid login mode or password').$end.$rtnlink); 1872: return; 1873: } 1874: # Determine desired host 1875: my $desiredhost = $env{'form.hserver'}; 1876: if (lc($desiredhost) eq 'default') { 1877: $desiredhost = undef; 1878: } else { 1879: my %home_servers = 1880: &Apache::lonnet::get_servers($env{'form.ccdomain'},'library'); 1881: if (! exists($home_servers{$desiredhost})) { 1882: $r->print($error.&mt('Invalid home server specified').$end.$rtnlink); 1883: return; 1884: } 1885: } 1886: # Check ID format 1887: my %checkhash; 1888: my %checks = ('id' => 1); 1889: %{$checkhash{$env{'form.ccuname'}.':'.$env{'form.ccdomain'}}} = ( 1890: 'newuser' => $newuser, 1891: 'id' => $env{'form.cid'}, 1892: ); 1893: if ($env{'form.cid'} ne '') { 1894: &Apache::loncommon::user_rule_check(\%checkhash,\%checks,\%alerts, 1895: \%rulematch,\%inst_results,\%curr_rules); 1896: if (ref($alerts{'id'}) eq 'HASH') { 1897: if (ref($alerts{'id'}{$env{'form.ccdomain'}}) eq 'HASH') { 1898: my $domdesc = 1899: &Apache::lonnet::domain($env{'form.ccdomain'},'description'); 1900: if ($alerts{'id'}{$env{'form.ccdomain'}}{$env{'form.cid'}}) { 1901: my $userchkmsg; 1902: if (ref($curr_rules{$env{'form.ccdomain'}}) eq 'HASH') { 1903: $userchkmsg = 1904: &Apache::loncommon::instrule_disallow_msg('id', 1905: $domdesc,1). 1906: &Apache::loncommon::user_rule_formats($env{'form.ccdomain'}, 1907: $domdesc,$curr_rules{$env{'form.ccdomain'}}{'id'},'id'); 1908: } 1909: $r->print($error.&mt('Invalid ID format').$end. 1910: $userchkmsg.$rtnlink); 1911: return; 1912: } 1913: } 1914: } 1915: } 1916: # Call modifyuser 1917: my $result = &Apache::lonnet::modifyuser 1918: ($env{'form.ccdomain'},$env{'form.ccuname'},$env{'form.cid'}, 1919: $amode,$genpwd,$env{'form.cfirstname'}, 1920: $env{'form.cmiddlename'},$env{'form.clastname'}, 1921: $env{'form.cgeneration'},undef,$desiredhost, 1922: $env{'form.cpermanentemail'}); 1923: $r->print(&mt('Generating user').': '.$result); 1924: $uhome = &Apache::lonnet::homeserver($env{'form.ccuname'}, 1925: $env{'form.ccdomain'}); 1926: my (%changeHash,%newcustom,%changed); 1927: if ($uhome ne 'no_host') { 1928: if ($env{'form.customquota'} == 1) { 1929: if ($env{'form.portfolioquota'} eq '') { 1930: $newcustom{'quota'} = 0; 1931: } else { 1932: $newcustom{'quota'} = $env{'form.portfolioquota'}; 1933: $newcustom{'quota'} =~ s/[^\d\.]//g; 1934: } 1935: $changed{'quota'} = "a_admin($newcustom{'quota'},\%changeHash); 1936: } 1937: foreach my $item (@usertools) { 1938: if ($env{'form.custom'.$item} == 1) { 1939: $newcustom{$item} = $env{'form.tools_'.$item}; 1940: $changed{$item} = &tool_admin($item,$newcustom{$item}, 1941: \%changeHash,'tools'); 1942: } 1943: } 1944: foreach my $item (@requestcourses) { 1945: $newcustom{$item} = $env{'form.requestcourses_'.$item}; 1946: $changed{$item} = &tool_admin($item,$newcustom{$item}, 1947: \%changeHash,'requestcourses'); 1948: } 1949: if (exists($env{'form.inststatus'})) { 1950: my @inststatuses = &Apache::loncommon::get_env_multiple('form.inststatus'); 1951: if (@inststatuses > 0) { 1952: $changeHash{'inststatus'} = join(',',@inststatuses); 1953: $changed{'inststatus'} = $changeHash{'inststatus'}; 1954: } 1955: } 1956: if (keys(%changed)) { 1957: $changeHash{'firstname'} = $env{'form.cfirstname'}; 1958: $changeHash{'middlename'} = $env{'form.cmiddlename'}; 1959: $changeHash{'lastname'} = $env{'form.clastname'}; 1960: $changeHash{'generation'} = $env{'form.cgeneration'}; 1961: $changeHash{'id'} = $env{'form.cid'}; 1962: $changeHash{'permanentemail'} = $env{'form.cpermanentemail'}; 1963: my $chgresult = 1964: &Apache::lonnet::put('environment',\%changeHash, 1965: $env{'form.ccdomain'},$env{'form.ccuname'}); 1966: } 1967: } 1968: $r->print('<br />'.&mt('Home server').': '.$uhome.' '. 1969: &Apache::lonnet::hostname($uhome)); 1970: } elsif (($env{'form.login'} ne 'nochange') && 1971: ($env{'form.login'} ne '' )) { 1972: # Modify user privileges 1973: if (! $amode || ! $genpwd) { 1974: $r->print($error.'Invalid login mode or password'.$end.$rtnlink); 1975: return; 1976: } 1977: # Only allow authentification modification if the person has authority 1978: if (&Apache::lonnet::allowed('mau',$env{'form.ccdomain'})) { 1979: $r->print('Modifying authentication: '. 1980: &Apache::lonnet::modifyuserauth( 1981: $env{'form.ccdomain'},$env{'form.ccuname'}, 1982: $amode,$genpwd)); 1983: $r->print('<br />'.&mt('Home server').': '.&Apache::lonnet::homeserver 1984: ($env{'form.ccuname'},$env{'form.ccdomain'})); 1985: } else { 1986: # Okay, this is a non-fatal error. 1987: $r->print($error.&mt('You do not have the authority to modify this users authentification information').'.'.$end); 1988: } 1989: } 1990: ## 1991: my (@userroles,%userupdate,$cnum,$cdom,$namechanged); 1992: if ($context eq 'course') { 1993: ($cnum,$cdom) = &Apache::lonuserutils::get_course_identity(); 1994: } 1995: if (! $env{'form.makeuser'} ) { 1996: # Check for need to change 1997: my %userenv = &Apache::lonnet::get 1998: ('environment',['firstname','middlename','lastname','generation', 1999: 'id','permanentemail','portfolioquota','inststatus','tools.aboutme', 2000: 'tools.blog','tools.portfolio','requestcourses.official', 2001: 'requestcourses.unofficial'], 2002: $env{'form.ccdomain'},$env{'form.ccuname'}); 2003: my ($tmp) = keys(%userenv); 2004: if ($tmp =~ /^(con_lost|error)/i) { 2005: %userenv = (); 2006: } 2007: my $no_forceid_alert; 2008: # Check to see if user information can be changed 2009: my %domconfig = 2010: &Apache::lonnet::get_dom('configuration',['usermodification'], 2011: $env{'form.ccdomain'}); 2012: my @statuses = ('active','future'); 2013: my %roles = &Apache::lonnet::get_my_roles($env{'form.ccuname'},$env{'form.ccdomain'},'userroles',\@statuses,undef,$env{'request.role.domain'}); 2014: my ($auname,$audom); 2015: if ($context eq 'author') { 2016: $auname = $env{'user.name'}; 2017: $audom = $env{'user.domain'}; 2018: } 2019: foreach my $item (keys(%roles)) { 2020: my ($rolenum,$roledom,$role) = split(/:/,$item,-1); 2021: if ($context eq 'course') { 2022: if ($cnum ne '' && $cdom ne '') { 2023: if ($rolenum eq $cnum && $roledom eq $cdom) { 2024: if (!grep(/^\Q$role\E$/,@userroles)) { 2025: push(@userroles,$role); 2026: } 2027: } 2028: } 2029: } elsif ($context eq 'author') { 2030: if ($rolenum eq $auname && $roledom eq $audom) { 2031: if (!grep(/^\Q$role\E$/,@userroles)) { 2032: push(@userroles,$role); 2033: } 2034: } 2035: } 2036: } 2037: if ($env{'form.action'} eq 'singlestudent') { 2038: if (!grep(/^st$/,@userroles)) { 2039: push(@userroles,'st'); 2040: } 2041: } else { 2042: # Check for course or co-author roles being activated or re-enabled 2043: if ($context eq 'author' || $context eq 'course') { 2044: foreach my $key (keys(%env)) { 2045: if ($context eq 'author') { 2046: if ($key=~/^form\.act_\Q$audom\E_\Q$auname\E_([^_]+)/) { 2047: if (!grep(/^\Q$1\E$/,@userroles)) { 2048: push(@userroles,$1); 2049: } 2050: } elsif ($key =~/^form\.ren\:\Q$audom\E\/\Q$auname\E_([^_]+)/) { 2051: if (!grep(/^\Q$1\E$/,@userroles)) { 2052: push(@userroles,$1); 2053: } 2054: } 2055: } elsif ($context eq 'course') { 2056: if ($key=~/^form\.act_\Q$cdom\E_\Q$cnum\E_([^_]+)/) { 2057: if (!grep(/^\Q$1\E$/,@userroles)) { 2058: push(@userroles,$1); 2059: } 2060: } elsif ($key =~/^form\.ren\:\Q$cdom\E\/\Q$cnum\E(\/?\w*)_([^_]+)/) { 2061: if (!grep(/^\Q$1\E$/,@userroles)) { 2062: push(@userroles,$1); 2063: } 2064: } 2065: } 2066: } 2067: } 2068: } 2069: #Check to see if we can change personal data for the user 2070: my (@mod_disallowed,@longroles); 2071: foreach my $role (@userroles) { 2072: if ($role eq 'cr') { 2073: push(@longroles,'Custom'); 2074: } else { 2075: push(@longroles,&Apache::lonnet::plaintext($role)); 2076: } 2077: } 2078: my @userinfo = ('firstname','middlename','lastname','generation','permanentemail','id'); 2079: my %canmodify = &Apache::lonuserutils::can_modify_userinfo($context,$env{'form.ccdomain'},\@userinfo,\@userroles); 2080: foreach my $item (@userinfo) { 2081: # Strip leading and trailing whitespace 2082: $env{'form.c'.$item} =~ s/(\s+$|^\s+)//g; 2083: if (!$canmodify{$item}) { 2084: if (defined($env{'form.c'.$item})) { 2085: if ($env{'form.c'.$item} ne $userenv{$item}) { 2086: push(@mod_disallowed,$item); 2087: } 2088: } 2089: $env{'form.c'.$item} = $userenv{$item}; 2090: } 2091: } 2092: # Check to see if we can change the Student/Employee ID 2093: my $forceid = $env{'form.forceid'}; 2094: my $recurseid = $env{'form.recurseid'}; 2095: my (%alerts,%rulematch,%idinst_results,%curr_rules,%got_rules); 2096: my %uidhash = &Apache::lonnet::idrget($env{'form.ccdomain'}, 2097: $env{'form.ccuname'}); 2098: if (($uidhash{$env{'form.ccuname'}}) && 2099: ($uidhash{$env{'form.ccuname'}}!~/error\:/) && 2100: (!$forceid)) { 2101: if ($env{'form.cid'} ne $uidhash{$env{'form.ccuname'}}) { 2102: $env{'form.cid'} = $userenv{'id'}; 2103: $no_forceid_alert = &mt('New student/employee ID does not match existing ID for this user.') 2104: .'<br />' 2105: .&mt("Change is not permitted without checking the 'Force ID change' checkbox on the previous page.") 2106: .'<br />'."\n"; 2107: } 2108: } 2109: if ($env{'form.cid'} ne $userenv{'id'}) { 2110: my $checkhash; 2111: my $checks = { 'id' => 1 }; 2112: $checkhash->{$env{'form.ccuname'}.':'.$env{'form.ccdomain'}} = 2113: { 'newuser' => $newuser, 2114: 'id' => $env{'form.cid'}, 2115: }; 2116: &Apache::loncommon::user_rule_check($checkhash,$checks, 2117: \%alerts,\%rulematch,\%idinst_results,\%curr_rules,\%got_rules); 2118: if (ref($alerts{'id'}) eq 'HASH') { 2119: if (ref($alerts{'id'}{$env{'form.ccdomain'}}) eq 'HASH') { 2120: $env{'form.cid'} = $userenv{'id'}; 2121: } 2122: } 2123: } 2124: my ($quotachanged,$oldportfolioquota,$newportfolioquota,$oldinststatus, 2125: $inststatus,$newinststatus,$oldisdefault,$newisdefault,$olddefquotatext, 2126: $newdefquotatext,%oldaccess,%oldaccesstext,%newaccess,%newaccesstext, 2127: $oldinststatuses,$newinststatuses); 2128: my ($defquota,$settingstatus) = 2129: &Apache::loncommon::default_quota($env{'form.ccdomain'},$inststatus); 2130: my ($showquota,$showtools,$showrequestcourses,$showinststatus); 2131: if (&Apache::lonnet::allowed('mpq',$env{'form.ccdomain'})) { 2132: $showquota = 1; 2133: } 2134: if (&Apache::lonnet::allowed('mut',$env{'form.ccdomain'})) { 2135: $showtools = 1; 2136: } 2137: if (&Apache::lonnet::allowed('ccc',$env{'form.ccdomain'})) { 2138: $showrequestcourses = 1; 2139: } 2140: if (&Apache::lonnet::allowed('mau',$env{'form.ccdomain'})) { 2141: $showinststatus = 1; 2142: } 2143: my (%changeHash,%changed); 2144: $oldinststatus = $userenv{'inststatus'}; 2145: if ($oldinststatus eq '') { 2146: $oldinststatuses = $othertitle; 2147: } else { 2148: if (ref($usertypes) eq 'HASH') { 2149: $oldinststatuses = join(', ',map{ $usertypes->{ &unescape($_) }; } (split(/:/,$userenv{'inststatus'}))); 2150: } else { 2151: $oldinststatuses = join(', ',map{ &unescape($_); } (split(/:/,$userenv{'inststatus'}))); 2152: } 2153: } 2154: $changeHash{'inststatus'} = $userenv{'inststatus'}; 2155: my %canmodify_inststatus = &Apache::lonuserutils::can_modify_userinfo($context,$env{'form.ccdomain'},['inststatus'],\@userroles); 2156: if ($canmodify_inststatus{'inststatus'}) { 2157: if (exists($env{'form.inststatus'})) { 2158: my @inststatuses = &Apache::loncommon::get_env_multiple('form.inststatus'); 2159: if (@inststatuses > 0) { 2160: $newinststatus = join(':',map { &escape($_); } @inststatuses); 2161: $changeHash{'inststatus'} = $newinststatus; 2162: if ($newinststatus ne $oldinststatus) { 2163: $changed{'inststatus'} = $newinststatus; 2164: } 2165: if (ref($usertypes) eq 'HASH') { 2166: $newinststatuses = join(', ',map{ $usertypes->{$_}; } (@inststatuses)); 2167: } else { 2168: $newinststatuses = join(', ',map{ $usertypes->{$_}; } (@inststatuses)); 2169: } 2170: } else { 2171: $newinststatus = ''; 2172: $changeHash{'inststatus'} = $newinststatus; 2173: $newinststatuses = $othertitle; 2174: if ($newinststatus ne $oldinststatus) { 2175: $changed{'inststatus'} = $changeHash{'inststatus'}; 2176: } 2177: } 2178: } 2179: } 2180: $changeHash{'portfolioquota'} = $userenv{'portfolioquota'}; 2181: if ($userenv{'portfolioquota'} ne '') { 2182: $oldportfolioquota = $userenv{'portfolioquota'}; 2183: if ($env{'form.customquota'} == 1) { 2184: if ($env{'form.portfolioquota'} eq '') { 2185: $newportfolioquota = 0; 2186: } else { 2187: $newportfolioquota = $env{'form.portfolioquota'}; 2188: $newportfolioquota =~ s/[^\d\.]//g; 2189: } 2190: if ($newportfolioquota != $oldportfolioquota) { 2191: $changed{'quota'} = "a_admin($newportfolioquota,\%changeHash); 2192: } 2193: } else { 2194: $changed{'quota'} = "a_admin('',\%changeHash); 2195: $newportfolioquota = $defquota; 2196: $newisdefault = 1; 2197: } 2198: } else { 2199: $oldisdefault = 1; 2200: $oldportfolioquota = $defquota; 2201: if ($env{'form.customquota'} == 1) { 2202: if ($env{'form.portfolioquota'} eq '') { 2203: $newportfolioquota = 0; 2204: } else { 2205: $newportfolioquota = $env{'form.portfolioquota'}; 2206: $newportfolioquota =~ s/[^\d\.]//g; 2207: } 2208: $changed{'quota'} = "a_admin($newportfolioquota,\%changeHash); 2209: } else { 2210: $newportfolioquota = $defquota; 2211: $newisdefault = 1; 2212: } 2213: } 2214: if ($oldisdefault) { 2215: $olddefquotatext = &get_defaultquota_text($settingstatus); 2216: } 2217: if ($newisdefault) { 2218: $newdefquotatext = &get_defaultquota_text($settingstatus); 2219: } 2220: &tool_changes('tools',\@usertools,\%oldaccess,\%oldaccesstext,\%userenv, 2221: \%changeHash,\%changed,\%newaccess,\%newaccesstext); 2222: &tool_changes('requestcourses',\@requestcourses,\%oldaccess,\%oldaccesstext, 2223: \%userenv, \%changeHash,\%changed,\%newaccess,\%newaccesstext); 2224: if ($env{'form.cfirstname'} ne $userenv{'firstname'} || 2225: $env{'form.cmiddlename'} ne $userenv{'middlename'} || 2226: $env{'form.clastname'} ne $userenv{'lastname'} || 2227: $env{'form.cgeneration'} ne $userenv{'generation'} || 2228: $env{'form.cid'} ne $userenv{'id'} || 2229: $env{'form.cpermanentemail'} ne $userenv{'permanentemail'} ) { 2230: $namechanged = 1; 2231: } 2232: if (($namechanged) || (keys(%changed) > 0)) { 2233: $changeHash{'firstname'} = $env{'form.cfirstname'}; 2234: $changeHash{'middlename'} = $env{'form.cmiddlename'}; 2235: $changeHash{'lastname'} = $env{'form.clastname'}; 2236: $changeHash{'generation'} = $env{'form.cgeneration'}; 2237: $changeHash{'id'} = $env{'form.cid'}; 2238: $changeHash{'permanentemail'} = $env{'form.cpermanentemail'}; 2239: my ($chgresult,$namechgresult); 2240: if (keys(%changed) > 0) { 2241: $chgresult = 2242: &Apache::lonnet::put('environment',\%changeHash, 2243: $env{'form.ccdomain'},$env{'form.ccuname'}); 2244: if ($chgresult eq 'ok') { 2245: if (($env{'user.name'} eq $env{'form.ccuname'}) && 2246: ($env{'user.domain'} eq $env{'form.ccdomain'})) { 2247: my %newenvhash; 2248: foreach my $key (keys(%changed)) { 2249: if (($key eq 'official') || ($key eq 'unofficial')) { 2250: $newenvhash{'environment.requestcourses.'.$key} = 2251: $changeHash{'requestcourses.'.$key}; 2252: if ($changeHash{'requestcourses.'.$key} ne '') { 2253: $newenvhash{'environment.canrequest.'.$key} = 2254: $changeHash{'requestcourses.'.$key}; 2255: } else { 2256: $newenvhash{'environment.canrequest.'.$key} = 2257: &Apache::lonnet::usertools_access($env{'user.name'},$env{'user.domain'}, 2258: $key,'reload','requestcourses'); 2259: } 2260: } elsif ($key ne 'quota') { 2261: $newenvhash{'environment.tools.'.$key} = 2262: $changeHash{'tools.'.$key}; 2263: if ($changeHash{'tools.'.$key} ne '') { 2264: $newenvhash{'environment.availabletools.'.$key} = 2265: $changeHash{'tools.'.$key}; 2266: } else { 2267: $newenvhash{'environment.availabletools.'.$key} = 2268: &Apache::lonnet::usertools_access($env{'user.name'},$env{'user.domain'}, $key,'reload','tools'); 2269: } 2270: } 2271: } 2272: if (keys(%newenvhash)) { 2273: &Apache::lonnet::appenv(\%newenvhash); 2274: } 2275: } 2276: } 2277: } 2278: if ($namechanged) { 2279: # Make the change 2280: $namechgresult = 2281: &Apache::lonnet::modifyuser($env{'form.ccdomain'}, 2282: $env{'form.ccuname'},$changeHash{'id'},undef,undef, 2283: $changeHash{'firstname'},$changeHash{'middlename'}, 2284: $changeHash{'lastname'},$changeHash{'generation'}, 2285: $changeHash{'id'},undef,$changeHash{'permanentemail'}); 2286: %userupdate = ( 2287: lastname => $env{'form.clastname'}, 2288: middlename => $env{'form.cmiddlename'}, 2289: firstname => $env{'form.cfirstname'}, 2290: generation => $env{'form.cgeneration'}, 2291: id => $env{'form.cid'}, 2292: ); 2293: } 2294: if (($namechanged && $namechgresult eq 'ok') || 2295: ((keys(%changed) > 0) && $chgresult eq 'ok')) { 2296: # Tell the user we changed the name 2297: my %lt=&Apache::lonlocal::texthash( 2298: 'uic' => 'User Information Changed', 2299: 'frst' => 'First Name', 2300: 'mddl' => 'Middle Name', 2301: 'lst' => 'Last Name', 2302: 'gen' => 'Generation', 2303: 'id' => 'Student/Employee ID', 2304: 'mail' => 'Permanent e-mail address', 2305: 'disk' => 'Disk space allocated to portfolio files', 2306: 'blog' => 'Blog Availability', 2307: 'aboutme' => 'Personal Information Page Availability', 2308: 'portfolio' => 'Portfolio Availability', 2309: 'official' => 'Can Request Official Courses', 2310: 'unofficial' => 'Can Request Unofficial Courses', 2311: 'inststatus' => "Affiliation", 2312: 'prvs' => 'Previous Value:', 2313: 'chto' => 'Changed To:' 2314: ); 2315: $r->print('<h4>'.$lt{'uic'}.'</h4>'. 2316: &Apache::loncommon::start_data_table(). 2317: &Apache::loncommon::start_data_table_header_row()); 2318: $r->print(<<"END"); 2319: <th> </th> 2320: <th>$lt{'frst'}</th> 2321: <th>$lt{'mddl'}</th> 2322: <th>$lt{'lst'}</th> 2323: <th>$lt{'gen'}</th> 2324: <th>$lt{'id'}</th> 2325: <th>$lt{'mail'}</th> 2326: END 2327: if ($showinststatus) { 2328: $r->print(" 2329: <th>$lt{'inststatus'}</th>\n"); 2330: } 2331: if ($showrequestcourses) { 2332: foreach my $item (@requestcourses) { 2333: $r->print(" 2334: <th>$lt{$item}</th>\n"); 2335: } 2336: } 2337: if ($showquota) { 2338: $r->print(" 2339: <th>$lt{'disk'}</th>\n"); 2340: } 2341: if ($showtools) { 2342: foreach my $item (@usertools) { 2343: $r->print(" 2344: <th>$lt{$item}</th>\n"); 2345: } 2346: } 2347: $r->print(&Apache::loncommon::end_data_table_header_row(). 2348: &Apache::loncommon::start_data_table_row()); 2349: $r->print(<<"END"); 2350: <td><b>$lt{'prvs'}</b></td> 2351: <td>$userenv{'firstname'} </td> 2352: <td>$userenv{'middlename'} </td> 2353: <td>$userenv{'lastname'} </td> 2354: <td>$userenv{'generation'} </td> 2355: <td>$userenv{'id'}</td> 2356: <td>$userenv{'permanentemail'} </td> 2357: END 2358: if ($showinststatus) { 2359: $r->print(" 2360: <td>$oldinststatuses</td>\n"); 2361: } 2362: if ($showrequestcourses) { 2363: foreach my $item (@requestcourses) { 2364: $r->print(" 2365: <td>$oldaccess{$item} $oldaccesstext{$item}</td>\n"); 2366: } 2367: } 2368: if ($showquota) { 2369: $r->print(" 2370: <td>$oldportfolioquota Mb $olddefquotatext </td>\n"); 2371: } 2372: if ($showtools) { 2373: foreach my $item (@usertools) { 2374: $r->print(" 2375: <td>$oldaccess{$item} $oldaccesstext{$item} </td>\n"); 2376: } 2377: } 2378: $r->print(&Apache::loncommon::end_data_table_row(). 2379: &Apache::loncommon::start_data_table_row()); 2380: $r->print(<<"END"); 2381: <td><span class="LC_nobreak"><b>$lt{'chto'}</b></span></td> 2382: <td>$env{'form.cfirstname'} </td> 2383: <td>$env{'form.cmiddlename'} </td> 2384: <td>$env{'form.clastname'} </td> 2385: <td>$env{'form.cgeneration'} </td> 2386: <td>$env{'form.cid'} </td> 2387: <td>$env{'form.cpermanentemail'} </td> 2388: END 2389: if ($showinststatus) { 2390: $r->print(" 2391: <td>$newinststatuses</td>\n"); 2392: } 2393: if ($showrequestcourses) { 2394: foreach my $item (@requestcourses) { 2395: $r->print(" 2396: <td>$newaccess{$item} $newaccesstext{$item} </td>\n"); 2397: } 2398: } 2399: if ($showquota) { 2400: $r->print(" 2401: <td>$newportfolioquota Mb $newdefquotatext </td>\n"); 2402: } 2403: if ($showtools) { 2404: foreach my $item (@usertools) { 2405: $r->print(" 2406: <td>$newaccess{$item} $newaccesstext{$item} </td>\n"); 2407: } 2408: } 2409: $r->print(&Apache::loncommon::end_data_table_row(). 2410: &Apache::loncommon::end_data_table().'<br />'); 2411: if ($env{'form.cid'} ne $userenv{'id'}) { 2412: &Apache::lonnet::idput($env{'form.ccdomain'}, 2413: ($env{'form.ccuname'} => $env{'form.cid'})); 2414: if (($recurseid) && 2415: (&Apache::lonnet::allowed('mau',$env{'form.ccdomain'}))) { 2416: my $idresult = 2417: &Apache::lonuserutils::propagate_id_change( 2418: $env{'form.ccuname'},$env{'form.ccdomain'}, 2419: \%userupdate); 2420: $r->print('<br />'.$idresult.'<br />'); 2421: } 2422: } 2423: if (($env{'form.ccdomain'} eq $env{'user.domain'}) && 2424: ($env{'form.ccuname'} eq $env{'user.name'})) { 2425: my %newenvhash; 2426: foreach my $key (keys(%changeHash)) { 2427: $newenvhash{'environment.'.$key} = $changeHash{$key}; 2428: } 2429: &Apache::lonnet::appenv(\%newenvhash); 2430: } 2431: } else { # error occurred 2432: $r->print('<span class="LC_error">'.&mt('Unable to successfully change environment for').' '. 2433: $env{'form.ccuname'}.' '.&mt('in domain').' '. 2434: $env{'form.ccdomain'}.'</span><br />'); 2435: } 2436: } else { # End of if ($env ... ) logic 2437: # They did not want to change the users name, quota, tool availability, 2438: # or ability to request creation of courses, 2439: # but we can still tell them what the name and quota and availabilities are 2440: my %lt=&Apache::lonlocal::texthash( 2441: 'id' => "Student/Employee ID", 2442: 'mail' => "Permanent e-mail address", 2443: 'disk' => "Disk space allocated to user's portfolio files", 2444: 'blog' => "Blog Availability", 2445: 'aboutme' => "Personal Information Page Availability", 2446: 'portfolio' => "Portfolio Availability", 2447: 'official' => "Can Request Official Courses", 2448: 'unofficial' => "Can Request Unofficial Course", 2449: 'inststatus' => "Affiliation", 2450: ); 2451: $r->print(<<"END"); 2452: <h4>$userenv{'firstname'} $userenv{'middlename'} $userenv{'lastname'} $userenv{'generation'} 2453: END 2454: if ($userenv{'permanentemail'} ne '') { 2455: $r->print('<br />['.$lt{'mail'}.': '. 2456: $userenv{'permanentemail'}.']'); 2457: } 2458: if ($showinststatus) { 2459: $r->print('<br />['.$lt{'inststatus'}.': '.$oldinststatuses.']'); 2460: } 2461: if ($showrequestcourses) { 2462: foreach my $item (@requestcourses) { 2463: $r->print('<br />['.$lt{$item}.': '.$newaccess{$item}.' '. 2464: $newaccesstext{$item}.']'."\n"); 2465: } 2466: } 2467: if ($showtools) { 2468: foreach my $item (@usertools) { 2469: $r->print('<br />['.$lt{$item}.': '.$newaccess{$item}.' '. 2470: $newaccesstext{$item}.']'."\n"); 2471: } 2472: } 2473: if ($showquota) { 2474: $r->print('<br />['.$lt{'disk'}.': '.$oldportfolioquota.' Mb '. 2475: $olddefquotatext.']'); 2476: } 2477: $r->print('</h4>'); 2478: } 2479: if (@mod_disallowed) { 2480: my ($rolestr,$contextname); 2481: if (@longroles > 0) { 2482: $rolestr = join(', ',@longroles); 2483: } else { 2484: $rolestr = &mt('No roles'); 2485: } 2486: if ($context eq 'course') { 2487: $contextname = &mt('course'); 2488: } elsif ($context eq 'author') { 2489: $contextname = &mt('co-author'); 2490: } 2491: $r->print(&mt('The following fields were not updated: ').'<ul>'); 2492: my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles(); 2493: foreach my $field (@mod_disallowed) { 2494: $r->print('<li>'.$fieldtitles{$field}.'</li>'."\n"); 2495: } 2496: $r->print('</ul>'); 2497: if (@mod_disallowed == 1) { 2498: $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)); 2499: } else { 2500: $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)); 2501: } 2502: my $helplink = 'javascript:helpMenu('."'display'".')'; 2503: $r->print('<span class="LC_cusr_emph">'.$rolestr.'</span><br />' 2504: .&mt('Please contact your [_1]helpdesk[_2] for more information.' 2505: ,'<a href="'.$helplink.'">','</a>') 2506: .'<br />'); 2507: } 2508: $r->print('<span class="LC_warning">' 2509: .$no_forceid_alert 2510: .&Apache::lonuserutils::print_namespacing_alerts($env{'form.ccdomain'},\%alerts,\%curr_rules) 2511: .'</span>'); 2512: } 2513: if ($env{'form.action'} eq 'singlestudent') { 2514: &enroll_single_student($r,$uhome,$amode,$genpwd,$now,$newuser,$context); 2515: $r->print('<p><a href="javascript:backPage(document.userupdate)">'. 2516: &mt('Enroll Another Student').'</a></p>'); 2517: } else { 2518: my @rolechanges = &update_roles($r,$context); 2519: if ($namechanged) { 2520: if ($context eq 'course') { 2521: if (@userroles > 0) { 2522: if ((@rolechanges == 0) || 2523: (!(grep(/^st$/,@rolechanges)))) { 2524: if (grep(/^st$/,@userroles)) { 2525: my $classlistupdated = 2526: &Apache::lonuserutils::update_classlist($cdom, 2527: $cnum,$env{'form.ccdomain'}, 2528: $env{'form.ccuname'},\%userupdate); 2529: } 2530: } 2531: } 2532: } 2533: } 2534: my $userinfo = &Apache::loncommon::plainname($env{'form.ccuname'}, 2535: $env{'form.ccdomain'}); 2536: if ($env{'form.popup'}) { 2537: $r->print('<p><a href="javascript:window.close()">'.&mt('Close window').'</a></p>'); 2538: } else { 2539: $r->print('<p><a href="javascript:backPage(document.userupdate,'."'$env{'form.prevphase'}','modify'".')">' 2540: .&mt('Modify this user: [_1]','<span class="LC_cusr_emph">'.$env{'form.ccuname'}.':'.$env{'form.ccdomain'}.' ('.$userinfo.')</span>').'</a>' 2541: .(' 'x5).'<a href="javascript:backPage(document.userupdate)">' 2542: .&mt('Create/Modify Another User').'</a></p>'); 2543: } 2544: } 2545: $r->print(&Apache::loncommon::end_page()); 2546: } 2547: 2548: sub tool_changes { 2549: my ($context,$usertools,$oldaccess,$oldaccesstext,$userenv,$changeHash, 2550: $changed,$newaccess,$newaccesstext) = @_; 2551: if (!((ref($usertools) eq 'ARRAY') && (ref($oldaccess) eq 'HASH') && 2552: (ref($oldaccesstext) eq 'HASH') && (ref($userenv) eq 'HASH') && 2553: (ref($changeHash) eq 'HASH') && (ref($changed) eq 'HASH') && 2554: (ref($newaccess) eq 'HASH') && (ref($newaccesstext) eq 'HASH'))) { 2555: return; 2556: } 2557: foreach my $tool (@{$usertools}) { 2558: if ($userenv->{$context.'.'.$tool} ne '') { 2559: $oldaccess->{$tool} = &mt('custom'); 2560: if ($userenv->{$context.'.'.$tool}) { 2561: $oldaccesstext->{$tool} = &mt("availability set to 'on'"); 2562: } else { 2563: $oldaccesstext->{$tool} = &mt("availability set to 'off'"); 2564: } 2565: $changeHash->{$context.'.'.$tool} = $userenv->{$context.'.'.$tool}; 2566: if ($env{'form.custom'.$tool} == 1) { 2567: if ($env{'form.'.$context.'_'.$tool} ne $userenv->{$context.'.'.$tool}) { 2568: $changed->{$tool} = &tool_admin($tool,$env{'form.'.$context.'_'.$tool}, 2569: $changeHash,$context); 2570: if ($changed->{$tool}) { 2571: $newaccess->{$tool} = &mt('custom'); 2572: if ($env{'form.'.$context.'_'.$tool}) { 2573: $newaccesstext->{$tool} = &mt("availability set to 'on'"); 2574: } else { 2575: $newaccesstext->{$tool} = &mt("availability set to 'off'"); 2576: } 2577: } else { 2578: $newaccess->{$tool} = $oldaccess->{$tool}; 2579: if ($userenv->{$context.'.'.$tool}) { 2580: $newaccesstext->{$tool} = &mt("availability set to 'on'"); 2581: } else { 2582: $newaccesstext->{$tool} = &mt("availability set to 'off'"); 2583: } 2584: } 2585: } else { 2586: $newaccess->{$tool} = $oldaccess->{$tool}; 2587: $newaccesstext->{$tool} = $oldaccesstext->{$tool}; 2588: } 2589: } else { 2590: $changed->{$tool} = &tool_admin($tool,'',$changeHash,$context); 2591: if ($changed->{$tool}) { 2592: $newaccess->{$tool} = &mt('default'); 2593: } else { 2594: $newaccess->{$tool} = $oldaccess->{$tool}; 2595: if ($userenv->{$context.'.'.$tool}) { 2596: $newaccesstext->{$tool} = &mt("availability set to 'on'"); 2597: } else { 2598: $newaccesstext->{$tool} = &mt("availability set to 'off'"); 2599: } 2600: } 2601: } 2602: } else { 2603: $oldaccess->{$tool} = &mt('default'); 2604: if ($env{'form.custom'.$tool} == 1) { 2605: $changed->{$tool} = &tool_admin($tool,$env{'form.'.$context.'_'.$tool}, 2606: $changeHash,$context); 2607: if ($changed->{$tool}) { 2608: $newaccess->{$tool} = &mt('custom'); 2609: if ($env{'form.'.$context.'_'.$tool}) { 2610: $newaccesstext->{$tool} = &mt("availability set to 'on'"); 2611: } else { 2612: $newaccesstext->{$tool} = &mt("availability set to 'off'"); 2613: } 2614: } else { 2615: $newaccess->{$tool} = $oldaccess->{$tool}; 2616: } 2617: } else { 2618: $newaccess->{$tool} = $oldaccess->{$tool}; 2619: } 2620: } 2621: } 2622: return; 2623: } 2624: 2625: sub update_roles { 2626: my ($r,$context) = @_; 2627: my $now=time; 2628: my @rolechanges; 2629: my %disallowed; 2630: $r->print('<h3>'.&mt('Modifying Roles').'</h3>'); 2631: foreach my $key (keys (%env)) { 2632: next if (! $env{$key}); 2633: next if ($key eq 'form.action'); 2634: # Revoke roles 2635: if ($key=~/^form\.rev/) { 2636: if ($key=~/^form\.rev\:([^\_]+)\_([^\_\.]+)$/) { 2637: # Revoke standard role 2638: my ($scope,$role) = ($1,$2); 2639: my $result = 2640: &Apache::lonnet::revokerole($env{'form.ccdomain'}, 2641: $env{'form.ccuname'}, 2642: $scope,$role,'','',$context); 2643: $r->print(&mt('Revoking [_1] in [_2]: [_3]', 2644: $role,$scope,'<b>'.$result.'</b>').'<br />'); 2645: if ($role eq 'st') { 2646: my $result = 2647: &Apache::lonuserutils::classlist_drop($scope, 2648: $env{'form.ccuname'},$env{'form.ccdomain'}, 2649: $now); 2650: $r->print($result); 2651: } 2652: if (!grep(/^\Q$role\E$/,@rolechanges)) { 2653: push(@rolechanges,$role); 2654: } 2655: } 2656: if ($key=~m{^form\.rev\:([^_]+)_cr\.cr/($match_domain)/($match_username)/(\w+)$}s) { 2657: # Revoke custom role 2658: $r->print(&mt('Revoking custom role:'). 2659: ' '.$4.' by '.$3.':'.$2.' in '.$1.': <b>'. 2660: &Apache::lonnet::revokecustomrole($env{'form.ccdomain'}, 2661: $env{'form.ccuname'},$1,$2,$3,$4,'','',$context). 2662: '</b><br />'); 2663: if (!grep(/^cr$/,@rolechanges)) { 2664: push(@rolechanges,'cr'); 2665: } 2666: } 2667: } elsif ($key=~/^form\.del/) { 2668: if ($key=~/^form\.del\:([^\_]+)\_([^\_\.]+)$/) { 2669: # Delete standard role 2670: my ($scope,$role) = ($1,$2); 2671: my $result = 2672: &Apache::lonnet::assignrole($env{'form.ccdomain'}, 2673: $env{'form.ccuname'}, 2674: $scope,$role,$now,0,1,'', 2675: $context); 2676: $r->print(&mt('Deleting [_1] in [_2]: [_3]',$role,$scope, 2677: '<b>'.$result.'</b>').'<br />'); 2678: if ($role eq 'st') { 2679: my $result = 2680: &Apache::lonuserutils::classlist_drop($scope, 2681: $env{'form.ccuname'},$env{'form.ccdomain'}, 2682: $now); 2683: $r->print($result); 2684: } 2685: if (!grep(/^\Q$role\E$/,@rolechanges)) { 2686: push(@rolechanges,$role); 2687: } 2688: } 2689: if ($key=~m{^form\.del\:([^_]+)_cr\.cr/($match_domain)/($match_username)/(\w+)$}) { 2690: my ($url,$rdom,$rnam,$rolename) = ($1,$2,$3,$4); 2691: # Delete custom role 2692: $r->print(&mt('Deleting custom role [_1] by [_2] in [_3]', 2693: $rolename,$rnam.':'.$rdom,$url).': <b>'. 2694: &Apache::lonnet::assigncustomrole($env{'form.ccdomain'}, 2695: $env{'form.ccuname'},$url,$rdom,$rnam,$rolename,$now, 2696: 0,1,$context).'</b><br />'); 2697: if (!grep(/^cr$/,@rolechanges)) { 2698: push(@rolechanges,'cr'); 2699: } 2700: } 2701: } elsif ($key=~/^form\.ren/) { 2702: my $udom = $env{'form.ccdomain'}; 2703: my $uname = $env{'form.ccuname'}; 2704: # Re-enable standard role 2705: if ($key=~/^form\.ren\:([^\_]+)\_([^\_\.]+)$/) { 2706: my $url = $1; 2707: my $role = $2; 2708: my $logmsg; 2709: my $output; 2710: if ($role eq 'st') { 2711: if ($url =~ m-^/($match_domain)/($match_courseid)/?(\w*)$-) { 2712: my $result = &Apache::loncommon::commit_studentrole(\$logmsg,$udom,$uname,$url,$role,$now,0,$1,$2,$3); 2713: if (($result =~ /^error/) || ($result eq 'not_in_class') || ($result eq 'unknown_course') || ($result eq 'refused')) { 2714: if ($result eq 'refused' && $logmsg) { 2715: $output = $logmsg; 2716: } else { 2717: $output = "Error: $result\n"; 2718: } 2719: } else { 2720: $output = &mt('Assigning').' '.$role.' in '.$url. 2721: &mt('starting').' '.localtime($now). 2722: ': <br />'.$logmsg.'<br />'. 2723: &mt('Add to classlist').': <b>ok</b><br />'; 2724: } 2725: } 2726: } else { 2727: my $result=&Apache::lonnet::assignrole($env{'form.ccdomain'}, 2728: $env{'form.ccuname'},$url,$role,0,$now,'','', 2729: $context); 2730: $output = &mt('Re-enabling [_1] in [_2]: [_3]', 2731: $role,$url,'<b>'.$result.'</b>').'<br />'; 2732: } 2733: $r->print($output); 2734: if (!grep(/^\Q$role\E$/,@rolechanges)) { 2735: push(@rolechanges,$role); 2736: } 2737: } 2738: # Re-enable custom role 2739: if ($key=~m{^form\.ren\:([^_]+)_cr\.cr/($match_domain)/($match_username)/(\w+)$}) { 2740: my ($url,$rdom,$rnam,$rolename) = ($1,$2,$3,$4); 2741: my $result = &Apache::lonnet::assigncustomrole( 2742: $env{'form.ccdomain'}, $env{'form.ccuname'}, 2743: $url,$rdom,$rnam,$rolename,0,$now,undef,$context); 2744: $r->print(&mt('Re-enabling custom role [_1] by [_2] in [_3]: [_4]', 2745: $rolename,$rnam.':'.$rdom,$url,'<b>'.$result.'</b>').'<br />'); 2746: if (!grep(/^cr$/,@rolechanges)) { 2747: push(@rolechanges,'cr'); 2748: } 2749: } 2750: } elsif ($key=~/^form\.act/) { 2751: my $udom = $env{'form.ccdomain'}; 2752: my $uname = $env{'form.ccuname'}; 2753: if ($key=~/^form\.act\_($match_domain)\_($match_courseid)\_cr_cr_($match_domain)_($match_username)_([^\_]+)$/) { 2754: # Activate a custom role 2755: my ($one,$two,$three,$four,$five)=($1,$2,$3,$4,$5); 2756: my $url='/'.$one.'/'.$two; 2757: my $full=$one.'_'.$two.'_cr_cr_'.$three.'_'.$four.'_'.$five; 2758: 2759: my $start = ( $env{'form.start_'.$full} ? 2760: $env{'form.start_'.$full} : 2761: $now ); 2762: my $end = ( $env{'form.end_'.$full} ? 2763: $env{'form.end_'.$full} : 2764: 0 ); 2765: 2766: # split multiple sections 2767: my %sections = (); 2768: my $num_sections = &build_roles($env{'form.sec_'.$full},\%sections,$5); 2769: if ($num_sections == 0) { 2770: $r->print(&Apache::loncommon::commit_customrole($udom,$uname,$url,$three,$four,$five,$start,$end,$context)); 2771: } else { 2772: my %curr_groups = 2773: &Apache::longroup::coursegroups($one,$two); 2774: foreach my $sec (sort {$a cmp $b} keys %sections) { 2775: if (($sec eq 'none') || ($sec eq 'all') || 2776: exists($curr_groups{$sec})) { 2777: $disallowed{$sec} = $url; 2778: next; 2779: } 2780: my $securl = $url.'/'.$sec; 2781: $r->print(&Apache::loncommon::commit_customrole($udom,$uname,$securl,$three,$four,$five,$start,$end,$context)); 2782: } 2783: } 2784: if (!grep(/^cr$/,@rolechanges)) { 2785: push(@rolechanges,'cr'); 2786: } 2787: } elsif ($key=~/^form\.act\_($match_domain)\_($match_name)\_([^\_]+)$/) { 2788: # Activate roles for sections with 3 id numbers 2789: # set start, end times, and the url for the class 2790: my ($one,$two,$three)=($1,$2,$3); 2791: my $start = ( $env{'form.start_'.$one.'_'.$two.'_'.$three} ? 2792: $env{'form.start_'.$one.'_'.$two.'_'.$three} : 2793: $now ); 2794: my $end = ( $env{'form.end_'.$one.'_'.$two.'_'.$three} ? 2795: $env{'form.end_'.$one.'_'.$two.'_'.$three} : 2796: 0 ); 2797: my $url='/'.$one.'/'.$two; 2798: my $type = 'three'; 2799: # split multiple sections 2800: my %sections = (); 2801: my $num_sections = &build_roles($env{'form.sec_'.$one.'_'.$two.'_'.$three},\%sections,$three); 2802: if ($num_sections == 0) { 2803: $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$three,$start,$end,$one,$two,'',$context)); 2804: } else { 2805: my %curr_groups = 2806: &Apache::longroup::coursegroups($one,$two); 2807: my $emptysec = 0; 2808: foreach my $sec (sort {$a cmp $b} keys %sections) { 2809: $sec =~ s/\W//g; 2810: if ($sec ne '') { 2811: if (($sec eq 'none') || ($sec eq 'all') || 2812: exists($curr_groups{$sec})) { 2813: $disallowed{$sec} = $url; 2814: next; 2815: } 2816: my $securl = $url.'/'.$sec; 2817: $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$securl,$three,$start,$end,$one,$two,$sec,$context)); 2818: } else { 2819: $emptysec = 1; 2820: } 2821: } 2822: if ($emptysec) { 2823: $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$three,$start,$end,$one,$two,'',$context)); 2824: } 2825: } 2826: if (!grep(/^\Q$three\E$/,@rolechanges)) { 2827: push(@rolechanges,$three); 2828: } 2829: } elsif ($key=~/^form\.act\_([^\_]+)\_([^\_]+)$/) { 2830: # Activate roles for sections with two id numbers 2831: # set start, end times, and the url for the class 2832: my $start = ( $env{'form.start_'.$1.'_'.$2} ? 2833: $env{'form.start_'.$1.'_'.$2} : 2834: $now ); 2835: my $end = ( $env{'form.end_'.$1.'_'.$2} ? 2836: $env{'form.end_'.$1.'_'.$2} : 2837: 0 ); 2838: my $one = $1; 2839: my $two = $2; 2840: my $url='/'.$one.'/'; 2841: # split multiple sections 2842: my %sections = (); 2843: my $num_sections = &build_roles($env{'form.sec_'.$one.'_'.$two},\%sections,$two); 2844: if ($num_sections == 0) { 2845: $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$two,$start,$end,$one,undef,'',$context)); 2846: } else { 2847: my $emptysec = 0; 2848: foreach my $sec (sort {$a cmp $b} keys %sections) { 2849: if ($sec ne '') { 2850: my $securl = $url.'/'.$sec; 2851: $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$securl,$two,$start,$end,$one,undef,$sec,$context)); 2852: } else { 2853: $emptysec = 1; 2854: } 2855: } 2856: if ($emptysec) { 2857: $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$two,$start,$end,$one,undef,'',$context)); 2858: } 2859: } 2860: if (!grep(/^\Q$two\E$/,@rolechanges)) { 2861: push(@rolechanges,$two); 2862: } 2863: } else { 2864: $r->print('<p><span class="LC_error">'.&mt('ERROR').': '.&mt('Unknown command').' <tt>'.$key.'</tt></span></p><br />'); 2865: } 2866: foreach my $key (sort(keys(%disallowed))) { 2867: $r->print('<p class="LC_warning">'); 2868: if (($key eq 'none') || ($key eq 'all')) { 2869: $r->print(&mt('[_1] may not be used as the name for a section, as it is a reserved word.','<tt>'.$key.'</tt>')); 2870: } else { 2871: $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>')); 2872: } 2873: $r->print('</p><p>' 2874: .&mt('Please [_1]go back[_2] and choose a different section name.' 2875: ,'<a href="javascript:history.go(-1)' 2876: ,'</a>') 2877: .'</p><br />' 2878: ); 2879: } 2880: } 2881: } # End of foreach (keys(%env)) 2882: # Flush the course logs so reverse user roles immediately updated 2883: &Apache::lonnet::flushcourselogs(); 2884: if (@rolechanges == 0) { 2885: $r->print(&mt('No roles to modify')); 2886: } 2887: return @rolechanges; 2888: } 2889: 2890: sub enroll_single_student { 2891: my ($r,$uhome,$amode,$genpwd,$now,$newuser,$context) = @_; 2892: $r->print('<h3>'.&mt('Enrolling Student').'</h3>'); 2893: 2894: # Remove non alphanumeric values from section 2895: $env{'form.sections'}=~s/\W//g; 2896: 2897: # Clean out any old student roles the user has in this class. 2898: &Apache::lonuserutils::modifystudent($env{'form.ccdomain'}, 2899: $env{'form.ccuname'},$env{'request.course.id'},undef,$uhome); 2900: my ($startdate,$enddate) = &Apache::lonuserutils::get_dates_from_form(); 2901: my $enroll_result = 2902: &Apache::lonnet::modify_student_enrollment($env{'form.ccdomain'}, 2903: $env{'form.ccuname'},$env{'form.cid'},$env{'form.cfirstname'}, 2904: $env{'form.cmiddlename'},$env{'form.clastname'}, 2905: $env{'form.generation'},$env{'form.sections'},$enddate, 2906: $startdate,'manual',undef,$env{'request.course.id'},'',$context); 2907: if ($enroll_result =~ /^ok/) { 2908: $r->print(&mt('<b>[_1]</b> enrolled',$env{'form.ccuname'}.':'.$env{'form.ccdomain'})); 2909: if ($env{'form.sections'} ne '') { 2910: $r->print(' '.&mt('in section [_1]',$env{'form.sections'})); 2911: } 2912: my ($showstart,$showend); 2913: if ($startdate <= $now) { 2914: $showstart = &mt('Access starts immediately'); 2915: } else { 2916: $showstart = &mt('Access starts: ').&Apache::lonlocal::locallocaltime($startdate); 2917: } 2918: if ($enddate == 0) { 2919: $showend = &mt('ends: no ending date'); 2920: } else { 2921: $showend = &mt('ends: ').&Apache::lonlocal::locallocaltime($enddate); 2922: } 2923: $r->print('.<br />'.$showstart.'; '.$showend); 2924: if ($startdate <= $now && !$newuser) { 2925: $r->print("<p> ".&mt('If the student is currently logged-in to LON-CAPA, the new role will be available when the student next logs in.')."</p>"); 2926: } 2927: } else { 2928: $r->print(&mt('unable to enroll').": ".$enroll_result); 2929: } 2930: return; 2931: } 2932: 2933: sub get_defaultquota_text { 2934: my ($settingstatus) = @_; 2935: my $defquotatext; 2936: if ($settingstatus eq '') { 2937: $defquotatext = &mt('(default)'); 2938: } else { 2939: my ($usertypes,$order) = 2940: &Apache::lonnet::retrieve_inst_usertypes($env{'form.ccdomain'}); 2941: if ($usertypes->{$settingstatus} eq '') { 2942: $defquotatext = &mt('(default)'); 2943: } else { 2944: $defquotatext = &mt('(default for [_1])',$usertypes->{$settingstatus}); 2945: } 2946: } 2947: return $defquotatext; 2948: } 2949: 2950: sub update_result_form { 2951: my ($uhome) = @_; 2952: my $outcome = 2953: '<form name="userupdate" method="post" />'."\n"; 2954: foreach my $item ('srchby','srchin','srchtype','srchterm','srchdomain','ccuname','ccdomain') { 2955: $outcome .= '<input type="hidden" name="'.$item.'" value="'.$env{'form.'.$item}.'" />'."\n"; 2956: } 2957: if ($env{'form.origname'} ne '') { 2958: $outcome .= '<input type="hidden" name="origname" value="'.$env{'form.origname'}.'" />'."\n"; 2959: } 2960: foreach my $item ('sortby','seluname','seludom') { 2961: if (exists($env{'form.'.$item})) { 2962: $outcome .= '<input type="hidden" name="'.$item.'" value="'.$env{'form.'.$item}.'" />'."\n"; 2963: } 2964: } 2965: if ($uhome eq 'no_host') { 2966: $outcome .= '<input type="hidden" name="forcenewuser" value="1" />'."\n"; 2967: } 2968: $outcome .= '<input type="hidden" name="phase" value="" />'."\n". 2969: '<input type ="hidden" name="currstate" value="" />'."\n". 2970: '<input type ="hidden" name="action" value="'.$env{'form.action'}.'" />'."\n". 2971: '</form>'; 2972: return $outcome; 2973: } 2974: 2975: sub quota_admin { 2976: my ($setquota,$changeHash) = @_; 2977: my $quotachanged; 2978: if (&Apache::lonnet::allowed('mpq',$env{'form.ccdomain'})) { 2979: # Current user has quota modification privileges 2980: if (ref($changeHash) eq 'HASH') { 2981: $quotachanged = 1; 2982: $changeHash->{'portfolioquota'} = $setquota; 2983: } 2984: } 2985: return $quotachanged; 2986: } 2987: 2988: sub tool_admin { 2989: my ($tool,$settool,$changeHash,$context) = @_; 2990: my $canchange = 0; 2991: if ($context eq 'requestcourses') { 2992: if (&Apache::lonnet::allowed('ccc',$env{'form.ccdomain'})) { 2993: $canchange = 1; 2994: } 2995: } elsif (&Apache::lonnet::allowed('mut',$env{'form.ccdomain'})) { 2996: # Current user has quota modification privileges 2997: $canchange = 1; 2998: } 2999: my $toolchanged; 3000: if ($canchange) { 3001: if (ref($changeHash) eq 'HASH') { 3002: $toolchanged = 1; 3003: $changeHash->{$context.'.'.$tool} = $settool; 3004: } 3005: } 3006: return $toolchanged; 3007: } 3008: 3009: sub build_roles { 3010: my ($sectionstr,$sections,$role) = @_; 3011: my $num_sections = 0; 3012: if ($sectionstr=~ /,/) { 3013: my @secnums = split/,/,$sectionstr; 3014: if ($role eq 'st') { 3015: $secnums[0] =~ s/\W//g; 3016: $$sections{$secnums[0]} = 1; 3017: $num_sections = 1; 3018: } else { 3019: foreach my $sec (@secnums) { 3020: $sec =~ ~s/\W//g; 3021: if (!($sec eq "")) { 3022: if (exists($$sections{$sec})) { 3023: $$sections{$sec} ++; 3024: } else { 3025: $$sections{$sec} = 1; 3026: $num_sections ++; 3027: } 3028: } 3029: } 3030: } 3031: } else { 3032: $sectionstr=~s/\W//g; 3033: unless ($sectionstr eq '') { 3034: $$sections{$sectionstr} = 1; 3035: $num_sections ++; 3036: } 3037: } 3038: 3039: return $num_sections; 3040: } 3041: 3042: # ========================================================== Custom Role Editor 3043: 3044: sub custom_role_editor { 3045: my ($r) = @_; 3046: my $rolename=$env{'form.rolename'}; 3047: 3048: if ($rolename eq 'make new role') { 3049: $rolename=$env{'form.newrolename'}; 3050: } 3051: 3052: $rolename=~s/[^A-Za-z0-9]//gs; 3053: 3054: if (!$rolename || $env{'form.phase'} eq 'pickrole') { 3055: &print_username_entry_form($r); 3056: return; 3057: } 3058: # ------------------------------------------------------- What can be assigned? 3059: my %full=(); 3060: my %courselevel=(); 3061: my %courselevelcurrent=(); 3062: my $syspriv=''; 3063: my $dompriv=''; 3064: my $coursepriv=''; 3065: my $body_top; 3066: my ($disp_dummy,$disp_roles) = &Apache::lonnet::get('roles',["st"]); 3067: my ($rdummy,$roledef)= 3068: &Apache::lonnet::get('roles',["rolesdef_$rolename"]); 3069: # ------------------------------------------------------- Does this role exist? 3070: $body_top .= '<h2>'; 3071: if (($rdummy ne 'con_lost') && ($roledef ne '')) { 3072: $body_top .= &mt('Existing Role').' "'; 3073: # ------------------------------------------------- Get current role privileges 3074: ($syspriv,$dompriv,$coursepriv)=split(/\_/,$roledef); 3075: } else { 3076: $body_top .= &mt('New Role').' "'; 3077: $roledef=''; 3078: } 3079: $body_top .= $rolename.'"</h2>'; 3080: foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:c'})) { 3081: my ($priv,$restrict)=split(/\&/,$item); 3082: if (!$restrict) { $restrict='F'; } 3083: $courselevel{$priv}=$restrict; 3084: if ($coursepriv=~/\:$priv/) { 3085: $courselevelcurrent{$priv}=1; 3086: } 3087: $full{$priv}=1; 3088: } 3089: my %domainlevel=(); 3090: my %domainlevelcurrent=(); 3091: foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:d'})) { 3092: my ($priv,$restrict)=split(/\&/,$item); 3093: if (!$restrict) { $restrict='F'; } 3094: $domainlevel{$priv}=$restrict; 3095: if ($dompriv=~/\:$priv/) { 3096: $domainlevelcurrent{$priv}=1; 3097: } 3098: $full{$priv}=1; 3099: } 3100: my %systemlevel=(); 3101: my %systemlevelcurrent=(); 3102: foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:s'})) { 3103: my ($priv,$restrict)=split(/\&/,$item); 3104: if (!$restrict) { $restrict='F'; } 3105: $systemlevel{$priv}=$restrict; 3106: if ($syspriv=~/\:$priv/) { 3107: $systemlevelcurrent{$priv}=1; 3108: } 3109: $full{$priv}=1; 3110: } 3111: my ($jsback,$elements) = &crumb_utilities(); 3112: my $button_code = "\n"; 3113: my $head_script = "\n"; 3114: $head_script .= '<script type="text/javascript">'."\n"; 3115: my @template_roles = ("cc","in","ta","ep","st"); 3116: foreach my $role (@template_roles) { 3117: $head_script .= &make_script_template($role); 3118: $button_code .= &make_button_code($role).' '; 3119: } 3120: $head_script .= "\n".$jsback."\n".'</script>'."\n"; 3121: $r->print(&Apache::loncommon::start_page('Custom Role Editor',$head_script)); 3122: &Apache::lonhtmlcommon::add_breadcrumb 3123: ({href=>"javascript:backPage(document.form1,'pickrole','')", 3124: text=>"Pick custom role", 3125: faq=>282,bug=>'Instructor Interface',}, 3126: {href=>"javascript:backPage(document.form1,'','')", 3127: text=>"Edit custom role", 3128: faq=>282,bug=>'Instructor Interface',}); 3129: $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management', 3130: 'Course_Editing_Custom_Roles')); 3131: 3132: $r->print($body_top); 3133: my %lt=&Apache::lonlocal::texthash( 3134: 'prv' => "Privilege", 3135: 'crl' => "Course Level", 3136: 'dml' => "Domain Level", 3137: 'ssl' => "System Level"); 3138: 3139: $r->print('<div>' 3140: .'<form action=""><fieldset>' 3141: .'<legend>'.&mt('Select a Template').'</legend>' 3142: .$button_code 3143: .'</fieldset></form>' 3144: .'</div>' 3145: ); 3146: 3147: $r->print(<<ENDCCF); 3148: <form name="form1" method="post"> 3149: <input type="hidden" name="phase" value="set_custom_roles" /> 3150: <input type="hidden" name="rolename" value="$rolename" /> 3151: ENDCCF 3152: $r->print(&Apache::loncommon::start_data_table(). 3153: &Apache::loncommon::start_data_table_header_row(). 3154: '<th>'.$lt{'prv'}.'</th><th>'.$lt{'crl'}.'</th><th>'.$lt{'dml'}. 3155: '</th><th>'.$lt{'ssl'}.'</th>'. 3156: &Apache::loncommon::end_data_table_header_row()); 3157: foreach my $priv (sort keys %full) { 3158: my $privtext = &Apache::lonnet::plaintext($priv); 3159: $r->print(&Apache::loncommon::start_data_table_row(). 3160: '<td>'.$privtext.'</td><td>'. 3161: ($courselevel{$priv}?'<input type="checkbox" name="'.$priv.'_c"'. 3162: ($courselevelcurrent{$priv}?' checked="checked"':'').' />':' '). 3163: '</td><td>'. 3164: ($domainlevel{$priv}?'<input type="checkbox" name="'.$priv.'_d"'. 3165: ($domainlevelcurrent{$priv}?' checked="checked"':'').' />':' '). 3166: '</td><td>'. 3167: ($systemlevel{$priv}?'<input type="checkbox" name="'.$priv.'_s"'. 3168: ($systemlevelcurrent{$priv}?' checked="checked"':'').' />':' '). 3169: '</td>'. 3170: &Apache::loncommon::end_data_table_row()); 3171: } 3172: $r->print(&Apache::loncommon::end_data_table(). 3173: '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />'. 3174: '<input type="hidden" name="startrolename" value="'.$env{'form.rolename'}. 3175: '" />'."\n".'<input type="hidden" name="currstate" value="" />'."\n". 3176: '<input type="reset" value="'.&mt("Reset").'" />'."\n". 3177: '<input type="submit" value="'.&mt('Save').'" /></form>'. 3178: &Apache::loncommon::end_page()); 3179: } 3180: # -------------------------------------------------------- 3181: sub make_script_template { 3182: my ($role) = @_; 3183: my %full_c=(); 3184: my %full_d=(); 3185: my %full_s=(); 3186: my $return_script; 3187: foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:c'})) { 3188: my ($priv,$restrict)=split(/\&/,$item); 3189: $full_c{$priv}=1; 3190: } 3191: foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:d'})) { 3192: my ($priv,$restrict)=split(/\&/,$item); 3193: $full_d{$priv}=1; 3194: } 3195: foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:s'})) { 3196: my ($priv,$restrict)=split(/\&/,$item); 3197: $full_s{$priv}=1; 3198: } 3199: $return_script .= 'function set_'.$role.'() {'."\n"; 3200: my @temp = split(/:/,$Apache::lonnet::pr{$role.':c'}); 3201: my %role_c; 3202: foreach my $priv (@temp) { 3203: my ($priv_item, $dummy) = split(/\&/,$priv); 3204: $role_c{$priv_item} = 1; 3205: } 3206: my %role_d; 3207: @temp = split(/:/,$Apache::lonnet::pr{$role.':d'}); 3208: foreach my $priv(@temp) { 3209: my ($priv_item, $dummy) = split(/\&/,$priv); 3210: $role_d{$priv_item} = 1; 3211: } 3212: my %role_s; 3213: @temp = split(/:/,$Apache::lonnet::pr{$role.':s'}); 3214: foreach my $priv(@temp) { 3215: my ($priv_item, $dummy) = split(/\&/,$priv); 3216: $role_s{$priv_item} = 1; 3217: } 3218: foreach my $priv_item (keys(%full_c)) { 3219: my ($priv, $dummy) = split(/\&/,$priv_item); 3220: if ((exists($role_c{$priv})) || (exists($role_d{$priv})) || 3221: (exists($role_s{$priv}))) { 3222: $return_script .= "document.form1.$priv"."_c.checked = true;\n"; 3223: } else { 3224: $return_script .= "document.form1.$priv"."_c.checked = false;\n"; 3225: } 3226: } 3227: foreach my $priv_item (keys(%full_d)) { 3228: my ($priv, $dummy) = split(/\&/,$priv_item); 3229: if ((exists($role_d{$priv})) || (exists($role_s{$priv}))) { 3230: $return_script .= "document.form1.$priv"."_d.checked = true;\n"; 3231: } else { 3232: $return_script .= "document.form1.$priv"."_d.checked = false;\n"; 3233: } 3234: } 3235: foreach my $priv_item (keys(%full_s)) { 3236: my ($priv, $dummy) = split(/\&/,$priv_item); 3237: if (exists($role_s{$priv})) { 3238: $return_script .= "document.form1.$priv"."_s.checked = true;\n"; 3239: } else { 3240: $return_script .= "document.form1.$priv"."_s.checked = false;\n"; 3241: } 3242: } 3243: $return_script .= '}'."\n"; 3244: return ($return_script); 3245: } 3246: # ---------------------------------------------------------- 3247: sub make_button_code { 3248: my ($role) = @_; 3249: my $label = &Apache::lonnet::plaintext($role); 3250: my $button_code = '<input type="button" onClick="set_'.$role.'()" value="'.$label.'" />'; 3251: return ($button_code); 3252: } 3253: # ---------------------------------------------------------- Call to definerole 3254: sub set_custom_role { 3255: my ($r,$context) = @_; 3256: my $rolename=$env{'form.rolename'}; 3257: $rolename=~s/[^A-Za-z0-9]//gs; 3258: if (!$rolename) { 3259: &custom_role_editor($r); 3260: return; 3261: } 3262: my ($jsback,$elements) = &crumb_utilities(); 3263: my $jscript = '<script type="text/javascript">'.$jsback."\n".'</script>'; 3264: 3265: $r->print(&Apache::loncommon::start_page('Save Custom Role'),$jscript); 3266: &Apache::lonhtmlcommon::add_breadcrumb 3267: ({href=>"javascript:backPage(document.customresult,'pickrole','')", 3268: text=>"Pick custom role", 3269: faq=>282,bug=>'Instructor Interface',}, 3270: {href=>"javascript:backPage(document.customresult,'selected_custom_edit','')", 3271: text=>"Edit custom role", 3272: faq=>282,bug=>'Instructor Interface',}, 3273: {href=>"javascript:backPage(document.customresult,'set_custom_roles','')", 3274: text=>"Result", 3275: faq=>282,bug=>'Instructor Interface',}); 3276: $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management', 3277: 'Course_Editing_Custom_Roles')); 3278: 3279: my ($rdummy,$roledef)= 3280: &Apache::lonnet::get('roles',["rolesdef_$rolename"]); 3281: 3282: # ------------------------------------------------------- Does this role exist? 3283: $r->print('<h3>'); 3284: if (($rdummy ne 'con_lost') && ($roledef ne '')) { 3285: $r->print(&mt('Existing Role').' "'); 3286: } else { 3287: $r->print(&mt('New Role').' "'); 3288: $roledef=''; 3289: } 3290: $r->print($rolename.'"</h3>'); 3291: # ------------------------------------------------------- What can be assigned? 3292: my $sysrole=''; 3293: my $domrole=''; 3294: my $courole=''; 3295: 3296: foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:c'})) { 3297: my ($priv,$restrict)=split(/\&/,$item); 3298: if (!$restrict) { $restrict=''; } 3299: if ($env{'form.'.$priv.'_c'}) { 3300: $courole.=':'.$item; 3301: } 3302: } 3303: 3304: foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:d'})) { 3305: my ($priv,$restrict)=split(/\&/,$item); 3306: if (!$restrict) { $restrict=''; } 3307: if ($env{'form.'.$priv.'_d'}) { 3308: $domrole.=':'.$item; 3309: } 3310: } 3311: 3312: foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:s'})) { 3313: my ($priv,$restrict)=split(/\&/,$item); 3314: if (!$restrict) { $restrict=''; } 3315: if ($env{'form.'.$priv.'_s'}) { 3316: $sysrole.=':'.$item; 3317: } 3318: } 3319: $r->print('<br />Defining Role: '. 3320: &Apache::lonnet::definerole($rolename,$sysrole,$domrole,$courole)); 3321: if ($env{'request.course.id'}) { 3322: my $url='/'.$env{'request.course.id'}; 3323: $url=~s/\_/\//g; 3324: $r->print('<br />'.&mt('Assigning Role to Self').': '. 3325: &Apache::lonnet::assigncustomrole($env{'user.domain'}, 3326: $env{'user.name'}, 3327: $url, 3328: $env{'user.domain'}, 3329: $env{'user.name'}, 3330: $rolename,undef,undef,undef,$context)); 3331: } 3332: $r->print('<p><a href="javascript:backPage(document.customresult,'."'pickrole'".')">'.&mt('Create or edit another custom role').'</a></p><form name="customresult" method="post">'); 3333: $r->print(&Apache::lonhtmlcommon::echo_form_input([]).'</form>'); 3334: $r->print(&Apache::loncommon::end_page()); 3335: } 3336: 3337: # ================================================================ Main Handler 3338: sub handler { 3339: my $r = shift; 3340: if ($r->header_only) { 3341: &Apache::loncommon::content_type($r,'text/html'); 3342: $r->send_http_header; 3343: return OK; 3344: } 3345: my $context; 3346: if ($env{'request.course.id'}) { 3347: $context = 'course'; 3348: } elsif ($env{'request.role'} =~ /^au\./) { 3349: $context = 'author'; 3350: } else { 3351: $context = 'domain'; 3352: } 3353: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, 3354: ['action','state','callingform','roletype','showrole','bulkaction','popup','phase', 3355: 'username','domain','srchterm','srchdomain','srchin','srchby','srchtype']); 3356: &Apache::lonhtmlcommon::clear_breadcrumbs(); 3357: if ($env{'form.action'} ne 'dateselect') { 3358: &Apache::lonhtmlcommon::add_breadcrumb 3359: ({href=>"/adm/createuser", 3360: text=>"User Management", 3361: 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'}); 3362: } 3363: #SD Following files not added to help, because the corresponding .tex-files seem to 3364: #be missing: Course_Approve_Selfenroll,Course_User_Logs, 3365: my ($permission,$allowed) = 3366: &Apache::lonuserutils::get_permission($context); 3367: if (!$allowed) { 3368: $env{'user.error.msg'}= 3369: "/adm/createuser:cst:0:0:Cannot create/modify user data ". 3370: "or view user status."; 3371: return HTTP_NOT_ACCEPTABLE; 3372: } 3373: 3374: &Apache::loncommon::content_type($r,'text/html'); 3375: $r->send_http_header; 3376: 3377: # Main switch on form.action and form.state, as appropriate 3378: if (! exists($env{'form.action'})) { 3379: $r->print(&header()); 3380: $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management')); 3381: $r->print(&print_main_menu($permission,$context)); 3382: $r->print(&Apache::loncommon::end_page()); 3383: } elsif ($env{'form.action'} eq 'upload' && $permission->{'cusr'}) { 3384: $r->print(&header()); 3385: &Apache::lonhtmlcommon::add_breadcrumb 3386: ({href=>'/adm/createuser?action=upload&state=', 3387: text=>"Upload Users List"}); 3388: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Upload Users List', 3389: 'Course_Create_Class_List')); 3390: $r->print('<form name="studentform" method="post" '. 3391: 'enctype="multipart/form-data" '. 3392: ' action="/adm/createuser">'."\n"); 3393: if (! exists($env{'form.state'})) { 3394: &Apache::lonuserutils::print_first_users_upload_form($r,$context); 3395: } elsif ($env{'form.state'} eq 'got_file') { 3396: &Apache::lonuserutils::print_upload_manager_form($r,$context, 3397: $permission); 3398: } elsif ($env{'form.state'} eq 'enrolling') { 3399: if ($env{'form.datatoken'}) { 3400: &Apache::lonuserutils::upfile_drop_add($r,$context,$permission); 3401: } 3402: } else { 3403: &Apache::lonuserutils::print_first_users_upload_form($r,$context); 3404: } 3405: $r->print('</form>'.&Apache::loncommon::end_page()); 3406: } elsif ((($env{'form.action'} eq 'singleuser') || ($env{'form.action'} 3407: eq 'singlestudent')) && ($permission->{'cusr'})) { 3408: my $phase = $env{'form.phase'}; 3409: my @search = ('srchterm','srchby','srchin','srchtype','srchdomain'); 3410: &Apache::loncreateuser::restore_prev_selections(); 3411: my $srch; 3412: foreach my $item (@search) { 3413: $srch->{$item} = $env{'form.'.$item}; 3414: } 3415: if (($phase eq 'get_user_info') || ($phase eq 'userpicked') || 3416: ($phase eq 'createnewuser')) { 3417: if ($env{'form.phase'} eq 'createnewuser') { 3418: my $response; 3419: if ($env{'form.srchterm'} !~ /^$match_username$/) { 3420: my $response = &mt('You must specify a valid username. Only the following are allowed: letters numbers - . @'); 3421: $env{'form.phase'} = ''; 3422: &print_username_entry_form($r,$context,$response,$srch); 3423: } else { 3424: my $ccuname =&LONCAPA::clean_username($srch->{'srchterm'}); 3425: my $ccdomain=&LONCAPA::clean_domain($srch->{'srchdomain'}); 3426: &print_user_modification_page($r,$ccuname,$ccdomain, 3427: $srch,$response,$context, 3428: $permission); 3429: } 3430: } elsif ($env{'form.phase'} eq 'get_user_info') { 3431: my ($currstate,$response,$forcenewuser,$results) = 3432: &user_search_result($context,$srch); 3433: if ($env{'form.currstate'} eq 'modify') { 3434: $currstate = $env{'form.currstate'}; 3435: } 3436: if ($currstate eq 'select') { 3437: &print_user_selection_page($r,$response,$srch,$results, 3438: \@search,$context); 3439: } elsif ($currstate eq 'modify') { 3440: my ($ccuname,$ccdomain); 3441: if (($srch->{'srchby'} eq 'uname') && 3442: ($srch->{'srchtype'} eq 'exact')) { 3443: $ccuname = $srch->{'srchterm'}; 3444: $ccdomain= $srch->{'srchdomain'}; 3445: } else { 3446: my @matchedunames = keys(%{$results}); 3447: ($ccuname,$ccdomain) = split(/:/,$matchedunames[0]); 3448: } 3449: $ccuname =&LONCAPA::clean_username($ccuname); 3450: $ccdomain=&LONCAPA::clean_domain($ccdomain); 3451: if ($env{'form.forcenewuser'}) { 3452: $response = ''; 3453: } 3454: &print_user_modification_page($r,$ccuname,$ccdomain, 3455: $srch,$response,$context, 3456: $permission); 3457: } elsif ($currstate eq 'query') { 3458: &print_user_query_page($r,'createuser'); 3459: } else { 3460: $env{'form.phase'} = ''; 3461: &print_username_entry_form($r,$context,$response,$srch, 3462: $forcenewuser); 3463: } 3464: } elsif ($env{'form.phase'} eq 'userpicked') { 3465: my $ccuname = &LONCAPA::clean_username($env{'form.seluname'}); 3466: my $ccdomain = &LONCAPA::clean_domain($env{'form.seludom'}); 3467: &print_user_modification_page($r,$ccuname,$ccdomain,$srch,'', 3468: $context,$permission); 3469: } 3470: } elsif ($env{'form.phase'} eq 'update_user_data') { 3471: &update_user_data($r,$context); 3472: } else { 3473: &print_username_entry_form($r,$context,undef,$srch); 3474: } 3475: } elsif ($env{'form.action'} eq 'custom' && $permission->{'custom'}) { 3476: if ($env{'form.phase'} eq 'set_custom_roles') { 3477: &set_custom_role($r,$context); 3478: } else { 3479: &custom_role_editor($r); 3480: } 3481: } elsif (($env{'form.action'} eq 'listusers') && 3482: ($permission->{'view'} || $permission->{'cusr'})) { 3483: if ($env{'form.phase'} eq 'bulkchange') { 3484: &Apache::lonhtmlcommon::add_breadcrumb 3485: ({href=>'/adm/createuser?action=listusers', 3486: text=>"List Users"}, 3487: {href=>"/adm/createuser", 3488: text=>"Result"}); 3489: my $setting = $env{'form.roletype'}; 3490: my $choice = $env{'form.bulkaction'}; 3491: $r->print(&header()); 3492: $r->print(&Apache::lonhtmlcommon::breadcrumbs("Update Users", 3493: 'Course_View_Class_List')); 3494: if ($permission->{'cusr'}) { 3495: &Apache::lonuserutils::update_user_list($r,$context,$setting,$choice); 3496: $r->print(&Apache::loncommon::end_page()); 3497: } else { 3498: $r->print(&mt('You are not authorized to make bulk changes to user roles')); 3499: $r->print('<p><a href="/adm/createuser?action=listusers">'.&mt('Display User Lists').'</a>'); 3500: $r->print(&Apache::loncommon::end_page()); 3501: } 3502: } else { 3503: &Apache::lonhtmlcommon::add_breadcrumb 3504: ({href=>'/adm/createuser?action=listusers', 3505: text=>"List Users"}); 3506: my ($cb_jscript,$jscript,$totcodes,$codetitles,$idlist,$idlist_titles); 3507: my $formname = 'studentform'; 3508: if ($context eq 'domain' && $env{'form.roletype'} eq 'course') { 3509: ($cb_jscript,$jscript,$totcodes,$codetitles,$idlist,$idlist_titles) = 3510: &Apache::lonuserutils::courses_selector($env{'request.role.domain'}, 3511: $formname); 3512: $jscript .= &verify_user_display(); 3513: my $js = &add_script($jscript).$cb_jscript; 3514: my $loadcode = 3515: &Apache::lonuserutils::course_selector_loadcode($formname); 3516: if ($loadcode ne '') { 3517: $r->print(&header($js,{'onload' => $loadcode,})); 3518: } else { 3519: $r->print(&header($js)); 3520: } 3521: } else { 3522: $r->print(&header(&add_script(&verify_user_display()))); 3523: } 3524: $r->print(&Apache::lonhtmlcommon::breadcrumbs("List Users", 3525: 'Course_View_Class_List')); 3526: &Apache::lonuserutils::print_userlist($r,undef,$permission,$context, 3527: $formname,$totcodes,$codetitles,$idlist,$idlist_titles); 3528: $r->print(&Apache::loncommon::end_page()); 3529: } 3530: } elsif ($env{'form.action'} eq 'drop' && $permission->{'cusr'}) { 3531: $r->print(&header()); 3532: &Apache::lonhtmlcommon::add_breadcrumb 3533: ({href=>'/adm/createuser?action=drop', 3534: text=>"Drop Students"}); 3535: if (!exists($env{'form.state'})) { 3536: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Drop Students', 3537: 'Course_Drop_Student')); 3538: 3539: &Apache::lonuserutils::print_drop_menu($r,$context,$permission); 3540: } elsif ($env{'form.state'} eq 'done') { 3541: &Apache::lonhtmlcommon::add_breadcrumb 3542: ({href=>'/adm/createuser?action=drop', 3543: text=>"Result"}); 3544: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Drop Students', 3545: 'Course_Drop_Student')); 3546: &Apache::lonuserutils::update_user_list($r,$context,undef, 3547: $env{'form.action'}); 3548: } 3549: $r->print(&Apache::loncommon::end_page()); 3550: } elsif ($env{'form.action'} eq 'dateselect') { 3551: if ($permission->{'cusr'}) { 3552: $r->print(&header(undef,undef,{'no_nav_bar' => 1}). 3553: &Apache::lonuserutils::date_section_selector($context, 3554: $permission). 3555: &Apache::loncommon::end_page()); 3556: } else { 3557: $r->print(&header(). 3558: '<span class="LC_error">'.&mt('You do not have permission to modify dates or sections for users').'</span>'. 3559: &Apache::loncommon::end_page()); 3560: } 3561: } elsif ($env{'form.action'} eq 'selfenroll') { 3562: $r->print(&header()); 3563: &Apache::lonhtmlcommon::add_breadcrumb 3564: ({href=>'/adm/createuser?action=selfenroll', 3565: text=>"Configure Self-enrollment"}); 3566: if (!exists($env{'form.state'})) { 3567: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Configure Self-enrollment', 3568: 'Course_Self_Enrollment')); 3569: $r->print('<h3>'.&mt('Self-enrollment with a student role').'</h3>'."\n"); 3570: &print_selfenroll_menu($r,$context,$permission); 3571: } elsif ($env{'form.state'} eq 'done') { 3572: &Apache::lonhtmlcommon::add_breadcrumb 3573: ({href=>'/adm/createuser?action=selfenroll', 3574: text=>"Result"}); 3575: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Self-enrollment result', 3576: 'Course_Self_Enrollment')); 3577: $r->print('<h3>'.&mt('Self-enrollment with a student role').'</h3>'."\n"); 3578: &update_selfenroll_config($r,$context,$permission); 3579: } 3580: $r->print(&Apache::loncommon::end_page()); 3581: } elsif ($env{'form.action'} eq 'selfenrollqueue') { 3582: $r->print(&header()); 3583: &Apache::lonhtmlcommon::add_breadcrumb 3584: ({href=>'/adm/createuser?action=selfenrollqueue', 3585: text=>"Enrollment requests"}); 3586: my $cid = $env{'request.course.id'}; 3587: my $cdom = $env{'course.'.$cid.'.domain'}; 3588: my $cnum = $env{'course.'.$cid.'.num'}; 3589: if (!exists($env{'form.state'})) { 3590: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enrollment requests', 3591: 'Course_SelfEnrollment_Approval')); 3592: $r->print('<h3>'.&mt('Pending enrollment requests').'</h3>'."\n"); 3593: &display_selfenroll_queue($r,$context,$permission,$cnum,$cdom); 3594: } elsif ($env{'form.state'} eq 'done') { 3595: &Apache::lonhtmlcommon::add_breadcrumb 3596: ({href=>'/adm/createuser?action=selfenrollqueue', 3597: text=>"Result"}); 3598: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enrollment result', 3599: 'Course_Self_Enrollment')); 3600: $r->print('<h3>'.&mt('Enrollment request processing').'</h3>'."\n"); 3601: &update_selfenroll_queue($r,$context,$permission,$cid,$cnum,$cdom); 3602: } 3603: $r->print(&Apache::loncommon::end_page()); 3604: } elsif ($env{'form.action'} eq 'changelogs') { 3605: $r->print(&header()); 3606: &Apache::lonhtmlcommon::add_breadcrumb 3607: ({href=>'/adm/createuser?action=changelogs', 3608: text=>"User Management Logs"}); 3609: $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Changes', 3610: 'Course_User_Logs')); 3611: &print_userchangelogs_display($r,$context,$permission); 3612: $r->print(&Apache::loncommon::end_page()); 3613: } else { 3614: $r->print(&header()); 3615: $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management')); 3616: $r->print(&print_main_menu($permission,$context)); 3617: $r->print(&Apache::loncommon::end_page()); 3618: } 3619: return OK; 3620: } 3621: 3622: sub header { 3623: my ($jscript,$loaditems,$args) = @_; 3624: my $start_page; 3625: if (ref($loaditems) eq 'HASH') { 3626: $start_page=&Apache::loncommon::start_page('User Management',$jscript,{'add_entries' => $loaditems}); 3627: } else { 3628: $start_page=&Apache::loncommon::start_page('User Management',$jscript,$args); 3629: } 3630: return $start_page; 3631: } 3632: 3633: sub add_script { 3634: my ($js) = @_; 3635: return '<script type="text/javascript">'."\n".$js."\n".'</script>'; 3636: } 3637: 3638: sub verify_user_display { 3639: my $output = <<"END"; 3640: 3641: function display_update() { 3642: document.studentform.action.value = 'listusers'; 3643: document.studentform.phase.value = 'display'; 3644: document.studentform.submit(); 3645: } 3646: 3647: END 3648: return $output; 3649: 3650: } 3651: 3652: ############################################################### 3653: ############################################################### 3654: # Menu Phase One 3655: sub print_main_menu { 3656: my ($permission,$context) = @_; 3657: my %links = ( 3658: domain => { 3659: upload => 'Upload a File of Users', 3660: singleuser => 'Add/Modify a Single User', 3661: listusers => 'Manage Multiple Users', 3662: }, 3663: author => { 3664: upload => 'Upload a File of Co-authors', 3665: singleuser => 'Add/Modify a Single Co-author', 3666: listusers => 'Display Co-authors and Manage Multiple Users', 3667: }, 3668: course => { 3669: upload => 'Upload a File of Course Users', 3670: singleuser => 'Add/Modify a Single Course User', 3671: listusers => 'Display Class Lists and Manage Multiple Users', 3672: }, 3673: ); 3674: 3675: my @menu = 3676: ( 3677: { text => $links{$context}{'upload'}, 3678: help => 'Course_Create_Class_List', 3679: action => 'upload', 3680: permission => $permission->{'cusr'}, 3681: }, 3682: { text => $links{$context}{'singleuser'}, 3683: help => 'Course_Change_Privileges', 3684: action => 'singleuser', 3685: permission => $permission->{'cusr'}, 3686: }, 3687: { text => $links{$context}{'listusers'}, 3688: help => 'Course_View_Class_List', 3689: action => 'listusers', 3690: permission => ($permission->{'view'} || $permission->{'cusr'}), 3691: }, 3692: ); 3693: if ($context eq 'domain' || $context eq 'course') { 3694: my $customlink = { text => 'Edit Custom Roles', 3695: help => 'Course_Editing_Custom_Roles', 3696: action => 'custom', 3697: permission => $permission->{'custom'}, 3698: }; 3699: push(@menu,$customlink); 3700: } 3701: if ($context eq 'course') { 3702: my ($cnum,$cdom) = &Apache::lonuserutils::get_course_identity(); 3703: my @courselinks = 3704: ( 3705: { text => 'Enroll a Single Student', 3706: help => 'Course_Add_Student', 3707: action => 'singlestudent', 3708: permission => $permission->{'cusr'}, 3709: }, 3710: { text => 'Drop Students', 3711: help => 'Course_Drop_Student', 3712: action => 'drop', 3713: permission => $permission->{'cusr'}, 3714: }); 3715: if (!exists($permission->{'cusr_section'})) { 3716: push(@courselinks, 3717: { text => 'Automated Enrollment Manager', 3718: help => 'Course_Automated_Enrollment', 3719: permission => (&Apache::lonnet::auto_run($cnum,$cdom) 3720: && $permission->{'cusr'}), 3721: url => '/adm/populate', 3722: }, 3723: { text => 'Configure User Self-enrollment', 3724: help => 'Course_Self_Enrollment', 3725: action => 'selfenroll', 3726: permission => $permission->{'cusr'}, 3727: }); 3728: } 3729: if ($env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_approval'}) { 3730: push(@courselinks, 3731: { text => 'Enrollment Requests', 3732: help => 'Course_Approve_Selfenroll', 3733: action => 'selfenrollqueue', 3734: permission => $permission->{'cusr'}, 3735: }); 3736: } 3737: push(@courselinks, 3738: { text => 'Manage Course Groups', 3739: help => 'Course_Manage_Group', 3740: permission => $permission->{'grp_manage'}, 3741: url => '/adm/coursegroups?refpage=cusr', 3742: }, 3743: { text => 'View Change Logs', 3744: help => 'Course_User_Logs', 3745: action => 'changelogs', 3746: permission => $permission->{'cusr'}, 3747: },); 3748: # { text => 'View Log-in History', 3749: # help => 'Course_User_Logins', 3750: # action => 'logins', 3751: # permission => $permission->{'cusr'}, 3752: # }); 3753: push(@menu,@courselinks); 3754: } 3755: my $menu_html = ''; 3756: foreach my $menu_item (@menu) { 3757: next if (! $menu_item->{'permission'}); 3758: $menu_html.='<p>'; 3759: if (exists($menu_item->{'help'})) { 3760: $menu_html.= 3761: &Apache::loncommon::help_open_topic($menu_item->{'help'}); 3762: } 3763: $menu_html.='<font size="+1">'; 3764: if (exists($menu_item->{'url'})) { 3765: $menu_html.=qq{<a href="$menu_item->{'url'}">}; 3766: } else { 3767: $menu_html.= 3768: qq{<a href="/adm/createuser?action=$menu_item->{'action'}">}; } 3769: $menu_html.= &mt($menu_item->{'text'}).'</a></font>'; 3770: $menu_html.='</p>'; 3771: } 3772: return $menu_html; 3773: } 3774: 3775: sub restore_prev_selections { 3776: my %saveable_parameters = ('srchby' => 'scalar', 3777: 'srchin' => 'scalar', 3778: 'srchtype' => 'scalar', 3779: ); 3780: &Apache::loncommon::store_settings('user','user_picker', 3781: \%saveable_parameters); 3782: &Apache::loncommon::restore_settings('user','user_picker', 3783: \%saveable_parameters); 3784: } 3785: 3786: sub print_selfenroll_menu { 3787: my ($r,$context,$permission) = @_; 3788: my $formname = 'enrollstudent'; 3789: my $nolink = 1; 3790: my ($row,$lt) = &get_selfenroll_titles(); 3791: my $groupslist = &Apache::lonuserutils::get_groupslist(); 3792: my $setsec_js = 3793: &Apache::lonuserutils::setsections_javascript($formname,$groupslist); 3794: my %alerts = &Apache::lonlocal::texthash( 3795: acto => 'Activation of self-enrollment was selected for the following domain(s)', 3796: butn => 'but no user types have been checked.', 3797: wilf => "Please uncheck 'activate' or check at least one type.", 3798: ); 3799: my $selfenroll_js = <<"ENDSCRIPT"; 3800: function update_types(caller,num) { 3801: var delidx = getIndexByName('selfenroll_delete'); 3802: var actidx = getIndexByName('selfenroll_activate'); 3803: if (caller == 'selfenroll_all') { 3804: var selall; 3805: for (var i=0; i<document.$formname.selfenroll_all.length; i++) { 3806: if (document.$formname.selfenroll_all[i].checked) { 3807: selall = document.$formname.selfenroll_all[i].value; 3808: } 3809: } 3810: if (selall == 1) { 3811: if (delidx != -1) { 3812: if (document.$formname.selfenroll_delete.length) { 3813: for (var j=0; j<document.$formname.selfenroll_delete.length; j++) { 3814: document.$formname.selfenroll_delete[j].checked = true; 3815: } 3816: } else { 3817: document.$formname.elements[delidx].checked = true; 3818: } 3819: } 3820: if (actidx != -1) { 3821: if (document.$formname.selfenroll_activate.length) { 3822: for (var j=0; j<document.$formname.selfenroll_activate.length; j++) { 3823: document.$formname.selfenroll_activate[j].checked = false; 3824: } 3825: } else { 3826: document.$formname.elements[actidx].checked = false; 3827: } 3828: } 3829: document.$formname.selfenroll_newdom.selectedIndex = 0; 3830: } 3831: } 3832: if (caller == 'selfenroll_activate') { 3833: if (document.$formname.selfenroll_activate.length) { 3834: for (var j=0; j<document.$formname.selfenroll_activate.length; j++) { 3835: if (document.$formname.selfenroll_activate[j].value == num) { 3836: if (document.$formname.selfenroll_activate[j].checked) { 3837: for (var i=0; i<document.$formname.selfenroll_all.length; i++) { 3838: if (document.$formname.selfenroll_all[i].value == '1') { 3839: document.$formname.selfenroll_all[i].checked = false; 3840: } 3841: if (document.$formname.selfenroll_all[i].value == '0') { 3842: document.$formname.selfenroll_all[i].checked = true; 3843: } 3844: } 3845: } 3846: } 3847: } 3848: } else { 3849: for (var i=0; i<document.$formname.selfenroll_all.length; i++) { 3850: if (document.$formname.selfenroll_all[i].value == '1') { 3851: document.$formname.selfenroll_all[i].checked = false; 3852: } 3853: if (document.$formname.selfenroll_all[i].value == '0') { 3854: document.$formname.selfenroll_all[i].checked = true; 3855: } 3856: } 3857: } 3858: } 3859: if (caller == 'selfenroll_delete') { 3860: if (document.$formname.selfenroll_delete.length) { 3861: for (var j=0; j<document.$formname.selfenroll_delete.length; j++) { 3862: if (document.$formname.selfenroll_delete[j].value == num) { 3863: if (document.$formname.selfenroll_delete[j].checked) { 3864: var delindex = getIndexByName('selfenroll_types_'+num); 3865: if (delindex != -1) { 3866: if (document.$formname.elements[delindex].length) { 3867: for (var k=0; k<document.$formname.elements[delindex].length; k++) { 3868: document.$formname.elements[delindex][k].checked = false; 3869: } 3870: } else { 3871: document.$formname.elements[delindex].checked = false; 3872: } 3873: } 3874: } 3875: } 3876: } 3877: } else { 3878: if (document.$formname.selfenroll_delete.checked) { 3879: var delindex = getIndexByName('selfenroll_types_'+num); 3880: if (delindex != -1) { 3881: if (document.$formname.elements[delindex].length) { 3882: for (var k=0; k<document.$formname.elements[delindex].length; k++) { 3883: document.$formname.elements[delindex][k].checked = false; 3884: } 3885: } else { 3886: document.$formname.elements[delindex].checked = false; 3887: } 3888: } 3889: } 3890: } 3891: } 3892: return; 3893: } 3894: 3895: function validate_types(form) { 3896: var needaction = new Array(); 3897: var countfail = 0; 3898: var actidx = getIndexByName('selfenroll_activate'); 3899: if (actidx != -1) { 3900: if (document.$formname.selfenroll_activate.length) { 3901: for (var j=0; j<document.$formname.selfenroll_activate.length; j++) { 3902: var num = document.$formname.selfenroll_activate[j].value; 3903: if (document.$formname.selfenroll_activate[j].checked) { 3904: countfail = check_types(num,countfail,needaction) 3905: } 3906: } 3907: } else { 3908: if (document.$formname.selfenroll_activate.checked) { 3909: var num = document.enrollstudent.selfenroll_activate.value; 3910: countfail = check_types(num,countfail,needaction) 3911: } 3912: } 3913: } 3914: if (countfail > 0) { 3915: var msg = "$alerts{'acto'}\\n"; 3916: var loopend = needaction.length -1; 3917: if (loopend > 0) { 3918: for (var m=0; m<loopend; m++) { 3919: msg += needaction[m]+", "; 3920: } 3921: } 3922: msg += needaction[loopend]+"\\n$alerts{'butn'}\\n$alerts{'wilf'}"; 3923: alert(msg); 3924: return; 3925: } 3926: setSections(form); 3927: } 3928: 3929: function check_types(num,countfail,needaction) { 3930: var typeidx = getIndexByName('selfenroll_types_'+num); 3931: var count = 0; 3932: if (typeidx != -1) { 3933: if (document.$formname.elements[typeidx].length) { 3934: for (var k=0; k<document.$formname.elements[typeidx].length; k++) { 3935: if (document.$formname.elements[typeidx][k].checked) { 3936: count ++; 3937: } 3938: } 3939: } else { 3940: if (document.$formname.elements[typeidx].checked) { 3941: count ++; 3942: } 3943: } 3944: if (count == 0) { 3945: var domidx = getIndexByName('selfenroll_dom_'+num); 3946: if (domidx != -1) { 3947: var domname = document.$formname.elements[domidx].value; 3948: needaction[countfail] = domname; 3949: countfail ++; 3950: } 3951: } 3952: } 3953: return countfail; 3954: } 3955: 3956: function getIndexByName(item) { 3957: for (var i=0;i<document.$formname.elements.length;i++) { 3958: if (document.$formname.elements[i].name == item) { 3959: return i; 3960: } 3961: } 3962: return -1; 3963: } 3964: ENDSCRIPT 3965: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; 3966: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; 3967: 3968: my $output = '<script type="text/javascript">'."\n". 3969: $setsec_js."\n".$selfenroll_js."\n". 3970: '</script>'."\n". 3971: '<h3>'.$lt->{'selfenroll'}.'</h3>'."\n"; 3972: my ($visible,$cansetvis,$vismsgs,$visactions) = &visible_in_cat($cdom,$cnum); 3973: if (ref($visactions) eq 'HASH') { 3974: if ($visible) { 3975: $output .= '<p class="LC_info">'.$visactions->{'vis'}.'</p>'; 3976: } else { 3977: $output .= '<p class="LC_warning">'.$visactions->{'miss'}.'</p>' 3978: .$visactions->{'yous'}. 3979: '<p>'.$visactions->{'gen'}.'<br />'.$visactions->{'coca'}; 3980: if (ref($vismsgs) eq 'ARRAY') { 3981: $output .= '<br />'.$visactions->{'make'}.'<ul>'; 3982: foreach my $item (@{$vismsgs}) { 3983: $output .= '<li>'.$visactions->{$item}.'</li>'; 3984: } 3985: $output .= '</ul>'; 3986: } 3987: $output .= '</p>'; 3988: } 3989: } 3990: $output .= '<form name="'.$formname.'" method="post" action="/adm/createuser">'."\n". 3991: &Apache::lonhtmlcommon::start_pick_box(); 3992: if (ref($row) eq 'ARRAY') { 3993: foreach my $item (@{$row}) { 3994: my $title = $item; 3995: if (ref($lt) eq 'HASH') { 3996: $title = $lt->{$item}; 3997: } 3998: $output .= 3999: &Apache::lonhtmlcommon::row_title($title, 4000: 'LC_selfenroll_pick_box_title','LC_oddrow_value')."\n"; 4001: if ($item eq 'types') { 4002: my $curr_types = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_types'}; 4003: my $showdomdesc = 1; 4004: my $includeempty = 1; 4005: my $num = 0; 4006: $output .= &Apache::loncommon::start_data_table(). 4007: &Apache::loncommon::start_data_table_row() 4008: .'<td colspan="2"><span class="LC_nobreak"><label>' 4009: .&mt('Any user in any domain:') 4010: .' <input type="radio" name="selfenroll_all" value="1" '; 4011: if ($curr_types eq '*') { 4012: $output .= ' checked="checked" '; 4013: } 4014: $output .= 'onchange="javascript:update_types('. 4015: "'selfenroll_all'".');" />'.&mt('Yes').'</label>'. 4016: ' <input type="radio" name="selfenroll_all" value="0" '; 4017: if ($curr_types ne '*') { 4018: $output .= ' checked="checked" '; 4019: } 4020: $output .= ' onchange="javascript:update_types('. 4021: "'selfenroll_all'".');"/>'.&mt('No').'</label></td>'. 4022: &Apache::loncommon::end_data_table_row(). 4023: &Apache::loncommon::end_data_table(). 4024: &mt('Or').'<br />'. 4025: &Apache::loncommon::start_data_table(); 4026: my %currdoms; 4027: if ($curr_types eq '') { 4028: $output .= &new_selfenroll_dom_row($cdom,'0'); 4029: } elsif ($curr_types ne '*') { 4030: my @entries = split(/;/,$curr_types); 4031: if (@entries > 0) { 4032: foreach my $entry (@entries) { 4033: my ($currdom,$typestr) = split(/:/,$entry); 4034: $currdoms{$currdom} = 1; 4035: my $domdesc = &Apache::lonnet::domain($currdom); 4036: my @currinsttypes = split(',',$typestr); 4037: $output .= &Apache::loncommon::start_data_table_row() 4038: .'<td valign="top"><span class="LC_nobreak">'.&mt('Domain:').'<b>' 4039: .' '.$domdesc.' ('.$currdom.')' 4040: .'</b><input type="hidden" name="selfenroll_dom_'.$num 4041: .'" value="'.$currdom.'" /></span><br />' 4042: .'<span class="LC_nobreak"><label><input type="checkbox" ' 4043: .'name="selfenroll_delete" value="'.$num.'" onchange="javascript:update_types('."'selfenroll_delete','$num'".');" />' 4044: .&mt('Delete').'</label></span></td>'; 4045: $output .= '<td valign="top"> '.&mt('User types:').'<br />' 4046: .&selfenroll_inst_types($num,$currdom,\@currinsttypes).'</td>' 4047: .&Apache::loncommon::end_data_table_row(); 4048: $num ++; 4049: } 4050: } 4051: } 4052: my $add_domtitle = &mt('Users in additional domain:'); 4053: if ($curr_types eq '*') { 4054: $add_domtitle = &mt('Users in specific domain:'); 4055: } elsif ($curr_types eq '') { 4056: $add_domtitle = &mt('Users in other domain:'); 4057: } 4058: $output .= &Apache::loncommon::start_data_table_row() 4059: .'<td colspan="2"><span class="LC_nobreak">'.$add_domtitle.'</span><br />' 4060: .&Apache::loncommon::select_dom_form('','selfenroll_newdom', 4061: $includeempty,$showdomdesc) 4062: .'<input type="hidden" name="selfenroll_types_total" value="'.$num.'" />' 4063: .'</td>'.&Apache::loncommon::end_data_table_row() 4064: .&Apache::loncommon::end_data_table(); 4065: } elsif ($item eq 'registered') { 4066: my ($regon,$regoff); 4067: if ($env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_registered'}) { 4068: $regon = ' checked="checked" '; 4069: $regoff = ' '; 4070: } else { 4071: $regon = ' '; 4072: $regoff = ' checked="checked" '; 4073: } 4074: $output .= '<label>'. 4075: '<input type="radio" name="selfenroll_registered" value="1"'.$regon.'/>'. 4076: &mt('Yes').'</label> <label>'. 4077: '<input type="radio" name="selfenroll_registered" value="0"'.$regoff.'/>'. 4078: &mt('No').'</label>'; 4079: } elsif ($item eq 'enroll_dates') { 4080: my $starttime = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_start_date'}; 4081: my $endtime = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_end_date'}; 4082: if ($starttime eq '') { 4083: $starttime = $env{'course.'.$env{'request.course.id'}.'.default_enrollment_start_date'}; 4084: } 4085: if ($endtime eq '') { 4086: $endtime = $env{'course.'.$env{'request.course.id'}.'.default_enrollment_end_date'}; 4087: } 4088: my $startform = 4089: &Apache::lonhtmlcommon::date_setter($formname,'selfenroll_start_date',$starttime, 4090: undef,undef,undef,undef,undef,undef,undef,$nolink); 4091: my $endform = 4092: &Apache::lonhtmlcommon::date_setter($formname,'selfenroll_end_date',$endtime, 4093: undef,undef,undef,undef,undef,undef,undef,$nolink); 4094: $output .= &selfenroll_date_forms($startform,$endform); 4095: } elsif ($item eq 'access_dates') { 4096: my $starttime = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_start_access'}; 4097: my $endtime = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_end_access'}; 4098: if ($starttime eq '') { 4099: $starttime = $env{'course.'.$env{'request.course.id'}.'.default_enrollment_start_date'}; 4100: } 4101: if ($endtime eq '') { 4102: $endtime = $env{'course.'.$env{'request.course.id'}.'.default_enrollment_end_date'}; 4103: } 4104: my $startform = 4105: &Apache::lonhtmlcommon::date_setter($formname,'selfenroll_start_access',$starttime, 4106: undef,undef,undef,undef,undef,undef,undef,$nolink); 4107: my $endform = 4108: &Apache::lonhtmlcommon::date_setter($formname,'selfenroll_end_access',$endtime, 4109: undef,undef,undef,undef,undef,undef,undef,$nolink); 4110: $output .= &selfenroll_date_forms($startform,$endform); 4111: } elsif ($item eq 'section') { 4112: my $currsec = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_section'}; 4113: my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum); 4114: my $newsecval; 4115: if ($currsec ne 'none' && $currsec ne '') { 4116: if (!defined($sections_count{$currsec})) { 4117: $newsecval = $currsec; 4118: } 4119: } 4120: my $sections_select = 4121: &Apache::lonuserutils::course_sections(\%sections_count,'st',$currsec); 4122: $output .= '<table class="LC_createuser">'."\n". 4123: '<tr class="LC_section_row">'."\n". 4124: '<td align="center">'.&mt('Existing sections')."\n". 4125: '<br />'.$sections_select.'</td><td align="center">'. 4126: &mt('New section').'<br />'."\n". 4127: '<input type="text" name="newsec" size="15" value="'.$newsecval.'" />'."\n". 4128: '<input type="hidden" name="sections" value="" />'."\n". 4129: '<input type="hidden" name="state" value="done" />'."\n". 4130: '</td></tr></table>'."\n"; 4131: } elsif ($item eq 'approval') { 4132: my ($appon,$appoff); 4133: my $cid = $env{'request.course.id'}; 4134: my $currnotified = $env{'course.'.$cid.'.internal.selfenroll_notifylist'}; 4135: if ($env{'course.'.$cid.'.internal.selfenroll_approval'}) { 4136: $appon = ' checked="checked" '; 4137: $appoff = ' '; 4138: } else { 4139: $appon = ' '; 4140: $appoff = ' checked="checked" '; 4141: } 4142: $output .= '<label>'. 4143: '<input type="radio" name="selfenroll_approval" value="1"'.$appon.'/>'. 4144: &mt('Yes').'</label> <label>'. 4145: '<input type="radio" name="selfenroll_approval" value="0"'.$appoff.'/>'. 4146: &mt('No').'</label>'; 4147: my %advhash = &Apache::lonnet::get_course_adv_roles($cid,1); 4148: my (@ccs,%notified); 4149: if ($advhash{'cc'}) { 4150: @ccs = split(/,/,$advhash{'cc'}); 4151: } 4152: if ($currnotified) { 4153: foreach my $current (split(/,/,$currnotified)) { 4154: $notified{$current} = 1; 4155: if (!grep(/^\Q$current\E$/,@ccs)) { 4156: push(@ccs,$current); 4157: } 4158: } 4159: } 4160: if (@ccs) { 4161: $output .= '<br />'.&mt('Personnel to be notified when an enrollment request needs approval, or has been approved:').' '.&Apache::loncommon::start_data_table(). 4162: &Apache::loncommon::start_data_table_row(); 4163: my $count = 0; 4164: my $numcols = 4; 4165: foreach my $cc (sort(@ccs)) { 4166: my $notifyon; 4167: my ($ccuname,$ccudom) = split(/:/,$cc); 4168: if ($notified{$cc}) { 4169: $notifyon = ' checked="checked" '; 4170: } 4171: if ($count && !$count%$numcols) { 4172: $output .= &Apache::loncommon::end_data_table_row(). 4173: &Apache::loncommon::start_data_table_row() 4174: } 4175: $output .= '<td><span class="LC_nobreak"><label>'. 4176: '<input type="checkbox" name="selfenroll_notify"'.$notifyon.' value="'.$cc.'" />'. 4177: &Apache::loncommon::plainname($ccuname,$ccudom). 4178: '</label></span></td>'; 4179: $count; 4180: } 4181: my $rem = $count%$numcols; 4182: if ($rem) { 4183: my $emptycols = $numcols - $rem; 4184: for (my $i=0; $i<$emptycols; $i++) { 4185: $output .= '<td> </td>'; 4186: } 4187: } 4188: $output .= &Apache::loncommon::end_data_table_row(). 4189: &Apache::loncommon::end_data_table(); 4190: } 4191: } elsif ($item eq 'limit') { 4192: my ($crslimit,$selflimit,$nolimit); 4193: my $cid = $env{'request.course.id'}; 4194: my $currlim = $env{'course.'.$cid.'.internal.selfenroll_limit'}; 4195: my $currcap = $env{'course.'.$cid.'.internal.selfenroll_cap'}; 4196: my $nolimit = ' checked="checked" '; 4197: if ($currlim eq 'allstudents') { 4198: $crslimit = ' checked="checked" '; 4199: $selflimit = ' '; 4200: $nolimit = ' '; 4201: } elsif ($currlim eq 'selfenrolled') { 4202: $crslimit = ' '; 4203: $selflimit = ' checked="checked" '; 4204: $nolimit = ' '; 4205: } else { 4206: $crslimit = ' '; 4207: $selflimit = ' '; 4208: } 4209: $output .= '<table><tr><td><label>'. 4210: '<input type="radio" name="selfenroll_limit" value="none"'.$nolimit.'/>'. 4211: &mt('No limit').'</label></td><td><label>'. 4212: '<input type="radio" name="selfenroll_limit" value="allstudents"'.$crslimit.'/>'. 4213: &mt('Limit by total students').'</label></td><td><label>'. 4214: '<input type="radio" name="selfenroll_limit" value="selfenrolled"'.$selflimit.'/>'. 4215: &mt('Limit by total self-enrolled students'). 4216: '</td></tr><tr>'. 4217: '<td> </td><td colspan="2"><span class="LC_nobreak">'. 4218: (' 'x3).&mt('Maximum number allowed: '). 4219: '<input type="text" name="selfenroll_cap" size = "5" value="'.$currcap.'" /></td></tr></table>'; 4220: } 4221: $output .= &Apache::lonhtmlcommon::row_closure(1); 4222: } 4223: } 4224: $output .= &Apache::lonhtmlcommon::end_pick_box(). 4225: '<br /><input type="button" name="selfenrollconf" value="' 4226: .&mt('Save').'" onclick="validate_types(this.form);" />' 4227: .'<input type="hidden" name="action" value="selfenroll" /></form>'; 4228: $r->print($output); 4229: return; 4230: } 4231: 4232: sub display_selfenroll_queue { 4233: my ($r,$context,$permission,$cnum,$cdom) = @_; 4234: my $namespace = 'selfenrollrequests'; 4235: my ($output,%queue_by_date); 4236: my %requesthash = &Apache::lonnet::dump($namespace,$cdom,$cnum); 4237: if (keys(%requesthash) > 0) { 4238: $r->print('<form method="post" name="changequeue" action="/adm/createuser" />'. 4239: '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />'. 4240: '<input type="hidden" name="state" value="done" />'. 4241: &Apache::loncommon::start_data_table(). 4242: &Apache::loncommon::start_data_table_header_row(). 4243: '<th>'.&mt('Action').'</th>'. 4244: '<th>'.&mt('Requestor').'</th>'. 4245: '<th>'.&mt('Section').'</th>'. 4246: '<th>'.&mt('Date requested').'</th>'. 4247: &Apache::loncommon::end_data_table_header_row()); 4248: foreach my $item (keys(%requesthash)) { 4249: my ($timestamp,$usec) = split(/:/,$requesthash{$item}); 4250: if (exists($queue_by_date{$timestamp})) { 4251: if (ref($queue_by_date{$timestamp}) eq 'ARRAY') { 4252: push(@{$queue_by_date{$timestamp}},$item.':'.$usec); 4253: } 4254: } else { 4255: @{$queue_by_date{$timestamp}} = ($item.':'.$usec); 4256: } 4257: } 4258: my @sortedtimes = sort {$a <=> $b} (keys(%queue_by_date)); 4259: my $count = 0; 4260: foreach my $item (@sortedtimes) { 4261: if (ref($queue_by_date{$item}) eq 'ARRAY') { 4262: foreach my $request (sort(@{$queue_by_date{$item}})) { 4263: my ($puname,$pudom,$pusec) = split(/:/,$request); 4264: my $showsec = $pusec; 4265: if ($showsec eq '') { 4266: $showsec = &mt('none'); 4267: } 4268: my $namelink = &Apache::loncommon::aboutmewrapper( 4269: &Apache::loncommon::plainname($puname,$pudom), 4270: $puname,$pudom); 4271: $r->print(&Apache::loncommon::start_data_table_row(). 4272: '<td><span class="LC_nobreak"><label>'. 4273: '<input type="checkbox" value="'.$count.':'.$puname.':'.$pudom.':'.$pusec.'" name="approvereq" />'.&mt('Approve').'</label></span><br />'. 4274: '<span class="LC_nobreak"><label>'. 4275: '<input type="checkbox" value="'.$puname.':'.$pudom.'" name="rejectreq" />'.&mt('Reject').'</label></span><br /></td>'. 4276: '<td>'.$namelink.'</td>'. 4277: '<td>'.$showsec.'</td>'. 4278: '<td>'.&Apache::lonlocal::locallocaltime($item).'</td>'. 4279: &Apache::loncommon::end_data_table_row()); 4280: $count ++; 4281: } 4282: } 4283: } 4284: $r->print(&Apache::loncommon::end_data_table(). 4285: '<input type="submit" name="processqueue" value="'.&mt('Save').'" /></form>'); 4286: } else { 4287: $r->print(&mt('There are currently no enrollment requests.')); 4288: } 4289: return; 4290: } 4291: 4292: sub update_selfenroll_queue { 4293: my ($r,$context,$permission,$cid,$cnum,$cdom) = @_; 4294: my @approvals = &Apache::loncommon::get_env_multiple('form.approvereq'); 4295: my @rejections = &Apache::loncommon::get_env_multiple('form.rejectreq'); 4296: my $access_start = $env{'course.'.$cid.'.internal.selfenroll_start_access'}; 4297: my $access_end = $env{'course.'.$cid.'.internal.selfenroll_end_access'}; 4298: my $limit = $env{'course.'.$cid.'.internal.selfenroll_limit'}; 4299: my $cap = $env{'course.'.$cid.'.internal.selfenroll_cap'}; 4300: my $notifylist = $env{'course.'.$cid.'.internal.selfenroll_notifylist'}; 4301: my $namespace = 'selfenrollrequests'; 4302: my ($stucounts,$idx,$classlist) = &get_student_counts($cdom,$cnum); 4303: my %requesthash = &Apache::lonnet::dump($namespace,$cdom,$cnum); 4304: my $coursedesc = $env{'course.'.$cid.'.description'}; 4305: my $chome = &Apache::lonnet::homeserver($cnum,$cdom); 4306: my $hostname = &Apache::lonnet::hostname($chome); 4307: my $protocol = $Apache::lonnet::protocol{$chome}; 4308: $protocol = 'http' if ($protocol ne 'https'); 4309: my (@existing,@missingreq,@invalidusers,@limitexceeded,@enrolled, 4310: @enrollerrors,@warn_approves,@warn_rejects); 4311: my $now = time; 4312: my $sender = $env{'user.name'}.':'.$env{'user.domain'}; 4313: my $approvedmsg = [{ 4314: mt => 'Your request for enrollment has been approved.', 4315: }, 4316: { 4317: mt => 'Visit [_1], to log-in and access the course', 4318: args => [$protocol.'://'.$hostname], 4319: }]; 4320: 4321: my $rejectedmsg = [{ 4322: mt => 'Your request for enrollment has not been approved.', 4323: }]; 4324: foreach my $item (sort {$a <=> $b} @approvals) { 4325: my ($num,$uname,$udom,$usec) = split(/:/,$item); 4326: my $uhome = &Apache::lonnet::homeserver($uname,$udom); 4327: if ($uhome ne 'no_host') { 4328: if (exists($requesthash{$uname.':'.$udom})) { 4329: 4330: if (exists($classlist->{$uname.':'.$udom})) { 4331: if (ref($classlist->{$uname.':'.$udom}) eq 'ARRAY') { 4332: if (($classlist->{$uname.':'.$udom}->[$idx->{'status'}] eq 'Active') || 4333: ($classlist->{$uname.':'.$udom}->[$idx->{'status'}] eq 'Future')) { 4334: push(@existing,$uname.':'.$udom); 4335: next; 4336: } 4337: } 4338: } 4339: } else { 4340: push(@missingreq,$uname.':'.$udom); 4341: next; 4342: } 4343: if (!grep(/^\Q$item\E$/,@rejections)) { 4344: if ($limit eq 'allstudents') { 4345: if ($stucounts->{$limit} >= $cap) { 4346: push(@limitexceeded,$uname.':'.$udom); 4347: last; 4348: } 4349: } elsif ($limit eq 'selfenrolled') { 4350: if ($stucounts->{$limit} >= $cap) { 4351: push(@limitexceeded,$uname.':'.$udom); 4352: last; 4353: } 4354: } 4355: my $result = 4356: &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$usec,$access_end,$access_start,'selfenroll',undef,$cdom.'_'.$cnum,1); 4357: if ($result eq 'ok') { 4358: push(@enrolled,$uname.':'.$udom); 4359: $stucounts->{'allstudents'} ++; 4360: $stucounts->{'selfenrolled'} ++; 4361: &Apache::selfenroll::send_notification($uname.':'.$udom,$approvedmsg,$cid, 4362: $coursedesc,$now,'enroller',$sender); 4363: my %userrequest = ( 4364: $cdom.'_'.$cnum => { 4365: timestamp => $now, 4366: section => $usec, 4367: adjudicator => $env{'user.name'}.':'.$env{'user.domain'}, 4368: status => 'approved', 4369: } 4370: ); 4371: my $userresult = 4372: &Apache::lonnet::put($namespace,\%userrequest,$udom,$uname); 4373: if ($userresult ne 'ok') { 4374: push(@warn_approves,$uname.':'.$udom); 4375: } 4376: } else { 4377: push(@enrollerrors,$uname.':'.$udom); 4378: } 4379: } 4380: } else { 4381: push(@invalidusers,$uname.':'.$udom); 4382: } 4383: } 4384: my @changes = (@enrolled,@rejections); 4385: if (@rejections) { 4386: foreach my $user (@rejections) { 4387: &Apache::selfenroll::send_notification($user,$rejectedmsg,$cid, 4388: $coursedesc,$now,'enroller',$sender); 4389: my ($uname,$udom) = split(/:/,$user); 4390: my %userrequest = ( 4391: $cdom.'_'.$cnum => { 4392: timestamp => $now, 4393: adjudicator => $env{'user.name'}.':'.$env{'user.domain'}, 4394: status => 'rejected', 4395: } 4396: ); 4397: my $userresult = 4398: &Apache::lonnet::put($namespace,\%userrequest,$udom,$uname); 4399: if ($userresult ne 'ok') { 4400: push(@warn_rejects,$user); 4401: } 4402: } 4403: } 4404: if (@changes) { 4405: my $delresult = &Apache::lonnet::del($namespace,\@changes,$cdom,$cnum); 4406: if ($delresult eq 'ok') { 4407: my $namelink = 4408: &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'}).' ('.$env{'user.name'}.':'.$env{'user.domain'}.')'; 4409: my $chgmsg = "'Action was taken on the following enrollment requests by [_1].',$namelink"; 4410: my ($approvedlist,$rejectedlist); 4411: if (@enrolled) { 4412: $approvedlist = join("\n",@enrolled); 4413: $r->print('<p>'.&mt('The following were enrolled in the course:').'<ul>'); 4414: foreach my $user (@enrolled) { 4415: my ($uname,$udom) = split(/:/,$user); 4416: my $userlink = 4417: &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$udom),$uname,$udom); 4418: $r->print('<li>'.$userlink.'</li>'); 4419: } 4420: $r->print('</ul></p>'); 4421: } 4422: if (@rejections) { 4423: $rejectedlist = join("\n",@rejections); 4424: $r->print('<p>'.&mt('The following enrollment requests were rejected:').'<ul>'); 4425: foreach my $user (@rejections) { 4426: $r->print('<li>'.$user.'</li>'); 4427: } 4428: $r->print('</ul></p>'); 4429: } 4430: &Apache::selfenroll::send_notification($notifylist,$chgmsg,$cid, 4431: $coursedesc,$now,'managers', 4432: $sender,$approvedlist,$rejectedlist); 4433: } 4434: } 4435: if (@existing) { 4436: $r->print('<p>'.&mt('The following enrollment requests were deleted because the user is already enrolled in the course:').'<ul>'); 4437: foreach my $user (@existing) { 4438: $r->print('<li>'.$user.'</li>'); 4439: } 4440: $r->print('</ul></p>'); 4441: } 4442: if (@missingreq) { 4443: $r->print('<p>'.&mt('The following enrollment requests were ignored because the request is no longer in the enrollment queue:').'<ul>'); 4444: foreach my $user (@missingreq) { 4445: $r->print('<li>'.$user.'</li>'); 4446: } 4447: $r->print('</ul></p>'); 4448: } 4449: if (@invalidusers) { 4450: $r->print('<p>'.&mt('The following enrollment requests were deleted because the requestor does not have a LON-CAPA account:').'<ul>'); 4451: foreach my $user (@invalidusers) { 4452: $r->print('<li>'.$user.'</li>'); 4453: } 4454: $r->print('</ul></p>'); 4455: } 4456: if (@limitexceeded) { 4457: $r->print('<p>'.&mt('The following enrollment requests were skipped because the enrollment limit has been reached for the course:').'<ul>'); 4458: foreach my $user (@limitexceeded) { 4459: $r->print('<li>'.$user.'</li>'); 4460: } 4461: $r->print('</ul></p>'); 4462: } 4463: if (@enrollerrors) { 4464: $r->print('<p>'.&mt('The following enrollment requests could not be processed because an error occurred:').'<ul>'); 4465: foreach my $user (@enrollerrors) { 4466: $r->print('<li>'.$user.'</li>'); 4467: } 4468: $r->print('</ul></p>'); 4469: } 4470: if (@warn_approves) { 4471: $r->print('<p>'.&mt("For the following users, an error occurred when updating the user's own self-enroll requests record:").'<ul>'); 4472: foreach my $user (@warn_approves) { 4473: $r->print('<li>'.$user.'</li>'); 4474: } 4475: $r->print('</ul></p>'); 4476: } 4477: if (@warn_rejects) { 4478: $r->print('<p>'.&mt("For the following users, an error occurred when updating the user's own self-enroll requests record:").'<ul>'); 4479: foreach my $user (@warn_rejects) { 4480: $r->print('<li>'.$user.'</li>'); 4481: } 4482: $r->print('</ul></p>'); 4483: } 4484: return; 4485: } 4486: 4487: sub get_student_counts { 4488: my ($cdom,$cnum) = @_; 4489: my (%idx,%stucounts); 4490: my $classlist = &Apache::loncoursedata::get_classlist($cdom,$cnum); 4491: $idx{'type'} = &Apache::loncoursedata::CL_TYPE(); 4492: $idx{'status'} = &Apache::loncoursedata::CL_STATUS(); 4493: while (my ($student,$data) = each(%$classlist)) { 4494: if (($data->[$idx{'status'}] eq 'Active') || 4495: ($data->[$idx{'status'}] eq 'Future')) { 4496: if ($data->[$idx{'type'}] eq 'selfenroll') { 4497: $stucounts{'selfenroll'} ++; 4498: } 4499: $stucounts{'allstudents'} ++; 4500: } 4501: } 4502: return (\%stucounts,\%idx,$classlist); 4503: } 4504: 4505: sub visible_in_cat { 4506: my ($cdom,$cnum) = @_; 4507: my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom); 4508: my ($cathash,%settable,@vismsgs,$cansetvis); 4509: my %visactions = &Apache::lonlocal::texthash( 4510: vis => 'Your course currently appears in the Course Catalog for this domain.', 4511: 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.', 4512: miss => 'Your course does not currently appear in the Course Catalog for this domain.', 4513: yous => 'You should remedy this if you plan to allow self-enrollment, otherwise students will have difficulty finding your course.', 4514: 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.', 4515: make => 'Make any changes to self-enrollment settings below, click "Save", then take action to include the course in the Catalog:', 4516: take => 'Take the following action to ensure the course appears in the Catalog:', 4517: dc_unhide => 'Ask a domain coordinator to change the "Exclude from course catalog" setting.', 4518: dc_addinst => 'Ask a domain coordinator to enable display the catalog of "Official courses (with institutional codes)".', 4519: dc_instcode => 'Ask a domain coordinator to assign an institutional code (if this is an official course).', 4520: dc_catalog => 'Ask a domain coordinator to enable or create at least one course category in the domain.', 4521: dc_categories => 'Ask a domain coordinator to create a hierarchy of categories and sub categories for courses in the domain.', 4522: 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', 4523: dc_addcat => 'Ask a domain coordinator to assign a category to the course.', 4524: ); 4525: $visactions{'unhide'} = &mt('Use [_1]Set course environment[_2] to change the "Exclude from course catalog" setting.','"<a href="/adm/parmset?action=crsenv">','</a>"'); 4526: $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>"'); 4527: $visactions{'addcat'} = &mt('Use [_1]Set course environment[_2] to assign a category to the course.','"<a href="/adm/parmset?action=crsenv">','</a>"'); 4528: if (ref($domconf{'coursecategories'}) eq 'HASH') { 4529: if ($domconf{'coursecategories'}{'togglecats'} eq 'crs') { 4530: $settable{'togglecats'} = 1; 4531: } 4532: if ($domconf{'coursecategories'}{'categorize'} eq 'crs') { 4533: $settable{'categorize'} = 1; 4534: } 4535: $cathash = $domconf{'coursecategories'}{'cats'}; 4536: } 4537: if ($settable{'togglecats'} && $settable{'categorize'}) { 4538: $cansetvis = &mt('You are able to both assign a course category and choose to exclude this course from the catalog.'); 4539: } elsif ($settable{'togglecats'}) { 4540: $cansetvis = &mt('You are able to choose to exclude this course from the catalog, but only a Domain Coordinator may assign a course category.'); 4541: } elsif ($settable{'categorize'}) { 4542: $cansetvis = &mt('You may assign a course category, but only a Domain Coordinator may choose to exclude this course from the catalog.'); 4543: } else { 4544: $cansetvis = &mt('Only a Domain Coordinator may assign a course category or choose to exclude this course from the catalog.'); 4545: } 4546: 4547: my %currsettings = 4548: &Apache::lonnet::get('environment',['hidefromcat','categories','internal.coursecode'], 4549: $cdom,$cnum); 4550: my $visible = 0; 4551: if ($currsettings{'internal.coursecode'} ne '') { 4552: if (ref($domconf{'coursecategories'}) eq 'HASH') { 4553: $cathash = $domconf{'coursecategories'}{'cats'}; 4554: if (ref($cathash) eq 'HASH') { 4555: if ($cathash->{'instcode::0'} eq '') { 4556: push(@vismsgs,'dc_addinst'); 4557: } else { 4558: $visible = 1; 4559: } 4560: } else { 4561: $visible = 1; 4562: } 4563: } else { 4564: $visible = 1; 4565: } 4566: } else { 4567: if (ref($cathash) eq 'HASH') { 4568: if ($cathash->{'instcode::0'} ne '') { 4569: push(@vismsgs,'dc_instcode'); 4570: } 4571: } else { 4572: push(@vismsgs,'dc_instcode'); 4573: } 4574: } 4575: if ($currsettings{'categories'} ne '') { 4576: my $cathash; 4577: if (ref($domconf{'coursecategories'}) eq 'HASH') { 4578: $cathash = $domconf{'coursecategories'}{'cats'}; 4579: if (ref($cathash) eq 'HASH') { 4580: if (keys(%{$cathash}) == 0) { 4581: push(@vismsgs,'dc_catalog'); 4582: } elsif ((keys(%{$cathash}) == 1) && ($cathash->{'instcode::0'} ne '')) { 4583: push(@vismsgs,'dc_categories'); 4584: } else { 4585: my @currcategories = split('&',$currsettings{'categories'}); 4586: my $matched = 0; 4587: foreach my $cat (@currcategories) { 4588: if ($cathash->{$cat} ne '') { 4589: $visible = 1; 4590: $matched = 1; 4591: last; 4592: } 4593: } 4594: if (!$matched) { 4595: if ($settable{'categorize'}) { 4596: push(@vismsgs,'chgcat'); 4597: } else { 4598: push(@vismsgs,'dc_chgcat'); 4599: } 4600: } 4601: } 4602: } 4603: } 4604: } else { 4605: if (ref($cathash) eq 'HASH') { 4606: if ((keys(%{$cathash}) > 1) || 4607: (keys(%{$cathash}) == 1) && ($cathash->{'instcode::0'} eq '')) { 4608: if ($settable{'categorize'}) { 4609: push(@vismsgs,'addcat'); 4610: } else { 4611: push(@vismsgs,'dc_addcat'); 4612: } 4613: } 4614: } 4615: } 4616: if ($currsettings{'hidefromcat'} eq 'yes') { 4617: $visible = 0; 4618: if ($settable{'togglecats'}) { 4619: unshift(@vismsgs,'unhide'); 4620: } else { 4621: unshift(@vismsgs,'dc_unhide') 4622: } 4623: } 4624: return ($visible,$cansetvis,\@vismsgs,\%visactions); 4625: } 4626: 4627: sub new_selfenroll_dom_row { 4628: my ($newdom,$num) = @_; 4629: my $domdesc = &Apache::lonnet::domain($newdom); 4630: my $output; 4631: if ($domdesc ne '') { 4632: $output .= &Apache::loncommon::start_data_table_row() 4633: .'<td valign="top"><span class="LC_nobreak">'.&mt('Domain:').' <b>'.$domdesc 4634: .' ('.$newdom.')</b><input type="hidden" name="selfenroll_dom_'.$num 4635: .'" value="'.$newdom.'" /></span><br />' 4636: .'<span class="LC_nobreak"><label><input type="checkbox" ' 4637: .'name="selfenroll_activate" value="'.$num.'" ' 4638: .'onchange="javascript:update_types(' 4639: ."'selfenroll_activate','$num'".');" />' 4640: .&mt('Activate').'</label></span></td>'; 4641: my @currinsttypes; 4642: $output .= '<td>'.&mt('User types:').'<br />' 4643: .&selfenroll_inst_types($num,$newdom,\@currinsttypes).'</td>' 4644: .&Apache::loncommon::end_data_table_row(); 4645: } 4646: return $output; 4647: } 4648: 4649: sub selfenroll_inst_types { 4650: my ($num,$currdom,$currinsttypes) = @_; 4651: my $output; 4652: my $numinrow = 4; 4653: my $count = 0; 4654: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($currdom); 4655: my $othervalue = 'any'; 4656: if ((ref($types) eq 'ARRAY') && (ref($usertypes) eq 'HASH')) { 4657: if (keys(%{$usertypes}) > 0) { 4658: $othervalue = 'other'; 4659: } 4660: $output .= '<table><tr>'; 4661: foreach my $type (@{$types}) { 4662: if (($count > 0) && ($count%$numinrow == 0)) { 4663: $output .= '</tr><tr>'; 4664: } 4665: if (defined($usertypes->{$type})) { 4666: my $esc_type = &escape($type); 4667: $output .= '<td><span class="LC_nobreak"><label><input type = "checkbox" value="'. 4668: $esc_type.'" '; 4669: if (ref($currinsttypes) eq 'ARRAY') { 4670: if (@{$currinsttypes} > 0) { 4671: if (grep(/^any$/,@{$currinsttypes})) { 4672: $output .= 'checked="checked"'; 4673: } elsif (grep(/^\Q$esc_type\E$/,@{$currinsttypes})) { 4674: $output .= 'checked="checked"'; 4675: } 4676: } else { 4677: $output .= 'checked="checked"'; 4678: } 4679: } 4680: $output .= ' name="selfenroll_types_'.$num.'" />'.$usertypes->{$type}.'</label></span></td>'; 4681: } 4682: $count ++; 4683: } 4684: if (($count > 0) && ($count%$numinrow == 0)) { 4685: $output .= '</tr><tr>'; 4686: } 4687: $output .= '<td><span class="LC_nobreak"><label><input type = "checkbox" value="'.$othervalue.'"'; 4688: if (ref($currinsttypes) eq 'ARRAY') { 4689: if (@{$currinsttypes} > 0) { 4690: if (grep(/^any$/,@{$currinsttypes})) { 4691: $output .= ' checked="checked"'; 4692: } elsif ($othervalue eq 'other') { 4693: if (grep(/^\Q$othervalue\E$/,@{$currinsttypes})) { 4694: $output .= ' checked="checked"'; 4695: } 4696: } 4697: } else { 4698: $output .= ' checked="checked"'; 4699: } 4700: } else { 4701: $output .= ' checked="checked"'; 4702: } 4703: $output .= ' name="selfenroll_types_'.$num.'" />'.$othertitle.'</label></span></td></tr></table>'; 4704: } 4705: return $output; 4706: } 4707: 4708: sub selfenroll_date_forms { 4709: my ($startform,$endform) = @_; 4710: my $output .= &Apache::lonhtmlcommon::start_pick_box()."\n". 4711: &Apache::lonhtmlcommon::row_title(&mt('Start date'), 4712: 'LC_oddrow_value')."\n". 4713: $startform."\n". 4714: &Apache::lonhtmlcommon::row_closure(1). 4715: &Apache::lonhtmlcommon::row_title(&mt('End date'), 4716: 'LC_oddrow_value')."\n". 4717: $endform."\n". 4718: &Apache::lonhtmlcommon::row_closure(1). 4719: &Apache::lonhtmlcommon::end_pick_box(); 4720: return $output; 4721: } 4722: 4723: sub print_userchangelogs_display { 4724: my ($r,$context,$permission) = @_; 4725: my $formname = 'roleslog'; 4726: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; 4727: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; 4728: my %roleslog=&Apache::lonnet::dump('nohist_rolelog',$cdom,$cnum); 4729: if ((keys(%roleslog))[0]=~/^error\:/) { undef(%roleslog); } 4730: 4731: $r->print('<form action="/adm/createuser" method="post" name="'.$formname.'">'); 4732: my %saveable_parameters = ('show' => 'scalar',); 4733: &Apache::loncommon::store_course_settings('roles_log', 4734: \%saveable_parameters); 4735: &Apache::loncommon::restore_course_settings('roles_log', 4736: \%saveable_parameters); 4737: # set defaults 4738: my $now = time(); 4739: my $defstart = $now - (7*24*3600); #7 days ago 4740: my %defaults = ( 4741: page => '1', 4742: show => '10', 4743: role => 'any', 4744: chgcontext => 'any', 4745: rolelog_start_date => $defstart, 4746: rolelog_end_date => $now, 4747: ); 4748: my $more_records = 0; 4749: 4750: # set current 4751: my %curr; 4752: foreach my $item ('show','page','role','chgcontext') { 4753: $curr{$item} = $env{'form.'.$item}; 4754: } 4755: my ($startdate,$enddate) = 4756: &Apache::lonuserutils::get_dates_from_form('rolelog_start_date','rolelog_end_date'); 4757: $curr{'rolelog_start_date'} = $startdate; 4758: $curr{'rolelog_end_date'} = $enddate; 4759: foreach my $key (keys(%defaults)) { 4760: if ($curr{$key} eq '') { 4761: $curr{$key} = $defaults{$key}; 4762: } 4763: } 4764: my (%whodunit,%changed,$version); 4765: ($version) = ($r->dir_config('lonVersion') =~ /^([\d\.]+)\-/); 4766: $r->print(&role_display_filter($formname,$cdom,$cnum,\%curr,$version)); 4767: my $showntablehdr = 0; 4768: my $tablehdr = &Apache::loncommon::start_data_table(). 4769: &Apache::loncommon::start_data_table_header_row(). 4770: '<th> </th><th>'.&mt('When').'</th><th>'.&mt('Who made the change'). 4771: '</th><th>'.&mt('Changed User').'</th><th>'.&mt('Role').'</th><th>'.&mt('Section').'</th><th>'. 4772: &mt('Context').'</th><th>'.&mt('Start').'</th><th>'.&mt('End').'</th>'. 4773: &Apache::loncommon::end_data_table_header_row(); 4774: my ($minshown,$maxshown); 4775: $minshown = 1; 4776: my $count = 0; 4777: if ($curr{'show'} ne &mt('all')) { 4778: $maxshown = $curr{'page'} * $curr{'show'}; 4779: if ($curr{'page'} > 1) { 4780: $minshown = 1 + ($curr{'page'} - 1) * $curr{'show'}; 4781: } 4782: } 4783: foreach my $id (sort { $roleslog{$b}{'exe_time'}<=>$roleslog{$a}{'exe_time'} } (keys(%roleslog))) { 4784: next if (($roleslog{$id}{'exe_time'} < $curr{'rolelog_start_date'}) || 4785: ($roleslog{$id}{'exe_time'} > $curr{'rolelog_end_date'})); 4786: if ($curr{'show'} ne &mt('all')) { 4787: if ($count >= $curr{'page'} * $curr{'show'}) { 4788: $more_records = 1; 4789: last; 4790: } 4791: } 4792: if ($curr{'role'} ne 'any') { 4793: next if ($roleslog{$id}{'logentry'}{'role'} ne $curr{'role'}); 4794: } 4795: if ($curr{'chgcontext'} ne 'any') { 4796: if ($curr{'chgcontext'} eq 'selfenroll') { 4797: next if (!$roleslog{$id}{'logentry'}{'selfenroll'}); 4798: } else { 4799: next if ($roleslog{$id}{'logentry'}{'context'} ne $curr{'chgcontext'}); 4800: } 4801: } 4802: $count ++; 4803: next if ($count < $minshown); 4804: if (!$showntablehdr) { 4805: $r->print($tablehdr); 4806: $showntablehdr = 1; 4807: } 4808: if ($whodunit{$roleslog{$id}{'exe_uname'}.':'.$roleslog{$id}{'exe_udom'}} eq '') { 4809: $whodunit{$roleslog{$id}{'exe_uname'}.':'.$roleslog{$id}{'exe_udom'}} = 4810: &Apache::loncommon::plainname($roleslog{$id}{'exe_uname'},$roleslog{$id}{'exe_udom'}); 4811: } 4812: if ($changed{$roleslog{$id}{'uname'}.':'.$roleslog{$id}{'udom'}} eq '') { 4813: $changed{$roleslog{$id}{'uname'}.':'.$roleslog{$id}{'udom'}} = 4814: &Apache::loncommon::plainname($roleslog{$id}{'uname'},$roleslog{$id}{'udom'}); 4815: } 4816: my $sec = $roleslog{$id}{'logentry'}{'section'}; 4817: if ($sec eq '') { 4818: $sec = &mt('None'); 4819: } 4820: my ($rolestart,$roleend); 4821: if ($roleslog{$id}{'delflag'}) { 4822: $rolestart = &mt('deleted'); 4823: $roleend = &mt('deleted'); 4824: } else { 4825: $rolestart = $roleslog{$id}{'logentry'}{'start'}; 4826: $roleend = $roleslog{$id}{'logentry'}{'end'}; 4827: if ($rolestart eq '' || $rolestart == 0) { 4828: $rolestart = &mt('No start date'); 4829: } else { 4830: $rolestart = &Apache::lonlocal::locallocaltime($rolestart); 4831: } 4832: if ($roleend eq '' || $roleend == 0) { 4833: $roleend = &mt('No end date'); 4834: } else { 4835: $roleend = &Apache::lonlocal::locallocaltime($roleend); 4836: } 4837: } 4838: my $chgcontext = $roleslog{$id}{'logentry'}{'context'}; 4839: if ($roleslog{$id}{'logentry'}{'selfenroll'}) { 4840: $chgcontext = 'selfenroll'; 4841: } 4842: my %lt = &rolechg_contexts(); 4843: if ($chgcontext ne '' && $lt{$chgcontext} ne '') { 4844: $chgcontext = $lt{$chgcontext}; 4845: } 4846: $r->print(&Apache::loncommon::start_data_table_row().'<td>'.$count.'</td><td>'.&Apache::lonlocal::locallocaltime($roleslog{$id}{'exe_time'}).'</td><td>'.$whodunit{$roleslog{$id}{'exe_uname'}.':'.$roleslog{$id}{'exe_udom'}}.'</td><td>'.$changed{$roleslog{$id}{'uname'}.':'.$roleslog{$id}{'udom'}}.'</td><td>'.&Apache::lonnet::plaintext($roleslog{$id}{'logentry'}{'role'}).'</td><td>'.$sec.'</td><td>'.$chgcontext.'</td><td>'.$rolestart.'</td><td>'.$roleend.'</td>'.&Apache::loncommon::end_data_table_row()."\n"); 4847: } 4848: if ($showntablehdr) { 4849: $r->print(&Apache::loncommon::end_data_table().'<br />'); 4850: if (($curr{'page'} > 1) || ($more_records)) { 4851: $r->print('<table><tr>'); 4852: if ($curr{'page'} > 1) { 4853: $r->print('<td><a href="javascript:chgPage('."'previous'".');">'.&mt('Previous [_1] changes',$curr{'show'}).'</a></td>'); 4854: } 4855: if ($more_records) { 4856: $r->print('<td><a href="javascript:chgPage('."'next'".');">'.&mt('Next [_1] changes',$curr{'show'}).'</a></td>'); 4857: } 4858: $r->print('</tr></table>'); 4859: $r->print(<<"ENDSCRIPT"); 4860: <script type="text/javascript"> 4861: function chgPage(caller) { 4862: if (caller == 'previous') { 4863: document.$formname.page.value --; 4864: } 4865: if (caller == 'next') { 4866: document.$formname.page.value ++; 4867: } 4868: document.$formname.submit(); 4869: return; 4870: } 4871: </script> 4872: ENDSCRIPT 4873: } 4874: } else { 4875: $r->print(&mt('There are no records to display')); 4876: } 4877: $r->print('<input type="hidden" name="page" value="'.$curr{'page'}.'" />'. 4878: '<input type="hidden" name="action" value="changelogs" /></form>'); 4879: return; 4880: } 4881: 4882: sub role_display_filter { 4883: my ($formname,$cdom,$cnum,$curr,$version) = @_; 4884: my $context = 'course'; 4885: my $nolink = 1; 4886: my $output = '<table><tr><td valign="top">'. 4887: '<span class="LC_nobreak"><b>'.&mt('Changes/page:').'</b><br />'. 4888: &Apache::lonmeta::selectbox('show',$curr->{'show'},undef, 4889: (&mt('all'),5,10,20,50,100,1000,10000)). 4890: '</td><td> </td>'; 4891: my $startform = 4892: &Apache::lonhtmlcommon::date_setter($formname,'rolelog_start_date', 4893: $curr->{'rolelog_start_date'},undef, 4894: undef,undef,undef,undef,undef,undef,$nolink); 4895: my $endform = 4896: &Apache::lonhtmlcommon::date_setter($formname,'rolelog_end_date', 4897: $curr->{'rolelog_end_date'},undef, 4898: undef,undef,undef,undef,undef,undef,$nolink); 4899: my %lt = &rolechg_contexts(); 4900: $output .= '<td valign="top"><b>'.&mt('Window during which changes occurred:').'</b><br /><table><tr><td>'.&mt('After:'). 4901: '</td><td>'.$startform.'</td></tr><tr><td>'.&mt('Before:').'</td><td>'. 4902: $endform.'</td></tr></table></td><td> </td>'. 4903: '<td valign="top"><b>'.&mt('Role:').'</b><br />'. 4904: '<select name="role"><option value="any"'; 4905: if ($curr->{'role'} eq 'any') { 4906: $output .= ' selected="selected"'; 4907: } 4908: $output .= '>'.&mt('Any').'</option>'."\n"; 4909: my @roles = &Apache::lonuserutils::course_roles($context,undef,1); 4910: foreach my $role (@roles) { 4911: my $plrole; 4912: if ($role eq 'cr') { 4913: $plrole = &mt('Custom Role'); 4914: } else { 4915: $plrole=&Apache::lonnet::plaintext($role); 4916: } 4917: my $selstr = ''; 4918: if ($role eq $curr->{'role'}) { 4919: $selstr = ' selected="selected"'; 4920: } 4921: $output .= ' <option value="'.$role.'"'.$selstr.'>'.$plrole.'</option>'; 4922: } 4923: $output .= '</select></td><td> </td><td valign="top"><b>'. 4924: &mt('Context:').'</b><br /><select name="chgcontext">'; 4925: foreach my $chgtype ('any','auto','updatenow','createcourse','course','domain','selfenroll') { 4926: my $selstr = ''; 4927: if ($curr->{'chgcontext'} eq $chgtype) { 4928: $output .= $selstr = ' selected="selected"'; 4929: } 4930: if (($chgtype eq 'auto') || ($chgtype eq 'updatenow')) { 4931: next if (!&Apache::lonnet::auto_run($cnum,$cdom)); 4932: } 4933: $output .= '<option value="'.$chgtype.'"'.$selstr.'>'.$lt{$chgtype}.'</option>'."\n"; 4934: } 4935: $output .= '</select></td><td> </td><td valign="middle"><input type="submit" value="'. 4936: &mt('Update Display').'" /></tr></table>'. 4937: '<span class="LC_roleslog_note">'. 4938: &mt('[_1]Note:[_2] Only changes made from servers running LON-CAPA 2.6.99.0 or later are displayed.'); 4939: if ($version) { 4940: $output .= ' '.&mt('This server is version [_3].','<b>','</b>',$version); } 4941: $output .= '</span><hr noshade><br />'; 4942: return $output; 4943: } 4944: 4945: sub rolechg_contexts { 4946: my %lt = &Apache::lonlocal::texthash ( 4947: any => 'Any', 4948: auto => 'Automated enrollment', 4949: updatenow => 'Roster Update', 4950: createcourse => 'Course Creation', 4951: course => 'User Management in course', 4952: domain => 'User Management in domain', 4953: selfenroll => 'Self-enrolled', 4954: ); 4955: return %lt; 4956: } 4957: 4958: #-------------------------------------------------- functions for &phase_two 4959: sub user_search_result { 4960: my ($context,$srch) = @_; 4961: my %allhomes; 4962: my %inst_matches; 4963: my %srch_results; 4964: my ($response,$currstate,$forcenewuser,$dirsrchres); 4965: $srch->{'srchterm'} =~ s/\s+/ /g; 4966: if ($srch->{'srchby'} !~ /^(uname|lastname|lastfirst)$/) { 4967: $response = &mt('Invalid search.'); 4968: } 4969: if ($srch->{'srchin'} !~ /^(crs|dom|alc|instd)$/) { 4970: $response = &mt('Invalid search.'); 4971: } 4972: if ($srch->{'srchtype'} !~ /^(exact|contains|begins)$/) { 4973: $response = &mt('Invalid search.'); 4974: } 4975: if ($srch->{'srchterm'} eq '') { 4976: $response = &mt('You must enter a search term.'); 4977: } 4978: if ($srch->{'srchterm'} =~ /^\s+$/) { 4979: $response = &mt('Your search term must contain more than just spaces.'); 4980: } 4981: if (($srch->{'srchin'} eq 'dom') || ($srch->{'srchin'} eq 'instd')) { 4982: if (($srch->{'srchdomain'} eq '') || 4983: ! (&Apache::lonnet::domain($srch->{'srchdomain'}))) { 4984: $response = &mt('You must specify a valid domain when searching in a domain or institutional directory.') 4985: } 4986: } 4987: if (($srch->{'srchin'} eq 'dom') || ($srch->{'srchin'} eq 'crs') || 4988: ($srch->{'srchin'} eq 'alc')) { 4989: if ($srch->{'srchby'} eq 'uname') { 4990: my $unamecheck = $srch->{'srchterm'}; 4991: if ($srch->{'srchtype'} eq 'contains') { 4992: if ($unamecheck !~ /^\w/) { 4993: $unamecheck = 'a'.$unamecheck; 4994: } 4995: } 4996: if ($unamecheck !~ /^$match_username$/) { 4997: $response = &mt('You must specify a valid username. Only the following are allowed: letters numbers - . @'); 4998: } 4999: } 5000: } 5001: if ($response ne '') { 5002: $response = '<span class="LC_warning">'.$response.'</span>'; 5003: } 5004: if ($srch->{'srchin'} eq 'instd') { 5005: my $instd_chk = &directorysrch_check($srch); 5006: if ($instd_chk ne 'ok') { 5007: $response = '<span class="LC_warning">'.$instd_chk.'</span>'. 5008: '<br />'.&mt('You may want to search in the LON-CAPA domain instead of the institutional directory.').'<br /><br />'; 5009: } 5010: } 5011: if ($response ne '') { 5012: return ($currstate,$response); 5013: } 5014: if ($srch->{'srchby'} eq 'uname') { 5015: if (($srch->{'srchin'} eq 'dom') || ($srch->{'srchin'} eq 'crs')) { 5016: if ($env{'form.forcenew'}) { 5017: if ($srch->{'srchdomain'} ne $env{'request.role.domain'}) { 5018: my $uhome=&Apache::lonnet::homeserver($srch->{'srchterm'},$srch->{'srchdomain'}); 5019: if ($uhome eq 'no_host') { 5020: my $domdesc = &Apache::lonnet::domain($env{'request.role.domain'},'description'); 5021: my $showdom = &display_domain_info($env{'request.role.domain'}); 5022: $response = &mt('New users can only be created in the domain to which your current role belongs - [_1].',$showdom); 5023: } else { 5024: $currstate = 'modify'; 5025: } 5026: } else { 5027: $currstate = 'modify'; 5028: } 5029: } else { 5030: if ($srch->{'srchin'} eq 'dom') { 5031: if ($srch->{'srchtype'} eq 'exact') { 5032: my $uhome=&Apache::lonnet::homeserver($srch->{'srchterm'},$srch->{'srchdomain'}); 5033: if ($uhome eq 'no_host') { 5034: ($currstate,$response,$forcenewuser) = 5035: &build_search_response($context,$srch,%srch_results); 5036: } else { 5037: $currstate = 'modify'; 5038: } 5039: } else { 5040: %srch_results = &Apache::lonnet::usersearch($srch); 5041: ($currstate,$response,$forcenewuser) = 5042: &build_search_response($context,$srch,%srch_results); 5043: } 5044: } else { 5045: my $courseusers = &get_courseusers(); 5046: if ($srch->{'srchtype'} eq 'exact') { 5047: if (exists($courseusers->{$srch->{'srchterm'}.':'.$srch->{'srchdomain'}})) { 5048: $currstate = 'modify'; 5049: } else { 5050: ($currstate,$response,$forcenewuser) = 5051: &build_search_response($context,$srch,%srch_results); 5052: } 5053: } else { 5054: foreach my $user (keys(%$courseusers)) { 5055: my ($cuname,$cudomain) = split(/:/,$user); 5056: if ($cudomain eq $srch->{'srchdomain'}) { 5057: my $matched = 0; 5058: if ($srch->{'srchtype'} eq 'begins') { 5059: if ($cuname =~ /^\Q$srch->{'srchterm'}\E/i) { 5060: $matched = 1; 5061: } 5062: } else { 5063: if ($cuname =~ /\Q$srch->{'srchterm'}\E/i) { 5064: $matched = 1; 5065: } 5066: } 5067: if ($matched) { 5068: $srch_results{$user} = 5069: {&Apache::lonnet::get('environment', 5070: ['firstname', 5071: 'lastname', 5072: 'permanentemail'], 5073: $cudomain,$cuname)}; 5074: } 5075: } 5076: } 5077: ($currstate,$response,$forcenewuser) = 5078: &build_search_response($context,$srch,%srch_results); 5079: } 5080: } 5081: } 5082: } elsif ($srch->{'srchin'} eq 'alc') { 5083: $currstate = 'query'; 5084: } elsif ($srch->{'srchin'} eq 'instd') { 5085: ($dirsrchres,%srch_results) = &Apache::lonnet::inst_directory_query($srch); 5086: if ($dirsrchres eq 'ok') { 5087: ($currstate,$response,$forcenewuser) = 5088: &build_search_response($context,$srch,%srch_results); 5089: } else { 5090: my $showdom = &display_domain_info($srch->{'srchdomain'}); 5091: $response = '<span class="LC_warning">'. 5092: &mt('Institutional directory search is not available in domain: [_1]',$showdom). 5093: '</span><br />'. 5094: &mt('You may want to search in the LON-CAPA domain instead of the institutional directory.'). 5095: '<br /><br />'; 5096: } 5097: } 5098: } else { 5099: if ($srch->{'srchin'} eq 'dom') { 5100: %srch_results = &Apache::lonnet::usersearch($srch); 5101: ($currstate,$response,$forcenewuser) = 5102: &build_search_response($context,$srch,%srch_results); 5103: } elsif ($srch->{'srchin'} eq 'crs') { 5104: my $courseusers = &get_courseusers(); 5105: foreach my $user (keys(%$courseusers)) { 5106: my ($uname,$udom) = split(/:/,$user); 5107: my %names = &Apache::loncommon::getnames($uname,$udom); 5108: my %emails = &Apache::loncommon::getemails($uname,$udom); 5109: if ($srch->{'srchby'} eq 'lastname') { 5110: if ((($srch->{'srchtype'} eq 'exact') && 5111: ($names{'lastname'} eq $srch->{'srchterm'})) || 5112: (($srch->{'srchtype'} eq 'begins') && 5113: ($names{'lastname'} =~ /^\Q$srch->{'srchterm'}\E/i)) || 5114: (($srch->{'srchtype'} eq 'contains') && 5115: ($names{'lastname'} =~ /\Q$srch->{'srchterm'}\E/i))) { 5116: $srch_results{$user} = {firstname => $names{'firstname'}, 5117: lastname => $names{'lastname'}, 5118: permanentemail => $emails{'permanentemail'}, 5119: }; 5120: } 5121: } elsif ($srch->{'srchby'} eq 'lastfirst') { 5122: my ($srchlast,$srchfirst) = split(/,/,$srch->{'srchterm'}); 5123: $srchlast =~ s/\s+$//; 5124: $srchfirst =~ s/^\s+//; 5125: if ($srch->{'srchtype'} eq 'exact') { 5126: if (($names{'lastname'} eq $srchlast) && 5127: ($names{'firstname'} eq $srchfirst)) { 5128: $srch_results{$user} = {firstname => $names{'firstname'}, 5129: lastname => $names{'lastname'}, 5130: permanentemail => $emails{'permanentemail'}, 5131: 5132: }; 5133: } 5134: } elsif ($srch->{'srchtype'} eq 'begins') { 5135: if (($names{'lastname'} =~ /^\Q$srchlast\E/i) && 5136: ($names{'firstname'} =~ /^\Q$srchfirst\E/i)) { 5137: $srch_results{$user} = {firstname => $names{'firstname'}, 5138: lastname => $names{'lastname'}, 5139: permanentemail => $emails{'permanentemail'}, 5140: }; 5141: } 5142: } else { 5143: if (($names{'lastname'} =~ /\Q$srchlast\E/i) && 5144: ($names{'firstname'} =~ /\Q$srchfirst\E/i)) { 5145: $srch_results{$user} = {firstname => $names{'firstname'}, 5146: lastname => $names{'lastname'}, 5147: permanentemail => $emails{'permanentemail'}, 5148: }; 5149: } 5150: } 5151: } 5152: } 5153: ($currstate,$response,$forcenewuser) = 5154: &build_search_response($context,$srch,%srch_results); 5155: } elsif ($srch->{'srchin'} eq 'alc') { 5156: $currstate = 'query'; 5157: } elsif ($srch->{'srchin'} eq 'instd') { 5158: ($dirsrchres,%srch_results) = &Apache::lonnet::inst_directory_query($srch); 5159: if ($dirsrchres eq 'ok') { 5160: ($currstate,$response,$forcenewuser) = 5161: &build_search_response($context,$srch,%srch_results); 5162: } else { 5163: my $showdom = &display_domain_info($srch->{'srchdomain'}); $response = '<span class="LC_warning">'. 5164: &mt('Institutional directory search is not available in domain: [_1]',$showdom). 5165: '</span><br />'. 5166: &mt('You may want to search in the LON-CAPA domain instead of the institutional directory.'). 5167: '<br /><br />'; 5168: } 5169: } 5170: } 5171: return ($currstate,$response,$forcenewuser,\%srch_results); 5172: } 5173: 5174: sub directorysrch_check { 5175: my ($srch) = @_; 5176: my $can_search = 0; 5177: my $response; 5178: my %dom_inst_srch = &Apache::lonnet::get_dom('configuration', 5179: ['directorysrch'],$srch->{'srchdomain'}); 5180: my $showdom = &display_domain_info($srch->{'srchdomain'}); 5181: if (ref($dom_inst_srch{'directorysrch'}) eq 'HASH') { 5182: if (!$dom_inst_srch{'directorysrch'}{'available'}) { 5183: return &mt('Institutional directory search is not available in domain: [_1]',$showdom); 5184: } 5185: if ($dom_inst_srch{'directorysrch'}{'localonly'}) { 5186: if ($env{'request.role.domain'} ne $srch->{'srchdomain'}) { 5187: return &mt('Institutional directory search in domain: [_1] is only allowed for users with a current role in the domain.',$showdom); 5188: } 5189: my @usertypes = split(/:/,$env{'environment.inststatus'}); 5190: if (!@usertypes) { 5191: push(@usertypes,'default'); 5192: } 5193: if (ref($dom_inst_srch{'directorysrch'}{'cansearch'}) eq 'ARRAY') { 5194: foreach my $type (@usertypes) { 5195: if (grep(/^\Q$type\E$/,@{$dom_inst_srch{'directorysrch'}{'cansearch'}})) { 5196: $can_search = 1; 5197: last; 5198: } 5199: } 5200: } 5201: if (!$can_search) { 5202: my ($insttypes,$order) = &Apache::lonnet::retrieve_inst_usertypes($srch->{'srchdomain'}); 5203: my @longtypes; 5204: foreach my $item (@usertypes) { 5205: if (defined($insttypes->{$item})) { 5206: push (@longtypes,$insttypes->{$item}); 5207: } elsif ($item eq 'default') { 5208: push (@longtypes,&mt('other')); 5209: } 5210: } 5211: my $insttype_str = join(', ',@longtypes); 5212: return &mt('Institutional directory search in domain: [_1] is not available to your user type: ',$showdom).$insttype_str; 5213: } 5214: } else { 5215: $can_search = 1; 5216: } 5217: } else { 5218: return &mt('Institutional directory search has not been configured for domain: [_1]',$showdom); 5219: } 5220: my %longtext = &Apache::lonlocal::texthash ( 5221: uname => 'username', 5222: lastfirst => 'last name, first name', 5223: lastname => 'last name', 5224: contains => 'contains', 5225: exact => 'as exact match to', 5226: begins => 'begins with', 5227: ); 5228: if ($can_search) { 5229: if (ref($dom_inst_srch{'directorysrch'}{'searchby'}) eq 'ARRAY') { 5230: if (!grep(/^\Q$srch->{'srchby'}\E$/,@{$dom_inst_srch{'directorysrch'}{'searchby'}})) { 5231: return &mt('Institutional directory search in domain: [_1] is not available for searching by "[_2]"',$showdom,$longtext{$srch->{'srchby'}}); 5232: } 5233: } else { 5234: return &mt('Institutional directory search in domain: [_1] is not available.', $showdom); 5235: } 5236: } 5237: if ($can_search) { 5238: if (ref($dom_inst_srch{'directorysrch'}{'searchtypes'}) eq 'ARRAY') { 5239: if (grep(/^\Q$srch->{'srchtype'}\E/,@{$dom_inst_srch{'directorysrch'}{'searchtypes'}})) { 5240: return 'ok'; 5241: } else { 5242: return &mt('Institutional directory search in domain [_1] is not available for the requested search type: "[_2]"',$showdom,$longtext{$srch->{'srchtype'}}); 5243: } 5244: } else { 5245: if ((($dom_inst_srch{'directorysrch'}{'searchtypes'} eq 'specify') && 5246: ($srch->{'srchtype'} eq 'exact' || $srch->{'srchtype'} eq 'contains')) || 5247: ($dom_inst_srch{'directorysrch'}{'searchtypes'} eq $srch->{'srchtype'})) { 5248: return 'ok'; 5249: } else { 5250: return &mt('Institutional directory search in domain [_1] is not available for the requested search type: "[_2]"',$showdom,$longtext{$srch->{'srchtype'}}); 5251: } 5252: } 5253: } 5254: } 5255: 5256: sub get_courseusers { 5257: my %advhash; 5258: my $classlist = &Apache::loncoursedata::get_classlist(); 5259: my %coursepersonnel=&Apache::lonnet::get_course_adv_roles(); 5260: foreach my $role (sort(keys(%coursepersonnel))) { 5261: foreach my $user (split(/\,/,$coursepersonnel{$role})) { 5262: if (!exists($classlist->{$user})) { 5263: $classlist->{$user} = []; 5264: } 5265: } 5266: } 5267: return $classlist; 5268: } 5269: 5270: sub build_search_response { 5271: my ($context,$srch,%srch_results) = @_; 5272: my ($currstate,$response,$forcenewuser); 5273: my %names = ( 5274: 'uname' => 'username', 5275: 'lastname' => 'last name', 5276: 'lastfirst' => 'last name, first name', 5277: 'crs' => 'this course', 5278: 'dom' => 'LON-CAPA domain: ', 5279: 'instd' => 'the institutional directory for domain: ', 5280: ); 5281: 5282: my %single = ( 5283: begins => 'A match', 5284: contains => 'A match', 5285: exact => 'An exact match', 5286: ); 5287: my %nomatch = ( 5288: begins => 'No match', 5289: contains => 'No match', 5290: exact => 'No exact match', 5291: ); 5292: if (keys(%srch_results) > 1) { 5293: $currstate = 'select'; 5294: } else { 5295: if (keys(%srch_results) == 1) { 5296: $currstate = 'modify'; 5297: $response = &mt("$single{$srch->{'srchtype'}} was found for the $names{$srch->{'srchby'}} ([_1]) in $names{$srch->{'srchin'}}.",$srch->{'srchterm'}); 5298: if ($srch->{'srchin'} eq 'dom' || $srch->{'srchin'} eq 'instd') { 5299: $response .= &display_domain_info($srch->{'srchdomain'}); 5300: } 5301: } else { 5302: $response = '<span class="LC_warning">'.&mt("$nomatch{$srch->{'srchtype'}} found for the $names{$srch->{'srchby'}} ([_1]) in $names{$srch->{'srchin'}}",$srch->{'srchterm'}); 5303: if ($srch->{'srchin'} eq 'dom' || $srch->{'srchin'} eq 'instd') { 5304: $response .= &display_domain_info($srch->{'srchdomain'}); 5305: } 5306: $response .= '</span>'; 5307: if ($srch->{'srchin'} ne 'alc') { 5308: $forcenewuser = 1; 5309: my $cansrchinst = 0; 5310: if ($srch->{'srchdomain'}) { 5311: my %domconfig = &Apache::lonnet::get_dom('configuration',['directorysrch'],$srch->{'srchdomain'}); 5312: if (ref($domconfig{'directorysrch'}) eq 'HASH') { 5313: if ($domconfig{'directorysrch'}{'available'}) { 5314: $cansrchinst = 1; 5315: } 5316: } 5317: } 5318: if ((($srch->{'srchby'} eq 'lastfirst') || 5319: ($srch->{'srchby'} eq 'lastname')) && 5320: ($srch->{'srchin'} eq 'dom')) { 5321: if ($cansrchinst) { 5322: $response .= '<br />'.&mt('You may want to broaden your search to a search of the institutional directory for the domain.'); 5323: } 5324: } 5325: if ($srch->{'srchin'} eq 'crs') { 5326: $response .= '<br />'.&mt('You may want to broaden your search to the selected LON-CAPA domain.'); 5327: } 5328: } 5329: if (!($srch->{'srchby'} eq 'uname' && $srch->{'srchin'} eq 'dom' && $srch->{'srchtype'} eq 'exact' && $srch->{'srchdomain'} eq $env{'request.role.domain'})) { 5330: my $cancreate = 5331: &Apache::lonuserutils::can_create_user($env{'request.role.domain'},$context); 5332: if ($cancreate) { 5333: my $showdom = &display_domain_info($env{'request.role.domain'}); 5334: $response .= '<br /><br />' 5335: .'<b>'.&mt('To add a new user:').'</b>' 5336: .'<br />' 5337: .&mt("(You can only create new users in your current role's domain - [_1])" 5338: ,'<span class="LC_cusr_emph">'.$env{'request.role.domain'}.'</span>') 5339: .'<ul><li>' 5340: .&mt("Set 'Domain/institution to search' to: [_1]",'<span class="LC_cusr_emph">'.$showdom.'</span>') 5341: .'</li><li>' 5342: .&mt("Set 'Search criteria' to: [_1]username is ..... in selected LON-CAPA domain[_2]",'<span class="LC_cusr_emph">','</span>') 5343: .'</li><li>' 5344: .&mt('Provide the proposed username') 5345: .'</li><li>' 5346: .&mt("Click 'Search'") 5347: .'</li></ul><br />'; 5348: } else { 5349: my $helplink = ' href="javascript:helpMenu('."'display'".')"'; 5350: $response .= '<br /><br />' 5351: .&mt("You are not authorized to create new users in your current role's domain - [_1]." 5352: ,'<span class="LC_cusr_emph">'.$env{'request.role.domain'}.'</span>') 5353: .'<br />' 5354: .&mt('Please contact the [_1]helpdesk[_2] if you need to create a new user.' 5355: ,' <a'.$helplink.'>' 5356: ,'</a>') 5357: .'<br /><br />'; 5358: } 5359: } 5360: } 5361: } 5362: return ($currstate,$response,$forcenewuser); 5363: } 5364: 5365: sub display_domain_info { 5366: my ($dom) = @_; 5367: my $output = $dom; 5368: if ($dom ne '') { 5369: my $domdesc = &Apache::lonnet::domain($dom,'description'); 5370: if ($domdesc ne '') { 5371: $output .= ' <span class="LC_cusr_emph">('.$domdesc.')</span>'; 5372: } 5373: } 5374: return $output; 5375: } 5376: 5377: sub crumb_utilities { 5378: my %elements = ( 5379: crtuser => { 5380: srchterm => 'text', 5381: srchin => 'selectbox', 5382: srchby => 'selectbox', 5383: srchtype => 'selectbox', 5384: srchdomain => 'selectbox', 5385: }, 5386: crtusername => { 5387: srchterm => 'text', 5388: srchdomain => 'selectbox', 5389: }, 5390: docustom => { 5391: rolename => 'selectbox', 5392: newrolename => 'textbox', 5393: }, 5394: studentform => { 5395: srchterm => 'text', 5396: srchin => 'selectbox', 5397: srchby => 'selectbox', 5398: srchtype => 'selectbox', 5399: srchdomain => 'selectbox', 5400: }, 5401: ); 5402: 5403: my $jsback .= qq| 5404: function backPage(formname,prevphase,prevstate) { 5405: if (typeof prevphase == 'undefined') { 5406: formname.phase.value = ''; 5407: } 5408: else { 5409: formname.phase.value = prevphase; 5410: } 5411: if (typeof prevstate == 'undefined') { 5412: formname.currstate.value = ''; 5413: } 5414: else { 5415: formname.currstate.value = prevstate; 5416: } 5417: formname.submit(); 5418: } 5419: |; 5420: return ($jsback,\%elements); 5421: } 5422: 5423: sub course_level_table { 5424: my (%inccourses) = @_; 5425: my $table = ''; 5426: # Custom Roles? 5427: 5428: my %customroles=&Apache::lonuserutils::my_custom_roles(); 5429: my %lt=&Apache::lonlocal::texthash( 5430: 'exs' => "Existing sections", 5431: 'new' => "Define new section", 5432: 'ssd' => "Set Start Date", 5433: 'sed' => "Set End Date", 5434: 'crl' => "Course Level", 5435: 'act' => "Activate", 5436: 'rol' => "Role", 5437: 'ext' => "Extent", 5438: 'grs' => "Section", 5439: 'sta' => "Start", 5440: 'end' => "End" 5441: ); 5442: 5443: foreach my $protectedcourse (sort( keys(%inccourses))) { 5444: my $thiscourse=$protectedcourse; 5445: $thiscourse=~s:_:/:g; 5446: my %coursedata=&Apache::lonnet::coursedescription($thiscourse); 5447: my $area=$coursedata{'description'}; 5448: my $type=$coursedata{'type'}; 5449: if (!defined($area)) { $area=&mt('Unavailable course').': '.$protectedcourse; } 5450: my ($domain,$cnum)=split(/\//,$thiscourse); 5451: my %sections_count; 5452: if (defined($env{'request.course.id'})) { 5453: if ($env{'request.course.id'} eq $domain.'_'.$cnum) { 5454: %sections_count = 5455: &Apache::loncommon::get_sections($domain,$cnum); 5456: } 5457: } 5458: my @roles = &Apache::lonuserutils::roles_by_context('course'); 5459: foreach my $role (@roles) { 5460: my $plrole=&Apache::lonnet::plaintext($role); 5461: if (&Apache::lonnet::allowed('c'.$role,$thiscourse)) { 5462: $table .= &course_level_row($protectedcourse,$role,$area,$domain, 5463: $plrole,\%sections_count,\%lt); 5464: } elsif ($env{'request.course.sec'} ne '') { 5465: if (&Apache::lonnet::allowed('c'.$role,$thiscourse.'/'. 5466: $env{'request.course.sec'})) { 5467: $table .= &course_level_row($protectedcourse,$role,$area,$domain, 5468: $plrole,\%sections_count,\%lt); 5469: } 5470: } 5471: } 5472: if (&Apache::lonnet::allowed('ccr',$thiscourse)) { 5473: foreach my $cust (sort keys %customroles) { 5474: my $role = 'cr_cr_'.$env{'user.domain'}.'_'.$env{'user.name'}.'_'.$cust; 5475: $table .= &course_level_row($protectedcourse,$role,$area,$domain, 5476: $cust,\%sections_count,\%lt); 5477: } 5478: } 5479: } 5480: return '' if ($table eq ''); # return nothing if there is nothing 5481: # in the table 5482: my $result; 5483: if (!$env{'request.course.id'}) { 5484: $result = '<h4>'.$lt{'crl'}.'</h4>'."\n"; 5485: } 5486: $result .= 5487: &Apache::loncommon::start_data_table(). 5488: &Apache::loncommon::start_data_table_header_row(). 5489: '<th>'.$lt{'act'}.'</th><th>'.$lt{'rol'}.'</th><th>'.$lt{'ext'}.'</th> 5490: <th>'.$lt{'grs'}.'</th><th>'.$lt{'sta'}.'</th><th>'.$lt{'end'}.'</th>'. 5491: &Apache::loncommon::end_data_table_header_row(). 5492: $table. 5493: &Apache::loncommon::end_data_table(); 5494: return $result; 5495: } 5496: 5497: sub course_level_row { 5498: my ($protectedcourse,$role,$area,$domain,$plrole,$sections_count,$lt) = @_; 5499: my $row = &Apache::loncommon::start_data_table_row(). 5500: ' <td><input type="checkbox" name="act_'. 5501: $protectedcourse.'_'.$role.'" /></td>'."\n". 5502: ' <td>'.$plrole.'</td>'."\n". 5503: ' <td>'.$area.'<br />Domain: '.$domain.'</td>'."\n"; 5504: if ($role eq 'cc') { 5505: $row .= '<td> </td>'; 5506: } elsif ($env{'request.course.sec'} ne '') { 5507: $row .= ' <td><input type="hidden" value="'. 5508: $env{'request.course.sec'}.'" '. 5509: 'name="sec_'.$protectedcourse.'_'.$role.'" />'. 5510: $env{'request.course.sec'}.'</td>'; 5511: } else { 5512: if (ref($sections_count) eq 'HASH') { 5513: my $currsec = 5514: &Apache::lonuserutils::course_sections($sections_count, 5515: $protectedcourse.'_'.$role); 5516: $row .= '<td><table class="LC_createuser">'."\n". 5517: '<tr class="LC_section_row">'."\n". 5518: ' <td valign="top">'.$lt->{'exs'}.'<br />'. 5519: $currsec.'</td>'."\n". 5520: ' <td> </td>'."\n". 5521: ' <td valign="top"> '.$lt->{'new'}.'<br />'. 5522: '<input type="text" name="newsec_'.$protectedcourse.'_'.$role. 5523: '" value="" />'. 5524: '<input type="hidden" '. 5525: 'name="sec_'.$protectedcourse.'_'.$role.'" /></td>'."\n". 5526: '</tr></table></td>'."\n"; 5527: } else { 5528: $row .= '<td><input type="text" size="10" '. 5529: 'name="sec_'.$protectedcourse.'_'.$role.'" /></td>'."\n"; 5530: } 5531: } 5532: $row .= <<ENDTIMEENTRY; 5533: <td><input type="hidden" name="start_$protectedcourse\_$role" value="" /> 5534: <a href= 5535: "javascript:pjump('date_start','Start Date $plrole',document.cu.start_$protectedcourse\_$role.value,'start_$protectedcourse\_$role','cu.pres','dateset')">$lt->{'ssd'}</a></td> 5536: <td><input type="hidden" name="end_$protectedcourse\_$role" value="" /> 5537: <a href= 5538: "javascript:pjump('date_end','End Date $plrole',document.cu.end_$protectedcourse\_$role.value,'end_$protectedcourse\_$role','cu.pres','dateset')">$lt->{'sed'}</a></td> 5539: ENDTIMEENTRY 5540: $row .= &Apache::loncommon::end_data_table_row(); 5541: return $row; 5542: } 5543: 5544: sub course_level_dc { 5545: my ($dcdom) = @_; 5546: my %customroles=&Apache::lonuserutils::my_custom_roles(); 5547: my @roles = &Apache::lonuserutils::roles_by_context('course'); 5548: my $hiddenitems = '<input type="hidden" name="dcdomain" value="'.$dcdom.'" />'. 5549: '<input type="hidden" name="origdom" value="'.$dcdom.'" />'. 5550: '<input type="hidden" name="dccourse" value="" />'; 5551: my $courseform='<b>'.&Apache::loncommon::selectcourse_link 5552: ('cu','dccourse','dcdomain','coursedesc',undef,undef,'Course').'</b>'; 5553: my $cb_jscript = &Apache::loncommon::coursebrowser_javascript($dcdom,'currsec','cu'); 5554: my %lt=&Apache::lonlocal::texthash( 5555: 'rol' => "Role", 5556: 'grs' => "Section", 5557: 'exs' => "Existing sections", 5558: 'new' => "Define new section", 5559: 'sta' => "Start", 5560: 'end' => "End", 5561: 'ssd' => "Set Start Date", 5562: 'sed' => "Set End Date" 5563: ); 5564: my $header = '<h4>'.&mt('Course Level').'</h4>'. 5565: &Apache::loncommon::start_data_table(). 5566: &Apache::loncommon::start_data_table_header_row(). 5567: '<th>'.$courseform.'</th><th>'.$lt{'rol'}.'</th><th>'.$lt{'grs'}.'</th><th>'.$lt{'sta'}.'</th><th>'.$lt{'end'}.'</th>'. 5568: &Apache::loncommon::end_data_table_header_row(); 5569: my $otheritems = &Apache::loncommon::start_data_table_row()."\n". 5570: '<td><input type="text" name="coursedesc" value="" onFocus="this.blur();opencrsbrowser('."'cu','dccourse','dcdomain','coursedesc',''".')" /></td>'."\n". 5571: '<td><select name="role">'."\n"; 5572: foreach my $role (@roles) { 5573: my $plrole=&Apache::lonnet::plaintext($role); 5574: $otheritems .= ' <option value="'.$role.'">'.$plrole; 5575: } 5576: if ( keys %customroles > 0) { 5577: foreach my $cust (sort keys %customroles) { 5578: my $custrole='cr_cr_'.$env{'user.domain'}. 5579: '_'.$env{'user.name'}.'_'.$cust; 5580: $otheritems .= ' <option value="'.$custrole.'">'.$cust; 5581: } 5582: } 5583: $otheritems .= '</select></td><td>'. 5584: '<table border="0" cellspacing="0" cellpadding="0">'. 5585: '<tr><td valign="top"><b>'.$lt{'exs'}.'</b><br /><select name="currsec">'. 5586: ' <option value=""><--'.&mt('Pick course first').'</select></td>'. 5587: '<td> </td>'. 5588: '<td valign="top"> <b>'.$lt{'new'}.'</b><br />'. 5589: '<input type="text" name="newsec" value="" />'. 5590: '<input type="hidden" name="section" value="" />'. 5591: '<input type="hidden" name="groups" value="" /></td>'. 5592: '</tr></table></td>'; 5593: $otheritems .= <<ENDTIMEENTRY; 5594: <td><input type="hidden" name="start" value='' /> 5595: <a href= 5596: "javascript:pjump('date_start','Start Date',document.cu.start.value,'start','cu.pres','dateset')">$lt{'ssd'}</a></td> 5597: <td><input type="hidden" name="end" value='' /> 5598: <a href= 5599: "javascript:pjump('date_end','End Date',document.cu.end.value,'end','cu.pres','dateset')">$lt{'sed'}</a></td> 5600: ENDTIMEENTRY 5601: $otheritems .= &Apache::loncommon::end_data_table_row(). 5602: &Apache::loncommon::end_data_table()."\n"; 5603: return $cb_jscript.$header.$hiddenitems.$otheritems; 5604: } 5605: 5606: sub update_selfenroll_config { 5607: my ($r,$context,$permission) = @_; 5608: my ($row,$lt) = &get_selfenroll_titles(); 5609: my %curr_groups = &Apache::longroup::coursegroups(); 5610: my (%changes,%warning); 5611: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; 5612: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; 5613: my $curr_types; 5614: if (ref($row) eq 'ARRAY') { 5615: foreach my $item (@{$row}) { 5616: if ($item eq 'enroll_dates') { 5617: my (%currenrolldate,%newenrolldate); 5618: foreach my $type ('start','end') { 5619: $currenrolldate{$type} = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_'.$type.'_date'}; 5620: $newenrolldate{$type} = &Apache::lonhtmlcommon::get_date_from_form('selfenroll_'.$type.'_date'); 5621: if ($newenrolldate{$type} ne $currenrolldate{$type}) { 5622: $changes{'internal.selfenroll_'.$type.'_date'} = $newenrolldate{$type}; 5623: } 5624: } 5625: } elsif ($item eq 'access_dates') { 5626: my (%currdate,%newdate); 5627: foreach my $type ('start','end') { 5628: $currdate{$type} = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_'.$type.'_access'}; 5629: $newdate{$type} = &Apache::lonhtmlcommon::get_date_from_form('selfenroll_'.$type.'_access'); 5630: if ($newdate{$type} ne $currdate{$type}) { 5631: $changes{'internal.selfenroll_'.$type.'_access'} = $newdate{$type}; 5632: } 5633: } 5634: } elsif ($item eq 'types') { 5635: $curr_types = 5636: $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_'.$item}; 5637: if ($env{'form.selfenroll_all'}) { 5638: if ($curr_types ne '*') { 5639: $changes{'internal.selfenroll_types'} = '*'; 5640: } else { 5641: next; 5642: } 5643: } else { 5644: my %currdoms; 5645: my @entries = split(/;/,$curr_types); 5646: my @deletedoms = &Apache::loncommon::get_env_multiple('form.selfenroll_delete'); 5647: my @activations = &Apache::loncommon::get_env_multiple('form.selfenroll_activate'); 5648: my $newnum = 0; 5649: my @latesttypes; 5650: foreach my $num (@activations) { 5651: my @types = &Apache::loncommon::get_env_multiple('form.selfenroll_types_'.$num); 5652: if (@types > 0) { 5653: @types = sort(@types); 5654: my $typestr = join(',',@types); 5655: my $typedom = $env{'form.selfenroll_dom_'.$num}; 5656: $latesttypes[$newnum] = $typedom.':'.$typestr; 5657: $currdoms{$typedom} = 1; 5658: $newnum ++; 5659: } 5660: } 5661: for (my $j=0; $j<$env{'form.selfenroll_types_total'}; $j++) { if ((!grep(/^$j$/,@deletedoms)) && (!grep(/^$j$/,@activations))) { 5662: my @types = &Apache::loncommon::get_env_multiple('form.selfenroll_types_'.$j); 5663: if (@types > 0) { 5664: @types = sort(@types); 5665: my $typestr = join(',',@types); 5666: my $typedom = $env{'form.selfenroll_dom_'.$j}; 5667: $latesttypes[$newnum] = $typedom.':'.$typestr; 5668: $currdoms{$typedom} = 1; 5669: $newnum ++; 5670: } 5671: } 5672: } 5673: if ($env{'form.selfenroll_newdom'} ne '') { 5674: my $typedom = $env{'form.selfenroll_newdom'}; 5675: if ((!defined($currdoms{$typedom})) && 5676: (&Apache::lonnet::domain($typedom) ne '')) { 5677: my $typestr; 5678: my ($othertitle,$usertypes,$types) = 5679: &Apache::loncommon::sorted_inst_types($typedom); 5680: my $othervalue = 'any'; 5681: if ((ref($types) eq 'ARRAY') && (ref($usertypes) eq 'HASH')) { 5682: if (@{$types} > 0) { 5683: my @esc_types = map { &escape($_); } @{$types}; 5684: $othervalue = 'other'; 5685: $typestr = join(',',(@esc_types,$othervalue)); 5686: } 5687: $typestr = $othervalue; 5688: } else { 5689: $typestr = $othervalue; 5690: } 5691: $latesttypes[$newnum] = $typedom.':'.$typestr; 5692: $newnum ++ ; 5693: } 5694: } 5695: my $selfenroll_types = join(';',@latesttypes); 5696: if ($selfenroll_types ne $curr_types) { 5697: $changes{'internal.selfenroll_types'} = $selfenroll_types; 5698: } 5699: } 5700: } elsif ($item eq 'limit') { 5701: my $newlimit = $env{'form.selfenroll_limit'}; 5702: my $newcap = $env{'form.selfenroll_cap'}; 5703: $newcap =~s/\s+//g; 5704: my $currlimit = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_limit'}; 5705: $currlimit = 'none' if ($currlimit eq ''); 5706: my $currcap = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_cap'}; 5707: if ($newlimit ne $currlimit) { 5708: if ($newlimit ne 'none') { 5709: if ($newcap =~ /^\d+$/) { 5710: if ($newcap ne $currcap) { 5711: $changes{'internal.selfenroll_cap'} = $newcap; 5712: } 5713: $changes{'internal.selfenroll_limit'} = $newlimit; 5714: } else { 5715: $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.'); 5716: } 5717: } elsif ($currcap ne '') { 5718: $changes{'internal.selfenroll_cap'} = ''; 5719: $changes{'internal.selfenroll_limit'} = $newlimit; 5720: } 5721: } elsif ($currlimit ne 'none') { 5722: if ($newcap =~ /^\d+$/) { 5723: if ($newcap ne $currcap) { 5724: $changes{'internal.selfenroll_cap'} = $newcap; 5725: } 5726: } else { 5727: $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.'); 5728: } 5729: } 5730: } elsif ($item eq 'approval') { 5731: my (@currnotified,@newnotified); 5732: my $currapproval = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_approval'}; 5733: my $currnotifylist = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_notifylist'}; 5734: if ($currnotifylist ne '') { 5735: @currnotified = split(/,/,$currnotifylist); 5736: @currnotified = sort(@currnotified); 5737: } 5738: my $newapproval = $env{'form.selfenroll_approval'}; 5739: @newnotified = &Apache::loncommon::get_env_multiple('form.selfenroll_notify'); 5740: @newnotified = sort(@newnotified); 5741: if ($newapproval ne $currapproval) { 5742: $changes{'internal.selfenroll_approval'} = $newapproval; 5743: if (!$newapproval) { 5744: if ($currnotifylist ne '') { 5745: $changes{'internal.selfenroll_notifylist'} = ''; 5746: } 5747: } else { 5748: my @differences = 5749: &Apache::loncommon::compare_arrays(\@currnotified,\@newnotified); 5750: if (@differences > 0) { 5751: if (@newnotified > 0) { 5752: $changes{'internal.selfenroll_notifylist'} = join(',',@newnotified); 5753: } else { 5754: $changes{'internal.selfenroll_notifylist'} = join(',',@newnotified); 5755: } 5756: } 5757: } 5758: } else { 5759: my @differences = &Apache::loncommon::compare_arrays(\@currnotified,\@newnotified); 5760: if (@differences > 0) { 5761: if (@newnotified > 0) { 5762: $changes{'internal.selfenroll_notifylist'} = join(',',@newnotified); 5763: } else { 5764: $changes{'internal.selfenroll_notifylist'} = ''; 5765: } 5766: } 5767: } 5768: } else { 5769: my $curr_val = 5770: $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_'.$item}; 5771: my $newval = $env{'form.selfenroll_'.$item}; 5772: if ($item eq 'section') { 5773: $newval = $env{'form.sections'}; 5774: if (defined($curr_groups{$newval})) { 5775: $newval = $curr_val; 5776: $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'); 5777: } elsif ($newval eq 'all') { 5778: $newval = $curr_val; 5779: $warning{$item} = &mt('Section for self-enrolled users unchanged, as "all" is a reserved section name.'); 5780: } 5781: if ($newval eq '') { 5782: $newval = 'none'; 5783: } 5784: } 5785: if ($newval ne $curr_val) { 5786: $changes{'internal.selfenroll_'.$item} = $newval; 5787: } 5788: } 5789: } 5790: if (keys(%warning) > 0) { 5791: foreach my $item (@{$row}) { 5792: if (exists($warning{$item})) { 5793: $r->print($warning{$item}.'<br />'); 5794: } 5795: } 5796: } 5797: if (keys(%changes) > 0) { 5798: my $putresult = &Apache::lonnet::put('environment',\%changes,$cdom,$cnum); 5799: if ($putresult eq 'ok') { 5800: if ((exists($changes{'internal.selfenroll_types'})) || 5801: (exists($changes{'internal.selfenroll_start_date'})) || 5802: (exists($changes{'internal.selfenroll_end_date'}))) { 5803: my %crsinfo = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.', 5804: $cnum,undef,undef,'Course'); 5805: my $chome = &Apache::lonnet::homeserver($cnum,$cdom); 5806: if (ref($crsinfo{$env{'request.course.id'}}) eq 'HASH') { 5807: foreach my $item ('selfenroll_types','selfenroll_start_date','selfenroll_end_date') { 5808: if (exists($changes{'internal.'.$item})) { 5809: $crsinfo{$env{'request.course.id'}}{$item} = 5810: $changes{'internal.'.$item}; 5811: } 5812: } 5813: my $crsputresult = 5814: &Apache::lonnet::courseidput($cdom,\%crsinfo, 5815: $chome,'notime'); 5816: } 5817: } 5818: $r->print(&mt('The following changes were made to self-enrollment settings:').'<ul>'); 5819: foreach my $item (@{$row}) { 5820: my $title = $item; 5821: if (ref($lt) eq 'HASH') { 5822: $title = $lt->{$item}; 5823: } 5824: if ($item eq 'enroll_dates') { 5825: foreach my $type ('start','end') { 5826: if (exists($changes{'internal.selfenroll_'.$type.'_date'})) { 5827: my $newdate = &Apache::lonlocal::locallocaltime($changes{'internal.selfenroll_'.$type.'_date'}); 5828: $r->print('<li>'.&mt('[_1]: "[_2]" set to "[_3]".', 5829: $title,$type,$newdate).'</li>'); 5830: } 5831: } 5832: } elsif ($item eq 'access_dates') { 5833: foreach my $type ('start','end') { 5834: if (exists($changes{'internal.selfenroll_'.$type.'_access'})) { 5835: my $newdate = &Apache::lonlocal::locallocaltime($changes{'internal.selfenroll_'.$type.'_access'}); 5836: $r->print('<li>'.&mt('[_1]: "[_2]" set to "[_3]".', 5837: $title,$type,$newdate).'</li>'); 5838: } 5839: } 5840: } elsif ($item eq 'limit') { 5841: if ((exists($changes{'internal.selfenroll_limit'})) || 5842: (exists($changes{'internal.selfenroll_cap'}))) { 5843: my ($newval,$newcap); 5844: if ($changes{'internal.selfenroll_cap'} ne '') { 5845: $newcap = $changes{'internal.selfenroll_cap'} 5846: } else { 5847: $newcap = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_cap'}; 5848: } 5849: if ($changes{'internal.selfenroll_limit'} eq 'none') { 5850: $newval = &mt('No limit'); 5851: } elsif ($changes{'internal.selfenroll_limit'} eq 5852: 'allstudents') { 5853: $newval = &mt('New self-enrollment no longer allowed when total (all students) reaches [_1].',$newcap); 5854: } elsif ($changes{'internal.selfenroll_limit'} eq 'selfenrolled') { 5855: $newval = &mt('New self-enrollment no longer allowed when total number of self-enrolled students reaches [_1].',$newcap); 5856: } else { 5857: my $currlimit = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_limit'}; 5858: if ($currlimit eq 'allstudents') { 5859: $newval = &mt('New self-enrollment no longer allowed when total (all students) reaches [_1].',$newcap); 5860: } elsif ($changes{'internal.selfenroll_limit'} eq 'selfenrolled') { 5861: $newval = &mt('New self-enrollment no longer allowed when total umber of self-enrolled students reaches [_1].',$newcap); 5862: } 5863: } 5864: $r->print('<li>'.&mt('"[_1]" set to "[_2]".',$title,$newval).'</li>'."\n"); 5865: } 5866: } elsif ($item eq 'approval') { 5867: if ((exists($changes{'internal.selfenroll_approval'})) || 5868: (exists($changes{'internal.selfenroll_notifylist'}))) { 5869: my ($newval,$newnotify); 5870: if (exists($changes{'internal.selfenroll_notifylist'})) { 5871: $newnotify = $changes{'internal.selfenroll_notifylist'}; 5872: } else { 5873: $newnotify = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_notifylist'}; 5874: } 5875: if ($changes{'internal.selfenroll_approval'}) { 5876: $newval = &mt('Yes'); 5877: } elsif ($changes{'internal.selfenroll_approval'} eq '0') { 5878: $newval = &mt('No'); 5879: } else { 5880: my $currapproval = 5881: $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_approval'}; 5882: if ($currapproval) { 5883: $newval = &mt('Yes'); 5884: } else { 5885: $newval = &mt('No'); 5886: } 5887: } 5888: $r->print('<li>'.&mt('"[_1]" set to "[_2]".',$title,$newval)); 5889: if ($newnotify) { 5890: $r->print('<br />'.&mt('The following will be notified when an enrollment request needs approval, or has been approved: [_1].',$newnotify)); 5891: } else { 5892: $r->print('<br />'.&mt('No notifications sent when an enrollment request needs approval, or has been approved.')); 5893: } 5894: $r->print('</li>'."\n"); 5895: } 5896: } else { 5897: if (exists($changes{'internal.selfenroll_'.$item})) { 5898: my $newval = $changes{'internal.selfenroll_'.$item}; 5899: if ($item eq 'types') { 5900: if ($newval eq '') { 5901: $newval = &mt('None'); 5902: } elsif ($newval eq '*') { 5903: $newval = &mt('Any user in any domain'); 5904: } 5905: } elsif ($item eq 'registered') { 5906: if ($newval eq '1') { 5907: $newval = &mt('Yes'); 5908: } elsif ($newval eq '0') { 5909: $newval = &mt('No'); 5910: } 5911: } 5912: $r->print('<li>'.&mt('"[_1]" set to "[_2]".',$title,$newval).'</li>'."\n"); 5913: } 5914: } 5915: } 5916: $r->print('</ul>'); 5917: my %newenvhash; 5918: foreach my $key (keys(%changes)) { 5919: $newenvhash{'course.'.$env{'request.course.id'}.'.'.$key} = $changes{$key}; 5920: } 5921: &Apache::lonnet::appenv(\%newenvhash); 5922: } else { 5923: $r->print(&mt('An error occurred when saving changes to self-enrollment settings in this course.').'<br />'.&mt('The error was: [_1].',$putresult)); 5924: } 5925: } else { 5926: $r->print(&mt('No changes were made to the existing self-enrollment settings in this course.')); 5927: } 5928: } else { 5929: $r->print(&mt('No changes were made to the existing self-enrollment settings in this course.')); 5930: } 5931: my ($visible,$cansetvis,$vismsgs,$visactions) = &visible_in_cat($cdom,$cnum); 5932: if (ref($visactions) eq 'HASH') { 5933: if (!$visible) { 5934: $r->print('<br />'.$visactions->{'miss'}.'<br />'.$visactions->{'yous'}. 5935: '<br />'); 5936: if (ref($vismsgs) eq 'ARRAY') { 5937: $r->print('<br />'.$visactions->{'take'}.'<ul>'); 5938: foreach my $item (@{$vismsgs}) { 5939: $r->print('<li>'.$visactions->{$item}.'</li>'); 5940: } 5941: $r->print('</ul>'); 5942: } 5943: $r->print($cansetvis); 5944: } 5945: } 5946: return; 5947: } 5948: 5949: sub get_selfenroll_titles { 5950: my @row = ('types','registered','enroll_dates','access_dates','section', 5951: 'approval','limit'); 5952: my %lt = &Apache::lonlocal::texthash ( 5953: types => 'Users allowed to self-enroll in this course', 5954: registered => 'Restrict self-enrollment to students officially registered for the course', 5955: enroll_dates => 'Dates self-enrollment available', 5956: access_dates => 'Course access dates assigned to self-enrolling users', 5957: section => 'Section assigned to self-enrolling users', 5958: approval => 'Self-enrollment requests need approval?', 5959: limit => 'Enrollment limit', 5960: ); 5961: return (\@row,\%lt); 5962: } 5963: 5964: #---------------------------------------------- end functions for &phase_two 5965: 5966: #--------------------------------- functions for &phase_two and &phase_three 5967: 5968: #--------------------------end of functions for &phase_two and &phase_three 5969: 5970: 1; 5971: __END__ 5972: 5973: