--- loncom/interface/loncommon.pm 2003/10/29 16:20:14 1.139 +++ loncom/interface/loncommon.pm 2003/12/22 23:34:49 1.162 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # a pile of common routines # -# $Id: loncommon.pm,v 1.139 2003/10/29 16:20:14 matthew Exp $ +# $Id: loncommon.pm,v 1.162 2003/12/22 23:34:49 www 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; @@ -91,50 +82,19 @@ my %category_extensions; my %designhash; # ---------------------------------------------- Thesaurus variables - -# FIXME: I don't think it's necessary to document these things; -# they're privately used - Jeremy - -=pod - -=over 4 - -=item * %Keywords - -A hash used by &keyword to determine if a word is considered a keyword. - -=item * $thesaurus_db_file - -Scalar containing the full path to the thesaurus database. - -=back - -=cut +# +# %Keywords: +# A hash used by &keyword to determine if a word is considered a keyword. +# $thesaurus_db_file +# Scalar containing the full path to the thesaurus database. my %Keywords; my $thesaurus_db_file; -# ----------------------------------------------------------------------- BEGIN - -# FIXME: I don't think this needs to be documented, it prepares -# private data structures - Jeremy -=pod - -=head1 General Subroutines - -=over 4 - -=item * BEGIN() - -Initialize values from language.tab, copyright.tab, filetypes.tab, -thesaurus.tab, and filecategories.tab. - -=back - -=cut - -# ----------------------------------------------------------------------- BEGIN - +# +# Initialize values from language.tab, copyright.tab, filetypes.tab, +# thesaurus.tab, and filecategories.tab. +# BEGIN { # Variable initialization $thesaurus_db_file = $Apache::lonnet::perlvar{'lonTabDir'}."/thesaurus.db"; @@ -142,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 @@ -178,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); + } } } @@ -195,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( "<font color=yellow>INFO: Read file types</font>"); @@ -246,8 +212,6 @@ containing javascript with two functions C<opensearcher>. Returned string does not contain E<lt>scriptE<gt> tags. -=over 4 - =item * openbrowser(formname,elementname,only,omit) [javascript] inputs: formname, elementname, only, omit @@ -268,8 +232,6 @@ 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 { @@ -521,6 +483,7 @@ function select1_changed() { // in with the nuclear for (i=0;i<values.length; i++) { $second.options[i] = new Option(values[i]); + $second.options[i].value = values[i]; $second.options[i].text = texts[i]; if (values[i] == select2def) { $second.options[i].selected = true; @@ -591,6 +554,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'))"; @@ -913,6 +878,8 @@ Outputs: =back +=back + =cut ############################################################### @@ -951,12 +918,6 @@ sub decode_user_agent { $clientunicode,$clientos,); } -=pod - -=back - -=cut - ############################################################### ## Authentication changing form generation subroutines ## ############################################################### @@ -997,6 +958,8 @@ See loncreateuser.pm for invocation and =back +=back + =cut #------------------------------------------- @@ -1087,10 +1050,10 @@ END sub authform_authorwarning{ my $result=''; - $result=<<"END"; -<i>As a general rule, only authors or co-authors should be filesystem -authenticated (which allows access to the server filesystem).</i> -END + $result='<i>'. + &mt('As a general rule, only authors or co-authors should be '. + 'filesystem authenticated '. + '(which allows access to the server filesystem).')."</i>\n"; return $result; } @@ -1100,12 +1063,10 @@ sub authform_nochange{ kerb_def_dom => 'MSU.EDU', @_, ); - my $result=''; - $result.=<<"END"; -<input type="radio" name="login" value="nochange" checked="checked" - onclick="javascript:changed_radio('nochange',$in{'formname'});" /> -Do not change login data -END + my $result = &mt('[_1] Do not change login data', + '<input type="radio" name="login" value="nochange" '. + 'checked="checked" onclick="'. + "javascript:changed_radio('nochange',$in{'formname'});".'" />'); return $result; } @@ -1116,24 +1077,23 @@ sub authform_kerberos{ kerb_def_auth => 'krb4', @_, ); - my $result=''; - my $check4; - my $check5; + my ($check4,$check5); if ($in{'kerb_def_auth'} eq 'krb5') { $check5 = " checked=\"on\""; } else { $check4 = " checked=\"on\""; } - $result.=<<"END"; -<input type="radio" name="login" value="krb" - onclick="javascript:changed_radio('krb',$in{'formname'});" - onchange="javascript:changed_radio('krb',$in{'formname'});" /> -Kerberos authenticated with domain -<input type="text" size="10" name="krbarg" value="$in{'kerb_def_dom'}" - onchange="javascript:changed_text('krb',$in{'formname'});" /> -<input type="radio" name="krbver" value="4" $check4 />Version 4 -<input type="radio" name="krbver" value="5" $check5 />Version 5 -END + my $jscall = "javascript:changed_radio('krb',$in{'formname'});"; + my $result .= &mt + ('[_1] Kerberos authenticated with domain [_2] '. + '[_3] Version 4 [_4] Version 5', + '<input type="radio" name="login" value="krb" '. + 'onclick="'.$jscall.'" onchange="'.$jscall.'" />', + '<input type="text" size="10" name="krbarg" '. + 'value="'.$in{'kerb_def_dom'}.'" '. + 'onchange="'.$jscall.'" />', + '<input type="radio" name="krbver" value="4" '.$check4.' />', + '<input type="radio" name="krbver" value="5" '.$check5.' />'); return $result; } @@ -1143,15 +1103,13 @@ sub authform_internal{ kerb_def_dom => 'MSU.EDU', @_, ); - my $result=''; - $result.=<<"END"; -<input type="radio" name="login" value="int" - onchange="javascript:changed_radio('int',$args{'formname'});" - onclick="javascript:changed_radio('int',$args{'formname'});" /> -Internally authenticated (with initial password -<input type="text" size="10" name="intarg" value="" - onchange="javascript:changed_text('int',$args{'formname'});" />) -END + my $jscall = "javascript:changed_radio('int',$args{'formname'});"; + my $result.=&mt + ('[_1] Internally authenticated (with initial password [_2])', + '<input type="radio" name="login" value="int" '. + 'onchange="'.$jscall.'" onclick="'.$jscall.'" />', + '<input type="text" size="10" name="intarg" value="" '. + 'onchange="'.$jscall.'" />'); return $result; } @@ -1161,15 +1119,12 @@ sub authform_local{ kerb_def_dom => 'MSU.EDU', @_, ); - my $result=''; - $result.=<<"END"; -<input type="radio" name="login" value="loc" - onchange="javascript:changed_radio('loc',$in{'formname'});" - onclick="javascript:changed_radio('loc',$in{'formname'});" /> -Local Authentication with argument -<input type="text" size="10" name="locarg" value="" - onchange="javascript:changed_text('loc',$in{'formname'});" /> -END + my $jscall = "javascript:changed_radio('loc',$in{'formname'});"; + my $result.=&mt('[_1] Local Authentication with argument [_2]', + '<input type="radio" name="login" value="loc" '. + 'onchange="'.$jscall.'" onclick="'.$jscall.'" />', + '<input type="text" size="10" name="locarg" value="" '. + 'onchange="'.$jscall.'" />'); return $result; } @@ -1179,24 +1134,16 @@ sub authform_filesystem{ kerb_def_dom => 'MSU.EDU', @_, ); - my $result=''; - $result.=<<"END"; -<input type="radio" name="login" value="fsys" - onchange="javascript:changed_radio('fsys',$in{'formname'});" - onclick="javascript:changed_radio('fsys',$in{'formname'});" /> -Filesystem authenticated (with initial password -<input type="text" size="10" name="fsysarg" value="" - onchange="javascript:changed_text('fsys',$in{'formname'});">) -END + my $jscall = "javascript:changed_radio('fsys',$in{'formname'});"; + my $result.= &mt + ('[_1] Filesystem Authenticated (with initial password [_2])', + '<input type="radio" name="login" value="fsys" '. + 'onchange="'.$jscall.'" onclick="'.$jscall.'" />', + '<input type="text" size="10" name="fsysarg" value="" '. + 'onchange="'.$jscall.'" />'); return $result; } -=pod - -=back - -=cut - ############################################################### ## Get Authentication Defaults for Domain ## ############################################################### @@ -1351,7 +1298,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. @@ -1535,6 +1482,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() @@ -1771,7 +1728,7 @@ sub get_previous_attempt { } else { $value=$returnhash{$version.':'.$_}; } - $prevattempts.='<td>'.$value.' </td>'; + $prevattempts.='<td>'.&Apache::lonnet::unescape($value).' </td>'; } } } @@ -1783,6 +1740,7 @@ sub get_previous_attempt { } else { $value=$lasthash{$_}; } + $value=&Apache::lonnet::unescape($value); if ($_ =~/$regexp$/ && (defined &$gradesub)) {$value = &$gradesub($value)} $prevattempts.='<td>'.$value.' </td>'; } @@ -2032,7 +1990,7 @@ sub domainlogo { my $lonhttpdPort=$Apache::lonnet::perlvar{'lonhttpdPort'}; if (!defined($lonhttpdPort)) { $lonhttpdPort='8080'; } return '<img src="http://'.$ENV{'HTTP_HOST'}.':'.$lonhttpdPort. - '/adm/lonDomLogos/'.$domain.'.gif" />'; + '/adm/lonDomLogos/'.$domain.'.gif" alt="'.$domain.'" />'; } elsif(exists($Apache::lonnet::domaindescription{$domain})) { return $Apache::lonnet::domaindescription{$domain}; } else { @@ -2143,8 +2101,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) @@ -2162,11 +2121,15 @@ sub bodytag { if (!defined($lonhttpdPort)) { $lonhttpdPort='8080'; } # construct main body tag my $bodytag = <<END; +<style> +h1, h2, h3, th { font-family: Arial, Helvetica, sans-serif } +a:focus { color: red; background: yellow } +</style> <body bgcolor="$pgbg" text="$font" alink="$alink" vlink="$vlink" link="$link" -$addentries> +style="margin-top: 0px;$addstyle" $addentries> END my $upperleft='<img src="http://'.$ENV{'HTTP_HOST'}.':'. - $lonhttpdPort.$img.'" />'; + $lonhttpdPort.$img.'" alt="'.$function.'" />'; if ($bodyonly) { return $bodytag; } elsif ($ENV{'browser.interface'} eq 'textual') { @@ -2178,7 +2141,7 @@ END # No Remote return $bodytag.&Apache::lonmenu::menubuttons($forcereg,'web', $forcereg). - '<table bgcolor="'.$pgbg.'" width="100%" border="0" cellspacing="3" cellpadding="3"><tr><td bgcolor="'.$tabbg.'"><font size="+3" color="'.$font.'"><b>'.$title. + '<table bgcolor="'.$pgbg.'" width="100%" border="0" cellspacing="3" cellpadding="3"><tr><td bgcolor="'.$tabbg.'"><font face="Arial, Helvetica, sans-serif" size="+3" color="'.$font.'"><b>'.$title. '</b></font></td></tr></table>'; } @@ -2194,9 +2157,9 @@ $upperleft</td> </tr> <tr> <td rowspan="3" bgcolor="$tabbg"> - <font size="5"><b>$title</b></font> -<td bgcolor="$tabbg" align="right"> -<font size="2"> + <font size="5" face="Arial, Helvetica, sans-serif"><b>$title</b></font> +<td bgcolor="$tabbg" align="right"> +<font size="2" face="Arial, Helvetica, sans-serif"> $ENV{'environment.firstname'} $ENV{'environment.middlename'} $ENV{'environment.lastname'} @@ -2205,10 +2168,10 @@ $upperleft</td> </td> </tr> <tr><td bgcolor="$tabbg" align="right"> -<font size="2">$role</font> +<font size="2" face="Arial, Helvetica, sans-serif">$role</font> </td></tr> <tr> -<td bgcolor="$tabbg" align="right"><font size="2">$realm</font> </td></tr> +<td bgcolor="$tabbg" align="right"><font size="2" face="Arial, Helvetica, sans-serif">$realm</font> </td></tr> </table><br> ENDBODY } @@ -2385,6 +2348,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 @@ -2409,9 +2398,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; } @@ -2430,11 +2422,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); } @@ -2508,26 +2501,39 @@ sub record_sep { return %components; } +###################################################### +###################################################### + =pod =item * upfile_select_html() -return HTML code to select file and specify its type +Return HTML code to select a file from the users machine and specify +the file type. =cut +###################################################### +###################################################### sub upfile_select_html { - return (<<'ENDUPFORM'); -<input type="file" name="upfile" size="50" /> -<br />Type: <select name="upfiletype"> -<option value="csv">CSV (comma separated values, spreadsheet)</option> -<option value="space">Space separated</option> -<option value="tab">Tabulator separated</option> -<option value="xml">HTML/XML</option> -</select> -ENDUPFORM + my %Types = ( + csv => &mt('CSV (comma separated values, spreadsheet)'), + space => &mt('Space separated'), + tab => &mt('Tabulator separated'), +# xml => &mt('HTML/XML'), + ); + my $Str = '<input type="file" name="upfile" size="50" />'. + '<br />Type: <select name="upfiletype">'; + foreach my $type (sort(keys(%Types))) { + $Str .= '<option value="'.$type.'" >'.$Types{$type}."</option>\n"; + } + $Str .= "</select>\n"; + return $Str; } +###################################################### +###################################################### + =pod =item * csv_print_samples($r,$records) @@ -2538,15 +2544,18 @@ Apache Request ref, $records is an array =cut +###################################################### +###################################################### sub csv_print_samples { my ($r,$records) = @_; my (%sone,%stwo,%sthree); %sone=&record_sep($$records[0]); if (defined($$records[1])) {%stwo=&record_sep($$records[1]);} if (defined($$records[2])) {%sthree=&record_sep($$records[2]);} - - $r->print('Samples<br /><table border="2"><tr>'); - foreach (sort({$a <=> $b} keys(%sone))) { $r->print('<th>Column '.($_+1).'</th>'); } + # + $r->print(&mt('Samples').'<br /><table border="2"><tr>'); + foreach (sort({$a <=> $b} keys(%sone))) { + $r->print('<th>'.&mt('Column [_1]',($_+1)).'</th>'); } $r->print('</tr>'); foreach my $hash (\%sone,\%stwo,\%sthree) { $r->print('<tr>'); @@ -2560,23 +2569,31 @@ sub csv_print_samples { $r->print('</tr></table><br />'."\n"); } +###################################################### +###################################################### + =pod =item * csv_print_select_table($r,$records,$d) Prints a table to create associations between values and table columns. + $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) =cut +###################################################### +###################################################### sub csv_print_select_table { my ($r,$records,$d) = @_; my $i=0;my %sone; %sone=&record_sep($$records[0]); - $r->print('Associate columns with student attributes.'."\n". - '<table border="2"><tr><th>Attribute</th><th>Column</th></tr>'."\n"); + $r->print(&mt('Associate columns with student attributes.')."\n". + '<table border="2"><tr>'. + '<th>'.&mt('Attribute').'</th>'. + '<th>'.&mt('Column').'</th></tr>'."\n"); foreach (@$d) { my ($value,$display)=@{ $_ }; $r->print('<tr><td>'.$display.'</td>'); @@ -2594,6 +2611,9 @@ sub csv_print_select_table { return $i; } +###################################################### +###################################################### + =pod =item * csv_samples_select_table($r,$records,$d) @@ -2606,22 +2626,25 @@ $d is an array of 2 element arrays (inte =cut +###################################################### +###################################################### sub csv_samples_select_table { my ($r,$records,$d) = @_; my %sone; my %stwo; my %sthree; my $i=0; - - $r->print('<table border=2><tr><th>Field</th><th>Samples</th></tr>'); + # + $r->print('<table border=2><tr><th>'. + &mt('Field').'</th><th>'.&mt('Samples').'</th></tr>'); %sone=&record_sep($$records[0]); if (defined($$records[1])) {%stwo=&record_sep($$records[1]);} if (defined($$records[2])) {%sthree=&record_sep($$records[2]);} - + # foreach (sort keys %sone) { - $r->print('<tr><td><select name=f'.$i. + $r->print('<tr><td><select name="f'.$i.'"'. ' onchange="javascript:flip(this.form,'.$i.');">'); foreach (@$d) { my ($value,$display)=@{ $_ }; - $r->print('<option value='.$value.'>'.$display.'</option>'); + $r->print('<option value="'.$value.'">'.$display.'</option>'); } $r->print('</select></td><td>'); if (defined($sone{$_})) { $r->print($sone{$_}."</br>\n"); } @@ -2634,6 +2657,9 @@ sub csv_samples_select_table { return($i); } +###################################################### +###################################################### + =pod =item clean_excel_name($name) @@ -2642,6 +2668,8 @@ Returns a replacement for $name which do =cut +###################################################### +###################################################### sub clean_excel_name { my ($name) = @_; $name =~ s/[:\*\?\/\\]//g; @@ -2672,11 +2700,14 @@ sub check_if_partid_hidden { my ($id,$symb,$udom,$uname) = @_; my $hiddenparts=&Apache::lonnet::EXT('resource.0.hiddenparts', $symb,$udom,$uname); + my $truth=1; + #if the string starts with !, then the list is the list to show not hide + if ($hiddenparts=~s/^\s*!//) { $truth=undef; } my @hiddenlist=split(/,/,$hiddenparts); foreach my $checkid (@hiddenlist) { - if ($checkid =~ /^\s*\Q$id\E\s*$/) { return 1; } + if ($checkid =~ /^\s*\Q$id\E\s*$/) { return $truth; } } - return undef; + return !$truth; } @@ -2685,8 +2716,12 @@ sub check_if_partid_hidden { =pod +=back + =head1 cgi-bin script and graphing routines +=over 4 + =item get_cgi_id Inputs: none @@ -2700,9 +2735,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); } ############################################################ @@ -2730,7 +2766,7 @@ Inputs: =item $Max: scalar, the maximum Y value to use in the plot If $Max is < any data point, the graph will not be rendered. -=teim $colors: array ref holding the colors to be used for the data sets when +=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 @Values: An array of array references. Each array reference holds data @@ -3018,10 +3054,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. @@ -3038,6 +3078,8 @@ Inputs: =back +=back + =cut ############################################################ @@ -3050,9 +3092,135 @@ sub chartlink { '">'.$linktext.'</a>'; } +####################################################### +####################################################### + +=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 = 'env.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.'.env.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 @file_ext = split(/\./,$file); + my $curfext = $file_ext[-1]; + my $iconname="unknown.gif"; + my $embstyle = &Apache::loncommon::fileembstyle($curfext); + # The unless conditional that follows is a bit of overkill + $iconname = $curfext.".gif" unless + (!defined($embstyle) || $embstyle eq 'unk' || $embstyle eq 'hdn'); + return $Apache::lonnet::perlvar{'lonIconsURL'}."/$iconname"; +} + =pod =back