Parent Directory
|
Revision Log
I made an &include subroutine available to the global.conf and course.conf evaluation environments. It allows the inclusion of files within the webworkRoot. -Dennis
1 ################################################################################ 2 # WeBWorK mod_perl (c) 2000-2002 WeBWorK Project 3 # $Id$ 4 ################################################################################ 5 6 package WeBWorK::CourseEnvironment; 7 8 =head1 NAME 9 10 WeBWorK::CourseEnvironment - Read configuration information from global.conf 11 and course.conf files. 12 13 =cut 14 15 use strict; 16 use warnings; 17 use Safe; 18 use WeBWorK::Utils qw(readFile); 19 20 # new($invocant, $webworkRoot, $webworkURLRoot, $pgRoot, $courseName) 21 # $invocant implicitly set by caller 22 # $webworkRoot directory that contains the WeBWorK distribution 23 # $webworkURLRoot URL that points to the WeBWorK system 24 # $pgRoot directory that contains the PG distribution 25 # $courseName name of the course being used 26 sub new { 27 my $invocant = shift; 28 my $class = ref($invocant) || $invocant; 29 my $webworkRoot = shift; 30 my $webworkURLRoot = shift; 31 my $pgRoot = shift; 32 my $courseName = shift || ""; 33 my $safe = Safe->new; 34 35 # set up some defaults that the environment files will need 36 $safe->reval("\$webworkRoot = '$webworkRoot'"); 37 $safe->reval("\$webworkURLRoot = '$webworkURLRoot'"); 38 $safe->reval("\$pgRoot = '$pgRoot'"); 39 $safe->reval("\$courseName = '$courseName'"); 40 41 # This crazy code to create &include in the safe compartment 42 # would have been crazier, but Safe->varglob doesn't do what it's 43 # authors think it does. 44 45 # This needs to be a closure so that it has a $webworkRoot variable 46 # that can't be modified by the code in the safe compartment. 47 # You can only include relative to webworkRoot. 48 local *include = sub { 49 my ($file) = @_; 50 my $fullPath = "$webworkRoot/$file"; 51 if ($fullPath =~ m/(?:^|\/)..(?:\/|$)/) { 52 die "Included file $file has potentially insecure path: contains '/..' or '../'"; 53 } else { 54 do $fullPath; 55 } 56 }; 57 $safe->share('&include'); 58 59 # determine location of globalEnvironmentFile 60 my $globalEnvironmentFile = "$webworkRoot/conf/global.conf"; 61 62 # read and evaluate the global environment file 63 my $globalFileContents = readFile($globalEnvironmentFile); 64 $safe->reval($globalFileContents); 65 66 # if that evaluation failed, we can't really go on... 67 # we need a global environment! 68 $@ and die "Could not evaluate global environment file $globalEnvironmentFile: $@"; 69 70 # determine location of courseEnvironmentFile 71 # pull it out of $safe's symbol table ad hoc 72 # (we don't want to do the hash conversion yet) 73 no strict 'refs'; 74 my $courseEnvironmentFile = ${*{${$safe->root."::"}{courseFiles}}}{environment}; 75 use strict 'refs'; 76 77 # read and evaluate the course environment file 78 # if readFile failed, we don't bother trying to reval 79 my $courseFileContents = eval { readFile($courseEnvironmentFile) }; # catch exceptions 80 $@ or $safe->reval($courseFileContents); 81 82 # get the safe compartment's namespace as a hash 83 no strict 'refs'; 84 my %symbolHash = %{$safe->root."::"}; 85 use strict 'refs'; 86 87 # convert the symbol hash into a hash of regular variables. 88 my $self = {}; 89 foreach my $name (keys %symbolHash) { 90 # weed out internal symbols 91 next if $name =~ /^(INC|_|__ANON__|main::)$/; 92 # pull scalar, array, and hash values for this symbol 93 my $scalar = ${*{$symbolHash{$name}}}; 94 my @array = @{*{$symbolHash{$name}}}; 95 my %hash = %{*{$symbolHash{$name}}}; 96 # for multiple variables sharing a symbol, scalar takes precedence 97 # over array, which takes precedence over hash. 98 if (defined $scalar) { 99 $self->{$name} = $scalar; 100 } elsif (@array) { 101 $self->{$name} = \@array; 102 } elsif (%hash) { 103 $self->{$name} = \%hash; 104 } 105 } 106 107 bless $self, $class; 108 return $self; 109 } 110 111 1; 112 113 __END__ 114 115 =head1 SYNOPSIS 116 117 use WeBWorK::CourseEnvironment; 118 $courseEnv = WeBWorK::CourseEnvironment->new($webworkRoot, $courseName); 119 120 $timeout = $courseEnv->{sessionKeyTimeout}; 121 $mode = $courseEnv->{pg}->{options}->{displayMode}; 122 # etc... 123 124 =head1 DESCRIPTION 125 126 The WeBWorK::CourseEnvironment module reads the system-wide F<global.conf> and 127 course-specific F<course.conf> files used by WeBWorK to calculate and store 128 settings needed throughout the system. The F<.conf> files are perl source files 129 that can contain any code allowed under the default safe compartment opset. 130 After evaluation of both files, any package variables are copied out of the 131 safe compartment into a hash. This hash becomes the course environment. 132 133 =head1 CONSTRUCTION 134 135 =over 136 137 =item new (ROOT, COURSE) 138 139 The C<new> method finds the file F<conf/global.conf> relative to the given ROOT 140 directory. After reading this file, it uses the C<$courseFiles{environment}> 141 variable, if present, to locate the course environment file. If found, the file 142 is read and added to the environment. 143 144 =back 145 146 =head1 ACCESS 147 148 There are no formal accessor methods. However, since the course environemnt is 149 a hash of hashes and arrays, is exists as the self hash of an instance 150 variable: 151 152 $courseEnvironment->{someKey}->{someOtherKey}; 153 154 =head1 AUTHOR 155 156 Written by Sam Hathaway, sh002i (at) math.rochester.edu. 157 158 =cut
| aubreyja at gmail dot com | ViewVC Help |
| Powered by ViewVC 1.0.9 |