package Foorum::Controller::Forum; use strict; use warnings; our $VERSION = '1.001000'; use parent 'Catalyst::Controller'; use Foorum::Utils qw/get_page_from_url/; use Foorum::Formatter qw/filter_format/; sub board : Path { my ( $self, $c ) = @_; my @forums = $c->model('DBIC')->resultset('Forum')->search( { forum_type => 'classical', status => { '!=', 'banned' }, }, { order_by => 'me.forum_id', } )->all; # get last_post and the author foreach (@forums) { next unless $_->last_post_id; $_->{last_post} = $c->model('DBIC::Topic')->get( $_->last_post_id ); next unless $_->{last_post}; $_->{last_post}->{updator} = $c->model('DBIC::User') ->get( { user_id => $_->{last_post}->{last_updator_id} } ); } $c->cache_page('300'); # get all moderators my @forum_ids; push @forum_ids, $_->forum_id foreach (@forums); if ( scalar @forum_ids ) { my $roles = $c->model('DBIC::UserForum') ->get_forum_moderators( \@forum_ids ); $c->stash->{forum_roles} = $roles; } $c->stash->{whos_view_this_page} = 1; $c->stash->{forums} = \@forums; $c->stash->{template} = 'forum/board.html'; } sub forum : PathPart('forum') Chained('/') CaptureArgs(1) { my ( $self, $c, $forum_code ) = @_; my $forum = $c->controller('Get')->forum( $c, $forum_code ); } sub forum_list : Regex('^forum/(\w+)$') { my ( $self, $c ) = @_; my $is_elite = ( $c->req->path =~ /\/elite(\/|$)/ ) ? 1 : 0; my $page = get_page_from_url( $c->req->path ); my $rss = ( $c->req->path =~ /\/rss(\/|$)/ ) ? 1 : 0; # /forum/1/rss # get the forum information my $forum_code = $c->req->snippets->[0]; my $forum = $c->controller('Get')->forum( $c, $forum_code ); my $forum_id = $forum->{forum_id}; $forum_code = $forum->{forum_code}; my @extra_cols = ($is_elite) ? ( 'elite', 1 ) : (); my $rows = ($rss) ? 10 : $c->config->{per_page}->{forum}; # 10 for RSS is enough my $it = $c->model('DBIC')->resultset('Topic')->search( { forum_id => $forum_id, 'me.status' => { '!=', 'banned' }, @extra_cols, }, { order_by => \'sticky DESC, last_update_date DESC', rows => $rows, page => $page, prefetch => [ 'author', 'last_updator' ], } ); my @topics = $it->all; if ($rss) { foreach (@topics) { my $rs = $c->model('DBIC::Comment')->find( { object_type => 'topic', object_id => $_->topic_id, }, { order_by => 'post_on', rows => 1, page => 1, columns => [ 'text', 'formatter' ], } ); next unless ($rs); $_->{text} = $rs->text; # filter format by Foorum::Filter $_->{text} = $c->model('DBIC::FilterWord') ->convert_offensive_word( $_->{text} ); $_->{text} = filter_format( $_->{text}, { format => $rs->formatter } ); } $c->stash->{topics} = \@topics; $c->stash->{template} = 'forum/forum.rss.html'; $c->cache_page('600'); return; } # above is for RSS, left is for HTML # get all moderators $c->stash->{forum_roles} = $c->model('DBIC::UserForum')->get_forum_moderators($forum_id); # for page 1 and normal mode if ( $page == 1 and not $is_elite ) { # for private forum if ( $forum->{policy} eq 'private' ) { my $pending_count = $c->model('DBIC::UserForum')->count( { forum_id => $forum_id, status => 'pending', } ); $c->stash( { pending_count => $pending_count, } ); } # check announcement $c->stash->{announcement} = $c->model('DBIC::Forum')->get_announcement($forum); } $c->cache_page('300'); if ( $c->user_exists ) { my @all_topic_ids = map { $_->topic_id } @topics; $c->stash->{is_visited} = $c->model('DBIC::Visit') ->is_visited( 'topic', \@all_topic_ids, $c->user->user_id ) if ( scalar @all_topic_ids ); } # Pager my $pager = $it->pager; # For Tabs $c->stash->{poll_count} = $c->model('DBIC')->resultset('Poll')->count( { forum_id => $forum_id, duration => { '>', time() }, } ); # Forum Links my @links = $c->model('DBIC::ForumSettings')->get_forum_links($forum_id); $c->stash->{forum_links} = \@links; $c->stash->{whos_view_this_page} = 1; $c->stash->{pager} = $pager; $c->stash->{topics} = \@topics; $c->stash->{template} = 'forum/forum.html'; } sub join : Chained('forum') Arg(0) { my ( $self, $c ) = @_; return $c->res->redirect('/login') unless ( $c->user_exists ); my $forum = $c->stash->{forum}; my $forum_id = $forum->{forum_id}; my $forum_code = $forum->{forum_code}; if ( $forum->{policy} eq 'private' ) { # check if already requested if ( $c->req->method eq 'POST' ) { my $rs = $c->model('DBIC::UserForum')->search( { user_id => $c->user->user_id, forum_id => $forum_id, }, { columns => ['status'], } )->first; if ($rs) { if ( $rs->status eq 'user' or $rs->status eq 'moderator' or $rs->status eq 'admin' ) { return $c->res->redirect( $forum->{forum_url} ); } elsif ( $rs->status eq 'blocked' or $rs->status eq 'pending' or $rs->status eq 'rejected' ) { my $status = uc( $rs->status ); $c->detach( '/print_error', ["ERROR_USER_$status"] ); } } else { $c->model('DBIC::UserForum')->create_user_forum( { user_id => $c->user->user_id, forum_id => $forum_id, status => 'pending', } ); my $forum_admin = $c->model('DBIC::UserForum') ->get_forum_admin($forum_id); my $requestor = $c->model('DBIC::User') ->get( { user_id => $c->user->user_id } ); my $forum; if ( $c->stash->{forum} and $c->stash->{forum}->{forum_id} == $forum_id ) { $forum = $c->stash->{forum}; } else { $forum = $c->model('DBIC::Forum')->get($forum_id); } # Send Notification Email $c->model('DBIC::ScheduledEmail')->create_email( { template => 'forum_pending_request', to => $forum_admin->{email}, lang => $c->stash->{lang}, stash => { rept => $forum_admin, from => $requestor, forum => $forum, } } ); $c->detach( '/print_message', [ 'Successfully Requested. You need wait for admin\'s approval' ] ); } } else { $c->stash( { simple_wrapper => 1, template => 'forum/join_us.html', } ); } } else { $c->model('DBIC::UserForum')->create_user_forum( { user_id => $c->user->user_id, forum_id => $forum_id, status => 'user', } ); $c->res->redirect( $forum->{forum_url} ); } } sub members : Chained('forum') Args { my ( $self, $c, $member_type ) = @_; my $forum = $c->stash->{forum}; my $forum_id = $forum->{forum_id}; my $forum_code = $forum->{forum_code}; $member_type ||= 'user'; if ( 'pending' ne $member_type and 'blocked' ne $member_type and 'rejected' ne $member_type ) { $member_type = 'user'; } my $page = get_page_from_url( $c->req->path ); my ( @query_cols, @attr_cols ); if ( 'user' eq $member_type ) { @query_cols = ( 'status', [ 'admin', 'moderator', 'user' ] ); @attr_cols = ( 'order_by' => 'status ASC' ); } else { @query_cols = ( 'status', $member_type ); } my $rs = $c->model('DBIC::UserForum')->search( { @query_cols, forum_id => $forum_id, }, { @attr_cols, rows => 20, page => $page, } ); my @user_roles = $rs->all; my @all_user_ids = map { $_->user_id } @user_roles; my @members; my %members; if ( scalar @all_user_ids ) { @members = $c->model('DBIC::User')->search( { user_id => { 'IN', \@all_user_ids }, }, { columns => [ 'user_id', 'username', 'nickname', 'gender', 'register_time' ], } )->all; %members = map { $_->user_id => $_ } @members; } $c->stash( { template => 'forum/members.html', member_type => $member_type, pager => $rs->pager, user_roles => \@user_roles, whos_view_this_page => 1, members => \%members, } ); } sub action_log : Chained('forum') Args(0) { my ( $self, $c ) = @_; my $forum = $c->stash->{forum}; my $forum_id = $forum->{forum_id}; my $forum_code = $forum->{forum_code}; my $page = get_page_from_url( $c->req->path ); my $rs = $c->model('DBIC')->resultset('LogAction')->search( { forum_id => $forum_id, }, { order_by => \'time DESC', page => $page, rows => 20, } ); my @actions = $rs->all; my @all_user_ids; my %unique_user_ids; foreach (@actions) { next if ( $unique_user_ids{ $_->user_id } ); push @all_user_ids, $_->user_id; $unique_user_ids{ $_->user_id } = 1; } if ( scalar @all_user_ids ) { my $authors = $c->model('DBIC::User')->get_multi( 'user_id', \@all_user_ids ); foreach (@actions) { $_->{operator} = $authors->{ $_->user_id }; } } $c->stash( { template => 'forum/action_log.html', pager => $rs->pager, logs => \@actions, } ); } sub create : Local { my ( $self, $c ) = @_; return $c->res->redirect('/login') unless ( $c->user_exists ); my $is_admin = $c->model('Policy')->is_admin( $c, 'site' ); # if function_on.create_forum is off, check is admin if ( not $c->config->{function_on}->{create_forum} and not $is_admin ) { $c->detach( '/print_error', ['ERROR_PERMISSION_DENIED'] ); } $c->stash( { template => 'forum/create.html' } ); return unless ( $c->req->method eq 'POST' ); $c->form( name => [ qw/NOT_BLANK/, [qw/LENGTH 1 40/] ], description => [ qw/NOT_BLANK/, [qw/LENGTH 1 200/] ], ); return if ( $c->form->has_error ); # check forum_code my $forum_code = $c->req->param('forum_code'); my $err = $c->model('DBIC::Forum')->validate_forum_code($forum_code); if ($err) { $c->set_invalid_form( forum_code => $err ); return; } my $name = $c->req->param('name'); my $description = $c->req->param('description'); my $moderators = $c->req->param('moderators'); my $private = $c->req->param('private'); # validate the admin for roles.site.admin my $admin_user; if ($is_admin) { my $admin = $c->req->param('admin'); $admin_user = $c->model('DBIC::User')->get( { username => $admin } ); unless ($admin_user) { return $c->set_invalid_form( admin => 'ADMIN_NONEXISTENCE' ); } } else { $admin_user = $c->user; } # validate the moderators my $total_members = 1; my @moderators = split( /\s*\,\s*/, $moderators ); my @moderator_users; foreach (@moderators) { next if ( $_ eq $admin_user->{username} ); # avoid the same man last if ( scalar @moderator_users > 2 ) ; # only allow 3 moderators at most my $moderator_user = $c->model('DBIC::User')->get( { username => $_ } ); unless ($moderator_user) { $c->stash->{non_existence_user} = $_; return $c->set_invalid_form( moderators => 'ADMIN_NONEXISTENCE' ); } $total_members++; push @moderator_users, $moderator_user; } # insert data into table. my $policy = ( $private and $private == 1 ) ? 'private' : 'public'; my $forum = $c->model('DBIC::Forum')->create( { name => $name, forum_code => $forum_code, description => $description, forum_type => 'classical', policy => $policy, total_members => $total_members, } ); $c->model('DBIC::UserForum')->create_user_forum( { user_id => $admin_user->{user_id}, status => 'admin', forum_id => $forum->forum_id, } ); foreach (@moderator_users) { $c->model('DBIC::UserForum')->create_user_forum( { user_id => $_->{user_id}, status => 'moderator', forum_id => $forum->forum_id, } ); } # create time $c->model('DBIC')->resultset('ForumSettings')->create( { forum_id => $forum->forum_id, type => 'created_time', value => time(), } ); $c->model('DBIC')->resultset('ForumSettings') ->clear_cache( $forum->forum_id ); $c->res->redirect("/forum/$forum_code"); } sub about : Chained('forum') Args(0) { my ( $self, $c ) = @_; my $forum = $c->stash->{forum}; my $forum_id = $forum->{forum_id}; my $forum_code = $forum->{forum_code}; # get all settings, so that we have created_time $c->stash->{settings} = $c->model('DBIC')->resultset('ForumSettings') ->get_all( $forum->{forum_id} ); # get all moderators $c->stash->{forum_roles} = $c->model('DBIC::UserForum')->get_forum_moderators($forum_id); $c->stash->{template} = 'forum/about.html'; } 1; __END__ =pod =head1 AUTHOR Fayland Lam =cut