'."\n".
- $browse_js."\n".$categorize_js."\n".$cloners_js."\n".''.
- "\n".$stubrowse_js."\n";
+ '// '."\n".
+ ''."\n".$stubrowse_js."\n";
return $jscript;
}
@@ -1128,7 +1886,7 @@ function update_cloners(caller,num) {
if (document.$formname.cloners_activate[i].value == '0') {
document.$formname.cloners_activate[i].checked = false;
}
- if (document.$formname.cloners_activate[i].value == '') {
+ if (document.$formname.cloners_activate[i].value == '-1') {
document.$formname.cloners_activate[i].checked = true;
}
}
@@ -1181,28 +1939,86 @@ ENDSCRIPT
sub print_courseinfo {
- my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
+ my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype) = @_;
unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
return;
}
- my ($cathash,$categoriesform);
- my $crstype = &Apache::loncommon::course_type();
+ my ($cathash,$categoriesform,$autocoowner,$clonedefaults);
my %domconf =
- &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom);
+ &Apache::lonnet::get_dom('configuration',
+ ['coursecategories','autoenroll','coursedefaults'],$cdom);
if (ref($domconf{'coursecategories'}) eq 'HASH') {
$cathash = $domconf{'coursecategories'}{'cats'};
if (ref($cathash) eq 'HASH') {
$categoriesform =
&Apache::loncommon::assign_categories_table($cathash,
- $settings->{'categories'})."\n";
+ $settings->{'categories'},$crstype)."\n";
+ }
+ }
+ if (ref($domconf{'autoenroll'}) eq 'HASH') {
+ $autocoowner = $domconf{'autoenroll'}{'co-owners'};
+ }
+ my ($currcanclone,@code_order,$cloner_instcode);
+ my %codedefaults;
+ &Apache::lonnet::auto_instcode_defaults($cdom,\%codedefaults,
+ \@code_order);
+ if ($settings->{'cloners'}) {
+ unless ($settings->{'cloners'} eq '*') {
+ my @currclone = split(/,/,$settings->{'cloners'});
+ foreach my $item (@currclone) {
+ unless ($item eq '*') {
+ if (($item !~ /\:/) && ($item =~ /=/)) {
+ $cloner_instcode = 1;
+ }
+ }
+ }
+ }
+ }
+ if (ref($domconf{'coursedefaults'}) eq 'HASH') {
+ my $canclone = $domconf{'coursedefaults'}{'canclone'};
+ if (ref($canclone) eq 'HASH') {
+ if (ref($canclone->{'instcode'}) eq 'ARRAY') {
+ if ($settings->{'internal.coursecode'}) {
+ my @posscodes;
+ if (@code_order > 0) {
+ $currcanclone = 'instcode';
+ foreach my $item (@{$canclone->{'instcode'}}) {
+ if (grep(/^\Q$item\E$/,@code_order)) {
+ push(@posscodes,$item);
+ }
+ }
+ my $codestr = join(' + ',@posscodes);
+ $clonedefaults = &mt('Default for official courses is to also allow cloning if [_1] match in cloner and cloned.',
+ '"'.$codestr.' "').' ';
+ }
+ }
+ }
+ } 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 for this domain');
+ $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 ($can_toggle_cat,$can_categorize) = &can_modify_catsettings($cdom);
-
+ my $replace;
+ if ($crstype eq 'Community') {
+ $replace = &mt('To replace the standard title for a course role, enter a title, otherwise leave blank');
+ } else {
+ $replace = &mt('To replace the standard title for a course role, enter a title, otherwise leave blank');
+ }
my %items = (
'url' => {
text => ''.&mt($itemtext->{'url'}).' '.(' 'x2).
@@ -1212,12 +2028,22 @@ sub print_courseinfo {
&mt('Modification may make assessment data inaccessible!').
'',
input => 'textbox',
- size => '40',
+ size => '55',
+ advanced => 1
},
'description' => {
text => ''.&mt($itemtext->{'description'}).' ',
input => 'textbox',
- size => '25',
+ size => '55',
+ },
+ 'owner' => {
+ text => ''.&mt($itemtext->{'owner'}).' ',
+ },
+ 'co-owners' => {
+ text => ''.&mt($itemtext->{'co-owners'}).' ',
+ },
+ 'clonedfrom' => {
+ text => ''.&mt($itemtext->{'clonedfrom'}).' ',
},
'courseid' => {
text => ''.&mt($itemtext->{'courseid'}).' '.'('.
@@ -1225,23 +2051,28 @@ sub print_courseinfo {
input => 'textbox',
size => '25',
},
+ 'uniquecode' => {
+ text => ''.&mt($itemtext->{'uniquecode'}).' ',
+ },
'cloners' => {
text => ''.&mt($itemtext->{'cloners'}).' '.
- &mt('Course Coordinators included automatically'),
+ &mt('Owner and Coordinators included automatically').
+ $clonedefaults,
input => 'textbox',
- size => '40',
+ size => '40'
},
'rolenames' => {
text => ''.&mt($itemtext->{'rolenames'}).' '.
- '('.&mt('To replace the standard title for a course role, enter a title, otherwise leave blank').')',
+ '('.$replace.')',
input => 'textbox',
size => '20',
+ advanced => 1
},
'externalsyllabus' => {
- text => ''.&mt($itemtext->{'externalsyllabus'}).' ('.
- &mt('not using syllabus template)'),
- input => 'textbox',
- size => '40',
+ text => ''.&mt($itemtext->{'externalsyllabus'}).' '.
+ &mt('(Syllabus type in use)').(' ' x2).
+ &mt('[_1]Edit[_2]','',
+ ' '),
},
'hidefromcat' => {
text => ''.&mt($itemtext->{'hidefromcat'}).' '.
@@ -1254,23 +2085,40 @@ sub print_courseinfo {
input => 'textbox',
size => '25',
},
+ '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);
} 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().
' '.
&mt('Any user in any domain:').
@@ -1280,30 +2128,42 @@ sub print_courseinfo {
}
$datatable .= 'onchange="javascript:update_cloners('.
"'cloners_all'".');" />'.&mt('Yes').' '.
- (' 'x2).' '.
+ ' {$item} ne '*') {
$datatable .= ' checked="checked" ';
}
$datatable .= ' onchange="javascript:update_cloners('.
- "'cloners_all'".');"/>'.&mt('No').' '.
+ "'cloners_all'".');" />'.&mt('No').''.
&Apache::loncommon::end_data_table_row().
&Apache::loncommon::end_data_table().
- ''.
+ ''.
&Apache::loncommon::start_data_table();
my @cloners;
if ($settings->{$item} eq '') {
- $datatable .= &new_cloners_dom_row($cdom,'0');
+ my $default;
+ if ($currcanclone eq 'domain') {
+ $default = '0';
+ }
+ $datatable .= &new_cloners_dom_row($cdom,'0',$default);
} elsif ($settings->{$item} ne '*') {
my @entries = split(/,/,$settings->{$item});
if (@entries > 0) {
foreach my $entry (@entries) {
my ($uname,$udom) = split(/:/,$entry);
+ if ($udom =~ /^$match_domain$/) {
+ unless (&Apache::lonnet::domain($udom)) {
+ next;
+ }
+ } else {
+ next;
+ }
if ($uname eq '*') {
$datatable .=
&Apache::loncommon::start_data_table_row().
''.
- &mt('Domain:').' '.$udom.
+ &mt('Any user in domain:').' '.$udom.
' '.
' '.
&Apache::loncommon::end_data_table_row();
$num ++;
- } else {
- push(@cloners,$entry);
+ } elsif (&Apache::lonnet::homeserver($uname,$udom) ne 'no_host') {
+ unless (grep(/^\Q$entry\E$/,@cloners)) {
+ push(@cloners,$entry);
+ }
}
}
}
@@ -1332,8 +2194,8 @@ sub print_courseinfo {
' '.
''.&Apache::loncommon::end_data_table_row().
&Apache::loncommon::end_data_table().
- ''.
+ ''.
&Apache::loncommon::start_data_table().
&Apache::loncommon::start_data_table_row().
''.
@@ -1343,9 +2205,48 @@ sub print_courseinfo {
$items{$item}{'size'}).
' '.&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::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_row().
+ ''.
+ &mt('Cloning by official course(s) based on course category').(' 'x2).
+ ''.
+ ' '.&mt('Yes').' '.
+ (' ').
+ ''.
+ ' '.&mt('No').' '.
+ &Apache::courseclassifier::build_instcode_selectors($numtitles,
+ $lasttitle,\%cat_items,\@codetitles,\%cat_titles,\%cat_order,
+ $showncodes,'LC_cloners_instcodes','LC_cloners_instcode').
+ ' '.&Apache::loncommon::end_data_table_row().
+ &Apache::loncommon::end_data_table();
+ }
} elsif ($item eq 'rolenames') {
- $datatable .= &Apache::loncommon::start_data_table();
- foreach my $role ('cc','in','ta','ep','ad','st') {
+ $datatable .= ''.
+ &Apache::loncommon::start_data_table();
+ my @roles;
+ if ($crstype eq 'Community') {
+ @roles = ('co');
+ } else {
+ @roles = ('cc');
+ }
+ push (@roles,('in','ta','ep','ad','st'));
+ foreach my $role (@roles) {
$datatable .= &Apache::loncommon::start_data_table_row().
' '.
&Apache::lonnet::plaintext($role,$crstype,undef,1).
@@ -1357,10 +2258,95 @@ sub print_courseinfo {
}
$datatable .= &Apache::loncommon::end_data_table().' ';
} elsif ($item eq 'categories') {
- my $launcher = 'onFocus="this.blur();javascript:catsbrowser();";';
+ my $launcher = 'onfocus="this.blur();javascript:catsbrowser();"';
$datatable .= ' '.
&Apache::lonhtmlcommon::textbox($item.'_display',$settings->{$item},
$items{$item}{size},$launcher);
+ } elsif ($item eq 'owner') {
+ my $owner = $env{'course.'.$env{'request.course.id'}.'.internal.courseowner'};
+ if ($owner =~ /:/) {
+ my ($ownername,$ownerdom) = split(':',$owner);
+ $owner = &Apache::loncommon::plainname($ownername,$ownerdom);
+ } elsif ($owner ne '') {
+ $owner = &Apache::loncommon::plainname($owner,$cdom);
+ } else {
+ $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 $coowners = $env{'course.'.$env{'request.course.id'}.'.internal.co-owners'};
+ my @currcoown;
+ if ($coowners) {
+ @currcoown = split(',',$coowners);
+ }
+ if (&Apache::lonnet::is_course_owner($cdom,$cnum)) {
+ if (($crstype eq 'Course') && ($env{'course.'.$env{'request.course.id'}.'.internal.coursecode'}) && ($autocoowner)) {
+ $datatable .= &show_autocoowners(@currcoown);
+ } else {
+ $datatable .= &coowner_invitations($cnum,$cdom,@currcoown);
+ }
+ } 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);
+ }
+ }
+ } elsif ($item eq 'externalsyllabus') {
+ 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;
+ if ($loncaparev) {
+ $showreqd = &mt('[_1] or newer',$loncaparev).' '.
+ &mt('Details').' ';
+ } else {
+ $showreqd = &mt('No specific version required');
+ }
+ $datatable .= $showreqd;
} else {
$datatable .= &Apache::lonhtmlcommon::textbox($item,$settings->{$item},$items{$item}{size});
}
@@ -1371,19 +2357,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).' '.
&mt('Yes').' '.(' 'x2).
' '.
&mt('No').'
@@ -1461,28 +2473,851 @@ ENDSCRIPT
} else {
my $onload;
}
+ my ($crscat,$catcrs,$assign);
+ if ($crstype eq 'Community') {
+ $crscat = 'Community Categories';
+ $catcrs = &mt('Categorize Community');
+ $assign = &mt('Assign one or more categories to this community.')
+ } else {
+ $crscat = 'Course Categories';
+ $catcrs = &mt('Categorize Course');
+ $assign = &mt('Assign one or more categories to this course.')
+ }
my $start_page =
- &Apache::loncommon::start_page('Course Categories',$catwin_js,
+ &Apache::loncommon::start_page($crscat,$catwin_js,
{'only_body' => 1,});
my $end_page = &Apache::loncommon::end_page();
- my $categoriesform = ''.&mt('Categorize Course').' ';
+ my $categoriesform = ''.$catcrs.' ';
if ($hascats) {
my %currsettings =
&Apache::lonnet::get('environment',['hidefromcat','categories'],$cdom,$cnum);
- $categoriesform .= &mt('Assign one or more categories to this course.').' '.
+ my $cattable = &Apache::loncommon::assign_categories_table($cathash,
+ $currsettings{'categories'},$crstype);
+ if ($cattable eq '') {
+ $categoriesform .= &mt('No suitable categories defined for this course type in this domain.');
+ } else {
+ $categoriesform .= $assign.' '.
' ';
+ }
} else {
- $categoriesform .= &mt('No categories defined for this domain');
+ $categoriesform .= &mt('No categories defined in this domain.');
}
$r->print($start_page.$categoriesform.$end_page);
return;
}
+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'};
+ my $output;
+ my %lt = &Apache::lonlocal::texthash (
+ 'all' => 'all',
+ 'section/group' => 'section/group',
+ 'user' => 'user',
+ );
+ &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,
+ $Apache::lonrelrequtils::checkcrstypes{$crstype}).' ';
+ }
+ my (%fromparam,%rowspan,%bymap,%byresource,@scopeorder,%toshow,%allmaps,
+ %byresponsetype,%bysubmission,%fromblocks);
+ @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})) {
+ my %found;
+ foreach my $item (keys(%Apache::lonrelrequtils::checkparms)) {
+ if ($key =~ /(\Q$item\E)$/) {
+ 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);
+ }
+ }
+ }
+ }
+ }
+ if (keys(%fromparam)) {
+ $output .= ''.&mt('Requirements from general settings').' '.
+ &Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row().
+ ' '.&mt('Release').' '.&mt('Scope').' '.
+ ''.&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;
+ foreach my $scope (@scopeorder) {
+ if (ref($fromparam{$rev}{$scope}) eq 'HASH') {
+ if ($newrow) {
+ $output .= &Apache::loncommon::continue_data_table_row();
+ }
+ $output .= ''.$lt{$scope}.' ';
+ foreach my $which (sort(keys(%{$fromparam{$rev}{$scope}}))) {
+ $output .= ''.$which.' '.
+ join(' ',@{$fromparam{$rev}{$scope}{$which}}).' ';
+ }
+ $output .= &Apache::loncommon::end_data_table_row();
+ $newrow = 1;
+ } elsif (ref($fromparam{$rev}{$scope}) eq 'ARRAY') {
+ if ($newrow) {
+ $output .= &Apache::loncommon::continue_data_table_row();
+ }
+ $output .= ''.$lt{$scope}.' '.
+ join(' ',@{$fromparam{$rev}{$scope}}).' '.
+ &Apache::loncommon::end_data_table_row();
+ $newrow = 1;
+ }
+ }
+ }
+ $output .= &Apache::loncommon::end_data_table().' ';
+ }
+ }
+
+ 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.' ';
+ }
+ $output =~ s{\Q \E$}{};
+ $output .= ' '.&Apache::loncommon::end_data_table_row();
+ }
+ }
+ }
+ $output .= &Apache::loncommon::end_data_table().' ';
+ }
+ }
+
+ if (defined($navmap)) {
+ my %anonsubms=&Apache::lonnet::dump('nohist_anonsurveys',$cdom,$cnum);
+ 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 $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');
+ my %checkedrev;
+ foreach my $res ($navmap->retrieveResources(undef,sub { $_[0]->is_problem() },1,0)) {
+ my @parts = @{$res->parts()};
+ my $symb = $res->symb();
+ my $enclosing_map = &Apache::lonnet::declutter($res->enclosing_map_src());
+ foreach my $part (@parts) {
+ if (exists($anonsubms{$symb."\0".$part})) {
+ my $rev = $rev_anonsurv;
+ my $what="$stdname=$valanon";
+ if (ref($bysubmission{$symb}{$rev}) eq 'ARRAY') {
+ unless (grep(/^\Q$what\E/,@{$bysubmission{$symb}{$rev}})) {
+ push(@{$bysubmission{$symb}{$rev}},$what);
+ }
+ } else {
+ 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;
+ my $what="$stdname=$valrandtry";
+ if (ref($bysubmission{$symb}{$rev}) eq 'ARRAY') {
+ unless (grep(/^\Q$what\E/,@{$bysubmission{$symb}{$rev}})) {
+ push(@{$bysubmission{$symb}{$rev}},$what);
+ }
+ } else {
+ 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($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;
+ }
+ }
+ }
+ if (keys(%byresource) > 0) {
+ foreach my $symb (keys(%byresource)) {
+ my ($map,$resid,$resurl)=&Apache::lonnet::decode_symb($symb);
+ $allmaps{$map} = 1;
+ }
+ }
+ if (keys(%bymap) > 0) {
+ foreach my $map (keys(%bymap)) {
+ $allmaps{$map} = 1;
+ }
+ }
+ foreach my $map (keys(%allmaps)) {
+ my $mapres = $navmap->getResourceByUrl($map);
+ if (ref($mapres)) {
+ my $mapsymb = $mapres->symb();
+ $toshow{$mapsymb} = 1;
+ my $pcslist = $mapres->map_hierarchy();
+ if ($pcslist ne '') {
+ foreach my $pc (split(/,/,$pcslist)) {
+ my $res = $navmap->getByMapPc($pc);
+ if (ref($res)) {
+ my $symb = $res->symb();
+ unless ($symb eq '______') {
+ $toshow{$symb} = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ my $mapres_header = ''.
+ &mt('Requirements for specific folders or resources').
+ ' ';
+ if ((keys(%toshow) > 0) || (keys(%byresource) > 0) ||
+ (keys(%bysubmission) > 0) || (keys(%byresponsetype))) {
+ $output .= $mapres_header;
+ }
+ my $top_header = ''.&mt('LON-CAPA version dependencies').' ';
+ my $title = 'Version Constraints';
+ my $start_page =
+ &Apache::loncommon::start_page($title,undef,{'only_body' => 1,});
+ $r->print($start_page.$top_header);
+ if ($output) {
+ $r->print($output);
+ if (defined($navmap)) {
+ &show_contents_view($r,$navmap,$cid,\%toshow,\%bymap,\%byresource,\%bysubmission,
+ \%byresponsetype,\@scopeorder,\%lt);
+ }
+ $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 = ' ';
+ my $topmap = $env{'course.'.$cid.'.url'};
+ $r->print(&Apache::loncommon::start_data_table().
+ &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 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;
+ my %parent = ();
+ my $startcount = 5;
+ my $lastcontainer = $startcount;
+ while ($curRes = $it->next()) {
+ if ($curRes == $it->BEGIN_MAP()) {
+ $depth++;
+ $parent{$depth}= $lastcontainer;
+ }
+ if ($curRes == $it->END_MAP()) {
+ $depth--;
+ $lastcontainer = $parent{$depth};
+ }
+ my $indent;
+ for (my $i=0; $i<$depth; $i++) {
+ $indent.= $whitespace;
+ }
+ if (ref($curRes)) {
+ my $symb = $curRes->symb();
+ my $ressymb = $symb;
+ my $srcf = $curRes->src();
+ my $title = &Apache::lonnet::gettitle($srcf);
+ if (($curRes->is_sequence()) || ($curRes->is_page())) {
+ next unless($toshow->{$symb});
+ my ($parent,$ind,$url) = &Apache::lonnet::decode_symb($symb);
+ $icon = ' ';
+ if ($curRes->is_page()) {
+ $icon = ' ';
+ }
+ my $rowspan = 1;
+ if (ref($bymap->{$url}) eq 'HASH') {
+ $rowspan = scalar(keys(%{$bymap->{$url}}));
+ }
+ $r->print(&Apache::loncommon::start_data_table_row().
+ ''.$indent.$icon.' '.$title.' ');
+ &releases_by_map($r,$bymap,$url,$scopeorder,$lt);
+ $r->print(&Apache::loncommon::end_data_table_row());
+ } else {
+ my $rowspan;
+ if (ref($byresource->{$symb}) eq 'HASH') {
+ $rowspan += scalar(keys(%{$byresource->{$symb}}));
+ }
+ if (ref($bysubmission->{$symb}) eq 'HASH') {
+ $rowspan += scalar(keys(%{$bysubmission->{$symb}}));
+ }
+ if (ref($byresponsetype->{$symb}) eq 'HASH') {
+ $rowspan += scalar(keys(%{$byresponsetype->{$symb}}));
+ }
+ next if (!$rowspan);
+ $icon = ' ';
+ $r->print(&Apache::loncommon::start_data_table_row().
+ ''.$indent.$icon.' '.$title.' ');
+ my $newrow;
+ if (ref($byresource->{$symb}) eq 'HASH') {
+ foreach my $rev (sort(keys(%{$byresource->{$symb}}))) {
+ if ($newrow) {
+ $r->print(&Apache::loncommon::continue_data_table_row());
+ }
+ $r->print(''.$rev.' ');
+ if (ref($byresource->{$symb}{$rev}) eq 'HASH') {
+ $r->print('');
+ foreach my $scope (@{$scopeorder}) {
+ if (ref($byresource->{$symb}{$rev}{$scope}) eq 'HASH') {
+ $r->print(''.&mt('Setting - scope: [_1]',$lt->{$scope}).' ');
+ foreach my $which (sort(keys(%{$byresource->{$symb}{$rev}{$scope}}))) {
+ $r->print(''.$which.' '.
+ join(' ',@{$byresource->{$symb}{$rev}{$scope}{$which}}).
+ ' ');
+ }
+ $r->print(' ');
+ } elsif (ref($byresource->{$symb}{$rev}{$scope}) eq 'ARRAY') {
+ $r->print(''.&mt('Setting - scope: [_1]',$lt->{$scope}).' '.
+ ' '.
+ join(' ',@{$byresource->{$symb}{$rev}{$scope}}).' ');
+ }
+ }
+ $r->print('
');
+ }
+ $r->print(' ');
+ $r->print(&Apache::loncommon::end_data_table_row());
+ $newrow = 1;
+ }
+ }
+ if (ref($bysubmission->{$symb}) eq 'HASH') {
+ foreach my $rev (sort(keys(%{$bysubmission->{$symb}}))) {
+ if ($newrow) {
+ $r->print(&Apache::loncommon::continue_data_table_row());
+ }
+ $r->print(''.$rev.' ');
+ if (ref($bysubmission->{$symb}{$rev}) eq 'ARRAY') {
+ $r->print(&mt('Submissions to: ').' '.
+ join(', ',@{$bysubmission->{$symb}{$rev}}));
+ }
+ $r->print(' ');
+ $r->print(&Apache::loncommon::end_data_table_row());
+ $newrow = 1;
+ }
+ }
+ if (ref($byresponsetype->{$symb}) eq 'HASH') {
+ foreach my $rev (sort(keys(%{$byresponsetype->{$symb}}))) {
+ if ($newrow) {
+ $r->print(&Apache::loncommon::continue_data_table_row());
+ }
+ $r->print(''.$rev.' ');
+ if (ref($byresponsetype->{$symb}{$rev}) eq 'ARRAY') {
+ $r->print(&mt('Response Type(s): ').' '.
+ join(' ',@{$byresponsetype->{$symb}{$rev}}));
+ }
+ $r->print(' ');
+ }
+ $r->print(&Apache::loncommon::end_data_table_row());
+ }
+ }
+ }
+ }
+ $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('');
+ foreach my $scope (@{$scopeorder}) {
+ if (ref($bymap->{$url}{$rev}{$scope}) eq 'HASH') {
+ $r->print(''.&mt('Setting - scope: [_1]',$lt->{$scope}).' ');
+ foreach my $which (sort(keys(%{$bymap->{$url}{$rev}{$scope}}))) {
+ $r->print(''.$which.' '.
+ join(' ',@{$bymap->{$url}{$rev}{$scope}{$which}}).
+ ' ');
+ }
+ $r->print(' ');
+ } elsif (ref($bymap->{$url}{$rev}{$scope}) eq 'ARRAY') {
+ $r->print(''.&mt('Setting - scope: [_1]',$lt->{$scope}).
+ ' '.
+ join(' ',@{$bymap->{$url}{$rev}{$scope}}).' ');
+ }
+ }
+ $r->print('
');
+ }
+ $r->print(' ');
+ $newrow = 1;
+ }
+ } else {
+ $r->print(' ');
+ }
+ return;
+}
+
+sub get_param_description {
+ 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 (@possibles) {
+ next unless (ref($possibilities) eq 'ARRAY');
+ 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[_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));
+ } else {
+ $output .= ' '.&mt('Currently no co-owners.');
+ }
+ return $output;
+}
+
+sub coowner_invitations {
+ my ($cnum,$cdom,@currcoown) = @_;
+ my ($output,@pendingcoown,@othercoords);
+ my $pendingcoowners =
+ $env{'course.'.$env{'request.course.id'}.'.internal.pendingco-owners'};
+ if ($pendingcoowners) {
+ @pendingcoown = split(',',$pendingcoowners);
+ }
+ my $ccrole = 'cc';
+ my %ccroles = &Apache::lonnet::get_my_roles($cnum,$cdom,undef,undef,[$ccrole]);
+ foreach my $key (sort(keys(%ccroles))) {
+ my ($ccname,$ccdom,$role) = split(':',$key);
+ next if ($key eq $env{'user.name'}.':'.$env{'user.domain'}.':'.$ccrole);
+ unless (grep(/^\Q$ccname\E:\Q$ccdom\E$/,@currcoown,@pendingcoown)) {
+ push(@othercoords,$ccname.':'.$ccdom);
+ }
+ }
+ my $coowner_rows = @currcoown + @pendingcoown + @othercoords;
+ if ($coowner_rows) {
+ $output .= &Apache::loncommon::start_data_table();
+ if (@currcoown) {
+ $output .= &Apache::loncommon::start_data_table_row().
+ ''.&mt('Current co-owners').' ';
+ foreach my $person (@currcoown) {
+ my ($co_uname,$co_dom) = split(':',$person);
+ $output .= ' '.&Apache::loncommon::plainname($co_uname,$co_dom).' '.(' 'x2).' ';
+ }
+ $output .= ' '.
+ &Apache::loncommon::end_data_table_row();
+ }
+ if ($pendingcoowners) {
+ $output .= &Apache::loncommon::start_data_table_row().
+ ''.&mt('Invited as co-owners [_1](agreement pending)',' ').' ';
+ foreach my $person (@pendingcoown) {
+ my ($co_uname,$co_dom) = split(':',$person);
+ $output .= ' '.&Apache::loncommon::plainname($co_uname,$co_dom).' '.(' 'x2).' ';
+ }
+ $output .= ' '.
+ &Apache::loncommon::end_data_table_row();
+ }
+ if (@othercoords) {
+ $output .= &Apache::loncommon::start_data_table_row().
+ ''.&mt('Invite other Coordinators [_1]to become co-owners',' ').' ';
+ foreach my $person (@othercoords) {
+ my ($co_uname,$co_dom) = split(':',$person);
+ $output .= ' '.&Apache::loncommon::plainname($co_uname,$co_dom).' '.(' 'x2).' ';
+ }
+ $output .= ' '.
+ &Apache::loncommon::end_data_table_row();
+ }
+ $output .= &Apache::loncommon::end_data_table();
+ } else {
+ $output = &mt('There are no coordinators to select as co-owners');
+ }
+ return $output;
+}
+
+sub manage_coownership {
+ my ($cnum,$cdom,@currcoown) = @_;
+ my (@pendingcoown);
+ my $pendingcoowners =
+ $env{'course.'.$env{'request.course.id'}.'.internal.pendingco-owners'};
+ if ($pendingcoowners) {
+ @pendingcoown = split(',',$pendingcoowners);
+ }
+ my ($is_coowner,$is_pending,$output);
+ my $uname = $env{'user.name'};
+ my $udom = $env{'user.domain'};
+ if (grep(/^\Q$uname\E:\Q$udom\E$/,@currcoown)) {
+ $is_coowner = 1;
+ }
+ if (grep(/^\Q$uname\E:\Q$udom\E$/,@pendingcoown)) {
+ $is_pending = 1;
+ }
+ if (@currcoown && ($is_coowner || $is_pending)) {
+ $output = &Apache::loncommon::start_data_table();
+ }
+ if (@currcoown) {
+ if ($is_coowner || $is_pending) {
+ $output .= &Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_row().'';
+ }
+ $output .= &mt('Current co-owners are:').' '.
+ join(', ', map { &Apache::loncommon::plainname(split(':',$_)); } (@currcoown));
+ if ($is_coowner || $is_pending) {
+ $output .= ' '.&Apache::loncommon::end_data_table_row();
+ }
+ }
+ if ($is_coowner || $is_pending) {
+ if (@currcoown) {
+ $output .= &Apache::loncommon::start_data_table_row().'';
+ }
+ $output .= '';
+ if ($is_coowner) {
+ $output .= &mt('You are currently a co-owner:').' '.&mt('Discontinue?').' ';
+ } else {
+ $output .= &mt('The course owner has invited you to become a co-owner:').' '.&mt('Accept?').' '.(' 'x2).
+ ' '.&mt('Decline?').' ';
+ }
+ $output .= ' ';
+ if (@currcoown) {
+ $output .= ' '.&Apache::loncommon::end_data_table_row();
+ }
+ }
+ if (@currcoown && ($is_coowner || $is_pending)) {
+ $output .= &Apache::loncommon::end_data_table();
+ }
+ return $output;
+}
+
sub print_localization {
my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
@@ -1490,16 +3325,16 @@ sub print_localization {
}
my %items = (
languages => {
- text => &mt($itemtext->{'languages'}).' '.
- &mt("(will override user's preference)"),
+ text => ''.&mt($itemtext->{'languages'}).' '.
+ &mt("(overrides individual user preference)"),
input => 'selectbox',
},
timezone => {
- text => &mt($itemtext->{'timezone'}),
+ text => ''.&mt($itemtext->{'timezone'}).' ',
input => 'selectbox',
},
datelocale => {
- text => &mt($itemtext->{'datelocale'}),
+ text => ''.&mt($itemtext->{'datelocale'}).' ',
input => 'selectbox',
},
);
@@ -1507,7 +3342,11 @@ sub print_localization {
my $count = 0;
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();
@@ -1526,12 +3365,13 @@ sub print_localization {
undef,$includeempty);
} else {
if ($settings->{$item} eq '') {
- $datatable .=
+ $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::start_data_table();
if (@languages > 0) {
my %langchoices = &get_lang_choices();
foreach my $lang (@languages) {
@@ -1558,7 +3398,7 @@ sub print_localization {
&Apache::loncommon::select_language('languages_'.$num,'',1).
' '.
' '.&Apache::loncommon::end_data_table_row().
- &Apache::loncommon::end_data_table();
+ &Apache::loncommon::end_data_table().' ';
}
}
$datatable .= &item_table_row_end();
@@ -1608,19 +3448,24 @@ sub print_feedback {
my %sections = &Apache::loncommon::get_sections($cdom,$cnum);
my @sections = sort( { $a <=> $b } keys(%sections));
my %lt = &Apache::lonlocal::texthash (
- currone => 'Current recipient:',
- curmult => 'Current recipients:',
- add => 'Additional recipient:',
- del => 'Delete?',
- sec => 'Sections:',
+ currone => 'Current recipient:',
+ currmult => 'Current recipients:',
+ add => 'Additional recipient:',
+ del => 'Delete?',
+ sec => 'Sections:',
);
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,
+ $datatable .= ''.
+ &user_table($cdom,$item,\@sections,
$settings->{$item},\%lt);
} else {
$datatable .= &Apache::lonhtmlcommon::textbox($item.'.text',
@@ -1640,7 +3485,7 @@ sub user_table {
} else {
my $num = 0;
my @curr = split(/,/,$currvalue);
- $output .= '';
+ $output .= '';
my ($currusers);
foreach my $val (@curr) {
next if ($val eq '');
@@ -1673,7 +3518,7 @@ sub user_table {
if ($num) {
$output .= ''.
'';
- if ($num > 1) {
+ if ($num == 1) {
$output .= $lt->{'currone'};
} else {
$output .= $lt->{'currmult'};
@@ -1753,8 +3598,7 @@ sub print_discussion {
}
my %items = (
'plc.roles.denied' => {
- text => ''.
- &mt($itemtext->{'plc.roles.denied'}).' '.
+ text => ''.&mt($itemtext->{'plc.roles.denied'}).' '.
&Apache::loncommon::help_open_topic("Course_Disable_Discussion").' '.
&mt('(role-based)'),
input => 'checkbox',
@@ -1767,8 +3611,7 @@ sub print_discussion {
},
'pch.roles.denied' => {
- text => ''.
- &mt($itemtext->{'pch.roles.denied'}).' '.
+ text => ''.&mt($itemtext->{'pch.roles.denied'}).' '.
&Apache::loncommon::help_open_topic("Course_Disable_Discussion").' '.
&mt('(role-based)'),
input => 'checkbox',
@@ -1779,6 +3622,20 @@ sub print_discussion {
&mt('(specific user(s))'),
input => 'checkbox',
},
+
+ 'pac.roles.denied' => {
+ text => ''.&mt($itemtext->{'pac.roles.denied'}).' '.
+ &Apache::loncommon::help_open_topic("Course_Disable_Anonymous_Discussion").' '.
+ &mt('(role-based)'),
+ input => 'checkbox',
+ },
+
+ 'pac.users.denied' => {
+ text => ''.&mt($itemtext->{'pac.users.denied'}).' '.
+ &mt('(specific user(s))'),
+ input => 'checkbox',
+ },
+
'allow_limited_html_in_feedback' => {
text => ''.&mt($itemtext->{'allow_limited_html_in_feedback'}).' ',
input => 'radio',
@@ -1788,6 +3645,11 @@ sub print_discussion {
text => ''.&mt($itemtext->{'allow_discussion_post_editing'}).' ',
input => 'checkbox',
},
+ 'discussion_post_fonts' => {
+ text => ''.&mt($itemtext->{'discussion_post_fonts'}).' ',
+ input => 'textbox',
+ size => '20',
+ },
);
my $datatable;
my $count;
@@ -1795,38 +3657,66 @@ sub print_discussion {
my %sections = &Apache::loncommon::get_sections($cdom,$cnum);
my @sections = sort( { $a <=> $b } keys(%sections));
my %lt = &Apache::lonlocal::texthash (
- currone => 'Disallowed:',
- curmult => 'Disallowed:',
- add => 'Disallow more:',
- del => 'Delete?',
- sec => 'Sections:',
+ currone => 'Disallowed:',
+ currmult => 'Disallowed:',
+ add => 'Disallow more:',
+ del => 'Delete?',
+ sec => 'Sections:',
);
-
foreach my $item (@{$ordered}) {
$count ++;
- $datatable .= &item_table_row_start($items{$item}{text},$count);
+ my $colspan;
+ if ($item eq 'allow_limited_html_in_feedback') {
+ $colspan = 2;
+ }
+ $datatable .= &item_table_row_start($items{$item}{text},$count,undef,$colspan);
if ($item eq 'plc.roles.denied') {
- $datatable .= ''.&role_checkboxes($cdom,$cnum,$item,$settings).
+ $datatable .= ''.
+ ''.&role_checkboxes($cdom,$cnum,$item,$settings).
'
';
} elsif ($item eq 'plc.users.denied') {
- $datatable .= &user_table($cdom,$item,undef,
+ $datatable .= ' '.
+ &user_table($cdom,$item,undef,
$settings->{$item},\%lt);
} elsif ($item eq 'pch.roles.denied') {
- $datatable .= ''.&role_checkboxes($cdom,$cnum,$item,$settings).
+ $datatable .= ''.
+ ''.&role_checkboxes($cdom,$cnum,$item,$settings).
'
';
} elsif ($item eq 'pch.users.denied') {
- $datatable .= &user_table($cdom,$item,undef,
+ $datatable .= ' '.
+ &user_table($cdom,$item,undef,
+ $settings->{$item},\%lt);
+ } elsif ($item eq 'pac.roles.denied') {
+ $datatable .= ' '.
+ ''.&role_checkboxes($cdom,$cnum,$item,$settings).
+ '
';
+ } elsif ($item eq 'pac.users.denied') {
+ $datatable .= ' '.
+ &user_table($cdom,$item,undef,
$settings->{$item},\%lt);
} elsif ($item eq 'allow_limited_html_in_feedback') {
$datatable .= &yesno_radio($item,$settings);
} elsif ($item eq 'allow_discussion_post_editing') {
- $datatable .= &Apache::loncommon::start_data_table().
+ $datatable .= ' '.
+ &Apache::loncommon::start_data_table().
&Apache::loncommon::start_data_table_row().
''.&mt('Role').' '.
&mt('Sections').' '.
&Apache::loncommon::end_data_table_row().
&role_checkboxes($cdom,$cnum,$item,$settings,1).
- &Apache::loncommon::end_data_table();
+ &Apache::loncommon::end_data_table().' ';
+ } elsif ($item eq 'discussion_post_fonts') {
+ $datatable .= ' '.
+ &Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_row().
+ ''.&mt('Sum of likes/dislikes').' '.
+ ''.&mt('font-size').' '.
+ ''.&mt('font-weight').' '.
+ ''.&mt('font-style').' '.
+ ''.&mt('Other css').' '.
+ &Apache::loncommon::end_data_table_row().
+ &set_discussion_fonts($cdom,$cnum,$item,$settings).
+ &Apache::loncommon::end_data_table().' ';
}
$datatable .= &item_table_row_end();
}
@@ -1835,8 +3725,13 @@ sub print_discussion {
}
sub role_checkboxes {
- my ($cdom,$cnum,$item,$settings,$showsections) = @_;
- my @roles = ('st','ad','ta','ep','in','cc');
+ my ($cdom,$cnum,$item,$settings,$showsections,$crstype) = @_;
+ my @roles = ('st','ad','ta','ep','in');
+ if ($crstype eq 'Community') {
+ push(@roles,'co');
+ } else {
+ push(@roles,'cc');
+ }
my $output;
my (@current,@curr_roles,%currsec,@sections);
if ($showsections) {
@@ -1873,7 +3768,7 @@ sub role_checkboxes {
if (grep(/^\Q$role\E$/,@current)) {
$checked = ' checked="checked" ';
}
- my $plrole=&Apache::lonnet::plaintext($role);
+ my $plrole=&Apache::lonnet::plaintext($role,$crstype);
if ($showsections) {
$output .= &Apache::loncommon::start_data_table_row();
} else {
@@ -1885,7 +3780,7 @@ sub role_checkboxes {
$output .= '';
}
}
- $output .= ' '.
$plrole.' ';
if ($showsections) {
@@ -1917,7 +3812,7 @@ sub role_checkboxes {
$output .= ' ';
}
}
- $output .= ' '.$rolename.
' ';
if ($showsections) {
@@ -1943,18 +3838,107 @@ sub role_checkboxes {
return $output;
}
+sub set_discussion_fonts {
+ my ($cdom,$cnum,$item,$settings) = @_;
+ my ($classorder,$classtitles) = &discussion_vote_classes();
+ my ($styleorder,$styleitems) = &discussion_vote_styles();
+ my $output;
+ if (ref($classorder) eq 'ARRAY') {
+ foreach my $cat (@{$classorder}) {
+ my %curr = ();
+ ($curr{'size'},$curr{'weight'},$curr{'style'},$curr{'other'}) =
+ split(/,/,$settings->{'discussion_post_fonts_'.$cat});
+ $output .= &Apache::loncommon::start_data_table_row().
+ ''.$classtitles->{$cat}.' ';
+ if (ref($styleorder) eq 'ARRAY') {
+ foreach my $item (@{$styleorder}) {
+ $output .= '';
+ my $selitem = $item;
+ if ($item eq 'size') {
+ my ($currsize,$currunit);
+ if ($curr{'size'} =~ /^(\d+)(px|%)$/) {
+ ($currsize,$currunit) = ($1,$2);
+ $curr{'size'} = $currunit;
+ }
+ $output .= ' '.
+ ' ';
+ $selitem = 'unit';
+ }
+ if ((ref($styleitems) eq 'HASH') && (ref($styleitems->{$item}) eq 'ARRAY')) {
+ $output .= '';
+ foreach my $val (@{$styleitems->{$item}}) {
+ my $sel;
+ if ($val eq $curr{$item}) {
+ $sel = ' selected="selected"';
+ }
+ $output .= ''.$val.' ';
+ }
+ }
+ }
+ }
+ $output .= ' ';
+ }
+ $output .= &Apache::loncommon::end_data_table_row();
+ }
+ return $output;
+}
+
+sub discussion_vote_classes {
+ my $classorder = ['twoplus','oneplus','zero','oneminus','twominus'];
+ my %classtitles = &Apache::lonlocal::texthash(
+ 'twoplus' => 'Two sigma above mean',
+ 'oneplus' => 'One sigma above mean',
+ 'zero' => 'Within one sigma of mean',
+ 'oneminus' => 'One sigma below mean',
+ 'twominus' => 'Two sigma below mean',
+ );
+ return ($classorder,\%classtitles);
+}
+
+sub discussion_vote_styles {
+ my $styleorder = ['size','weight','style'];
+ my $styleitems = {
+ size => ['','px','%','xx-small','x-small','small','medium','large',
+ 'x-large','xx-large','smaller','larger'],
+ weight => ['','normal','bold','bolder','lighter','100','200','300','400',
+ '500','600','700','800','900'],
+ style => ['','normal','italic','oblique'],
+ };
+ return ($styleorder,$styleitems);
+}
+
sub print_classlists {
- my ($position,$cdom,$settings,$itemtext,$rowtotal) = @_;
+ my ($position,$cdom,$settings,$itemtext,$rowtotal,$crstype) = @_;
my @ordered;
if ($position eq 'top') {
@ordered = ('default_enrollment_start_date',
'default_enrollment_end_date');
+ if ($crstype eq 'Course') {
+ push(@ordered,'defaultcredits');
+ }
} elsif ($position eq 'middle') {
- @ordered = ('nothideprivileged');
+ @ordered = ('nothideprivileged','checkforpriv');
} else {
@ordered = ('student_classlist_view',
- 'student_opt_in','student_classlist_portfiles');
+ 'student_classlist_opt_in',
+ 'student_classlist_portfiles');
+ }
+ my %lt;
+
+ if ($crstype eq 'Community') {
+ %lt = &Apache::lonlocal::texthash (
+ disabled => 'No viewable membership list',
+ section => "Membership of viewer's section",
+ all => 'List of all members',
+ );
+ } else {
+ %lt = &Apache::lonlocal::texthash (
+ disabled => 'No viewable classlist',
+ section => "Classlist of viewer's section",
+ all => 'Classlist of all students',
+ );
}
+
my %items = (
'default_enrollment_start_date' => {
text => ''.&mt($itemtext->{'default_enrollment_start_date'}).' ',
@@ -1964,24 +3948,28 @@ sub print_classlists {
text => ''.&mt($itemtext->{'default_enrollment_end_date'}).' ',
input => 'dates',
},
-
+ 'defaultcredits' => {
+ text => ''.&mt($itemtext->{'defaultcredits'}).' ',
+ },
+
'nothideprivileged' => {
text => ''.&mt($itemtext->{'nothideprivileged'}).' ',
input => 'checkbox',
},
+ 'checkforpriv' => {
+ text => ''.&mt($itemtext->{'checkforpriv'}).' ',
+ input => 'selectbox',
+ },
+
'student_classlist_view' => {
text => ''.&mt($itemtext->{'student_classlist_view'}).' ',
input => 'selectbox',
- options => {
- disabled => &mt('No viewable classlist'),
- section => &mt("Classlist of viewer's section"),
- all => &mt('Classlist of all students'),
- },
+ options => \%lt,
order => ['disabled','all','section'],
},
- 'student_opt_in' => {
- text => ''.&mt($itemtext->{'student_opt_in'}).' ',
+ 'student_classlist_opt_in' => {
+ text => ''.&mt($itemtext->{'student_classlist_opt_in'}).' ',
input => 'radio',
},
@@ -1994,14 +3982,20 @@ sub print_classlists {
($settings->{'student_classlist_view'} eq 'section')) {
$settings->{'student_classlist_view'} = 'disabled';
}
- return &make_item_rows($cdom,\%items,\@ordered,$settings,$rowtotal);
+ return &make_item_rows($cdom,\%items,\@ordered,$settings,$rowtotal,$crstype,'classlists');
}
sub print_appearance {
- my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
+ my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype) = @_;
unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
return;
}
+ my $mathdef;
+ if ($crstype eq 'Community') {
+ $mathdef = &mt("None specified - use member's choice");
+ } else {
+ $mathdef = &mt("None specified - use student's choice");
+ }
my %items = (
'default_xml_style' => {
text => ''.&mt($itemtext->{'default_xml_style'}).' '.
@@ -2024,24 +4018,32 @@ sub print_appearance {
text => ''.&mt($itemtext->{'texengine'}).' ',
input => 'selectbox',
options => {
- jsMath => 'jsMath',
+ MathJax => 'MathJax',
mimetex => &mt('Convert to Images'),
tth => &mt('TeX to HTML'),
},
- order => ['jsMath','mimetex','tth'],
- nullval => &mt("None specified - use student's choice"),
+ order => ['MathJax','mimetex','tth'],
+ nullval => $mathdef,
},
'tthoptions' => {
text => ''.&mt($itemtext->{'tthoptions'}).' ',
input => 'textbox',
size => 40,
},
+ 'uselcmath' => {
+ text => ''.&mt($itemtext->{'uselcmath'}).' ',
+ input => 'radio',
+ },
+ 'usejsme' => {
+ text => ''.&mt($itemtext->{'usejsme'}).' ',
+ input => 'radio',
+ },
);
- return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal);
+ return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'appearance');
}
sub print_grading {
- my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
+ my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype) = @_;
unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
return;
}
@@ -2052,15 +4054,16 @@ sub print_grading {
input => 'selectbox',
options => {
standard => &mt('Standard: shows points'),
+ categories => &mt('Categories: shows points according to categories'),
external => &mt('External: shows number of completed parts and totals'),
externalnototals => &mt('External: shows only number of completed parts'),
spreadsheet => &mt('Spreadsheet: (with link to detailed scores)'),
},
- order => ['standard','external','externalnototals','spreadsheet'],
+ order => ['standard','categories','external','externalnototals','spreadsheet'],
},
'rndseed' => {
text => ''.&mt($itemtext->{'rndseed'}).' '.
- ''.' '.
+ ''.' '.
&mt('Modifying this will make problems have different numbers and answers!').
' ',
input => 'selectbox',
@@ -2073,6 +4076,7 @@ sub print_grading {
'64bit5' => '64bit5',
},
order => ['32bit','64bit','64bit2','64bit3','64bit4','64bit5'],
+ advanced => 1
},
'receiptalg' => {
text => ''.&mt($itemtext->{'receiptalg'}).' '.
@@ -2084,17 +4088,18 @@ sub print_grading {
receipt3 => 'receipt3',
},
order => ['receipt','receipt2','receipt3'],
+ advanced => 1
},
'disablesigfigs' => {
text => ''.&mt($itemtext->{'disablesigfigs'}).' ',
input => 'radio',
},
);
- return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal);
+ return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'grading');
}
sub print_printouts {
- my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
+ my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype) = @_;
unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
return;
}
@@ -2122,7 +4127,7 @@ sub print_printouts {
A6 => &mt('A6').' [105x148 mm]',
},
order => ['Letter','Legal','Tabloid','Executive','A2','A3','A4','A5','A6'],
- nullval => 'None specified',
+ nullval => &mt('None specified'),
},
print_header_format => {
text => ''.&mt($itemtext->{'print_header_format'}).' ',
@@ -2132,12 +4137,22 @@ sub print_printouts {
text => ''.&mt($itemtext->{'disableexampointprint'}).' ',
input => 'radio',
},
+ canuse_pdfforms => {
+ text => ''.&mt($itemtext->{'canuse_pdfforms'}).' ',
+ input => 'selectbox',
+ options => {
+ 1 => &mt('Yes'),
+ 0 => &mt('No'),
+ },
+ order => ['1','0'],
+ nullval => &mt('None specified - use domain default'),
+ }
);
- return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal);
+ return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'printouts');
}
sub print_spreadsheet {
- my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
+ my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype) = @_;
unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
return;
}
@@ -2169,21 +4184,29 @@ sub print_spreadsheet {
input => 'radio',
},
);
- return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal);
-}
+ return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'spreadsheet');
+}
sub print_bridgetasks {
- my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
+ my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype) = @_;
unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
return;
}
+ my ($stumsg,$msgnote);
+ if ($crstype eq 'Community') {
+ $stumsg = &mt('Send message to member');
+ $msgnote = &mt('Message to member and add to user notes');
+ } else {
+ $stumsg = &mt('Send message to student');
+ $msgnote = &mt('Message to student and add to user notes');
+ }
my %items = (
task_messages => {
text => ''.&mt($itemtext->{'task_messages'}).' ',
input => 'selectbox',
options => {
- only_student => &mt('Send message to student'),
- student_and_user_notes_screen => &mt('Message to student and add to user notes'),
+ only_student => $stumsg,
+ student_and_user_notes_screen => $msgnote,
},
order => ['only_student','student_and_user_notes_screen'],
nullval => &mt('No message or record in user notes'),
@@ -2203,11 +4226,11 @@ sub print_bridgetasks {
input => 'radio',
},
);
- return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal);
+ return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'bridgetasks');
}
sub print_other {
- my ($cdom,$settings,$allitems,$rowtotal) = @_;
+ my ($cdom,$settings,$allitems,$rowtotal,$crstype) = @_;
unless ((ref($settings) eq 'HASH') && (ref($allitems) eq 'ARRAY')) {
return;
}
@@ -2228,7 +4251,7 @@ sub print_other {
input => 'textbox',
size => '30',
};
- my $output = &make_item_rows($cdom,\%items,\@ordered,$settings,$rowtotal);
+ my $output = &make_item_rows($cdom,\%items,\@ordered,$settings,$rowtotal,$crstype,'other');
}
sub get_other_items {
@@ -2245,7 +4268,10 @@ sub get_other_items {
unless (($parameter =~ m/^internal\./)||($parameter =~ m/^metadata\./) ||
($parameter =~ m/^selfenroll_/) || ($parameter =~ /_selfenroll$/)
|| ($parameter eq 'type') ||
- ($parameter =~ m/^(cc|in|ta|ep|ad|st)\.plaintext$/)) {
+ ($parameter =~ m/^(cc|co|in|ta|ep|ad|st)\.plaintext$/)
+ || ($parameter =~ m/^discussion_post_fonts/) ||
+ ($parameter =~ m{^(minimal|updated|uploaded|external)syllabus$}) ||
+ ($parameter eq 'clonedfrom')) {
push(@ordered,$parameter);
}
}
@@ -2254,15 +4280,18 @@ sub get_other_items {
}
sub item_table_row_start {
- my ($text,$count) = @_;
+ my ($text,$count,$add_class,$colspan) = @_;
my $output;
- if ($count%2) {
- $output .= '';
+ my $css_class = ($count % 2) ? 'LC_odd_row' : 'LC_even_row';
+ $css_class = (join(' ',$css_class,$add_class)) unless ($add_class eq '');
+ $output .= ' '."\n".
+ ''.$text.
+ ' ';
+ if ($colspan) {
+ $output .= '';
} else {
- $output .= ' ';
+ $output .= '';
}
- $output .= ' '.$text.
- ' ';
return $output;
}
@@ -2271,20 +4300,30 @@ sub item_table_row_end {
}
sub yesno_radio {
- my ($item,$settings) = @_;
+ my ($item,$settings,$unsetdefault,$valueyes,$valueno) = @_;
my $itemon = ' ';
my $itemoff = ' checked="checked" ';
+ if (($valueyes eq '') && ($valueno eq '')) {
+ $valueyes = 'yes';
+ $valueno = '';
+ }
if (ref($settings) eq 'HASH') {
- if ($settings->{$item} eq 'yes') {
+ if ($settings->{$item} eq $valueyes) {
$itemon = $itemoff;
$itemoff = ' ';
}
+ unless (exists($settings->{$item})) {
+ if ($unsetdefault eq $valueyes) {
+ $itemon = $itemoff;
+ $itemoff = ' ';
+ }
+ }
}
return ''.
' '.&mt('Yes').' '.
+ $itemon.' value="'.$valueyes.'" />'.&mt('Yes').' '.
' '.&mt('No').' ';
+ $itemoff.' value="'.$valueno.'" />'.&mt('No').'';
}
sub select_from_options {
@@ -2333,15 +4372,35 @@ sub select_from_options {
}
sub make_item_rows {
- my ($cdom,$items,$ordered,$settings,$rowtotal) = @_;
+ my ($cdom,$items,$ordered,$settings,$rowtotal,$crstype,$caller) = @_;
my $datatable;
if ((ref($items) eq 'HASH') && (ref($ordered) eq 'ARRAY')) {
my $count = 0;
foreach my $item (@{$ordered}) {
$count ++;
- $datatable .= &item_table_row_start($items->{$item}{text},$count);
- if ($item eq 'nothideprivileged') {
- $datatable .= ¬hidepriv_row($cdom,$item,$settings);
+ my $colspan;
+ if ((($caller eq 'classlists') && ($item eq 'nothideprivileged')) ||
+ (($caller eq 'printouts') && ($item ne 'print_header_format'))) {
+ $colspan = 2;
+ }
+ 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 ($item eq 'defaultcredits') {
+ my $defaultcredits = $env{'course.'.$env{'request.course.id'}.'.internal.defaultcredits'};
+ my $showcredits;
+ if ($defaultcredits ne '') {
+ $showcredits = &mt('Default is [quant,_1,credit]',$defaultcredits);
+ } else {
+ $showcredits = &mt('No default set');
+ }
+ $datatable .= $showcredits;
+ } elsif ($item eq 'nothideprivileged') {
+ $datatable .= ¬hidepriv_row($cdom,$item,$settings,$crstype);
+ } elsif ($item eq 'checkforpriv') {
+ $datatable .= &checkforpriv_row($cdom,$item,$settings,$crstype);
} elsif ($item eq 'print_header_format') {
$datatable .= &print_hdrfmt_row($item,$settings);
} elsif ($items->{$item}{input} eq 'dates') {
@@ -2349,7 +4408,16 @@ sub make_item_rows {
&Apache::lonhtmlcommon::date_setter('display',$item,
$settings->{$item});
} elsif ($items->{$item}{input} eq 'radio') {
- $datatable .= &yesno_radio($item,$settings);
+ my ($unsetdefault,$valueyes,$valueno);
+ if (($item eq 'usejsme') || ($item eq 'uselcmath')) {
+ my %domdefs = &Apache::lonnet::get_domain_defaults($cdom);
+ unless ($domdefs{$item} eq '0') {
+ $unsetdefault = 1;
+ }
+ $valueyes = "1";
+ $valueno = "0";
+ }
+ $datatable .= &yesno_radio($item,$settings,$unsetdefault,$valueyes,$valueno);
} elsif ($items->{$item}{input} eq 'selectbox') {
my $curr = $settings->{$item};
$datatable .=
@@ -2371,10 +4439,9 @@ sub make_item_rows {
}
sub nothidepriv_row {
- my ($cdom,$item,$settings) = @_;
+ my ($cdom,$item,$settings,$crstype) = @_;
my ($cnum) = &get_course();
- my %nothide;
- my $datatable;
+ my ($datatable,%nothide,@checkdoms);
if (ref($settings) eq 'HASH') {
if ($settings->{$item} ne '') {
foreach my $user (split(/\s*\,\s*/,$settings->{$item})) {
@@ -2385,38 +4452,30 @@ sub nothidepriv_row {
}
}
}
+ if ($settings->{'checkforpriv'}) {
+ @checkdoms = split(/,/,$settings->{'checkforpriv'});
+ }
}
- my %coursepersonnel = &Apache::lonnet::dump('nohist_userroles',$cdom,$cnum);
- my $now = time;
+ push(@checkdoms,$cdom);
+ my %coursepersonnel =
+ &Apache::lonnet::get_my_roles($cnum,$cdom,'',['previous','future','active']);
my @privusers;
- my %privileged;
foreach my $person (keys(%coursepersonnel)) {
- my ($role,$user,$usec) = ($person =~ /^([^:]*):([^:]+:[^:]+):([^:]*)/);
- $user =~ s/:$//;
- my ($end,$start) = split(/:/,$coursepersonnel{$person});
+ my ($uname,$udom,$role) = split(/:/,$person);
+ my $user = $uname.':'.$udom;
+ my ($start,$end) = split(/:/,$coursepersonnel{$person});
if ($end == -1 || $start == -1) {
next;
}
- my ($uname,$udom) = split(':',$user);
- unless (ref($privileged{$udom}) eq 'HASH') {
- my %dompersonnel = &Apache::lonnet::get_domain_roles($udom,['dc'],undef,$now);
- $privileged{$udom} = {};
- if (keys(%dompersonnel)) {
- foreach my $server (keys(%dompersonnel)) {
- foreach my $user (sort(keys(%{$dompersonnel{$server}}))) {
- my ($trole,$uname,$udom) = split(/:/,$user);
- $privileged{$udom}{$uname} = $trole;
- }
+ foreach my $dom (@checkdoms) {
+ if (&Apache::lonnet::privileged($uname,$udom,\@checkdoms,['dc','su'])) {
+ unless (grep(/^\Q$user\E$/,@privusers)) {
+ push(@privusers,$user);
}
}
}
- if (exists($privileged{$udom}{$uname})) {
- unless (grep(/^\Q$user\E$/,@privusers)) {
- push(@privusers,$user);
- }
- }
}
- if (@privusers) {
+ if (@privusers > 0) {
$datatable .= '';
} else {
- $datatable .= &mt('No Domain Coordinators have course roles');
+ if ($crstype eq 'Community') {
+ $datatable .= &mt('No Domain Coordinators have community roles');
+ } else {
+ $datatable .= &mt('No Domain Coordinators have course roles');
+ }
+ }
+ return $datatable;
+}
+
+sub checkforpriv_row {
+ my ($cdom,$item,$settings,$crstype) = @_;
+ my $datatable;
+ my %domains=map { $_ => 1; } &Apache::lonnet::all_domains();
+ if (keys(%domains) == 1) {
+ $datatable = ' '.
+ &mt("Course's domain is only domain");
+ return $datatable;
+ }
+ my @excdoms = ($cdom);
+ my $num = 0;
+ if ($settings->{$item} eq '') {
+ $datatable = ' '.
+ &Apache::loncommon::select_dom_form('','checkforpriv_'.$num,
+ 1,1,undef,undef,\@excdoms);
+ } else {
+ my @privdoms = split(/,/,$settings->{$item});
+ my %domains=map { $_ => 1; } &Apache::lonnet::all_domains();
+ $datatable = ' '.
+ &Apache::loncommon::start_data_table();
+ if (@privdoms > 0) {
+ foreach my $currdom (@privdoms) {
+ next unless ($domains{$currdom});
+ my $domdesc = &Apache::lonnet::domain($currdom,'description');
+ if ($domdesc eq '') {
+ $domdesc = $currdom;
+ }
+ $datatable .=
+ &Apache::loncommon::start_data_table_row().
+ ''.
+ &mt('Domain:').' '.$domdesc.
+ ' '.
+ ' '.
+ &mt('Delete').' '.
+ &Apache::loncommon::end_data_table_row();
+ $num ++;
+ unless (grep(/^\Q$currdom\E$/,@excdoms)) {
+ push(@excdoms,$currdom);
+ }
+ }
+ }
+ if ((scalar(keys(%domains)) - scalar(@excdoms)) > 0) {
+ $datatable .=
+ &Apache::loncommon::start_data_table_row().
+ ''.
+ &mt('Additional domain:'). ' '.
+ &Apache::loncommon::select_dom_form('','checkforpriv_'.$num,1,
+ 1,undef,undef,\@excdoms).
+ ' '.&Apache::loncommon::end_data_table_row();
+ }
+ $datatable .= &Apache::loncommon::end_data_table().
+ ' '.
+ ' ';
}
return $datatable;
}
@@ -2454,9 +4577,9 @@ sub print_hdrfmt_row {
$currstr .= ''.&mt('Current print header:').' '.
$settings->{$item}.' ';
my @current = split(/(%\d*[nca])/,$settings->{$item});
- foreach my $item (@current) {
- unless ($item eq '') {
- push(@curr,$item);
+ foreach my $val (@current) {
+ unless ($val eq '') {
+ push(@curr,$val);
}
}
$currnum = @curr;
@@ -2516,7 +4639,8 @@ function getIndexByName(item) {
ENDJS
- $output .= $currstr.'';
+ $output .= ' '.
+ $currstr.'';
if (@curr > 0) {
for (my $i=0; $i<@curr; $i++) {
my $pos = $i+1;
@@ -2543,7 +4667,7 @@ ENDJS
&position_selector($pos,$currnum,$maxnum).
''.&mt('New').' '.
&substitution_selector($currnum).' '.
- '';
+ '';
$pos ++;
$currnum ++;
$output .= ''.
@@ -2556,7 +4680,7 @@ ENDJS
' '.
' '.
- '
';
+ '
';
return $output;
}
@@ -2576,14 +4700,22 @@ sub position_selector {
}
sub substitution_selector {
- my ($num,$subst,$limit) = @_;
+ my ($num,$subst,$limit,$crstype) = @_;
+ my ($stunametxt,$crsidtxt);
+ if ($crstype eq 'Community') {
+ $stunametxt = 'member name';
+ $crsidtxt = 'community ID',
+ } else {
+ $stunametxt = 'student name';
+ $crsidtxt = 'course ID',
+ }
my %lt = &Apache::lonlocal::texthash(
- n => 'student name',
- c => 'course ID',
+ n => $stunametxt,
+ c => $crsidtxt,
a => 'assignment note',
);
my $output .= &mt('Substitution').' '.
- '';
+ '';
if ($subst eq '') {
$output .= ' ';
}
@@ -2601,4 +4733,70 @@ sub substitution_selector {
return $output;
}
+sub change_clone {
+ my ($cdom,$cnum,$clonelist,$oldcloner) = @_;
+ my $clone_crs = $cnum.':'.$cdom;
+ if ($cnum && $cdom) {
+ my $clone_crs = $cnum.':'.$cdom;
+ my @allowclone;
+ if ($clonelist =~ /,/) {
+ @allowclone = split(',',$clonelist);
+ } else {
+ $allowclone[0] = $clonelist;
+ }
+ foreach my $currclone (@allowclone) {
+ if (!grep(/^$currclone$/,@$oldcloner)) {
+ if ($currclone ne '*') {
+ if ($currclone =~ /:/) {
+ my ($uname,$udom) = split(/:/,$currclone);
+ if ($uname && $udom && $uname ne '*') {
+ if (&Apache::lonnet::homeserver($uname,$udom) ne 'no_host') {
+ my %currclonecrs = &Apache::lonnet::dump('environment',$udom,$uname,'cloneable');
+ if ($currclonecrs{'cloneable'} !~ /\Q$clone_crs\E/) {
+ if ($currclonecrs{'cloneable'} eq '') {
+ $currclonecrs{'cloneable'} = $clone_crs;
+ } else {
+ $currclonecrs{'cloneable'} .= ','.$clone_crs;
+ }
+ &Apache::lonnet::put('environment',\%currclonecrs,$udom,$uname);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ foreach my $oldclone (@$oldcloner) {
+ if (!grep(/^\Q$oldclone\E$/,@allowclone)) {
+ if ($oldclone ne '*') {
+ if ($oldclone =~ /:/) {
+ my ($uname,$udom) = split(/:/,$oldclone);
+ if ($uname && $udom && $uname ne '*' ) {
+ if (&Apache::lonnet::homeserver($uname,$udom) ne 'no_host') {
+ my %currclonecrs = &Apache::lonnet::dump('environment',$udom,$uname,'cloneable');
+ my %newclonecrs = ();
+ if ($currclonecrs{'cloneable'} =~ /\Q$clone_crs\E/) {
+ if ($currclonecrs{'cloneable'} =~ /,/) {
+ my @currclonecrs = split/,/,$currclonecrs{'cloneable'};
+ foreach my $crs (@currclonecrs) {
+ if ($crs ne $clone_crs) {
+ $newclonecrs{'cloneable'} .= $crs.',';
+ }
+ }
+ $newclonecrs{'cloneable'} =~ s/,$//;
+ } else {
+ $newclonecrs{'cloneable'} = '';
+ }
+ &Apache::lonnet::put('environment',\%newclonecrs,$udom,$uname);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return;
+}
+
1;