################################################################################ # WeBWorK mod_perl (c) 2000-2002 WeBWorK Project # $Id$ ################################################################################ package WeBWorK::Utils; =head1 NAME WeBWorK::Utils - useful utilities used by other WeBWorK modules. =cut use strict; use warnings; use base qw(Exporter); use Date::Format; use Date::Parse; our @EXPORT = (); our @EXPORT_OK = qw( runtime_use readFile formatDateTime parseDateTime writeLog writeTimingLogEntry dbDecode dbEncode decodeAnswers encodeAnswers ref2string ); sub runtime_use($) { return unless @_; eval "package Main; require $_[0]; import $_[0]"; die $@ if $@; } sub readFile($) { my $fileName = shift; local *INPUTFILE; open INPUTFILE, "<", $fileName or die "Failed to read $fileName: $!"; local $/ = undef; my $result = ; close INPUTFILE; return $result; } sub formatDateTime($) { my $dateTime = shift; # "standard" WeBWorK date/time format (for set definition files): # %m month number, starting with 01 # %d numeric day of the month, with leading zeros (eg 01..31) # %y year (2 digits) # %I hour, 12 hour clock, leading 0's) # %M minute, leading 0's # %P am or pm (Yes %p and %P are backwards :) return time2str("%m/%d/%y %I:%M%P", $dateTime); } sub parseDateTime($) { my $string = shift; return str2time $string; } sub writeLog($$@) { my ($ce, $facility, @message) = @_; unless ($ce->{webworkFiles}->{logs}->{$facility}) { warn "There is no log file for the $facility facility defined.\n"; return; } my $logFile = $ce->{webworkFiles}->{logs}->{$facility}; local *LOG; if (open LOG, ">>", $logFile) { print LOG "[", time2str("%a %b %d %H:%M:%S %Y", time), "] @message\n"; close LOG; } else { warn "failed to open $logFile for writing: $!"; } } sub writeTimingLogEntry($$$$) { my ($ce, $function, $details, $beginEnd) = @_; return unless defined $ce->{webworkFiles}->{logs}->{timing}; $beginEnd = ($beginEnd eq "begin") ? ">" : "<"; writeLog($ce, "timing", "$$ ".time." $beginEnd $function [$details]"); } # ----- sub dbDecode($) { my $string = shift; return unless defined $string and $string; my %hash = $string =~ /(.*?)(?{$refType}) { my $baseType = refBaseType($ref); $result .= '' . $refType; $result .= " ($baseType)" if $baseType and $refType ne $baseType; $result .= ":
"; $result .= ''; if ($baseType eq "HASH") { my %hash = %$ref; foreach (sort keys %hash) { $result .= ''; $result .= ""; $result .= ""; $result .= ""; } } elsif ($baseType eq "ARRAY") { my @array = @$ref; # special case for Problem, Set, and User objects, which are defined # using lists and contain a @FIELDS package variable: no strict 'refs'; my @FIELDS = eval { @{$refType."::FIELDS"} }; use strict 'refs'; undef @FIELDS unless scalar @FIELDS == scalar @array and not $@; foreach (0 .. $#array) { $result .= ''; $result .= ""; $result .= "" if @FIELDS; $result .= ""; $result .= ""; } } elsif ($baseType eq "SCALAR") { my $scalar = $$ref; $result .= ''; $result .= ""; $result .= ""; } else { # perhaps a coderef? in any case, i don't feel like dealing with it! $result .= ''; $result .= ""; $result .= ""; } $result .= "
$_" . ref2string($hash{$_}, $dontExpand) . "
$_".$FIELDS[$_]."" . ref2string($array[$_], $dontExpand) . "
$scalar
$ref
" } else { $result .= defined $ref ? $ref : 'undef'; } } sub refBaseType($) { my $ref = shift; local $SIG{__DIE__} = 'IGNORE'; return "HASH" if eval { $_ = %$ref; 1 }; return "ARRAY" if eval { $_ = @$ref; 1 }; return "SCALAR" if eval { $_ = $$ref; 1 }; return 0; } 1;