diff --git a/lib/WebGUI/Asset/File.pm b/lib/WebGUI/Asset/File.pm index 74b023a30..ef1b2cdc1 100644 --- a/lib/WebGUI/Asset/File.pm +++ b/lib/WebGUI/Asset/File.pm @@ -55,11 +55,15 @@ Override the default method in order to deal with attachments. sub addRevision { my $self = shift; - my $newSelf = $self->SUPER::addRevision(@_); - if ($self->get("storageId")) { + my $properties = shift; + + if ($self->get("storageId") ne "") { my $newStorage = WebGUI::Storage->get($self->session,$self->get("storageId"))->copy; - $newSelf->update({storageId=>$newStorage->getId}); + $properties->{storageId} = $newStorage->getId; } + + my $newSelf = $self->SUPER::addRevision($properties); + return $newSelf; } @@ -243,12 +247,26 @@ sub prepareView { #------------------------------------------------------------------- sub processPropertiesFromFormPost { - my $self = shift; + my $self = shift; + my $session = $self->session; $self->SUPER::processPropertiesFromFormPost; + + #Get the storage location out of memory. If you call getStorageLocation you risk creating another one. + my $storageLocation = $self->{_storageLocation}; + my $storageId = undef; + $storageId = $storageLocation->getId if(defined $storageLocation); + + #Now remove the storage location to prevent wierd caching stuff. delete $self->{_storageLocation}; - my $fileStorageId = WebGUI::Form::File->new($self->session, {name => 'newFile'})->getValueFromPost; - my $storage = WebGUI::Storage->get($self->session, $fileStorageId); + #Clear the storage location if a file was uploaded. + if($session->form->get("newFile_file") ne "") { + $storageLocation->clear(); + } + + #Pass in the storage Id to prevent another one from being created. + my $fileStorageId = WebGUI::Form::File->new($session, {name => 'newFile', value=>$storageId })->getValueFromPost; + my $storage = WebGUI::Storage->get($session, $fileStorageId); if (defined $storage) { $storage->setPrivileges($self->get('ownerUserId'), $self->get('groupIdView'), $self->get('groupIdEdit')); @@ -258,9 +276,9 @@ sub processPropertiesFromFormPost { my %data; $data{filename} = $filename; $data{storageId} = $storage->getId; - $data{title} = $filename unless ($self->session->form->process("title")); - $data{menuTitle} = $filename unless ($self->session->form->process("menuTitle")); - $data{url} = $self->getParent->get('url').'/'.$filename unless ($self->session->form->process("url")); + $data{title} = $filename unless ($session->form->process("title")); + $data{menuTitle} = $filename unless ($session->form->process("menuTitle")); + $data{url} = $self->getParent->get('url').'/'.$filename unless ($session->form->process("url")); $self->update(\%data); $self->setSize($storage->getFileSize($filename)); } @@ -306,11 +324,13 @@ sub purgeRevision { sub setSize { my $self = shift; my $fileSize = shift || 0; - my $storage = $self->getStorageLocation; - foreach my $file (@{$storage->getFiles}) { - $fileSize += $storage->getFileSize($file); + my $storage = $self->{_storageLocation}; + if (defined $storage) { + foreach my $file (@{$storage->getFiles}) { + $fileSize += $storage->getFileSize($file); + } } - $self->SUPER::setSize($fileSize); + return $self->SUPER::setSize($fileSize); } #------------------------------------------------------------------- diff --git a/lib/WebGUI/Asset/File/Image.pm b/lib/WebGUI/Asset/File/Image.pm index 85e995b8f..0f7d782c1 100644 --- a/lib/WebGUI/Asset/File/Image.pm +++ b/lib/WebGUI/Asset/File/Image.pm @@ -224,10 +224,13 @@ sub processPropertiesFromFormPost { #------------------------------------------------------------------- sub setSize { - my $self = shift; + my $self = shift; my $input = shift; - my $storage = $self->getStorageLocation; - my $size = ($input > $storage->getFileSize($self->get("filename"))) ? $input : $storage->getFileSize($self->get("filename")); + my $size = 0; + my $storage = $self->{_storageLocation}; + if (defined $storage) { + $size = ($input > $storage->getFileSize($self->get("filename"))) ? $input : $storage->getFileSize($self->get("filename")); + } return $self->SUPER::setSize($size); } diff --git a/lib/WebGUI/Asset/FilePile.pm b/lib/WebGUI/Asset/FilePile.pm index 6b565fb5e..5c9ab386c 100644 --- a/lib/WebGUI/Asset/FilePile.pm +++ b/lib/WebGUI/Asset/FilePile.pm @@ -139,15 +139,17 @@ sub editSave { ##This is a hack. File uploads should go through the WebGUI::Form::File API my $tempFileStorageId = WebGUI::Form::File->new($self->session,{name => 'file'})->getValueFromPost; - my $tempStorage = WebGUI::Storage->get($self->session, $tempFileStorageId); + my $tempStorage = WebGUI::Storage::Image->get($self->session, $tempFileStorageId); foreach my $filename (@{$tempStorage->getFiles}) { - my $storage = WebGUI::Storage::Image->create($self->session); - $storage->addFileFromFilesystem($tempStorage->getPath($filename)); + #my $storage = WebGUI::Storage::Image->create($self->session); + #$storage->addFileFromFilesystem($tempStorage->getPath($filename)); + #$storage->setPrivileges($self->getParent->get("ownerUserId"),$self->getParent->get("groupIdView"),$self->getParent->get("groupIdEdit")); my %data; my $selfName = 'WebGUI::Asset::File'; - $selfName = "WebGUI::Asset::File::Image" if ($storage->isImage($filename)); + $selfName = "WebGUI::Asset::File::Image" if ($tempStorage->isImage($filename)); + foreach my $definition (@{$selfName->definition($self->session)}) { foreach my $property (keys %{$definition->{properties}}) { $data{$property} = $self->session->form->process( @@ -157,9 +159,9 @@ sub editSave { ); } } - $storage->setPrivileges($data{"ownerUserId"},$data{"groupIdView"},$data{"groupIdEdit"}); + $data{className} = $selfName; - $data{storageId} = $storage->getId; + #$data{storageId} = $storage->getId; $data{filename} = $data{title} = $data{menuTitle} = $filename; $data{templateId} = 'PBtmpl0000000000000024'; if ($selfName eq "WebGUI::Asset::File::Image") { @@ -168,22 +170,34 @@ sub editSave { # Resize image if it is bigger than the max allowed image size. my $maxSize = $self->session->setting->get("maxImageSize"); - my ($width, $height) = $storage->getSizeInPixels($filename); + my ($width, $height) = $tempStorage->getSizeInPixels($filename); if($width > $maxSize || $height > $maxSize) { if($width > $height) { - $storage->resize($filename, $maxSize); + $tempStorage->resize($filename, $maxSize); } else { - $storage->resize($filename, 0, $maxSize); + $tempStorage->resize($filename, 0, $maxSize); } } } $data{url} = $self->getParent->get('url').'/'.$filename; + + #Create the new asset my $newAsset = $self->getParent->addChild(\%data); - delete $newAsset->{_storageLocation}; - $newAsset->setSize($storage->getFileSize($filename)); + + #Get the current storage location + my $storage = $newAsset->getStorageLocation(); + $storage->addFileFromFilesystem($tempStorage->getPath($filename)); + $storage->setPrivileges($data{"ownerUserId"},$data{"groupIdView"},$data{"groupIdEdit"}); + + $newAsset->setSize($tempStorage->getFileSize($filename)); $newAsset->generateThumbnail if ($selfName eq "WebGUI::Asset::File::Image"); + $newAsset->update({ storageId=> $storage->getId }); + + #Now remove the reference to the storeage location to prevent problems with different revisions. + delete $newAsset->{_storageLocation}; + } $tempStorage->delete; return $self->getParent->www_manageAssets if ($self->session->form->process("proceed") eq "manageAssets"); diff --git a/lib/WebGUI/Session/Id.pm b/lib/WebGUI/Session/Id.pm index aecaf874f..d9bfdeeb2 100644 --- a/lib/WebGUI/Session/Id.pm +++ b/lib/WebGUI/Session/Id.pm @@ -18,7 +18,7 @@ package WebGUI::Session::Id; use strict; use Digest::MD5; use Time::HiRes qw( gettimeofday usleep ); - +use MIME::Base64; =head1 NAME @@ -104,6 +104,29 @@ sub session { return $self->{_session}; } + +#------------------------------------------------------------------- + +=head2 toHex ( guid ) + +Returns the hex value of a guid + +=head3 guid + +guid to convert to hex value. + +=cut + +sub toHex { + my $self = shift; + my $id = shift; + $id =~ tr{_-}{+/}; + my $bin_id = decode_base64("$id=="); + my $hex_id = sprintf('%*v02x', '', $bin_id); + return $hex_id +} + + #------------------------------------------------------------------- =head2 valid ( $idString ) diff --git a/lib/WebGUI/Storage.pm b/lib/WebGUI/Storage.pm index a8d2ab344..1c8fb99dd 100644 --- a/lib/WebGUI/Storage.pm +++ b/lib/WebGUI/Storage.pm @@ -110,7 +110,7 @@ NOTE: This is a private method and should never be called except internally to t sub _makePath { my $self = shift; my $node = $self->session->config->get("uploadsPath"); - foreach my $folder ($self->{_part1}, $self->{_part2}, $self->{_id}) { + foreach my $folder ($self->{_part1}, $self->{_part2}, $self->getFileId) { $node .= '/'.$folder; unless (-e $node) { # check to see if it already exists unless (mkdir($node)) { # check to see if there was an error during creation @@ -287,6 +287,22 @@ sub addFileFromScalar { return $filename; } +#------------------------------------------------------------------- + +=head2 clear ( ) + +Clears a storage locations of all files except the .wgaccess file + +=cut + +sub clear { + my $self = shift; + my $filelist = $self->getFiles(1); + foreach my $file (@{$filelist}) { + $self->deleteFile($file); + } +} + #------------------------------------------------------------------- @@ -337,10 +353,23 @@ A reference to the current session; =cut sub create { - my $class = shift; + my $class = shift; my $session = shift; - my $id = $session->id->generate(); - my $self = $class->get($session,$id); + my $id = $session->id->generate(); + + #Determine whether or not to use case insensitive files + my $config = $session->config; + my $db = $session->db; + my $caseInsensitive = $config->get("caseInsensitiveOS"); + + #$session->errorHandler->warn($caseInsensitive.": $id\n".Carp::longmess()."\n"); + #For case insensitive operating systems, convert guid to hex + if($caseInsensitive) { + my $hexId = $session->id->toHex($id); + $db->write("insert into storageTranslation (guidValue,hexValue) values (?,?)",[$id,$hexId]); + } + + my $self = $class->get($session,$id); $self->_makePath; return $self; } @@ -359,11 +388,25 @@ A reference to the current session. =cut sub createTemp { - my $class = shift; + my $class = shift; my $session = shift; - my $id = $session->id->generate(); + my $id = $session->id->generate(); + my $guid = $id; + + #Determine whether or not to use case insensitive files + my $config = $session->config; + my $db = $session->db; + my $caseInsensitive = $config->get("caseInsensitiveOS"); + + #For case insensitive operating systems, convert guid to hex + if($caseInsensitive) { + my $hexId = $session->id->toHex($id); + $db->write("insert into storageTranslation (guidValue,hexValue) values (?,?)",[$id,$hexId]); + $id = $hexId; + } + $id =~ m/^(.{2})/; - my $self = {_session=>$session, _id => $id, _part1 => 'temp', _part2 => $1}; + my $self = {_session=>$session, _id => $guid, _part1 => 'temp', _part2 => $1}; bless $self, ref($class)||$class; $self->_makePath; return $self; @@ -379,6 +422,8 @@ Deletes this storage location and its contents (if any) from the filesystem. sub delete { my $self = shift; + my $db = $self->session->db; + my $path = $self->getPath; if ($path) { rmtree($path) if ($path); @@ -395,6 +440,10 @@ sub delete { $self->session->errorHandler->warn("Unable to open $uDir for directory reading"); } } + #Delete the item from the storageTranslation table + if($self->session->config->get("caseInsensitiveOS")){ + $db->write("delete from storageTranslation where guidValue=?",[$self->getId]); + } } return; } @@ -435,12 +484,29 @@ The unique identifier for this file system storage location. =cut sub get { - my $class = shift; + my $class = shift; my $session = shift; - my $id = shift; + my $id = shift; return undef unless $id; + my $guid = $id; my $self; - $self = {_session=>$session, _id => $id, _errors => []}; + + my $db = $session->db; + + #Determine whether or not to use case insensitive files + my $config = $session->config; + my $caseInsensitive = $config->get("caseInsensitiveOS"); + + #For case insensitive operating systems, convert guid to hex + if($caseInsensitive) { + #Determine if the item is in the database + my ($hexId) = $db->quickArray("select hexValue from storageTranslation where guidValue=?",[$id]); + + #Set the value of the guid to the hex value if found. + $id = $hexId if($hexId); + } + + $self = {_session=>$session, _id => $guid, _errors => []}; bless $self, ref($class)||$class; if (my ($part1, $part2) = $id =~ m/^(.{2})(.{2})/) { $self->{_part1} = $part1; @@ -616,8 +682,35 @@ sub getFiles { return []; } +#------------------------------------------------------------------- +=head2 getFileId ( ) +Returns the file id for this storage location. + +=cut + +sub getFileId { + my $self = shift; + my $session = $self->session; + my $config = $session->config; + my $db = $session->db; + + my $id = $self->getId; + + my $caseInsensitive = $config->get("caseInsensitiveOS"); + + #For case insensitive operating systems, convert guid to hex + if($caseInsensitive) { + #Determine if the item is in the database + my ($hexId) = $db->quickArray("select hexValue from storageTranslation where guidValue=?",[$id]); + + #Set the value of the guid to the hex value if found. + return $hexId if($hexId); + } + + return $id; +} #------------------------------------------------------------------- @@ -662,14 +755,16 @@ If specified, we'll return a path to the file rather than the storage location. sub getPath { my $self = shift; my $file = shift; - unless ($self->session->config->get("uploadsPath") && $self->{_part1} && $self->{_part2} && $self->getId) { + my $id = $self->getFileId; + + unless ($self->session->config->get("uploadsPath") && $self->{_part1} && $self->{_part2} && $id) { $self->_addError("storage object malformed"); return undef; } my $path = $self->session->config->get("uploadsPath") .'/'.$self->{_part1} .'/'.$self->{_part2} - .'/'.$self->getId; + .'/'.$id; if (defined $file) { $path .= '/'.$file; } @@ -692,7 +787,7 @@ If specified, we'll return a URL to the file rather than the storage location. sub getUrl { my $self = shift; my $file = shift; - my $url = $self->session->config->get("uploadsURL").'/'.$self->{_part1}.'/'.$self->{_part2}.'/'.$self->getId; + my $url = $self->session->config->get("uploadsURL").'/'.$self->{_part1}.'/'.$self->{_part2}.'/'.$self->getFileId; if (defined $file) { $url .= '/'.$file; }