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