--- loncom/interface/lonmodifycourse.pm 2007/12/14 00:24:11 1.36 +++ loncom/interface/lonmodifycourse.pm 2008/10/27 14:32:30 1.40 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # handler for DC-only modifiable course settings # -# $Id: lonmodifycourse.pm,v 1.36 2007/12/14 00:24:11 raeburn Exp $ +# $Id: lonmodifycourse.pm,v 1.40 2008/10/27 14:32:30 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -43,6 +43,22 @@ sub get_dc_settable { return ('courseowner','coursecode','authtype','autharg'); } +sub catalog_settable { + my ($confhash) = @_; + my @settable; + if (ref($confhash) eq 'HASH') { + if ($confhash->{'togglecats'} ne 'crs') { + push(@settable,'togglecats'); + } + if ($confhash->{'categorize'} ne 'crs') { + push(@settable,'categorize'); + } + } else { + push(@settable,('togglecats','categorize')); + } + return @settable; +} + sub get_enrollment_settings { my ($cdom,$cnum) = @_; my %settings = &Apache::lonnet::dump('environment',$cdom,$cnum); @@ -108,22 +124,12 @@ sub print_course_search_page { my $action = '/adm/modifycourse'; my $cctitle = &Apache::lonnet::plaintext('cc',$type); my $dctitle = &Apache::lonnet::plaintext('dc'); - my %lt=&Apache::lonlocal::texthash( - 'some' => "Certain settings which control auto-enrollment of students from your institution's student information system.", - 'crqo' => 'The total disk space allocated for storage of portfolio files in all groups in a course.', - 'tmod' => 'To view or modify these settings use the criteria below to select a course from this domain.', - ); - $r->print('<h3>'. - &mt('Course settings which only a [_1] may modify.' - ,$dctitle).'</h3>'. - &mt('Although almost all course settings can be modified by a [_1], a number of settings exist which only a [_2] may change:',$cctitle,$dctitle).' -<ul> - <li>'.$lt{'some'}.'</li> - <li>'.$lt{'crqo'}.'</li> -</ul>'. -$lt{'tmod'}.' ('.$domdesc.') -<br /><br /> - '); + $r->print( + '<h3>'.&mt('Search for a course in the [_1] domain',$domdesc).'</h3>'. + &mt('Actions available after searching for a course:').'<ul>'. + '<li>'.&mt('Enter the course with the role of [_1]',$cctitle).'</li>'."\n". + '<li>'.&mt('View or modify course settings which only a [_1] may modify.' + ,$dctitle).'</li>'."\n".'</ul>'); $r->print(&Apache::lonpickcourse::build_filters($filterlist,$type, undef,undef,$filter,$action,'modifycourse')); } @@ -149,18 +155,22 @@ sub print_course_selection_page { $filter{'domainfilter'} = $dom; my %courses = &Apache::lonpickcourse::search_courses($r,$type,0, \%filter); - if (keys(%courses) > 0) { - $r->print(&mt("Click a 'Select' button to view or modify settings for a [_1] which may only be modified by a [_2] in this domain.",lc($type),$dctitle).'<br /><br />'); - } - &Apache::lonpickcourse::display_matched_courses($r,$type,0,$action, %courses); return; } sub print_modification_menu { - my ($r,$cdesc) = @_; + my ($r,$cdesc,$domdesc,$dom) = @_; &print_header($r,$cdesc); + my $type = 'Course'; + my $action = '/adm/modifycourse'; + my $cctitle = &Apache::lonnet::plaintext('cc',$type); + my $dctitle = &Apache::lonnet::plaintext('dc'); + my %lt=&Apache::lonlocal::texthash( + 'some' => "Certain settings which control auto-enrollment of students from your institution's student information system.", + 'crqo' => 'The total disk space allocated for storage of portfolio files in all groups in a course.', + ); my @menu = ( { text => 'Modify quota for group portfolio files', @@ -171,11 +181,32 @@ sub print_modification_menu { }, { text => 'Modify institutional code, course owner and/or default authentication', phase => 'setparms', - } + }, ); + my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$dom); + my @additional_params = &catalog_settable($domconf{'coursecategories'}); + if (@additional_params > 0) { + push (@menu, { text => 'Modify course catalog settings for course', + phase => 'catsettings', + }); + } my $menu_html = '<h3>'.&mt('View/Modify settings for: ').$cdesc.'</h3>'."\n". - '<form name="menu" method="post" action="/adm/modifycourse" />'."\n". - &hidden_form_elements(); + &mt('Although almost all course settings can be modified by a [_1], a number of settings exist which only a [_2] may change:',$cctitle,$dctitle).' +<ul> + <li>'.$lt{'some'}.'</li> + <li>'.$lt{'crqo'}.'</li>'."\n"; + foreach my $item (@additional_params) { + if ($item eq 'togglecats') { + $menu_html .= ' <li>'.&mt('Hiding a course from the course catalog (can be [_1]configured[_2] to be modifiable in course context)','<a href="/adm/domainprefs?actions=coursecategories&phase=display">','</a>').'</li>'."\n"; + } elsif ($item eq 'categorize') { + $menu_html .= ' <li>'.&mt('Manual cataloging of a course (can be [_1]configured[_2] to be modifiable in course context)','<a href="/adm/domainprefs?actions=coursecategories&phase=display">','</a>').'</li>'."\n"; + + } + } + $menu_html .= ' </ul> +<form name="menu" method="post" action="'.$action.'" />'."\n". + &hidden_form_elements(); + foreach my $menu_item (@menu) { $menu_html.='<p>'; $menu_html.='<font size="+1">'; @@ -189,6 +220,16 @@ sub print_modification_menu { return; } +sub print_ccrole_selected { + my ($r,$cdesc,$domdesc) = @_; + &print_header($r); + my ($cdom,$cnum) = split(/_/,$env{'form.pickedcourse'}); + $r->print('<form name="ccrole" method="post" action="/adm/roles"> +<input type="hidden" name="selectrole" value="1" /> +<input type="hidden" name="newrole" value="cc./'.$cdom.'/'.$cnum.'" /> +</form>'); +} + sub print_settings_display { my ($r,$cdom,$cnum,$cdesc,$type) = @_; my %enrollvar = &get_enrollment_settings($cdom,$cnum); @@ -239,7 +280,7 @@ sub print_settings_display { </p><p> <a href="javascript:changePage(document.viewparms,'."'menu'".')">'.$lt{'back'}.'</a> <a href="javascript:changePage(document.viewparms,'."'setparms'".')">'.&mt('Modify [_1]-only settings',$dctitle).'</a>'."\n". -&hidden_form_elements(). +&hidden_form_elements(). '</form>'); } @@ -279,6 +320,59 @@ ENDDOCUMENT return; } +sub print_catsettings { + my ($r,$cdom,$cnum,$cdesc) = @_; + &print_header($r,$cdesc); + my %lt = &Apache::lonlocal::texthash( + 'back' => 'Back to options page', + ); + $r->print('<form action="/adm/modifycourse" method="post" name="catsettings">'. + '<h3>'.&mt('Catalog Settings for Course').'</h3>'); + my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom); + my @cat_params = &catalog_settable($domconf{'coursecategories'}); + if (@cat_params > 0) { + my %currsettings = + &Apache::lonnet::get('environment',['hidefromcat','categories'],$cdom,$cnum); + if (grep(/^togglecats$/,@cat_params)) { + my $excludeon = ''; + my $excludeoff = ' checked="checked" '; + if ($currsettings{'hidefromcat'} eq 'yes') { + $excludeon = $excludeoff; + $excludeoff = ''; + } + $r->print('<h4>'.&mt('Visibility in Course Catalog').'</h4>'. + &mt("Unless excluded, a course is listed in this domain's publicly accessible course catalog, if at least one of the following applies").':<ul>'. + '<li>'.&mt('Auto-cataloging is enabled and the course is assigned an institutional code').'</li>'. + '<li>'.&mt('The course has been categorized into at least one of the course categories defined for the domain.').'</li></ul>'. + &mt('Exclude from course catalog').' <label><input name="hidefromcat" type="radio" value="yes" '.$excludeon.' />'.&mt('Yes').'</label> <label><input name="hidefromcat" type="radio" value="" '.$excludeoff.' />'.&mt('No').'</label><br />'); + } + if (grep(/^categorize$/,@cat_params)) { + $r->print('<h4>'.&mt('Categorize Course').'</h4>'); + if (ref($domconf{'coursecategories'}) eq 'HASH') { + my $cathash = $domconf{'coursecategories'}{'cats'}; + if (ref($cathash) eq 'HASH') { + $r->print(&mt('Assign one or more categories to this course.').'<br /><br />'. + &Apache::loncommon::assign_categories_table($cathash, + $currsettings{'categories'})); + } else { + $r->print(&mt('No categories defined for this domain')); + } + } else { + $r->print(&mt('No categories defined for this domain')); + } + $r->print('<p>'.&mt('If auto-cataloging based on institutional code is enabled in the domain, a course will continue to be listed in the catalog of official courses, in addition to receiving a listing under any manually assigned categor(ies).').'</p>'); + } + $r->print('<input type="button" name="chgcatsettings" value="'. + &mt('Save').'" onclick="javascript:changePage(document.catsettings,'."'processcat'".');" />'); + } else { + $r->print('<span class="LC_warning">'.&mt('Catalog settings in this domain are set in course context via "Set Course Environment".').'</span><br /><br />'."\n". + '<a href="javascript:changePage(document.catsettings,'."'menu'".');">'. + $lt{'back'}.'</a>'); + } + $r->print(&hidden_form_elements().'</form>'."\n"); + return; +} + sub print_course_modification_page { my ($r,$cdom,$cnum,$cdesc,$domdesc) = @_; my %longtype = &course_settings_descrip(); @@ -498,8 +592,9 @@ sub modify_course { my @nochanges = (); my @sections = (); my @xlists = (); - my $changecode = 0; - my $changeowner = 0; + my %changed = ( code => 0, + owner => 0, + ); unless ($settings{'internal.sectionnums'} eq '') { if ($settings{'internal.sectionnums'} =~ m/,/) { @sections = split/,/,$settings{'internal.sectionnums'}; @@ -522,7 +617,6 @@ sub modify_course { } my $description = $settings{'description'}; - my %cenv = (); if ($env{'form.login'} eq 'krb') { $newattr{'authtype'} = $env{'form.login'}; @@ -549,28 +643,25 @@ sub modify_course { if ( exists($env{'form.courseowner'}) ) { $newattr{'courseowner'}=$env{'form.courseowner'}; unless ( $newattr{'courseowner'} eq $currattr{'courseowner'} ) { - $changeowner = 1; + $changed{'owner'} = 1; } } if ( exists($env{'form.coursecode'}) ) { $newattr{'coursecode'}=$env{'form.coursecode'}; unless ( $newattr{'coursecode'} eq $currattr{'coursecode'} ) { - $changecode = 1; + $changed{'code'} = 1; } } - if ($changeowner == 1 || $changecode == 1) { - my $courseid_entry = &escape($cdom.'_'.$cnum).'='.&escape($description).':'.&escape($env{'form.coursecode'}).':'.&escape($env{'form.courseowner'}).':'.&escape($type); - my %courseid_entry = ( - $cdom.'_'.$cnum => { - description => $description, - inst_code => $env{'form.coursecode'}, - owner => $env{'form.courseowner'}, - type => $type, - }, - ); - &Apache::lonnet::courseidput($cdom,\%courseid_entry, - &Apache::lonnet::homeserver($cnum,$cdom),'notime'); + if ($changed{'owner'} || $changed{'code'}) { + my %crsinfo = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.',$cnum, + undef,undef,'.'); + if (ref($crsinfo{$env{'form.pickedcourse'}}) eq 'HASH') { + $crsinfo{$env{'form.pickedcourse'}}{'inst_code'} = $env{'form.coursecode'}; + $crsinfo{$env{'form.pickedcourse'}}{'owner'} = $env{'form.courseowner'}; + my $chome = &Apache::lonnet::homeserver($cnum,$cdom); + my $putres = &Apache::lonnet::courseidput($cdom,\%crsinfo,$chome,'notime'); + } } foreach my $param (@modifiable_params) { if ($currattr{$param} eq $newattr{$param}) { @@ -599,12 +690,12 @@ sub modify_course { $nochgresponse .= "<li>$longtype{$attr} ".&mt("still set to \"").$currattr{$attr}."\".</li>"; } } - if ($changecode || $changeowner) { + if ($changed{'code'} || $changed{'owner'}) { if ( $newattr{'courseowner'} eq '') { $warning .= &mt("There is no owner associated with this LON-CAPA course. If automated enrollment in LON-CAPA courses at your institution requires validation of course owners, automated enrollment will fail for this course.<br/>"); } else { if (@sections > 0) { - if ($changecode) { + if ($changed{'code'}) { foreach my $sec (@sections) { if ($sec =~ m/^(.+):/) { my $inst_course_id = $newattr{'coursecode'}.$1; @@ -621,7 +712,7 @@ sub modify_course { $warning .= &mt("If automatic enrollment is enabled for LON-CAPA course: ").$description.&mt(", automated enrollment may fail for ").$newattr{'coursecode'}.&mt(" - section $sec because this is not a valid section entry.<br/>"); } } - } elsif ($changeowner) { + } elsif ($changed{'owner'}) { foreach my $sec (@sections) { if ($sec =~ m/^(.+):/) { my $inst_course_id = $newattr{'coursecode'}.$1; @@ -637,7 +728,7 @@ sub modify_course { } else { $warning .= &mt("As no section numbers are currently listed for LON-CAPA course: ").$description.&mt(", automated enrollment will not occur for any sections of coursecode: ").$newattr{'coursecode'}."<br/>"; } - if ( (@xlists > 0) && ($changeowner) ) { + if ( (@xlists > 0) && ($changed{'owner'}) ) { foreach my $xlist (@xlists) { if ($xlist =~ m/^(.+):/) { my $outcome = &Apache::lonnet::auto_new_course($cnum,$cdom,$1,$newattr{'courseowner'}); @@ -740,6 +831,126 @@ sub modify_quota { return; } +sub modify_catsettings { + my ($r,$cdom,$cnum,$cdesc,$domdesc) = @_; + &print_header($r,$cdesc); + my %lt = &Apache::lonlocal::texthash( + 'back' => 'Back to options page', + ); + my %desc = &Apache::lonlocal::texthash( + 'hidefromcat' => 'Excluded from course catalog', + 'categories' => 'Assigned categories for this course', + ); + $r->print(' +<form action="/adm/modifycourse" method="post" name="processcat"> +<h3>'.&mt('Category settings').'</h3>'); + my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom); + my @cat_params = &catalog_settable($domconf{'coursecategories'}); + if (@cat_params > 0) { + my (%cenv,@changes,@nochanges); + my %currsettings = + &Apache::lonnet::get('environment',['hidefromcat','categories'],$cdom,$cnum); + my (@newcategories,%showitem); + if (grep(/^togglecats$/,@cat_params)) { + if ($currsettings{'hidefromcat'} ne $env{'form.hidefromcat'}) { + push(@changes,'hidefromcat'); + $cenv{'hidefromcat'} = $env{'form.hidefromcat'}; + } else { + push(@nochanges,'hidefromcat'); + } + if ($env{'form.hidefromcat'} eq 'yes') { + $showitem{'hidefromcat'} = '"'.&mt('Yes')."'"; + } else { + $showitem{'hidefromcat'} = '"'.&mt('No').'"'; + } + } + if (grep(/^categorize$/,@cat_params)) { + my (@cats,@trails,%allitems,%idx,@jsarray); + if (ref($domconf{'coursecategories'}) eq 'HASH') { + my $cathash = $domconf{'coursecategories'}{'cats'}; + if (ref($cathash) eq 'HASH') { + &Apache::loncommon::extract_categories($cathash,\@cats,\@trails, + \%allitems,\%idx,\@jsarray); + } + } + @newcategories = &Apache::loncommon::get_env_multiple('form.usecategory'); + if (@newcategories == 0) { + $showitem{'categories'} = '"'.&mt('None').'"'; + } else { + $showitem{'categories'} = '<ul>'; + foreach my $item (@newcategories) { + $showitem{'categories'} .= '<li>'.$trails[$allitems{$item}].'</li>'; + } + $showitem{'categories'} .= '</ul>'; + } + my $catchg = 0; + if ($currsettings{'categories'} ne '') { + my @currcategories = split('&',$currsettings{'categories'}); + foreach my $cat (@currcategories) { + if (!grep(/^\Q$cat\E$/,@newcategories)) { + $catchg = 1; + last; + } + } + if (!$catchg) { + foreach my $cat (@newcategories) { + if (!grep(/^\Q$cat\E$/,@currcategories)) { + $catchg = 1; + last; + } + } + } + } else { + if (@newcategories > 0) { + $catchg = 1; + } + } + if ($catchg) { + $cenv{'categories'} = join('&',@newcategories); + push(@changes,'categories'); + } else { + push(@nochanges,'categories'); + } + if (@changes > 0) { + my $putreply = &Apache::lonnet::put('environment',\%cenv,$cdom,$cnum); + if ($putreply eq 'ok') { + my %crsinfo = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.', + $cnum,undef,undef,'.'); + if (ref($crsinfo{$env{'form.pickedcourse'}}) eq 'HASH') { + if (grep(/^hidefromcat$/,@changes)) { + $crsinfo{$env{'form.pickedcourse'}}{'hidefromcat'} = $env{'form.hidefromcat'}; + } + if (grep(/^categories$/,@changes)) { + $crsinfo{$env{'form.pickedcourse'}}{'categories'} = $cenv{'categories'}; + } + my $chome = &Apache::lonnet::homeserver($cnum,$cdom); + my $putres = &Apache::lonnet::courseidput($cdom,\%crsinfo,$chome,'notime'); + } + $r->print(&mt('The following changes occurred').'<ul>'); + foreach my $item (@changes) { + $r->print('<li>'.&mt('[_1] now set to [_2]',$desc{$item},$showitem{$item}).'</li>'); + } + $r->print('</ul><br />'); + } + } + if (@nochanges > 0) { + $r->print(&mt('The following were unchanged').'<ul>'); + foreach my $item (@nochanges) { + $r->print('<li>'.&mt('[_1] still set to [_2]',$desc{$item},$showitem{$item}).'</li>'); + } + $r->print('</ul>'); + } + } + } else { + $r->print(&mt('Category settings for courses in this domain should be modified in course context (via "Set Course Environment").').'<br />'); + } + $r->print('<br />'."\n". + '<a href="javascript:changePage(document.processcat,'."'menu'".')">'. + $lt{'back'}.'</a>'); + $r->print(&hidden_form_elements().'</form>'); + return; +} + sub print_header { my ($r,$cdesc,$javascript_validations) = @_; my $phase = "start"; @@ -788,8 +999,14 @@ function verify_quota(formname) { </script> ENDSCRIPT } + my $starthash; + if ($env{'form.phase'} eq 'ccrole') { + $starthash = { + add_entries => {'onload' => "javascript:document.ccrole.submit();"}, + }; + } $r->print(&Apache::loncommon::start_page('View/Modify Course Settings', - $js)); + $js,$starthash)); my $bread_text = "View/Modify Courses"; if ($cdesc ne '') { $bread_text = "Course Settings: $cdesc"; @@ -817,7 +1034,7 @@ sub check_course { if ($cdom eq $dom) { my $description; my %courseIDs = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.', - $cnum,undef,undef,'.'); + $cnum,undef,undef,'.'); if (keys(%courseIDs) > 0) { $ok_course = 'ok'; my ($instcode,$owner); @@ -861,8 +1078,9 @@ sub course_settings_descrip { sub hidden_form_elements { my $hidden_elements = &Apache::lonhtmlcommon::echo_form_input(['gosearch','coursecode', - 'numlocalcc','courseowner', - 'login','coursequota','intarg', 'locarg','krbarg','krbver']); + 'prevphase','numlocalcc','courseowner','login','coursequota','intarg', + 'locarg','krbarg','krbver','counter','hidefromcat','usecategory'])."\n". + '<input type="hidden" name="prevphase" value="'.$env{'form.phase'}.'" />'; return $hidden_elements; } @@ -882,21 +1100,24 @@ sub handler { &Apache::lonhtmlcommon::clear_breadcrumbs(); my $phase = $env{'form.phase'}; - &Apache::lonhtmlcommon::add_breadcrumb + if ($phase eq '') { + &Apache::lonhtmlcommon::add_breadcrumb ({href=>"/adm/modifycourse", text=>"Course search"}); - if ($phase eq '') { &print_course_search_page($r,$dom,$domdesc); } else { + my $firstform = $phase; + if ($phase eq 'courselist') { + $firstform = 'filterpicker'; + } &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"javascript:changePage(document.$phase,'courselist')", + ({href=>"javascript:changePage(document.$firstform,'')", + text=>"Course search"}, + {href=>"javascript:changePage(document.$phase,'courselist')", text=>"Choose a course"}); if ($phase eq 'courselist') { &print_course_selection_page($r,$dom,$domdesc); } else { - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"javascript:changePage(document.$phase,'menu')", - text=>"Pick action"}); my ($checked,$cdesc) = &check_course($r,$dom,$domdesc); my $type = $env{'form.type'}; if ($type eq '') { @@ -904,14 +1125,25 @@ sub handler { } if ($checked eq 'ok') { if ($phase eq 'menu') { - &print_modification_menu($r,$cdesc); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:changePage(document.$phase,'menu')", + text=>"Pick action"}); + &print_modification_menu($r,$cdesc,$domdesc,$dom); + } elsif ($phase eq 'ccrole') { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:changePage(document.$phase,'ccrole')", + text=>"Enter course"}); + &print_ccrole_selected($r,$cdesc,$domdesc); } else { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:changePage(document.$phase,'menu')", + text=>"Pick action"}); my ($cdom,$cnum) = split(/_/,$env{'form.pickedcourse'}); if ($phase eq 'setquota') { &Apache::lonhtmlcommon::add_breadcrumb ({href=>"javascript:changePage(document.$phase,'$phase')", text=>"Set quota"}); - &print_setquota($r,$cdom,$cnum,$cdesc,$type) + &print_setquota($r,$cdom,$cnum,$cdesc,$type); } elsif ($phase eq 'processquota') { &Apache::lonhtmlcommon::add_breadcrumb ({href=>"javascript:changePage(document.$phase,'setquota')", @@ -938,6 +1170,19 @@ sub handler { ({href=>"javascript:changePage(document.$phase,'$phase')", text=>"Result"}); &modify_course($r,$cdom,$cnum,$cdesc,$domdesc,$type); + } elsif ($phase eq 'catsettings') { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:changePage(document.$phase,'$phase')", + text=>"Catalog settings"}); + &print_catsettings($r,$cdom,$cnum,$cdesc,$type); + } elsif ($phase eq 'processcat') { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:changePage(document.$phase,'catsettings')", + text=>"Catalog settings"}); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:changePage(document.$phase,'$phase')", + text=>"Result"}); + &modify_catsettings($r,$cdom,$cnum,$cdesc,$domdesc); } } } else {