Parent Directory
|
Revision Log
fixed "odd number of elements in hash" problem when decoding form fields. -sam
1 ################################################################################ 2 # WeBWorK mod_perl (c) 1995-2002 WeBWorK Team, Univeristy of Rochester 3 # $Id$ 4 ################################################################################ 5 6 package WeBWorK::Utils; 7 8 use strict; 9 use warnings; 10 use base qw(Exporter); 11 use Date::Format; 12 use Date::Parse; 13 14 our @EXPORT = (); 15 our @EXPORT_OK = qw( 16 runtime_use 17 readFile 18 formatDateTime 19 parseDateTime 20 dbDecode 21 dbEncode 22 decodeAnswers 23 encodeAnswers 24 ref2string 25 hash2string 26 array2string 27 ); 28 29 sub runtime_use($) { 30 return unless @_; 31 eval "package Main; require $_[0]; import $_[0]"; 32 die $@ if $@; 33 } 34 35 sub readFile($) { 36 my $fileName = shift; 37 open INPUTFILE, "<", $fileName 38 or die "Failed to read $fileName: $!"; 39 local $/ = undef; 40 my $result = <INPUTFILE>; 41 close INPUTFILE; 42 return $result; 43 } 44 45 sub formatDateTime($) { 46 my $dateTime = shift; 47 # "standard" WeBWorK date/time format: 48 # %m month number, starting with 01 49 # %d numeric day of the month, with leading zeros (eg 01..31) 50 # %y year (2 digits) 51 # %I hour, 12 hour clock, leading 0's) 52 # %M minute, leading 0's 53 # %P am or pm (Yes %p and %P are backwards :) 54 return time2str "%m/%d/%y %I:%M%P", $dateTime; 55 } 56 57 sub parseDateTime($) { 58 my $string = shift; 59 return str2time $string; 60 } 61 62 # ----- 63 64 sub dbDecode($) { 65 my $string = shift; 66 return unless defined $string and $string; 67 my %hash = $string =~ /(.*?)(?<!\\)=(.*?)(?:(?<!\\)&|$)/g; 68 $hash{$_} =~ s/\\(&|=)/$1/g foreach keys %hash; # unescape & and = 69 return %hash; 70 } 71 72 sub dbEncode(@) { 73 my %hash = @_; 74 my $string; 75 foreach (keys %hash) { 76 $hash{$_} = "" unless defined $hash{$_}; # promote undef to "" 77 $hash{$_} =~ s/(=|&)/\\$1/g; # escape & and = 78 $string .= "$_=$hash{$_}&"; 79 } 80 chop $string; # remove final '&' from string for old code :p 81 return $string; 82 } 83 84 sub decodeAnswers($) { 85 my $string = shift; 86 return unless defined $string and $string; 87 my @array = split m/##/, $string; 88 $array[$_] =~ s/\\#\\/#/g foreach 0 .. $#array; 89 push @array, "" if @array%2; 90 return @array; # it's actually a hash ;) 91 } 92 93 sub encodeAnswers(\%\@) { 94 my %hash = %{ shift() }; 95 my @order = @{ shift() }; 96 my $string; 97 foreach my $name (@order) { 98 my $value = defined $hash{$name} ? $hash{$name} : ""; 99 $name =~ s/#/\\#\\/g; # this is a WEIRD way to escape things 100 $value =~ s/#/\\#\\/g; # and it's not my fault! 101 $string .= "$name##$value##"; # this is also not my fault 102 } 103 $string =~ s/##$//; # remove last pair of hashs 104 return $string; 105 } 106 107 # ----- 108 109 sub ref2string($;$); 110 sub ref2string($;$) { 111 my $ref = shift; 112 my $dontExpand = shift || {}; 113 my $refType = ref $ref; 114 my $result; 115 if ($refType and not $dontExpand->{$refType}) { 116 my $baseType = refBaseType($ref); 117 $result .= '<font size="1" color="grey">' . $refType; 118 $result .= " ($baseType)" if $baseType and $refType ne $baseType; 119 $result .= ":</font><br>"; 120 $result .= '<table border="1" cellpadding="2">'; 121 if ($baseType eq "HASH") { 122 my %hash = %$ref; 123 foreach (sort keys %hash) { 124 $result .= '<tr valign="top">'; 125 $result .= "<td>$_</td>"; 126 $result .= "<td>" . ref2string($hash{$_}, $dontExpand) . "</td>"; 127 $result .= "</tr>"; 128 } 129 } elsif ($baseType eq "ARRAY") { 130 my @array = @$ref; 131 # special case for Problem, Set, and User objects, which are defined 132 # using lists and contain a @FIELDS package variable: 133 no strict 'refs'; 134 my @FIELDS = eval { @{$refType."::FIELDS"} }; 135 use strict 'refs'; 136 undef @FIELDS unless scalar @FIELDS == scalar @array and not $@; 137 foreach (0 .. $#array) { 138 $result .= '<tr valign="top">'; 139 $result .= "<td>$_</td>"; 140 $result .= "<td>".$FIELDS[$_]."</td>" if @FIELDS; 141 $result .= "<td>" . ref2string($array[$_], $dontExpand) . "</td>"; 142 $result .= "</tr>"; 143 } 144 } elsif ($baseType eq "SCALAR") { 145 my $scalar = $$ref; 146 $result .= '<tr valign="top">'; 147 $result .= "<td>$scalar</td>"; 148 $result .= "</tr>"; 149 } else { 150 # perhaps a coderef? in any case, i don't feel like dealing with it! 151 $result .= '<tr valign="top">'; 152 $result .= "<td>$ref</td>"; 153 $result .= "</tr>"; 154 } 155 $result .= "</table>" 156 } else { 157 $result .= defined $ref ? $ref : '<font color="red">undef</font>'; 158 } 159 } 160 161 sub refBaseType($) { 162 my $ref = shift; 163 local $SIG{__DIE__} = 'IGNORE'; 164 return "HASH" if eval { $_ = %$ref; 1 }; 165 return "ARRAY" if eval { $_ = @$ref; 1 }; 166 return "SCALAR" if eval { $_ = $$ref; 1 }; 167 return 0; 168 } 169 170 # ----- 171 172 #sub hash2string($;$$) { 173 # my $hr = shift; 174 # my $table = shift || 0; 175 # my $indent = shift || 0; 176 # my $result = $table ? '<table border="1">' : ""; 177 # foreach my $key (keys %$hr) { 178 # my $value = $hr->{$key}; 179 # $result .= $table 180 # ? "<tr><td>$key</td>" 181 # : "\t"x$indent . "{$key} ="; 182 # if (ref $value eq 'HASH') { 183 # $result .= $table ? "<td>" : "\n"; 184 # $result .= hash2string($value, $table, $indent+1); 185 # $result .= $table ? "</td>" : ""; 186 # } elsif (ref $value eq 'ARRAY') { 187 # $result .= $table ? "<td>" : "\n"; 188 # $result .= array2string($value, $table, $indent+1); 189 # $result .= $table ? "</td>" : ""; 190 # } elsif (defined $value) { 191 # $result .= $table 192 # ? "<td>$value</td>" 193 # : " $value\n"; 194 # } else { 195 # $result .= $table ? "" : "\n"; 196 # } 197 # $result .= $table ? "</tr>" : ""; 198 # } 199 # $result .= "</table>"; 200 # return $result; 201 #} 202 # 203 #sub array2string($;$$) { 204 # my $ar = shift; 205 # my $table = shift || 0; 206 # my $indent = shift || 0; 207 # my $result = $table ? '<table border="1">' : ""; 208 # foreach my $index (0 .. @$ar-1) { 209 # my $value = $ar->[$index]; 210 # $result .= $table 211 # ? "<tr><td>$index</td>" 212 # : "\t"x$indent . "[$index] ="; 213 # if (ref $value eq 'HASH') { 214 # $result .= $table ? "<td>" : "\n"; 215 # $result .= hash2string($value, $table, $indent+1); 216 # $result .= $table ? "</td>" : ""; 217 # } elsif (ref $value eq 'ARRAY') { 218 # $result .= $table ? "<td>" : "\n"; 219 # $result .= array2string($value, $table, $indent+1); 220 # $result .= $table ? "</td>" : ""; 221 # } elsif (defined $value) { 222 # $result .= $table 223 # ? "<td>$value</td>" 224 # : " $value\n"; 225 # } else { 226 # $result .= $table ? "" : "\n"; 227 # } 228 # $result .= $table ? "</tr>" : ""; 229 # } 230 # $result .= "</table>"; 231 # return $result; 232 #} 233 # 234 #sub isHashRef($) { 235 # my $ref = shift; 236 # local $SIG{__DIE__} = 'IGNORE'; 237 # $_ = eval{ %$ref }; 238 # return not defined $@; 239 #} 240 # 241 #sub isArrayRef($) { 242 # my $ref = shift; 243 # local $SIG{__DIE__} = 'IGNORE'; 244 # $_ = eval{ @$ref }; 245 # return not defined $@; 246 #} 247 248 1;
| aubreyja at gmail dot com | ViewVC Help |
| Powered by ViewVC 1.0.9 |