diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index 6be97a889..c4bb091ca 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -1,8 +1,10 @@ 7.4.1 - - Fixed a bug where crons wouldn't load into spectre's queue at startup. - - Fixed a bug in the Collaboration System where posts from the Safari browser - would be submitted without changes. + - fix: crons wouldn't load into spectre's queue at startup. + - fix: in the Collaboration System, posts from the Safari browser + are submitted without changes. - fix: New pagination breaks SQL Reports with semicolons + - fix: purge old asset revisions could purge the most recent revision if the + database had some referential integrity probems - Wiki autolinks prefer longest title match 7.4.0 diff --git a/lib/WebGUI/Asset.pm b/lib/WebGUI/Asset.pm index 8d821e70d..d0b5fc045 100644 --- a/lib/WebGUI/Asset.pm +++ b/lib/WebGUI/Asset.pm @@ -1652,15 +1652,7 @@ sub new { return undef; } - my $assetRevision = $session->stow->get("assetRevision"); - my $revisionDate = shift || $assetRevision->{$assetId}{$session->scratch->get("versionTag")||'_'}; - unless ($revisionDate) { - ($revisionDate) = $session->db->quickArray("select max(revisionDate) from assetData where assetId=? and - (status='approved' or status='archived' or tagId=?) order by assetData.revisionDate", - [$assetId, $session->scratch->get("versionTag")]); - $assetRevision->{$assetId}{$session->scratch->get("versionTag")||'_'} = $revisionDate; - $session->stow->set("assetRevision",$assetRevision); - } + my $revisionDate = shift || $class->getCurrentRevisionDate($session, $assetId); return undef unless ($revisionDate); unless ($class ne 'WebGUI::Asset' or defined $className) { diff --git a/lib/WebGUI/AssetVersioning.pm b/lib/WebGUI/AssetVersioning.pm index cdaf85ade..6b173670d 100644 --- a/lib/WebGUI/AssetVersioning.pm +++ b/lib/WebGUI/AssetVersioning.pm @@ -178,6 +178,40 @@ sub getAutoCommitWorkflowId { #------------------------------------------------------------------- +=head2 getCurrentRevisionDate ( session, assetId ) + +This is a class method. Returns the revision date for the revision of the specified asset that is the currently +published revision for the version tag that we're currently operating under. If no version tag, then the revision +that will be displayed publicly is the one returned. + +=head3 session + +A session object. + +=head3 assetId + +The unique identifier for an asset. + +=cut + +sub getCurrentRevisionDate { + my $class = shift; + my $session = shift; + my $assetId = shift; + my $assetRevision = $session->stow->get("assetRevision"); + my $revisionDate = $assetRevision->{$assetId}{$session->scratch->get("versionTag")||'_'}; + unless ($revisionDate) { + ($revisionDate) = $session->db->quickArray("select max(revisionDate) from assetData where assetId=? and + (status='approved' or status='archived' or tagId=?) order by assetData.revisionDate", + [$assetId, $session->scratch->get("versionTag")]); + $assetRevision->{$assetId}{$session->scratch->get("versionTag")||'_'} = $revisionDate; + $session->stow->set("assetRevision",$assetRevision); + } + return $revisionDate; +} + +#------------------------------------------------------------------- + =head2 getRevisionCount ( [ status ] ) Returns the number of revisions available for this asset. diff --git a/lib/WebGUI/Workflow/Activity/PurgeOldAssetRevisions.pm b/lib/WebGUI/Workflow/Activity/PurgeOldAssetRevisions.pm index 2683e38c9..36db100de 100644 --- a/lib/WebGUI/Workflow/Activity/PurgeOldAssetRevisions.pm +++ b/lib/WebGUI/Workflow/Activity/PurgeOldAssetRevisions.pm @@ -75,19 +75,49 @@ See WebGUI::Workflow::Activity::execute() for details. =cut sub execute { - my $self = shift; - my $sth = $self->session->db->read("select assetData.assetId,asset.className,assetData.revisionDate from asset left join assetData on asset.assetId=assetData.assetId where assetData.revisionDateget("purgeAfter")]); - while (my ($id, $class, $version) = $sth->array) { - my $asset = WebGUI::Asset->new($self->session, $id,$class,$version); - if (defined $asset) { - if ($asset->getRevisionCount("approved") > 1) { - $asset->purgeRevision; - } - } else { - $self->session->errorHandler->error("Could not instanciate asset $id $class $version perhaps it is corrupt.") - } + my ($self, $nothing, $instance) = @_; + my $session = $self->session; + my $log = $session->errorHandler; + + # keep track of how much time it's taking + my $start = time(); + + # figure out if we left off somewhere + my $lastRunVersion = $instance->getScratch("purgeOldAssetsLastRevisionDate"); + my $suspectDate = time() - $self->get("purgeAfter"); + $suspectDate = ($suspectDate > $lastRunVersion) ? $suspectDate : $lastRunVersion; + + # the query to find old revisions + my $sth = $session->db->read("select assetData.assetId,asset.className,assetData.revisionDate from asset + left join assetData on asset.assetId=assetData.assetId where assetData.revisionDatearray) { + + # we never want to purge the current version + if (WebGUI::Asset->getCurrentRevisionDate($session, $id) == $version) { + next; } - $sth->finish; + + # instanciate and purge + my $asset = WebGUI::Asset->new($session, $id,$class,$version); + if (defined $asset) { + if ($asset->getRevisionCount("approved") > 1) { + $log->info("Purging revision $version for asset $id."); + $asset->purgeRevision; + } + } + else { + $log->error("Could not instanciate asset $id $class $version perhaps it is corrupt.") + } + + # give up if we're taking too long + if (time() - $start > 55) { + $log->info("Ran out of time, will pick up with revision $version when we start again."); + $instance->setScratch("purgeOldAssetsLastRevisionDate", $version); + $sth->finish; + return $self->WAITING; + } + } return $self->COMPLETE; }