--- loncom/interface/lonrequestcourse.pm 2009/09/05 20:24:15 1.28 +++ loncom/interface/lonrequestcourse.pm 2009/09/08 13:05:00 1.31 @@ -1,7 +1,7 @@ # The LearningOnline Network # Request a course # -# $Id: lonrequestcourse.pm,v 1.28 2009/09/05 20:24:15 raeburn Exp $ +# $Id: lonrequestcourse.pm,v 1.31 2009/09/08 13:05:00 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -122,6 +122,7 @@ use Apache::lonnet; use Apache::loncommon; use Apache::lonlocal; use Apache::loncoursequeueadmin; +use Apache::lonuserutils; use LONCAPA qw(:DEFAULT :match); sub handler { @@ -262,7 +263,11 @@ sub handler { if (($state eq 'courseinfo') && ($env{'form.clonedom'} eq '')) { $env{'form.clonedom'} = $dom; } - $jscript = &Apache::lonhtmlcommon::set_form_elements($elementsref,\%stored); + if ($state eq 'crstype') { + $jscript = &mainmenu_javascript(); + } else { + $jscript = &Apache::lonhtmlcommon::set_form_elements($elementsref,\%stored); + } } if ($state eq 'personnel') { @@ -291,7 +296,7 @@ sub handler { } } elsif ($action eq 'view') { if ($state eq 'crstype') { - &print_main_menu($r,\%can_request,\%states,$dom,$jscript,'',$crumb); + &print_main_menu($r,\%can_request,\%states,$dom,$jscript,$loaditems,$crumb); } else { &request_administration($r,$action,$state,$page,\%states,$dom,$jscript, $loaditems,$crumb); @@ -315,6 +320,30 @@ sub handler { return OK; } +sub mainmenu_javascript { + return <<"END"; +function setType(courseForm) { + for (var i=0; i<courseForm.crstype.length; i++) { + if (courseForm.crstype.options[i].value == "$env{'form.crstype'}") { + courseForm.crstype.options[i].selected = true; + } else { + courseForm.crstype.options[i].selected = false; + } + } +} + +function setAction(courseForm) { + for (var i=0; i<courseForm.action.length; i++) { + if (courseForm.action.options[i].value == "$env{'form.action'}") { + courseForm.action.options[i].selected = true; + } else { + courseForm.action.options[i].selected = false; + } + } +} +END +} + sub get_breadcrumbs { my ($dom,$action,$state,$states,$trail) = @_; my ($crumb,$newinstcode,$codechk,$checkedcode,$numtitles); @@ -498,9 +527,9 @@ sub form_elements { ); if ($env{'form.sectotal'} > 0) { for (my $i=0; $i<$env{'form.sectotal'}; $i++) { - $extras{'sec_'.$i} = 'checkbox', - $extras{'secnum_'.$i} = 'text', - $extras{'loncapasec_'.$i} = 'text', + $extras{'sec_'.$i} = 'radio'; + $extras{'secnum_'.$i} = 'text'; + $extras{'loncapasec_'.$i} = 'text'; } } my $crosslisttotal = $env{'form.crosslisttotal'}; @@ -555,7 +584,11 @@ sub onload_action { my ($action,$state) = @_; my %loaditems; if (($action eq 'new') || ($action eq 'view')) { - $loaditems{'onload'} = 'javascript:setFormElements(document.requestcrs)'; + if ($state eq 'crstype') { + $loaditems{'onload'} = 'javascript:setAction(document.mainmenu_action);javascript:setType(document.mainmenu_coursetype)'; + } else { + $loaditems{'onload'} = 'javascript:setFormElements(document.requestcrs)'; + } } return \%loaditems; } @@ -767,8 +800,15 @@ END } if ($action eq 'new') { my $jsextra; - unless (($state eq 'review') || ($state eq 'process')) { + if ($state eq 'courseinfo') { $jsextra = "\n".&Apache::loncommon::coursebrowser_javascript($dom); + } elsif ($state eq 'enrollment') { + if (($env{'form.crstype'} eq 'official') && + (&Apache::lonnet::auto_run('',$dom))) { + $js .= "\n".§ion_check_javascript()."\n".&enrollment_lcsec_js(); + } + } elsif ($state eq 'personnel') { + $js .= "\n".§ion_check_javascript()."\n".&personnel_lcsec_js(); } $r->print(&header('Request a course',$js.$jscript,$loaditems,$jsextra).$crumb); &print_request_form($r,$action,$state,$page,$states,$dom,$newinstcode, @@ -792,7 +832,7 @@ END my $form = '<form method="post" name="'.$formname.'" action="/adm/requestcourse" />'; if ($state eq 'pick_request') { $r->print('<h3>'.&mt('Pending course requests').'</h3><div>'."\n".$form."\n". - &print_request_status($dom).'</form>'); + &print_request_status($dom).'</form></div>'); } elsif ($state eq 'details') { my (@codetitles,%cat_titles,%cat_order,@code_order,$instcode,$code_chk); my $origcnum = $env{'form.cnum'}; @@ -816,8 +856,8 @@ END other => 'Modify Request', next => 'Cancel Request', ); - &display_navbuttons($r,$formname,$prev,$navtxt{'prev'},$next,$navtxt{'next'}, - $state,$other,$navtxt{'other'}); + &display_navbuttons($r,$dom,$formname,$prev,$navtxt{'prev'},$next, + $navtxt{'next'},$state,$other,$navtxt{'other'}); $r->print('</form>'); } elsif ($state eq 'cancel') { my ($result,$output) = &print_cancel_request($dom,$env{'form.origcnum'}); @@ -830,10 +870,11 @@ END next => 'Confirm Cancellation', ); if ($result eq 'ok') { - &display_navbuttons($r,$formname,$prev,$navtxt{'prev'},$next, + &display_navbuttons($r,$dom,$formname,$prev,$navtxt{'prev'},$next, $navtxt{'next'},$state); } else { - &display_navbuttons($r,$formname,$prev,$navtxt{'prev'},undef,'',$state); + &display_navbuttons($r,$dom,$formname,$prev,$navtxt{'prev'},undef, + '',$state); } $r->print('</form>'); } elsif ($state eq 'removal') { @@ -896,6 +937,166 @@ END return; } +sub enrollment_lcsec_js { + my %alerts = §ion_check_alerts(); + my $secname = $alerts{'badsec'}; + my $secnone = $alerts{'reserved'}; + my $output = ' +function validateEnrollSections(formname,nextstate) { + var badsectotal = 0; + var reservedtotal = 0; + var secTest = ""; +'; + for (my $i=0; $i<$env{'form.sectotal'}; $i++) { + $output .= " + var selSec = 0; + for (var j=0; j<document.requestcrs.sec_".$i.".length; j++) { + if (document.requestcrs.sec_".$i."[j].checked) { + selSec = document.requestcrs.sec_".$i."[j].value; + } + if (selSec == 1) { + secTest = validsection(document.requestcrs.loncapasec_".$i."); + if (secTest == 'badsec') { + badsectotal++; + } + if (secTest == 'reserved') { + reservedtotal++; + } + } + } +"; + } + for (my $i=0; $i<$env{'form.crosslisttotal'}; $i++) { + $output .= " + if (document.requestcrs.crosslist_".$i.".checked) { + secTest = validsection(document.requestcrs.crosslist_".$i."_lcsec); + if (secTest == 'badsec') { + badsectotal++; + } + if (secTest == 'reserved') { + reservedtotal++; + } + } +"; + } + $output .= " + if (badsectotal>0) { + alert('$secname'); + return false; + } + if (reservedtotal>0) { + alert('$secnone'); + return false; + } + formname.state.value= nextstate; + formname.submit(); + return; +} +"; + return $output; +} + +sub personnel_lcsec_js { + my %alerts = §ion_check_alerts(); + my $secname = $alerts{'badsec'}.'\\n'.$alerts{'separate'}; + my $secnone = $alerts{'reserved'}; + my $output = ' +function validatePersonnelSections(formname,nextstate) { + var badsectotal = 0; + var reservedtotal = 0; + var secTest = ""; +'; + for (my $i=0; $i<$env{'form.persontotal'}; $i++) { + $output .= " + if (document.requestcrs.person_".$i."_uname.value != '') { + secTest = validsection(document.requestcrs.person_".$i."_newsec,'1'); + if (secTest == 'badsec') { + badsectotal++; + } + if (secTest == 'reserved') { + reservedtotal++; + } + } +"; + } + $output .= " + if (badsectotal > 0) { + alert('$secname'); + return false; + } else { + if (reservedtotal > 0) { + alert('$secnone'); + return false; + } + } + formname.state.value = nextstate; + formname.submit(); + return; +} +"; + return $output; +} + +sub section_check_alerts { + my %lt = + &Apache::lonlocal::texthash( + reserved => "You need to change one or more LON-CAPA section names - none is a reserved word in the system, and may not be used.", + badsec => 'You need to change one or more LON-CAPA section names - names may only contain letters or numbers.', + separate => 'Separate multiple sections with a comma.' + ); + return %lt; +} + +sub section_check_javascript { + return <<"END"; +function validsection(field,mult) { + var str = field.value; + var badsec=0; + var reserved=0; + if (window.RegExp) { + var badsecnum=0; + var reservednum=0; + var pattern=/[^a-zA-Z0-9]/; + str = str.replace(/(^\\s*)|(\\s*\$)/gi,""); + str = str.replace(/[ ]{2,}/gi," "); + if (mult == '1') { + var sections = new Array(); + sections = str.split(/\\s*[\\s,;:]\\s*/); + var i; + for (i=0; i<sections.length; i++) { + if ((sections[i] != '') && (sections[i] != undefined) && (sections[i] != null)) { + if (pattern.test(sections[i])) { + badsecnum++; + } else { + if (sections[i] == 'none') { + reservednum++; + } + } + } + } + } else { + if ((str != '') && (str != undefined) && (str != null)) { + if (pattern.test(str)) { + badsecnum++; + } else { + if (str == 'none') { + reservednum++; + } + } + } + } + if (badsecnum > 0) { + return 'badsec'; + } + if (reservednum > 0) { + return 'reserved'; + } + } + return; +} +END +} + sub close_popup_form { my $close= &mt('Close Window'); return << "END"; @@ -934,7 +1135,8 @@ sub print_request_form { ); $crstype = $env{'form.crstype'}; $r->print('<form name="'.$formname.'" method="post" action="/adm/requestcourse">'); - my (@codetitles,%cat_titles,%cat_order,@code_order,$instcode,$code_chk); + my (@codetitles,%cat_titles,%cat_order,@code_order,$instcode,$code_chk, + @disallowed); if ($crstype eq 'official') { if ($env{'form.instcode'} ne '') { $instcode = $env{'form.instcode'}; @@ -997,6 +1199,79 @@ sub print_request_form { } elsif ($state eq 'personnel') { $r->print(&print_personnel_menu($dom,$formname,$crstype,$invalidcrosslist)); } elsif ($state eq 'review') { + my (%alerts,%rulematch,%inst_results,%curr_rules,%got_rules,%disallowmsg); + my $now = time; + for (my $i=0; $i<$env{'form.persontotal'}; $i++) { + my $personname = $env{'form.person_'.$i.'_uname'}; + my $persondom = $env{'form.person_'.$i.'_dom'}; + if (($personname =~ /^$match_username$/) && + ($persondom =~ /^$match_domain$/)) { + if (&Apache::lonnet::domain($persondom)) { + my $personhome = + &Apache::lonnet::homeserver($personname,$persondom); + if ($personhome eq 'no_host') { + if ($persondom ne $dom) { + my $skipuser = 1; + if ($env{'user.role.dc./'.$persondom.'/'}) { + my ($start,$end) = split('.',$env{'user.role.dc./'.$persondom.'/'}); + if (((!$start) || ($start < $now)) && + ((!$end) || ($end > $now))) { + $skipuser = 0; + } + } + if ($skipuser) { + push(@disallowed,$i); + $disallowmsg{$i} = &mt('[_1] was excluded because new users need be from the course domain','<tt>'.$personname.':'.$persondom.'</tt>'); + next; + } + } + if (&get_cancreate_status($persondom,$personname,$dom)) { + my ($allowed,$msg) = + &check_newuser_rules($persondom,$personname, + \%alerts,\%rulematch,\%inst_results, + \%curr_rules,\%got_rules); + if ($allowed) { + if (ref($inst_results{$personname.':'.$persondom}) eq 'HASH') { + if ($inst_results{$personname.':'.$persondom}{'lastname'} ne '') { + $env{'form.person_'.$i.'_lastname'} = $inst_results{$personname.':'.$persondom}{'lastname'}; + } + if ($inst_results{$personname.':'.$persondom}{'firstname'} ne '') { + $env{'form.person_'.$i.'_firstname'} = $inst_results{$personname.':'.$persondom}{'firstname'}; + } + if ($inst_results{$personname.':'.$persondom}{'permanentemail'} ne '') { + $env{'form.person_'.$i.'_emailaddr'} = $inst_results{$personname.':'.$persondom}{'permanentemail'}; + } + } + } else { + push(@disallowed,$i); + $disallowmsg{$i} = &mt('[_1] was excluded because the username violated format rules for the domain','<tt>'.$personname.':'.$persondom.'</tt>'); + } + } else { + push(@disallowed,$i); + $disallowmsg{$i} = &mt('[_1] was excluded because you may not request new users in the domain','<tt>'.$personname.':'.$persondom.'</tt>'); + } + } else { + my %userenv = + &Apache::lonnet::userenvironment($persondom,$personname,'lastname','firstname','permanentemail'); + if ($env{'form.person_'.$i.'_lastname'} eq '') { + $env{'form.person_'.$i.'_lastname'} = $userenv{'lastname'}; + } + if ($env{'form.person_'.$i.'_firstname'} eq '') { + $env{'form.person_'.$i.'_firstname'} = $userenv{'firstname'}; + } + if ($env{'form.person_'.$i.'_emailaddr'} eq '') { + $env{'form.person_'.$i.'_emailaddr'} = $userenv{'permanentemail'}; + } + } + } elsif ($personname ne '') { + push(@disallowed,$i); + $disallowmsg{$i} = &mt('[_1] was excluded because the domain is invalid','<tt>'.$personname.':'.$persondom.'</tt>'); + } + } elsif ($personname ne '') { + push(@disallowed,$i); + $disallowmsg{$i} = &mt('[_1] was excluded because the username or domain is invalid.','<tt>'.$personname.':'.$persondom.'</tt>'); + } + } my $cnum; if ($env{'form.origcnum'} =~ /^($match_courseid)$/) { $cnum = $env{'form.origcnum'}; @@ -1006,7 +1281,7 @@ sub print_request_form { &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles, \%cat_order,\@code_order); $r->print('<h3>'.&mt('Review course request details before submission').'</h3>'. - &print_review($dom,\@codetitles,\%cat_titles,\%cat_order,\@code_order). + &print_review($dom,\@codetitles,\%cat_titles,\%cat_order,\@code_order,'','',\@disallowed,\%disallowmsg). '<input type="hidden" name="cnum" value="'.$cnum.'" />'); $navtxt{'next'} = &mt('Submit course request'); } elsif ($state eq 'process') { @@ -1031,14 +1306,80 @@ sub print_request_form { if ($state eq 'personnel') { push(@excluded,'persontotal'); } + if ($state eq 'review') { + if (@disallowed > 0) { + my @items = qw(uname dom lastname firstname emailaddr hidedom role newsec); + my @currsecs = ¤t_lc_sections(); + if (@currsecs) { + push(@items,'sec'); + } + my $count = 0; + for (my $i=0; $i<$env{'form.persontotal'}; $i++) { + unless ($env{'form.person_'.$i.'_uname'} eq '') { + if (grep(/^$i$/,@disallowed)) { + foreach my $item (@items) { + $env{'form.person_'.$i.'_'.$item} = ''; + } + } else { + foreach my $item (@items) { + $env{'form.person_'.$count.'_'.$item} = $env{'form.person_'.$i.'_'.$item}; + } + } + } + $count ++; + } + $env{'form.persontotal'} = $count; + + } + } if ($state eq 'enrollment') { push(@excluded,'crosslisttotal'); } $r->print(&Apache::lonhtmlcommon::echo_form_input(\@excluded).'</form>'); - &display_navbuttons($r,$formname,$prev,$navtxt{'prev'},$next,$navtxt{'next'},$state); + &display_navbuttons($r,$dom,$formname,$prev,$navtxt{'prev'},$next, + $navtxt{'next'},$state); return; } +sub get_cancreate_status { + my ($persondom,$personname,$dom) = @_; + my ($rules,$ruleorder) = + &Apache::lonnet::inst_userrules($persondom,'username'); + my $usertype = &Apache::lonuserutils::check_usertype($persondom,$personname, + $rules); + return &Apache::lonuserutils::can_create_user($dom,'requestcrs',$usertype); +} + +sub check_newuser_rules { + my ($persondom,$personname,$alerts,$rulematch,$inst_results,$curr_rules, + $got_rules) = @_; + my $allowed = 1; + my $newuser = 1; + my ($checkhash,$userchkmsg); + my $checks = { 'username' => 1 }; + $checkhash->{$personname.':'.$persondom} = { 'newuser' => $newuser }; + &Apache::loncommon::user_rule_check($checkhash,$checks,$alerts,$rulematch, + $inst_results,$curr_rules,$got_rules); + if (ref($alerts->{'username'}) eq 'HASH') { + if (ref($alerts->{'username'}{$persondom}) eq 'HASH') { + my $domdesc = + &Apache::lonnet::domain($persondom,'description'); + if ($alerts->{'username'}{$persondom}{$personname}) { + if (ref($curr_rules->{$persondom}) eq 'HASH') { + $userchkmsg = + &Apache::loncommon::instrule_disallow_msg('username', + $domdesc,1). + &Apache::loncommon::user_rule_formats($persondom, + $domdesc,$curr_rules->{$persondom}{'username'}, + 'username'); + } + $allowed = 0; + } + } + } + return ($allowed,$userchkmsg); +} + sub get_excluded_elements { my ($dom,$states,$action,$state) = @_; my @excluded = ('counter'); @@ -1193,14 +1534,18 @@ sub inst_section_selector { &Apache::loncommon::end_data_table_row(); for (my $i=0; $i<@sections; $i++) { my $colflag = $i%2; - my $checked = ' checked="checked"'; + my $secon = ' checked="checked"'; + my $secoff = ''; if ($env{'form.origcnum'}) { - $checked=''; + $secoff = $secon; + $secon=''; } $output .= &Apache::loncommon::start_data_table_row(). - '<td><input type="checkbox" name="sec_'.$i. - '"'.$checked.' value="1" /></td>'. - '<td>'.$sections[$i]. + '<td><label><input type="radio" name="sec_'.$i. + '"'.$secon.' value="1" />'.&mt('Yes').'</label>'. + (' 'x2).'<label><input type="radio" name="sec_'.$i. + '"'.$secoff.' value="0" />'.&mt('No').'</label></td>'. + '<td align="center">'.$sections[$i]. '<input type="hidden" name="secnum_'.$i.'" value="'. $sections[$i].'" /></td>'. '<td><input type="text" size="10" name="loncapasec_'.$i. @@ -1252,7 +1597,6 @@ sub print_personnel_menu { if ($env{'form.addperson'}) { $persontotal ++; } - my $userlinktxt = &mt('Set User'); my @items = ('uname','dom','lastname','firstname','emailaddr','hidedom'); my $roleoptions; @@ -1273,17 +1617,7 @@ sub print_personnel_menu { } } - my @currsecs; - if ($env{'form.sectotal'}) { - for (my $i=0; $i<$env{'form.sectotal'}; $i++) { - if (defined($env{'form.loncapasec_'.$i})) { - my $lcsec = $env{'form.loncapasec_'.$i}; - unless (grep(/^\Q$lcsec\E$/,@currsecs)) { - push(@currsecs,$lcsec); - } - } - } - } + my @currsecs = ¤t_lc_sections(); my ($existtitle,$existops,$existmult,$newtitle,$seccolspan); if (@currsecs) { @@ -1311,16 +1645,12 @@ sub print_personnel_menu { for (my $i=0; $i<$persontotal; $i++) { my @linkargs = map { 'person_'.$i.'_'.$_ } (@items); my $linkargstr = join("','",@linkargs); - my $userlink = &Apache::loncommon::selectuser_link($formname,@linkargs,$dom,$userlinktxt); - my $uname_form = '<input type="text" name="person_'.$i.'_uname" value=""'. - ' onFocus="this.blur();'. - 'openuserbrowser('."'$formname','$linkargstr','$dom'".');" />'; + my $uname_form = '<input type="text" name="person_'.$i.'_uname" value="" size="20" />'; my $onchange = 'javascript:fix_domain('."'$formname','person_".$i."_dom',". - "'person_".$i."_hidedom'".');'. - 'openuserbrowser('."'$formname','$linkargstr','$dom'".');'; + "'person_".$i."_hidedom','person_".$i."_uname'".');'; my $udom_form = &Apache::loncommon::select_dom_form($dom,'person_'.$i.'_dom','', 1,$onchange). - '<input type="hidden" name="person_'.$i.'_hidedom" value="'.$dom.'" />'; + '<input type="hidden" name="person_'.$i.'_hidedom" value="" />'; my %form_elems; foreach my $item (@items) { next if (($item eq 'dom') || ($item eq 'uname') || ($item eq 'hidedom')); @@ -1336,12 +1666,19 @@ sub print_personnel_menu { } $sectionselector .= $newtitle. '<input type="text" name="person_'.$i.'_newsec" size="15" value="" />'."\n"; + my $usersrchlinktxt = &mt('Search for user'); + my $usersrchlink = &Apache::loncommon::selectuser_link($formname,@linkargs,$dom, + $usersrchlinktxt); + my $userchklinktxt = &mt('Check username'); + my $userchklink = &Apache::loncommon::selectuser_link($formname,@linkargs,$dom, + $userchklinktxt,'checkusername'); $output .= - &Apache::lonhtmlcommon::row_title(&mt('Additional Personnel').'<br />'. - '<span class="LC_nobreak">'.$userlink. - '</span>'). - '<table><tr><td align="center" valign="top">'.&mt('Username').'<br />'.$uname_form.'</td>'."\n". - '<td align="center" valign="top" colspan="2">'.&mt('Domain').'<br />'.$udom_form.'</td></tr><tr>'."\n". + &Apache::lonhtmlcommon::row_title(&mt('Additional Personnel')). + '<table><tr><td align="center" valign="middle"><b>'.$usersrchlink.'</b></td>'."\n". + '<td align="left" valign="top" colspan="2"><span class="LC_nobreak">'. + &mt('Username').': '.$uname_form.' '.$userchklink.'</span><br />'."\n". + '<span class="LC_nobreak">'.&mt('Domain').': '.$udom_form.'</span></td>'. + '</tr>'."\n".'<tr>'. '<td align="center" valign="top">'.&mt('First Name').'<br />'.$form_elems{'firstname'}.'</td>'."\n". '<td align="center" valign="top">'.&mt('Last Name').'<br />'.$form_elems{'lastname'}.'</td>'."\n". '<td align="center" valign="top">'.&mt('E-mail').'<br />'.$form_elems{'emailaddr'}.'</td></tr>'."\n". @@ -1358,6 +1695,23 @@ sub print_personnel_menu { return $output; } +sub current_lc_sections { + my @currsecs; + if ($env{'form.sectotal'}) { + for (my $i=0; $i<$env{'form.sectotal'}; $i++) { + if ($env{'form.sec_'.$i}) { + if (defined($env{'form.loncapasec_'.$i})) { + my $lcsec = $env{'form.loncapasec_'.$i}; + unless (grep(/^\Q$lcsec\E$/,@currsecs)) { + push(@currsecs,$lcsec); + } + } + } + } + } + return @currsecs; +} + sub print_request_status { my ($dom) = @_; my %statusinfo = &Apache::lonnet::dump('courserequests',$env{'user.domain'}, @@ -1466,8 +1820,7 @@ sub print_request_status { $output .= '<div>'.&mt('You have no matching course requests awaiting approval by a Domain Coordinator or held in a queue pending administrative action at your institution.').'</div>'; } $output .= ' -<br /><input type="button" name="prev" value="'.&mt('Back').'" onclick="javascript:backPage(document.'.$formname.",'crstype'".')" /> -</form></div>'; +<br /><input type="button" name="prev" value="'.&mt('Back').'" onclick="javascript:backPage(document.'.$formname.",'crstype'".')" />'; return $output; } @@ -1573,7 +1926,8 @@ sub print_request_logs { } sub print_review { - my ($dom,$codetitles,$cat_titles,$cat_order,$code_order,$uname,$udom) = @_; + my ($dom,$codetitles,$cat_titles,$cat_order,$code_order,$uname,$udom, + $disallowed,$disallowmsg) = @_; my ($types,$typename) = &course_types(); my ($owner,$ownername,$owneremail); if ($uname eq '' || $udom eq '') { @@ -1751,14 +2105,25 @@ sub print_review { '<td>'.&mt('None').'</td></tr>'; for (my $i=0; $i<$env{'form.persontotal'}; $i++) { if ($env{'form.person_'.$i.'_uname'} ne '') { - my @allsecs = &Apache::loncommon::get_env_multiple('form.person_'.$i.'_sec'); + if (ref($disallowed) eq 'ARRAY') { + next if (grep(/^$i$/,@{$disallowed})); + } + my @officialsecs = &Apache::loncommon::get_env_multiple('form.person_'.$i.'_sec'); + my @allsecs; + foreach my $sec (@officialsecs) { + next unless ($sec =~ /\w/); + next if ($sec =~ /\W/); + next if ($sec eq 'none'); + push(@allsecs,$sec); + } my $newsec = $env{'form.person_'.$i.'_newsec'}; $newsec =~ s/^\s+//; $newsec =~s/\s+$//; - my @newsecs = split(/[\s,;]+/,$newsec); + my @newsecs = split(/\s*[\s,;:]\s*/,$newsec); foreach my $sec (@newsecs) { + next unless ($sec =~ /\w/); next if ($sec =~ /\W/); - next if ($newsec eq 'none'); + next if ($sec eq 'none'); if ($sec ne '') { unless (grep(/^\Q$sec\E$/,@allsecs)) { push(@allsecs,$sec); @@ -1785,8 +2150,20 @@ sub print_review { '<td>'.$showsec.'</td></tr>'; } } - my $output = - '<div>'.&Apache::lonhtmlcommon::start_pick_box(). + my $output; + if (ref($disallowed) eq 'ARRAY') { + if (@{$disallowed} > 0) { + if (ref($disallowmsg) eq 'HASH') { + $output = '<p class="LC_warning">'. + &mt('Not all requested personnel could be included.').'<ul>'; + foreach my $item (@{$disallowed}) { + $output .= '<li>'.$disallowmsg->{$item}.'</li>'; + } + $output .= '</ul></p>'; + } + } + } + $output .= '<div>'.&Apache::lonhtmlcommon::start_pick_box(). &Apache::lonhtmlcommon::row_title(&mt('Owner')). '<table class="LC_innerpickbox"><tr>'. '<th>'.&mt('Name').'</th>'. @@ -1887,8 +2264,7 @@ sub clone_form { my %lt = &clone_text(); my $output .= &Apache::lonhtmlcommon::row_title($lt{'cid'}).'<label>'. - '<input type="text" size="25" name="clonecrs" value="" onfocus="this.blur();'. - 'opencrsbrowser('."'$formname','clonecrs','clonedom','','','','$type'".');" />'. + '<input type="text" size="25" name="clonecrs" value="" />'. '</label>'.&Apache::lonhtmlcommon::row_closure(1).'<label>'. &Apache::lonhtmlcommon::row_title($lt{'dmn'}).'</label>'. $cloneform.'</label>'.&Apache::lonhtmlcommon::row_closure(1). @@ -2049,11 +2425,11 @@ sub get_course_dom { } sub display_navbuttons { - my ($r,$formname,$prev,$prevtext,$next,$nexttext,$state,$other,$othertext) = @_; + my ($r,$dom,$formname,$prev,$prevtext,$next,$nexttext,$state,$other,$othertext) = @_; $r->print('<div class="LC_navbuttons">'); if ($prev) { $r->print('<input type="button" name="previous" value = "'.$prevtext.'" '. - 'onclick="javascript:backPage(document.'.$formname.','."'".$prev."'".')"/>'. + 'onclick="javascript:backPage('."document.$formname,'$prev'".')"/>'. (' 'x3)); } elsif ($prevtext) { $r->print('<input type="button" name="previous" value = "'.$prevtext.'" '. @@ -2061,16 +2437,34 @@ sub display_navbuttons { } if ($state eq 'details') { $r->print(' <input type="button" name="other" value="'.$othertext.'" '. - 'onclick="javascript:nextPage(document.'.$formname.','."'".$other."'". + 'onclick="javascript:nextPage('."document.$formname,'$other'". ')" />'); } + my $gotnext; if ($state eq 'courseinfo') { $r->print('<input type="button" name="next" value="'.$nexttext.'" '. 'onclick="javascript:validateForm();" />'); - } elsif ($next) { - $r->print(' - <input type="button" name="next" value="'.$nexttext.'" '. - 'onclick="javascript:nextPage(document.'.$formname.','."'".$next."'".')" />'); + $gotnext = 1; + } elsif ($state eq 'enrollment') { + if (($env{'form.crstype'} eq 'official') && + (&Apache::lonnet::auto_run('',$dom))) { + $r->print('<input type="button" name="next" value="'.$nexttext.'" '. + 'onclick="javascript:validateEnrollSections('."document.$formname,'$next'".');" />'); + $gotnext = 1; + } + } elsif ($state eq 'personnel') { + if ($env{'form.persontotal'} > 0) { + $r->print('<input type="button" name="next" value="'.$nexttext.'" '. + 'onclick="javascript:validatePersonnelSections('."document.$formname,'$next'".');" />'); + $gotnext = 1; + } + } + unless ($gotnext) { + if ($next) { + $r->print(' + <input type="button" name="next" value="'.$nexttext.'" '. + 'onclick="javascript:nextPage('."document.$formname,'$next'".')" />'); + } } $r->print('</div>'); } @@ -2160,20 +2554,27 @@ sub print_request_outcome { @{$personnel{$uname.':'.$udom}{$role}{'usec'}} = (); } else { my @currsec = &Apache::loncommon::get_env_multiple('form.person_'.$i.'_sec'); + my @allsecs; + foreach my $sec (@currsec) { + next unless ($sec =~ /\w/); + next if ($sec =~ /\W/); + next if ($sec eq 'none'); + push(@allsecs,$sec); + } my $newsec = $env{'form.person_'.$i.'_newsec'}; $newsec =~ s/^\s+//; $newsec =~s/\s+$//; my @newsecs = split(/[\s,;]+/,$newsec); foreach my $sec (@newsecs) { next if ($sec =~ /\W/); - next if ($newsec eq 'none'); + next if ($sec eq 'none'); if ($sec ne '') { - unless (grep(/^\Q$sec\E$/,@currsec)) { - push(@currsec,$sec); + unless (grep(/^\Q$sec\E$/,@allsecs)) { + push(@allsecs,$sec); } } } - @{$personnel{$uname.':'.$udom}{$role}{'usec'}} = @currsec; + @{$personnel{$uname.':'.$udom}{$role}{'usec'}} = @allsecs; } } } else {