+
+
+
+
ENDHEAD
+}
- $r->print(''.$message.' Sort list by ');
- $r->print('');
- $r->print('Enclosing Map ');
- map {
- $r->print('print(' selected'); }
- $r->print('>'.$allkeys{$_}.' ');
- } keys %allkeys;
- $r->print(' ');
-# ----------------------------------------------------------------- Start Table
- my $coursespan=$csec?8:5;
- $r->print(<
-
-Any User
-ENDTABLEHEAD
- if ($uname) {
- $r->print("User $uname at Domain $udom ");
+
+sub print_row {
+ my ($r,$which,$part,$name,$symbp,$rid,$default,$defaulttype,$display,$defbgone,
+ $defbgtwo,$defbgthree,$parmlev,$uname,$udom,$csec,$cgroup,$usersgroups)=@_;
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
+# get the values for the parameter in cascading order
+# empty levels will remain empty
+ my ($result,@outpar)=&parmval($$part{$which}.'.'.$$name{$which},
+ $rid,$$default{$which},$uname,$udom,$csec,$cgroup,$courseopt);
+# get the type for the parameters
+# problem: these may not be set for all levels
+ my ($typeresult,@typeoutpar)=&parmval($$part{$which}.'.'.
+ $$name{$which}.'.type',$rid,
+ $$defaulttype{$which},$uname,$udom,$csec,$cgroup,$courseopt);
+# cascade down manually
+ my $cascadetype=$$defaulttype{$which};
+ for (my $i=14;$i>0;$i--) {
+ if ($typeoutpar[$i]) {
+ $cascadetype=$typeoutpar[$i];
+ } else {
+ $typeoutpar[$i]=$cascadetype;
+ }
}
- $r->print(<Parameter in Effect
-Resource Level
-in Course
-ENDTABLETWO
- if ($csec) {
- $r->print("in Section/Group $csec ");
+ my $parm=$$display{$which};
+
+ if ($parmlev eq 'full') {
+ $r->print(''
+ .$$part{$which}.' ');
+ } else {
+ $parm=~s|\[.*\]\s||g;
}
- $r->print(<Assessment URL and Title Type
-Enclosing Map Part No. Parameter Name
-default from Enclosing Map
-general for Enclosing Map for Resource
-ENDTABLEHEADFOUR
- if ($csec) {
- $r->print('general for Enclosing Map for Resource ');
+ my $automatic=&rulescache(($which=~/\_([^\_]+)$/)[0].'_triggers');
+ if ($automatic) {
+ $parm.=' '.&mt('Automatically sets').' '.join(', ',split(/\:/,$automatic)).' ';
+ }
+ $r->print(''.$parm.' ');
+
+ my $thismarker=$which;
+ $thismarker=~s/^parameter\_//;
+ my $mprefix=$rid.'&'.$thismarker.'&';
+ my $effective_parm = &valout($outpar[$result],$typeoutpar[$result]);
+ my ($othergrp,$grp_parm,$controlgrp);
+
+ if ($parmlev eq 'general') {
+
+ if ($uname) {
+ &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ } elsif ($cgroup) {
+ &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ } elsif ($csec) {
+ &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ } else {
+ &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ }
+ } elsif ($parmlev eq 'map') {
+
+ if ($uname) {
+ &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ } elsif ($cgroup) {
+ &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ } elsif ($csec) {
+ &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ } else {
+ &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ }
+ } else {
+ if ($uname) {
+ if (@{$usersgroups} > 1) {
+ my ($coursereply,$grp_parm,$controlgrp);
+ ($coursereply,$othergrp,$grp_parm,$controlgrp) =
+ &print_usergroups($r,$$part{$which}.'.'.$$name{$which},
+ $rid,$cgroup,$defbgone,$usersgroups,$result,$courseopt);
+ if ($coursereply && $result > 3) {
+ if (defined($controlgrp)) {
+ if ($cgroup ne $controlgrp) {
+ $effective_parm = $grp_parm;
+ $result = 0;
+ }
+ }
+ }
+ }
+ }
+
+ &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+
+ &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ &print_td($r,12,'#FFDDDD',$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ &print_td($r,11,'#FFDDDD',$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ &print_td($r,10,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+
+ if ($csec) {
+ &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ &print_td($r,7,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ }
+
+ if ($cgroup) {
+ &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ &print_td($r,4,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ }
+
+ if ($uname) {
+ if ($othergrp) {
+ $r->print($othergrp);
+ }
+ &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ &print_td($r,1,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
+ }
+
+ } # end of $parmlev if/else
+ $r->print(''.$effective_parm.' ');
+
+ if ($parmlev eq 'full') {
+ my $sessionval=&Apache::lonnet::EXT('resource.'.$$part{$which}.
+ '.'.$$name{$which},$$symbp{$rid});
+ my $sessionvaltype=$typeoutpar[$result];
+ if (!defined($sessionvaltype)) { $sessionvaltype=$$defaulttype{$which}; }
+ $r->print(''.
+ &valout($sessionval,$sessionvaltype).' '.
+ ' ');
+ }
+ $r->print(' ');
+ $r->print("\n");
+}
+
+sub print_td {
+ my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display)=@_;
+ $r->print('');
+ if ($which<11 || $which > 12) {
+ $r->print(&plink($$typeoutpar[$which],
+ $$display{$value},$$outpar[$which],
+ $mprefix."$which",'parmform.pres','psub'));
+ } else {
+ $r->print(&valout($$outpar[$which],$$typeoutpar[$which]));
}
+ $r->print(' '."\n");
+}
+
+sub print_usergroups {
+ my ($r,$what,$rid,$cgroup,$defbg,$usersgroups,$result,$courseopt) = @_;
+ my $courseid = $env{'request.course.id'};
+ my $output;
+ my $symb = &symbcache($rid);
+ my $symbparm=$symb.'.'.$what;
+ my $map=(&Apache::lonnet::decode_symb($symb))[0];
+ my $mapparm=$map.'___(all).'.$what;
+ my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype) =
+ &parm_control_group($courseid,$usersgroups,$symbparm,$mapparm,$what,
+ $courseopt);
+ my $bgcolor = $defbg;
+ my $grp_parm;
+ if (($coursereply) && ($cgroup ne $resultgroup)) {
+ if ($result > 3) {
+ $bgcolor = '"#AAFFAA"';
+ $grp_parm = &valout($coursereply,$resulttype);
+ }
+ $grp_parm = &valout($coursereply,$resulttype);
+ $output = '';
+ if ($resultgroup && $resultlevel) {
+ $output .= ''.$resultgroup.' ('.$resultlevel.'): '.$grp_parm;
+ } else {
+ $output .= ' ';
+ }
+ $output .= ' ';
+ } else {
+ $output .= ' ';
+ }
+ return ($coursereply,$output,$grp_parm,$resultgroup);
+}
+
+sub parm_control_group {
+ my ($courseid,$usersgroups,$symbparm,$mapparm,$what,$courseopt) = @_;
+ my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype);
+ my $grpfound = 0;
+ my @levels = ($symbparm,$mapparm,$what);
+ my @levelnames = ('resource','map/folder','general');
+ foreach my $group (@{$usersgroups}) {
+ if ($grpfound) { last; }
+ for (my $i=0; $i<@levels; $i++) {
+ my $item = $courseid.'.['.$group.'].'.$levels[$i];
+ if (defined($$courseopt{$item})) {
+ $coursereply = $$courseopt{$item};
+ $resultitem = $item;
+ $resultgroup = $group;
+ $resultlevel = $levelnames[$i];
+ $resulttype = $$courseopt{$item.'.type'};
+ $grpfound = 1;
+ last;
+ }
+ }
+ }
+ return($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype);
+}
+
+=pod
+
+=item B: Given the course data hash, extractResourceInformation extracts lots of information about the course's resources into a variety of hashes.
+
+Input: See list below:
+
+=over 4
+
+=item B: An array that will contain all of the ids in the course.
+
+=item B: hash, id->type, where "type" contains the extension of the file, thus, I.
+
+=item B: hash, id->key list, will contain a comma separated list of the meta-data keys available for the given id
+
+=item B: hash, name of parameter->display value (what is the display value?)
+
+=item B: hash, part identification->text representation of part, where the text representation is "[Part $part]"
+
+=item B: hash, full key to part->display value (what's display value?)
+
+=item B: hash, ???
+
+=item B: ???
+
+=item B: hash, ???
+
+=item B: ??
+
+=item B: hash, id->full sym?
+
+=back
+
+=cut
+
+sub extractResourceInformation {
+ my $ids = shift;
+ my $typep = shift;
+ my $keyp = shift;
+ my $allparms = shift;
+ my $allparts = shift;
+ my $allmaps = shift;
+ my $mapp = shift;
+ my $symbp = shift;
+ my $maptitles=shift;
+ my $uris=shift;
+ my $keyorder=shift;
+ my $defkeytype=shift;
+
+ my $keyordercnt=100;
+
+ my $navmap = Apache::lonnavmaps::navmap->new();
+ my @allres=$navmap->retrieveResources(undef,undef,1,undef,1);
+ foreach my $resource (@allres) {
+ my $id=$resource->id();
+ my ($mapid,$resid)=split(/\./,$id);
+ if ($mapid eq '0') { next; }
+ $$ids[$#$ids+1]=$id;
+ my $srcf=$resource->src();
+ $srcf=~/\.(\w+)$/;
+ $$typep{$id}=$1;
+ $$keyp{$id}='';
+ $$uris{$id}=$srcf;
+ foreach my $key (split(/\,/,&Apache::lonnet::metadata($srcf,'allpossiblekeys'))) {
+ next if ($key!~/^parameter_/);
+
+# Hidden parameters
+ next if (&Apache::lonnet::metadata($srcf,$key.'.hidden') eq 'parm');
+#
+# allparms is a hash of parameter names
+#
+ my $name=&Apache::lonnet::metadata($srcf,$key.'.name');
+ if (!exists($$allparms{$name}) || $$allparms{$name} =~ m/^\s*$/ ) {
+ my $display= &Apache::lonnet::metadata($srcf,$key.'.display');
+ my $parmdis = $display;
+ $parmdis =~ s/\s*\[Part.*$//g;
+ $$allparms{$name}=$parmdis;
+ if (ref($defkeytype)) {
+ $$defkeytype{$name}=
+ &Apache::lonnet::metadata($srcf,$key.'.type');
+ }
+ }
+
+#
+# allparts is a hash of all parts
+#
+ my $part= &Apache::lonnet::metadata($srcf,$key.'.part');
+ $$allparts{$part} = &mt('Part: [_1]',$part);
+#
+# Remember all keys going with this resource
+#
+ if ($$keyp{$id}) {
+ $$keyp{$id}.=','.$key;
+ } else {
+ $$keyp{$id}=$key;
+ }
+#
+# Put in order
+#
+ unless ($$keyorder{$key}) {
+ $$keyorder{$key}=$keyordercnt;
+ $keyordercnt++;
+ }
+ }
+
+
+ if (!exists($$mapp{$mapid})) {
+ $$mapp{$id}=
+ &Apache::lonnet::declutter($resource->enclosing_map_src());
+ $$mapp{$mapid}=$$mapp{$id};
+ $$allmaps{$mapid}=$$mapp{$id};
+ if ($mapid eq '1') {
+ $$maptitles{$mapid}=&mt('Main Course Documents');
+ } else {
+ $$maptitles{$mapid}=
+ &Apache::lonnet::gettitle($$mapp{$id});
+ }
+ $$maptitles{$$mapp{$id}}=$$maptitles{$mapid};
+ $$symbp{$mapid}=$$mapp{$id}.'___(all)';
+ } else {
+ $$mapp{$id} = $$mapp{$mapid};
+ }
+ $$symbp{$id}=&Apache::lonnet::encode_symb($$mapp{$id},$resid,$srcf);
+ }
+}
+
+
+##################################################
+##################################################
+
+sub isdateparm {
+ my $type=shift;
+ return (($type=~/^date/) && (!($type eq 'date_interval')));
+}
+
+sub parmmenu {
+ my ($r,$allparms,$pscat,$keyorder)=@_;
+ my $tempkey;
+ $r->print(<
+ function checkall(value, checkName) {
+ for (i=0; i
+ENDSCRIPT
+ $r->print();
+ $r->print("\n'
+ );
+}
+
+sub partmenu {
+ my ($r,$allparts,$psprt)=@_;
+ $r->print('');
+ $r->print('print(' selected="selected"') unless (@{$psprt});
+ $r->print('>'.&mt('All Parts').' ');
+ my %temphash=();
+ foreach (@{$psprt}) { $temphash{$_}=1; }
+ foreach my $tempkey (sort {
+ if ($a==$b) { return ($a cmp $b) } else { return ($a <=> $b); }
+ } keys(%{$allparts})) {
+ unless ($tempkey =~ /\./) {
+ $r->print('print(' selected="selected"');
+ }
+ $r->print('>'.$$allparts{$tempkey}.' ');
+ }
+ }
+ $r->print(' ');
+}
+
+sub usermenu {
+ my ($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,$usersgroups)=@_;
+ my $chooseopt=&Apache::loncommon::select_dom_form($udom,'udom').' '.
+ &Apache::loncommon::selectstudent_link('parmform','uname','udom');
+ my $selscript=&Apache::loncommon::studentbrowser_javascript();
+
+ my $sections='';
+ my %sectionhash = &Apache::loncommon::get_sections();
+
+ my $groups;
+ my %grouphash = &Apache::longroup::coursegroups();
+
+ my $g_s_header='';
+ my $g_s_footer='';
+
+ if (%sectionhash) {
+ $sections=&mt('Section:').' '.$section.
+ '';
+ }
+ $sections.=' ';
+ }
+
+ if (%sectionhash && %grouphash && $parmlev ne 'full') {
+ $sections .= ' '.&mt('or').' ';
+ $sections .= qq|
+
+|;
+ } else {
+ $sections .= qq|
+
+|;
+ }
+
+ if (%grouphash) {
+ $groups=&mt('Group:').' ';
+ }
+ $groups.=' ';
+ }
+
+ if (%sectionhash || %grouphash) {
+ $g_s_header=''.&mt('Group/Section').' ';
+ $g_s_footer='
';
+ }
+
+ $r->print(''
+ .$g_s_header
+ .$sections
+ .$groups
+ .$g_s_footer
+ .''.&mt('User').' '
+ .&mt('For User [_1] or Student/Employee ID [_2] at Domain [_3]'
+ ,' '
+ ,' '
+ ,$chooseopt)
+ .'
'
+ .' '
+ );
+}
+
+sub displaymenu {
+ my ($r,$allparms,$allparts,$pscat,$psprt,$keyorder)=@_;
+ $r->print(''.&mt('Select Parameters to View').' '.
+ &mt('Select Parts to View').' ');
+ &parmmenu($r,$allparms,$pscat,$keyorder);
+ $r->print(' ');
+ &partmenu($r,$allparts,$psprt);
+ $r->print('
');
+}
+
+sub mapmenu {
+ my ($r,$allmaps,$pschp,$maptitles)=@_;
+ $r->print(''.&mt('Select Enclosing Map or Folder').' ');
+ $r->print('');
+ $r->print(''.&mt('All Maps or Folders').' ');
+ foreach (sort {$$allmaps{$a} cmp $$allmaps{$b}} keys %{$allmaps}) {
+ $r->print('print(' selected="selected"'); }
+ $r->print('>'.$$maptitles{$_}.($$allmaps{$_}!~/^uploaded/?' ['.$$allmaps{$_}.']':'').' ');
+ }
+ $r->print(" ");
+}
+
+sub levelmenu {
+ my ($r,$alllevs,$parmlev)=@_;
+ $r->print(''.&mt('Select Parameter Level').
+ &Apache::loncommon::help_open_topic('Course_Parameter_Levels').' ');
+ $r->print('');
+ foreach (reverse sort keys %{$alllevs}) {
+ $r->print('print(' selected="selected"');
+ }
+ $r->print('>'.&mt($_).' ');
+ }
+ $r->print(" ");
+}
+
+
+sub sectionmenu {
+ my ($r,$selectedsections)=@_;
+ my %sectionhash = &Apache::loncommon::get_sections();
+ return if (!%sectionhash);
+
+ $r->print('');
+ foreach my $s ('all',sort keys %sectionhash) {
+ $r->print(' print(' selected="selected"');
+ last;
+ }
+ }
+ $r->print('>'.$s." \n");
+ }
+ $r->print(" \n");
+}
+
+sub groupmenu {
+ my ($r,$selectedgroups)=@_;
+ my %grouphash = &Apache::longroup::coursegroups();
+ return if (!%grouphash);
+
+ $r->print('');
+ foreach my $group (sort(keys(%grouphash))) {
+ $r->print(' print(' selected="selected"');
+ last;
+ }
+ }
+ $r->print('>'.$group." \n");
+ }
+ $r->print(" \n");
+}
+
+
+sub keysplit {
+ my $keyp=shift;
+ return (split(/\,/,$keyp));
+}
+
+sub keysinorder {
+ my ($name,$keyorder)=@_;
+ return sort {
+ $$keyorder{$a} <=> $$keyorder{$b};
+ } (keys %{$name});
+}
+
+sub keysinorder_bytype {
+ my ($name,$keyorder)=@_;
+ return sort {
+ my $ta=(split('_',$a))[-1];
+ my $tb=(split('_',$b))[-1];
+ if ($$keyorder{'parameter_0_'.$ta} == $$keyorder{'parameter_0_'.$tb}) {
+ return ($a cmp $b);
+ }
+ $$keyorder{'parameter_0_'.$ta} <=> $$keyorder{'parameter_0_'.$tb};
+ } (keys %{$name});
+}
+
+sub keysindisplayorder {
+ my ($name,$keyorder)=@_;
+ return sort {
+ $$keyorder{'parameter_0_'.$a} <=> $$keyorder{'parameter_0_'.$b};
+ } (keys %{$name});
+}
+
+sub sortmenu {
+ my ($r,$sortorder)=@_;
+ $r->print(' print(' checked="on"');
+ }
+ $r->print(' />'.&mt('Sort by realm first, then student (group/section)'));
+ $r->print(' print(' checked="on"');
+ }
+ $r->print(' />'.&mt('Sort by student (group/section) first, then realm').
+ ' ');
+}
+
+sub standardkeyorder {
+ return ('parameter_0_opendate' => 1,
+ 'parameter_0_duedate' => 2,
+ 'parameter_0_answerdate' => 3,
+ 'parameter_0_interval' => 4,
+ 'parameter_0_weight' => 5,
+ 'parameter_0_maxtries' => 6,
+ 'parameter_0_hinttries' => 7,
+ 'parameter_0_contentopen' => 8,
+ 'parameter_0_contentclose' => 9,
+ 'parameter_0_type' => 10,
+ 'parameter_0_problemstatus' => 11,
+ 'parameter_0_hiddenresource' => 12,
+ 'parameter_0_hiddenparts' => 13,
+ 'parameter_0_display' => 14,
+ 'parameter_0_ordered' => 15,
+ 'parameter_0_tol' => 16,
+ 'parameter_0_sig' => 17,
+ 'parameter_0_turnoffunit' => 18,
+ 'parameter_0_discussend' => 19,
+ 'parameter_0_discusshide' => 20);
+}
+
+##################################################
+##################################################
+
+=pod
+
+=item assessparms
+
+Show assessment data and parameters. This is a large routine that should
+be simplified and shortened... someday.
+
+Inputs: $r
+
+Returns: nothing
+
+Variables used (guessed by Jeremy):
+
+=over 4
+
+=item B: ParameterS CATegories? ends up a list of the types of parameters that exist, e.g., tol, weight, acc, opendate, duedate, answerdate, sig, maxtries, type.
+
+=item B: ParameterS PaRTs? a list of the parts of a problem that we are displaying? Used to display only selected parts?
+
+=item B:
+
+=back
+
+=cut
+
+##################################################
+##################################################
+sub assessparms {
+
+ my $r=shift;
+
+ my @ids=();
+ my %symbp=();
+ my %mapp=();
+ my %typep=();
+ my %keyp=();
+ my %uris=();
+ my %maptitles=();
+
+# -------------------------------------------------------- Variable declaration
+
+ my %allmaps=();
+ my %alllevs=();
+
+ my $uname;
+ my $udom;
+ my $uhome;
+ my $csec;
+ my $cgroup;
+ my @usersgroups = ();
+
+ my $coursename=$env{'course.'.$env{'request.course.id'}.'.description'};
+
+ $alllevs{'Resource Level'}='full';
+ $alllevs{'Map/Folder Level'}='map';
+ $alllevs{'Course Level'}='general';
+
+ my %allparms;
+ my %allparts;
+#
+# Order in which these parameters will be displayed
+#
+ my %keyorder=&standardkeyorder();
+
+ @ids=();
+ %symbp=();
+ %typep=();
+
+ my $message='';
+
+ $csec=$env{'form.csec'};
+ $cgroup=$env{'form.cgroup'};
+
+ if ($udom=$env{'form.udom'}) {
+ } elsif ($udom=$env{'request.role.domain'}) {
+ } elsif ($udom=$env{'user.domain'}) {
+ } else {
+ $udom=$r->dir_config('lonDefDomain');
+ }
+
+ my @pscat=&Apache::loncommon::get_env_multiple('form.pscat');
+ my $pschp=$env{'form.pschp'};
+ my @psprt=&Apache::loncommon::get_env_multiple('form.psprt');
+ if (!@psprt) { $psprt[0]='0'; }
+
+ my $pssymb='';
+ my $parmlev='';
+
+ unless ($env{'form.parmlev'}) {
+ $parmlev = 'map';
+ } else {
+ $parmlev = $env{'form.parmlev'};
+ }
+
+# ----------------------------------------------- Was this started from grades?
+
+ if (($env{'form.command'} eq 'set') && ($env{'form.url'})
+ && (!$env{'form.dis'})) {
+ my $url=$env{'form.url'};
+ $url=~s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
+ $pssymb=&Apache::lonnet::symbread($url);
+ if (!@pscat) { @pscat=('all'); }
+ $pschp='';
+ $parmlev = 'full';
+ } elsif ($env{'form.symb'}) {
+ $pssymb=$env{'form.symb'};
+ if (!@pscat) { @pscat=('all'); }
+ $pschp='';
+ $parmlev = 'full';
+ } else {
+ $env{'form.url'}='';
+ }
+
+ my $id=$env{'form.id'};
+ if (($id) && ($udom)) {
+ $uname=(&Apache::lonnet::idget($udom,$id))[1];
+ if ($uname) {
+ $id='';
+ } else {
+ $message=
+ ''.&mt("Unknown ID")." '$id' ".
+ &mt('at domain')." '$udom' ";
+ }
+ } else {
+ $uname=$env{'form.uname'};
+ }
+ unless ($udom) { $uname=''; }
+ $uhome='';
if ($uname) {
- $r->print('general for Enclosing Map for Resource ');
+ $uhome=&Apache::lonnet::homeserver($uname,$udom);
+ if ($uhome eq 'no_host') {
+ $message=
+ ''.&mt("Unknown user")." '$uname' ".
+ &mt("at domain")." '$udom' ";
+ $uname='';
+ } else {
+ $csec=&Apache::lonnet::getsection($udom,$uname,
+ $env{'request.course.id'});
+
+ if ($csec eq '-1') {
+ $message=''.
+ &mt("User")." '$uname' ".&mt("at domain")." '$udom' ".
+ &mt("not in this course")." ";
+ $uname='';
+ $csec=$env{'form.csec'};
+ $cgroup=$env{'form.cgroup'};
+ } else {
+ my %name=&Apache::lonnet::userenvironment($udom,$uname,
+ ('firstname','middlename','lastname','generation','id'));
+ $message="\n\n".&mt("Full Name").": ".
+ $name{'firstname'}.' '.$name{'middlename'}.' '
+ .$name{'lastname'}.' '.$name{'generation'}.
+ " \n".&mt('ID').": ".$name{'id'}.'
';
+ }
+ @usersgroups = &Apache::lonnet::get_users_groups(
+ $udom,$uname,$env{'request.course.id'});
+ if (@usersgroups > 0) {
+ unless (grep(/^\Q$cgroup\E$/,@usersgroups)) {
+ $cgroup = $usersgroups[0];
+ }
+ }
+ }
}
- $r->print('
');
- my $defbgone='';
- my $defbgtwo='';
- map {
-# ------------------------------------------------------ Entry for one resource
- if ($defbgone eq '"E0E099"') {
- $defbgone='"E0E0DD"';
- } else {
- $defbgone='"E0E099"';
- }
- if ($defbgtwo eq '"FFFF99"') {
- $defbgtwo='"FFFFDD"';
- } else {
- $defbgtwo='"FFFF99"';
- }
- @outpar=();
- my $rid=$_;
- my $thistitle='';
- my %name= ();
- my %part= ();
- my %display=();
- my %type= ();
- my %default=();
- my $uri=&Apache::lonnet::declutter($bighash{'src_'.$rid});
-
- map {
- $part{$_}=&Apache::lonnet::metadata($uri,$_.'.part');
- $name{$_}=&Apache::lonnet::metadata($uri,$_.'.name');
- $display{$_}=&Apache::lonnet::metadata($uri,$_.'.display');
- unless ($display{$_}) { $display{$_}=''; }
- $display{$_}.=' ('.$name{$_}.')';
- $default{$_}=&Apache::lonnet::metadata($uri,$_);
- $type{$_}=&Apache::lonnet::metadata($uri,$_.'.type');
- $thistitle=&Apache::lonnet::metadata($uri,$_.'.title');
- } split(/\,/,$keyp{$rid});
-
- my $totalparms=scalar keys %name;
- my $isdef=1;
- unless ($totalparms) { $totalparms=1; $isdef=0; }
- $r->print(''.
- join(' / ',split(/\//,$uri)).
- ' '.
- $bighash{'title_'.$rid});
- if ($thistitle) {
- $r->print(' ('.$thistitle.')');
- }
- $r->print('
');
- $r->print(''.$typep{$rid}.' ');
- $r->print(''.
- join(' / ',split(/\//,$mapp{$rid})).' ');
- if ($isdef) {
- map {
- my $result=&parmval($part{$_}.'.'.$name{$_},$rid,$default{$_});
-
- $r->print("$part{$_} $display{$_} ");
- my $thismarker=$_;
- $thismarker=~s/^parameter\_//;
- my $mprefix=$rid.'&'.$thismarker.'&';
-
- $r->print(''.
- &valout($outpar[11],$type{$_}).' ');
- $r->print(''.
- &valout($outpar[10],$type{$_}).' ');
-
- $r->print(''.
- &plink($type{$_},$display{$_},$outpar[9],$mprefix.'9',
- 'parmform.pres','psub').' ');
- $r->print(''.
- &plink($type{$_},$display{$_},$outpar[8],$mprefix.'8',
- 'parmform.pres','psub').' ');
- $r->print(''.
- &plink($type{$_},$display{$_},$outpar[7],$mprefix.'7',
- 'parmform.pres','psub').' ');
-
- if ($csec) {
- $r->print(''.
- &plink($type{$_},$display{$_},$outpar[6],$mprefix.'6',
- 'parmform.pres','psub').' ');
- $r->print(''.
- &plink($type{$_},$display{$_},$outpar[5],$mprefix.'5',
- 'parmform.pres','psub').' ');
- $r->print(''.
- &plink($type{$_},$display{$_},$outpar[4],$mprefix.'4',
- 'parmform.pres','psub').' ');
+
+ unless ($csec) { $csec=''; }
+ unless ($cgroup) { $cgroup=''; }
+
+# --------------------------------------------------------- Get all assessments
+ &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,
+ \%mapp, \%symbp,\%maptitles,\%uris,
+ \%keyorder);
+
+ $mapp{'0.0'} = '';
+ $symbp{'0.0'} = '';
+
+# ---------------------------------------------------------- Anything to store?
+ if ($env{'form.pres_marker'}) {
+ my @markers=split(/\&\&\&/,$env{'form.pres_marker'});
+ my @values=split(/\&\&\&/,$env{'form.pres_value'});
+ my @types=split(/\&\&\&/,$env{'form.pres_type'});
+ for (my $i=0;$i<=$#markers;$i++) {
+ $message.=&storeparm(split(/\&/,$markers[$i]),
+ $values[$i],
+ $types[$i],
+ $uname,$udom,$csec,$cgroup);
+ }
+# ---------------------------------------------------------------- Done storing
+ $message.=''.&mt('Changes can take up to 10 minutes before being active for all students.').&Apache::loncommon::help_open_topic('Caching').' ';
+ }
+#----------------------------------------------- if all selected, fill in array
+ if ($pscat[0] eq "all") {@pscat = (keys %allparms);}
+ if (!@pscat) { @pscat=('duedate','opendate','answerdate','weight','maxtries') };
+ if ($psprt[0] eq "all" || !@psprt) {@psprt = (keys %allparts);}
+# ------------------------------------------------------------------ Start page
+
+ &startpage($r);
+
+ foreach ('tolerance','date_default','date_start','date_end',
+ 'date_interval','int','float','string') {
+ $r->print(' ').
+ '" name="recent_'.$_.'" />');
+ }
+
+ if (!$pssymb) {
+ $r->print('');
+ &levelmenu($r,\%alllevs,$parmlev);
+ if ($parmlev ne 'general') {
+ $r->print(' ');
+ &mapmenu($r,\%allmaps,$pschp,\%maptitles);
+ $r->print(' ');
+ }
+ $r->print('
');
+ &displaymenu($r,\%allparms,\%allparts,\@pscat,\@psprt,\%keyorder);
+ } else {
+ my ($map,$id,$resource)=&Apache::lonnet::decode_symb($pssymb);
+ my $title = &Apache::lonnet::gettitle($pssymb);
+ $r->print(&mt('Specific Resource: [_1] ([_2])',$title,$resource).
+ ' '.
+ ''.&mt('Show all parts').': ');
+ }
+ &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups);
+
+ $r->print(''.$message.'
');
+
+ $r->print(' ');
+
+ my @temp_pscat;
+ map {
+ my $cat = $_;
+ push(@temp_pscat, map { $_.'.'.$cat } @psprt);
+ } @pscat;
+
+ @pscat = @temp_pscat;
+
+ if (($env{'form.prevvisit'}) || ($pschp) || ($pssymb)) {
+# ----------------------------------------------------------------- Start Table
+ my @catmarker=map { tr|.|_|; 'parameter_'.$_; } @pscat;
+ my $csuname=$env{'user.name'};
+ my $csudom=$env{'user.domain'};
+
+ if ($parmlev eq 'full') {
+ my $coursespan=$csec?8:5;
+ my $userspan=3;
+ if ($cgroup ne '') {
+ $coursespan += 3;
+ }
+
+ $r->print('
');
+ $r->print(' ');
+ $r->print(''.&mt('Any User').' ');
+ if ($uname) {
+ if (@usersgroups > 1) {
+ $userspan ++;
}
+ $r->print('');
+ $r->print(&mt("User")." $uname ".&mt('at Domain')." $udom ");
+ }
+ my %lt=&Apache::lonlocal::texthash(
+ 'pie' => "Parameter in Effect",
+ 'csv' => "Current Session Value",
+ 'at' => 'at',
+ 'rl' => "Resource Level",
+ 'ic' => 'in Course',
+ 'aut' => "Assessment URL and Title",
+ 'type' => 'Type',
+ 'emof' => "Enclosing Map or Folder",
+ 'part' => 'Part',
+ 'pn' => 'Parameter Name',
+ 'def' => 'default',
+ 'femof' => 'from Enclosing Map or Folder',
+ 'gen' => 'general',
+ 'foremf' => 'for Enclosing Map or Folder',
+ 'fr' => 'for Resource'
+ );
+ $r->print(<$lt{'pie'}
+$lt{'csv'} ($csuname $lt{'at'} $csudom)
+ $lt{'ic'} $lt{'rl'}
+$lt{'ic'}
+
+ENDTABLETWO
+ if ($csec) {
+ $r->print("".
+ &mt("in Section")." $csec ");
+ }
+ if ($cgroup) {
+ $r->print("".
+ &mt("in Group")." $cgroup ");
+ }
+ $r->print(<$lt{'aut'} $lt{'type'}
+$lt{'emof'} $lt{'part'} $lt{'pn'}
+$lt{'gen'} $lt{'foremf'}
+$lt{'def'} $lt{'femof'} $lt{'fr'}
+ENDTABLEHEADFOUR
+
+ if ($csec) {
+ $r->print(''.&mt('general').' '.&mt('for Enclosing Map or Folder').' '.&mt('for Resource').' ');
+ }
- if ($uname) {
- $r->print(''.
- &plink($type{$_},$display{$_},$outpar[3],$mprefix.'3',
- 'parmform.pres','psub').' ');
- $r->print(''.
- &plink($type{$_},$display{$_},$outpar[2],$mprefix.'2',
- 'parmform.pres','psub').' ');
- $r->print(''.
- &plink($type{$_},$display{$_},$outpar[1],$mprefix.'1',
- 'parmform.pres','psub').' ');
+ if ($cgroup) {
+ $r->print(''.&mt('general').' '.&mt('for Enclosing Map or Folder').' '.&mt('for Resource').' ');
+ }
+
+ if ($uname) {
+ if (@usersgroups > 1) {
+ $r->print(''.&mt('Control by other group?').' ');
}
+ $r->print(''.&mt('general').' '.&mt('for Enclosing Map or Folder').' '.&mt('for Resource').' ');
+ }
+
+ $r->print(' ');
+
+ my $defbgone='';
+ my $defbgtwo='';
+ my $defbgthree = '';
+
+ foreach (@ids) {
+
+ my $rid=$_;
+ my ($inmapid)=($rid=~/\.(\d+)$/);
+
+ if ((!$pssymb &&
+ (($pschp eq 'all') || ($allmaps{$pschp} eq $mapp{$rid})))
+ ||
+ ($pssymb && $pssymb eq $symbp{$rid})) {
+# ------------------------------------------------------ Entry for one resource
+ if ($defbgone eq '"#E0E099"') {
+ $defbgone='"#E0E0DD"';
+ } else {
+ $defbgone='"#E0E099"';
+ }
+ if ($defbgtwo eq '"#FFFF99"') {
+ $defbgtwo='"#FFFFDD"';
+ } else {
+ $defbgtwo='"#FFFF99"';
+ }
+ if ($defbgthree eq '"#FFBB99"') {
+ $defbgthree='"#FFBBDD"';
+ } else {
+ $defbgthree='"#FFBB99"';
+ }
+
+ my $thistitle='';
+ my %name= ();
+ undef %name;
+ my %part= ();
+ my %display=();
+ my %type= ();
+ my %default=();
+ my $uri=&Apache::lonnet::declutter($uris{$rid});
+
+ foreach (&keysplit($keyp{$rid})) {
+ my $tempkeyp = $_;
+ if (grep $_ eq $tempkeyp, @catmarker) {
+ $part{$_}=&Apache::lonnet::metadata($uri,$_.'.part');
+ $name{$_}=&Apache::lonnet::metadata($uri,$_.'.name');
+ $display{$_}=&Apache::lonnet::metadata($uri,$_.'.display');
+ unless ($display{$_}) { $display{$_}=''; }
+ $display{$_}.=' ('.$name{$_}.')';
+ $default{$_}=&Apache::lonnet::metadata($uri,$_);
+ $type{$_}=&Apache::lonnet::metadata($uri,$_.'.type');
+ $thistitle=&Apache::lonnet::metadata($uri,$_.'.title');
+ }
+ }
+ my $totalparms=scalar keys %name;
+ if ($totalparms>0) {
+ my $firstrow=1;
+ my $title=&Apache::lonnet::gettitle($symbp{$rid});
+ $r->print(''.
+ join(' / ',split(/\//,$uri)).
+ ' '.
+ "$title");
+
+ if ($thistitle) {
+ $r->print(' ('.$thistitle.')');
+ }
+ $r->print('
');
+ $r->print(''.$typep{$rid}.
+ ' ');
+
+ $r->print(''.$maptitles{$mapp{$rid}}.' ');
+
+ foreach (&keysinorder_bytype(\%name,\%keyorder)) {
+ unless ($firstrow) {
+ $r->print('');
+ } else {
+ undef $firstrow;
+ }
+ &print_row($r,$_,\%part,\%name,\%symbp,$rid,\%default,
+ \%type,\%display,$defbgone,$defbgtwo,
+ $defbgthree,$parmlev,$uname,$udom,$csec,
+ $cgroup,\@usersgroups);
+ }
+ }
+ }
+ } # end foreach ids
+# -------------------------------------------------- End entry for one resource
+ $r->print('
');
+ } # end of full
+#--------------------------------------------------- Entry for parm level map
+ if ($parmlev eq 'map') {
+ my $defbgone = '"E0E099"';
+ my $defbgtwo = '"FFFF99"';
+ my $defbgthree = '"FFBB99"';
+
+ my %maplist;
+
+ if ($pschp eq 'all') {
+ %maplist = %allmaps;
+ } else {
+ %maplist = ($pschp => $mapp{$pschp});
+ }
+
+#-------------------------------------------- for each map, gather information
+ my $mapid;
+ foreach $mapid (sort {$maplist{$a} cmp $maplist{$b}} keys %maplist) {
+ my $maptitle = $maplist{$mapid};
+
+#----------------------- loop through ids and get all parameter types for map
+#----------------------------------------- and associated information
+ my %name = ();
+ my %part = ();
+ my %display = ();
+ my %type = ();
+ my %default = ();
+ my $map = 0;
+
+# $r->print("Catmarker: @catmarker \n");
+
+ foreach (@ids) {
+ ($map)=(/([\d]*?)\./);
+ my $rid = $_;
+
+# $r->print("$mapid:$map: $rid \n");
+
+ if ($map eq $mapid) {
+ my $uri=&Apache::lonnet::declutter($uris{$rid});
+# $r->print("Keys: $keyp{$rid} \n");
+
+#--------------------------------------------------------------------
+# @catmarker contains list of all possible parameters including part #s
+# $fullkeyp contains the full part/id # for the extraction of proper parameters
+# $tempkeyp contains part 0 only (no ids - ie, subparts)
+# When storing information, store as part 0
+# When requesting information, request from full part
+#-------------------------------------------------------------------
+ foreach (&keysplit($keyp{$rid})) {
+ my $tempkeyp = $_;
+ my $fullkeyp = $tempkeyp;
+ $tempkeyp =~ s/_\w+_/_0_/;
+
+ if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {
+ $part{$tempkeyp}="0";
+ $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name');
+ $display{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.display');
+ unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
+ $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
+ $display{$tempkeyp} =~ s/_\w+_/_0_/;
+ $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp);
+ $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type');
+ }
+ } # end loop through keys
+ }
+ } # end loop through ids
+
+#---------------------------------------------------- print header information
+ my $foldermap=&mt($maptitle=~/^uploaded/?'Folder':'Map');
+ my $showtitle=$maptitles{$maptitle}.($maptitle!~/^uploaded/?' ['.$maptitle.']':'');
+ my $tmp="";
+ if ($uname) {
+ my $person=&Apache::loncommon::plainname($uname,$udom);
+ $tmp.=&mt("User")." $uname \($person\) ".
+ &mt('in')." \n";
+ } else {
+ $tmp.="".&mt('all').' '.&mt('users in')." \n";
+ }
+ if ($cgroup) {
+ $tmp.=&mt("Group")." $cgroup".
+ " ".&mt('of')." \n";
+ $csec = '';
+ } elsif ($csec) {
+ $tmp.=&mt("Section")." $csec".
+ " ".&mt('of')." \n";
+ }
+ $r->print(''
+ .&mt('Set Defaults for All Resources in [_1]Specifically for [_2][_3]'
+ ,$foldermap.''.$showtitle.' '
+ ,$tmp
+ ,''.$coursename.' '
+ )
+ ." \n"
+ );
+#---------------------------------------------------------------- print table
+ $r->print('
');
+ $r->print(''.&mt('Parameter Name').' ');
+ $r->print(''.&mt('Default Value').' ');
+ $r->print(''.&mt('Parameter in Effect').' ');
+
+ foreach (&keysinorder(\%name,\%keyorder)) {
+ $r->print('');
+ &print_row($r,$_,\%part,\%name,\%symbp,$mapid,\%default,
+ \%type,\%display,$defbgone,$defbgtwo,$defbgthree,
+ $parmlev,$uname,$udom,$csec,$cgroup);
+ }
+ $r->print("
");
+ } # end each map
+ } # end of $parmlev eq map
+#--------------------------------- Entry for parm level general (Course level)
+ if ($parmlev eq 'general') {
+ my $defbgone = '"E0E099"';
+ my $defbgtwo = '"FFFF99"';
+ my $defbgthree = '"FFBB99"';
+
+#-------------------------------------------- for each map, gather information
+ my $mapid="0.0";
+#----------------------- loop through ids and get all parameter types for map
+#----------------------------------------- and associated information
+ my %name = ();
+ my %part = ();
+ my %display = ();
+ my %type = ();
+ my %default = ();
+
+ foreach (@ids) {
+ my $rid = $_;
+
+ my $uri=&Apache::lonnet::declutter($uris{$rid});
+
+#--------------------------------------------------------------------
+# @catmarker contains list of all possible parameters including part #s
+# $fullkeyp contains the full part/id # for the extraction of proper parameters
+# $tempkeyp contains part 0 only (no ids - ie, subparts)
+# When storing information, store as part 0
+# When requesting information, request from full part
+#-------------------------------------------------------------------
+ foreach (&keysplit($keyp{$rid})) {
+ my $tempkeyp = $_;
+ my $fullkeyp = $tempkeyp;
+ $tempkeyp =~ s/_\w+_/_0_/;
+ if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {
+ $part{$tempkeyp}="0";
+ $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name');
+ $display{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.display');
+ unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
+ $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
+ $display{$tempkeyp} =~ s/_\w+_/_0_/;
+ $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp);
+ $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type');
+ }
+ } # end loop through keys
+ } # end loop through ids
+
+#---------------------------------------------------- print header information
+ my $setdef=&mt("Set Defaults for All Resources in Course");
+ $r->print(<$setdef
+$coursename
+ENDMAPONE
+ if ($uname) {
+ my $person=&Apache::loncommon::plainname($uname,$udom);
+ $r->print(" ".&mt("User")." $uname \($person\) \n");
+ } else {
+ $r->print(" ".&mt("ALL")." ".&mt("USERS")." \n");
+ }
+
+ if ($csec) {$r->print(&mt("Section")." $csec \n")};
+ if ($cgroup) {$r->print(&mt("Group")." $cgroup \n")};
+ $r->print(" \n");
+#---------------------------------------------------------------- print table
+ $r->print('
');
+ $r->print(''.&mt('Parameter Name').' ');
+ $r->print(''.&mt('Default Value').' ');
+ $r->print(''.&mt('Parameter in Effect').' ');
+
+ foreach (&keysinorder(\%name,\%keyorder)) {
+ $r->print('');
+ &print_row($r,$_,\%part,\%name,\%symbp,$mapid,\%default,
+ \%type,\%display,$defbgone,$defbgtwo,$defbgthree,
+ $parmlev,$uname,$udom,$csec,$cgroup);
+ }
+ $r->print("
");
+ } # end of $parmlev eq general
+ }
+ $r->print(''.&Apache::loncommon::end_page());
+} # end sub assessparms
+
+
+##################################################
+##################################################
+
+=pod
+
+=item crsenv
+
+Show and set course data and parameters. This is a large routine that should
+be simplified and shortened... someday.
+
+Inputs: $r
+
+Returns: nothing
+
+=cut
+
+##################################################
+##################################################
+sub crsenv {
+ my $r=shift;
+ my $setoutput='';
+
+ &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=crsenv',
+ text=>"Course Environment"});
+ my $breadcrumbs =
+ &Apache::lonhtmlcommon::breadcrumbs('Edit Course Environment');
+ my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
+
+ my (%crsinfo,$chome);
+
+ #
+ # Go through list of changes
+ foreach (keys %env) {
+ next if ($_!~/^form\.(.+)\_setparmval$/);
+ my $name = $1;
+ my $value = $env{'form.'.$name.'_value'};
+ if ($name eq 'newp') {
+ $name = $env{'form.newp_name'};
+ }
+ if ($name eq 'url') {
+ $value=~s/^\/res\///;
+ my $bkuptime=time;
+ my @tmp = &Apache::lonnet::get
+ ('environment',['url'],$dom,$crs);
+ $setoutput.=&mt('Backing up previous URL').': '.
+ &Apache::lonnet::put
+ ('environment',
+ {'top level map backup '.$bkuptime => $tmp[1] },
+ $dom,$crs).
+ ' ';
+ }
+ #
+ # Deal with modified default spreadsheets
+ if ($name =~ /^spreadsheet_default_(classcalc|
+ studentcalc|
+ assesscalc)$/x) {
+ my $sheettype = $1;
+ if ($sheettype eq 'classcalc') {
+ # no need to do anything since viewing the sheet will
+ # cause it to be updated.
+ } elsif ($sheettype eq 'studentcalc') {
+ # expire all the student spreadsheets
+ &Apache::lonnet::expirespread('','','studentcalc');
+ } else {
+ # expire all the assessment spreadsheets
+ # this includes non-default spreadsheets, but better to
+ # be safe than sorry.
+ &Apache::lonnet::expirespread('','','assesscalc');
+ # expire all the student spreadsheets
+ &Apache::lonnet::expirespread('','','studentcalc');
+ }
+ }
+ #
+ # Deal with the enrollment dates
+ if ($name =~ /^default_enrollment_(start|end)_date$/) {
+ $value=&Apache::lonhtmlcommon::get_date_from_form($name.'_value');
+ }
+ #
+ # Deal with the emails
+ if ($name =~ /\.email$/) {
+ foreach my $specifier (split(',',$value)) {
+ my ($user,$sections_or_groups)=
+ ($specifier=~/^([^\(]+)\(([^\)]+)\)/);
+ if (!$sections_or_groups) {
+ $user = $specifier;
+ }
+ my ($name,$domain) = split(':',$user);
+ if (!defined($user) || !defined($domain)) {
+ $setoutput.= ' '.
+ &mt("Invalid email address specified, address must be of the form username:domain what was specified was ([_1])",$user).
+ ' ';
+ undef($value);
+ } elsif (&Apache::lonnet::homeserver($user,$domain) eq 'no_host') {
+ $setoutput.= ' '.
+ &mt("Invalid email address specified, user [_1] is unknown.",$name).
+ ' ';
+ undef($value);
+ }
+ }
+ }
+ # Get existing cloners
+ my @oldcloner = ();
+ if ($name eq 'cloners') {
+ my %clonenames=&Apache::lonnet::dump('environment',$dom,$crs,'cloners');
+ if ($clonenames{'cloners'} =~ /,/) {
+ @oldcloner = split/,/,$clonenames{'cloners'};
+ } else {
+ $oldcloner[0] = $clonenames{'cloners'};
+ }
+ }
+ #
+ # Let the user know we made the changes
+ if ($name && defined($value)) {
+ my %failed_cloners;
+ if ($name eq 'cloners') {
+ $value =~ s/\s//g;
+ $value =~ s/^,//;
+ $value =~ s/,$//;
+ # check requested clones are valid users.
+ %failed_cloners = &check_cloners(\$value,\@oldcloner);
+ }
+ my $put_result = &Apache::lonnet::put('environment',
+ {$name=>$value},$dom,$crs);
+ if ($put_result eq 'ok') {
+ $setoutput.=&mt('Set').' '.$name.' '.&mt('to').' ';
+ if ($name =~ /^default_enrollment_(start|end)_date$/) {
+ $setoutput .= &Apache::lonlocal::locallocaltime($value);
+ } elsif ($name eq 'categories') {
+ $setoutput .= $env{'form.categories_display'};
+ } else {
+ $setoutput .= $value;
+ }
+ $setoutput .= ' . ';
+ if ($name eq 'cloners') {
+ &change_clone($value,\@oldcloner);
+ }
+ # Update environment and nohist_courseids.db
+ if (($name eq 'description') || ($name eq 'cloners') ||
+ ($name eq 'hidefromcat') || ($name eq 'categories')) {
+ if ($chome eq '') {
+ %crsinfo =
+ &Apache::lonnet::courseiddump($dom,'.',1,'.','.',
+ $crs,undef,undef,'.');
+ $chome = &Apache::lonnet::homeserver($crs,$dom);
+ }
+ }
+ if ($name eq 'description' && defined($value)) {
+ &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.description' => $value});
+ if (ref($crsinfo{$env{'request.course.id'}}) eq 'HASH') {
+ $crsinfo{$env{'request.course.id'}}{'description'} = $value;
+ my $putresult =
+ &Apache::lonnet::courseidput($dom,\%crsinfo,
+ $chome,'notime');
+ }
+ }
+ if (($name eq 'cloners') || ($name eq 'hidefromcat') || ($name eq 'categories')) {
+ if (ref($crsinfo{$env{'request.course.id'}}) eq 'HASH') {
+ &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.'.$name => $value});
+ $crsinfo{$env{'request.course.id'}}{$name} = $value;
+ my $putresult =
+ &Apache::lonnet::courseidput($dom,\%crsinfo,
+ $chome,'notime');
+ }
+ }
+ } else {
+ $setoutput.=&mt('Unable to set').' '.$name.' '.&mt('to').
+ ' '.$value.' '.&mt('due to').' '.$put_result.'. ';
+ }
+ if (($name eq 'cloners') && (keys(%failed_cloners) > 0)) {
+ $setoutput.= &mt('Unable to include').': ';
+ my @fails;
+ my $num = 0;
+ if (defined($failed_cloners{'format'})) {
+ $fails[$num] .= ''.$failed_cloners{'format'}.
+ ' , '.&mt('reason').' - '.
+ &mt('Invalid format');
+ $num ++;
+ }
+ if (defined($failed_cloners{'domain'})) {
+ $fails[$num] .= ''.$failed_cloners{'domain'}.
+ ' , '.&mt('reason').' - '.
+ &mt('Domain does not exist');
+ $num ++;
+ }
+ if (defined($failed_cloners{'newuser'})) {
+ $fails[$num] .= ''.$failed_cloners{'newuser'}. ' , '.&mt('reason').' - '.
+ &mt('LON-CAPA user(s) do(es) not exist.').
+ '. '.&mt('Please ').
+ ' '.
+ &mt('add the user(s)').' , '.
+ &mt('and then return to the ').
+ ''.
+ &mt('Course Parameters page').' '.
+ &mt('to add the new user(s) to the list of possible cloners');
+ }
+ $setoutput .= join('; ',@fails).'. ';
+ }
+ }
+ }
+
+ my $start_table =&Apache::loncommon::start_data_table();
+ my $start_header_row=&Apache::loncommon::start_data_table_header_row();
+ my $end_header_row =&Apache::loncommon::end_data_table_header_row();
+# ------------------------- Re-init course environment entries for this session
+
+ &Apache::lonnet::coursedescription($env{'request.course.id'},
+ {'freshen_cache' => 1});
+
+# -------------------------------------------------------- Get parameters again
+
+ my %values=&Apache::lonnet::dump('environment',$dom,$crs);
+ my $SelectStyleFile=&mt('Select Style File');
+ my $SelectSpreadsheetFile=&mt('Select Spreadsheet File');
+ my $output='';
+ my $can_categorize;
+ if (! exists($values{'con_lost'})) {
+ my %descriptions=
+ ('url' => ''.&mt('Top Level Map').' '.
+ '".
+ &mt('Select Map').' '.
+ &mt('Modification may make assessment data inaccessible!').
+ ' ',
+ 'description' => ''.&mt('Course Description').' ',
+ 'courseid' => ''.&mt('Course ID or number').
+ ' '.
+ '('.&mt('internal, optional').')',
+ 'cloners' => ''.&mt('Users allowed to clone course').' '
+ .'("'.&mt('user:domain,user:domain,*:domain').' ") '
+ .&mt('Users with active Course Coordinator role in this course are permitted to clone and need not be included.').' '
+ .&mt('Use [_1] to allow course to be cloned by anyone in the specified domain.','"*:domain "').' '
+ .&mt('Use [_1] to allow unrestricted cloning in all domains.','"* "'),
+ 'grading' => ''.&mt('Grading').' '.
+ &mt('[_1], [_2], or [_3]','"standard "','"external "','"spreadsheet "').&Apache::loncommon::help_open_topic('GradingOptions'),
+ 'task_grading' => ''.&mt('Bridge Task Grading').' '
+ .&mt('Instructors and TAs in sections, when grading bridge tasks, should be allowed to grade other sections.').' '
+ .'('.&mt('[_1]: they are allowed (this is the default). [_2]: no, they can only grade their own section.','"any "','"section "').')',
+ 'default_xml_style' => ''.&mt('Default XML Style File').' '.
+ '$SelectStyleFile ",
+ 'question.email' => ''.&mt('Feedback Addresses for Resource Content Question').' '
+ .'("'.&mt('user:domain,user:domain(section;section;...;*;...),...').' ")',
+ 'question.email.text' => ''.&mt('Custom Text for Resource Content Question Option in Feedback').' ',
+ 'comment.email' => ''.&mt('Feedback Addresses for Course Content Comments').' '
+ .'("'.&mt('user:domain,user:domain(section;section;...;*;...),...').' ")',
+ 'comment.email.text' => ''.&mt('Custom Text for Course Content Option in Feedback').' ',
+ 'policy.email' => ''.&mt('Feedback Addresses for Course Policy').' '
+ .'("'.&mt('user:domain,user:domain(section;section;...;*;...),...').' ")',
+ 'policy.email.text' => ''.&mt('Custom Text for Course Policy Option in Feedback').' ',
+ 'hideemptyrows' => ''.&mt('Hide Empty Rows in Spreadsheets').' '
+ .'('.&mt('[_1] for default hiding','"yes "').')',
+ 'pageseparators' => ''.&mt('Visibly Separate Items on Pages').' '
+ .'('.&mt('[_1] for visible separation.','"yes "').' '
+ .&mt('Changes will not show until next login.').')',
+ 'student_classlist_view' => ''.&mt('Allow students to view classlist.').' '
+ .'('.&mt('[_1]: students can view all sections. [_2]: students can only view their own section. blank or [_3] prevents student view.','"all "','"section "','"disabled "').')',
+ 'student_classlist_portfiles' => ''.&mt('Include link to accessible portfolio files').' '
+ .'('.&mt('[_1] for link to each a listing of each student\'s files.','"yes "').')',
+ 'student_classlist_opt_in' => ''.&mt("Student's agreement needed for listing in student-viewable roster").' '
+ .'('.&mt('[_1] to require students to opt-in to listing in the roster (on the roster page).','"yes "').')',
+ 'plc.roles.denied'=> ''.&mt('Disallow live chatroom use for Roles').' '
+ .'('.&mt('[_1]: student, [_2]: TA, [_3]: instructor','"st "','"ta "','"in "').') '
+ .'("'.&mt('role,role,...').' ") '
+ .Apache::loncommon::help_open_topic("Course_Disable_Discussion"),
+ 'plc.users.denied' =>
+ ''.&mt('Disallow live chatroom use for Users').' '.
+ '("'.&mt('user:domain,user:domain,...').' ")',
+
+ 'pch.roles.denied'=> ''.&mt('Disallow Resource Discussion for Roles').' '
+ .'('.&mt('[_1]: student, [_2]: TA, [_3]: instructor','"st "','"ta "','"in "')
+ .'("'.&mt('role,role,...').' ") '
+ .Apache::loncommon::help_open_topic("Course_Disable_Discussion"),
+ 'pch.users.denied' =>
+ ''.&mt('Disallow Resource Discussion for Users').' '.
+ '("'.&mt('user:domain,user:domain,...').' ")',
+ 'spreadsheet_default_classcalc'
+ => ''.&mt('Default Course Spreadsheet').' '.
+ '$SelectSpreadsheetFile ",
+ 'spreadsheet_default_studentcalc'
+ => ''.&mt('Default Student Spreadsheet').' '.
+ '$SelectSpreadsheetFile ",
+ 'spreadsheet_default_assesscalc'
+ => ''.&mt('Default Assessment Spreadsheet').' '.
+ '$SelectSpreadsheetFile ",
+ 'allow_limited_html_in_feedback'
+ => ''.&mt('Allow limited HTML in discussion posts').' '.
+ '('.&mt('Set value to [_1] to allow.','"yes "').')',
+ 'allow_discussion_post_editing'
+ => ''.&mt('Allow users with specified roles to edit/delete their own discussion posts').' '
+ .'('.&mt('[_1]: student, [_2]: TA, [_3]: instructor','"st "','"ta "','"in "').') '
+ .'('.&mt('Set value to [_1] to allow all roles.','"yes "').')'
+ .'("'.&mt('role:section,role:section,...').' ") '
+ .'('.&mt('Example: "st:001,st:002,in,cc " would permit students in sections 001 and 002 and instructors in any section, and course coordinators to edit their own posts.').')',
+ 'rndseed'
+ => ''.&mt('Randomization algorithm used').' '
+ .''
+ .&mt('Modifying this will make problems have different numbers and answers!')
+ .' ',
+ 'receiptalg'
+ => ''.&mt('Receipt algorithm used').' '.
+ &mt('This controls how receipt numbers are generated.'),
+ 'suppress_tries'
+ => ''.&mt('Suppress number of tries in printing').' '.
+ ' ('.&mt('[_1] to suppress, anything else to not suppress','"yes "').')',
+ 'problem_stream_switch'
+ => ''.&mt('Allow problems to be split over pages').' '.
+ ' ('.&mt('[_1] if allowed, anything else if not','"yes "').')',
+ 'default_paper_size'
+ => ''.&mt('Default paper type').' '.
+ ' ('.&mt('supported types').': Letter [8 1/2x11 in], Legal [8 1/2x14 in],'.
+ ' Tabloid [11x17 in], Executive [7 1/2x10 in], A2 [420x594 mm],'.
+ ' A3 [297x420 mm], A4 [210x297 mm], A5 [148x210 mm], A6 [105x148 mm])',
+ 'print_header_format'
+ => ' '.&mt('Print header format').' '
+ .&mt('Substitutions: [_1]: student name, [_2]: course id, [_3]: assignment note. Numbers after the % limit the field size.','"%n "','"%c "','"%a "'),
+ 'default_enrollment_start_date' => ''.&mt('Default beginning date for student access.').' ',
+ 'default_enrollment_end_date' => ''.&mt('Default ending date for student access.').' ',
+ 'nothideprivileged' => ''.&mt('Privileged users that should not be hidden on staff listings').' '
+ .'("'.&mt('user:domain,user:domain,*:domain').' ")',
+ 'languages' => ''.&mt('Languages used').' ',
+ 'disable_receipt_display'
+ => ''.&mt('Disable display of problem receipts').' '.
+ ' ('.&mt('"[_1]" to disable, anything else if not','yes ').')',
+ 'task_messages'
+ => ''.&mt('Send message to student when clicking Done on Tasks').' ('.&mt('[_1] to send a message only to student, [_2] to send message to student and add record to user information page for instructors. Leave blank to disable.','"only_student "','"student_and_user_notes_screen "').')',
+ 'disablesigfigs'
+ => ''.&mt('Disable checking of Significant Figures').' '.
+ ' ('.&mt('"[_1]" to disable, anything else if not','yes ').')',
+ 'disableexampointprint'
+ => ''.&mt('Disable automatically printing point values onto exams.').' '.
+ ' ('.&mt('"[_1]" to disable, anything else if not','yes ').')',
+ 'externalsyllabus'
+ => ''.&mt('URL of Syllabus (not using internal handler)').' ',
+ 'tthoptions'
+ => ''.&mt('Default set of options to pass to tth/m when converting tex').' ',
+
+ 'texengine'
+ => ''.&mt('Force all students in the course to use a specific math rendering engine.').' '
+ .'('.&mt('[_1], [_2] (Convert to Images), [_3] (TeX to HTML), or blank for student\'s preference','"jsMath "','"mimetex "','"tth "').')',
+ 'timezone'
+ => ''.&mt('Timezone in which the course takes place').' ',
+
+ 'suppress_embed_prompt'
+ => ''.&mt('Suppress prompt to upload items referenced in a web page being uploaded to portfolio, when current role is student.').' '.
+ ' ('.&mt('[_1] to suppress, anything else to not suppress','"yes "').')',
+ 'hidefromcat'
+ => ''.&mt('Exclude from course catalog').' '.
+ ' ('.&mt('[_1] to exclude, anything else to include - included if assigned an institutional code, or manually catagorized','"yes "').')',
+ 'categories'
+ => ''.&mt('Categorize course').' '.
+ &mt('Display Categories').' ',
+ 'datelocale'
+ => ''.&mt('Locale used for course calendar').' ',
+ );
+ my @Display_Order = ('url','description','courseid','cloners');
+ (my $can_toggle_cat,$can_categorize) = &can_modify_catsettings($dom);
+ if ($can_toggle_cat) {
+ push(@Display_Order,'hidefromcat');
+ }
+ if ($can_categorize) {
+ push(@Display_Order,'categories');
+ }
+ push (@Display_Order,('grading',
+ 'externalsyllabus',
+ 'default_xml_style','pageseparators',
+ 'question.email','question.email.text','comment.email',
+ 'comment.email.text','policy.email','policy.email.text',
+ 'student_classlist_view',
+ 'student_classlist_opt_in',
+ 'student_classlist_portfiles',
+ 'plc.roles.denied','plc.users.denied',
+ 'pch.roles.denied','pch.users.denied',
+ 'allow_limited_html_in_feedback',
+ 'allow_discussion_post_editing',
+ 'languages',
+ 'timezone',
+ 'datelocale',
+ 'nothideprivileged',
+ 'rndseed',
+ 'receiptalg',
+ 'problem_stream_switch',
+ 'suppress_tries',
+ 'suppress_embed_prompt',
+ 'default_paper_size',
+ 'print_header_format',
+ 'disable_receipt_display',
+ 'spreadsheet_default_classcalc',
+ 'spreadsheet_default_studentcalc',
+ 'spreadsheet_default_assesscalc',
+ 'hideemptyrows',
+ 'default_enrollment_start_date',
+ 'default_enrollment_end_date',
+ 'tthoptions',
+ 'texengine',
+ 'disablesigfigs',
+ 'disableexampointprint',
+ 'task_messages','task_grading'));
+ foreach my $parameter (sort(keys(%values))) {
+ unless (($parameter =~ m/^internal\./)||($parameter =~ m/^metadata\./) ||
+ ($parameter =~ m/^selfenroll_/) || ($parameter =~ /_selfenroll$/)
+ || ($parameter eq 'type')) {
+ if (! $descriptions{$parameter}) {
+ $descriptions{$parameter}=$parameter;
+ push(@Display_Order,$parameter);
+ }
+ }
+ }
+
+ foreach my $parameter (@Display_Order) {
+ my $description = $descriptions{$parameter};
+ # onchange is javascript to automatically check the 'Set' button.
+ my $onchange = 'onFocus="javascript:window.document.forms'.
+ "['envform'].elements['".$parameter."_setparmval']".
+ '.checked=true;"';
+ $output .= &Apache::loncommon::start_data_table_row().
+ ''.$description.' ';
+ if ($parameter =~ /^default_enrollment_(start|end)_date$/) {
+ $output .= ''.
+ &Apache::lonhtmlcommon::date_setter('envform',
+ $parameter.'_value',
+ $values{$parameter},
+ $onchange).
+ ' ';
+ } elsif ($parameter eq 'timezone') {
+ my $includeempty = 1;
+ my $timezone = &Apache::lonlocal::gettimezone();
+ $output .= ''.
+ &Apache::loncommon::select_timezone($parameter.'_value',
+ $timezone,
+ $onchange,$includeempty).' ';
+ } elsif ($parameter eq 'datelocale') {
+ my $includeempty = 1;
+ my $locale_obj = &Apache::lonlocal::getdatelocale();
+ my $currdatelocale;
+ if (ref($locale_obj)) {
+ $currdatelocale = $locale_obj->id();
+ }
+ $output .= ''.
+ &Apache::loncommon::select_datelocale($parameter.'_value',
+ $currdatelocale,
+ $onchange,$includeempty).' ';
+ } elsif ($parameter eq 'categories') {
+ my $catdisplay;
+ if ($values{'categories'} ne '') {
+ my @curritems = split(/\&/,$values{'categories'});
+ foreach my $item (@curritems) {
+ my ($name,$parent,$pos) = split(/:/,$item);
+ $catdisplay .= &unescape($name).'&';
+ }
+ $catdisplay =~ s/\&$//;
+ }
+ $output .= ''.
+ ' '.
+ ' ';
+ } else {
+ $output .= ''.
+ &Apache::lonhtmlcommon::textbox($parameter.'_value',
+ $values{$parameter},
+ 40,$onchange).' ';
+ }
+ $output .= ''.
+ &Apache::lonhtmlcommon::checkbox($parameter.'_setparmval').
+ ' ';
+ $output .= &Apache::loncommon::end_data_table_row()."\n";
+ }
+ my $onchange = 'onFocus="javascript:window.document.forms'.
+ '[\'envform\'].elements[\'newp_setparmval\']'.
+ '.checked=true;"';
+ $output.=&Apache::loncommon::start_data_table_row().
+ ''.&mt('Create New Environment Variable').' '.
+ ''.
+ ' '.
+ ' '.
+ &Apache::loncommon::end_data_table_row()."\n";
+ }
+ my %lt=&Apache::lonlocal::texthash(
+ 'par' => 'Parameter',
+ 'val' => 'Value',
+ 'set' => 'Set?',
+ 'sav' => 'Save'
+ );
+
+ my $Parameter=&mt('Parameter');
+ my $Value=&mt('Value');
+ my $Set=&mt('Set');
+ my ($jscript,$categorize_js);
+ my $browse_js = &Apache::loncommon::browser_and_searcher_javascript('parmset');
+ if ($can_categorize) {
+ $categorize_js = <'."\n".
+ $browse_js."\n".$categorize_js."\n".'';
+ my $start_page =
+ &Apache::loncommon::start_page('Set Course Environment',
+ $jscript);
+ my $end_page =
+ &Apache::loncommon::end_page();
+ my $end_table=&Apache::loncommon::end_data_table();
+ $r->print(<
+$setoutput
+
+$start_table
+$start_header_row
+$lt{'par'} $lt{'val'} $lt{'set'}
+$end_header_row
+$output
+$end_table
+
+
+$end_page
+ENDENV
+}
+
+sub can_modify_catsettings {
+ my ($dom) = @_;
+ my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$dom);
+ my ($can_toggle_cat,$can_categorize);
+ if (ref($domconf{'coursecategories'}) eq 'HASH') {
+ if ($domconf{'coursecategories'}{'togglecats'} eq 'crs') {
+ $can_toggle_cat = 1;
+ }
+ if ($domconf{'coursecategories'}{'categorize'} eq 'crs') {
+ $can_categorize = 1;
+ }
+ }
+ return ($can_toggle_cat,$can_categorize);
+}
+
+sub assign_course_categories {
+ my ($r) = @_;
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ my $hascats = 0;
+ my $cathash;
+ my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom);
+ if (ref($domconf{'coursecategories'}) eq 'HASH') {
+ $cathash = $domconf{'coursecategories'}{'cats'};
+ if (ref($cathash) eq 'HASH') {
+ $hascats = 1;
+ }
+ }
+ my $catwin_js;
+ if ($hascats) {
+ my $alert = &mt('Use \"Save\" in the main window to save course categories');
+ $catwin_js = <
+
+function updateCategories() {
+ var newcategories = '';
+ var unescapedcats = '';
+ if (document.chgcats.usecategory.length) {
+ for (var i=0; i 0) {
+ newcategories = newcategories.slice(0,-1);
+ }
+ if (unescapedcats.length > 0) {
+ unescapedcats = unescapedcats.slice(0,-3);
+ }
+ } else {
+ if (document.chgcats.usecategory.checked == true) {
+ newcategories = document.chgcats.usecategory.value;
+ unescapedcats = document.chgcats.catname.value;
+ }
+ }
+ opener.document.envform.categories_value.value = newcategories;
+ opener.document.envform.categories_display.value = unescapedcats;
+ opener.document.envform.categories_setparmval.checked = true;
+ alert("$alert");
+ self.close();
+ return;
+}
+
+
+ENDSCRIPT
+ } else {
+ my $onload;
+ }
+ my $start_page =
+ &Apache::loncommon::start_page('Course Categories',$catwin_js,
+ {'only_body' => 1,});
+ my $end_page = &Apache::loncommon::end_page();
+ my $categoriesform = ''.&mt('Categorize Course').' ';
+ if ($hascats) {
+ my %currsettings =
+ &Apache::lonnet::get('environment',['hidefromcat','categories'],$cdom,$cnum);
+ $categoriesform .= &mt('Assign one or more categories to this course.').' '.
+ ' ';
+ } else {
+ $categoriesform .= &mt('No categories defined for this domain');
+ }
+ $r->print($start_page.$categoriesform.$end_page);
+ return;
+}
+
+##################################################
+# Overview mode
+##################################################
+my $tableopen;
+
+sub tablestart {
+ if ($tableopen) {
+ return '';
+ } else {
+ $tableopen=1;
+ return &Apache::loncommon::start_data_table().''.&mt('Parameter').' '.
+ &mt('Delete').' '.&mt('Set to ...').' ';
+ }
+}
+
+sub tableend {
+ if ($tableopen) {
+ $tableopen=0;
+ return &Apache::loncommon::end_data_table();
+ } else {
+ return'';
+ }
+}
+
+sub readdata {
+ my ($crs,$dom)=@_;
+# Read coursedata
+ my $resourcedata=&Apache::lonnet::get_courseresdata($crs,$dom);
+# Read userdata
+
+ my $classlist=&Apache::loncoursedata::get_classlist();
+ foreach (keys %$classlist) {
+ if ($_=~/^($match_username)\:($match_domain)$/) {
+ my ($tuname,$tudom)=($1,$2);
+ my $useropt=&Apache::lonnet::get_userresdata($tuname,$tudom);
+ foreach my $userkey (keys %{$useropt}) {
+ if ($userkey=~/^$env{'request.course.id'}/) {
+ my $newkey=$userkey;
+ $newkey=~s/^($env{'request.course.id'}\.)/$1\[useropt\:$tuname\:$tudom\]\./;
+ $$resourcedata{$newkey}=$$useropt{$userkey};
+ }
+ }
+ }
+ }
+ return $resourcedata;
+}
+
+
+# Setting
+
+sub storedata {
+ my ($r,$crs,$dom)=@_;
+# Set userlevel immediately
+# Do an intermediate store of course level
+ my $olddata=&readdata($crs,$dom);
+ my %newdata=();
+ undef %newdata;
+ my @deldata=();
+ undef @deldata;
+ foreach (keys %env) {
+ if ($_=~/^form\.([a-z]+)\_(.+)$/) {
+ my $cmd=$1;
+ my $thiskey=$2;
+ my ($tuname,$tudom)=&extractuser($thiskey);
+ my $tkey=$thiskey;
+ if ($tuname) {
+ $tkey=~s/\.\[useropt\:$tuname\:$tudom\]\./\./;
+ }
+ if ($cmd eq 'set' || $cmd eq 'datepointer' || $cmd eq 'dateinterval') {
+ my ($data, $typeof, $text);
+ if ($cmd eq 'set') {
+ $data=$env{$_};
+ $typeof=$env{'form.typeof_'.$thiskey};
+ $text = &mt('Saved modified parameter for');
+ } elsif ($cmd eq 'datepointer') {
+ $data=&Apache::lonhtmlcommon::get_date_from_form($env{$_});
+ $typeof=$env{'form.typeof_'.$thiskey};
+ $text = &mt('Saved modified date for');
+ } elsif ($cmd eq 'dateinterval') {
+ $data=&get_date_interval_from_form($thiskey);
+ $typeof=$env{'form.typeof_'.$thiskey};
+ $text = &mt('Saved modified date for');
+ }
+ if (defined($data) and $$olddata{$thiskey} ne $data) {
+ if ($tuname) {
+ if (&Apache::lonnet::put('resourcedata',{$tkey=>$data,
+ $tkey.'.type' => $typeof},
+ $tudom,$tuname) eq 'ok') {
+ &log_parmset({$tkey=>$data,$tkey.'.type' => $typeof},0,$tuname,$tudom);
+ $r->print(' '.$text.' '.
+ &Apache::loncommon::plainname($tuname,$tudom));
+ } else {
+ $r->print(''.
+ &mt('Error saving parameters').'
');
+ }
+ &Apache::lonnet::devalidateuserresdata($tuname,$tudom);
+ } else {
+ $newdata{$thiskey}=$data;
+ $newdata{$thiskey.'.type'}=$typeof;
+ }
+ }
+ } elsif ($cmd eq 'del') {
+ if ($tuname) {
+ if (&Apache::lonnet::del('resourcedata',[$tkey],$tudom,$tuname) eq 'ok') {
+ &log_parmset({$tkey=>''},1,$tuname,$tudom);
+ $r->print(' '.&mt('Deleted parameter for').' '.&Apache::loncommon::plainname($tuname,$tudom));
+ } else {
+ $r->print(''.
+ &mt('Error deleting parameters').'
');
+ }
+ &Apache::lonnet::devalidateuserresdata($tuname,$tudom);
+ } else {
+ push (@deldata,$thiskey,$thiskey.'.type');
+ }
+ }
+ }
+ }
+# Store all course level
+ my $delentries=$#deldata+1;
+ my @newdatakeys=keys %newdata;
+ my $putentries=$#newdatakeys+1;
+ if ($delentries) {
+ if (&Apache::lonnet::del('resourcedata',\@deldata,$dom,$crs) eq 'ok') {
+ my %loghash=map { $_ => '' } @deldata;
+ &log_parmset(\%loghash,1);
+ $r->print(''.&mt('Deleted [_1] parameter(s) ',$delentries));
+ } else {
+ $r->print(''.
+ &mt('Error deleting parameters').'
');
+ }
+ &Apache::lonnet::devalidatecourseresdata($crs,$dom);
+ }
+ if ($putentries) {
+ if (&Apache::lonnet::put('resourcedata',\%newdata,$dom,$crs) eq 'ok') {
+ &log_parmset(\%newdata,0);
+ $r->print(''.&mt('Saved [_1] parameter(s)',$putentries/2).' ');
+ } else {
+ $r->print(''.
+ &mt('Error saving parameters').'
');
+ }
+ &Apache::lonnet::devalidatecourseresdata($crs,$dom);
+ }
+}
- $r->print(
- ''.&valout($outpar[$result],$type{$_}).' ');
- $r->print(" \n");
- } sort keys %name;
+sub extractuser {
+ my $key=shift;
+ return ($key=~/^$env{'request.course.id'}.\[useropt\:($match_username)\:($match_domain)\]\./);
+}
+
+sub parse_listdata_key {
+ my ($key,$listdata) = @_;
+ # split into student/section affected, and
+ # the realm (folder/resource part and parameter
+ my ($student,$realm) =
+ ($key=~/^\Q$env{'request.course.id'}\E\.\[([^\.]+)\]\.(.+)$/);
+ # if course wide student would be undefined
+ if (!defined($student)) {
+ ($realm)=($key=~/^\Q$env{'request.course.id'}\E\.(.+)$/);
+ }
+ # strip off the .type if it's not the Question type parameter
+ if ($realm=~/\.type$/ && !exists($listdata->{$key.'.type'})) {
+ $realm=~s/\.type//;
+ }
+ # split into resource+part and parameter name
+ my ($res, $parm) = ($realm=~/^(.*)\.(.*)$/);
+ ($res, my $part) = ($res =~/^(.*)\.(.*)$/);
+ return ($student,$res,$part,$parm);
+}
+
+sub listdata {
+ my ($r,$resourcedata,$listdata,$sortorder)=@_;
+# Start list output
+
+ my $oldsection='';
+ my $oldrealm='';
+ my $oldpart='';
+ my $pointer=0;
+ $tableopen=0;
+ my $foundkeys=0;
+ my %keyorder=&standardkeyorder();
+
+ foreach my $thiskey (sort {
+ my ($astudent,$ares,$apart,$aparm) = &parse_listdata_key($a,$listdata);
+ my ($bstudent,$bres,$bpart,$bparm) = &parse_listdata_key($b,$listdata);
+
+ # get the numerical order for the param
+ $aparm=$keyorder{'parameter_0_'.$aparm};
+ $bparm=$keyorder{'parameter_0_'.$bparm};
+
+ my $result=0;
+
+ if ($sortorder eq 'realmstudent') {
+ if ($ares ne $bres ) {
+ $result = ($ares cmp $bres);
+ } elsif ($astudent ne $bstudent) {
+ $result = ($astudent cmp $bstudent);
+ } elsif ($apart ne $bpart ) {
+ $result = ($apart cmp $bpart);
+ }
} else {
- $r->print(" \n");
+ if ($astudent ne $bstudent) {
+ $result = ($astudent cmp $bstudent);
+ } elsif ($ares ne $bres ) {
+ $result = ($ares cmp $bres);
+ } elsif ($apart ne $bpart ) {
+ $result = ($apart cmp $bpart);
+ }
+ }
+
+ if (!$result) {
+ if (defined($aparm) && defined($bparm)) {
+ $result = ($aparm <=> $bparm);
+ } elsif (defined($aparm)) {
+ $result = -1;
+ } elsif (defined($bparm)) {
+ $result = 1;
+ }
+ }
+
+ $result;
+ } keys %{$listdata}) {
+
+ if ($$listdata{$thiskey.'.type'}) {
+ my $thistype=$$listdata{$thiskey.'.type'};
+ if ($$resourcedata{$thiskey.'.type'}) {
+ $thistype=$$resourcedata{$thiskey.'.type'};
+ }
+ my ($middle,$part,$name)=
+ ($thiskey=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);
+ my $section=&mt('All Students');
+ if ($middle=~/^\[(.*)\]/) {
+ my $issection=$1;
+ if ($issection=~/^useropt\:($match_username)\:($match_domain)/) {
+ $section=&mt('User').": ".&Apache::loncommon::plainname($1,$2);
+ } else {
+ $section=&mt('Group/Section').': '.$issection;
+ }
+ $middle=~s/^\[(.*)\]//;
+ }
+ $middle=~s/\.+$//;
+ $middle=~s/^\.+//;
+ my $realm=''.&mt('All Resources').' ';
+ if ($middle=~/^(.+)\_\_\_\(all\)$/) {
+ $realm=''.&mt('Folder/Map').': '.&Apache::lonnet::gettitle($1).' ('.$1.') ';
+ } elsif ($middle) {
+ my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
+ $realm=''.&mt('Resource').': '.&Apache::lonnet::gettitle($middle).' ('.$url.' in '.$map.' id: '.$id.') ';
+ }
+ if ($sortorder eq 'realmstudent') {
+ if ($realm ne $oldrealm) {
+ $r->print(&tableend()."\n$realm ");
+ $oldrealm=$realm;
+ $oldsection='';
+ }
+ if ($section ne $oldsection) {
+ $r->print(&tableend()."\n$section ");
+ $oldsection=$section;
+ $oldpart='';
+ }
+ } else {
+ if ($section ne $oldsection) {
+ $r->print(&tableend()."\n$section ");
+ $oldsection=$section;
+ $oldrealm='';
+ }
+ if ($realm ne $oldrealm) {
+ $r->print(&tableend()."\n$realm ");
+ $oldrealm=$realm;
+ $oldpart='';
+ }
+ }
+ if ($part ne $oldpart) {
+ $r->print(&tableend().
+ "\n".&mt('Part').": $part ");
+ $oldpart=$part;
+ }
+#
+# Ready to print
+#
+ $r->print(&tablestart().
+ &Apache::loncommon::start_data_table_row().
+ ''.&standard_parameter_names($name).
+ ' ');
+ $foundkeys++;
+ if (&isdateparm($thistype)) {
+ my $jskey='key_'.$pointer;
+ $pointer++;
+ $r->print(
+ &Apache::lonhtmlcommon::date_setter('parmform',
+ $jskey,
+ $$resourcedata{$thiskey},
+ '',1,'','').
+' '.
+(($$resourcedata{$thiskey}!=0)?''.
+&mt('Shift all dates based on this date').' ':'').
+&date_sanity_info($$resourcedata{$thiskey})
+ );
+ } elsif ($thistype eq 'date_interval') {
+ $r->print(&date_interval_selector($thiskey,
+ $$resourcedata{$thiskey}));
+ } elsif ($thistype =~ m/^string/) {
+ $r->print(&string_selector($thistype,$thiskey,
+ $$resourcedata{$thiskey}));
+ } else {
+ $r->print(&default_selector($thiskey,$$resourcedata{$thiskey}));
+ }
+ $r->print(' ');
+ $r->print(' '.&Apache::loncommon::end_data_table_row());
+ }
+ }
+ return $foundkeys;
+}
+
+
+sub date_interval_selector {
+ my ($thiskey, $showval) = @_;
+ my $result;
+ foreach my $which (['days', 86400, 31],
+ ['hours', 3600, 23],
+ ['minutes', 60, 59],
+ ['seconds', 1, 59]) {
+ my ($name, $factor, $max) = @{ $which };
+ my $amount = int($showval/$factor);
+ $showval %= $factor;
+ my %select = ((map {$_ => $_} (0..$max)),
+ 'select_form_order' => [0..$max]);
+ $result .= &Apache::loncommon::select_form($amount,$name.'_'.$thiskey,
+ %select);
+ $result .= ' '.&mt($name);
+ }
+ $result .= ' ';
+ return $result;
+
+}
+
+sub get_date_interval_from_form {
+ my ($key) = @_;
+ my $seconds = 0;
+ foreach my $which (['days', 86400],
+ ['hours', 3600],
+ ['minutes', 60],
+ ['seconds', 1]) {
+ my ($name, $factor) = @{ $which };
+ if (defined($env{'form.'.$name.'_'.$key})) {
+ $seconds += $env{'form.'.$name.'_'.$key} * $factor;
+ }
+ }
+ return $seconds;
+}
+
+
+sub default_selector {
+ my ($thiskey, $showval) = @_;
+ return ' ';
+}
+
+my %strings =
+ (
+ 'string_yesno'
+ => [[ 'yes', 'Yes' ],
+ [ 'no', 'No' ]],
+ 'string_problemstatus'
+ => [[ 'yes', 'Yes' ],
+ [ 'answer', 'Yes, and show correct answer if they exceed the maximum number of tries.' ],
+ [ 'no', 'No, don\'t show correct/incorrect feedback.' ],
+ [ 'no_feedback_ever', 'No, show no feedback at all.' ]],
+ );
+
+
+sub string_selector {
+ my ($thistype, $thiskey, $showval) = @_;
+
+ if (!exists($strings{$thistype})) {
+ return &default_selector($thiskey,$showval);
+ }
+
+ my $result;
+ foreach my $possibilities (@{ $strings{$thistype} }) {
+ my ($name, $description) = @{ $possibilities };
+ $result .= ' ';
+ }
+ return $result;
+}
+
+#
+# Shift all start and end dates by $shift
+#
+
+sub dateshift {
+ my ($shift)=@_;
+ my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
+ my %data=&Apache::lonnet::dump('resourcedata',$dom,$crs);
+# ugly retro fix for broken version of types
+ foreach my $key (keys %data) {
+ if ($key=~/\wtype$/) {
+ my $newkey=$key;
+ $newkey=~s/type$/\.type/;
+ $data{$newkey}=$data{$key};
+ delete $data{$key};
}
-# -------------------------------------------------- End entry for one resource
- } @ids;
- $r->print('