diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index e8b08960f..000905496 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -14,7 +14,9 @@ - Added a reverse option for the getAssets method in VersionTag. - Fixed a bug that would occur when deploying a package that contained a collaboration system with posts. - + - structure: normalize signature of Asset::duplicate method + - fix: Copying Collaboration System assets fails + - fix: Collaboration System packages do not deploy 7.0.7 - rfe: Image Management (funded by Formation Design Systems) diff --git a/lib/WebGUI/Asset/Event.pm b/lib/WebGUI/Asset/Event.pm index 1f073868d..cb30600fb 100644 --- a/lib/WebGUI/Asset/Event.pm +++ b/lib/WebGUI/Asset/Event.pm @@ -182,7 +182,7 @@ sub processPropertiesFromFormPost { $start = $self->session->datetime->addToDate($self->get("eventStartDate"),($i*$interval),0,0); $end = $self->session->datetime->addToDate($self->get("eventEndDate"),($i*$interval),0,0); } - my $newEvent = $self->getParent->duplicate($self); + my $newEvent = $self->duplicate; $newEvent->update({ eventStartDate=>$start, eventEndDate=>$end diff --git a/lib/WebGUI/Asset/File.pm b/lib/WebGUI/Asset/File.pm index 2e9309db0..3a90ca8f5 100644 --- a/lib/WebGUI/Asset/File.pm +++ b/lib/WebGUI/Asset/File.pm @@ -117,7 +117,7 @@ sub definition { sub duplicate { my $self = shift; - my $newAsset = $self->SUPER::duplicate(shift); + my $newAsset = $self->SUPER::duplicate(@_); my $newStorage = $self->getStorageLocation->copy; $newAsset->update({storageId=>$newStorage->getId}); return $newAsset; diff --git a/lib/WebGUI/Asset/File/ZipArchive.pm b/lib/WebGUI/Asset/File/ZipArchive.pm index 6631ee63d..8e3accdc9 100644 --- a/lib/WebGUI/Asset/File/ZipArchive.pm +++ b/lib/WebGUI/Asset/File/ZipArchive.pm @@ -134,22 +134,6 @@ sub definition { } -#------------------------------------------------------------------- - -=head2 duplicate ( ) - - This method exists for demonstration purposes only. The superclass - handles duplicating ZipArchive Assets. This method will be called - whenever a copy action is executed - -=cut - -sub duplicate { - my $self = shift; - my $newAsset = $self->SUPER::duplicate(shift); - return $newAsset; -} - #------------------------------------------------------------------- =head2 prepareView ( ) diff --git a/lib/WebGUI/Asset/Post.pm b/lib/WebGUI/Asset/Post.pm index 257f5c13d..00f862836 100644 --- a/lib/WebGUI/Asset/Post.pm +++ b/lib/WebGUI/Asset/Post.pm @@ -81,7 +81,9 @@ sub addRevision { isHidden => 1, dateUpdated=>$now, }); + $newSelf->getThread->unmarkRead; + return $newSelf; } @@ -498,7 +500,7 @@ sub getTemplateVars { #------------------------------------------------------------------- sub getThread { my $self = shift; - unless (exists $self->{_thread}) { + unless (defined $self->{_thread}) { $self->{_thread} = WebGUI::Asset::Post::Thread->new($self->session, $self->get("threadId")); } return $self->{_thread}; @@ -858,6 +860,14 @@ sub rate { } } +#------------------------------------------------------------------- +sub rethreadUnder { + my $self = shift; + my $thread = shift; + $self->update({threadId => $thread->getId}); + delete $self->{_thread}; +} + #------------------------------------------------------------------- # allows us to let the cs post use it's own workflow approval process sub requestCommit { diff --git a/lib/WebGUI/Asset/Post/Thread.pm b/lib/WebGUI/Asset/Post/Thread.pm index 57057af92..13b83c90b 100644 --- a/lib/WebGUI/Asset/Post/Thread.pm +++ b/lib/WebGUI/Asset/Post/Thread.pm @@ -26,9 +26,7 @@ our @ISA = qw(WebGUI::Asset::Post); sub addRevision { my $self = shift; my $newSelf = $self->SUPER::addRevision(@_); - if ($newSelf->get("subscriptionGroupId") eq "") { - $newSelf->createSubscriptionGroup; - } + $newSelf->createSubscriptionGroup; return $newSelf; } @@ -62,6 +60,22 @@ sub commit { } } +#------------------------------------------------------------------- +# Override duplicateBranch here so that new posts get their threadId set correctly. +# Buggo: should this be part of the addRevision override instead? + +sub duplicateBranch { + my $self = shift; + my $newAsset = $self->SUPER::duplicateBranch(@_); + + foreach my $post (@{$newAsset->getPosts}) { + $post->rethreadUnder($newAsset); + } + $newAsset->normalizeLastPost; + + return $newAsset; +} + #------------------------------------------------------------------- sub createSubscriptionGroup { my $self = shift; @@ -592,6 +606,13 @@ sub setLastPost { $self->getParent->setLastPost($id,$date); } +sub normalizeLastPost { + my $self = shift; + # Hmm. Is this right? + my ($lastPostId, $lastPostDate) = $self->session->db->quickArray("SELECT a.assetId, a.creationDate FROM asset as a INNER JOIN Post as t ON a.assetId = t.assetId WHERE t.threadId = ? ORDER BY a.creationDate DESC LIMIT 1", [$self->getId]); + $self->setLastPost($lastPostId, $lastPostDate); +} + #------------------------------------------------------------------- diff --git a/lib/WebGUI/Asset/Wobject/Article.pm b/lib/WebGUI/Asset/Wobject/Article.pm index 31d289609..677cc84c7 100644 --- a/lib/WebGUI/Asset/Wobject/Article.pm +++ b/lib/WebGUI/Asset/Wobject/Article.pm @@ -145,7 +145,7 @@ sub definition { sub duplicate { my $self = shift; - my $newAsset = $self->SUPER::duplicate(shift); + my $newAsset = $self->SUPER::duplicate(@_); my $newStorage = $self->getStorageLocation->copy; $newAsset->update({storageId=>$newStorage->getId}); return $newAsset; diff --git a/lib/WebGUI/Asset/Wobject/Collaboration.pm b/lib/WebGUI/Asset/Wobject/Collaboration.pm index 1699e0773..b0217784e 100644 --- a/lib/WebGUI/Asset/Wobject/Collaboration.pm +++ b/lib/WebGUI/Asset/Wobject/Collaboration.pm @@ -495,7 +495,7 @@ sub definition { #------------------------------------------------------------------- sub duplicate { my $self = shift; - my $newAsset = $self->SUPER::duplicate; + my $newAsset = $self->SUPER::duplicate(@_); $newAsset->createSubscriptionGroup; return $newAsset; } diff --git a/lib/WebGUI/Asset/Wobject/DataForm.pm b/lib/WebGUI/Asset/Wobject/DataForm.pm index 279a4d191..8952f497b 100644 --- a/lib/WebGUI/Asset/Wobject/DataForm.pm +++ b/lib/WebGUI/Asset/Wobject/DataForm.pm @@ -182,30 +182,30 @@ sub definition { #------------------------------------------------------------------- sub duplicate { my $self = shift; - my $newAsset = $self->SUPER::duplicate(shift); - my (%dataField, %dataTab, $sthField, $sthTab, $newTabId); - tie %dataTab, 'Tie::CPHash'; - tie %dataField, 'Tie::CPHash'; - $sthTab = $self->session->db->read("select * from DataForm_tab where assetId=".$self->session->db->quote($self->getId)); - while (%dataTab = $sthTab->hash) { - $sthField = $self->session->db->read("select * from DataForm_field where assetId=".$self->session->db->quote($self->getId)." AND DataForm_tabId=".$self->session->db->quote($dataTab{DataForm_tabId})); - $dataTab{DataForm_tabId} = "new"; - $newTabId = $newAsset->setCollateral("DataForm_tab","DataForm_tabId",\%dataTab); - while (%dataField = $sthField->hash) { - $dataField{DataForm_fieldId} = "new"; - $dataField{DataForm_tabId} = $newTabId; - $newAsset->setCollateral("DataForm_field","DataForm_fieldId",\%dataField); - } - $sthField->finish; - } - $sthField = $self->session->db->read("select * from DataForm_field where assetId=".$self->session->db->quote($self->getId)." AND DataForm_tabId='0'"); - while (%dataField = $sthField->hash) { - $dataField{DataForm_fieldId} = "new"; - $newAsset->setCollateral("DataForm_field","DataForm_fieldId",\%dataField); - } - $sthField->finish; - $sthTab->finish; - return $newAsset; + my $newAsset = $self->SUPER::duplicate(@_); + my (%dataField, %dataTab, $sthField, $sthTab, $newTabId); + tie %dataTab, 'Tie::CPHash'; + tie %dataField, 'Tie::CPHash'; + + $sthTab = $self->session->db->read("select * from DataForm_tab where assetId=?", [$self->getId]); + while (%dataTab = $sthTab->hash) { + $sthField = $self->session->db->read("select * from DataForm_field where assetId=? AND DataForm_tabId=?", [$self->getId, $dataTab{DataForm_tabId}]); + $dataTab{DataForm_tabId} = "new"; + $newTabId = $newAsset->setCollateral("DataForm_tab","DataForm_tabId",\%dataTab); + while (%dataField = $sthField->hash) { + $dataField{DataForm_fieldId} = "new"; + $dataField{DataForm_tabId} = $newTabId; + $newAsset->setCollateral("DataForm_field","DataForm_fieldId",\%dataField); + } + } + + $sthField = $self->session->db->read("select * from DataForm_field where assetId=? AND DataForm_tabId='0'", [$self->getId]); + while (%dataField = $sthField->hash) { + $dataField{DataForm_fieldId} = "new"; + $newAsset->setCollateral("DataForm_field","DataForm_fieldId",\%dataField); + } + + return $newAsset; } #------------------------------------------------------------------- diff --git a/lib/WebGUI/Asset/Wobject/Matrix.pm b/lib/WebGUI/Asset/Wobject/Matrix.pm index d36ad51db..2e8c37b3c 100644 --- a/lib/WebGUI/Asset/Wobject/Matrix.pm +++ b/lib/WebGUI/Asset/Wobject/Matrix.pm @@ -96,7 +96,8 @@ sub definition { #------------------------------------------------------------------- sub duplicate { - return ""; + # Buggo: how do we duplicate these? + return undef; } diff --git a/lib/WebGUI/Asset/Wobject/Poll.pm b/lib/WebGUI/Asset/Wobject/Poll.pm index f8e566d38..b8f47a3fd 100644 --- a/lib/WebGUI/Asset/Wobject/Poll.pm +++ b/lib/WebGUI/Asset/Wobject/Poll.pm @@ -168,8 +168,8 @@ sub definition { #------------------------------------------------------------------- sub duplicate { my $self = shift; - my $newAsset = $self->SUPER::duplicate(shift); - my $sth = $self->session->db->read("select * from Poll_answer where assetId=".$self->session->db->quote($self->getId)); + my $newAsset = $self->SUPER::duplicate(@_); + my $sth = $self->session->db->read("select * from Poll_answer where assetId=?", [$self->getId]); while (my $data = $sth->hashRef) { $newAsset->setVote($data->{answer}, $data->{userId}, $data->{ipAddress}); } diff --git a/lib/WebGUI/Asset/Wobject/Product.pm b/lib/WebGUI/Asset/Wobject/Product.pm index 6da308770..a6af25975 100644 --- a/lib/WebGUI/Asset/Wobject/Product.pm +++ b/lib/WebGUI/Asset/Wobject/Product.pm @@ -156,55 +156,35 @@ sub definition { #------------------------------------------------------------------- sub duplicate { - my $self = shift; - my $newAsset = $self->SUPER::duplicate(shift); - - my (%data, $file, $row, $sth, $newstore); - tie %data, 'Tie::CPHash'; - - $self->_duplicateFile($newAsset,"image1"); - $self->_duplicateFile($newAsset,"image2"); - $self->_duplicateFile($newAsset,"image3"); - $self->_duplicateFile($newAsset,"manual"); - $self->_duplicateFile($newAsset,"brochure"); - $self->_duplicateFile($newAsset,"warranty"); - - $sth = $self->session->db->read("select * from Product_feature where assetId=".$self->session->db->quote($self->getId)); - while ($row = $sth->hashRef) { - $row->{"Product_featureId"} = "new"; - $row->{"assetId"} = $newAsset->getId; - $newAsset->setCollateral("Product_feature","Product_featureId",$row); - } - $sth->finish; - - $sth = $self->session->db->read("select * from Product_benefit where assetId=".$self->session->db->quote($self->getId)); - while ($row = $sth->hashRef) { - $row->{"Product_benefitId"} = "new"; - $row->{"assetId"} = $newAsset->getId; - $newAsset->setCollateral("Product_benefit","Product_benefitId",$row); - } - $sth->finish; - - $sth = $self->session->db->read("select * from Product_specification where assetId=".$self->session->db->quote($self->getId)); - while ($row = $sth->hashRef) { - $row->{"Product_specificationId"} = "new"; - $row->{"assetId"} = $newAsset->getId; - $newAsset->setCollateral("Product_specification","Product_specificationId",$row); - } - $sth->finish; - - $sth = $self->session->db->read("select * from Product_accessory where assetId=".$self->session->db->quote($self->getId)); - while (%data = $sth->hash) { - $self->session->db->write("insert into Product_accessory (assetId,accessoryAssetId,sequenceNumber) values (".$self->session->db->quote($newAsset->getId).", ".$self->session->db->quote($data{accessoryAssetId}).", $data{sequenceNumber})"); - } - $sth->finish; + my $self = shift; + my $newAsset = $self->SUPER::duplicate(@_); - $sth = $self->session->db->read("select * from Product_related where assetId=".$self->session->db->quote($self->getId)); - while (%data = $sth->hash) { - $self->session->db->write("insert into Product_related (assetId,relatedAssetId,sequenceNumber) values (".$self->session->db->quote($newAsset->getId).", ".$self->session->db->quote($data{relatedAssetId}).", $data{sequenceNumber})"); - } - $sth->finish; - return $newAsset; + foreach my $file ('image1', 'image2', 'image3', 'manual', 'brochure', 'warranty') { + $self->_duplicateFile($newAsset, $file); + } + + foreach my $basename ('feature', 'benefit', 'specification') { + my $table = "Product_${basename}"; + my $sth = $self->session->db->read("select * from $table where assetId=?", [$self->getId]); + while (my $row = $sth->hashRef) { + $row->{"${table}Id"} = "new"; + $row->{"assetId"} = $newAsset->getId; + $newAsset->setCollateral($table, "${table}Id", $row); + } + } + + foreach my $basename ('accessory', 'related') { + my $table = "Product_${basename}"; + my $tableAssetId = "${basename}AssetId"; + my $sth = $self->session->db->read("select * from $table where assetId=?", [$self->getId]); + my %data; + tie %data, 'Tie::CPHash'; + while (%data = $sth->hash) { + $self->session->db->write("insert into $table (assetId, $tableAssetId, sequenceNumber) values (?, ?, ?)", [$newAsset->getId, $data{$tableAssetId}, $data{sequenceNumber}]); + } + } + + return $newAsset; } diff --git a/lib/WebGUI/Asset/Wobject/ProjectManager.pm b/lib/WebGUI/Asset/Wobject/ProjectManager.pm index a110514f2..bb77b88f2 100644 --- a/lib/WebGUI/Asset/Wobject/ProjectManager.pm +++ b/lib/WebGUI/Asset/Wobject/ProjectManager.pm @@ -152,13 +152,6 @@ sub definition { } -#------------------------------------------------------------------- -sub duplicate { - my $self = shift; - my $newAsset = $self->SUPER::duplicate(shift); - return $newAsset; -} - #------------------------------------------------------------------- #API method called by Time Tracker to return the instance of the PM wobject which this project blongs sub getProjectInstance { diff --git a/lib/WebGUI/Asset/Wobject/Survey.pm b/lib/WebGUI/Asset/Wobject/Survey.pm index 377ab8273..a252a4666 100644 --- a/lib/WebGUI/Asset/Wobject/Survey.pm +++ b/lib/WebGUI/Asset/Wobject/Survey.pm @@ -139,7 +139,7 @@ sub duplicate { $self = shift; - $newAsset = $self->SUPER::duplicate(shift); + $newAsset = $self->SUPER::duplicate(@_); $newSurveyId = $self->session->id->generate(); $newAsset->update({ Survey_id=>$newSurveyId @@ -172,13 +172,9 @@ sub duplicate { $rdata->{Survey_questionId} = $qdata->{Survey_questionId}; $newAsset->setCollateral("Survey_questionResponse","Survey_responseId",$rdata,0,0); } - $responses->finish; } - $answers->finish; } - $questions->finish; } - $section->finish; return $newAsset; } diff --git a/lib/WebGUI/Asset/Wobject/TimeTracking.pm b/lib/WebGUI/Asset/Wobject/TimeTracking.pm index 3350046ec..56866fca5 100644 --- a/lib/WebGUI/Asset/Wobject/TimeTracking.pm +++ b/lib/WebGUI/Asset/Wobject/TimeTracking.pm @@ -81,13 +81,6 @@ sub definition { } -#------------------------------------------------------------------- -sub duplicate { - my $self = shift; - my $newAsset = $self->SUPER::duplicate(shift); - return $newAsset; -} - #------------------------------------------------------------------- sub prepareView { my $self = shift; diff --git a/lib/WebGUI/Asset/Wobject/_NewWobject.skeleton b/lib/WebGUI/Asset/Wobject/_NewWobject.skeleton index 3da26bfc5..4f3da3276 100644 --- a/lib/WebGUI/Asset/Wobject/_NewWobject.skeleton +++ b/lib/WebGUI/Asset/Wobject/_NewWobject.skeleton @@ -82,7 +82,7 @@ wobject instances, you will need to duplicate them here. sub duplicate { my $self = shift; - my $newAsset = $self->SUPER::duplicate(shift); + my $newAsset = $self->SUPER::duplicate(@_); return $newAsset; } diff --git a/lib/WebGUI/Asset/_NewAsset.skeleton b/lib/WebGUI/Asset/_NewAsset.skeleton index c88e2c322..219c2c942 100644 --- a/lib/WebGUI/Asset/_NewAsset.skeleton +++ b/lib/WebGUI/Asset/_NewAsset.skeleton @@ -128,7 +128,7 @@ sub definition { sub duplicate { my $self = shift; - my $newAsset = $self->SUPER::duplicate(shift); + my $newAsset = $self->SUPER::duplicate(@_); return $newAsset; } diff --git a/lib/WebGUI/AssetBranch.pm b/lib/WebGUI/AssetBranch.pm index 98a05a163..37a3d0089 100644 --- a/lib/WebGUI/AssetBranch.pm +++ b/lib/WebGUI/AssetBranch.pm @@ -38,31 +38,26 @@ These methods are available from this class: #------------------------------------------------------------------- -=head2 duplicateBranch ( [assetToDuplicate] ) +=head2 duplicateBranch ( ) -Duplicates an asset and all its descendants. Calls addChild with assetToDuplicate as an argument. Returns a new Asset object. - -=head3 assetToDuplicate - -The asset to duplicate. Defaults to self. +Duplicates this asset and the entire subtree below it. Returns the root of the new subtree. =cut sub duplicateBranch { my $self = shift; - my $assetToDuplicate = shift || $self; - my $newAsset = $assetToDuplicate->duplicate(); - $newAsset->setParent($self); - my $contentPositions; - $contentPositions = $assetToDuplicate->get("contentPositions"); - foreach my $child (@{$assetToDuplicate->getLineage(["children"],{returnObjects=>1})}) { - my $newChild = $newAsset->duplicateBranch($child); + my $newAsset = $self->duplicate; + my $contentPositions = $self->get("contentPositions"); + + foreach my $child (@{$self->getLineage(["children"],{returnObjects=>1})}) { + my $newChild = $child->duplicateBranch; + $newChild->setParent($newAsset); if ($contentPositions) { - my $newChildId = $newChild->getId; - my $oldChildId = $child->getId; - $contentPositions =~ s/${oldChildId}/${newChildId}/g; + my ($oldChildId, $newChildId) = ($child->getId, $newChild->getId); + $contentPositions =~ s/\Q${oldChildId}\E/${newChildId}/g; } } + $newAsset->update({contentPositions=>$contentPositions}) if $contentPositions; return $newAsset; } diff --git a/lib/WebGUI/AssetClipboard.pm b/lib/WebGUI/AssetClipboard.pm index e6abccb35..677150172 100644 --- a/lib/WebGUI/AssetClipboard.pm +++ b/lib/WebGUI/AssetClipboard.pm @@ -61,26 +61,19 @@ sub cut { #------------------------------------------------------------------- -=head2 duplicate ( [assetToDuplicate] ) +=head2 duplicate ( ) -Duplicates an asset. Calls addChild with assetToDuplicate as an arguement. Returns a new Asset object. - -=head3 assetToDuplicate - -If not supplied, defaults to self. +Duplicates this asset, returning the new asset. =cut sub duplicate { my $self = shift; - my $assetToDuplicate = shift || $self; - my $newAsset = $self->addChild($assetToDuplicate->get); - my $sth = $self->session->db->read("select * from metaData_values where assetId = ".$self->session->db->quote($assetToDuplicate->getId)); - while( my $h = $sth->hashRef) { - $self->session->db->write("insert into metaData_values (fieldId, assetId, value) values (". - $self->session->db->quote($h->{fieldId}).",".$self->session->db->quote($newAsset->getId).",".$self->session->db->quote($h->{value}).")"); + my $newAsset = $self->getParent->addChild($self->get); + my $sth = $self->session->db->read("select * from metaData_values where assetId = ?", [$self->getId]); + while (my $h = $sth->hashRef) { + $self->session->db->write("insert into metaData_values (fieldId, assetId, value) values (?, ?, ?)", [$h->{fieldId}, $newAsset->getId, $h->{value}]); } - $sth->finish; return $newAsset; } @@ -291,7 +284,6 @@ sub www_duplicateList { if ($asset->canEdit) { my $newAsset = $asset->duplicate; $newAsset->update({ title=>$newAsset->getTitle.' (copy)'}); - $newAsset->setParent($asset->getParent); } } if ($self->session->form->process("proceed") ne "") { diff --git a/lib/WebGUI/AssetPackage.pm b/lib/WebGUI/AssetPackage.pm index d0755a6b2..970f238c7 100644 --- a/lib/WebGUI/AssetPackage.pm +++ b/lib/WebGUI/AssetPackage.pm @@ -183,7 +183,9 @@ sub importPackage { =head2 www_deployPackage ( ) -Returns "". Deploys a Package. If canEdit is Fales, renders an insufficient Privilege page. +Deploys the package referenced by the query parameter 'assetId' as a +new child of the current asset. Requires edit privileges on the +current asset. =cut @@ -201,7 +203,8 @@ sub www_deployPackage { } my $masterLineage = $packageMasterAsset->get("lineage"); if (defined $packageMasterAsset && $packageMasterAsset->canView && $self->get("lineage") !~ /^$masterLineage/) { - my $deployedTreeMaster = $self->duplicateBranch($packageMasterAsset); + my $deployedTreeMaster = $packageMasterAsset->duplicateBranch; + $deployedTreeMaster->setParent($self); $deployedTreeMaster->update({isPackage=>0, styleTemplateId=>$self->get("styleTemplateId")}); } }