--- loncom/interface/loncommon.pm 2003/11/07 21:04:37 1.144 +++ loncom/interface/loncommon.pm 2004/02/23 21:10:06 1.184 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # a pile of common routines # -# $Id: loncommon.pm,v 1.144 2003/11/07 21:04:37 matthew Exp $ +# $Id: loncommon.pm,v 1.184 2004/02/23 21:10:06 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -25,13 +25,6 @@ # # http://www.lon-capa.org/ # -# YEAR=2001 -# 2/13-12/7 Guy Albertelli -# 12/21 Gerd Kortemeyer -# 12/25,12/28 Gerd Kortemeyer -# YEAR=2002 -# 1/4 Gerd Kortemeyer -# 6/24,7/2 H. K. Ng # Makes a table out of the previous attempts # Inputs result_from_symbread, user, domain, course_id @@ -73,11 +66,9 @@ use HTML::Entities; my $readit; -=pod - -=head1 Global Variables - -=cut +## +## Global Variables +## # ----------------------------------------------- Filetypes/Languages/Copyright my %language; @@ -111,32 +102,34 @@ BEGIN { unless ($readit) { # ------------------------------------------------------------------- languages { - my $fh=Apache::File->new($Apache::lonnet::perlvar{'lonTabDir'}. - '/language.tab'); - if ($fh) { - while (<$fh>) { - next if /^\#/; - chomp; - my ($key,$two,$country,$three,$enc,$val,$sup)=(split(/\t/,$_)); - $language{$key}=$val.' - '.$enc; - if ($sup) { - $supported_language{$key}=$sup; - } - } - } + my $langtabfile = $Apache::lonnet::perlvar{'lonTabDir'}. + '/language.tab'; + if ( open(my $fh,"<$langtabfile") ) { + while (<$fh>) { + next if /^\#/; + chomp; + my ($key,$two,$country,$three,$enc,$val,$sup)=(split(/\t/,$_)); + $language{$key}=$val.' - '.$enc; + if ($sup) { + $supported_language{$key}=$sup; + } + } + close($fh); + } } # ------------------------------------------------------------------ copyrights { - my $fh=Apache::File->new($Apache::lonnet::perlvar{'lonIncludes'}. - '/copyright.tab'); - if ($fh) { - while (<$fh>) { - next if /^\#/; - chomp; - my ($key,$val)=(split(/\s+/,$_,2)); - $cprtag{$key}=$val; - } - } + my $copyrightfile = $Apache::lonnet::perlvar{'lonIncludes'}. + '/copyright.tab'; + if ( open (my $fh,"<$copyrightfile") ) { + while (<$fh>) { + next if /^\#/; + chomp; + my ($key,$val)=(split(/\s+/,$_,2)); + $cprtag{$key}=$val; + } + close($fh); + } } # -------------------------------------------------------------- domain designs @@ -147,15 +140,16 @@ BEGIN { while ($filename=readdir(DIR)) { my ($domain)=($filename=~/^(\w+)\./); { - my $fh=Apache::File->new($designdir.'/'.$filename); - if ($fh) { - while (<$fh>) { - next if /^\#/; - chomp; - my ($key,$val)=(split(/\=/,$_)); - if ($val) { $designhash{$domain.'.'.$key}=$val; } - } - } + my $designfile = $designdir.'/'.$filename; + if ( open (my $fh,"<$designfile") ) { + while (<$fh>) { + next if /^\#/; + chomp; + my ($key,$val)=(split(/\=/,$_)); + if ($val) { $designhash{$domain.'.'.$key}=$val; } + } + close($fh); + } } } @@ -164,32 +158,35 @@ BEGIN { # ------------------------------------------------------------- file categories { - my $fh=Apache::File->new($Apache::lonnet::perlvar{'lonTabDir'}. - '/filecategories.tab'); - if ($fh) { - while (<$fh>) { - next if /^\#/; - chomp; - my ($extension,$category)=(split(/\s+/,$_,2)); - push @{$category_extensions{lc($category)}},$extension; - } - } + my $categoryfile = $Apache::lonnet::perlvar{'lonTabDir'}. + '/filecategories.tab'; + if ( open (my $fh,"<$categoryfile") ) { + while (<$fh>) { + next if /^\#/; + chomp; + my ($extension,$category)=(split(/\s+/,$_,2)); + push @{$category_extensions{lc($category)}},$extension; + } + close($fh); + } + } # ------------------------------------------------------------------ file types { - my $fh=Apache::File->new($Apache::lonnet::perlvar{'lonTabDir'}. - '/filetypes.tab'); - if ($fh) { + my $typesfile = $Apache::lonnet::perlvar{'lonTabDir'}. + '/filetypes.tab'; + if ( open (my $fh,"<$typesfile") ) { while (<$fh>) { - next if (/^\#/); - chomp; - my ($ending,$emb,$descr)=split(/\s+/,$_,3); - if ($descr ne '') { - $fe{$ending}=lc($emb); - $fd{$ending}=$descr; - } - } - } + next if (/^\#/); + chomp; + my ($ending,$emb,$descr)=split(/\s+/,$_,3); + if ($descr ne '') { + $fe{$ending}=lc($emb); + $fd{$ending}=$descr; + } + } + close($fh); + } } &Apache::lonnet::logthis( "INFO: Read file types"); @@ -204,10 +201,6 @@ BEGIN { =pod -=head1 General Subroutines - -=over 4 - =head1 HTML and Javascript Functions =over 4 @@ -219,8 +212,6 @@ containing javascript with two functions C. Returned string does not contain EscriptE tags. -=over 4 - =item * openbrowser(formname,elementname,only,omit) [javascript] inputs: formname, elementname, only, omit @@ -241,15 +232,14 @@ Inputs: formname, elementname formname and elementname specify the name of the html form and the name of the element the selection from the search results will be placed in. -=back - =cut sub browser_and_searcher_javascript { + my $resurl=&lastresurl(); return < $resurl}); + &Apache::lonnet::appenv('environment.lastresurl' => $resurl); + return 1; +} + sub studentbrowser_javascript { unless ( (($ENV{'request.course.id'}) && @@ -565,6 +572,8 @@ sub help_open_topic { my $template = ""; my $link; + $topic=~s/\W/\_/g; + if (!$stayOnPage) { $link = "javascript:void(open('/adm/help/${filename}.hlp', 'Help_for_$topic', 'menubar=0,toolbar=1,scrollbars=1,width=$width,height=$height,resizable=yes'))"; @@ -583,8 +592,9 @@ sub help_open_topic { } # Add the graphic + my $title = &mt('Online Help'); $template .= <<"ENDTEMPLATE"; - (Help: $topic) + (Help: $topic) ENDTEMPLATE if ($text ne '') { $template.='' }; return $template; @@ -611,6 +621,97 @@ sub helpLatexCheatsheet { .''; } +sub help_open_bug { + my ($topic, $text, $stayOnPage, $width, $height) = @_; + unless ($ENV{'user.adv'}) { return ''; } + unless ($Apache::lonnet::perlvar{'BugzillaHost'}) { return ''; } + $text = "" if (not defined $text); + $stayOnPage = 0 if (not defined $stayOnPage); + if ($ENV{'browser.interface'} eq 'textual' || + $ENV{'environment.remote'} eq 'off' ) { + $stayOnPage=1; + } + $width = 600 if (not defined $width); + $height = 600 if (not defined $height); + + $topic=~s/\W+/\+/g; + my $link=''; + my $template=''; + my $url=$Apache::lonnet::perlvar{'BugzillaHost'}.'enter_bug.cgi?product=LON-CAPA&bug_file_loc='. + &Apache::lonnet::escape($ENV{'REQUEST_URI'}).'&component='.$topic; + if (!$stayOnPage) + { + $link = "javascript:void(open('$url', 'Bugzilla', 'menubar=0,toolbar=1,scrollbars=1,width=$width,height=$height,resizable=yes'))"; + } + else + { + $link = $url; + } + # Add the text + if ($text ne "") + { + $template .= + "". + "
$text"; + } + + # Add the graphic + my $title = &mt('Report a Bug'); + $template .= <<"ENDTEMPLATE"; + (Bug: $topic) +ENDTEMPLATE + if ($text ne '') { $template.='
' }; + return $template; + +} + +sub help_open_faq { + my ($topic, $text, $stayOnPage, $width, $height) = @_; + unless ($ENV{'user.adv'}) { return ''; } + unless ($Apache::lonnet::perlvar{'FAQHost'}) { return ''; } + $text = "" if (not defined $text); + $stayOnPage = 0 if (not defined $stayOnPage); + if ($ENV{'browser.interface'} eq 'textual' || + $ENV{'environment.remote'} eq 'off' ) { + $stayOnPage=1; + } + $width = 350 if (not defined $width); + $height = 400 if (not defined $height); + + $topic=~s/\W+/\+/g; + my $link=''; + my $template=''; + my $url=$Apache::lonnet::perlvar{'FAQHost'}.'/fom/cache/'.$topic.'.html'; + if (!$stayOnPage) + { + $link = "javascript:void(open('$url', 'FAQ-O-Matic', 'menubar=0,toolbar=1,scrollbars=1,width=$width,height=$height,resizable=yes'))"; + } + else + { + $link = $url; + } + + # Add the text + if ($text ne "") + { + $template .= + "". + "
$text"; + } + + # Add the graphic + my $title = &mt('View the FAQ'); + $template .= <<"ENDTEMPLATE"; + (FAQ: $topic) +ENDTEMPLATE + if ($text ne '') { $template.='
' }; + return $template; + +} + +############################################################### +############################################################### + =pod =item * csv_translate($text) @@ -620,6 +721,8 @@ format. =cut +############################################################### +############################################################### sub csv_translate { my $text = shift; $text =~ s/\"/\"\"/g; @@ -627,6 +730,60 @@ sub csv_translate { return $text; } + +############################################################### +############################################################### + +=pod + +=item * define_excel_formats + +Define some commonly used Excel cell formats. + +Currently supported formats: + +=over 4 + +=item header + +=item bold + +=item h1 + +=item h2 + +=item h3 + +=item date + +=back + +Inputs: $workbook + +Returns: $format, a hash reference. + +=cut + +############################################################### +############################################################### +sub define_excel_formats { + my ($workbook) = @_; + my $format; + $format->{'header'} = $workbook->add_format(bold => 1, + bottom => 1, + align => 'center'); + $format->{'bold'} = $workbook->add_format(bold=>1); + $format->{'h1'} = $workbook->add_format(bold=>1, size=>18); + $format->{'h2'} = $workbook->add_format(bold=>1, size=>16); + $format->{'h3'} = $workbook->add_format(bold=>1, size=>14); + $format->{'date'} = $workbook->add_format(num_format=> + 'mmm d yyyy hh:mm AM/PM'); + return $format; +} + +############################################################### +############################################################### + =pod =item * change_content_javascript(): @@ -735,11 +892,40 @@ sub get_domains { my @domains; my %seen; foreach (sort values(%Apache::lonnet::hostdom)) { - push (@domains,$_) unless $seen{$_}++; + push (@domains,$_) unless $seen{$_}++; } return @domains; } +# ------------------------------------------ + +sub domain_select { + my ($name,$value,$multiple)=@_; + my %domains=map { + $_ => $_.' '.$Apache::lonnet::domaindescription{$_} + } &get_domains; + if ($multiple) { + $domains{''}=&mt('Any domain'); + return &multiple_select_form($name,$value,%domains); + } else { + return &select_form($name,$value,%domains); + } +} + +sub multiple_select_form { + my ($name,$value,%hash)=@_; + my %selected = map { $_ => 1 } ref($value)?@{$value}:($value); + my $output=''; + my $size =(scalar keys %hash<4?scalar keys %hash:4); + $output.="\n\n"; + return $output; +} + #------------------------------------------- =pod @@ -771,6 +957,42 @@ sub select_form { return $selectform; } +sub gradeleveldescription { + my $gradelevel=shift; + my %gradelevels=(0 => 'Not specified', + 1 => 'Grade 1', + 2 => 'Grade 2', + 3 => 'Grade 3', + 4 => 'Grade 4', + 5 => 'Grade 5', + 6 => 'Grade 6', + 7 => 'Grade 7', + 8 => 'Grade 8', + 9 => 'Grade 9', + 10 => 'Grade 10', + 11 => 'Grade 11', + 12 => 'Grade 12', + 13 => 'Grade 13', + 14 => '100 Level', + 15 => '200 Level', + 16 => '300 Level', + 17 => '400 Level', + 18 => 'Graduate Level'); + return &mt($gradelevels{$gradelevel}); +} + +sub select_level_form { + my ($deflevel,$name)=@_; + unless ($deflevel) { $deflevel=0; } + my $selectform = ""; + return $selectform; +} #------------------------------------------- @@ -887,6 +1109,8 @@ Outputs: =back +=back + =cut ############################################################### @@ -925,12 +1149,6 @@ sub decode_user_agent { $clientunicode,$clientos,); } -=pod - -=back - -=cut - ############################################################### ## Authentication changing form generation subroutines ## ############################################################### @@ -971,6 +1189,8 @@ See loncreateuser.pm for invocation and =back +=back + =cut #------------------------------------------- @@ -998,10 +1218,30 @@ END $Javascript_toUpperCase = ""; } + my $radioval = "'nochange'"; + if (exists($in{'curr_authtype'}) && + defined($in{'curr_authtype'}) && + $in{'curr_authtype'} ne '') { + $radioval = "'$in{'curr_authtype'}arg'"; + } + my $argfield = 'null'; + if ( grep/^mode$/,(keys %in) ) { + if ($in{'mode'} eq 'modifycourse') { + if ( grep/^curr_authtype$/,(keys %in) ) { + $radioval = "'$in{'curr_authtype'}'"; + } + if ( grep/^curr_autharg$/,(keys %in) ) { + unless ($in{'curr_autharg'} eq '') { + $argfield = "'$in{'curr_autharg'}'"; + } + } + } + } + $result.=<<"END"; var current = new Object(); -current.radiovalue = 'nochange'; -current.argfield = null; +current.radiovalue = $radioval; +current.argfield = $argfield; function changed_radio(choice,currentform) { var choicearg = choice + 'arg'; @@ -1088,20 +1328,32 @@ sub authform_kerberos{ kerb_def_auth => 'krb4', @_, ); - my ($check4,$check5); + my ($check4,$check5,$krbarg); if ($in{'kerb_def_auth'} eq 'krb5') { $check5 = " checked=\"on\""; } else { $check4 = " checked=\"on\""; } + $krbarg = $in{'kerb_def_dom'}; + + my $krbcheck = ""; + if ( grep/^curr_authtype$/,(keys %in) ) { + if ($in{'curr_authtype'} =~ m/^krb/) { + $krbcheck = " checked=\"on\""; + if ( grep/^curr_autharg$/,(keys %in) ) { + $krbarg = $in{'curr_autharg'}; + } + } + } + my $jscall = "javascript:changed_radio('krb',$in{'formname'});"; my $result .= &mt ('[_1] Kerberos authenticated with domain [_2] '. '[_3] Version 4 [_4] Version 5', '', + 'onclick="'.$jscall.'" onchange="'.$jscall.'"'.$krbcheck.' />', '', '', ''); @@ -1114,13 +1366,25 @@ sub authform_internal{ kerb_def_dom => 'MSU.EDU', @_, ); + + my $intcheck = ""; + my $intarg = 'value=""'; + if ( grep/^curr_authtype$/,(keys %args) ) { + if ($args{'curr_authtype'} eq 'int') { + $intcheck = " checked=\"on\""; + if ( grep/^curr_autharg$/,(keys %args) ) { + $intarg = "value=\"$args{'curr_autharg'}\""; + } + } + } + my $jscall = "javascript:changed_radio('int',$args{'formname'});"; my $result.=&mt ('[_1] Internally authenticated (with initial password [_2])', - '', - ''); + '', + ''); return $result; } @@ -1130,12 +1394,24 @@ sub authform_local{ kerb_def_dom => 'MSU.EDU', @_, ); + + my $loccheck = ""; + my $locarg = 'value=""'; + if ( grep/^curr_authtype$/,(keys %in) ) { + if ($in{'curr_authtype'} eq 'loc') { + $loccheck = " checked=\"on\""; + if ( grep/^curr_autharg$/,(keys %in) ) { + $locarg = "value=\"$in{'curr_autharg'}\""; + } + } + } + my $jscall = "javascript:changed_radio('loc',$in{'formname'});"; - my $result.=&mt('[_1] Local Authentication with arguement [_2]', - '', - ''); + my $result.=&mt('[_1] Local Authentication with argument [_2]', + '', + ''); return $result; } @@ -1155,12 +1431,6 @@ sub authform_filesystem{ return $result; } -=pod - -=back - -=cut - ############################################################### ## Get Authentication Defaults for Domain ## ############################################################### @@ -1315,7 +1585,7 @@ sub keyword { =item * get_related_words -Look up a word in the thesaurus. Takes a scalar arguement and returns +Look up a word in the thesaurus. Takes a scalar argument and returns an array of words. If the keyword is not in the thesaurus, an empty array will be returned. The order of the words returned is determined by the database which holds them. @@ -1451,8 +1721,9 @@ sub noteswrapper { # ------------------------------------------------------------- Aboutme Wrapper sub aboutmewrapper { - my ($link,$username,$domain)=@_; - return "$link"; + my ($link,$username,$domain,$target)=@_; + return "$link"; } # ------------------------------------------------------------ Syllabus Wrapper @@ -1499,6 +1770,16 @@ sub languagedescription { ($supported_language{$code}?' ('.&mt('interface available').')':''); } +sub plainlanguagedescription { + my $code=shift; + return $language{$code}; +} + +sub supportedlanguagecode { + my $code=shift; + return $supported_language{$code}; +} + =pod =item * copyrightids() @@ -1520,7 +1801,7 @@ returns description of a specified copyr =cut sub copyrightdescription { - return $cprtag{shift(@_)}; + return &mt($cprtag{shift(@_)}); } =pod @@ -1560,6 +1841,14 @@ sub fileembstyle { return $fe{lc(shift(@_))}; } + +sub filecategoryselect { + my ($name,$value)=@_; + return &select_form($name,$value, + '' => &mt('Any category'), + map { $_,$_ } sort(keys(%category_extensions))); +} + =pod =item * filedescription() @@ -1569,7 +1858,7 @@ returns description for a specified file =cut sub filedescription { - return $fd{lc(shift(@_))}; + return &mt($fd{lc(shift(@_))}); } =pod @@ -1583,7 +1872,7 @@ extra formatting sub filedescriptionex { my $ex=shift; - return '.'.$ex.' '.$fd{lc($ex)}; + return '.'.$ex.' '.&mt($fd{lc($ex)}); } # End of .tab access @@ -1618,13 +1907,13 @@ sub display_languages { sub preferred_languages { my @languages=(); - if ($ENV{'environment.languages'}) { - @languages=split(/\s*(\,|\;|\:)\s*/,$ENV{'environment.languages'}); - } if ($ENV{'course.'.$ENV{'request.course.id'}.'.languages'}) { @languages=(@languages,split(/\s*(\,|\;|\:)\s*/, $ENV{'course.'.$ENV{'request.course.id'}.'.languages'})); } + if ($ENV{'environment.languages'}) { + @languages=split(/\s*(\,|\;|\:)\s*/,$ENV{'environment.languages'}); + } my $browser=(split(/\;/,$ENV{'HTTP_ACCEPT_LANGUAGE'}))[0]; if ($browser) { @languages=(@languages,split(/\s*(\,|\;|\:)\s*/,$browser)); @@ -1911,21 +2200,6 @@ sub maketime { $th{'day'},$th{'month'}-1,$th{'year'}-1900,0,0,$th{'dlsav'})); } - -######################################### -# -# Retro-fixing of un-backward-compatible time format - -sub unsqltime { - my $timestamp=shift; - if ($timestamp=~/^(\d+)\-(\d+)\-(\d+)\s+(\d+)\:(\d+)\:(\d+)$/) { - $timestamp=&maketime( - 'year'=>$1,'month'=>$2,'day'=>$3, - 'hours'=>$4,'minutes'=>$5,'seconds'=>$6); - } - return $timestamp; -} - ######################################### sub findallcourses { @@ -1997,7 +2271,7 @@ sub domainlogo { my $lonhttpdPort=$Apache::lonnet::perlvar{'lonhttpdPort'}; if (!defined($lonhttpdPort)) { $lonhttpdPort='8080'; } return ''; + '/adm/lonDomLogos/'.$domain.'.gif" alt="'.$domain.'" />'; } elsif(exists($Apache::lonnet::domaindescription{$domain})) { return $Apache::lonnet::domaindescription{$domain}; } else { @@ -2085,19 +2359,7 @@ other decorations will be returned. sub bodytag { my ($title,$function,$addentries,$bodyonly,$domain,$forcereg)=@_; $title=&mt($title); - unless ($function) { - $function='student'; - if ($ENV{'request.role'}=~/^(cc|in|ta|ep)/) { - $function='coordinator'; - } - if ($ENV{'request.role'}=~/^(su|dc|ad|li)/) { - $function='admin'; - } - if (($ENV{'request.role'}=~/^(au|ca)/) || - ($ENV{'REQUEST_URI'}=~/^(\/priv|\~)/)) { - $function='author'; - } - } + $function = &get_users_function() if (!$function); my $img=&designparm($function.'.img',$domain); my $pgbg=&designparm($function.'.pgbg',$domain); my $tabbg=&designparm($function.'.tabbg',$domain); @@ -2108,8 +2370,9 @@ sub bodytag { my $sidebg=&designparm($function.'.sidebg',$domain); # Accessibility font enhance unless ($addentries) { $addentries=''; } + my $addstyle=''; if ($ENV{'browser.fontenhance'} eq 'on') { - $addentries.=' style="font-size: x-large"'; + $addstyle=' font-size: x-large;'; } # role and realm my ($role,$realm) @@ -2127,11 +2390,15 @@ sub bodytag { if (!defined($lonhttpdPort)) { $lonhttpdPort='8080'; } # construct main body tag my $bodytag = < +h1, h2, h3, th { font-family: Arial, Helvetica, sans-serif } +a:focus { color: red; background: yellow } + +style="margin-top: 0px;$addstyle" $addentries> END my $upperleft=''; + $lonhttpdPort.$img.'" alt="'.$function.'" />'; if ($bodyonly) { return $bodytag; } elsif ($ENV{'browser.interface'} eq 'textual') { @@ -2143,7 +2410,7 @@ END # No Remote return $bodytag.&Apache::lonmenu::menubuttons($forcereg,'web', $forcereg). - ' - +
'.$title. + '
'.$title. '
'; } @@ -2159,9 +2426,9 @@ $upperleft
$title - -$title + + $ENV{'environment.firstname'} $ENV{'environment.middlename'} $ENV{'environment.lastname'} @@ -2170,16 +2437,43 @@ $upperleft
-$role  +$role 
$realm 
$realm 

ENDBODY } ############################################### +=pod + +=item get_users_function + +Used by &bodytag to determine the current users primary role. +Returns either 'student','coordinator','admin', or 'author'. + +=cut + +############################################### +sub get_users_function { + my $function = 'student'; + if ($ENV{'request.role'}=~/^(cc|in|ta|ep)/) { + $function='coordinator'; + } + if ($ENV{'request.role'}=~/^(su|dc|ad|li)/) { + $function='admin'; + } + if (($ENV{'request.role'}=~/^(au|ca)/) || + ($ENV{'REQUEST_URI'}=~/^(\/priv|\~)/)) { + $function='author'; + } + return $function; +} + +############################################### + sub get_posted_cgi { my $r=shift; @@ -2314,11 +2608,16 @@ sub no_cache { } sub content_type { - my ($r,$type,$charset) = @_; - unless ($charset) { - $charset=&Apache::lonlocal::current_encoding; - } - $r->content_type($type.($charset?'; charset='.$charset:'')); + my ($r,$type,$charset) = @_; + unless ($charset) { + $charset=&Apache::lonlocal::current_encoding; + } + if ($charset) { $type.='; charset='.$charset; } + if ($r) { + $r->content_type($type); + } else { + print("Content-type: $type\n\n"); + } } =pod @@ -2350,6 +2649,32 @@ sub add_to_env { =pod +=item * get_env_multiple($name) + +gets $name from the %ENV hash, it seemlessly handles the cases where multiple +values may be defined and end up as an array ref. + +returns an array of values + +=cut + +sub get_env_multiple { + my ($name) = @_; + my @values; + if (defined($ENV{$name})) { + # exists is it an array + if (ref($ENV{$name})) { + @values=@{ $ENV{$name} }; + } else { + $values[0]=$ENV{$name}; + } + } + return(@values); +} + + +=pod + =back =head1 CSV Upload/Handling functions @@ -2374,9 +2699,12 @@ sub upfile_store { my $datatoken=$ENV{'user.name'}.'_'.$ENV{'user.domain'}. '_enroll_'.$ENV{'request.course.id'}.'_'.time.'_'.$$; { - my $fh=Apache::File->new('>'.$r->dir_config('lonDaemons'). - '/tmp/'.$datatoken.'.tmp'); - print $fh $ENV{'form.upfile'}; + my $datafile = $r->dir_config('lonDaemons'). + '/tmp/'.$datatoken.'.tmp'; + if ( open(my $fh,">$datafile") ) { + print $fh $ENV{'form.upfile'}; + close($fh); + } } return $datatoken; } @@ -2395,11 +2723,12 @@ sub load_tmp_file { my $r=shift; my @studentdata=(); { - my $fh; - if ($fh=Apache::File->new($r->dir_config('lonDaemons'). - '/tmp/'.$ENV{'form.datatoken'}.'.tmp')) { - @studentdata=<$fh>; - } + my $studentfile = $r->dir_config('lonDaemons'). + '/tmp/'.$ENV{'form.datatoken'}.'.tmp'; + if ( open(my $fh,"<$studentfile") ) { + @studentdata=<$fh>; + close($fh); + } } $ENV{'form.upfile'}=join('',@studentdata); } @@ -2444,7 +2773,7 @@ sub record_sep { } } elsif ($ENV{'form.upfiletype'} eq 'tab') { my $i=0; - foreach (split(/\t+/,$record)) { + foreach (split(/\t/,$record)) { my $field=$_; $field=~s/^(\"|\')//; $field=~s/(\"|\')$//; @@ -2552,7 +2881,7 @@ Prints a table to create associations be $r is an Apache Request ref, $records is an arrayref from &Apache::loncommon::upfile_record_sep, -$d is an array of 2 element arrays (internal name, displayed name) +$d is an array of 2 element arrays (internal name, displayed name,defaultcol) =cut @@ -2567,14 +2896,16 @@ sub csv_print_select_table { ''.&mt('Attribute').''. ''.&mt('Column').''."\n"); foreach (@$d) { - my ($value,$display)=@{ $_ }; + my ($value,$display,$defaultcol)=@{ $_ }; $r->print(''.$display.''); $r->print(''."\n"); $i++; @@ -2615,8 +2946,10 @@ sub csv_samples_select_table { $r->print(''); if (defined($sone{$_})) { $r->print($sone{$_}."
\n"); } @@ -2688,8 +3021,12 @@ sub check_if_partid_hidden { =pod +=back + =head1 cgi-bin script and graphing routines +=over 4 + =item get_cgi_id Inputs: none @@ -2703,9 +3040,10 @@ the routine &Apache::lonnet::transfer_pr ############################################################ ############################################################ - +my $uniq=0; sub get_cgi_id { - return (time.'_'.int(rand(1000))); + $uniq=($uniq+1)%100000; + return (time.'_'.$uniq); } ############################################################ @@ -2736,6 +3074,8 @@ If $Max is < any data point, the graph w =item $colors: array ref holding the colors to be used for the data sets when they are plotted. If undefined, default values will be used. +=item $labels: array ref holding the labels to use on the x-axis for the bars. + =item @Values: An array of array references. Each array reference holds data to be plotted in a stacked bar chart. @@ -2751,7 +3091,7 @@ information for the plot. ############################################################ ############################################################ sub DrawBarGraph { - my ($Title,$xlabel,$ylabel,$Max,$colors,@Values)=@_; + my ($Title,$xlabel,$ylabel,$Max,$colors,$labels,@Values)=@_; # if (! defined($colors)) { $colors = ['#33ff00', @@ -2794,8 +3134,12 @@ sub DrawBarGraph { } # my @Labels; - for (my $i=0;$i<@{$Values[0]};$i++) { - push (@Labels,$i+1); + if (defined($labels)) { + @Labels = @$labels; + } else { + for (my $i=0;$i<@{$Values[0]};$i++) { + push (@Labels,$i+1); + } } # $Max = 1 if ($Max < 1); @@ -3021,10 +3365,14 @@ sub DrawXYYGraph { =pod +=back + =head1 Statistics helper routines? Bad place for them but what the hell. +=over 4 + =item &chartlink Returns a link to the chart for a specific student. @@ -3041,6 +3389,8 @@ Inputs: =back +=back + =cut ############################################################ @@ -3053,9 +3403,139 @@ sub chartlink { '">'.$linktext.''; } +####################################################### +####################################################### + +=pod + +=head1 Course Environment Routines + +=over 4 + +=item &restore_course_settings + +=item &store_course_settings + +Restores/Store indicated form parameters from the course environment. +Will not overwrite existing values of the form parameters. + +Inputs: +a scalar describing the data (e.g. 'chart', 'problem_analysis') + +a hash ref describing the data to be stored. For example: + +%Save_Parameters = ('Status' => 'scalar', + 'chartoutputmode' => 'scalar', + 'chartoutputdata' => 'scalar', + 'Section' => 'array', + 'StudentData' => 'array', + 'Maps' => 'array'); + +Returns: both routines return nothing + +=cut + +####################################################### +####################################################### +sub store_course_settings { + # save to the environment + # appenv the same items, just to be safe + my $courseid = $ENV{'request.course.id'}; + my $coursedom = $ENV{'course.'.$courseid.'.domain'}; + my ($prefix,$Settings) = @_; + my %SaveHash; + my %AppHash; + while (my ($setting,$type) = each(%$Settings)) { + my $basename = 'internal.'.$prefix.'.'.$setting; + my $envname = 'course.'.$courseid.'.'.$basename; + if (exists($ENV{'form.'.$setting})) { + # Save this value away + if ($type eq 'scalar' && + (! exists($ENV{$envname}) || + $ENV{$envname} ne $ENV{'form.'.$setting})) { + $SaveHash{$basename} = $ENV{'form.'.$setting}; + $AppHash{$envname} = $ENV{'form.'.$setting}; + } elsif ($type eq 'array') { + my $stored_form; + if (ref($ENV{'form.'.$setting})) { + $stored_form = join(',', + map { + &Apache::lonnet::escape($_); + } sort(@{$ENV{'form.'.$setting}})); + } else { + $stored_form = + &Apache::lonnet::escape($ENV{'form.'.$setting}); + } + # Determine if the array contents are the same. + if ($stored_form ne $ENV{$envname}) { + $SaveHash{$basename} = $stored_form; + $AppHash{$envname} = $stored_form; + } + } + } + } + my $put_result = &Apache::lonnet::put('environment',\%SaveHash, + $coursedom, + $ENV{'course.'.$courseid.'.num'}); + if ($put_result !~ /^(ok|delayed)/) { + &Apache::lonnet::logthis('unable to save form parameters, '. + 'got error:'.$put_result); + } + # Make sure these settings stick around in this session, too + &Apache::lonnet::appenv(%AppHash); + return; +} + +sub restore_course_settings { + my $courseid = $ENV{'request.course.id'}; + my ($prefix,$Settings) = @_; + while (my ($setting,$type) = each(%$Settings)) { + next if (exists($ENV{'form.'.$setting})); + my $envname = 'course.'.$courseid.'.internal.'.$prefix. + '.'.$setting; + if (exists($ENV{$envname})) { + if ($type eq 'scalar') { + $ENV{'form.'.$setting} = $ENV{$envname}; + } elsif ($type eq 'array') { + $ENV{'form.'.$setting} = [ + map { + &Apache::lonnet::unescape($_); + } split(',',$ENV{$envname}) + ]; + } + } + } +} + ############################################################ ############################################################ +sub propath { + my ($udom,$uname)=@_; + $udom=~s/\W//g; + $uname=~s/\W//g; + my $subdir=$uname.'__'; + $subdir =~ s/(.)(.)(.).*/$1\/$2\/$3/; + my $proname="$Apache::lonnet::perlvar{'lonUsersDir'}/$udom/$subdir/$uname"; + return $proname; +} + +sub icon { + my ($file)=@_; + my $curfext = (split(/\./,$file))[-1]; + my $iconname=$Apache::lonnet::perlvar{'lonIconsURL'}.'/unknown.gif'; + my $embstyle = &Apache::loncommon::fileembstyle($curfext); + if (!(!defined($embstyle) || $embstyle eq 'unk' || $embstyle eq 'hdn')) { + if (-e $Apache::lonnet::perlvar{'lonDocRoot'}.'/'. + $Apache::lonnet::perlvar{'lonIconsURL'}.'/'. + $curfext.".gif") { + $iconname=$Apache::lonnet::perlvar{'lonIconsURL'}.'/'. + $curfext.".gif"; + } + } + return $iconname; +} + =pod =back