1467 lines
46 KiB
Perl
1467 lines
46 KiB
Perl
package WebGUI::Asset::Wobject::Collaboration;
|
|
|
|
#-------------------------------------------------------------------
|
|
# 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
|
|
#-------------------------------------------------------------------
|
|
|
|
use strict;
|
|
use Tie::IxHash;
|
|
use WebGUI::Group;
|
|
use WebGUI::Cache;
|
|
use WebGUI::HTML;
|
|
use WebGUI::International;
|
|
use WebGUI::Paginator;
|
|
use WebGUI::Utility;
|
|
use WebGUI::Asset::Wobject;
|
|
use WebGUI::Workflow::Cron;
|
|
use WebGUI::Asset::RSSCapable;
|
|
use base 'WebGUI::Asset::RSSCapable';
|
|
use base 'WebGUI::Asset::Wobject';
|
|
|
|
#-------------------------------------------------------------------
|
|
sub _computePostCount {
|
|
my $self = shift;
|
|
return scalar @{$self->getLineage(['descendants'], {includeOnlyClasses => ['WebGUI::Asset::Post']})};
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
sub _computeThreadCount {
|
|
my $self = shift;
|
|
return scalar @{$self->getLineage(['children'], {includeOnlyClasses => ['WebGUI::Asset::Post::Thread']})};
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
# format the date according to rfc 822 (for RSS export)
|
|
my @_months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
|
|
sub _get_rfc822_date {
|
|
my $self = shift;
|
|
my ($time) = @_;
|
|
my ($year, $mon, $mday, $hour, $min, $sec) = $self->session->datetime->localtime($time);
|
|
my $month = $_months[$mon - 1];
|
|
return sprintf("%02d %s %04d %02d:%02d:%02d GMT",
|
|
$mday, $month, $year, $hour, $min, $sec);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
sub _visitorCacheKey {
|
|
my $self = shift;
|
|
my $pn = $self->session->form->process('pn');
|
|
return "view_".$self->getId."?pn=".$pn;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
sub _visitorCacheOk {
|
|
my $self = shift;
|
|
return ($self->session->user->isVisitor
|
|
&& !$self->session->form->process('sortBy'));
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
# encode a string to include in xml (for RSS export)
|
|
sub _xml_encode {
|
|
my $text = shift;
|
|
$text =~ s/&/&/g;
|
|
$text =~ s/</</g;
|
|
$text =~ s/\]\]>/\]\]>/g;
|
|
return $text;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
sub addChild {
|
|
my $self = shift;
|
|
my $properties = shift;
|
|
my @other = @_;
|
|
if ($properties->{className} ne "WebGUI::Asset::Post::Thread"
|
|
and $properties->{className} ne 'WebGUI::Asset::RSSFromParent') {
|
|
$self->session->errorHandler->security("add a ".$properties->{className}." to a ".$self->get("className"));
|
|
return undef;
|
|
}
|
|
return $self->SUPER::addChild($properties, @other);
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
sub appendPostListTemplateVars {
|
|
my $self = shift;
|
|
my $var = shift;
|
|
my $p = shift;
|
|
my $page = $p->getPageData;
|
|
my $i = 0;
|
|
my ($icon, $datetime) = $self->session->quick(qw(icon datetime));
|
|
foreach my $row (@$page) {
|
|
my $post = WebGUI::Asset->new($self->session,$row->{assetId}, $row->{className}, $row->{revisionDate});
|
|
$post->{_parent} = $self; # caching parent for efficiency
|
|
my $controls = $icon->delete('func=delete',$post->get("url"),"Delete") . $icon->edit('func=edit',$post->get("url"));
|
|
if ($self->get("sortBy") eq "lineage") {
|
|
if ($self->get("sortOrder") eq "desc") {
|
|
$controls .= $icon->moveUp('func=demote',$post->get("url")).$icon->moveDown('func=promote',$post->get("url"));
|
|
}
|
|
else {
|
|
$controls .= $icon->moveUp('func=promote',$post->get("url")).$icon->moveDown('func=demote',$post->get("url"));
|
|
}
|
|
}
|
|
my @rating_loop;
|
|
for (my $i=0;$i<=$post->get("rating");$i++) {
|
|
push(@rating_loop,{'rating_loop.count'=>$i});
|
|
}
|
|
my %lastReply;
|
|
my $hasRead = 0;
|
|
if ($post->get("className") =~ /Thread/) {
|
|
if ($self->get("displayLastReply")) {
|
|
my $lastPost = $post->getLastPost();
|
|
%lastReply = (
|
|
"lastReply.url" => $lastPost->getUrl.'#'.$lastPost->getId,
|
|
"lastReply.title" => $lastPost->get("title"),
|
|
"lastReply.user.isVisitor" => $lastPost->get("ownerUserId") eq "1",
|
|
"lastReply.username" => $lastPost->get("username"),
|
|
"lastReply.userProfile.url" => $lastPost->getPosterProfileUrl(),
|
|
"lastReply.dateSubmitted.human" => $datetime->epochToHuman($lastPost->get("creationDate"),"%z"),
|
|
"lastReply.timeSubmitted.human" => $datetime->epochToHuman($lastPost->get("creationDate"),"%Z"),
|
|
);
|
|
}
|
|
$hasRead = $post->isMarkedRead;
|
|
}
|
|
my $url;
|
|
if ($post->get("status") eq "pending") {
|
|
$url = $post->getUrl("revision=".$post->get("revisionDate"))."#".$post->getId;
|
|
} else {
|
|
$url = $post->getUrl."#".$post->getId;
|
|
}
|
|
my %postVars = (
|
|
%{$post->get},
|
|
"id" => $post->getId,
|
|
"url" => $url,
|
|
rating_loop => \@rating_loop,
|
|
"content" => $post->formatContent,
|
|
"status" => $post->getStatus,
|
|
"thumbnail" => $post->getThumbnailUrl,
|
|
"image.url" => $post->getImageUrl,
|
|
"dateSubmitted.human" => $datetime->epochToHuman($post->get("creationDate"),"%z"),
|
|
"dateUpdated.human" => $datetime->epochToHuman($post->get("revisionDate"),"%z"),
|
|
"timeSubmitted.human" => $datetime->epochToHuman($post->get("creationDate"),"%Z"),
|
|
"timeUpdated.human" => $datetime->epochToHuman($post->get("revisionDate"),"%Z"),
|
|
"userProfile.url" => $post->getPosterProfileUrl,
|
|
"user.isVisitor" => $post->get("ownerUserId") eq "1",
|
|
"edit.url" => $post->getEditUrl,
|
|
'controls' => $controls,
|
|
"isSecond" => (($i+1)%2==0),
|
|
"isThird" => (($i+1)%3==0),
|
|
"isFourth" => (($i+1)%4==0),
|
|
"isFifth" => (($i+1)%5==0),
|
|
"user.hasRead" => $hasRead,
|
|
"user.isPoster" => $post->isPoster,
|
|
"avatar.url" => $post->getAvatarUrl,
|
|
%lastReply
|
|
);
|
|
$post->getTemplateMetadataVars(\%postVars);
|
|
if ($row->{className} =~ m/^WebGUI::Asset::Post::Thread/) {
|
|
$postVars{'rating'} = $post->get('threadRating');
|
|
}
|
|
push(@{$var->{post_loop}}, \%postVars );
|
|
$i++;
|
|
}
|
|
$p->appendTemplateVars($var);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
sub appendTemplateLabels {
|
|
my $self = shift;
|
|
my $var = shift;
|
|
my $i18n = WebGUI::International->new($self->session, "Asset_Collaboration");
|
|
$var->{"transferkarma.label"} = $i18n->get("transfer karma");
|
|
$var->{"karmaScale.label"} = $i18n->get("karma scale");
|
|
$var->{"close.label"} = $i18n->get("close");
|
|
$var->{"closed.label"} = $i18n->get("closed");
|
|
$var->{"open.label"} = $i18n->get("open");
|
|
$var->{"critical.label"} = $i18n->get("critical");
|
|
$var->{"cosmetic.label"} = $i18n->get("cosmetic");
|
|
$var->{"minor.label"} = $i18n->get("minor");
|
|
$var->{"fatal.label"} = $i18n->get("fatal");
|
|
$var->{"severity.label"} = $i18n->get("severity");
|
|
$var->{"add.label"} = $i18n->get("add");
|
|
$var->{"addlink.label"} = $i18n->get("addlink");
|
|
$var->{"addquestion.label"} = $i18n->get("addquestion");
|
|
$var->{'answer.label'} = $i18n->get("answer");
|
|
$var->{'attachment.label'} = $i18n->get("attachment");
|
|
$var->{'archive.label'} = $i18n->get("archive");
|
|
$var->{'unarchive.label'} = $i18n->get("unarchive");
|
|
$var->{"by.label"} = $i18n->get("by");
|
|
$var->{'body.label'} = $i18n->get("body");
|
|
$var->{"back.label"} = $i18n->get("back");
|
|
$var->{'compensation.label'} = $i18n->get("compensation");
|
|
$var->{'contentType.label'} = $i18n->get("contentType");
|
|
$var->{"date.label"} = $i18n->get("date");
|
|
$var->{"delete.label"} = $i18n->get("delete");
|
|
$var->{'description.label'} = $i18n->get("description");
|
|
$var->{"edit.label"} = $i18n->get("edit");
|
|
$var->{'image.label'} = $i18n->get("image");
|
|
$var->{"job.header.label"} = $i18n->get("edit job");
|
|
$var->{"job.title.label"} = $i18n->get("job title");
|
|
$var->{"job.description.label"} = $i18n->get("job description");
|
|
$var->{"job.requirements.label"} = $i18n->get("job requirements");
|
|
$var->{"karmaRank.label"} = $i18n->get("karma rank");
|
|
$var->{"location.label"} = $i18n->get("location");
|
|
$var->{"layout.flat.label"} = $i18n->get("flatLayout");
|
|
$var->{'link.header.label'} = $i18n->get("edit link");
|
|
$var->{"lastReply.label"} = $i18n->get("lastReply");
|
|
$var->{"lock.label"} = $i18n->get("lock");
|
|
$var->{"layout.label"} = $i18n->get("layout");
|
|
$var->{'message.header.label'} = $i18n->get("edit message");
|
|
$var->{'message.label'} = $i18n->get("message");
|
|
$var->{"next.label"} = $i18n->get("next");
|
|
$var->{'newWindow.label'} = $i18n->get("new window");
|
|
$var->{"layout.nested.label"} = $i18n->get("nested");
|
|
$var->{"previous.label"} = $i18n->get("previous");
|
|
$var->{"post.label"} = $i18n->get("post");
|
|
$var->{'question.label'} = $i18n->get("question");
|
|
$var->{'question.header.label'} = $i18n->get("edit question");
|
|
$var->{"rating.label"} = $i18n->get("rating");
|
|
$var->{"rate.label"} = $i18n->get("rate");
|
|
$var->{"reply.label"} = $i18n->get("reply");
|
|
$var->{"replies.label"} = $i18n->get("replies");
|
|
$var->{"readmore.label"} = $i18n->get("read more");
|
|
$var->{"responses.label"} = $i18n->get("responses");
|
|
$var->{"search.label"} = $i18n->get("search");
|
|
$var->{'subject.label'} = $i18n->get("subject");
|
|
$var->{"subscribe.label"} = $i18n->get("subscribe");
|
|
$var->{'submission.header.label'} = $i18n->get("edit submission");
|
|
$var->{"stick.label"} = $i18n->get("sticky");
|
|
$var->{"status.label"} = $i18n->get("status");
|
|
$var->{"synopsis.label"} = $i18n->get("synopsis");
|
|
$var->{"thumbnail.label"} = $i18n->get("thumbnail");
|
|
$var->{"title.label"} = $i18n->get("title");
|
|
$var->{"unlock.label"} = $i18n->get("unlock");
|
|
$var->{"unstick.label"} = $i18n->get("unstick");
|
|
$var->{"unsubscribe.label"} = $i18n->get("unsubscribe");
|
|
$var->{'url.label'} = $i18n->get("url");
|
|
$var->{"user.label"} = $i18n->get("user");
|
|
$var->{"views.label"} = $i18n->get("views");
|
|
$var->{'visitorName.label'} = $i18n->get("visitor");
|
|
$var->{"captcha_label"} = $i18n->get("captcha label");
|
|
$var->{'keywords.label'} = $i18n->get('keywords label');
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
sub canEdit {
|
|
my $self = shift;
|
|
my $userId = shift || $self->session->user->userId;
|
|
return (
|
|
(
|
|
(
|
|
$self->session->form->process("func") eq "add" ||
|
|
(
|
|
$self->session->form->process("assetId") eq "new" &&
|
|
$self->session->form->process("func") eq "editSave" &&
|
|
$self->session->form->process("class") eq "WebGUI::Asset::Post::Thread"
|
|
)
|
|
) &&
|
|
$self->canStartThread( $userId )
|
|
) || # account for new threads
|
|
$self->SUPER::canEdit( $userId )
|
|
);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
sub canModerate {
|
|
my $self = shift;
|
|
my $userId = shift || $self->session->user->userId;
|
|
return $self->SUPER::canEdit( $userId );
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
sub canPost {
|
|
my $self = shift;
|
|
my $userId = shift;
|
|
my $session = $self->session;
|
|
my $user = $userId
|
|
? WebGUI::User->new( $session, $userId )
|
|
: $self->session->user
|
|
;
|
|
|
|
# checks to make sure that the cs has been committed at least once
|
|
if ( $self->get("status") ne "approved" && $self->getTagCount <= 1 ) {
|
|
return 0;
|
|
}
|
|
# Users in the postGroupId can post
|
|
elsif ( $user->isInGroup( $self->get("postGroupId") ) ) {
|
|
return 1;
|
|
}
|
|
# Users who can edit the collab can post
|
|
else {
|
|
return $self->SUPER::canEdit( $userId );
|
|
}
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
sub canSubscribe {
|
|
my $self = shift;
|
|
my $userId = shift;
|
|
my $session = $self->session;
|
|
my $user = $userId
|
|
? WebGUI::User->new( $session, $userId )
|
|
: $self->session->user
|
|
;
|
|
return ($user->isRegistered && $self->canView( $userId ) );
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
sub canStartThread {
|
|
my $self = shift;
|
|
my $userId = shift;
|
|
my $session = $self->session;
|
|
my $user = $userId
|
|
? WebGUI::User->new( $session, $userId )
|
|
: $self->session->user
|
|
;
|
|
return (
|
|
$user->isInGroup($self->get("canStartThreadGroupId"))
|
|
|| $self->SUPER::canEdit( $userId )
|
|
);
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
sub canView {
|
|
my $self = shift;
|
|
my $userId = shift || $self->session->user->userId;
|
|
return $self->SUPER::canView( $userId ) || $self->canPost( $userId );
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
sub commit {
|
|
my $self = shift;
|
|
$self->SUPER::commit;
|
|
my $cron = undef;
|
|
if ($self->get("getMailCronId")) {
|
|
$cron = WebGUI::Workflow::Cron->new($self->session, $self->get("getMailCronId"));
|
|
}
|
|
my $i18n = WebGUI::International->new($self->session, "Asset_Collaboration");
|
|
unless (defined $cron) {
|
|
$cron = WebGUI::Workflow::Cron->create($self->session, {
|
|
title=>$self->getTitle." ".$i18n->get("mail"),
|
|
minuteOfHour=>"*/".($self->get("getMailInterval")/60),
|
|
className=>(ref $self),
|
|
methodName=>"new",
|
|
parameters=>$self->getId,
|
|
workflowId=>"csworkflow000000000001"
|
|
});
|
|
$self->update({getMailCronId=>$cron->getId});
|
|
}
|
|
if ($self->get("getMail")) {
|
|
$cron->set({enabled=>1,title=>$self->getTitle." ".$i18n->get("mail"), minuteOfHour=>"*/".($self->get("getMailInterval")/60)});
|
|
} else {
|
|
$cron->set({enabled=>0,title=>$self->getTitle." ".$i18n->get("mail"), minuteOfHour=>"*/".($self->get("getMailInterval")/60)});
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
sub createSubscriptionGroup {
|
|
my $self = shift;
|
|
my $group = WebGUI::Group->new($self->session, "new");
|
|
$group->name($self->getId);
|
|
$group->description("The group to store subscriptions for the collaboration system ".$self->getId);
|
|
$group->isEditable(0);
|
|
$group->showInForms(0);
|
|
$group->deleteGroups([3]); # admins don't want to be auto subscribed to this thing
|
|
$self->update({
|
|
subscriptionGroupId=>$group->getId
|
|
});
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
sub definition {
|
|
my $class = shift;
|
|
my $session = shift;
|
|
my $definition = shift;
|
|
my $i18n = WebGUI::International->new($session,"Asset_Collaboration");
|
|
my $useKarma = $session->setting->get('useKarma');
|
|
|
|
# obtain the groupIdEdit default value. Try to get it from the parent asset
|
|
# if it exists. If not, default to the value specified in WebGUI::Asset's
|
|
# definition.
|
|
my $groupIdEdit;
|
|
if($session->asset) {
|
|
$groupIdEdit = $session->asset->get('groupIdEdit');
|
|
}
|
|
else {
|
|
$groupIdEdit = '4';
|
|
}
|
|
|
|
|
|
my %sortByOptions;
|
|
tie %sortByOptions, 'Tie::IxHash';
|
|
%sortByOptions = (lineage=>$i18n->get('sequence'),
|
|
"assetData.revisionDate"=>$i18n->get('date updated'),
|
|
creationDate=>$i18n->get('date submitted'),
|
|
title=>$i18n->get('title'),
|
|
userDefined1=>$i18n->get('user defined 1'),
|
|
userDefined2=>$i18n->get('user defined 2'),
|
|
userDefined3=>$i18n->get('user defined 3'),
|
|
userDefined4=>$i18n->get('user defined 4'),
|
|
userDefined5=>$i18n->get('user defined 5'),
|
|
($useKarma? (karmaRank=>$i18n->get('karma rank')) : ()),
|
|
);
|
|
|
|
my %properties;
|
|
tie %properties, 'Tie::IxHash';
|
|
%properties = (
|
|
visitorCacheTimeout => {
|
|
tab => "display",
|
|
fieldType => "interval",
|
|
defaultValue => 3600,
|
|
uiLevel => 8,
|
|
label => $i18n->get("visitor cache timeout"),
|
|
hoverHelp => $i18n->get("visitor cache timeout help")
|
|
},
|
|
autoSubscribeToThread => {
|
|
fieldType=>"yesNo",
|
|
defaultValue=>1,
|
|
tab=>'mail',
|
|
label=>$i18n->get("auto subscribe to thread"),
|
|
hoverHelp=>$i18n->get("auto subscribe to thread help"),
|
|
},
|
|
requireSubscriptionForEmailPosting => {
|
|
fieldType=>"yesNo",
|
|
defaultValue=>1,
|
|
tab=>'mail',
|
|
label=>$i18n->get("require subscription for email posting"),
|
|
hoverHelp=>$i18n->get("require subscription for email posting help"),
|
|
},
|
|
approvalWorkflow =>{
|
|
fieldType=>"workflow",
|
|
defaultValue=>"pbworkflow000000000003",
|
|
type=>'WebGUI::VersionTag',
|
|
tab=>'security',
|
|
label=>$i18n->get('approval workflow'),
|
|
hoverHelp=>$i18n->get('approval workflow description'),
|
|
},
|
|
threadApprovalWorkflow =>{
|
|
fieldType=>"workflow",
|
|
defaultValue=>"pbworkflow000000000003",
|
|
type=>'WebGUI::VersionTag',
|
|
tab=>'security',
|
|
label=>$i18n->get('thread approval workflow'),
|
|
hoverHelp=>$i18n->get('thread approval workflow description'),
|
|
},
|
|
thumbnailSize => {
|
|
fieldType => "integer",
|
|
defaultValue => 0,
|
|
tab => "display",
|
|
label => $i18n->get("thumbnail size"),
|
|
hoverHelp => $i18n->get("thumbnail size help")
|
|
},
|
|
maxImageSize => {
|
|
fieldType => "integer",
|
|
defaultValue => 0,
|
|
tab => "display",
|
|
label => $i18n->get("max image size"),
|
|
hoverHelp => $i18n->get("max image size help")
|
|
},
|
|
mailServer=>{
|
|
fieldType=>"text",
|
|
defaultValue=>undef,
|
|
tab=>'mail',
|
|
label=>$i18n->get("mail server"),
|
|
hoverHelp=>$i18n->get("mail server help"),
|
|
},
|
|
mailAccount=>{
|
|
fieldType=>"text",
|
|
defaultValue=>undef,
|
|
tab=>'mail',
|
|
label=>$i18n->get("mail account"),
|
|
hoverHelp=>$i18n->get("mail account help"),
|
|
},
|
|
mailPassword=>{
|
|
fieldType=>"password",
|
|
defaultValue=>undef,
|
|
tab=>'mail',
|
|
label=>$i18n->get("mail password"),
|
|
hoverHelp=>$i18n->get("mail password help"),
|
|
},
|
|
mailAddress=>{
|
|
fieldType=>"email",
|
|
defaultValue=>undef,
|
|
tab=>'mail',
|
|
label=>$i18n->get("mail address"),
|
|
hoverHelp=>$i18n->get("mail address help"),
|
|
},
|
|
mailPrefix=>{
|
|
fieldType=>"text",
|
|
defaultValue=>undef,
|
|
tab=>'mail',
|
|
label=>$i18n->get("mail prefix"),
|
|
hoverHelp=>$i18n->get("mail prefix help"),
|
|
},
|
|
getMailCronId=>{
|
|
fieldType=>"hidden",
|
|
defaultValue=>undef,
|
|
noFormPost=>1
|
|
},
|
|
getMail=>{
|
|
fieldType=>"yesNo",
|
|
defaultValue=>0,
|
|
tab=>'mail',
|
|
label=>$i18n->get("get mail"),
|
|
hoverHelp=>$i18n->get("get mail help"),
|
|
},
|
|
getMailInterval=>{
|
|
fieldType=>"interval",
|
|
defaultValue=>300,
|
|
tab=>'mail',
|
|
label=>$i18n->get("get mail interval"),
|
|
hoverHelp=>$i18n->get("get mail interval help"),
|
|
},
|
|
displayLastReply =>{
|
|
fieldType=>"yesNo",
|
|
defaultValue=>0,
|
|
tab=>'display',
|
|
label=>$i18n->get('display last reply'),
|
|
hoverHelp=>$i18n->get('display last reply description'),
|
|
},
|
|
allowReplies =>{
|
|
fieldType=>"yesNo",
|
|
defaultValue=>1,
|
|
tab=>'security',
|
|
label=>$i18n->get('allow replies'),
|
|
hoverHelp=>$i18n->get('allow replies description'),
|
|
},
|
|
threadsPerPage =>{
|
|
fieldType=>"integer",
|
|
defaultValue=>30,
|
|
tab=>'display',
|
|
label=>$i18n->get('threads/page'),
|
|
hoverHelp=>$i18n->get('threads/page description'),
|
|
},
|
|
postsPerPage =>{
|
|
fieldType=>"integer",
|
|
defaultValue=>10,
|
|
tab=>'display',
|
|
label=>$i18n->get('posts/page'),
|
|
hoverHelp=>$i18n->get('posts/page description'),
|
|
},
|
|
archiveEnabled => {
|
|
fieldType => "yesNo",
|
|
defaultValue => 1,
|
|
tab => 'properties',
|
|
label => $i18n->get('editForm archiveEnabled label'),
|
|
hoverHelp => $i18n->get('editForm archiveEnabled description'),
|
|
},
|
|
archiveAfter =>{
|
|
fieldType=>"interval",
|
|
defaultValue=>31536000,
|
|
tab=>'properties',
|
|
label=>$i18n->get('archive after'),
|
|
hoverHelp=>$i18n->get('archive after description'),
|
|
},
|
|
lastPostDate =>{
|
|
noFormPost=>1,
|
|
fieldType=>"hidden",
|
|
defaultValue=>undef
|
|
},
|
|
lastPostId =>{
|
|
noFormPost=>1,
|
|
fieldType=>"hidden",
|
|
defaultValue=>undef
|
|
},
|
|
rating =>{
|
|
noFormPost=>1,
|
|
fieldType=>"hidden",
|
|
defaultValue=>undef
|
|
},
|
|
replies =>{
|
|
noFormPost=>1,
|
|
fieldType=>"hidden",
|
|
defaultValue=>undef
|
|
},
|
|
views =>{
|
|
noFormPost=>1,
|
|
fieldType=>"hidden",
|
|
defaultValue=>undef
|
|
},
|
|
threads =>{
|
|
noFormPost=>1,
|
|
fieldType=>"hidden",
|
|
defaultValue=>undef
|
|
},
|
|
useContentFilter =>{
|
|
fieldType=>"yesNo",
|
|
defaultValue=>1,
|
|
tab=>'display',
|
|
label=>$i18n->get('content filter'),
|
|
hoverHelp=>$i18n->get('content filter description'),
|
|
},
|
|
filterCode =>{
|
|
fieldType=>"filterContent",
|
|
defaultValue=>'javascript',
|
|
tab=>'security',
|
|
label=>$i18n->get('filter code'),
|
|
hoverHelp=>$i18n->get('filter code description'),
|
|
},
|
|
richEditor =>{
|
|
fieldType=>"selectRichEditor",
|
|
defaultValue=>"PBrichedit000000000002",
|
|
tab=>'display',
|
|
label=>$i18n->get('rich editor'),
|
|
hoverHelp=>$i18n->get('rich editor description'),
|
|
},
|
|
attachmentsPerPost =>{
|
|
fieldType=>"integer",
|
|
defaultValue=>0,
|
|
tab=>'properties',
|
|
label=>$i18n->get('attachments/post'),
|
|
hoverHelp=>$i18n->get('attachments/post description'),
|
|
},
|
|
editTimeout =>{
|
|
fieldType=>"interval",
|
|
defaultValue=>3600,
|
|
tab=>'security',
|
|
label=>$i18n->get('edit timeout'),
|
|
hoverHelp=>$i18n->get('edit timeout description'),
|
|
},
|
|
addEditStampToPosts =>{
|
|
fieldType=>"yesNo",
|
|
defaultValue=>0,
|
|
tab=>'security',
|
|
label=>$i18n->get('edit stamp'),
|
|
hoverHelp=>$i18n->get('edit stamp description'),
|
|
},
|
|
usePreview =>{
|
|
fieldType=>"yesNo",
|
|
defaultValue=>1,
|
|
tab=>'properties',
|
|
label=>$i18n->get('use preview'),
|
|
hoverHelp=>$i18n->get('use preview description'),
|
|
},
|
|
sortOrder =>{
|
|
fieldType=>"selectBox",
|
|
defaultValue=>'desc',
|
|
tab=>'display',
|
|
options=>{ asc => $i18n->get('ascending'),
|
|
desc => $i18n->get('descending') },
|
|
label=>$i18n->get('sort order'),
|
|
hoverHelp=>$i18n->get('sort order description'),
|
|
},
|
|
sortBy =>{
|
|
fieldType=>"selectBox",
|
|
defaultValue=>'assetData.revisionDate',
|
|
tab=>'display',
|
|
options=>\%sortByOptions,
|
|
label=>$i18n->get('sort by'),
|
|
hoverHelp=>$i18n->get('sort by description'),
|
|
},
|
|
notificationTemplateId =>{
|
|
fieldType=>"template",
|
|
namespace=>"Collaboration/Notification",
|
|
defaultValue=>'PBtmpl0000000000000027',
|
|
tab=>'mail',
|
|
label=>$i18n->get('notification template'),
|
|
hoverHelp=>$i18n->get('notification template description'),
|
|
},
|
|
searchTemplateId =>{
|
|
fieldType=>"template",
|
|
namespace=>"Collaboration/Search",
|
|
defaultValue=>'PBtmpl0000000000000031',
|
|
tab=>'display',
|
|
label=>$i18n->get('search template'),
|
|
hoverHelp=>$i18n->get('search template description'),
|
|
},
|
|
postFormTemplateId =>{
|
|
fieldType=>"template",
|
|
namespace=>"Collaboration/PostForm",
|
|
defaultValue=>'PBtmpl0000000000000029',
|
|
tab=>'display',
|
|
label=>$i18n->get('post template'),
|
|
hoverHelp=>$i18n->get('post template description'),
|
|
},
|
|
threadTemplateId =>{
|
|
fieldType=>"template",
|
|
namespace=>"Collaboration/Thread",
|
|
defaultValue=>'PBtmpl0000000000000032',
|
|
tab=>'display',
|
|
label=>$i18n->get('thread template'),
|
|
hoverHelp=>$i18n->get('thread template description'),
|
|
},
|
|
collaborationTemplateId =>{
|
|
fieldType=>"template",
|
|
namespace=>'Collaboration',
|
|
defaultValue=>'PBtmpl0000000000000026',
|
|
tab=>'display',
|
|
label=>$i18n->get('system template'),
|
|
hoverHelp=>$i18n->get('system template description'),
|
|
},
|
|
karmaPerPost =>{
|
|
fieldType=>"integer",
|
|
defaultValue=>0,
|
|
tab=>'properties',
|
|
visible=>$useKarma,
|
|
label=>$i18n->get('karma/post'),
|
|
hoverHelp=>$i18n->get('karma/post description'),
|
|
},
|
|
karmaSpentToRate => {
|
|
fieldType => "integer",
|
|
defaultValue=> 0,
|
|
tab=>'properties',
|
|
visible => $useKarma,
|
|
label => $i18n->get('karma spent to rate'),
|
|
hoverHelp => $i18n->get('karma spent to rate description'),
|
|
},
|
|
karmaRatingMultiplier => {
|
|
fieldType => "integer",
|
|
defaultValue=> 1,
|
|
tab=>'properties',
|
|
visible => $useKarma,
|
|
label=>$i18n->get('karma rating multiplier'),
|
|
hoverHelp=>$i18n->get('karma rating multiplier description'),
|
|
},
|
|
avatarsEnabled =>{
|
|
fieldType=>"yesNo",
|
|
defaultValue=>0,
|
|
tab=>'properties',
|
|
label=>$i18n->get('enable avatars'),
|
|
hoverHelp=>$i18n->get('enable avatars description'),
|
|
},
|
|
enablePostMetaData =>{
|
|
fieldType=>"yesNo",
|
|
defaultValue=>0,
|
|
tab=>'meta',
|
|
label=>$i18n->get('enable metadata'),
|
|
hoverHelp=>$i18n->get('enable metadata description'),
|
|
},
|
|
postGroupId =>{
|
|
fieldType=>"group",
|
|
defaultValue=>'2',
|
|
tab=>'security',
|
|
label=>$i18n->get('who posts'),
|
|
hoverHelp=>$i18n->get('who posts description'),
|
|
},
|
|
canStartThreadGroupId =>{
|
|
fieldType=>"group",
|
|
defaultValue=>'2',
|
|
tab=>'security',
|
|
label=>$i18n->get('who threads'),
|
|
hoverHelp=>$i18n->get('who threads description'),
|
|
},
|
|
defaultKarmaScale => {
|
|
fieldType=>"integer",
|
|
defaultValue=>1,
|
|
tab=>'properties',
|
|
visible=>$useKarma,
|
|
label=>$i18n->get("default karma scale"),
|
|
hoverHelp=>$i18n->get('default karma scale help'),
|
|
},
|
|
useCaptcha => {
|
|
fieldType=>"yesNo",
|
|
defaultValue=>'0',
|
|
tab=>'security',
|
|
label=>$i18n->get('use captcha label'),
|
|
hoverHelp=>$i18n->get('use captcha hover help'),
|
|
},
|
|
subscriptionGroupId =>{
|
|
fieldType=>"subscriptionGroup",
|
|
tab=>'security',
|
|
label=>$i18n->get("subscription group label"),
|
|
hoverHelp=>$i18n->get("subscription group hoverHelp"),
|
|
noFormPost=>1,
|
|
defaultValue=>undef,
|
|
},
|
|
groupToEditPost=>{
|
|
tab=>"security",
|
|
label=>$i18n->get('group to edit label'),
|
|
excludeGroups=>[1,7],
|
|
hoverHelp=>$i18n->get('group to edit hoverhelp'),
|
|
uiLevel=>6,
|
|
fieldType=>'group',
|
|
filter=>'fixId',
|
|
defaultValue=>$groupIdEdit, # groupToEditPost should default to groupIdEdit
|
|
},
|
|
postReceivedTemplateId =>{
|
|
fieldType=>'template',
|
|
namespace=>'Collaboration/PostReceived',
|
|
tab=>'display',
|
|
label=>$i18n->get('post received template'),
|
|
hoverHelp=>$i18n->get('post received template hoverHelp'),
|
|
defaultValue=>'default_post_received1',
|
|
},
|
|
);
|
|
|
|
push(@{$definition}, {
|
|
assetName=>$i18n->get('assetName'),
|
|
autoGenerateForms=>1,
|
|
icon=>'collaboration.gif',
|
|
tableName=>'Collaboration',
|
|
className=>'WebGUI::Asset::Wobject::Collaboration',
|
|
properties=>\%properties,
|
|
});
|
|
return $class->SUPER::definition($session, $definition);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
sub duplicate {
|
|
my $self = shift;
|
|
my $newAsset = $self->SUPER::duplicate(@_);
|
|
$newAsset->createSubscriptionGroup;
|
|
return $newAsset;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getEditTabs
|
|
|
|
Add a tab for the mail interface.
|
|
|
|
=cut
|
|
|
|
sub getEditTabs {
|
|
my $self = shift;
|
|
my $i18n = WebGUI::International->new($self->session,"Asset_Collaboration");
|
|
return ($self->SUPER::getEditTabs(), ['mail', $i18n->get('mail'), 9]);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getNewThreadUrl( )
|
|
|
|
Formats the url to start a new thread.
|
|
|
|
=cut
|
|
|
|
sub getNewThreadUrl {
|
|
my $self = shift;
|
|
$self->getUrl("func=add;class=WebGUI::Asset::Post::Thread");
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
sub getRssItems {
|
|
my $self = shift;
|
|
|
|
# XXX copied and reformatted this query from www_viewRSS, but why is it constructed like this?
|
|
# And it's duplicated inside view, too! Eeeagh! And it uses the versionTag scratch var...
|
|
my ($sortBy, $sortOrder) = ($self->getValue('sortBy'), $self->getValue('sortOrder'));
|
|
|
|
my @postIds = $self->session->db->buildArray(<<"SQL", [$self->getId, $self->session->scratch->get('versionTag')]);
|
|
SELECT asset.assetId
|
|
FROM Thread
|
|
LEFT JOIN asset ON Thread.assetId = asset.assetId
|
|
LEFT JOIN Post ON Post.assetId = Thread.assetId AND Post.revisionDate = Thread.revisionDate
|
|
LEFT JOIN assetData ON assetData.assetId = Thread.assetId
|
|
AND assetData.revisionDate = Thread.revisionDate
|
|
WHERE asset.parentId = ? AND asset.state = 'published' AND asset.className = 'WebGUI::Asset::Post::Thread'
|
|
AND (assetData.status = 'approved' OR assetData.tagId = ?)
|
|
GROUP BY assetData.assetId
|
|
ORDER BY $sortBy $sortOrder
|
|
SQL
|
|
my $siteUrl = $self->session->url->getSiteURL();
|
|
my $datetime = $self->session->datetime;
|
|
|
|
my @posts;
|
|
for my $postId (@postIds) {
|
|
my $post = WebGUI::Asset->new($self->session, $postId, 'WebGUI::Asset::Post::Thread');
|
|
my $postUrl = $siteUrl . $post->getUrl;
|
|
# Buggo: this is an abuse of 'author'. 'author' is supposed to be an email address.
|
|
# But this is how it was in the original Collaboration RSS, so.
|
|
|
|
# Create the attachment template loop
|
|
my $storage = $post->getStorageLocation;
|
|
my $attachmentLoop = [];
|
|
if ($post->get('storageId')) {
|
|
for my $file (@{$storage->getFiles}) {
|
|
push @{$attachmentLoop}, {
|
|
'attachment.url' => $storage->getUrl($file),
|
|
'attachment.path' => $storage->getPath($file),
|
|
'attachment_thumbnail' => $storage->getThumbnailUrl($file),
|
|
'attachment.length' => $storage->getFileSize($file),
|
|
};
|
|
}
|
|
}
|
|
|
|
push @posts, {
|
|
author => $post->get('username'),
|
|
title => $post->get('title'),
|
|
'link' => $postUrl,
|
|
guid => $postUrl,
|
|
description => $post->get('synopsis'),
|
|
epochDate => $post->get('creationDate'),
|
|
pubDate => $datetime->epochToMail($post->get('creationDate')),
|
|
attachmentLoop => $attachmentLoop,
|
|
userDefined1 => $post->get("userDefined1"),
|
|
userDefined2 => $post->get("userDefined2"),
|
|
userDefined3 => $post->get("userDefined3"),
|
|
userDefined4 => $post->get("userDefined4"),
|
|
userDefined5 => $post->get("userDefined5"),
|
|
};
|
|
}
|
|
|
|
return @posts;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getSearchUrl ( )
|
|
|
|
Formats the url to the forum search engine.
|
|
|
|
=cut
|
|
|
|
sub getSearchUrl {
|
|
my $self = shift;
|
|
return $self->getUrl("func=search");
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getSortByUrl ( sortBy )
|
|
|
|
Formats the url to change the default sort.
|
|
|
|
=head3 sortBy
|
|
|
|
The sort by string. Can be views, rating, date replies, or lastreply.
|
|
|
|
=cut
|
|
|
|
sub getSortByUrl {
|
|
my $self = shift;
|
|
my $sortBy = shift;
|
|
return $self->getUrl("sortBy=".$sortBy);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getSortBy
|
|
|
|
Retrieves the field to sort by
|
|
|
|
=cut
|
|
|
|
sub getSortBy {
|
|
my $self = shift;
|
|
my $scratchSortBy = $self->getId."_sortBy";
|
|
my $sortBy = $self->session->scratch->get($scratchSortBy) || $self->getValue("sortBy");
|
|
return $sortBy;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getSortOrder
|
|
|
|
Retrieves the direction to sort in
|
|
|
|
=cut
|
|
|
|
sub getSortOrder {
|
|
my $self = shift;
|
|
my $scratchSortOrder = $self->getId."_sortDir";
|
|
my $sortOrder = $self->session->scratch->get($scratchSortOrder) || $self->getValue("sortOrder");
|
|
return $sortOrder;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getSubscribeUrl ( )
|
|
|
|
Formats the url to subscribe to the forum.
|
|
|
|
=cut
|
|
|
|
sub getSubscribeUrl {
|
|
my $self = shift;
|
|
return $self->getUrl("func=subscribe");
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getThreadsPaginator
|
|
|
|
Returns a WebGUI::Paginator object containing all the threads in this
|
|
Collaboration System
|
|
|
|
=cut
|
|
|
|
sub getThreadsPaginator {
|
|
my $self = shift;
|
|
|
|
my $scratchSortBy = $self->getId."_sortBy";
|
|
my $scratchSortOrder = $self->getId."_sortDir";
|
|
my $sortBy = $self->session->form->process("sortBy") || $self->session->scratch->get($scratchSortBy) || $self->get("sortBy");
|
|
my $sortOrder = $self->session->scratch->get($scratchSortOrder) || $self->get("sortOrder");
|
|
if ($sortBy ne $self->session->scratch->get($scratchSortBy) && $self->session->form->process("func") ne "editSave") {
|
|
$self->session->scratch->set($scratchSortBy,$self->session->form->process("sortBy"));
|
|
} elsif ($self->session->form->process("sortBy") && $self->session->form->process("func") ne "editSave") {
|
|
if ($sortOrder eq "asc") {
|
|
$sortOrder = "desc";
|
|
} else {
|
|
$sortOrder = "asc";
|
|
}
|
|
$self->session->scratch->set($scratchSortOrder, $sortOrder);
|
|
}
|
|
$sortBy ||= "assetData.revisionDate";
|
|
$sortOrder ||= "desc";
|
|
# Sort by the thread rating instead of the post rating. other places don't care about threads.
|
|
if ($sortBy eq 'rating') {
|
|
$sortBy = 'threadRating';
|
|
}
|
|
$sortBy = join('.', map { $self->session->db->dbh->quote_identifier($_) } split(/\./, $sortBy));
|
|
my $sql = "
|
|
select
|
|
asset.assetId,
|
|
asset.className,
|
|
assetData.revisionDate as revisionDate
|
|
from Thread
|
|
left join asset on Thread.assetId=asset.assetId
|
|
left join Post on Post.assetId=Thread.assetId and Thread.revisionDate = Post.revisionDate
|
|
left join assetData on assetData.assetId=Thread.assetId and Thread.revisionDate = assetData.revisionDate
|
|
where
|
|
asset.parentId=".$self->session->db->quote($self->getId)."
|
|
and asset.state='published'
|
|
and asset.className='WebGUI::Asset::Post::Thread'
|
|
and assetData.revisionDate=(
|
|
select
|
|
max(revisionDate)
|
|
from
|
|
assetData
|
|
where
|
|
assetData.assetId=asset.assetId
|
|
and (status='approved' or status='archived')
|
|
)
|
|
and status='approved'
|
|
group by
|
|
assetData.assetId
|
|
order by
|
|
Thread.isSticky desc,
|
|
".$sortBy."
|
|
".$sortOrder;
|
|
my $p = WebGUI::Paginator->new($self->session,$self->getUrl,$self->get("threadsPerPage"));
|
|
$p->setDataByQuery($sql);
|
|
|
|
return $p;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getUnsubscribeUrl ( )
|
|
|
|
Formats the url to unsubscribe from the forum.
|
|
|
|
=cut
|
|
|
|
sub getUnsubscribeUrl {
|
|
my $self = shift;
|
|
return $self->getUrl("func=unsubscribe");
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
sub getViewTemplateVars {
|
|
my $self = shift;
|
|
my %var;
|
|
$var{'user.canPost'} = $self->canPost;
|
|
$var{'user.canStartThread'} = $self->canStartThread;
|
|
$var{"add.url"} = $self->getNewThreadUrl;
|
|
$var{"rss.url"} = $self->getRssUrl;
|
|
$var{'user.isModerator'} = $self->canModerate;
|
|
$var{'user.isVisitor'} = ($self->session->user->isVisitor);
|
|
$var{'user.isSubscribed'} = $self->isSubscribed;
|
|
$var{'sortby.title.url'} = $self->getSortByUrl("title");
|
|
$var{'sortby.username.url'} = $self->getSortByUrl("username");
|
|
$var{'karmaIsEnabled'} = $self->session->setting->get("useKarma");
|
|
$var{'sortby.karmaRank.url'} = $self->getSortByUrl("karmaRank");
|
|
$var{'sortby.date.url'} = $self->getSortByUrl("creationDate");
|
|
$var{'sortby.lastreply.url'} = $self->getSortByUrl("lastPostDate");
|
|
$var{'sortby.views.url'} = $self->getSortByUrl("views");
|
|
$var{'sortby.replies.url'} = $self->getSortByUrl("replies");
|
|
$var{'sortby.rating.url'} = $self->getSortByUrl("rating");
|
|
$var{"search.url"} = $self->getSearchUrl;
|
|
$var{"subscribe.url"} = $self->getSubscribeUrl;
|
|
$var{"unsubscribe.url"} = $self->getUnsubscribeUrl;
|
|
$var{"collaborationAssetId"} = $self->getId;
|
|
|
|
# Get the threads in this CS
|
|
my $p = $self->getThreadsPaginator;
|
|
$self->appendPostListTemplateVars(\%var, $p);
|
|
$self->appendTemplateLabels(\%var);
|
|
|
|
return \%var;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 incrementReplies ( lastPostDate, lastPostId )
|
|
|
|
Increments the reply counter for this forum.
|
|
|
|
=head3 lastPostDate
|
|
|
|
The date of the post being added.
|
|
|
|
=head3 lastPostId
|
|
|
|
The unique identifier of the post being added.
|
|
|
|
=cut
|
|
|
|
sub incrementReplies {
|
|
my ($self, $lastPostDate, $lastPostId) = @_;
|
|
my $threads = $self->_computeThreadCount;
|
|
my $replies = $self->_computePostCount;
|
|
$self->update({replies=>$replies, threads=>$threads, lastPostId=>$lastPostId, lastPostDate=>$lastPostDate});
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 incrementThreads ( lastPostDate, lastPostId )
|
|
|
|
Increments the thread counter for this forum.
|
|
|
|
=head3 lastPostDate
|
|
|
|
The date of the post that was just added.
|
|
|
|
=head3 lastPostId
|
|
|
|
The unique identifier of the post that was just added.
|
|
|
|
=cut
|
|
|
|
sub incrementThreads {
|
|
my ($self, $lastPostDate, $lastPostId) = @_;
|
|
$self->update({threads=>$self->_computeThreadCount, lastPostId=>$lastPostId, lastPostDate=>$lastPostDate});
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 incrementViews ( )
|
|
|
|
Increments the views counter on this forum.
|
|
|
|
=cut
|
|
|
|
sub incrementViews {
|
|
my ($self) = @_;
|
|
$self->update({views=>$self->get("views")+1});
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 isSubscribed ( )
|
|
|
|
Returns a boolean indicating whether the user is subscribed to the forum.
|
|
|
|
=cut
|
|
|
|
sub isSubscribed {
|
|
my $self = shift;
|
|
return $self->session->user->isInGroup($self->get("subscriptionGroupId"));
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 prepareView ( )
|
|
|
|
See WebGUI::Asset::prepareView() for details.
|
|
|
|
=cut
|
|
|
|
sub prepareView {
|
|
my $self = shift;
|
|
$self->SUPER::prepareView();
|
|
my $template = WebGUI::Asset::Template->new($self->session, $self->get("collaborationTemplateId")) or die "no good: ".$self->get("collaborationTemplateId");
|
|
if ($self->get('rssCapableRssEnabled')) {
|
|
$self->session->style->setLink($self->getRssUrl,{ rel=>'alternate', type=>'application/rss+xml', title=>$self->get('title') . ' RSS' });
|
|
}
|
|
$template->prepare($self->getMetaDataAsTemplateVariables);
|
|
$self->{_viewTemplate} = $template;
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
sub processPropertiesFromFormPost {
|
|
my $self = shift;
|
|
my $updatePrivs = ($self->session->form->process("groupIdView") ne $self->get("groupIdView") || $self->session->form->process("groupIdEdit") ne $self->get("groupIdEdit"));
|
|
$self->SUPER::processPropertiesFromFormPost;
|
|
if ($self->get("subscriptionGroupId") eq "") {
|
|
$self->createSubscriptionGroup;
|
|
}
|
|
if ($updatePrivs) {
|
|
foreach my $descendant (@{$self->getLineage(["descendants"],{returnObjects=>1})}) {
|
|
$descendant->update({
|
|
groupIdView=>$self->get("groupIdView"),
|
|
groupIdEdit=>$self->get("groupIdEdit")
|
|
});
|
|
}
|
|
}
|
|
$self->session->scratch->delete($self->getId."_sortBy");
|
|
$self->session->scratch->delete($self->getId."_sortDir");
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
sub purge {
|
|
my $self = shift;
|
|
my $group = WebGUI::Group->new($self->session, $self->get("subscriptionGroupId"));
|
|
if ($group) {
|
|
$group->delete;
|
|
}
|
|
if ($self->get("getMailCronId")) {
|
|
my $cron = WebGUI::Workflow::Cron->new($self->session, $self->get("getMailCronId"));
|
|
$cron->delete if defined $cron;
|
|
}
|
|
$self->SUPER::purge;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 purgeCache ( )
|
|
|
|
See WebGUI::Asset::purgeCache() for details.
|
|
|
|
=cut
|
|
|
|
sub purgeCache {
|
|
my $self = shift;
|
|
WebGUI::Cache->new($self->session,"view_".$self->getId)->delete;
|
|
WebGUI::Cache->new($self->session,$self->_visitorCacheKey)->delete;
|
|
$self->SUPER::purgeCache;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 recalculateRating ( )
|
|
|
|
Calculates the rating of this forum from its threads and stores the new value in the forum properties.
|
|
|
|
=cut
|
|
|
|
sub recalculateRating {
|
|
my $self = shift;
|
|
|
|
# Get the number of threads
|
|
my ($count)
|
|
= $self->session->db->quickArray(
|
|
"select count(*) from Thread
|
|
left join asset on Thread.assetId=asset.assetId
|
|
left join Post on Thread.assetId=Post.assetId
|
|
AND Thread.revisionDate = (SELECT MAX(revisionDate) FROM Thread t WHERE t.assetId=asset.assetId)
|
|
where asset.parentId=?",
|
|
[$self->getId]
|
|
);
|
|
$count = $count || 1;
|
|
|
|
# Get the ratings of all the threads
|
|
my ($sum)
|
|
= $self->session->db->quickArray(
|
|
"SELECT SUM(Thread.threadRating)
|
|
FROM Thread
|
|
LEFT JOIN asset ON Thread.assetId=asset.assetId
|
|
LEFT JOIN Post ON Thread.assetId=Post.assetId
|
|
AND Thread.revisionDate = (SELECT MAX(revisionDate) FROM Thread t WHERE t.assetId=asset.assetId)
|
|
WHERE asset.parentId=?",
|
|
[$self->getId]
|
|
);
|
|
|
|
my $average = round($sum/$count);
|
|
$self->update({rating=>$average});
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 setLastPost ( id, date )
|
|
|
|
Sets the most recent post in this collaboration system.
|
|
|
|
=head3 id
|
|
|
|
The assetId of the most recent post.
|
|
|
|
=head3 date
|
|
|
|
The date of the most recent post.
|
|
|
|
=cut
|
|
|
|
sub setLastPost {
|
|
my $self = shift;
|
|
my $id = shift;
|
|
my $date = shift;
|
|
$self->update({lastPostId=>$id, lastPostDate=>$date});
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 sumReplies ( )
|
|
|
|
Calculates the number of replies to this collaboration system and updates the counter to reflect that. Also updates thread count since it needs to know that to calculate reply count.
|
|
|
|
=cut
|
|
|
|
sub sumReplies {
|
|
my $self = shift;
|
|
my $threads = $self->_computeThreadCount;
|
|
my $replies = $self->_computePostCount;
|
|
$self->update({replies=>$replies, threads=>$threads});
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 sumThreads ( )
|
|
|
|
Calculates the number of threads in this collaboration system and updates the counter to reflect that.
|
|
|
|
=cut
|
|
|
|
sub sumThreads {
|
|
my $self = shift;
|
|
$self->update({threads=>$self->_computeThreadCount});
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 subscribe ( )
|
|
|
|
Subscribes a user to this collaboration system.
|
|
|
|
=cut
|
|
|
|
sub subscribe {
|
|
my $self = shift;
|
|
my $group;
|
|
my $subscriptionGroup = $self->get('subscriptionGroupId');
|
|
if ($subscriptionGroup) {
|
|
$group = WebGUI::Group->new($self->session,$subscriptionGroup);
|
|
}
|
|
if (!$group) {
|
|
$self->createSubscriptionGroup;
|
|
$group = WebGUI::Group->new($self->session,$self->get('subscriptionGroupId'));
|
|
}
|
|
$group->addUsers([$self->session->user->userId]);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 unsubscribe ( )
|
|
|
|
Unsubscribes a user from this collaboration system
|
|
|
|
=cut
|
|
|
|
sub unsubscribe {
|
|
my $self = shift;
|
|
my $group = WebGUI::Group->new($self->session,$self->get("subscriptionGroupId"));
|
|
return
|
|
unless $group;
|
|
$group->deleteUsers([$self->session->user->userId],[$self->get("subscriptionGroupId")]);
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
sub view {
|
|
my $self = shift;
|
|
if ($self->_visitorCacheOk) {
|
|
my $out = WebGUI::Cache->new($self->session,$self->_visitorCacheKey)->get;
|
|
$self->session->errorHandler->debug("HIT") if $out;
|
|
return $out if $out;
|
|
}
|
|
|
|
# If the asset is not called through the normal prepareView/view cycle, first call prepareView.
|
|
# This happens for instance in the viewDetail method in the Matrix. In that case the Collaboration
|
|
# is called through the api.
|
|
$self->prepareView unless ($self->{_viewTemplate});
|
|
my $out = $self->processTemplate($self->getViewTemplateVars,undef,$self->{_viewTemplate});
|
|
if ($self->_visitorCacheOk) {
|
|
WebGUI::Cache->new($self->session,$self->_visitorCacheKey)->set($out,$self->get("visitorCacheTimeout"));
|
|
}
|
|
return $out;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_search ( )
|
|
|
|
The web method to display and use the forum search interface.
|
|
|
|
=cut
|
|
|
|
sub www_search {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my $i18n = WebGUI::International->new($session, 'Asset_Collaboration');
|
|
my $var = {};
|
|
|
|
my $query = $self->session->form->process("query","text");
|
|
$var->{'form.header'} = WebGUI::Form::formHeader($self->session,{
|
|
action=>$self->getUrl("func=search;doit=1")
|
|
});
|
|
$var->{'query.form'} = WebGUI::Form::text($self->session,{
|
|
name => 'query',
|
|
value => $query
|
|
});
|
|
$var->{'form.search'} = WebGUI::Form::submit($self->session,{
|
|
value => $i18n->get(170,'WebGUI')
|
|
});
|
|
$var->{'form.footer'} = WebGUI::Form::formFooter($self->session);
|
|
$var->{'back.url' } = $self->getUrl;
|
|
|
|
$self->appendTemplateLabels($var);
|
|
$var->{'doit' } = $self->session->form->process("doit");
|
|
if ($self->session->form->process("doit")) {
|
|
my $search = WebGUI::Search->new($self->session);
|
|
$search->search({
|
|
keywords=>$query,
|
|
lineage=>[$self->get("lineage")],
|
|
classes=>["WebGUI::Asset::Post", "WebGUI::Asset::Post::Thread"]
|
|
});
|
|
my $p = $search->getPaginatorResultSet($self->getUrl("func=search;doit=1;query=".$query), $self->get("threadsPerPage"));
|
|
$self->appendPostListTemplateVars($var, $p);
|
|
}
|
|
return $self->processStyle($self->processTemplate($var, $self->get("searchTemplateId")));
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_subscribe ( )
|
|
|
|
The web method to subscribe to a collaboration.
|
|
|
|
=cut
|
|
|
|
sub www_subscribe {
|
|
my $self = shift;
|
|
$self->subscribe if $self->canSubscribe;
|
|
return $self->www_view;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_unsubscribe ( )
|
|
|
|
The web method to unsubscribe from a collaboration.
|
|
|
|
=cut
|
|
|
|
sub www_unsubscribe {
|
|
my $self = shift;
|
|
if($self->canSubscribe){
|
|
$self->unsubscribe;
|
|
return $self->www_view;
|
|
}else{
|
|
return $self->session->privilege->noAccess;
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
sub www_view {
|
|
my $self = shift;
|
|
my $disableCache = ($self->session->form->process("sortBy") ne "");
|
|
$self->session->http->setCacheControl($self->get("visitorCacheTimeout")) if ($self->session->user->isVisitor && !$disableCache);
|
|
return $self->SUPER::www_view(@_);
|
|
}
|
|
|
|
1;
|
|
|