--- loncom/interface/lonmodifycourse.pm 2007/10/06 04:32:49 1.34 +++ loncom/interface/lonmodifycourse.pm 2008/06/30 04:14:40 1.39 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # handler for DC-only modifiable course settings # -# $Id: lonmodifycourse.pm,v 1.34 2007/10/06 04:32:49 raeburn Exp $ +# $Id: lonmodifycourse.pm,v 1.39 2008/06/30 04:14:40 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -33,7 +33,7 @@ use Apache::lonnet; use Apache::loncommon; use Apache::lonhtmlcommon; use Apache::lonlocal; -use Apache::londropadd; +use Apache::lonuserutils; use Apache::lonpickcourse; use LONCAPA::Enrollment; use lib '/home/httpd/lib/perl'; @@ -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('

'. - &mt('Course settings which only a [_1] may modify.' - ,$dctitle).'

'. - &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).' -'. -$lt{'tmod'}.' ('.$domdesc.') -

- '); + $r->print( + '

'.&mt('Search for a course in the [_1] domain',$domdesc).'

'. + &mt('Actions available after searching for a course:').''); $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).'

'); - } - &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 = '

'.&mt('View/Modify settings for: ').$cdesc.'

'."\n". - '
'."\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).' + +'."\n". + &hidden_form_elements(); + foreach my $menu_item (@menu) { $menu_html.='

'; $menu_html.=''; @@ -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(' + + +'); +} + 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 {

'.$lt{'back'}.'     '.&mt('Modify [_1]-only settings',$dctitle).''."\n". -&hidden_form_elements(). +&hidden_form_elements(). ''); } @@ -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('

'. + '

'.&mt('Catalog Settings for Course').'

'); + 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('

'.&mt('Visibility in Course Catalog').'

'. + &mt("Unless excluded, a course is listed in this domain's publicly accessible course catalog, if at least of one the following applies").':'. + &mt('Exclude from course catalog').'    
'); + } + if (grep(/^categorize$/,@cat_params)) { + $r->print('

'.&mt('Categorize Course').'

'); + 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.').'

'. + &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('

'.&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).').'

'); + } + $r->print(''); + } else { + $r->print(''.&mt('Catalog settings in this domain are set in course context via "Set Course Environment".').'

'."\n". + ''. + $lt{'back'}.''); + } + $r->print(&hidden_form_elements().''."\n"); + return; +} + sub print_course_modification_page { my ($r,$cdom,$cnum,$cdesc,$domdesc) = @_; my %longtype = &course_settings_descrip(); @@ -369,8 +463,8 @@ all settings except course code, course unless ($curr_authtype eq '') { $curr_authfield = $curr_authtype.'arg'; } - my $javascript_validations=&Apache::londropadd::javascript_validations('modifycourse',$krbdefdom,$curr_authtype,$curr_authfield); - my %param = ( formname => 'document.cmod', + my $javascript_validations=&Apache::lonuserutils::javascript_validations('modifycourse',$krbdefdom,$curr_authtype,$curr_authfield); + my %param = ( formname => 'document.'.$env{'form.phase'}, kerb_def_dom => $krbdefdom, kerb_def_auth => $krbdef, mode => 'modifycourse', @@ -437,7 +531,7 @@ all settings except course code, course my $mainheader = &mt('Course settings modifiable by [_1] only.',$dctitle); my $hidden_elements = &hidden_form_elements(); $r->print(< +

$mainheader

@@ -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 .= "
  • $longtype{$attr} ".&mt("still set to \"").$currattr{$attr}."\".
  • "; } } - 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.
    "); } 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.
    "); } } - } 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'}."
    "; } - 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(' + +

    '.&mt('Category settings').'

    '); + 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'} = '
      '; + foreach my $item (@newcategories) { + $showitem{'categories'} .= '
    • '.$trails[$allitems{$item}].'
    • '; + } + $showitem{'categories'} .= '
    '; + } + 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').'
      '); + foreach my $item (@changes) { + $r->print('
    • '.&mt('[_1] now set to [_2]',$desc{$item},$showitem{$item}).'
    • '); + } + $r->print('

    '); + } + } + if (@nochanges > 0) { + $r->print(&mt('The following were unchanged').'
      '); + foreach my $item (@nochanges) { + $r->print('
    • '.&mt('[_1] still set to [_2]',$desc{$item},$showitem{$item}).'
    • '); + } + $r->print('
    '); + } + } + } else { + $r->print(&mt('Category settings for courses in this domain should be modified in course context (via "Set Course Environment").').'
    '); + } + $r->print('
    '."\n". + ''. + $lt{'back'}.''); + $r->print(&hidden_form_elements().''); + return; +} + sub print_header { my ($r,$cdesc,$javascript_validations) = @_; my $phase = "start"; @@ -788,8 +999,14 @@ function verify_quota(formname) { 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"; @@ -807,31 +1024,36 @@ sub print_footer { sub check_course { my ($r,$dom,$domdesc) = @_; my ($ok_course,$description,$instcode,$owner); - if (defined($env{'form.pickedcourse'})) { - my ($cdom,$cnum) = split(/_/,$env{'form.pickedcourse'}); - if ($cdom eq $dom) { - my %courseIDs = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.', - $cnum,undef,undef,'.'); - if (keys(%courseIDs) > 0) { - $ok_course = 'ok'; - my ($description,$instcode,$owner); - if (ref($courseIDs{$cdom.'_'.$cnum}) eq 'HASH') { - $description = $courseIDs{$cdom.'_'.$cnum}{'description'}; - $instcode = $courseIDs{$cdom.'_'.$cnum}{'inst_code'}; - $owner = $courseIDs{$cdom.'_'.$cnum}{'owner'}; - } else { - ($description,$instcode,$owner) = - split(/:/,$courseIDs{$cdom.'_'.$cnum}); - } - $description = &unescape($description); - $instcode = &unescape($instcode); - if ($instcode) { - $description .= " ($instcode)"; - } + my %args = ( + one_time => 1, + ); + my %coursehash = + &Apache::lonnet::coursedescription($env{'form.pickedcourse'},\%args); + my $cnum = $coursehash{'num'}; + my $cdom = $coursehash{'domain'}; + if ($cdom eq $dom) { + my $description; + my %courseIDs = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.', + $cnum,undef,undef,'.'); + if (keys(%courseIDs) > 0) { + $ok_course = 'ok'; + my ($instcode,$owner); + if (ref($courseIDs{$cdom.'_'.$cnum}) eq 'HASH') { + $description = $courseIDs{$cdom.'_'.$cnum}{'description'}; + $instcode = $courseIDs{$cdom.'_'.$cnum}{'inst_code'}; + $owner = $courseIDs{$cdom.'_'.$cnum}{'owner'}; + } else { + ($description,$instcode,$owner) = + split(/:/,$courseIDs{$cdom.'_'.$cnum}); } + $description = &unescape($description); + $instcode = &unescape($instcode); + if ($instcode) { + $description .= " ($instcode)"; + } + return ($ok_course,$description); } } - return ($ok_course,$description); } sub course_settings_descrip { @@ -856,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". + ''; return $hidden_elements; } @@ -877,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 '') { @@ -899,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')", @@ -933,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 {