migrating uss and forum to collaboration

This commit is contained in:
JT Smith 2005-02-11 17:03:45 +00:00
parent 4dd121e634
commit 2abe8c078c
9 changed files with 1116 additions and 1663 deletions

View file

@ -45,6 +45,7 @@
- bugfix [ 991070 ] 5.5.4 Editor(s) replacing ^ symbol
- bugfix [ 1022287 ] WYSIWYG-Editor Add new web link
- bugfix [ 1055153 ] Turn Admin ON with SSL and IE.
- fix [ 1118753 ] GUID not displayed in 6.2.9 if it begins with "-".
- RFE [ 1034549 ] Docu für Encrypt Pag
- Added internationalized URL handling.
- Moved site icon and fav icon directly into style templates.

View file

@ -59,6 +59,16 @@ save you many hours of grief.
* If you have any custom code, please check out docs/migration.txt as
there have been many changes to the API in this release.
* There are many new components in this release, and as a result many
tables. Here is a list of the new tables. Make sure you have no
plug-ins installed that conflict with this, or tables you've
created for your own uses: Collaboration, Post, Thread,
Post_rating, Post_read, Folder, FileAsset, ITransact_recurringStatus,
ImageAsset, Layout, Shortcut, asset, assetHistory, commerceSettings,
redirect, shoppingCart, snippet, subscription, subscriptionCode,
subscriptionCodeBatch, subscriptionCodeSubscriptions, transaction,
transactionItem
6.2.10
--------------------------------------------------------------------

View file

@ -255,9 +255,7 @@ create table Collaboration (
karmaPerPost int not null default 0,
collaborationTemplateId varchar(22) not null,
threadTemplateId varchar(22) not null,
postTemplateId varchar(22) not null,
postFormTemplateId varchar(22) not null,
postPreviewTemplateId varchar(22) not null,
searchTemplateId varchar(22) not null,
notificationTemplateId varchar(22) not null,
sortBy varchar(35) not null default 'dateUpdated',
@ -278,19 +276,18 @@ create table Collaboration (
archiveAfter int not null default 31536000,
postsPerPage int not null default 10,
threadsPerPage int not null default 30,
subscriptionGroupId varchar(22)
subscriptionGroupId varchar(22),
allowReplies int not null default 0
);
create table Thread (
assetId varchar(22) not null primary key,
views int not null default 0,
replies int not null default 0,
lastPostId varchar(22) not null default 0,
lastPostDate bigint,
isLocked int not null default 0,
isSticky int not null default 0,
status varchar(30) not null default 'approved',
rating int not null default 0
subscriptionGroupId varchar(22)
);
create table Post (

View file

@ -30,7 +30,6 @@ use WebGUI::Paginator;
use WebGUI::Privilege;
use WebGUI::Session;
use WebGUI::SQL;
use WebGUI::Style;
use WebGUI::URL;
use WebGUI::User;
use WebGUI::Utility;
@ -154,21 +153,32 @@ sub definition {
sub DESTROY {
my $self = shift;
$self->{_thread}->DESTROY if (exists $self->{_thread});
$self->SUPER::DESTROY;
}
#-------------------------------------------------------------------
=head2 formatContent ( )
=head2 formatContent ( [ content, contentType ])
Formats post content for display.
=head3 content
The content to format. Defaults to the content in this post.
=head3 contentType
The content type to use for formatting. Defaults to the content type specified in this post.
=cut
sub formatContent {
my $self = shift;
my $msg = WebGUI::HTML::filter($self->get("content"),$self->getThread->getParent->get("filterCode"));
$msg = WebGUI::HTML::format($msg, $self->get("contentType"));
my $content = shift || $self->get("content");
my $contentType = shift || $self->get("contentType");
my $msg = WebGUI::HTML::filter($content,$self->getThread->getParent->get("filterCode"));
$msg = WebGUI::HTML::format($msg, $contentType));
if ($self->getThread->getParent->get("useContentFilter")) {
$msg = WebGUI::HTML::processReplacements($msg);
}
@ -289,82 +299,64 @@ sub getReplyUrl {
return $self->getUrl("func=add&class=WebGUI::Asset::Post&withQuote=".$withQuote);
}
#-------------------------------------------------------------------
sub getStatus {
my $self = shift;
my $status = $self->get("status");
if ($status eq "approved") {
return "Approved";
} elsif ($status eq "denied") {
return "Denied";
} elsif ($status eq "pending") {
return "Pending";
}
}
#-------------------------------------------------------------------
sub getSynopsisAndContentFromFormPost {
my $self = shift;
my $synopsis = $session{form}{synopsis};
my $body = $session{form}{content};
unless ($synopsis) {
$body =~ s/\n/\^\-\;/ unless ($body =~ m/\^\-\;/);
my @content = split(/\^\-\;/,$body);
$synopsis = WebGUI::HTML::filter($content[0],"none");
}
$body =~ s/\^\-\;/\n/;
return ($synopsis,$content);
}
#-------------------------------------------------------------------
sub getTemplateVars {
my $self = shift;
my %var;
#my $callback = WebGUI::URL::gateway($parentsPage->get("urlizedTitle"),"func=viewSubmission&wid=".$self->wid."&sid=".$submission->{USS_submissionId});
# if ($session{form}{forumOp} ne "" && $session{form}{forumOp} ne "viewForum") {
# return WebGUI::Forum::UI::forumOp({
# callback=>$callback,
# title=>$submission->{title},
# forumId=>$submission->{forumId}
# });
# }
$self->update({views=>$self->get("views")+1});
$var{content} = WebGUI::HTML::filter($self->get("content"),$self->get("filterContent"));
$var{content} = WebGUI::HTML::format($var{content},"USS");
$var{"user.label"} = WebGUI::International::get(21,"USS");
$var{"userProfile.url"} = $self->getUrl('op=viewProfile&uid='.$self->get("ownerUserId"));
$var{"userId"} = $self->get("ownerUserId");
$var{"username"} = $self->get("username");
$var{"dateSubmitted.label"} = WebGUI::International::get(13,"USS");
$var{"dateSubmitted.human"} = epochToHuman($self->get("dateSubmitted"));
$var{"dateUpdated.label"} = WebGUI::International::get(78,"USS");
$var{"dateUpdated.human"} = epochToHuman($self->get("dateUpdated"));
$var{"status.label"} = WebGUI::International::get(14,"USS");
$var{"status.status"} = $self->getParent->status($self->get("status"));
$var{"views.label"} = WebGUI::International::get(514);
$var{canPost} = $self->canContribute;
$var{"post.url"} = $self->getUrl("func=edit");
$var{"post.label"} = WebGUI::International::get(20,"USS");
my $previous = WebGUI::Asset::Post->newByPropertyHashRef(
WebGUI::SQL->quickHashRef("
select asset.*,Post.*
from Thread
left join asset on asset.parentId=Thread.assetId
left join Post on Post.assetId=asset.assetId
where Thread.parentId=".quote($self->get("parentId"))."
and asset.state='published'
and ".$self->getParent->getValue("sortBy")."<".quote($self->get($self->getParent->getValue("sortBy")))."
and (userId=".quote($self->get("ownerUserId"))." or Post.status='approved')
order by ".$self->getParent->getValue("sortBy")." desc
",WebGUI::SQL->getSlave)
);
$var{"previous.more"} = defined $previous;
$var{"previous.url"} = $previous->getUrl if ($var{"previous.more"});
$var{"previous.label"} = WebGUI::International::get(58,"USS");
my $next = WebGUI::Asset::Post->newByPropertyHashRef(
WebGUI::SQL->quickHashRef("
select asset.*,Post.*
from Thread
left join asset on asset.parentId=Thread.assetId
left join Post on Post.assetId=asset.assetId
where Thread.parentId=".quote($self->get("parentId"))."
and asset.state='published'
and ".$self->getParent->getValue("sortBy").">".quote($self->get($self->getParent->getValue("sortBy")))."
and (userId=".quote($self->get("ownerUserId"))." or Post.status='approved')
order by ".$self->getParent->getValue("sortBy")." asc
",WebGUI::SQL->getSlave)
);
$var{"next.more"} = defined $next;
$var{"next.url"} = $next->getUrl if ($var{"next.more"});
$var{"next.label"} = WebGUI::International::get(59,"USS");
$var{content} = $self->formatContent;
$var{canEdit} = $self->canEdit;
$var{"delete.url"} = $self->getUrl("func=delete");
$var{"delete.label"} = WebGUI::International::get(37,"USS");
$var{"edit.url"} = $self->getUrl("func=edit");
$var{"edit.label"} = WebGUI::International::get(27,"USS");
$var{canChangeStatus} = $self->canModerate;
$var{"approve.url"} = $self->getUrl("func=approve&mlog=".$session{form}{mlog});
$var{"approve.label"} = WebGUI::International::get(572);
$var{"leave.url"} = $self->getUrl('op=viewMessageLog');
$var{"leave.label"} = WebGUI::International::get(573);
$var{"deny.url"} = $self->getUrl("func=deny&mlog=".$session{form}{mlog});
$var{"deny.label"} = WebGUI::International::get(574);
$var{"canReply"} = $self->get("allowDiscussion");
# $var{"reply.url"} = WebGUI::Forum::UI::formatNewThreadURL($callback,$submission->{forumId});
# $var{"reply.label"} = WebGUI::International::get(47,"USS");
$var{"delete.url"} = $self->getDeleteUrl;
$var{"edit.url"} = $self->getEditUrl;
$var{"status"} = $self->getStatus;
$var{"approve.url"} = $self->getApproveUrl;
$var{"deny.url"} = $self->getDenyUrl;
$var{"reply.url"} = $self->getReplyUrl;
$var{'reply.withquote.url'} = $self->getReplyUrl(1);
$var{'url'} = WebGUI::URL::getSiteURL().$self->getUrl;
$var{'rating.value'} = $self->get("rating")+0;
$var{'rate.url.1'} = $self->getRateUrl(1);
$var{'rate.url.2'} = $self->getRateUrl(2);
$var{'rate.url.3'} = $self->getRateUrl(3);
$var{'rate.url.4'} = $self->getRateUrl(4);
$var{'rate.url.5'} = $self->getRateUrl(5);
$var{'hasRated'} = $self->hasRated;
# if ($submission->{image} ne "") {
# $file = WebGUI::Attachment->new($submission->{image},$self->wid,$submissionId);
# $var{"image.url"} = $file->getURL;
@ -377,11 +369,6 @@ sub getTemplateVars {
# $var{"attachment.icon"} = $file->getIcon;
# $var{"attachment.name"} = $file->getFilename;
# }
if ($self->get("allowDiscussion")) {
# $var{"replies"} = WebGUI::Forum::UI::www_viewForum(
# {callback=>$callback,title=>$submission->{title},forumId=>$submission->{forumId}},
# $submission->{forumId});
}
}
#-------------------------------------------------------------------
@ -422,7 +409,6 @@ Increments the views counter for this post.
sub incrementViews {
my ($self) = @_;
$self->update({views=>$self->get("views")+1});
$self->getThread->incrementViews;
}
#-------------------------------------------------------------------
@ -458,27 +444,13 @@ sub isPoster {
=head2 isReply ( )
Returns a boolean indicating whether this post is a reply. This is the opposite of isRootPost().
Returns a boolean indicating whether this post is a reply.
=cut
sub isReply {
my $self = shift;
return !$self->isRootPost;
}
#-------------------------------------------------------------------
=head2 isRootPost ( )
Returns a boolean indicating that this post is the root post in the thread. This is the opposite of isReply().
=cut
sub isReply {
my $self = shift;
return $self->get("parentId") eq $self->get("threadId");
return $self->getId ne $self->get("threadId");
}
@ -535,24 +507,32 @@ sub notifySubscribers {
sub processPropertiesFromFormPost {
my $self = shift;
$self->SUPER::processPropertiesFromFormPost;
if ($session{form}{assetId} eq "new" && $session{setting}{enableKarma} && $self->getThread->getParent->get("karmaPerPost")) {
my $u = WebGUI::User->new($session{user}{userId});
$u->addKarma($self->getThread->getParent->get("karmaPerPost"), $self->getId, "Collaboration post");
}
my %data = (
ownerUserId => $session{user}{userId},
groupIdView => $self->getThread->get("groupIdView"),
groupIdEdit => $self->getThread->get("groupIdEdit")
);
$data{startDate} = $self->getThread->get("startDate") unless ($session{form}{startDate});
$data{endDate} = $self->getThread->get("endDate") unless ($session{form}{endDate});
unless ($session{form}{synopsis}) {
my $body = $session{form}{content};
$body =~ s/\n/\^\-\;/ unless ($body =~ m/\^\-\;/);
my @content = split(/\^\-\;/,$body);
$content[0] = WebGUI::HTML::filter($content[0],"none");
$data{synopsis} = $content[0];
$body =~ s/\^\-\;/\n/;
$data{content} = $body;
}
$data{startDate} = $self->getThread-getParent->get("startDate") unless ($session{form}{startDate});
$data{endDate} = $self->getThread-getParent->get("endDate") unless ($session{form}{endDate});
($data{synopsis}, $data{content}) = $self->getSynopsisAndContentFromFormPost;
if ($self->getThread->getParent->get("addEditStampToPosts")) {
$data{content} .= "<p>\n\n --- (Edited on ".WebGUI::DateTime::epochToHuman()." by ".$session{user}{alias}.") --- \n</p>";
}
$data{isHidden} = 1;
$self->update(\%data);
$self->getThread->subscribe if ($session{form}{subscribe});
$self->getThread->lock if ($session{form}{'lock'});
$self->getThread->stick if ($session{form}{stick});
if ($self->getThread->getParent->get("moderatePosts")) {
$self->setStatusPending;
} else {
$self->setStatusApproved;
}
$session{form}{proceed} = "redirectToParent";
}
@ -575,46 +555,15 @@ sub rate {
WebGUI::SQL->write("insert into Post_rating (assetId,userId,ipAddress,dateOfRating,rating) values ("
.quote($self->getId).", ".quote($session{user}{userId}).", ".quote($session{env}{REMOTE_ADDR}).",
".WebGUI::DateTime::time().", $rating)");
$self->recalculateRating;
my ($count) = WebGUI::SQL->quickArray("select count(*) from Post_rating where postId=".quote($self->getId));
$count = $count || 1;
my ($sum) = WebGUI::SQL->quickArray("select sum(rating) from Post_rating where postId=".quote($self->getId));
my $average = round($sum/$count);
$self->update({rating=>$average});
$self->getThread->rate;
}
}
#-------------------------------------------------------------------
=head2 recalculateRating ( )
Recalculates the average rating of the post from all the ratings and stores the result to the database.
=cut
sub recalculateRating {
my ($self) = @_;
my ($count) = WebGUI::SQL->quickArray("select count(*) from Post_rating where postId=".quote($self->getId));
$count = $count || 1;
my ($sum) = WebGUI::SQL->quickArray("select sum(rating) from Post_rating where postId=".quote($self->getId));
my $average = round($sum/$count);
$self->update({rating=>$average});
$self->getThread->recalculateRating;
}
#-------------------------------------------------------------------
=head2 setDefaultStatus ( )
Sets a new post's status based upon forum settings.
=cut
sub setDefaultStatus {
my $self = shift;
if ($self->getThread->getParent->get("moderatePosts")) {
$self->setStatusPending;
} else {
$self->setStatusApproved;
}
}
#-------------------------------------------------------------------
@ -627,7 +576,6 @@ Sets the post to approved and sends any necessary notifications.
sub setStatusApproved {
my $self
$self->update({status=>'approved'});
$self->getThread->setStatusApproved if $self->isRootPost;
$self->getThread->incrementReplies($self->get("dateUpdated"),$self->getId) if $self->isReply;
unless ($self->isPoster) {
WebGUI::MessageLog::addInternationalizedEntry($self->get("ownerUserId"),'',$self->getUrl,579);
@ -649,7 +597,6 @@ Sets the status of this post to archived.
sub setStatusArchived {
my ($self) = @_;
$self->update({status=>'archived'});
$self->getThread->setStatusArchived if $self->isRootPost;
}
@ -664,7 +611,6 @@ Sets the status of this post to denied.
sub setStatusDenied {
my ($self) = @_;
$self->update({status=>'denied'});
$self->getThread->setStatusDenied if $self->isRootPost;
WebGUI::MessageLog::addInternationalizedEntry($self->get("ownerUserId"),'',$self->getUrl,580);
}
@ -679,7 +625,6 @@ Sets the status of this post to pending.
sub setStatusPending {
my ($self) = @_;
$self->update({status=>'pending'});
$self->getThread->setStatusPending if $self->isRootPost;
WebGUI::MessageLog::addInternationalizedEntry('',$self->getThread->getParent->get("moderateGroupId"),
$self->getUrl,578,'WebGUI','pending');
}
@ -698,6 +643,16 @@ sub unmarkRead {
WebGUI::SQL->write("delete from forumRead where userId=".quote($session{user}{userId})." and postId=".quote($self->getId));
}
#-------------------------------------------------------------------
sub view {
my $self = shift;
$self->markRead;
$self->incrementViews;
return $self->getThread->view;
}
#-------------------------------------------------------------------
=head2 www_approve ( )
@ -729,26 +684,16 @@ sub www_deny {
#-------------------------------------------------------------------
sub www_edit {
my $self = shift;
return WebGUI::Privilege::insufficient() unless ($self->canEdit);
my %var;
if ($session{form}{func} eq "add") {
$self->{_properties}{contentType} = "mixed";
$var{'isNew'} = 1;
}
$var{'link.header.label'} = WebGUI::International::get(90,"USS");
$var{'question.header.label'} = WebGUI::International::get(84,"USS");
$var{'submission.header.label'} = WebGUI::International::get(19,"USS");
$var{'user.isVisitor'} = ($session{user}{userId} eq '1');
$var{'visitorName.label'} = WebGUI::International::get(438);
$var{'visitorName.form'} = WebGUI::Form::text({
name=>"visitorName"
});
$var{'form.header'} = WebGUI::Form::formHeader()
my %var = %{$self->getTemplateVars};
$var{'form.header'} = WebGUI::Form::formHeader({action=>$self->getUrl})
.WebGUI::Form::hidden({
name=>"func",
value=>"editSave"
value=>"add"
});
if ($self->getId eq "new") {
my $content;
my $title;
if ($session{form}{func} eq "add") { # new post
$var{'isNewPost'} = 1;
$var{'form.header'} .= WebGUI::Form::hidden({
name=>"assetId",
value=>"new"
@ -756,49 +701,102 @@ sub www_edit {
name=>"class",
value=>$session{form}{class}
});
if ($self->getThread->getParent->canModerate) {
$var->{'lock.form'} = WebGUI::Form::yesNo({
name=>'lock',
value=>$session{form}{'lock'}
});
}
if ($session{form}{className} eq "WebGUI::Asset::Post") { # new reply
return $self->getThread->getParent->processStyle(WebGUI::Privilege::insufficient()) unless ($self->canReply);
$var{isReply} = 1;
if ($session{form}{content} || $session{form}{title}) {
$content = $session{form}{content};
$title = $session{form}{title};
} else {
$content = "[quote]".$self->getParent->get("content")."[/quote]" if ($session{form}{withQuote});
$title = $self->getParent->get("subject");
$title = "Re: ".$title unless ($title =~ /^Re:/);
}
$var{'subscribe.form'} = WebGUI::Form::yesNo({
name=>"subscribe",
value=>$session{form}{subscribe}
});
} elsif ($session{form}{className} eq "WebGUI::Asset::Post::Thread") { # new thread
return $self->getThread->getParent->processStyle(WebGUI::Privilege::insufficient()) unless ($self->getThread->getParent->canPost);
$var{isNewThread} = 1;
if ($self->getThread->getParent->canModerate) {
$var{'sticky.form'} = WebGUI::Form::yesNo({
name=>'stick',
value=>$session{form}{stick}
});
}
$var{'subscribe.form'} = WebGUI::Form::yesNo({
name=>"subscribe",
value=>$session{form}{subscribe} || 1
});
}
$content .= "\n\n".$session{user}{signature} if ($session{user}{signature});
} else { # edit
return $self->getThread->getParent->processStyle(WebGUI::Privilege::insufficient()) unless ($self->canEdit);
$var{isEdit} = 1;
$content = $self->getValue("content");
$title = $self->getValue("title");
}
$var{'url.label'} = WebGUI::International::get(91,"USS");
$var{'newWindow.label'} = WebGUI::International::get(92,"USS");
if ($session{form}{title} || $session{form}{content} || $session{form}{synopsis}) {
$var{'preview.title'} = WebGUI::HTML::filter($session{form}{title},"none");
($var{'preview.synopsis'}, $var{'preview.content'}) = $self->getSynopsisAndContentFromFormPost;
$var{'preview.content'} = $self->formatContent($var{'preview.content'},$session{form}{contentType});
}
$var{'form.preview'} = WebGUI::Form::submit({value=>"Preview"});
$var{'form.submit'} = WebGUI::Form::button({
value=>"Save",
onclick=>"this.value='Please wait...'; this.form.func.value='editSave'; this.form.submit();"
});
$var{'form.footer'} = WebGUI::Form::formFooter();
$var{usePreview} = $self->getThread->getParent->get("usePreview")) {
$var{'user.isVisitor'} = ($session{user}{userId} eq '1');
$var{'visitorName.form'} = WebGUI::Form::text({
name=>"visitorName",
value=>$self->getValue("visitorName")
});
for my $x (1..5) {
$var{'userDefined'.$x.'.form'} = WebGUI::Form::text({
name=>"userDefined".$x,
value=>$self->get("userDefined".$x)
value=>$self->getValue("userDefined".$x)
});
$var{'userDefined'.$x.'.form.yesNo'} = WebGUI::Form::yesNo({
name=>"userDefined".$x,
value=>$self->get("userDefined".$x)
value=>$self->getValue("userDefined".$x)
});
$var{'userDefined'.$x.'.form.textarea'} = WebGUI::Form::textarea({
name=>"userDefined".$x,
value=>$self->get("userDefined".$x)
value=>$self->getValue("userDefined".$x)
});
$var{'userDefined'.$x.'.form.textarea'} = WebGUI::Form::HTMLArea({
name=>"userDefined".$x,
value=>$self->get("userDefined".$x)
value=>$self->getValue("userDefined".$x)
});
}
$var{'question.label'} = WebGUI::International::get(85,"USS");
$var{'title.label'} = WebGUI::International::get(35,"USS");
$var{'title.form'} = WebGUI::Form::text({
name=>"title",
value=>$self->get("title")
value=>$title
});
$var{'title.form.textarea'} = WebGUI::Form::textarea({
name=>"title",
value=>$self->get("title")
value=>$title
});
$var{'body.label'} = WebGUI::International::get(31,"USS");
$var{'answer.label'} = WebGUI::International::get(86,"USS");
$var{'description.label'} = WebGUI::International::get(85);
$var{'contet.form'} = WebGUI::Form::HTMLArea({
name=>"content",
value=>$self->get("content")
});
$var{'content.form.textarea'} = WebGUI::Form::textarea({
name=>"content",
value=>$self->get("content")
});
# $var{'image.label'} = WebGUI::International::get(32,"USS");
if ($self->getThread->getParent->get("allowRichEdit")) {
$var{'content.form'} = WebGUI::Form::HTMLArea({
name=>"content",
value=>$content
});
} else {
$var{'content.form'} = WebGUI::Form::textarea({
name=>"content",
value=>$content
});
}
# if ($submission->{image} ne "") {
# $var{'image.form'} = '<a href="'.WebGUI::URL::page('func=deleteFile&amp;file=image&amp;wid='.$session{form}{wid}
# .'&amp;sid='.$submission->{USS_submissionId}).'">'.WebGUI::International::get(391).'</a>';
@ -807,7 +805,6 @@ sub www_edit {
# name=>"image"
# });
# }
# $var{'attachment.label'} = WebGUI::International::get(33,"USS");
# if ($submission->{attachment} ne "") {
# $var{'attachment.form'} = '<a href="'.WebGUI::URL::page('func=deleteFile&amp;file=attachment&amp;wid='
# .$session{form}{wid}.'&amp;sid='.$submission->{USS_submissionId}).'">'.WebGUI::International::get(391).'</a>';
@ -816,291 +813,22 @@ sub www_edit {
# name=>"attachment"
# });
# }
$var{'contentType.label'} = WebGUI::International::get(1007);
$var{'contentType.form'} = WebGUI::Form::contentType({
name=>'contentType',
value=>$self->get("contentType") || "mixed"
value=>$self->getValue("contentType") || "mixed"
});
$var{'startDate.label'} = WebGUI::International::get(497);
$var{'endDate.label'} = WebGUI::International::get(498);
$var{'startDate.form'} = WebGUI::Form::dateTime({
name => 'startDate',
value => $self->get("startDate")
value => $self->getValue("startDate")
});
$var{'endDate.form'} = WebGUI::Form::dateTime({
name => 'endDate',
value => $self->get("startDate")
value => $self->getValue("startDate")
});
$var{'form.submit'} = WebGUI::Form::submit();
$var{'form.footer'} = WebGUI::Form::formFooter();
$self->getThread->getParent->appendTemplateLabels(\%var);
return $self->getParent->processStyle($self->processTemplate(\%var,$self->getParent->get("submissionFormTemplateId")));
}
#-------------------------------------------------------------------
=head2 www_post ( caller )
The web method to display the post form.
=head3 caller
A hash reference containing information passed from the calling object.
=cut
sub www_post {
my ($caller) = @_;
my ($subject, $message, $forum);
my $var;
$var->{'newpost.header'} = WebGUI::International::get(1064);
$var->{'newpost.isReply'} = ($session{form}{parentId} ne "");
$var->{'newpost.isEdit'} = ($session{form}{forumPostId} ne "");
$var->{'newpost.isNewThread'} = ($session{form}{parentId} eq "" && !$var->{'newpost.isEdit'});
$var->{'user.isVisitor'} = ($session{user}{userId} eq '1');
$var->{'newpost.isNewMessage'} = ($var->{'newpost.isNewThread'} || $var->{'newpost.isReply'});
$var->{'form.begin'} = WebGUI::Form::formHeader({
action=>$caller->{callback}
});
my $defaultSubscribeValue = 0;
my $contentType = "mixed";
if ($var->{'newpost.isReply'}) {
my $reply = WebGUI::Forum::Post->new($session{form}{parentId});
return WebGUI::Privilege::insufficient() unless ($reply->getThread->getForum->canPost);
$var->{'form.begin'} .= WebGUI::Form::hidden({
name=>'parentId',
value=>$reply->get("forumPostId")
});
$forum = $reply->getThread->getForum;
$var->{'form.begin'} .= WebGUI::Form::hidden({
name=>'forumId',
value=>$forum->get("forumId")
});
$message = "[quote]".$reply->get("message")."[/quote]" if ($session{form}{withQuote});
$var = getPostTemplateVars($reply, $reply->getThread, $forum, $caller, $var);
$subject = $reply->get("subject");
$subject = "Re: ".$subject unless ($subject =~ /^Re:/);
}
if ($var->{'newpost.isNewThread'}) {
$var->{'form.begin'} .= WebGUI::Form::hidden({
name=>'forumId',
value=>$session{form}{forumId}
});
$forum = WebGUI::Forum->new($session{form}{forumId});
if ($forum->isModerator) {
$var->{'sticky.label'} = WebGUI::International::get(1013);
$var->{'sticky.form'} = WebGUI::Form::yesNo({
name=>'isSticky',
value=>0
});
}
$defaultSubscribeValue = 1 unless ($forum->isSubscribed);
}
if ($var->{'newpost.isNewMessage'}) {
$var->{'subscribe.label'} = WebGUI::International::get(873);
return WebGUI::Privilege::insufficient() unless ($forum->canPost);
my $u = WebGUI::User->new($session{user}{userId});
$u->karma($forum->get("karmaPerPost"),"Forum (".$forum->get("forumId").")","Forum Post") if ($session{setting}{useKarma});
if ($forum->isModerator) {
$var->{'lock.label'} = WebGUI::International::get(1012);
$var->{'lock.form'} = WebGUI::Form::yesNo({
name=>'isLocked',
value=>0
});
}
$var->{'subscribe.form'} = WebGUI::Form::yesNo({
name=>'subscribe',
value=>$defaultSubscribeValue
});
$message .= "\n\n".$session{user}{signature} if ($session{user}{signature});
}
if ($var->{'newpost.isEdit'}) {
my $post = WebGUI::Forum::Post->new($session{form}{forumPostId});
return WebGUI::Privilege::insufficient() unless ($post->getThread->getForum->canPost);
$subject = $post->get("subject");
$message = $post->get("message");
$forum = $post->getThread->getForum;
$var->{'form.begin'} .= WebGUI::Form::hidden({
name=>"forumPostId",
value=>$post->get("forumPostId")
});
$contentType = $post->get("contentType");
}
$var->{'contentType.label'} = WebGUI::International::get(1007);
$var->{'contentType.form'} = WebGUI::Form::contentType({
name=>'contentType',
value=>[$contentType]
});
$var->{'user.isModerator'} = $forum->isModerator;
$var->{allowReplacements} = $forum->get("allowReplacements");
if ($forum->get("allowRichEdit")) {
$var->{'message.form'} = WebGUI::Form::HTMLArea({
name=>'message',
value=>$message
});
} else {
$var->{'message.form'} = WebGUI::Form::textarea({
name=>'message',
value=>$message
});
}
$var->{'message.label'} = WebGUI::International::get(230);
if ($var->{'user.isVisitor'}) {
$var->{'visitorName.label'} = WebGUI::International::get(438);
$var->{'visitorName.form'} = WebGUI::Form::text({
name=>'visitorName'
});
}
my $forumOp = ($forum->get("usePreview"))? "postPreview" : "postSave";
$var->{'form.begin'} .= WebGUI::Form::hidden({
name=>'forumOp',
value=>$forumOp
});
$var->{'form.submit'} = WebGUI::Form::submit();
$var->{'subject.label'} = WebGUI::International::get(229);
$var->{'subject.form'} = WebGUI::Form::text({
name=>'subject',
value=>$subject
});
$var->{'form.end'} = WebGUI::Form::formFooter();
return WebGUI::Template::process($forum->get("postformTemplateId"),"Forum/PostForm", $var);
}
#-------------------------------------------------------------------
=head2 www_postPreview ( caller )
The web method to generate a preview of a posting.
=head3 caller
A hash reference containing information passed from the calling object.
=cut
sub www_postPreview {
my ($caller) = @_;
my $forumId = $session{form}{forumId};
my $threadId = $session{form}{forumThreadId};
my $postId = $session{form}{forumPostId};
my $subject = $session{form}{subject};
$subject = WebGUI::International::get(232) if ($subject eq "");
$subject .= ' '.WebGUI::International::get(233) if ($session{form}{message} eq "");
if ( $subject ne "") { # subjects could never contain anything other than text
$subject = WebGUI::HTML::filter(WebGUI::HTML::processReplacements($subject),"all");
}
my $newPost = WebGUI::Forum::Post->new();
$newPost->{_properties}->{message} = $session{form}{message};
$newPost->{_properties}->{subject} = $subject;
$newPost->{_properties}->{contentType} = $session{form}{contentType};
$newPost->{_properties}->{userId} = $session{user}{userId};
$newPost->{_properties}->{username} = ($session{form}{visitorName} || $session{user}{alias});
$newPost->{_properties}->{dateUpdated} = WebGUI::DateTime::time();
my $forum = WebGUI::Forum->new($forumId);
my $var = getPostTemplateVars($newPost, WebGUI::Forum::Thread->new($threadId), WebGUI::Forum->new($forumId), $caller);
$var->{'newpost.header'} = WebGUI::International::get('Forum, Preview Heading');
$var->{'form.begin'} = WebGUI::Form::formHeader({
action=>$caller->{callback}
});
$var->{'form.begin'} .= WebGUI::Form::hidden({name=>'forumId', value=>$forumId});
$var->{'form.begin'} .= WebGUI::Form::hidden({name=>'forumThreadId', value=>$threadId});
$var->{'form.begin'} .= WebGUI::Form::hidden({name=>'forumPostId', value=>$postId});
$var->{'form.begin'} .= WebGUI::Form::hidden({name=>'parentId', value=>$session{form}{parentId}});
$var->{'form.begin'} .= WebGUI::Form::hidden({name=>'subject', value=>$subject});
$var->{'form.begin'} .= WebGUI::Form::hidden({name=>'message', value=>$session{form}{message}});
$var->{'form.begin'} .= WebGUI::Form::hidden({name=>'contentType', value=>$session{form}{contentType}});
$var->{'form.begin'} .= WebGUI::Form::hidden({name=>'visitorName', value=>$session{form}{visitorName}});
$var->{'form.begin'} .= WebGUI::Form::hidden({name=>'subscribe', value=>$session{form}{subscribe}});
$var->{'form.begin'} .= WebGUI::Form::hidden({name=>'isLocked', value=>$session{form}{isLocked}});
$var->{'form.begin'} .= WebGUI::Form::hidden({name=>'isSticky', value=>$session{form}{isSticky}});
$var->{'form.begin'} .= WebGUI::Form::hidden({name=>'forumOp', value=>"postSave"});
$var->{'form.submit'} = WebGUI::Form::submit();
$var->{'form.end'} = WebGUI::Form::formFooter();
return WebGUI::Template::process($forum->get("postPreviewTemplateId"),"Forum/PostPreview", $var);
}
#-------------------------------------------------------------------
=head2 www_postSave ( caller )
The web method to save the data from the post form.
=head3 caller
A hash reference containing information passed from the calling object.
=cut
sub www_postSave {
my ($caller) = @_;
my $forumId = $session{form}{forumId};
my $threadId = $session{form}{forumThreadId};
my $postId = $session{form}{forumPostId};
my $subject = $session{form}{subject};
$subject = WebGUI::International::get(232) if ($subject eq "");
$subject .= ' '.WebGUI::International::get(233) if ($session{form}{message} eq "");
if ( $subject ne "") { # subjects could never contain anything other than text
$subject = WebGUI::HTML::filter(WebGUI::HTML::processReplacements($subject),"all");
}
my %postData = (
message=>$session{form}{message},
subject=>$subject,
contentType=>$session{form}{contentType}
);
my %postDataNew = (
userId=>$session{user}{userId},
username=>($session{form}{visitorName} || $session{user}{alias})
);
if ($session{form}{parentId} ne '') { # reply
%postData = (%postData, %postDataNew);
my $parentPost = WebGUI::Forum::Post->new($session{form}{parentId});
return WebGUI::Privilege::insufficient() unless ($parentPost->getThread->getForum->canPost);
$parentPost->getThread->subscribe($session{user}{userId}) if ($session{form}{subscribe});
$parentPost->getThread->lock if ($session{form}{isLocked});
$postData{forumThreadId} = $parentPost->getThread->get("forumThreadId");
$postData{parentId} = $session{form}{parentId};
my $post = WebGUI::Forum::Post->create(\%postData);
setPostStatus($caller,$post);
WebGUI::HTTP::setRedirect(formatThreadURL($caller->{callback}, $post->get("forumPostId")));
return "Redirecting...";
#return www_viewThread($caller,$post->get("forumPostId"));
}
if ($session{form}{forumPostId} ne '') { # edit
my $post = WebGUI::Forum::Post->new($session{form}{forumPostId});
return WebGUI::Privilege::insufficient() unless ($post->canEdit);
if ($post->getThread->getForum->get("addEditStampToPosts")) {
$postData{message} .= "\n\n --- (".WebGUI::International::get(1029)." "
.WebGUI::DateTime::epochToHuman(WebGUI::DateTime::time())." ".WebGUI::International::get(1030)
." $session{user}{username}) --- \n";
}
$post->set(\%postData);
WebGUI::HTTP::setRedirect(formatThreadURL($caller->{callback}, $post->get("forumPostId")));
return "Redirecting...";
#return www_viewThread($caller,$post->get("forumPostId"));
}
if ($forumId) { # new post
%postData = (%postData, %postDataNew);
my $forum = WebGUI::Forum->new($forumId);
return WebGUI::Privilege::insufficient() unless ($forum->canPost);
my $thread = WebGUI::Forum::Thread->create({
forumId=>$forumId,
isSticky=>$session{form}{isSticky},
isLocked=>$session{form}{isLocked}
}, \%postData);
$thread->subscribe($session{user}{userId}) if ($session{form}{subscribe});
setPostStatus($caller,$thread->getPost($thread->get("rootPostId")));
WebGUI::HTTP::setRedirect(formatForumURL($caller->{callback}, $forumId));
return "Redirecting...";
#return www_viewForum($caller,$forumId);
}
}
#-------------------------------------------------------------------
@ -1117,11 +845,27 @@ sub www_rate {
}
#-------------------------------------------------------------------
=head2 www_redirectToParent ( )
This is here to stop people from duplicating posts by hitting refresh in their browser.
=cut
sub www_redirectToParent {
my $self = shift;
WebGUI::HTTP::setRedirect($self->getThread->getParent->getUrl);
}
#-------------------------------------------------------------------
sub www_view {
my $self = shift;
return $self->getParent->processStyle(WebGUI::Privilege::noAccess()) unless $self->canView;
return $self->getParent->processStyle($self->view);
$self->markRead;
$self->incrementViews;
return $self->getThread->www_view;
}

View file

@ -0,0 +1,732 @@
package WebGUI::Asset::Post::Thread;
#-------------------------------------------------------------------
# WebGUI is Copyright 2001-2005 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 WebGUI::Asset::Template;
use WebGUI::Asset::Post;
use WebGUI::DateTime;
use WebGUI::Grouping;
use WebGUI::International;
use WebGUI::MessageLog;
use WebGUI::Paginator;
use WebGUI::Privilege;
use WebGUI::Session;
use WebGUI::SQL;
our @ISA = qw(WebGUI::Asset::Post);
#-------------------------------------------------------------------
sub canReply {
my $self = shift;
return !$self->isLocked && $self->getParent->get("allowReplies") && $self->getParent->canPost;
}
#-------------------------------------------------------------------
sub canSubscribe {
my $self = shift;
return ($session{user}{userId} ne "1" && $self->canView);
}
#-------------------------------------------------------------------
sub createSubscriptionGroup {
my $self = shift;
my $group = WebGUI::Group->new("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->groupId
});
}
#-------------------------------------------------------------------
=head2 decrementReplies ( )
Deccrements this reply counter.
=cut
sub decrementReplies {
my $self = shift;
$self->update({replies=>$self->get("replies")-1});
$self->getParent->decrementReplies;
}
#-------------------------------------------------------------------
sub definition {
my $class = shift;
my $definition = shift;
push(@{$definition}, {
tableName=>'Thread',
className=>'WebGUI::Asset::Post::Thread',
properties=>{
subscriptionGroupId => {
fieldType=>"hidden",
defaultValue=>undef
},
replies => {
fieldType=>"hidden",
defaultValue=>undef
},
isSticky => {
fieldType=>"yesNo",
defaultValue=>0
},
isLocked => {
fieldType=>"yesNo",
defaultValue=>0
},
lastPostId => {
fieldType=>"hidden",
defaultValue=>undef
},
lastPostDate => {
fieldType=>"hidden",
defaultValue=>undef
}
},
});
return $class->SUPER::definition($definition);
}
#-------------------------------------------------------------------
sub DESTROY {
my $self = shift;
$self->{_next}->DESTROY if (exists $self->{_next});
$self->{_previous}->DESTROY if (exists $self->{_previous});
$self->SUPER::DESTROY;
}
#-------------------------------------------------------------------
sub getIcon {
my $self = shift;
my $small = shift;
return $session{config}{extrasURL}.'/assets/small/thread.gif' if ($small);
return $session{config}{extrasURL}.'/assets/thread.gif';
}
#-------------------------------------------------------------------
sub getName {
return "Thread";
}
#-------------------------------------------------------------------
=head2 getLayoutUrl ( layout [, postId] )
Formats the url to change the layout of a thread.
=head3 layout
A string indicating the type of layout to use. Can be flat, nested, or threaded.
=head3 postId
The asset id of the post to position on. Defaults to the root post of the thread.
=cut
sub getLayoutUrl {
my $self = shift;
my $layout = shift;
my $postId = shift || $self->get("rootPostId");
return $self->getUrl("layout=".$layout."#".$postId);
}
#-------------------------------------------------------------------
=head2 getLockUrl ( [ postId ] )
Formats the url to lock a thread.
=head3 postId
The asset id of the post to position on. Defaults to the root post of the thread.
=cut
sub getLockUrl {
my $self = shift;
my $postId = shift || $self->get("rootPostId");
$self->getUrl("fucn=lock#">$postId);
}
#-------------------------------------------------------------------
=head2 getNextThread ( )
Returns a thread object for the next (newer) thread in the same forum.
=cut
sub getNextThread {
my $self = shift;
unless (exists $self->{_next}) {
$self->{_next} = WebGUI::Asset::Post->newByPropertyHashRef(
WebGUI::SQL->quickHashRef("
select asset.*,Post.*
from Thread
left join asset on asset.assetId=Thread.assetId
left join Post on Post.assetId=asset.assetId
where Thread.parentId=".quote($self->get("parentId"))."
and asset.state='published'
and asset.className='WebGUI::Asset::Post::Thread'
and ".$self->getParent->getValue("sortBy").">".quote($self->get($self->getParent->getValue("sortBy")))."
and (userId=".quote($self->get("ownerUserId"))." or Post.status='approved')
order by ".$self->getParent->getValue("sortBy")." asc
",WebGUI::SQL->getSlave)
);
};
return $self->{_next};
}
#-------------------------------------------------------------------
=head2 getPreviousThread ( )
Returns a thread object for the previous (older) thread in the same forum.
=cut
sub getPreviousThread {
my $self = shift;
unless (exists $self->{_previous}) {
$self->{_previous} = WebGUI::Asset::Post->newByPropertyHashRef(
WebGUI::SQL->quickHashRef("
select asset.*,Post.*
from Thread
left join asset on asset.assetId=Thread.assetId
left join Post on Post.assetId=asset.assetId
where Thread.parentId=".quote($self->get("parentId"))."
and asset.state='published'
and asset.className='WebGUI::Asset::Post::Thread'
and ".$self->getParent->getValue("sortBy")."<".quote($self->get($self->getParent->getValue("sortBy")))."
and (userId=".quote($self->get("ownerUserId"))." or Post.status='approved')
order by ".$self->getParent->getValue("sortBy")." desc
",WebGUI::SQL->getSlave)
);
};
return $self->{_previous};
}
#-------------------------------------------------------------------
=head2 getStickUrl ( [ postId ] )
Formats the url to make a thread sticky.
=head3 postId
The asset id of the post to position on. Defaults to the root post of the thread.
=cut
sub getStickUrl {
my $self = shift;
my $postId = shift || $self->get("rootPostId");
return $self->getUrl("func=stick#".$postId);
}
#-------------------------------------------------------------------
=head2 getSubscribeUrl ( [ postId ] )
Formats the url to subscribe to the thread
=head3 postId
The asset id of the post to position on. Defaults to the root post of the thread.
=cut
sub getSubscribeUrl {
my $self = shift;
my $postId = shift || $self->get("rootPostId");
return $self->getUrl("func=subscribe#".$postId);
}
#-------------------------------------------------------------------
sub getThread {
return $self;
}
#-------------------------------------------------------------------
=head2 getUnlockUrl ( [ postId ] )
Formats the url to unlock the thread
=head3 postId
The asset id of the post to position on. Defaults to the root post of the thread.
=cut
sub getUnlockUrl {
my $self = shift;
my $postId = shift || $self->get("rootPostId");
return $self->getUrl("func=unlock#".$postId);
}
#-------------------------------------------------------------------
=head2 getUnstickUrl ( [ postId ] )
Formats the url to unstick the thread
=head3 postId
The asset id of the post to position on. Defaults to the root post of the thread.
=cut
sub getUnstickUrl {
my $self = shift;
my $postId = shift || $self->get("rootPostId");
return $self->getUrl("func=unstick#".$postId);
}
#-------------------------------------------------------------------
=head2 getUnsubscribeUrl ( [ postId ] )
Formats the url to unsubscribe from the thread
=head3 postId
The asset id of the post to position on. Defaults to the root post of the thread.
=cut
sub getUnsubscribeUrl {
my $self = shift;
my $postId = shift || $self->get("rootPostId");
return $self->getUrl("func=unsubscribe#".$postId);
}
#-------------------------------------------------------------------
=head2 isLocked ( )
Returns a boolean indicating whether this thread is locked from new posts and other edits.
=cut
sub isLocked {
my ($self) = @_;
return $self->get("isLocked");
}
#-------------------------------------------------------------------
=head2 incrementReplies ( lastPostDate, lastPostId )
Increments the replies counter for this thread.
=head3 lastPostDate
The date of the reply that caused the replies counter to be incremented.
=head3 lastPostId
The id of the reply that caused the replies counter to be incremented.
=cut
sub incrementReplies {
my ($self, $dateOfReply, $replyId) = @_;
$self->update({replies=>$self->get("replies")+1, lastPostId=>$replyId, lastPostDate=>$dateOfReply});
$self->getParent->incrementReplies($dateOfReply,$replyId);
}
#-------------------------------------------------------------------
=head2 incrementViews ( )
Increments the views counter for this thread.
=cut
sub incrementViews {
my ($self) = @_;
$self->update({views=>$self->get("views")+1});
$self->getParent->incrementViews;
}
#-------------------------------------------------------------------
=head2 isMarkedRead ( )
Returns a boolean indicating whether this thread is marked read for the user.
=cut
sub isMarkedRead {
my $self = shift;
return 1 if $self->isPoster;
my ($isRead) = WebGUI::SQL->quickArray("select count(*) from Post_read where userId=".quote($session{user}{userId})." and threadId=".quote($self->getId));
return $isRead;
}
#-------------------------------------------------------------------
=head2 isSticky ( )
Returns a boolean indicating whether this thread should be "stuck" a the top of the forum and not be sorted with the rest of the threads.
=cut
sub isSticky {
my ($self) = @_;
return $self->get("isSticky");
}
#-------------------------------------------------------------------
=head2 isSubscribed ( )
Returns a boolean indicating whether the user is subscribed to this thread.
=cut
sub isSubscribed {
my $self = shift;
return WebGUI::Grouping::isInGroup($self->get("subscriptionGroupId"));
}
#-------------------------------------------------------------------
=head2 lock ( )
Sets this thread to be locked from edits.
=cut
sub lock {
my ($self) = @_;
$self->update({isLocked=>1});
}
#-------------------------------------------------------------------
=head2 rate ( rating )
Stores a rating against this post.
=head3 rating
An integer between 1 and 5 (5 being best) to rate this post with.
=cut
sub rate {
my $self = shift;
my $rating = shift;
unless ($self->hasRated) {
WebGUI::SQL->write("insert into Post_rating (assetId,userId,ipAddress,dateOfRating,rating) values ("
.quote($self->getId).", ".quote($session{user}{userId}).", ".quote($session{env}{REMOTE_ADDR}).",
".WebGUI::DateTime::time().", $rating)");
my ($count) = WebGUI::SQL->quickArray("select count(*) from Post left join asset on Post.assetId=asset.assetId
where Post.threadId=".quote($self->getId)." and Post.rating>0");
$count = $count || 1;
my ($sum) = WebGUI::SQL->quickArray("select sum(Post.rating) from Post left join asset on Post.assetId=asset.assetId
where Post.threadId=".quote($self->getId)." and Post.rating>0");
my $average = round($sum/$count);
$self->update({rating=>$average});
$self->getParent->recalculateRating;
}
}
#-------------------------------------------------------------------
=head2 setLastPost ( lastPostDate, lastPostId )
Sets the pertinent details for the last post. Can also be done directly using the set method.
=head3 lastPostDate
The epoch date of the post.
=head3 lastPostId
The unique id of the post.
=cut
sub setLastPost {
my ($self, $postDate, $postId) = @_;
$self->update({
lastPostId=>$postId,
lastPostDate=>$postDate
});
$self->getParent->setLastPost($postDate, $postId);
}
#-------------------------------------------------------------------
=head2 stick ( )
Makes this thread sticky.
=cut
sub stick {
my ($self) = @_;
$self->update({isSticky=>1});
}
#-------------------------------------------------------------------
=head2 subscribe ( )
Subscribes the user to this thread.
=cut
sub subscribe {
my $self = shift;
unless ($self->isSubscribed) {
WebGUI::Grouping::addUsersToGroups([$session{user}{userId}],[$self->get("subscriptionGroupId")]);
}
}
#-------------------------------------------------------------------
=head2 unlock ( )
Negates the lock method.
=cut
sub unlock {
my ($self) = @_;
$self->update({isLocked=>0});
}
#-------------------------------------------------------------------
=head2 unstick ( )
Negates the stick method.
=cut
sub unstick {
my ($self) = @_;
$self->update({isSticky=>0});
}
#-------------------------------------------------------------------
=head2 unsubscribe ( )
Negates the subscribe method.
=cut
sub unsubscribe {
my $self = shift;
if ($self->isSubscribed) {
WebGUI::Grouping::deleteUsersFromGroups([$session{user}{userId}],[$self->get("subscriptionGroupId")]);
}
}
#-------------------------------------------------------------------
sub view {
my $self = shift;
$self->markRead;
$self->incrementViews;
WebGUI::Session::setScratch("forumThreadLayout",$session{form}{layout});
my $var = $self->getTemplateVars;
$self->getParent->appendTemplateLabels($var);
$var->{'user.isVisitor'} = ($session{user}{userId} eq '1');
$var->{'user.isModerator'} = $self->canModerate;
$var->{'user.canPost'} = $self->getParent->canPost;
$var->{'user.canReply'} = $self->canReply;
$var->{'layout.nested.url'} = formatThreadLayoutURL($callback,$post->get("forumPostId"),"nested");
$var->{'layout.flat.url'} = formatThreadLayoutURL($callback,$post->get("forumPostId"),"flat");
$var->{'layout.threaded.url'} = formatThreadLayoutURL($callback,$post->get("forumPostId"),"threaded");
my $layout = $session{scratch}{forumThreadLayout} || $session{user}{discussionLayout};
$var->{'layout.isFlat'} = ($layout eq "flat");
$var->{'layout.isNested'} = ($layout eq "nested");
$var->{'layout.isThreaded'} = ($layout eq "threaded" || !($var->{'thread.layout.isNested'} || $var->{'thread.layout.isFlat'}));
$var->{'user.isSubscribed'} = $thread->isSubscribed;
$var->{'subscribe.url'} = formatThreadSubscribeURL($callback,$post->get("forumPostId"));
$var->{'unsubscribe.url'} = formatThreadUnsubscribeURL($callback,$post->get("forumPostId"));
$var->{'isSticky'} = $thread->isSticky;
$var->{'stick.url'} = formatThreadStickURL($callback,$post->get("forumPostId"));
$var->{'unstick.url'} = formatThreadUnstickURL($callback,$post->get("forumPostId"));
$var->{'isLocked'} = $thread->isLocked;
$var->{'lock.url'} = formatThreadLockURL($callback,$post->get("forumPostId"));
$var->{'unlock.url'} = formatThreadUnlockURL($callback,$post->get("forumPostId"));
my $p = WebGUI::Paginator->new($self->getUrl),$self->getParent->get("postsPerPage"));
my $sql = "select * from asset
left join Post on Post.assetId=asset.assetId
left join Thread on Thread.assetId=asset.assetId
where asset.lineage like ".quote($self->get("lineage").'%')."
and asset.assetId<>".quote($self->getId)."
and (
Post.status in ('approved','archived')";
$sql .= " or Post.status='pending'" if ($self->getParent->canModerate);
$sql .= " or (asset.ownerUserId=".quote($session{user}{userId})." and asset.ownerUserId<>'1')
)
order by ";
if ($layout eq "flat") {
$sql .= "post.dateSubmitted";
} else {
$sql .= "asset.lineage";
}
$p->setDataByQuery($sql);
foreach my $dataSet (@{$p->getPageData()}) {
my $reply = WebGUI::Asset::Post->newByPropertyHashRef($dataSet);
my $replyVars = $reply->getTemplateVars;
$replyVars->{isCurrent} = $session{asset}->getId eq $reply->getId;
$replyVars->{depth} = $reply->getLineageLength - $self->getLineageLength - 1;
my @depth_loop;
for (my $i=0; $i<$replyVars->{depth}; $i++) {
push(@{$replyVars->{indent_loop}},{depth=>$i});
}
push (@{$var->{reply_loop}}, $replyVars);
}
$p->appendTemplateVars($var);
$var->{'add.url'} = $self->getParent->getNewThreadUrl;
my $previous = $self->getPreviousThread;
$var->{"previous.url"} = $previous->getUrl if (defined $previous);
my $next = $self->getNextThread;
$var->{"next.url"} = $next->getUrl if (defined $next);
$var->{"search.url"} = $self->getParent->getSearchUrl;
$var->{"back.url"} = $self->getThread->getParent->getUrl;
return $self->processTemplate($var,$self->getParent->get("submissionTemplateId"));
}
#-------------------------------------------------------------------
=head2 www_lock ( )
The web method to lock a thread.
=cut
sub www_lock {
my $self = shift;
$self->lock if $self->getParent->canModerate;
return $self->www_view;
}
#-------------------------------------------------------------------
=head2 www_stick ( )
The web method to make a thread sticky.
=cut
sub www_stick {
my $self = shift;
$self->stick if $self->getParent->canModerate;
return $self->www_view;
}
#-------------------------------------------------------------------
=head2 www_subscribe ( )
The web method to subscribe to a thread.
=cut
sub www_subscribe {
my $self = shift;
$self->subscribe if $self->canSubscribe;
return $self->www_view;
}
#-------------------------------------------------------------------
=head2 www_unlock ( )
The web method to unlock a thread.
=cut
sub www_unlock {
my $self = shift;
$self->unlock if $self->getParent->canModerate;
return $self->www_view;
}
#-------------------------------------------------------------------
=head2 www_unstick ( )
The web method to make a sticky thread normal again.
=cut
sub www_unstick {
my $self = shift;
$self->unstick if $self->getParent->canModerate;
$self->www_view;
}
#-------------------------------------------------------------------
=head2 www_threadUnsubscribe ( )
The web method to unsubscribe from a thread.
=cut
sub www_unsubscribe {
my $self = shift;
$self->unsubscribe if $self->canSubscribe;
return $self->www_view;
}
#-------------------------------------------------------------------
sub www_view {
my $self = shift;
return $self->getParent->processStyle(WebGUI::Privilege::noAccess()) unless $self->canView;
return $self->getParent->processStyle($self->view);
}
1;

File diff suppressed because it is too large Load diff

View file

@ -31,6 +31,64 @@ use WebGUI::Asset::USS_submission;
our @ISA = qw(WebGUI::Asset::Wobject);
#-------------------------------------------------------------------
sub appendTemplateLabels {
my $self = shift;
my $var = shift;
my $i18n = WebGUI::International->new("Collaboration");
$var->{'question.label'} = WebGUI::International::get(85,"USS");
$var->{'title.label'} = WebGUI::International::get(35,"USS");
$var->{'link.header.label'} = WebGUI::International::get(90,"USS");
$var->{'visitorName.label'} = WebGUI::International::get(438);
$var->{'question.header.label'} = WebGUI::International::get(84,"USS");
$var->{'submission.header.label'} = WebGUI::International::get(19,"USS");
$var->{'body.label'} = WebGUI::International::get(31,"USS");
$var->{'answer.label'} = WebGUI::International::get(86,"USS");
$var->{'description.label'} = WebGUI::International::get(85);
$var->{'contentType.label'} = WebGUI::International::get(1007);
$var->{'startDate.label'} = WebGUI::International::get(497);
$var->{'endDate.label'} = WebGUI::International::get(498);
$var->{'url.label'} = WebGUI::International::get(91,"USS");
$var->{'newWindow.label'} = WebGUI::International::get(92,"USS");
$var->{'newpost.header'} = WebGUI::International::get(1064);
$var->{'sticky.label'} = WebGUI::International::get(1013);
$var->{'subscribe.label'} = WebGUI::International::get(873);
$var->{'lock.label'} = WebGUI::International::get(1012);
$var->{'message.label'} = WebGUI::International::get(230);
$var->{'subject.label'} = WebGUI::International::get(229);
$var->{'image.label'} = WebGUI::International::get(32,"USS");
$var->{'attachment.label'} = WebGUI::International::get(33,"USS");
$var->{"user.label"} = "User";
$var->{"title.label"} = "Title";
$var->{"subject.label"} = "Subject";
$var->{"status.label"} = "Status";
$var->{"date.label"} = "Date";
$var->{"approve.label"} = "Approve";
$var->{"delete.label"} = "Delete";
$var->{"deny.label"} = "Deny";
$var->{"edit.label"} = "Edit";
$var->{"reply.label"} = "Reply";
$var->{"views.label"} = "Views";
$var->{"rating.label"} = "Rating";
$var->{"rate.label"} = "Rate";
$var->{"layout.label"} = "Layout";
$var->{"nested.label"} = "Nested";
$var->{"threaded.label"} = "Threaded";
$var->{"flat.label"} = "Flat";
$var->{"lock.label"} = "Lock";
$var->{"unlock.label"} = "Unlock";
$var->{"stick.label"} = "Make Sticky";
$var->{"unstick.label"} = "Unstick";
$var->{"subscribe.label"} = "Subscribe";
$var->{"unsubscribe.label"} = "Unsubscribe";
$var->{"previous.label"} = "Previous";
$var->{"next.label"} = "Next";
$var->{"next.label"} = "Search";
$var->{"back.label"} = "Back";
$var->{"add.label"} = "Add";
}
#-------------------------------------------------------------------
sub canModerate {
my $shift;
@ -190,18 +248,10 @@ sub definition {
fieldType=>"template",
defaultValue=>undef
},
postPreviewTemplateId =>{
fieldType=>"template",
defaultValue=>undef
},
postFormTemplateId =>{
fieldType=>"template",
defaultValue=>undef
},
postTemplateId =>{
fieldType=>"template",
defaultValue=>undef
},
threadTemplateId =>{
fieldType=>"template",
defaultValue=>undef
@ -256,24 +306,12 @@ sub getEditForm {
-namespace=>"Collaboration/Thread",
-label=>"Thread Template"
);
$tabform->getTab("display")->template(
-name=>"postTemplateId",
-value=>$self->getValue("postTemplateId"),
-namespace=>"Collaboration/Post",
-label=>"Post Template"
);
$tabform->getTab("display")->template(
-name=>"postFormTemplateId",
-value=>$self->getValue("postFormTemplateId"),
-namespace=>"Collaboration/PostForm",
-label=>"Post Form Template"
);
$tabform->getTab("display")->template(
-name=>"postPreviewTemplateId",
-value=>$self->getValue("postPreviewTemplateId"),
-namespace=>"Collaboration/Preview",
-label=>"Post Preview Template"
);
$tabform->getTab("display")->template(
-name=>"searchTemplateId",
-value=>$self->getValue("SearchTemplateId"),
@ -400,7 +438,7 @@ sub getName {
#-------------------------------------------------------------------
=head2 formatNewThreadURL ( callback, forumId )
=head2 getNewThreadUrl( )
Formats the url to start a new thread.
@ -408,7 +446,20 @@ Formats the url to start a new thread.
sub getNewThreadUrl {
my $self = shift;
$self->getUrl("func=add&class=WebGUI::Asset::Post");
$self->getUrl("func=add&class=WebGUI::Asset::Post::Thread");
}
#-------------------------------------------------------------------
=head2 getRssUrl ( )
Formats the url to start a new thread.
=cut
sub getRssUrl {
my $self = shift;
$self->getUrl("func=viewRSS");
}
#-------------------------------------------------------------------
@ -599,19 +650,6 @@ sub setLastPost {
}
#-------------------------------------------------------------------
sub status {
my $self = shift;
my $status = shift;
if ($status eq "approved") {
return "Approved";
} elsif ($status eq "denied") {
return "Denied";
} elsif ($status eq "pending") {
return "Pending";
}
}
#-------------------------------------------------------------------
=head2 subscribe ( )
@ -646,55 +684,70 @@ sub unsubscribe {
#-------------------------------------------------------------------
sub view {
my $self = shift;
my $scratchSortBy = $self->getId."_sortBy";
my $scratchSortDir = $self->getId."_sortDir";
if($session{scratch}{$scratchSortBy} ne $session{form}{sortBy}){
WebGUI::Session::setScratch($scratchSortBy,$session{form}{sortBy});
WebGUI::Session::setScratch($scratchSortDir, "desc");
}else{
my $sortDir;
if($session{scratch}{$scratchSortDir} eq "asc"){
$sortDir = "desc";
}else{
$sortDir = "asc";
}
WebGUI::Session::setScratch($scratchSortDir, $sortDir);
}
my $numResults = $self->get("threadsPerPage");
my %var;
$var{"readmore.label"} = "Read More";
$var{"responses.label"} = "Responses";
$var{canPost} = $self->canPost;
$var{"post.url"} = $self->getUrl('func=add&class=WebGUI::Asset::Thread');
$var{"post.label"} = "Add a post.";
$var{"addquestion.label"} = "Add a question.";
$var{"addlink.label"} = "Add a link.";
$var{"search.label"} = "Search";
$var{"search.Form"} = WebGUI::Search::form({func=>'view',search=>1});
$var{"search.url"} = WebGUI::Search::toggleURL("func=view");
$var{"rss.url"} = WebGUI::URL::page('func=viewRSS',1);
$var{canModerate} = $self->canModerate;
$var{"title.label"} = WebGUI::International::get(99);
$var{"thumbnail.label"} = WebGUI::International::get(52,"USS");
$var{"date.label"} = WebGUI::International::get(13,"USS");
$var{"date.updated.label"} = WebGUI::International::get(78,"USS");
$var{"by.label"} = WebGUI::International::get(21,"USS");
$var{"submission.edit.label"} = WebGUI::International::get(27,"USS");
$var{canPost} = $self->canPost;
$var{"post.url"} = $self->getNewThreadUrl;
$var{"rss.url"} = $self->getRssUrl;
$var{canModerate} = $self->canModerate;
WebGUI::Style::setLink($var{"rss.url"},{ rel=>'alternate', type=>'application/rss+xml', title=>'RSS' });
#$var{"search.Form"} = WebGUI::Search::form({func=>'view',search=>1});
#$var{"search.url"} = WebGUI::Search::toggleURL("func=view");
my $constraints;
if ($session{scratch}{search}) {
$numResults = $session{scratch}{numResults};
$constraints = WebGUI::Search::buildConstraints([qw(Post.username asset.synopsis asset.title Post.content Post.userDefined1 Post.userDefined2 Post.userDefined3 Post.userDefined4 Post.userDefined5)]);
}
if ($constraints ne "") {
$constraints = "Post.status='approved' and ".$constraints;
} else {
#if ($session{scratch}{search}) {
# $numResults = $session{scratch}{numResults};
# $constraints = WebGUI::Search::buildConstraints([qw(Post.username asset.synopsis asset.title Post.content Post.userDefined1 Post.userDefined2 Post.userDefined3 Post.userDefined4 Post.userDefined5)]);
# }
# if ($constraints ne "") {
# $constraints = "Post.status='approved' and ".$constraints;
# } else {
$constraints = "(Post.status='approved' or (asset.ownerUserId=".quote($session{user}{userId})." and asset.ownerUserId<>'1')";
if ($var{canModerate}) {
$constraints .= " or Post.status='pending'";
}
$constraints .= ")";
}
#}
my $p = WebGUI::Paginator->new($self->getUrl,$numResults);
my $sql = "select asset.*,Post.*
my $sql = "select *
from Thread
left join asset on Thread.assetId=asset.parentId
left join asset on Thread.assetId=asset.assetId
left join Post on Post.assetId=asset.assetId
where Thread.parentId=".quote($self->getId)." and asset.state='published' and asset.className='WebGUI::Asset::Post' and $constraints
where Thread.parentId=".quote($self->getId)." and asset.state='published' and asset.className='WebGUI::Asset::Post::Thread' and $constraints
order by ".$self->getValue("sortBy")." ".$self->getValue("sortOrder");
$p->setDataByQuery($sql);
my $page = $p->getPageData;
my $i = 0;
my $imageURL = "";
foreach my $row (@$page) {
my $post = WebGUI::Asset::USS_submission->newByPropertyHashRef($row);
my $controls = deleteIcon('func=delete',$post->getUrl,"Delete").editIcon('func=edit',$post->getUrl);
my $post = WebGUI::Asset::Post->newByPropertyHashRef($row);
$post->{_parent} = $self; # caching parent for efficiency
my $controls = deleteIcon('func=delete',$post->get("url"),"Delete").editIcon('func=edit',$post->get("ur"));
if ($self->get("sortBy") eq "lineage") {
if ($self->get("sortOrder") eq "desc") {
$controls .= moveUpIcon('func=demote',$post->get("url")).moveDownIcon('func=promote',$post->get("url"));
@ -712,8 +765,8 @@ sub view {
"id"=>$post->getId,
"url"=>$post->getUrl,
"synopsis"=>$post->get("synopsis"),
"content"=>WebGUI::HTML::format(WebGUI::HTML::filter($post->get("content"),$self->get("filterCode")),$post->get("contentType")),
"reply.count"=>$post->getResponseCount,
"content"=>$self->formatContent,
"reply.count"=>$post->get("replies"),
"title"=>$post->get("title"),
"userDefined1"=>$post->get("userDefined1"),
"userDefined2"=>$post->get("userDefined2"),
@ -727,11 +780,15 @@ sub view {
# "submission.image"=>$submission->getImageUrl,
"date.submitted"=>epochToHuman($post->get("dateSubmitted")),
"date.updated"=>epochToHuman($post->get("dateUpdated")),
"userProfile.url"=>$post->getUrl("op=viewProfile&uid=".$post->get("ownerUserId")),
"edit.url"=>$submission->getUrl("func=edit"),
'controls'=>$submission->getToolbar,
"userProfile.url"=>$post->getUserProfileUrl,
"edit.url"=>$post->getEditUrl,
'controls'=>$controls,
'inDateRange'=>$inDateRange,
"currentUserIsOwner"=>($session{user}{userId} eq $post->get("ownerUserId") && $session{user}{userId} ne "1")
"isSecond"=>(($i+1)%2==0),
"isThird"=>(($i+1)%3==0),
"isFourth"=>(($i+1)%4==0),
"isFifth"=>(($i+1)%5==0),
"currentUserIsPoster"=>$post->isPoster
});
$i++;
}
@ -749,28 +806,22 @@ sub www_edit {
#-------------------------------------------------------------------
=head2 www_search ( caller )
=head2 www_search ( )
The web method to display and use the forum search interface.
=head3 caller
A hash reference containing information passed from the calling object.
=cut
sub www_search {
my ($caller) = @_;
my $forum = WebGUI::Forum->new($session{form}{forumId});
WebGUI::Session::setScratch("all",$session{form}{all});
WebGUI::Session::setScratch("atLeastOne",$session{form}{atLeastOne});
WebGUI::Session::setScratch("exactPhrase",$session{form}{exactPhrase});
WebGUI::Session::setScratch("without",$session{form}{without});
WebGUI::Session::setScratch("numResults",$session{form}{numResults});
my $self = shift;
WebGUI::Session::setScratch($self->getId."_all",$session{form}{all});
WebGUI::Session::setScratch($self->getId."_atLeastOne",$session{form}{atLeastOne});
WebGUI::Session::setScratch($self->getId."_exactPhrase",$session{form}{exactPhrase});
WebGUI::Session::setScratch($self->getId."_without",$session{form}{without});
WebGUI::Session::setScratch($self->getId."_numResults",$session{form}{numResults});
my %var;
$var{'callback.url'} = $caller->{callback};
$var{'callback.label'} = WebGUI::International::get(1039);
$var{'form.begin'} = WebGUI::Form::formHeader({action=>$caller->{callback}});
$var{'form.begin'} = WebGUI::Form::formHeader({action=>$self->getUrl});
$var{'form.begin'} .= WebGUI::Form::hidden({ name=>"forumOp", value=>"search" });
$var{'form.begin'} .= WebGUI::Form::hidden({ name=>"doit", value=>1 });
$var{'form.begin'} .= WebGUI::Form::hidden({ name=>"forumId", value=>$session{form}{forumId} });
@ -879,56 +930,34 @@ sub www_unsubscribe {
}
#-------------------------------------------------------------------
=head2 www_viewForum ( caller [ , forumId ] )
The web method to display a forum.
=head3 caller
The url to get back to the calling object.
=head3 forumId
Specify a forumId and call this method directly, rather than over the web.
=cut
sub www_viewForum {
my ($caller, $forumId) = @_;
$forumId = $session{form}{forumId} unless ($forumId);
if($session{scratch}{forumSortBy} ne $session{form}{sortBy}){
WebGUI::Session::setScratch("forumSortBy",$session{form}{sortBy});
WebGUI::Session::setScratch("forumSortDir", "desc");
}else{
my $sortDir;
if($session{scratch}{forumSortDir} eq "asc"){
$sortDir = "desc";
}else{
$sortDir = "asc";
}
WebGUI::Session::setScratch("forumSortDir", $sortDir);
}
my $forum = WebGUI::Forum->new($forumId);
return WebGUI::Privilege::insufficient() unless ($forum->canView);
my $var = getForumTemplateVars($caller, $forum);
return WebGUI::Template::process($forum->get("forumTemplateId"),"Forum", $var);
# 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 ($time) = @_;
my ($year, $mon, $mday, $hour, $min, $sec) = WebGUI::DateTime::localtime($time);
my $month = $_months[$mon - 1];
return sprintf("%02d %s %04d %02d:%02d:%02d GMT",
$mday, $month, $year, $hour, $min, $sec);
}
#-------------------------------------------------------------------
# encode a string to include in xml (for RSS export)
sub _xml_encode {
my $text = shift;
$text =~ s/&/&amp;/g;
$text =~ s/</&lt;/g;
$text =~ s/\]\]>/\]\]&gt;/g;
return $text;
}
#-------------------------------------------------------------------
# print out RSS 2.0 feed describing the items visible on the first page
sub www_viewRSS {
$_[0]->logView() if ($session{setting}{passiveProfilingEnabled});
my $wid = $_[0]->get("wobjectId");
my $numResults = $_[0]->get("submissionsPerPage");
my $encTitle = _xml_encode($_[0]->get("title"));
my $encDescription = _xml_encode($_[0]->get("description"));
my $encUrl = _xml_encode(WebGUI::URL::page("wid=$wid"));
my $self = shift;
$self->logView() if ($session{setting}{passiveProfilingEnabled});
my $encTitle = _xml_encode($self->get("title"));
my $encDescription = _xml_encode($self->get("description"));
my $encUrl = _xml_encode($self->getUrl);
my $xml = qq~<?xml version="1.0"?>
<rss version="2.0">
<channel>
@ -936,25 +965,21 @@ sub www_viewRSS {
<link>$encUrl</link>
<description>$encDescription</description>
~;
my $res = WebGUI::SQL->read
("select USS_submissionId, content, title, " .
"dateSubmitted, username from USS_submission " .
"where USS_id = " .quote($_[0]->get("USS_id")) . " and status='Approved' " .
"order by ".$_[0]->getValue("sortBy")." ".$_[0]->getValue("sortOrder")." limit " . $numResults,WebGUI::SQL->getSlave);
while (my $row = $res->{_sth}->fetchrow_arrayref()) {
my ($sid, $content, $title, $dateSubmitted, $username) =
@{$row};
my $sth = WebGUI::SQL->read("select *
from Thread
left join asset on Thread.assetId=asset.parentId
left join Post on Post.assetId=asset.assetId
where Thread.parentId=".quote($self->getId)." and asset.state='published'
and asset.className='WebGUI::Asset::Post::Thread' and Post.status='approved'
order by ".$self->getValue("sortBy")." ".$self->getValue("sortOrder"));
my $i = 1;
while (my $data = $sth->hashref) {
my $post = WebGUI::Asset::Post::Thread->newByPropertyHashRef($data);
my $encUrl = _xml_encode
(WebGUI::URL::page
("wid=$wid&func=viewSubmission&sid=$sid"));
my $encTitle = _xml_encode($title);
my $encPubDate = _xml_encode
(_get_rfc822_date($dateSubmitted));
my $encDescription = _xml_encode($content);
my $encUrl = _xml_encode($post->getUrl);
my $encTitle = _xml_encode($post->get("title"));
my $encPubDate = _xml_encode(_get_rfc822_date($post->get("dateUpdated")));
my $encDescription = _xml_encode($self->get("synopsis"));
$xml .= qq~
<item>
<title>$encTitle</title>
@ -964,6 +989,8 @@ sub www_viewRSS {
<pubDate>$encPubDate</pubDate>
</item>
~;
$i++;
last if ($i == $$self->get("threadsPerPage");
}
$xml .=qq~

View file

@ -31,26 +31,6 @@ use WebGUI::Asset::USS_submission;
our @ISA = qw(WebGUI::Asset::Wobject);
#-------------------------------------------------------------------
# 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 ($time) = @_;
my ($year, $mon, $mday, $hour, $min, $sec) = WebGUI::DateTime::localtime($time);
my $month = $_months[$mon - 1];
return sprintf("%02d %s %04d %02d:%02d:%02d GMT",
$mday, $month, $year, $hour, $min, $sec);
}
#-------------------------------------------------------------------
# encode a string to include in xml (for RSS export)
sub _xml_encode {
$_[0] =~ s/&/&amp;/g;
$_[0] =~ s/</&lt;/g;
$_[0] =~ s/\]\]>/\]\]&gt;/g;
return $_[0];
}
#-------------------------------------------------------------------
sub definition {
my $class = shift;

View file

@ -177,7 +177,7 @@ sub identifier {
#-------------------------------------------------------------------
=head2 karma ( amount, source, description )
=head2 karma ( [ amount, source, description ] )
Returns the current level of karma this user has earned.