Update lastPost information in the Thread and CS when a Post is archived. Made a separate method so it can be used by other actions, and in the upgrade script. Fixes bug #11628.

This commit is contained in:
Colin Kuskie 2010-06-21 14:38:46 -07:00
parent 73d6ed7800
commit 54c56019d1
4 changed files with 245 additions and 7 deletions

View file

@ -3,6 +3,7 @@
- fixed #11656: Thingy: Select list fields are not sorted properly
- fixed #11662: yahooapis.com sourced links
- fixed #11658: tmpl var message missing in template help for the cart
- fixed #11628: Message Board: Last Post doesn't show up in CS Thread List
7.9.7
- added #11571: Allow return from photo edit view to gallery edit view

View file

@ -22,17 +22,19 @@ use Getopt::Long;
use WebGUI::Session;
use WebGUI::Storage;
use WebGUI::Asset;
use WebGUI::Asset::Wobject::Collaboration;
use WebGUI::Asset::Post::Thread;
use WebGUI::ProfileField;
my $toVersion = '7.9.8';
my $quiet; # this line required
my $session = start(); # this line required
# upgrade functions go here
changeFirstDayOfWeekDefault($session);
updateLastPostCS($session);
updateLastPostThread($session);
finish($session); # this line required
@ -51,11 +53,47 @@ finish($session); # this line required
sub changeFirstDayOfWeekDefault {
my $session = shift;
print "\tMake the default for firstDayOfWeek a number instead of a string... " unless $quiet;
# and here's our code
my $profileField = WebGUI::ProfileField->new($session, 'firstDayOfWeek');
my $properties = $profileField->get();
$properties->{dataDefault} = 0;
$profileField->set($properties);
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Describe what our function does
sub updateLastPostCS {
my $session = shift;
print "\tUpdating last post information in every Collaboration System. This could take a very long time... " unless $quiet;
# and here's our code
my $getCs = WebGUI::Asset::Wobject::Collaboration->getIsa($session);
CS: while (my $cs = eval { $getCs->() } ) {
next CS if Exception::Class->caught();
last CS if ! $cs;
next CS unless $cs->get('lastPostId');
my $lastPost = WebGUI::Asset->newByDynamicClass($session, $cs->get('lastPostId'));
next CS unless $lastPost && $lastPost->get('status') eq 'archived';
$lastPost->disqualifyAsLastPost;
}
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Describe what our function does
sub updateLastPostThread {
my $session = shift;
print "\tUpdating last post information in every Thread. This could also take a very long time... " unless $quiet;
# and here's our code
my $getThread = WebGUI::Asset::Wobject::Collaboration->getIsa($session);
THREAD: while (my $thread = eval { $getThread->() } ) {
next THREAD if Exception::Class->caught();
last THREAD if ! $thread;
next THREAD unless $thread->get('lastPostId');
my $lastPost = WebGUI::Asset->newByDynamicClass($session, $thread->get('lastPostId'));
next THREAD unless $lastPost && $lastPost->get('status') eq 'archived';
$lastPost->disqualifyAsLastPost;
}
print "DONE!\n" unless $quiet;
}

View file

@ -62,6 +62,7 @@ sub _fixReplyCount {
my $lastPostId = $asset->getLineage( [ qw{ self descendants } ], {
isa => 'WebGUI::Asset::Post',
orderByClause => 'assetData.revisionDate desc',
limit => 1,
} )->[0];
if (my $lastPost = WebGUI::Asset->newByDynamicClass( $self->session, $lastPostId ) ) {
@ -353,6 +354,53 @@ sub definition {
}
#-------------------------------------------------------------------
=head2 disqualifyAsLastPost ( )
This method should be called whenever something happens to the Post or Thread that would disqualify
it as being the last post in a Thread, or Collaboration System. Good examples are cutting to the
clipboard, trashing, or archiving.
If the Post was the last post, it will find the second to last post for each kind of parent asset,
and update that asset with that Post's information.
=cut
sub disqualifyAsLastPost {
my $self = shift;
my $thread = $self->getThread;
if ($thread->get('lastPostId') eq $self->getId) {
my $secondary_post = $thread->getLineage(['descendants'], {
returnObjects => 1,
includeOnlyClasses => ["WebGUI::Asset::Post", ],
limit => 1,
orderByClause => 'revisionDate,lineage DESC',
})->[0];
if ($secondary_post) { ##Handle edge case for no other
$thread->update({ lastPostId => $secondary_post->getId, lastPostDate => $secondary_post->get('creationDate'), });
}
else {
$thread->update({ lastPostId => '', lastPostDate => '', });
}
}
my $cs = $thread->getParent;
if ($cs->get('lastPostId') eq $self->getId) {
my $secondary_post = $cs->getLineage(['descendants'], {
returnObjects => 1,
includeOnlyClasses => ["WebGUI::Asset::Post","WebGUI::Asset::Post::Thread"],
limit => 1,
orderByClause => 'revisionDate DESC',
})->[0];
if ($secondary_post) { ##Handle edge case for no other
$cs->update({ lastPostId => $secondary_post->getId, lastPostDate => $secondary_post->get('creationDate'), });
}
else {
$cs->update({ lastPostId => '', lastPostDate => '', });
}
}
}
#-------------------------------------------------------------------
=head2 DESTROY
@ -1188,6 +1236,31 @@ sub purgeRevision {
#-------------------------------------------------------------------
=head2 qualifyAsLastPost ( )
This method should be called whenever something happens to the Post or Thread that would qualify
it as being the last post in a Thread, or Collaboration System. Good examples are pasting from
the clipboard, restoring from the trash, or changing the state from archiving.
It checks the parent Thread and CS to see if it is now the last Post, and updates that asset with
its information.
=cut
sub qualifyAsLastPost {
my ($self) = @_;
my $thread = $self->getThread();
if ($self->get('creationDate') > $thread->get('lastPostDate')) {
$thread->update({ lastPostId => $self->getId, lastPostDate => $self->get('creationDate'), });
}
my $cs = $thread->getParent;
if ($self->get('creationDate') > $cs->get('lastPostDate')) {
$cs->update({ lastPostId => $self->getId, lastPostDate => $self->get('creationDate'), });
}
}
#-------------------------------------------------------------------
=head2 rate ( rating )
@ -1292,14 +1365,16 @@ sub setParent {
=head2 setStatusArchived ( )
Sets the status of this post to archived.
Sets the status of this post to archived. Updates the parent thread and CS to remove
the lastPost, if this post is the last post.
=cut
sub setStatusArchived {
my ($self) = @_;
$self->update({status=>'archived'});
my ($self) = @_;
$self->update({status=>'archived'});
$self->disqualifyAsLastPost;
}
@ -1308,13 +1383,15 @@ sub setStatusArchived {
=head2 setStatusUnarchived ( )
Sets the status of this post to approved, but does so without any of the normal notifications and other stuff.
Updates the last post information in the parent Thread and CS if applicable.
=cut
sub setStatusUnarchived {
my ($self) = @_;
$self->update({status=>'approved'}) if ($self->get("status") eq "archived");
my ($self) = @_;
$self->update({status=>'approved'}) if ($self->get("status") eq "archived");
$self->qualifyAsLastPost;
}
#-------------------------------------------------------------------

122
t/Asset/Post/archiving.t Normal file
View file

@ -0,0 +1,122 @@
#-------------------------------------------------------------------
# WebGUI is Copyright 2001-2009 Plain Black Corporation.
#-------------------------------------------------------------------
# Please read the legal notices (docs/legal.txt) and the license
# (docs/license.txt) that came with this distribution before using
# this software.
#-------------------------------------------------------------------
# http://www.plainblack.com info@plainblack.com
#-------------------------------------------------------------------
# 1. The basic framework for a test suite for the Post Asset.
# Includes setup, cleanup, boilerplate, etc. Basically the really boring,
# repetitive parts of the test that you don't want to write yourself.
# 2. The tests for the features I've implemented; namely, functionality and
# general access controls on who can edit a post.
use FindBin;
use strict;
use lib "$FindBin::Bin/../../lib";
use WebGUI::Test;
use WebGUI::Session;
use Test::More tests => 13; # increment this value for each test you create
use WebGUI::Asset::Wobject::Collaboration;
use WebGUI::Asset::Post;
use WebGUI::Asset::Post::Thread;
my $session = WebGUI::Test->session;
# Do our work in the import node
my $node = WebGUI::Asset->getImportNode($session);
# Grab a named version tag
my $versionTag = WebGUI::VersionTag->getWorking($session);
$versionTag->set({name=>"Collab setup"});
# Need to create a Collaboration system in which the post lives.
my @addArgs = ( undef, undef, { skipAutoCommitWorkflows => 1, skipNotification => 1 } );
my $collab = $node->addChild({className => 'WebGUI::Asset::Wobject::Collaboration'}, @addArgs);
# finally, add posts and threads to the collaboration system
my $first_thread = $collab->addChild(
{ className => 'WebGUI::Asset::Post::Thread', },
undef,
WebGUI::Test->webguiBirthday,
{ skipAutoCommitWorkflows => 1, skipNotification => 1 }
);
my $second_thread = $collab->addChild(
{ className => 'WebGUI::Asset::Post::Thread', },
undef,
WebGUI::Test->webguiBirthday,
{ skipAutoCommitWorkflows => 1, skipNotification => 1 }
);
##Thread 1, Post 1 => t1p1
my $t1p1 = $first_thread->addChild(
{ className => 'WebGUI::Asset::Post', },
undef,
WebGUI::Test->webguiBirthday,
{ skipAutoCommitWorkflows => 1, skipNotification => 1 }
);
my $t1p2 = $first_thread->addChild(
{ className => 'WebGUI::Asset::Post', },
undef,
WebGUI::Test->webguiBirthday + 1,
{ skipAutoCommitWorkflows => 1, skipNotification => 1 }
);
my $past = time()-15;
my $t2p1 = $second_thread->addChild(
{ className => 'WebGUI::Asset::Post', },
undef,
$past,
{ skipAutoCommitWorkflows => 1, skipNotification => 1 }
);
my $t2p2 = $second_thread->addChild(
{ className => 'WebGUI::Asset::Post', },
undef,
undef,
{ skipAutoCommitWorkflows => 1, skipNotification => 1 }
);
$versionTag->commit();
WebGUI::Test->addToCleanup($versionTag);
foreach my $asset ($collab, $t1p1, $t1p2, $t2p1, $t2p2, $first_thread, $second_thread, ) {
$asset = $asset->cloneFromDb;
}
is $collab->getChildCount, 2, 'collab has correct number of children';
is $collab->get('lastPostId'), $t2p2->getId, 'lastPostId set in collab';
is $collab->get('lastPostDate'), $t2p2->get('creationDate'), 'lastPostDate, too';
$t2p2->setStatusArchived;
is $t2p2->get('status'), 'archived', 'setStatusArchived set the post to be archived';
$second_thread = $second_thread->cloneFromDb;
is $second_thread->get('lastPostId'), $t2p1->getId, '.. updated lastPostId in the thread';
is $second_thread->get('lastPostDate'), $t2p1->get('creationDate'), '... lastPostDate, too';
$collab = $collab->cloneFromDb;
is $collab->get('lastPostId'), $t2p1->getId, '.. updated lastPostId in the CS';
is $collab->get('lastPostDate'), $t2p1->get('creationDate'), '... lastPostDate, too';
$t2p2->setStatusUnarchived;
is $t2p2->get('status'), 'approved', 'setStatusUnarchived sets the post back to approved';
$second_thread = $second_thread->cloneFromDb;
is $second_thread->get('lastPostId'), $t2p2->getId, '.. updated lastPostId in the thread';
is $second_thread->get('lastPostDate'), $t2p2->get('creationDate'), '... lastPostDate, too';
$collab = $collab->cloneFromDb;
is $collab->get('lastPostId'), $t2p2->getId, '.. updated lastPostId in the CS';
is $collab->get('lastPostDate'), $t2p2->get('creationDate'), '... lastPostDate, too';
#vim:ft=perl