--- loncom/interface/courseprefs.pm 2011/05/24 04:56:45 1.28.2.9 +++ loncom/interface/courseprefs.pm 2020/10/29 17:14:23 1.90 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set configuration settings for a course # -# $Id: courseprefs.pm,v 1.28.2.9 2011/05/24 04:56:45 raeburn Exp $ +# $Id: courseprefs.pm,v 1.90 2020/10/29 17:14:23 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -137,7 +137,7 @@ whether Domain coordinators who are curr advanced course user .db file for a course are to be hidden (e.g., in syllabus, or from course user lists). -Inputs: $cdom,$item,$settings,$crstype +Inputs: $cdom,$item,$settings,$crstype,$noedit where $cdom is course domain, item is nothideprivileged, $settings is HASH ref of the current values for nothideprivileged, $crstype is course type (Course or Community). @@ -215,9 +215,15 @@ use Apache::lonnet; use Apache::loncommon(); use Apache::lonhtmlcommon(); use Apache::lonconfigsettings; +use Apache::lonrelrequtils; +use Apache::lonparmset; +use Apache::courseclassifier; use Apache::lonlocal; use LONCAPA qw(:DEFAULT :match); +my $registered_cleanup; +my $modified_courses; + sub handler { my $r=shift; if ($r->header_only) { @@ -227,11 +233,11 @@ sub handler { } my $context = 'course'; my $cid = $env{'request.course.id'}; - my ($cnum,$cdom) = &get_course($cid); + my ($cnum,$cdom,$chome) = &get_course($cid); my $crstype = &Apache::loncommon::course_type(); - my $parm_permission = &Apache::lonnet::allowed('opa',$cid); + my ($parm_permission,$allowed) = &get_permission($cid); my $navmap = Apache::lonnavmaps::navmap->new(); - if ($parm_permission && $navmap) { + if ($allowed && $navmap) { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; } else { @@ -256,6 +262,9 @@ sub handler { return HTTP_NOT_ACCEPTABLE; } + $registered_cleanup=0; + @{$modified_courses}=(); + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['phase','actions','origin']); &Apache::lonhtmlcommon::clear_breadcrumbs(); @@ -267,10 +276,11 @@ sub handler { my %lt; if ($crstype eq 'Community') { %lt = ( - conf => 'Community Configuration', - edit => 'Edit Community Configuration', + conf => 'Community Settings', + edit => 'Edit Community Settings', gens => 'General community settings', idnu => 'Community ID or number', + unco => 'Unique code', desc => 'Community Description', ownr => 'Community Owner', cown => 'Community Co-owners', @@ -286,19 +296,21 @@ sub handler { defd => 'Default dates for member access', stuv => 'Member-viewable membership list options', stul => 'Member agreement needed to be listed', - clas => 'Membership and Facilitator Listing', - priv => 'Privileged users (Domain Coordinators) in facilitator listing', + clas => 'Membership and facilitator listing', + prus => 'Privileged users (Domain Coordinators) in facilitator listing', defc => 'Default Community Spreadsheet', defs => 'Default User Spreadsheet', seme => 'Send message to member when clicking Done on Tasks' ); } else { %lt = ( - conf => 'Course Configuration', - edit => 'Edit Course Configuration', + conf => 'Course Settings', + edit => 'Edit Course Settings', gens => 'General course settings', idnu => 'Course ID or number', + unco => 'Unique code', desc => 'Course Description', + cred => 'Student credits', ownr => 'Course Owner', cown => 'Course Co-owners', catg => 'Categorize course', @@ -313,8 +325,9 @@ sub handler { defd => 'Default dates for student access', stuv => 'Student-viewable classlist options', stul => 'Student agreement needed to be listed', - clas => 'Classlists and Staff Listing', - priv => 'Privileged users (Domain Coordinators) in staff listing', + clas => 'Classlists and staff listing', + prus => 'Privileged users (Domain Coordinators) in staff listing', + prdo => "Domains to check for privileged users (besides course's domain)", defc => 'Default Course Spreadsheet', defs => 'Default Student Spreadsheet', seme => 'Send message to student when clicking Done on Tasks', @@ -331,15 +344,22 @@ sub handler { $phase = $env{'form.phase'}; } - if ($phase eq 'categorizecourse') { + if (($phase eq 'categorizecourse') && ($parm_permission->{'categorizecourse'})) { &assign_course_categories($r,$crstype); return OK; } - if ($phase eq 'releaseinfo') { + if (($phase eq 'releaseinfo') && ($parm_permission->{'releaseinfo'})) { my $loncaparev = $env{'course.'.$cid.'.internal.releaserequired'}; - if ($loncaparev) { - &display_loncaparev_constraints($r,$navmap,$loncaparev,$crstype); + if ($loncaparev) { + if (&display_loncaparev_constraints($r,$navmap,$loncaparev,$crstype)) { + push(@{$modified_courses},[$cdom,$cnum,$chome,$crstype]); + unless ($registered_cleanup) { + my $handlers = $r->get_handlers('PerlCleanupHandler'); + $r->set_handlers('PerlCleanupHandler' => [\&update_releasereq,@{$handlers}]); + $registered_cleanup=1; + } + } return OK; } } @@ -347,36 +367,35 @@ sub handler { my %values=&Apache::lonnet::dump('environment',$cdom,$cnum); my @prefs_order = ('courseinfo','localization','feedback','discussion', 'classlists','appearance','grading','printouts', - 'spreadsheet','bridgetasks','other'); + 'spreadsheet','bridgetasks','lti','other'); my %prefs = ( 'courseinfo' => { text => $lt{'gens'}, - help => 'Course_Environment', - header => [{col1 => 'Setting', - col2 => 'Value'}], + help => 'Course_Prefs_General', ordered => ['owner','co-owners','loncaparev','description', - 'courseid','categories','hidefromcat', - 'externalsyllabus','cloners','url','rolenames'], + 'clonedfrom','courseid','uniquecode','categories', + 'hidefromcat','syllabus','cloners','url', + 'rolenames'], itemtext => { 'owner' => $lt{'ownr'}, 'co-owners' => $lt{'cown'}, 'description' => $lt{'desc'}, 'courseid' => $lt{'idnu'}, + 'uniquecode' => $lt{'unco'}, 'categories' => $lt{'catg'}, 'hidefromcat' => $lt{'excc'}, 'cloners' => $lt{'clon'}, - 'externalsyllabus' => 'URL of Syllabus', + 'syllabus' => 'Syllabus status', 'url' => 'Top Level Map', 'rolenames' => $lt{'rept'}, 'loncaparev' => $lt{'lcrv'}, + 'clonedfrom' => 'Cloned from', }, }, 'localization' => - { text => 'Language and Time Localization', - help => 'Course_Environment', - header => [{col1 => 'Setting', - col2 => 'Value',}], + { text => 'Language and time localization', + help => 'Course_Prefs_Language', ordered => ['languages','timezone','datelocale'], itemtext => { languages => 'Languages used', @@ -386,11 +405,9 @@ sub handler { }, 'feedback' => { text => 'Feedback messages', - help => 'Course_Environment', + help => 'Course_Prefs_Feedback', header => [{col1 => 'Questions about:', - col2 => 'Recipients'}, - {col1 => 'Questions about:', - col2 => 'Custom Text'}], + col2 => 'Recipients'}], ordered => ['question.email','comment.email','policy.email'], itemtext => { 'question.email' => 'Resource Content', @@ -400,23 +417,28 @@ sub handler { }, 'discussion' => { text => 'Discussion and Chat', - help => 'Course_Environment', + help => 'Course_Prefs_Discussions', ordered => ['pch.roles.denied','pch.users.denied', + 'pac.roles.denied','pac.users.denied', 'plc.roles.denied','plc.users.denied', 'allow_limited_html_in_feedback', - 'allow_discussion_post_editing'], + 'allow_discussion_post_editing', + 'discussion_post_fonts'], itemtext => { 'pch.roles.denied' => 'No Resource Discussion', 'pch.users.denied' => 'No Resource Discussion', 'plc.roles.denied' => 'No Chat room use', 'plc.users.denied' => 'No Chat room use', + 'pac.roles.denied' => 'No Anonymous Resource Discussion', + 'pac.users.denied' => 'No Anonymous Resource Discussion', allow_limited_html_in_feedback => 'Allow limited HTML in discussion', allow_discussion_post_editing => 'Users can edit/delete own discussion posts', + discussion_post_fonts => 'Discussion post fonts based on likes/unlikes', }, }, 'classlists' => { text => $lt{'clas'}, - help => 'Course_Environment', + help => 'Course_Prefs_Classlists', header => [{col1 => 'Type', col2 => $lt{'defd'}}, {col1 => 'Setting', @@ -425,38 +447,40 @@ sub handler { col2 => $lt{'stuv'}}], ordered => ['default_enrollment_start_date', 'default_enrollment_end_date', - 'nothideprivileged','student_classlist_view', + 'defaultcredits', + 'nothideprivileged','checkforpriv', + 'student_classlist_view', 'student_classlist_opt_in','student_classlist_portfiles'], itemtext => { default_enrollment_start_date => 'Start date', default_enrollment_end_date => 'End date', - nothideprivileged => $lt{'priv'}, + nothideprivileged => $lt{'prus'}, + checkforpriv => $lt{'prdo'}, student_classlist_view => $lt{'stuv'}, student_classlist_opt_in => $lt{'stul'}, student_classlist_portfiles => 'Include link to accessible portfolio files', + defaultcredits => $lt{'cred'}, }, }, 'appearance' => { text => 'Display of resources ', - help => 'Course_Environment', - header => [{col1 => 'Setting', - col2 => 'Value',}], + help => 'Course_Prefs_Display', ordered => ['default_xml_style','pageseparators', 'disable_receipt_display','texengine', - 'tthoptions'], + 'tthoptions','uselcmath','usejsme'], itemtext => { default_xml_style => 'Default XML style file', pageseparators => 'Visibly Separate Items on Pages', disable_receipt_display => 'Disable display of problem receipts', texengine => 'Force use of a specific math rendering engine', tthoptions => 'Default set of options to pass to tth/m when converting TeX', + uselcmath => 'Student formula entry uses inline preview, not DragMath pop-up', + usejsme => 'Molecule editor uses JSME (HTML5) in place of JME (Java)', }, }, 'grading' => { text => 'Grading', - help => 'Course_Environment', - header => [{col1 => 'Setting', - col2 => 'Value',}], + help => 'Course_Prefs_Grading', ordered => ['grading','rndseed', 'receiptalg','disablesigfigs'], itemtext => { @@ -469,26 +493,22 @@ sub handler { }, 'printouts' => { text => 'Printout generation', - help => 'Course_Environment', - header => [{col1 => 'Setting', - col2 => 'Value',}], + help => 'Course_Prefs_Printouts', ordered => ['problem_stream_switch','suppress_tries', 'default_paper_size','print_header_format', - 'disableexampointprint'], + 'disableexampointprint','canuse_pdfforms'], itemtext => { problem_stream_switch => 'Allow problems to be split over pages', suppress_tries => 'Suppress number of tries in printing', default_paper_size => 'Default paper type', print_header_format => 'Print header format', - disableexampointprint => 'Disable automatically printing point values on exams', + disableexampointprint => 'Disable automatically printing point values on bubblesheet exams', canuse_pdfforms => 'Users can print problems as PDF forms and upload later for grading', }, }, 'spreadsheet' => { text => 'Spreadsheets', - help => 'Course_Environment', - header => [{col1 => 'Setting', - col2 => 'Value'}], + help => 'Course_Prefs_Spreadsheet', ordered => ['spreadsheet_default_classcalc', 'spreadsheet_default_studentcalc', 'spreadsheet_default_assesscalc','hideemptyrows'], @@ -501,9 +521,7 @@ sub handler { }, 'bridgetasks' => { text => 'Bridge tasks', - help => 'Course_Environment', - header => [{col1 => 'Setting', - col2 => 'Value'}], + help => 'Course_Prefs_Bridgetasks', ordered => ['task_messages','task_grading', 'suppress_embed_prompt'], itemtext => { @@ -512,31 +530,72 @@ sub handler { suppress_embed_prompt => 'Hide upload references prompt if uploading file to portfolio', }, }, + 'lti' => + { + text => 'LTI provider settings', + help => 'Course_Prefs_LTIProvider', + ordered => ['lti.override','lti.topmenu','lti.inlinemenu','lti.lcmenu'], + itemtext => { + 'lti.override' => 'Override domain defaults', + 'lti.topmenu' => 'Display LON-CAPA page header', + 'lti.inlinemenu' => 'Display LON-CAPA inline menu', + 'lti.lcmenu' => 'Menu items', + }, + }, 'other' => { text => 'Other settings', - help => 'Course_Environment', + help => 'Course_Prefs_Other', header => [ {col1 => 'Item', col2 => 'Value', }], }, ); - if ($phase eq 'process') { + if (($phase eq 'process') && ($parm_permission->{'process'})) { my @allitems = &get_allitems(%prefs); &Apache::lonconfigsettings::make_changes($r,$cdom,$phase,$context, \@prefs_order,\%prefs,\%values, - $cnum,undef,\@allitems); - } elsif ($phase eq 'display') { - my $jscript = &get_jscript($cid,$cdom,$phase,$crstype); + $cnum,undef,\@allitems, + 'coursepref',$parm_permission); + } elsif (($phase eq 'display') && ($parm_permission->{'display'})) { + my $jscript = &get_jscript($cid,$cdom,$phase,$crstype,\%values); my @allitems = &get_allitems(%prefs); &Apache::lonconfigsettings::display_settings($r,$cdom,$phase,$context, - \@prefs_order,\%prefs,\%values,undef,$jscript,\@allitems,$crstype); + \@prefs_order,\%prefs,\%values,undef,$jscript,\@allitems,$crstype, + 'coursepref',$parm_permission); } else { &Apache::lonconfigsettings::display_choices($r,$phase,$context, - \@prefs_order,\%prefs); + \@prefs_order,\%prefs, + 'coursepref',$parm_permission); } return OK; } +sub get_permission { + my ($cid) = @_; + my %permission; + my $allowed = 0; + return (\%permission,$allowed) unless ($cid); + if (&Apache::lonnet::allowed('opa',$cid)) { + %permission= ( + 'pickactions' => 1, + 'categorizecourse' => 1, + 'releaseinfo' => 1, + 'process' => 1, + 'display' => 1, + ); + } elsif (&Apache::lonnet::allowed('vpa',$env{'request.course.id'})) { + %permission = ( + 'pickactions' => 1, + 'releaseinfo' => 1, + 'display' => 1, + ); + } + foreach my $perm (values(%permission)) { + if ($perm) { $allowed=1; last; } + } + return (\%permission,$allowed); +} + sub get_allitems { my (%prefs) = @_; my @allitems; @@ -554,50 +613,73 @@ sub get_allitems { } sub print_config_box { - my ($r,$cdom,$phase,$action,$item,$settings,$allitems,$crstype) = @_; + my ($r,$cdom,$phase,$action,$item,$settings,$allitems,$crstype,$parm_permission) = @_; my $ordered = $item->{'ordered'}; my $itemtext = $item->{'itemtext'}; + my $noedit; + if (ref($parm_permission) eq 'HASH') { + unless ($parm_permission->{'process'}) { + $noedit = 1; + } + } my $rowtotal = 0; my $output = '
'. - &mt($item->{text}).' '. - &Apache::loncommon::help_open_topic($item->{'help'}).' | '."\n". - '|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
-
+ |
|
@@ -605,14 +687,14 @@ sub print_config_box {
|
'; + } + } + } + } elsif ($canclone eq 'domain') { + $clonedefaults = &mt('Default is for any course requester in [_1] domain to be able to clone.', + ''.$cdom.'').' '; + $currcanclone = 'domain'; + } + if ($clonedefaults) { + if ($settings->{'cloners'} ne '') { + $clonedefaults .= ' '.&mt('Default does [_1]not[_2] currently apply because values have been set in the course.','',''); + } else { + $clonedefaults .= &mt('Default is disregarded if [_1]any[_2] values are set here in the course.','',''); + } + $clonedefaults = ' '.$clonedefaults; + } + } if (!defined($categoriesform)) { $categoriesform = &mt('No categories defined in this domain.'); } - my ($can_toggle_cat,$can_categorize) = &can_modify_catsettings($cdom,$crstype); + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; my $replace; if ($crstype eq 'Community') { @@ -1707,21 +2139,28 @@ sub print_courseinfo { } else { $replace = &mt('To replace the standard title for a course role, enter a title, otherwise leave blank'); } + my ($editmap,$editsyllabus); + unless ($noedit) { + $editmap = (' 'x2). + '". + &mt('Select Map').' '. + &mt('Modification may make assessment data inaccessible!'). + ''; + $editsyllabus = &mt('[_1]Edit[_2]','', + ''); + } my %items = ( 'url' => { - text => ''.&mt($itemtext->{'url'}).''.(' 'x2). - '". - &mt('Select Map').' '. - &mt('Modification may make assessment data inaccessible!'). - '', + text => ''.&mt($itemtext->{'url'}).''.$editmap, input => 'textbox', - size => '40', + size => '55', + advanced => 1 }, 'description' => { text => ''.&mt($itemtext->{'description'}).'', input => 'textbox', - size => '25', + size => '55', }, 'owner' => { text => ''.&mt($itemtext->{'owner'}).'', @@ -1729,29 +2168,36 @@ sub print_courseinfo { 'co-owners' => { text => ''.&mt($itemtext->{'co-owners'}).'', }, + 'clonedfrom' => { + text => ''.&mt($itemtext->{'clonedfrom'}).'', + }, 'courseid' => { text => ''.&mt($itemtext->{'courseid'}).' '.'('. &mt('internal, optional').')', input => 'textbox', size => '25', }, + 'uniquecode' => { + text => ''.&mt($itemtext->{'uniquecode'}).'', + }, 'cloners' => { text => ''.&mt($itemtext->{'cloners'}).' '. - &mt('Owner and Coordinators included automatically'), + &mt('Owner and Coordinators included automatically'). + $clonedefaults, input => 'textbox', - size => '40', + size => '40' }, 'rolenames' => { text => ''.&mt($itemtext->{'rolenames'}).' '. '('.$replace.')', input => 'textbox', size => '20', + advanced => 1 }, - 'externalsyllabus' => { - text => ''.&mt($itemtext->{'externalsyllabus'}).' ('. - &mt('not using syllabus template)'), - input => 'textbox', - size => '40', + 'syllabus' => { + text => ''.&mt($itemtext->{'syllabus'}).' '. + &mt('(Syllabus type in use)').(' ' x2). + $editsyllabus, }, 'hidefromcat' => { text => ''.&mt($itemtext->{'hidefromcat'}).' '. @@ -1767,23 +2213,37 @@ sub print_courseinfo { 'loncaparev' => { text => ''.&mt($itemtext->{'loncaparev'}).'', }, + 'defaultcredits' => { + text => ''.&mt($itemtext->{'defaultcredits'}).'', + }, ); my $datatable; my $count = 0; foreach my $item (@{$ordered}) { + my $colspan; if ($item eq 'hidefromcat') { next if (!$can_toggle_cat); } elsif ($item eq 'categories') { next if (!$can_categorize); + } elsif ($item eq 'uniquecode') { + next if (!$env{'course.'.$env{'request.course.id'}.'.internal.uniquecode'}); + } + unless (($item eq 'cloners') || ($item eq 'rolenames')) { + $colspan = 2; } $count ++; - $datatable .= &item_table_row_start($items{$item}{text},$count); + if (exists $items{$item}{advanced} && $items{$item}{advanced} == 1) { + $datatable .= &item_table_row_start($items{$item}{text},$count,"advanced",$colspan); + } else { + $datatable .= &item_table_row_start($items{$item}{text},$count,undef,$colspan); + } if ($items{$item}{input} eq 'radio') { - $datatable .= &yesno_radio($item,$settings); + $datatable .= &yesno_radio($item,$settings,undef,undef,undef,$noedit); } elsif ($item eq 'cloners') { my $includeempty = 1; my $num = 0; - $datatable .= &Apache::loncommon::start_data_table(). + $datatable .= ' '.
+ &Apache::loncommon::start_data_table().
&Apache::loncommon::start_data_table_row().
' | '.
- (' 'x2).''.&mt('Yes').''.
+ (' 'x2).' | '.
+ "'cloners_all'".');"'.$disabled.' />'.&mt('No').''.
&Apache::loncommon::end_data_table_row().
&Apache::loncommon::end_data_table().
- '
'. ''. &Apache::loncommon::end_data_table_row(); $num ++; @@ -1850,23 +2317,56 @@ sub print_courseinfo { ' '.
$add_domtitle.' | '.&Apache::loncommon::end_data_table_row().
&Apache::loncommon::end_data_table().
- ''. &Apache::loncommon::select_dom_form('','cloners_newdom', - $includeempty). + $includeempty,undef,undef, + undef,undef,$noedit). ''. '
'.
&mt('Specific users').' ('.
&mt('user:domain,user:domain').') | '.&Apache::loncommon::end_data_table_row().
&Apache::loncommon::end_data_table();
+ if (@code_order > 0) {
+ my (%cat_items,@codetitles,%cat_titles,%cat_order);
+ my ($jscript,$totcodes,$numtitles,$lasttitle) =
+ &Apache::courseclassifier::instcode_selectors_data($cdom,'display',
+ \%cat_items,\@codetitles,
+ \%cat_titles,\%cat_order);
+ my $showncodes = 'off';
+ my $checkedoff = ' checked="checked"';
+ my $checkedon = '';
+ if ($cloner_instcode) {
+ $checkedon = $checkedoff;
+ $checkedoff = '';
+ $showncodes = 'on';
+ }
+ $datatable .= ''. &Apache::lonhtmlcommon::textbox($item,$cloners_str, - $items{$item}{'size'}). + $items{$item}{'size'},$disabled). '
'.
+ &mt('Cloning by official course(s) based on course category').(' 'x2).
+ ''.
+ (' ').
+ ''.
+ &Apache::courseclassifier::build_instcode_selectors($numtitles,
+ $lasttitle,\%cat_items,\@codetitles,\%cat_titles,\%cat_order,
+ $showncodes,'LC_cloners_instcodes','LC_cloners_instcode',$noedit).
+ ' | '.&Apache::loncommon::end_data_table_row().
+ &Apache::loncommon::end_data_table();
+ }
} elsif ($item eq 'rolenames') {
- $datatable .= &Apache::loncommon::start_data_table();
+ $datatable .= ''.
+ &Apache::loncommon::start_data_table();
my @roles;
if ($crstype eq 'Community') {
@roles = ('co');
@@ -1881,12 +2381,17 @@ sub print_courseinfo {
' | '.
&Apache::lonhtmlcommon::textbox('rolenames_'.$role,
$settings->{$role.'.plaintext'},
- $items{$item}{size}).' | '.
+ $items{$item}{size},$disabled).''.
&Apache::loncommon::end_data_table_row();
}
$datatable .= &Apache::loncommon::end_data_table().'';
} elsif ($item eq 'categories') {
- my $launcher = 'onFocus="this.blur();javascript:catsbrowser();";';
+ my $launcher;
+ if ($noedit) {
+ $launcher = $disabled;
+ } else {
+ $launcher = 'onfocus="this.blur();javascript:catsbrowser();"';
+ }
$datatable .= ''.
&Apache::lonhtmlcommon::textbox($item.'_display',$settings->{$item},
$items{$item}{size},$launcher);
@@ -1901,8 +2406,22 @@ sub print_courseinfo {
$owner = &mt('None specified');
}
$datatable .= $owner;
+ } elsif ($item eq 'clonedfrom') {
+ my $clonesrc = $env{'course.'.$env{'request.course.id'}.'.clonedfrom'};
+ my $clonedfrom = &mt('None');
+ if ($clonesrc =~ m{/$match_domain/$match_courseid}) {
+ my %clonesrcinfo = &Apache::lonnet::coursedescription($clonesrc);
+ if ($clonesrcinfo{'description'}) {
+ $clonedfrom = $clonesrcinfo{'description'}.' '.($clonesrc);
+ }
+ }
+ $datatable .= $clonedfrom;
+ } elsif ($item eq 'uniquecode') {
+ my $code = $env{'course.'.$env{'request.course.id'}.'.internal.uniquecode'};
+ if ($code) {
+ $datatable .= $code;
+ }
} elsif ($item eq 'co-owners') {
- my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
my $coowners = $env{'course.'.$env{'request.course.id'}.'.internal.co-owners'};
my @currcoown;
if ($coowners) {
@@ -1912,15 +2431,45 @@ sub print_courseinfo {
if (($crstype eq 'Course') && ($env{'course.'.$env{'request.course.id'}.'.internal.coursecode'}) && ($autocoowner)) {
$datatable .= &show_autocoowners(@currcoown);
} else {
- $datatable .= &coowner_invitations($cnum,$cdom,@currcoown);
+ $datatable .= &coowner_invitations($cnum,$cdom,\@currcoown,$noedit);
}
} else {
if (($crstype eq 'Course') && ($env{'course.'.$env{'request.course.id'}.'.internal.coursecode'}) && ($autocoowner)) {
$datatable .= &show_autocoowners(@currcoown);
} else {
- $datatable .= &manage_coownership($cnum,$cdom,@currcoown);
+ $datatable .= &manage_coownership($cnum,$cdom,\@currcoown,$noedit);
+ }
+ }
+ } elsif ($item eq 'syllabus') {
+ my $external = $env{'course.'.$env{'request.course.id'}.'.externalsyllabus'};
+ my $uploaded = $env{'course.'.$env{'request.course.id'}.'.uploadedsyllabus'};
+ my $minimal = $env{'course.'.$env{'request.course.id'}.'.minimalsyllabus'};
+ if (($minimal =~/\w/) || ($uploaded =~/\w/)) {
+ if ($minimal =~/\w/) {
+ if ($external =~ m{\Q$minimal\E$}) {
+ undef($external);
+ }
+ } elsif ($uploaded =~/\w/) {
+ if ($external =~ m{\Q$uploaded\E$}) {
+ undef($external);
+ }
}
+ } elsif ($external!~/\w/) {
+ undef($external);
+ }
+ if ($external) {
+ $datatable .= &mt('External URL');
+ } elsif ($minimal) {
+ $datatable .= &mt('Minimal template');
+ } elsif ($uploaded) {
+ $datatable .= &mt('Uploaded file');
+ } else {
+ $datatable .= &mt('Standard template');
}
+ $datatable .= (' ' x 2).
+ &mt('[_1]View[_2]',
+ '',
+ '');
} elsif ($item eq 'loncaparev') {
my $loncaparev = $env{'course.'.$env{'request.course.id'}.'.internal.releaserequired'};
my $showreqd;
@@ -1932,7 +2481,7 @@ sub print_courseinfo {
}
$datatable .= $showreqd;
} else {
- $datatable .= &Apache::lonhtmlcommon::textbox($item,$settings->{$item},$items{$item}{size});
+ $datatable .= &Apache::lonhtmlcommon::textbox($item,$settings->{$item},$items{$item}{size},$disabled);
}
$datatable .= &item_table_row_end();
}
@@ -1941,19 +2490,24 @@ sub print_courseinfo {
}
sub new_cloners_dom_row {
- my ($newdom,$num) = @_;
- my $output;
+ my ($newdom,$num,$default) = @_;
+ my ($output,$checkedon,$checkedoff);
if ($newdom ne '') {
+ if ($num eq $default) {
+ $checkedon = 'checked="checked" ';
+ } else {
+ $checkedoff = 'checked="checked" ';
+ }
$output .= &Apache::loncommon::start_data_table_row().
''.
&mt('Any user in domain:').' '.$newdom.''.
(' 'x2).''.(' 'x2).
'
@@ -2090,6 +2645,7 @@ ENDSCRIPT
sub display_loncaparev_constraints {
my ($r,$navmap,$loncaparev,$crstype) = @_;
+ my ($reqdmajor,$reqdminor);
my $cid = $env{'request.course.id'};
my $cdom = $env{'course.'.$cid.'.domain'};
my $cnum = $env{'course.'.$cid.'.num'};
@@ -2099,103 +2655,167 @@ sub display_loncaparev_constraints {
'section/group' => 'section/group',
'user' => 'user',
);
- my (%checkparms,%checkresponsetypes,%checkcrstypes,%anonsurvey,%randomizetry);
- &Apache::loncommon::build_release_hashes(\%checkparms,\%checkresponsetypes,
- \%checkcrstypes,\%anonsurvey,\%randomizetry);
- if (defined($checkcrstypes{$crstype})) {
+ &Apache::lonrelrequtils::init_global_hashes();
+ if (defined($Apache::lonrelrequtils::checkcrstypes{$crstype})) {
+ ($reqdmajor,$reqdminor) = split(/\./,$Apache::lonrelrequtils::checkcrstypes{$crstype});
$output .= ' | '.&mt('Course type: [_1] requires [_2] or newer',$crstype, - $checkcrstypes{$crstype}).''; + $Apache::lonrelrequtils::checkcrstypes{$crstype}).''; } my (%fromparam,%rowspan,%bymap,%byresource,@scopeorder,%toshow,%allmaps, - %byresponsetype,%bysubmission); + %byresponsetype,%bysubmission,%fromblocks,%bycrsrestype); @scopeorder = ('all','section/group','user'); + my $now = time; my $resourcedata = &Apache::lonparmset::readdata($cnum,$cdom); if (ref($resourcedata) eq 'HASH') { foreach my $key (keys(%{$resourcedata})) { - foreach my $item (keys(%checkparms)) { + my %found; + foreach my $item (keys(%Apache::lonrelrequtils::checkparms)) { if ($key =~ /(\Q$item\E)$/) { - if (ref($checkparms{$item}) eq 'ARRAY') { - my $value = $resourcedata->{$key}; - my ($middle,$scope,$which,$level,$map,$resource); - if (grep(/^\Q$value\E$/,@{$checkparms{$item}})) { - my $stdtype = &Apache::lonparmset::standard_parameter_types($item); - my $stdname = &Apache::lonparmset::standard_parameter_names($item); - my $valname = &get_param_description($stdtype,$value); - my $rev = $Apache::lonnet::needsrelease{'parameter:'.$item.':'.$value}; - my $start = $cid.'.'; - if ($key =~ /^\Q$start\E(\[useropt\:($match_username\:$match_domain)\]\.)/) { - $middle = $1; - $which = $2; - $scope = 'user'; - } elsif ($key =~ /^\Q$start\E(\[(\w+)\]\.)/) { - $middle = $1; - $which = $2; - $scope = 'section/group'; - } else { - $scope = 'all'; - } - my $what="$stdname=$valname"; - if ($key =~ /^\Q$start$middle\E\w+\.\Q$item\E$/) { - $level = 'general'; - if ($scope eq 'all') { - if (ref($fromparam{$rev}{$scope}) eq 'ARRAY') { - unless(grep(/^\Q$what\E$/,@{$fromparam{$rev}{$scope}})) { - push(@{$fromparam{$rev}{$scope}},$what); - } - } else { - push(@{$fromparam{$rev}{$scope}},$what); - } - } else { - if (ref($fromparam{$rev}{$scope}{$which}) eq 'ARRAY') { - unless (grep(/^\Q$what\E$/,@{$fromparam{$rev}{$scope}{$which}})) { - push(@{$fromparam{$rev}{$scope}{$which}},$what); - } - } else { - push(@{$fromparam{$rev}{$scope}{$which}},$what); - } - } - $rowspan{$rev} ++; - } elsif ($key =~ /^\Q$start$middle\E(.+)___\(all\).\w+\.\Q$item\E$/) { - $level = 'folder'; - $map = $1; - if ($scope eq 'all') { - if (ref($bymap{$map}{$rev}{$scope}) eq 'ARRAY') { - unless(grep(/^\Q$what\E$/,@{$bymap{$map}{$rev}{$scope}})) { - push(@{$bymap{$map}{$rev}{$scope}},$what); - } - } else { - push(@{$bymap{$map}{$rev}{$scope}},$what); - } - } else { - if (ref($bymap{$map}{$rev}{$scope}{$which}) eq 'ARRAY') { - unless(grep(/^\Q$what\E$/,@{$bymap{$map}{$rev}{$scope}{$which}})) { - push(@{$bymap{$map}{$rev}{$scope}{$which}},$what); - } - } else { - push(@{$bymap{$map}{$rev}{$scope}{$which}},$what); - } - } - } elsif ($key =~ /^\Q$start$middle\E(.+)\.\w+\.\Q$item\E$/) { - $level = 'resource'; - $resource = $1; - if ($scope eq 'all') { - if (ref($byresource{$resource}{$rev}{$scope}) eq 'ARRAY') { - unless(grep(/^\Q$what\E$/,@{$byresource{$resource}{$rev}{$scope}})) { - push(@{$byresource{$resource}{$rev}{$scope}},$what); - } - } else { - push(@{$byresource{$resource}{$rev}{$scope}},$what); - } - } else { - if (ref($byresource{$resource}{$rev}{$scope}{$which}) eq 'ARRAY') { - unless (grep(/^\Q$what\E$/,@{$byresource{$resource}{$rev}{$scope}{$which}})) { - push(@{$byresource{$resource}{$rev}{$scope}{$which}},$what); - } - } else { - push(@{$byresource{$resource}{$rev}{$scope}{$which}},$what); - } - } - } + if (ref($Apache::lonrelrequtils::checkparms{$item}) eq 'ARRAY') { + my $value = $resourcedata->{$key}; + if ($item eq 'examcode') { + if (&Apache::lonnet::validCODE($value)) { + $value = 'valid'; + } else { + $value = ''; + } + } elsif ($item eq 'printstartdate') { + if ($value =~ /^\d+$/) { + if ($value > $now) { + $value = 'future'; + } + } + } elsif ($item eq 'printenddate') { + if ($value =~ /^\d+$/) { + if ($value < $now) { + $value = 'past'; + } + } + } + if (grep(/^\Q$value\E$/,@{$Apache::lonrelrequtils::checkparms{$item}})) { + my $stdtype = &Apache::lonparmset::standard_parameter_types($item); + $found{$item}{'valname'} = &get_param_description($stdtype,$value); + $found{$item}{'rev'} = $Apache::lonnet::needsrelease{'parameter:'.$item.':'.$value.'::'}; + } + } + } + } + foreach my $item (keys(%Apache::lonrelrequtils::checkparmvalsmatch)) { + if (ref($Apache::lonrelrequtils::checkparmvalsmatch{$item}) eq 'ARRAY') { + my $value = $resourcedata->{$key}; + foreach my $valuematch (@{$Apache::lonrelrequtils::checkparmvalsmatch{$item}}) { + if ($value =~ /$valuematch/) { + my $stdtype = &Apache::lonparmset::standard_parameter_types($item); + $found{$item}{'valname'} = &get_param_description($stdtype,$value,1); + $found{$item}{'rev'} = + $Apache::lonnet::needsrelease{'parameter:'.$item.'::'.$valuematch.':'}; + last; + } + } + } + } + foreach my $item (keys(%Apache::lonrelrequtils::checkparmnamesmatch)) { + my $regexp; + if ($item eq 'maplevelrecurse') { + $regexp = '\.(?:sequence|page)___\(rec\)\.'; + } + if ($regexp ne '') { + if ($key =~ /$regexp.*\.(\w+)$/) { + my $name = $1; + my $value = $resourcedata->{$key}; + if ($name eq 'type') { + last unless (($value eq 'problem') || ($value eq 'practice') || ($value eq 'exam') || + ($value eq 'survey') || ($value eq 'surveycred') || ($value eq 'anonsurvey') || + ($value eq 'anonsurveycred') || ($value eq 'randomizetry') || ($value eq 'library')); + } + my $stdtype = &Apache::lonparmset::standard_parameter_types($name); + $found{$name}{'valname'} = &get_param_description($stdtype,$value); + $found{$name}{'extra'} = &mt('Recursive into sub-folders'); + $found{$name}{'rev'} = + $Apache::lonnet::needsrelease{'parameter::::'.$item}; + } + } + } + foreach my $item (keys(%found)) { + my $stdname = &Apache::lonparmset::standard_parameter_names($item); + my $rev = $found{$item}{'rev'}; + my $valname = $found{$item}{'valname'}; + my $extra = $found{$item}{'extra'}; + my ($middle,$scope,$which,$level,$map,$resource); + my $start = $cid.'.'; + if ($key =~ /^\Q$start\E(\[useropt\:($match_username\:$match_domain)\]\.)/) { + $middle = $1; + $which = $2; + $scope = 'user'; + } elsif ($key =~ /^\Q$start\E(\[(\w+)\]\.)/) { + $middle = $1; + $which = $2; + $scope = 'section/group'; + } else { + $scope = 'all'; + } + my $what="$stdname=$valname"; + if ($extra) { + $what .= "$extra "; + } + if ($key =~ /^\Q$start$middle\E\w+\.\Q$item\E$/) { + $level = 'general'; + if ($scope eq 'all') { + if (ref($fromparam{$rev}{$scope}) eq 'ARRAY') { + unless(grep(/^\Q$what\E$/,@{$fromparam{$rev}{$scope}})) { + push(@{$fromparam{$rev}{$scope}},$what); + } + } else { + push(@{$fromparam{$rev}{$scope}},$what); + } + } else { + if (ref($fromparam{$rev}{$scope}{$which}) eq 'ARRAY') { + unless (grep(/^\Q$what\E$/,@{$fromparam{$rev}{$scope}{$which}})) { + push(@{$fromparam{$rev}{$scope}{$which}},$what); + } + } else { + push(@{$fromparam{$rev}{$scope}{$which}},$what); + } + } + $rowspan{$rev} ++; + } elsif ($key =~ /^\Q$start$middle\E(.+)___\((all|rec)\).\w+\.\Q$item\E$/) { + $level = 'folder'; + $map = $1; + if ($scope eq 'all') { + if (ref($bymap{$map}{$rev}{$scope}) eq 'ARRAY') { + unless(grep(/^\Q$what\E$/,@{$bymap{$map}{$rev}{$scope}})) { + push(@{$bymap{$map}{$rev}{$scope}},$what); + } + } else { + push(@{$bymap{$map}{$rev}{$scope}},$what); + } + } else { + if (ref($bymap{$map}{$rev}{$scope}{$which}) eq 'ARRAY') { + unless(grep(/^\Q$what\E$/,@{$bymap{$map}{$rev}{$scope}{$which}})) { + push(@{$bymap{$map}{$rev}{$scope}{$which}},$what); + } + } else { + push(@{$bymap{$map}{$rev}{$scope}{$which}},$what); + } + } + } elsif ($key =~ /^\Q$start$middle\E(.+)\.\w+\.\Q$item\E$/) { + $level = 'resource'; + $resource = $1; + if ($scope eq 'all') { + if (ref($byresource{$resource}{$rev}{$scope}) eq 'ARRAY') { + unless(grep(/^\Q$what\E$/,@{$byresource{$resource}{$rev}{$scope}})) { + push(@{$byresource{$resource}{$rev}{$scope}},$what); + } + } else { + push(@{$byresource{$resource}{$rev}{$scope}},$what); + } + } else { + if (ref($byresource{$resource}{$rev}{$scope}{$which}) eq 'ARRAY') { + unless (grep(/^\Q$what\E$/,@{$byresource{$resource}{$rev}{$scope}{$which}})) { + push(@{$byresource{$resource}{$rev}{$scope}{$which}},$what); + } + } else { + push(@{$byresource{$resource}{$rev}{$scope}{$which}},$what); } } } @@ -2209,6 +2829,9 @@ sub display_loncaparev_constraints { ' '.&mt('Extent').' | '.&mt('Setting').' | '.
&Apache::loncommon::end_data_table_header_row();
foreach my $rev (keys(%fromparam)) {
+ my ($major,$minor) = split(/\./,$rev);
+ ($reqdmajor,$reqdminor) =
+ &Apache::lonrelrequtils::update_reqd_loncaparev($major,$minor,$reqdmajor,$reqdminor);
$output .= &Apache::loncommon::start_data_table_row().
''.$rev.' | ';
my $newrow;
@@ -2239,20 +2862,96 @@ sub display_loncaparev_constraints {
}
}
+ my %comm_blocks = &Apache::lonnet::dump('comm_block',$cdom,$cnum);
+ my $now = time;
+ if (keys(%comm_blocks) > 0) {
+ foreach my $block (keys(%comm_blocks)) {
+ if ($block =~ /^firstaccess____(.+)$/) {
+ my $rev = $Apache::lonnet::needsrelease{'course:commblock:timer'};
+ if (ref($comm_blocks{$block}) eq 'HASH') {
+ push(@{$fromblocks{'timer'}{$rev}},&unescape($comm_blocks{$block}{'event'}).
+ ' '.&mt('set by [_1]',
+ &Apache::loncommon::plainname(split(/:/,$comm_blocks{$block}{'setter'}))));
+ }
+ next;
+ } elsif ($block =~ /^(\d+)____(\d+)$/) {
+ my ($start,$end) = ($1,$2);
+ next if ($end < $now);
+ }
+ if (ref($comm_blocks{$block}) eq 'HASH') {
+ if (ref($comm_blocks{$block}{'blocks'}) eq 'HASH') {
+ if (ref($comm_blocks{$block}{'blocks'}{'docs'}) eq 'HASH') {
+ if (keys(%{$comm_blocks{$block}{'blocks'}{'docs'}}) > 0) {
+ my $rev = $Apache::lonnet::needsrelease{'course:commblock:docs'};
+ push(@{$fromblocks{'docs'}{$rev}},&unescape($comm_blocks{$block}{'event'}).
+ ' '.
+ &mt('set by [_1]',
+ &Apache::loncommon::plainname(split(/:/,$comm_blocks{$block}{'setter'}))));
+ }
+ } elsif ($comm_blocks{$block}{'blocks'}{'printout'} eq 'on') {
+ my $rev = $Apache::lonnet::needsrelease{'course:commblock:printout'};
+ push(@{$fromblocks{'printout'}{$rev}},&unescape($comm_blocks{$block}{'event'}).
+ ' '.
+ &mt('set by [_1]',
+ &Apache::loncommon::plainname(split(/:/,$comm_blocks{$block}{'setter'}))));
+
+ }
+ }
+ }
+ }
+ if (keys(%fromblocks)) {
+ my %lt = (
+ docs => 'Content blocking',
+ printout => 'Printout generation',
+ timer => 'Timed quiz trigger',
+ );
+ $output .= ''.&mt('Requirements from exam blocking').''. + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + ''.&mt('Release').' | '.&mt('Setting').' | '.
+ ''.&mt('Event(s)').' | '.
+ &Apache::loncommon::end_data_table_header_row();
+ foreach my $type ('docs','printout','timer') {
+ if (ref($fromblocks{$type}) eq 'HASH') {
+ foreach my $rev (keys(%{$fromblocks{$type}})) {
+ my ($major,$minor) = split(/\./,$rev);
+ ($reqdmajor,$reqdminor) =
+ &Apache::lonrelrequtils::update_reqd_loncaparev($major,$minor,$reqdmajor,$reqdminor);
+ $output .= &Apache::loncommon::start_data_table_row().
+ ''.$rev.' | '.$lt{$type}.' | ';
+ foreach my $event (sort(@{$fromblocks{$type}{$rev}})) {
+ $output .= $event.' | '.&Apache::loncommon::end_data_table_row();
+ }
+ }
+ }
+ $output .= &Apache::loncommon::end_data_table().''; + } + $output =~ s{\Q \E$}{}; + $output .= ' '; + } + } + if (defined($navmap)) { my %anonsubms=&Apache::lonnet::dump('nohist_anonsurveys',$cdom,$cnum); - my $rev_anonsurv=$Apache::lonnet::needsrelease{'parameter:type:anonsurvey'}; + my $rev_anonsurv=$Apache::lonnet::needsrelease{'parameter:type:anonsurvey::'}; my %randtrysubms=&Apache::lonnet::dump('nohist_randomizetry',$cdom,$cnum); - my $rev_randtry=$Apache::lonnet::needsrelease{'parameter:type:randomizetry'}; + my $rev_randtry=$Apache::lonnet::needsrelease{'parameter:type:randomizetry::'}; + my $rev_exttool=$Apache::lonnet::needsrelease{'course:courserestype:exttool'}; my $stdtype=&Apache::lonparmset::standard_parameter_types('type'); my $stdname=&Apache::lonparmset::standard_parameter_names('type'); my $valanon=&get_param_description($stdtype,'anonsurvey'); my $valrandtry=&get_param_description($stdtype,'randomizetry'); - - foreach my $res ($navmap->retrieveResources(undef,sub { $_[0]->is_problem() },1,0)) { + my %checkedrev; + foreach my $res ($navmap->retrieveResources(undef,sub { $_[0]->is_problem() || $_[0]->is_tool() },1,0)) { my @parts = @{$res->parts()}; my $symb = $res->symb(); my $enclosing_map = &Apache::lonnet::declutter($res->enclosing_map_src()); + if ($res->is_tool()) { + my $rev = $rev_exttool; + $bycrsrestype{$symb}{$rev} = &mt('External Tool'); + $allmaps{$enclosing_map} = 1; + next; + } foreach my $part (@parts) { if (exists($anonsubms{$symb."\0".$part})) { my $rev = $rev_anonsurv; @@ -2265,6 +2964,13 @@ sub display_loncaparev_constraints { push(@{$bysubmission{$symb}{$rev}},$what); } $allmaps{$enclosing_map} = 1; + unless ($checkedrev{'anonsurvey'}) { + my ($major,$minor) = split(/\./,$rev); + ($reqdmajor,$reqdminor) = + &Apache::lonrelrequtils::update_reqd_loncaparev($major,$minor, + $reqdmajor,$reqdminor); + $checkedrev{'anonsurvey'} = 1; + } } if (exists($randtrysubms{$symb."\0".$part})) { my $rev = $rev_randtry; @@ -2277,12 +2983,27 @@ sub display_loncaparev_constraints { push(@{$bysubmission{$symb}{$rev}},$what); } $allmaps{$enclosing_map} = 1; + unless ($checkedrev{'randomizetry'}) { + my ($major,$minor) = split(/\./,$rev); + ($reqdmajor,$reqdminor) = + &Apache::lonrelrequtils::update_reqd_loncaparev($major,$minor, + $reqdmajor,$reqdminor); + $checkedrev{'randomizetry'} = 1; + } } } my %responses = $res->responseTypes(); foreach my $key (keys(%responses)) { - if (exists($checkresponsetypes{$key})) { - push(@{$byresponsetype{$symb}{$checkresponsetypes{$key}}},$key); + if (exists($Apache::lonrelrequtils::checkresponsetypes{$key})) { + my $rev = $Apache::lonrelrequtils::checkresponsetypes{$key}; + unless ($checkedrev{$key}) { + my ($major,$minor) = split(/\./,$rev); + ($reqdmajor,$reqdminor) = + &Apache::lonrelrequtils::update_reqd_loncaparev($major,$minor, + $reqdmajor,$reqdminor); + $checkedrev{$key} = 1; + } + push(@{$byresponsetype{$symb}{$rev}},$key); $allmaps{$enclosing_map} = 1; } } @@ -2300,9 +3021,9 @@ sub display_loncaparev_constraints { } foreach my $map (keys(%allmaps)) { my $mapres = $navmap->getResourceByUrl($map); - my $mapsymb = $mapres->symb(); - $toshow{$mapsymb} = 1; if (ref($mapres)) { + my $mapsymb = $mapres->symb(); + $toshow{$mapsymb} = 1; my $pcslist = $mapres->map_hierarchy(); if ($pcslist ne '') { foreach my $pc (split(/,/,$pcslist)) { @@ -2318,10 +3039,14 @@ sub display_loncaparev_constraints { } } } + my $suppmap = 'supplemental.sequence'; + my ($suppcount,$supptools,$errors) = (0,0,0); + ($suppcount,$supptools,$errors) = &Apache::loncommon::recurse_supplemental($cnum,$cdom, + $suppmap,$suppcount,$supptools,$errors); my $mapres_header = ' '. &mt('Requirements for specific folders or resources'). ''; - if ((keys(%toshow) > 0) || (keys(%byresource) > 0) || + if ((keys(%toshow) > 0) || (keys(%byresource) > 0) || (keys(%bysubmission) > 0) || (keys(%byresponsetype))) { $output .= $mapres_header; } @@ -2332,38 +3057,50 @@ sub display_loncaparev_constraints { $r->print($start_page.$top_header); if ($output) { $r->print($output); - if (defined($navmap)) { + if (defined($navmap) || $supptools) { &show_contents_view($r,$navmap,$cid,\%toshow,\%bymap,\%byresource,\%bysubmission, - \%byresponsetype,\@scopeorder,\%lt); + \%byresponsetype,\%bycrsrestype,\@scopeorder,\%lt,$supptools); } - $r->print(''); + $r->print(' '); } else { $r->print(' '. &mt('No version requirements from resource content or settings.'). - ' '); + ''); } $r->print(&Apache::loncommon::end_page()); + my ($currmajor,$currminor) = split(/\./,$loncaparev); + if (($currmajor != $reqdmajor) || ($currminor != $reqdminor)) { + return 1; + } return; } sub show_contents_view { my ($r,$navmap,$cid,$toshow,$bymap,$byresource,$bysubmission,$byresponsetype, - $scopeorder,$lt) = @_; - if ((keys(%{$toshow}) > 0) || (keys(%{$byresource}) > 0) || - (keys(%{$bysubmission}) > 0) || (keys(%{$byresponsetype}) > 0)) { - my $location=&Apache::loncommon::lonhttpdurl("/adm/lonIcons"); - my $whitespace = ''; - my $icon = ''; + $bycrsrestype,$scopeorder,$lt,$supptools) = @_; + my $location=&Apache::loncommon::lonhttpdurl("/adm/lonIcons"); + my $whitespace = ''; + my $showmaincontent; + if ((ref($navmap)) && + ((keys(%{$toshow}) > 0) || (keys(%{$byresource}) > 0) || + (keys(%{$bysubmission}) > 0) || (keys(%{$byresponsetype}) > 0) || + (keys(%{$bycrsrestype}) > 0))) { + $showmaincontent = 1; + } + if ($showmaincontent || $supptools) { + $r->print(&Apache::loncommon::start_data_table()); + } + if ($showmaincontent) { + my $icon = ''; my $topmap = $env{'course.'.$cid.'.url'}; - $r->print(&Apache::loncommon::start_data_table(). - &Apache::loncommon::start_data_table_header_row(). + $r->print(&Apache::loncommon::start_data_table_header_row(). ''.&mt('Location').' | '.&mt('Release').' | '.
''.&mt('Attribute/Setting').' | '.
&Apache::loncommon::end_data_table_header_row().
&Apache::loncommon::start_data_table_row().
- ' '.$icon.' '.&mt('Main Course Documents').' | ');
- &releases_by_map($r,$bymap,$topmap,$scopeorder,$lt);
- $r->print(&Apache::loncommon::end_data_table_row());
+ ' '.$icon.' '.&mt('Main Content').' | ');
+ &releases_by_map($r,$bymap,$topmap,$scopeorder,$lt);
+ $r->print(&Apache::loncommon::end_data_table_row());
my $it=$navmap->getIterator(undef,undef,undef,1,1,undef);
my $curRes;
my $depth = 0;
@@ -2401,7 +3138,7 @@ sub show_contents_view {
}
$r->print(&Apache::loncommon::start_data_table_row().
''.$indent.$icon.' '.$title.' | ');
- &releases_by_map($r,$bymap,$url,$scopeorder);
+ &releases_by_map($r,$bymap,$url,$scopeorder,$lt);
$r->print(&Apache::loncommon::end_data_table_row());
} else {
my $rowspan;
@@ -2414,6 +3151,9 @@ sub show_contents_view {
if (ref($byresponsetype->{$symb}) eq 'HASH') {
$rowspan += scalar(keys(%{$byresponsetype->{$symb}}));
}
+ if (ref($bycrsrestype->{$symb}) eq 'HASH') {
+ $rowspan += scalar(keys(%{$bycrsrestype->{$symb}}));
+ }
next if (!$rowspan);
$icon = '';
@@ -2478,19 +3218,52 @@ sub show_contents_view {
$r->print('');
}
$r->print(&Apache::loncommon::end_data_table_row());
+ $newrow = 1;
+ }
+ if (ref($bycrsrestype->{$symb}) eq 'HASH') {
+ foreach my $rev (sort(keys(%{$bycrsrestype->{$symb}}))) {
+ if ($newrow) {
+ $r->print(&Apache::loncommon::continue_data_table_row());
+ }
+ $r->print(''.$rev.' | '.$bycrsrestype->{$symb}{$rev}.' | ');
+ }
+ $r->print(&Apache::loncommon::end_data_table_row());
}
}
}
}
+ }
+ if ($supptools) {
+ my $icon = '';
+ $r->print(&Apache::loncommon::start_data_table_header_row().
+ ''.&mt('Location').' | '.&mt('Release').' | '.
+ ''.&mt('Resource Type').' | '.
+ &Apache::loncommon::end_data_table_header_row().
+ &Apache::loncommon::start_data_table_row().
+ ' '.$icon.' '.&mt('Supplemental Content').' | '.
+ ''.
+ $Apache::lonrelrequtils::exttool{'major'}.'.'.
+ $Apache::lonrelrequtils::exttool{'minor'}.
+ ' | '.&mt('[quant,_1,External Tool,External Tools]',
+ $supptools).' | '.
+ &Apache::loncommon::end_data_table_row());
+ }
+ if ($showmaincontent || $supptools) {
$r->print(&Apache::loncommon::end_data_table());
}
+ return;
}
sub releases_by_map {
my ($r,$bymap,$url,$scopeorder,$lt) = @_;
return unless ((ref($bymap) eq 'HASH') && (ref($scopeorder) eq 'ARRAY'));
+ my $newrow = 0;
if (ref($bymap->{$url}) eq 'HASH') {
foreach my $rev (sort(keys(%{$bymap->{$url}}))) {
+ if ($newrow) {
+ $r->print(&Apache::loncommon::end_data_table_row().
+ &Apache::loncommon::continue_data_table_row());
+ }
$r->print(''.$rev.' | ');
if (ref($bymap->{$url}{$rev}) eq 'HASH') {
$r->print(' | ');
+ $newrow = 1;
}
} else {
$r->print(' | ');
@@ -2520,26 +3294,93 @@ sub releases_by_map {
}
sub get_param_description {
- my ($stdtype,$value) = @_;
- my $name = $value;
- my $paramstrings = &Apache::lonparmset::standard_string_options($stdtype);
- unless (ref($paramstrings) eq 'ARRAY') {
- return $name;
+ my ($stdtype,$value,$regexp) = @_;
+ my ($name,$parammatches,$paramstrings,@possibles);
+ if ($stdtype =~ /^string/) {
+ $paramstrings = &Apache::lonparmset::standard_string_options($stdtype);
+ } elsif ($stdtype eq 'date_interval') {
+ $paramstrings = &Apache::lonparmset::standard_interval_options($stdtype);
+ }
+ if ($regexp) {
+ if ($stdtype =~ /^string/) {
+ $parammatches = &Apache::lonparmset::standard_string_matches($stdtype);
+ } elsif ($stdtype eq 'date_interval') {
+ $parammatches = &Apache::lonparmset::standard_interval_matches($stdtype);
+ }
+ if (ref($parammatches) eq 'ARRAY') {
+ @possibles = @{$parammatches};
+ } else {
+ undef($regexp);
+ $name = $value;
+ }
+ }
+ unless ($regexp) {
+ $name = $value;
+ if (ref($paramstrings) eq 'ARRAY') {
+ @possibles = @{$paramstrings};
+ } else {
+ if (($stdtype eq 'date_start') || ($stdtype eq 'date_end')) {
+ if ($name == 0) {
+ $name = &mt('Never');
+ } elsif (($name ne '') && ($name !~ /\D/)) {
+ $name = &Apache::lonlocal::locallocaltime($name);
+ }
+ }
+ return $name;
+ }
}
- foreach my $possibilities (@{$paramstrings}) {
+ foreach my $possibilities (@possibles) {
next unless (ref($possibilities) eq 'ARRAY');
- my ($thing, $description) = @{ $possibilities };
- if ($thing eq $value) {
- $name = $description;
- last;
+ my $gotregexmatch = '';
+ if ($regexp) {
+ last if ($gotregexmatch);
+ my ($item,$pattern) = @{ $possibilities };
+ if ($value =~ /$pattern/) {
+ if (ref($paramstrings) eq 'ARRAY') {
+ foreach my $possibles (@{$paramstrings}) {
+ next unless (ref($possibles) eq 'ARRAY');
+ my ($thing,$description) = @{$possibles};
+ if ($thing eq $item) {
+ $name = $description;
+ $gotregexmatch = 1;
+ last;
+ }
+ }
+ last if ($gotregexmatch);
+ }
+ }
+ } else {
+ my ($thing,$description) = @{ $possibilities };
+ if ($thing eq $value) {
+ $name = $description;
+ last;
+ }
}
}
return $name;
}
+sub update_releasereq {
+ my $readmap = 1;
+ my $getrelreq = 1;
+ if (ref($modified_courses) eq 'ARRAY') {
+ foreach my $item (@{$modified_courses}) {
+ if (ref($item) eq 'ARRAY') {
+ my ($cdom,$cnum,$chome,$crstype) = @{$item};
+ &Apache::lonrelrequtils::modify_course_relreq(undef,undef,$cnum,$cdom,
+ $chome,$crstype,$cdom.'_'.$cnum,
+ $readmap,$getrelreq);
+ }
+ }
+ $modified_courses = [];
+ }
+ undef($registered_cleanup);
+ return;
+}
+
sub show_autocoowners {
my (@currcoown) = @_;
- my $output = ''.&mt('Co-ownership is set automatically when a Course Coordinator role is assigned to official course personnel (from institutional data).').'';
+ my $output = ''.&mt('Co-ownership is set automatically when a Course Coordinator role[_1] is assigned to official course personnel (from institutional data).','').''; if (@currcoown > 0) { $output .= ' '.&mt('Current co-owners are:').' '. join(', ',map { &Apache::loncommon::plainname(split(':',$_)); } (@currcoown)); @@ -2550,13 +3391,20 @@ sub show_autocoowners { } sub coowner_invitations { - my ($cnum,$cdom,@currcoown) = @_; - my ($output,@pendingcoown,@othercoords); + my ($cnum,$cdom,$currcoownref,$noedit) = @_; + my ($output,@pendingcoown,@othercoords,@currcoown); my $pendingcoowners = $env{'course.'.$env{'request.course.id'}.'.internal.pendingco-owners'}; if ($pendingcoowners) { @pendingcoown = split(',',$pendingcoowners); } + if (ref($currcoownref) eq 'ARRAY') { + @currcoown == @{$currcoownref}; + } + my $disabled; + if ($noedit) { + $disabled = ' disabled="disabled"'; + } my $ccrole = 'cc'; my %ccroles = &Apache::lonnet::get_my_roles($cnum,$cdom,undef,undef,[$ccrole]); foreach my $key (sort(keys(%ccroles))) { @@ -2574,7 +3422,7 @@ sub coowner_invitations { ' '.&mt('Current co-owners').' | ';
foreach my $person (@currcoown) {
my ($co_uname,$co_dom) = split(':',$person);
- $output .= ''.(' 'x2).' ';
+ $output .= ''.(' 'x2).' ';
}
$output .= ' | '.
&Apache::loncommon::end_data_table_row();
@@ -2584,7 +3432,7 @@ sub coowner_invitations {
''.&mt('Invited as co-owners [_1](agreement pending)',' | ').' ';
foreach my $person (@pendingcoown) {
my ($co_uname,$co_dom) = split(':',$person);
- $output .= ''.(' 'x2).' ';
+ $output .= ''.(' 'x2).' ';
}
$output .= ' | '.
&Apache::loncommon::end_data_table_row();
@@ -2594,7 +3442,7 @@ sub coowner_invitations {
''.&mt('Invite other Coordinators [_1]to become co-owners',' | ').' ';
foreach my $person (@othercoords) {
my ($co_uname,$co_dom) = split(':',$person);
- $output .= ''.(' 'x2).' ';
+ $output .= ''.(' 'x2).' ';
}
$output .= ' | '.
&Apache::loncommon::end_data_table_row();
@@ -2607,13 +3455,20 @@ sub coowner_invitations {
}
sub manage_coownership {
- my ($cnum,$cdom,@currcoown) = @_;
- my (@pendingcoown);
+ my ($cnum,$cdom,$currcoownref,$noedit) = @_;
+ my (@pendingcoown,@currcoown);
my $pendingcoowners =
$env{'course.'.$env{'request.course.id'}.'.internal.pendingco-owners'};
if ($pendingcoowners) {
@pendingcoown = split(',',$pendingcoowners);
}
+ if (ref($currcoownref) eq 'ARRAY') {
+ @currcoown == @{$currcoownref};
+ }
+ my $disabled;
+ if ($noedit) {
+ $disabled = ' disabled="disabled"';
+ }
my ($is_coowner,$is_pending,$output);
my $uname = $env{'user.name'};
my $udom = $env{'user.domain'};
@@ -2643,10 +3498,10 @@ sub manage_coownership {
}
$output .= '';
if ($is_coowner) {
- $output .= &mt('You are currently a co-owner:').' ';
+ $output .= &mt('You are currently a co-owner:').' ';
} else {
- $output .= &mt('The course owner has invited you to become a co-owner:').' '.(' 'x2).
- '';
+ $output .= &mt('The course owner has invited you to become a co-owner:').' '.(' 'x2).
+ '';
}
$output .= '';
if (@currcoown) {
@@ -2660,7 +3515,7 @@ sub manage_coownership {
}
sub print_localization {
- my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
+ my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$noedit) = @_;
unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
return;
}
@@ -2679,17 +3534,24 @@ sub print_localization {
input => 'selectbox',
},
);
- my $datatable;
+ my ($datatable,$disabled);
my $count = 0;
+ if ($noedit) {
+ $disabled = ' disabled="disabled"';
+ }
foreach my $item (@{$ordered}) {
$count ++;
- $datatable .= &item_table_row_start($items{$item}{text},$count);
+ my $colspan;
+ unless ($item eq 'languages') {
+ $colspan = 2;
+ }
+ $datatable .= &item_table_row_start($items{$item}{text},$count,undef,$colspan);
if ($item eq 'timezone') {
my $includeempty = 1;
my $timezone = &Apache::lonlocal::gettimezone();
$datatable .=
&Apache::loncommon::select_timezone($item,$timezone,undef,
- $includeempty);
+ $includeempty,$disabled);
} elsif ($item eq 'datelocale') {
my $includeempty = 1;
my $locale_obj = &Apache::lonlocal::getdatelocale();
@@ -2699,15 +3561,18 @@ sub print_localization {
}
$datatable .=
&Apache::loncommon::select_datelocale($item,$currdatelocale,
- undef,$includeempty);
+ undef,$includeempty,$disabled);
} else {
if ($settings->{$item} eq '') {
- $datatable .=
- &Apache::loncommon::select_language('languages_0','',1);
+ unless ($noedit) {
+ $datatable .= ''.
+ &Apache::loncommon::select_language('languages_0','',1);
+ }
} else {
my $num = 0;
my @languages = split(/\s*[,;:]\s*/,$settings->{$item});
- $datatable .= &Apache::loncommon::start_data_table();
+ $datatable .= ' | | '.
&Apache::loncommon::end_data_table_row();
$num ++;
}
}
- $datatable .= &Apache::loncommon::start_data_table_row().
+ unless ($noedit) {
+ $datatable .=
+ &Apache::loncommon::start_data_table_row().
''. + &Apache::loncommon::start_data_table(); if (@languages > 0) { my %langchoices = &get_lang_choices(); foreach my $lang (@languages) { @@ -2722,19 +3587,22 @@ sub print_localization { ' '. ' '.
&mt('Additional language:'). ' | '.&Apache::loncommon::end_data_table_row().
- &Apache::loncommon::end_data_table();
+ ''.&Apache::loncommon::end_data_table_row();
+ }
+ $datatable .= &Apache::loncommon::end_data_table().''. &Apache::loncommon::select_language('languages_'.$num,'',1). ''. - ' '; } } $datatable .= &item_table_row_end(); @@ -2755,7 +3623,7 @@ sub get_lang_choices { } sub print_feedback { - my ($position,$cdom,$settings,$ordered,$itemtext,$rowtotal) = @_; + my ($position,$cdom,$settings,$ordered,$itemtext,$rowtotal,$noedit) = @_; unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) { return; } @@ -2790,17 +3658,25 @@ sub print_feedback { del => 'Delete?', sec => 'Sections:', ); - + my $disabled; + if ($noedit) { + $disabled = ' disabled="disabled"'; + } foreach my $item (@{$ordered}) { $count ++; - $datatable .= &item_table_row_start($items{$item}{text},$count); + if ($position eq 'top') { + $datatable .= &item_table_row_start($items{$item}{text},$count); + } else { + $datatable .= &item_table_row_start($items{$item}{text}." (Custom text)",$count, "advanced",2); + } if ($position eq 'top') { my $includeempty = 0; - $datatable .= &user_table($cdom,$item,\@sections, - $settings->{$item},\%lt); + $datatable .= ' '.
+ &user_table($cdom,$item,\@sections,
+ $settings->{$item},\%lt,$noedit);
} else {
$datatable .= &Apache::lonhtmlcommon::textbox($item.'.text',
- $settings->{$item.'.text'},$items{$item}{size});
+ $settings->{$item.'.text'},$items{$item}{size},$disabled);
}
$datatable .= &item_table_row_end();
}
@@ -2809,15 +3685,21 @@ sub print_feedback {
}
sub user_table {
- my ($cdom,$item,$sections,$currvalue,$lt) = @_;
+ my ($cdom,$item,$sections,$currvalue,$lt,$noedit) = @_;
my $output;
if ($currvalue eq '') {
- $output .= &select_recipient($item,'0',$cdom,$sections);
+ unless ($noedit) {
+ $output .= &select_recipient($item,'0',$cdom,$sections);
+ }
} else {
my $num = 0;
my @curr = split(/,/,$currvalue);
- $output .= ' |
'.
$lt->{'add'}.' | '. &select_recipient($item,$num,$cdom,$sections). ''. - '
|