[system] / trunk / webwork2 / lib / WeBWorK / CourseEnvironment.pm Repository:
ViewVC logotype

View of /trunk/webwork2/lib/WeBWorK/CourseEnvironment.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1085 - (download) (as text) (annotate)
Mon Jun 9 18:28:46 2003 UTC (9 years, 11 months ago) by malsyned
File size: 5011 byte(s)
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