diff --git a/lib/WebGUI/Forum.pm b/lib/WebGUI/Forum.pm index 72addbfe4..3bc295e14 100644 --- a/lib/WebGUI/Forum.pm +++ b/lib/WebGUI/Forum.pm @@ -1,9 +1,13 @@ package WebGUI::Forum; +use strict; use WebGUI::Forum::Thread; +use WebGUI::Paginator; +use WebGUI::Privilege; use WebGUI::Session; use WebGUI::SQL; + sub create { my ($self, $data) = @_; $data->{forumId} = "new"; @@ -27,6 +31,12 @@ sub getThread { return $self->{_thread}{$threadId}; } +sub isModerator { + my ($self, $userId) = @_; + $userId = $session{user}{userId} unless ($userId); + return WebGUI::Privilege::isInGroup($self->get("groupToModerate"), $userId); +} + sub new { my ($self, $forumId) = @_; my $properties = WebGUI::SQL->getRow("forum","forumId",$forumId); diff --git a/lib/WebGUI/Forum/Post.pm b/lib/WebGUI/Forum/Post.pm index dae95e0a2..84921e1a3 100644 --- a/lib/WebGUI/Forum/Post.pm +++ b/lib/WebGUI/Forum/Post.pm @@ -1,5 +1,6 @@ package WebGUI::Forum::Post; +use strict; use WebGUI::DateTime; use WebGUI::Forum::Thread; use WebGUI::Session; @@ -31,6 +32,17 @@ sub get { return $self->{_properties}->{$key}; } +sub getReplies { + my ($self) = @_; + my @replies; + my $sth = WebGUI::SQL->read("select forumPostId from forumPost where parentId=".$self->get("forumPostId")." order by forumPostId"); + while (my ($postId) = $sth->array) { + push(@replies,WebGUI::Forum::Post->new($postId)); + } + $sth->finish; + return \@replies; +} + sub getThread { my ($self) = @_; unless (exists $self->{_thread}) { diff --git a/lib/WebGUI/Forum/Thread.pm b/lib/WebGUI/Forum/Thread.pm index 72bdac1ee..d60b59805 100644 --- a/lib/WebGUI/Forum/Thread.pm +++ b/lib/WebGUI/Forum/Thread.pm @@ -1,5 +1,6 @@ package WebGUI::Forum::Thread; +use strict; use WebGUI::Forum; use WebGUI::Forum::Post; use WebGUI::Session; @@ -21,8 +22,8 @@ sub create { $data->{forumThreadId} = "new"; my $forumThreadId = WebGUI::SQL->setRow("forumThread","forumThreadId",$data); $self = WebGUI::Forum::Thread->new($forumThreadId); - $postData{forumThreadId} = $forumThreadId; - $postData{parentId} = 0; + $postData->{forumThreadId} = $forumThreadId; + $postData->{parentId} = 0; my $post = WebGUI::Discuss::Post->create($postData); $self->set({ rootPostId=>$post->get("forumPostId"), @@ -49,6 +50,15 @@ sub getForum { return $self->{_forum}; } +sub getNextThread { + my ($self) = @_; + unless (exists $self->{_next}) { + my ($nextId) = WebGUI::SQL->quickArray("select min(forumThreadId) from forumThread where forumThreadId>".$self->get("forumThreadId")); + $self->{_next} = WebGUI::Forum::Thread->new($nextId); + } + return $self->{_next}; +} + sub getPost { my ($self, $postId) = @_; unless (exists $self->{_post}{$postId}) { @@ -57,6 +67,15 @@ sub getPost { return $self->{_post}{$postId}; } +sub getPreviousThread { + my ($self) = @_; + unless (exists $self->{_previous}) { + my ($nextId) = WebGUI::SQL->quickArray("select max(forumThreadId) from forumThread where forumThreadId<".$self->get("forumThreadId")); + $self->{_previous} = WebGUI::Forum::Thread->new($nextId); + } + return $self->{_previous}; +} + sub isLocked { my ($self) = @_; return $self->get("isLocked"); @@ -86,9 +105,13 @@ sub stick { } sub new { - my ($self, $forumThreadId) = @_; + my ($class, $forumThreadId) = @_; my $properties = WebGUI::SQL->getRow("forumThread","forumThreadId",$forumThreadId); - bless {_properties=>$properties}, $self; + if (defined $properties) { + bless {_properties=>$properties}, $class; + } else { + return undef; + } } sub set { diff --git a/lib/WebGUI/Forum/Web.pm b/lib/WebGUI/Forum/Web.pm index 42d47fdcd..1ef5af5bc 100644 --- a/lib/WebGUI/Forum/Web.pm +++ b/lib/WebGUI/Forum/Web.pm @@ -1,16 +1,72 @@ package WebGUI::Forum::Web; +use strict qw(vars subs); use WebGUI::DateTime; +use WebGUI::Form; use WebGUI::Forum; use WebGUI::Forum::Post; use WebGUI::Forum::Thread; -use WebGUI::HTML::Filter; +use WebGUI::HTML; use WebGUI::Session; use WebGUI::Template; -sub getPostTemplateVars { - my ($post, $thread, $forum) = @_; - my %var; + +sub _chopSubject { + return substr(_formatSubject($_[0]),0,30); +} + +sub _formatEditPostURL { + return WebGUI::URL::append($_[0],"forumOp=post&forumPostId=".$_[1]); +} + +sub _formatNextThreadURL { + return WebGUI::URL::append($_[0],"forumOp=nextThread&forumThreadId=".$_[1]); +} + +sub _formatNewThreadURL { + return WebGUI::URL::append($_[0],"forumOp=post&forumId=".$_[1]); +} + +sub _formatPostDate { + return WebGUI::DateTime::epochToHuman($_[0],"%z"); +} + +sub _formatPostTime { + return WebGUI::DateTime::epochToHuman($_[0],"%Z"); +} + +sub _formatPreviousThreadURL { + return WebGUI::URL::append($_[0],"forumOp=previousThread&forumThreadId=".$_[1]); +} + +sub _formatReplyPostURL { + return WebGUI::URL::append($_[0],"forumOp=post&parentId=".$_[1]); +} + +sub _formatSubject { + return WebGUI::HTML::filter($_[0],"all"); +} + +sub _formatStatus { + if ($_[0] eq "approved") { + return WebGUI::International::get(560); + } elsif ($_[0] eq "denied") { + return WebGUI::International::get(561); + } elsif ($_[0] eq "pending") { + return WebGUI::International::get(562); + } +} + +sub _formatThreadURL { + return WebGUI::URL::append($_[0],"forumOp=viewThread&forumPostId=".$_[1]."#".$_[1]); +} + +sub _formatUserProfileURL { + return WebGUI::URL::page("op=viewProfile&uid=".$_[0]); +} + +sub _getPostTemplateVars { + my ($post, $thread, $forum, $var) = @_; $var->{'post.subject'} = WebGUI::HTML::filter($post->get("subject"),"none"); $var->{'post.message'} = WebGUI::HTML::filter($post->get("message"),$forum->get("filterPosts")); if ($forum->get("allowReplacements")) { @@ -20,28 +76,172 @@ sub getPostTemplateVars { } $sth->finish; } - $var->{'post.date'} = WebGUI::DateTime::epochToHuman($post->get("dateOfPost"),"%z"); - $var->{'post.time'} = WebGUI::DateTime::epochToHuman($post->get("dateOfPost"),"%Z"); + $var->{'post.date'} = _formatPostDate($post->get("dateOfPost")); + $var->{'post.time'} = _formatPostTime($post->get("dateOfPost")); $var->{'post.views'} = $post->get("views"); - $var->{'post.status'} = getStatus($post->get("status")); - $var->{'post.isLocked'} = $post->isLocked; + $var->{'post.status'} = _formatStatus($post->get("status")); + $var->{'post.isLocked'} = $thread->isLocked; $var->{'post.isModerator'} = $forum->isModerator; $var->{'post.username'} = $post->get("username"); $var->{'post.userId'} = $post->get("userId"); - $var->{'post.userProfile'} = WebGUI::URL::page("op=viewProfile&uid=".$post->get("userId")); + $var->{'post.userProfile'} = _formatUserProfileURL($post->get("userId")); $var->{'post.id'} = $post->get("forumPostId"); - $var->{'post.full'} = WebGUI::Template::process(WebGUI::Template::get($forum->get("postTemplate"),"Forum/Post"), \%var); + $var->{'post.full'} = WebGUI::Template::process(WebGUI::Template::get(1,"Forum/Post"), $var); + return $var; } -sub getStatus { +sub _recurseThread { + my ($post, $thread, $forum, $depth) = @_; + my @depth_loop; + for (my $i=0; $i<$depth; $i++) { + push(@depth_loop,""); + } + my @post_loop; + push (@post_loop, _getPostTemplateVars($post, $thread, $forum, {'indent_loop'=>\@depth_loop})); + my $replies = $post->getReplies; + foreach my $reply (@{$replies}) { + @post_loop = (@post_loop,@{_recurseThread($reply, $thread, $forum, $depth+1)}); + } + return \@post_loop; +} +sub forumOp { + my ($callback) = @_; + my $cmd = "www_".$session{form}{forumOp}; + return &$cmd($callback); +} + +sub viewForum { + my ($callback, $forumId) = @_; + my (%var, @thread_loop); + $var{'thread.new.url'} = _formatNewThreadURL($callback,$forumId); + $var{'thread.new.label'} = 'Post a new thread.'; + my $p = WebGUI::Paginator->new($callback); + $p->setDataByQuery("select * from forumThread where forumId=".$forumId." order by isSticky desc, lastPostDate desc"); + my $threads = $p->getPageData; + foreach my $thread (@{$threads}) { + my $root = WebGUI::Forum::Post->new($thread->{rootPostId}); + my $last = WebGUI::Forum::Post->new($thread->{lastPostId}); + push(@thread_loop,{ + 'thread.views'=>$thread->{views}, + 'thread.replies'=>$thread->{replies}, + 'thread.isSticky'=>$thread->{isSticky}, + 'thread.isLocked'=>$thread->{isLocked}, + 'thread.root.subject'=>_chopSubject($root->get("subject")), + 'thread.root.url'=>_formatThreadURL($callback,$root->get("forumPostId")), + 'thread.root.epoch'=>$root->get("dateOfPost"), + 'thread.root.date'=>_formatPostDate($root->get("dateOfPost")), + 'thread.root.time'=>_formatPostTime($root->get("dateOfPost")), + 'thread.root.user.profile'=>_formatUserProfileURL($root->get("userId")), + 'thread.root.user.name'=>$root->get("username"), + 'thread.root.user.id'=>$root->get("userId"), + 'thread.root.status'=>_formatStatus($root->get("status")), + 'thread.last.subject'=>_chopSubject($last->get("subject")), + 'thread.last.url'=>_formatThreadURL($callback,$last->get("forumPostId")), + 'thread.last.epoch'=>$last->get("dateOfPost"), + 'thread.last.date'=>_formatPostDate($last->get("dateOfPost")), + 'thread.last.time'=>_formatPostTime($last->get("dateOfPost")), + 'thread.last.user.profile'=>_formatUserProfileURL($last->get("userId")), + 'thread.last.user.name'=>$last->get("username"), + 'thread.last.user.id'=>$last->get("userId"), + 'thread.last.status'=>_formatStatus($last->get("status")) + }); + } + $var{thread_loop} = \@thread_loop; + return WebGUI::Template::process(WebGUI::Template::get(1,"Forum"), \%var); +} + +sub www_nextThread { + my ($callback) = @_; + my $thread = WebGUI::Forum::Thread->new($session{form}{forumThreadId}); + return www_viewThread($callback,$thread->getNextThread->get("rootPostId")); } sub www_post { + my ($callback) = @_; + my ($subject, $message, $forum); + my $var; + $var->{header} = 'Post a Message'; + $var->{isNewThread} = ($session{form}{forumId} ne ""); + $var->{isReply} = ($session{form}{parentId} ne ""); + $var->{isEdit} = ($session{form}{forumPostId} ne ""); + $var->{isVisitor} = ($session{user}{userId} == 1); + $var->{'form.begin'} = WebGUI::Form::formHeader({ + action=>$callback + }); + if ($var->{isReply}) { + my $reply = WebGUI::Forum::Post->new($session{form}{parentId}); + $var->{'form.begin'} .= WebGUI::Form::hidden({ + name=>'parentId', + value=>$reply->get("forumPostId") + }); + $forum = $reply->getThread->getForum; + $var = _getPostTemplateVars($reply, $reply->getThread, $forum, $var); + $subject = $reply->get("subject"); + $subject = "Re: ".$subject unless ($subject =~ /^Re:/); + } + if ($var->{isNewThread}) { + $var->{'form.begin'} .= WebGUI::Form::hidden({ + name=>'forumId', + value=>$session{form}{forumId} + }); + $forum = WebGUI::Forum->new($session{form}{forumId}); + $var->{'subscribe.label'} = WebGUI::International::get(873); + $var->{'subscribe.form'} = WebGUI::Form::yesNo({ + name=>'subscribe', + value=>1 + }); + if ($forum->isModerator) { + $var->{'sticky.label'} = 'Make Sticky'; + $var->{'sticky.form'} = WebGUI::Form::yesNo({ + name=>'sticky', + value=>0 + }); + } + } + if ($var->{isEdit}) { + my $post = WebGUI::Forum::Post->new($session{form}{forumPostId}); + $subject = $post->get("subject"); + $message = $post->get("message"); + $forum = $post->getThread->getForum; + } + $var->{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->{isVisitor}) { + $var->{'visitorName.label'} = WebGUI::International::get(438); + $var->{'visitorName.form'} = WebGUI::Form::text({ + name=>'visitorName' + }); + } + $var->{'form.begin'} .= WebGUI::Form::hidden({ + name=>'forumOp', + value=>'postSave' + }); + $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'} = ''; + return WebGUI::Template::process(WebGUI::Template::get(1,"Forum/PostForm"), $var); } sub www_postSave { + my ($callback) = @_; my $forumId = $session{form}{forumId}; my $threadId = $session{form}{forumThreadId}; if ($session{form}{parentId} > 0) { @@ -56,8 +256,33 @@ sub www_postSave { } } -sub www_viewPost { +sub www_previousThread { + my ($callback) = @_; + my $thread = WebGUI::Forum::Thread->new($session{form}{forumThreadId}); + return www_viewThread($callback,$thread->getPreviousThread->get("rootPostId")); +} +sub www_viewThread { + my ($callback, $postId) = @_; + $postId = $session{form}{forumPostId} unless ($postId); + my $post = WebGUI::Forum::Post->new($postId); + my $thread = $post->getThread; + my $forum = $thread->getForum; + my $var = _getPostTemplateVars($post, $thread, $forum); + my $root = WebGUI::Forum::Post->new($thread->get("rootPostId")); + $var->{post_loop} = _recurseThread($root, $thread, $forum, 0); + $var->{'thread.layout.isFlat'} = ($session{user}{discussionLayout} eq "flat"); + $var->{'thread.layout.isThreaded'} = ($session{user}{discussionLayout} eq "threaded"); + $var->{'thread.layout.isNested'} = ($session{user}{discussionLayout} eq "nested"); + $var->{'thread.new.url'} = ''; + $var->{'thread.new.label'} = WebGUI::International::get(0); + $var->{'thread.previous.url'} = _formatPreviousThreadURL($callback,$thread->get("forumThreadId")); + $var->{'thread.previous.label'} = WebGUI::International::get(513); + $var->{'thread.next.url'} = _formatNextThreadURL($callback,$thread->get("forumThreadId")); + $var->{'thread.next.label'} = WebGUI::International::get(512); + $var->{'thread.list.url'} = ''; + $var->{'thread.list.label'} = WebGUI::International::get(0); + return WebGUI::Template::process(WebGUI::Template::get(1,"Forum/Thread"), $var); } diff --git a/lib/WebGUI/Wobject/Article.pm b/lib/WebGUI/Wobject/Article.pm index bb7ec4012..586d68333 100644 --- a/lib/WebGUI/Wobject/Article.pm +++ b/lib/WebGUI/Wobject/Article.pm @@ -14,6 +14,7 @@ use strict; use Tie::CPHash; use WebGUI::Attachment; use WebGUI::DateTime; +use WebGUI::Forum::Web; use WebGUI::HTML; use WebGUI::HTMLForm; use WebGUI::Icon; @@ -190,7 +191,11 @@ sub www_view { $var{"post.URL"} = WebGUI::URL::page('func=post&mid=new&wid='.$_[0]->get("wobjectId")); $var{"post.label"} = WebGUI::International::get(24,$_[0]->get("namespace")); } - return $_[0]->processTemplate($_[0]->getValue("templateId"),\%var); + if ($session{form}{forumOp}) { + return WebGUI::Forum::Web::forumOp(WebGUI::URL::page("func=view&wid=".$_[0]->get("wobjectId"))); + } else { + return $_[0]->processTemplate($_[0]->getValue("templateId"),\%var).WebGUI::Forum::Web::viewForum(WebGUI::URL::page("func=view&wid=".$_[0]->get("wobjectId")),1); + } }