From e5c56dcf70bc42225f63906f6fa8be2a5eaa21b3 Mon Sep 17 00:00:00 2001 From: Colin Kuskie Date: Tue, 3 Mar 2009 00:36:38 +0000 Subject: [PATCH] Add JSON handling, and move code form addRevision to update. --- lib/WebGUI/Asset/Story.pm | 101 +++++++++++++++++++++++++++++++++++--- t/Asset/Story.t | 50 ++++++++++++++++++- 2 files changed, 142 insertions(+), 9 deletions(-) diff --git a/lib/WebGUI/Asset/Story.pm b/lib/WebGUI/Asset/Story.pm index 0ba85ef33..a7103e61b 100644 --- a/lib/WebGUI/Asset/Story.pm +++ b/lib/WebGUI/Asset/Story.pm @@ -20,6 +20,8 @@ use base 'WebGUI::Asset'; use Tie::IxHash; use WebGUI::Utility; use WebGUI::International; +use JSON qw/from_json to_json/; +use Storable qw/dclone/; =head1 NAME @@ -56,8 +58,7 @@ sub addChild { =head2 addRevision -Make sure that Stories are always hidden from navigation. Copy storage locations so that -purging individual revisions works correctly. +Copy storage locations so that purging individual revisions works correctly. =cut @@ -141,7 +142,7 @@ sub definition { }, photo => { fieldType => 'text', - defaultValue => '', + defaultValue => '{}', }, storageId => { fieldType => 'hidden', @@ -179,17 +180,39 @@ sub exportAssetData { #------------------------------------------------------------------- -=head2 getStorageLocation +=head2 getPhotoData ( ) + +Returns the photo hash formatted as perl data. See also L. + +=cut + +sub getPhotoData { + my $self = shift; + if (!exists $self->{_photoData}) { + $self->{_photoData} = from_json($self->get('photo')); + } + return dclone($self->{_photoData}); +} + +#------------------------------------------------------------------- + +=head2 getStorageLocation ( [$noCreate] ) Returns the storage location for this Story. If it does not exist, then it creates it via setStorageLocation. Subsequent lookups return an internally cached Storage object to save time. +=head3 $noCreate + +If $noCreate is true, then no storage location will be created, even +if it does not exist. + =cut sub getStorageLocation { - my $self = shift; - unless (exists $self->{_storageLocation}) { + my $self = shift; + my $noCreate = shift; + if (!exists $self->{_storageLocation} && !$noCreate) { $self->setStorageLocation; } return $self->{_storageLocation}; @@ -262,6 +285,56 @@ sub purgeRevision { #------------------------------------------------------------------- +=head2 setPhotoData ( $perlStructure ) + +Returns the storage location for this Story. If it does not exist, +then it creates it via setStorageLocation. Subsequent lookups return +an internally cached Storage object to save time. + +=head3 $perlStructure + +This should be a hash of hashes. The keys will be names of photos in the +storage location for this Story. The values in the subhash will be +metadata about the Photo. + +=item * + +caption + +=item * + +byLine + +=item * + +alt + +=item * + +title + +=item * + +url + +=back + +subhash keys can be empty, or missing altogether. Shoot, you can really put anything you +want in there so there's no valid content checking. + +=cut + +sub setPhotoData { + my $self = shift; + my $photoData = shift || {}; + my $photo = to_json($photoData); + $self->update({photo => $photo}); + delete $self->{_photoData}; + return; +} + +#------------------------------------------------------------------- + =head2 setSize ( fileSize ) Set the size of this asset by including all the files in its storage @@ -273,7 +346,7 @@ the asset size. sub setSize { my $self = shift; my $fileSize = shift || 0; - my $storage = $self->getStorageLocation; + my $storage = $self->getStorageLocation('noCreate'); if (defined $storage) { foreach my $file (@{$storage->getFiles}) { $fileSize += $storage->getFileSize($file); @@ -309,6 +382,20 @@ sub setStorageLocation { #------------------------------------------------------------------- +=head2 update + +Extend the superclass to make sure that the asset always stays hidden from navigation. + +=cut + +sub update { + my $self = shift; + my $properties = shift; + return $self->SUPER::update({%$properties, isHidden => 1}); +} + +#------------------------------------------------------------------- + =head2 validParent Make sure that the current session asset is a StoryArchive for pasting and adding checks. diff --git a/t/Asset/Story.t b/t/Asset/Story.t index 7a6f956f1..fdf152f1c 100644 --- a/t/Asset/Story.t +++ b/t/Asset/Story.t @@ -20,7 +20,7 @@ use Test::More; # increment this value for each test you create use Test::Deep; my $tests = 1; -plan tests => 4 +plan tests => 12 + $tests ; @@ -58,7 +58,7 @@ ok( WebGUI::Asset::Story->validParent($session), 'validParent: StoryArchive is ############################################################ # -# make a new one +# Make a new one. Test defaults # ############################################################ @@ -68,6 +68,52 @@ $story = $defaultNode->addChild({ }); isa_ok($story, 'WebGUI::Asset::Story', 'Created a Story asset'); +is($story->get('storageId'), '', 'by default, there is no storageId'); +is($story->get('photo'), '{}', 'by default, photos is an empty JSON hash'); +is($story->get('isHidden'), 1, 'by default, photos are hidden'); +$story->update({isHidden => 0}); +is($story->get('isHidden'), 1, 'photos cannot be set to not be hidden'); + +############################################################ +# +# Photo JSON +# +############################################################ + +my $photoData = $story->getPhotoData(); +cmp_deeply( + $photoData, {}, + 'getPhotoData: returns an empty hash with no JSON data' +); + +$story->setPhotoData({ + filename1 => { + byLine => 'Andrew Dufresne', + caption => 'Shawshank Prison', + }, +}); + +is($story->get('photo'), q|{"filename1":{"caption":"Shawshank Prison","byLine":"Andrew Dufresne"}}|, 'setPhotoData: set JSON in the photo property'); + +$photoData = $story->getPhotoData(); +$photoData->{filename1}->{caption}="My cell"; + +cmp_deeply( + $story->getPhotoData, + { + filename1 => { + byLine => 'Andrew Dufresne', + caption => 'Shawshank Prison', + }, + }, + 'getPhotoData does not return an unsafe reference' +); + +$story->setPhotoData(); +cmp_deeply( + $story->getPhotoData, {}, + 'setPhotoData: wipes the stored data if nothing is passed' +); }