diff --git a/lib/WebGUI/Group.pm b/lib/WebGUI/Group.pm index e93f2f7d1..fe7fca17d 100755 --- a/lib/WebGUI/Group.pm +++ b/lib/WebGUI/Group.pm @@ -1079,7 +1079,7 @@ sub new { $self->{_groupId} = shift; my $override = shift; - my $cached = $self->{_session}->stow->get("groupObj"); + my $cached = $self->{_session}->stow->get("groupObj", { noclone => 1}); return $cached->{$self->{_groupId}} if ($cached->{$self->{_groupId}}); bless $self, $class; diff --git a/lib/WebGUI/Session/Stow.pm b/lib/WebGUI/Session/Stow.pm index b9717f697..0583baad3 100644 --- a/lib/WebGUI/Session/Stow.pm +++ b/lib/WebGUI/Session/Stow.pm @@ -95,33 +95,49 @@ sub DESTROY { =head2 get( varName ) -Retrieves the current value of a stow variable. Note that if you use references, you're -getting back a reference and modifying the contents of the reference will change the -contents of the stow variable. +Retrieves the current value of a stow variable. By default, will try +to create a safe copy. + +WARNING: Not all structures can be made completely safe. Objects will +not be cloned. =head3 varName The name of the variable. +=head3 options + +A hashref of options with the following keys: + + noclone - If true, will not create a safe copy. This can be much much + faster than creating a safe copy. Defaults to false. + =cut sub get { - my $self = shift; - my $var = shift; + my $self = shift; + my $var = shift; + my $opt = shift || {}; return undef if $self->session->config->get("disableCache"); - my $ref = $self->{_data}{$var}; - if (ref $ref eq 'ARRAY') { - my @safeArray = @{ $ref }; + my $value = $self->{_data}{$var}; + return unless $value; + my $ref = ref $value; + return $value if ( !$ref || $opt->{noclone} ); + + # Try to clone + # NOTE: Clone and Storable::dclone do not currently work here, but + # would be safer if they did + if ($ref eq 'ARRAY') { + my @safeArray = @{ $value }; return \@safeArray; } - elsif (ref $ref eq 'HASH') { - my %safeHash = %{ $ref }; + elsif ($ref eq 'HASH') { + my %safeHash = %{ $value }; return \%safeHash; } - else { - return $ref - } - return $self->{_data}{$var}; + + # Can't figure out how to clone + return $value; } diff --git a/lib/WebGUI/User.pm b/lib/WebGUI/User.pm index b518fb8a0..9aae6efbb 100644 --- a/lib/WebGUI/User.pm +++ b/lib/WebGUI/User.pm @@ -486,7 +486,7 @@ sub isInGroup { return 1 if ($gid eq '1' && $uid eq '1'); # visitors are in the visitors group return 1 if ($gid eq '2' && $uid ne '1'); # if you're not a visitor, then you're a registered user ### Get data for auxillary checks. - my $isInGroup = $self->session->stow->get("isInGroup"); + my $isInGroup = $self->session->stow->get("isInGroup", { noclone => 1 }); ### Look to see if we've already looked up this group. return $isInGroup->{$uid}{$gid} if exists $isInGroup->{$uid}{$gid}; ### Lookup the actual groupings. diff --git a/t/Session/Stow.t b/t/Session/Stow.t index 2e13d5d82..25aa216f0 100644 --- a/t/Session/Stow.t +++ b/t/Session/Stow.t @@ -15,7 +15,7 @@ use lib "$FindBin::Bin/../lib"; use WebGUI::Test; use WebGUI::Session; -use Test::More tests => 33; # increment this value for each test you create +use Test::More tests => 35; # increment this value for each test you create my $session = WebGUI::Test->session; @@ -88,6 +88,17 @@ is($stow->delete('noSuchKey'), undef, 'deleting non-existant variable returns un $stow->set('countedKey', 5); is($stow->delete('countedKey'), 5, 'delete method returns what was deleted'); +#---------------------------------------------------------------------------- +# Test get( ... { noclone => 1 } ) +my $arr = [ 'get busy living', 'get busy dying' ]; +$session->stow->set( 'possibilities', $arr ); +isnt( $session->stow->get( 'possibilities' ), $arr, + "Without noclone does not return same reference", +); +is( $session->stow->get( 'possibilities', { noclone => 1 } ), $arr, + "With noclone returns same reference" +); + END { $session->config->set('disableCache',$disableCache); }