[Affelio-cvs 1179] CVS update: affelio/apps/bb/bb

Back to archive index

Yoshihisa Fukuhara higef****@users*****
2006年 3月 23日 (木) 12:46:14 JST


Index: affelio/apps/bb/bb/Admin.pm
diff -u /dev/null affelio/apps/bb/bb/Admin.pm:1.1
--- /dev/null	Thu Mar 23 12:46:14 2006
+++ affelio/apps/bb/bb/Admin.pm	Thu Mar 23 12:46:14 2006
@@ -0,0 +1,133 @@
+# Copyright (C) 2006 Affelio Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+
+package bb;
+{
+    use strict;
+    use bb::SpamFilter;
+    use bb::SetPermission;
+    ######################################################################
+    #run_admin
+    ######################################################################
+    sub run_admin{
+	my $self = shift;
+	my $afap = $self->{afap};
+	my $cgi = $self->{cgi};
+	my $wi = $self->{wi};
+	
+	my %handlers = (
+	    "pref_set","PrefSet",
+	    "spam_filter", "SpamFilter",
+	    "category", "Category",
+	    "set_permission","SetPermission",
+	    "help", "Help");
+
+	###########################
+	#Check access
+	###########################
+	unless ($afap->check_access("DF_access")) {
+	    $self->accessErrorExit('Access Denied. You don\'t have permission to this application.');
+	}   
+	unless ($afap->get_visitor_info("type") eq "self"){
+	    $self->accessErrorExit('Access Denied. You don\'t have permission to this application.');
+	}
+	###########################
+	#Going to the owner mode
+	###########################
+	$afap->{af}->set_owner_mode();
+
+	##############################################################
+	#prep vars
+	##############################################################
+	my %output_data = ("tmpl_path", Cwd::getcwd()."/templates/");
+
+	##############################################################
+	#Model invocation
+	##############################################################
+	my $mode = $wi->PTN_mode($cgi->param("mode"));
+	if ($mode eq "") {$mode="pref_set";}
+	debug_print("bb::Admin::run: mode=$mode");
+	
+	my $classname = "bb::" . $handlers{$mode};
+	debug_print("bb::Admin::run: handler= $classname");
+	eval "use $classname";
+	if($@){
+	    throw Affelio::exception::SystemException("Could not load handler [$mode]");
+	}
+	debug_print("bb::Admin::run: handler function loaded.");
+
+	my $ret="";
+	try{
+	    debug_print("bb::Admin::run: handler function..... ");
+	    handler($cgi, $self, \%output_data);
+	    debug_print("bb::Admin::run: handler function done.");
+	}catch Error with{
+	    my $e = shift;
+	    $output_data{"err_msg"} .= $e->stacktrace;
+	};
+	    debug_print("bb::Admin::run: $output_data{tmpl_file}");
+	##############################################################
+	#Output View
+	##############################################################
+	my $tmpl = new HTML::Template(filename => $output_data{tmpl_file},
+				      die_on_bad_params => 0);
+	$output_data{"access_control_URL"} = $afap->get_URL("access_control");
+	$tmpl->param(%output_data);
+	
+	print "Content-type: text/html; charset=UTF-8\n";
+	print "Pragma: no-cache", "\n\n";
+	print $self->get_HTML_header_owner($self->{header_title}.": 管理者モード");
+	print $self->translate_templateL10N($tmpl->output);
+	print $afap->get_HTML_footer;
+	
+}
+
+sub get_HTML_header_owner{
+    my $self = shift;
+#    my $af = $self->{af};
+    my $app__page_title = shift;
+
+    #Set template file name
+    my $TMPL_FILE = "$self->{afap}->{af}->{site__tmpldyn_dir}/_header.tmpl";
+    #Set data for template
+    my %output_data = ();
+    $output_data{'app__css_path'} = $self->{afap}->{af}->{site__web_root}."/templates/default/owner_side";
+    $output_data{'app__page_title'} = $app__page_title;
+    $output_data{"site__skin_dir"} = $self->{afap}->{af}->{site__web_root} . "/skins/" . $self->{afap}->{af}->{userpref__skin};
+    $output_data{'site__web_root'} = $self->{afap}->{af}->{site__web_root};
+    $output_data{'site__locale'} = $self->{afap}->{af}->{site__locale};
+
+    $self->{afap}->{af}->get_module_list(\%output_data, $self->{afap}->{af}->{site__web_root},"self");
+    $self->{afap}->{af}->get_guest_owner_list(\%output_data);
+
+    #Initiate Template
+    my $tmpl = new HTML::Template( filename => $TMPL_FILE,
+				   die_on_bad_params => 0);
+    $tmpl->param(%output_data);
+
+    my $menu_tmpl = new HTML::Template( filename => "./templates/owner/admin_menu.tmpl",
+				   die_on_bad_params => 0);
+    $menu_tmpl->param(access_control_URL => $self->{afap}->get_URL("access_control"));
+    
+    my $final_out = $self->translate_templateL10N($tmpl->output)
+	. '<div class="afMain">' . "\n".$self->translate_templateL10N($menu_tmpl->output);
+
+    return($final_out);
+}
+
+}
+1;
Index: affelio/apps/bb/bb/Category.pm
diff -u /dev/null affelio/apps/bb/bb/Category.pm:1.1
--- /dev/null	Thu Mar 23 12:46:14 2006
+++ affelio/apps/bb/bb/Category.pm	Thu Mar 23 12:46:14 2006
@@ -0,0 +1,129 @@
+# Copyright (C) 2006 Affelio Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+
+package bb::Category;
+{
+    use strict;
+    use Affelio::misc::Debug qw( debug_print);
+
+    use Exporter;
+    @bb::Category::ISA = "Exporter";
+    @bb::Category::EXPORT = qw (show handler);
+
+
+    #######################################################################
+    #handler
+    #######################################################################
+    sub handler{
+	my $cgi = shift;
+	my $bb = shift;
+	my $output_ref = shift;
+	
+	debug_print("bb::Category::handler: start.");
+
+	#check access
+	$bb->errorExit('<AF_M text="Access denied">') if($bb->{pb_user});
+	$bb->errorExit('<AF_M text="Access denied">') unless ($bb->getPermission("category_edit"));
+
+	$output_ref->{tmpl_file}
+	= $bb->{afap}->{app__fs_root}."/templates/category.tmpl";
+	my $wi = new Affelio::misc::WebInput();
+	my $action = $wi->PTN_mode($cgi->param("action"));
+	my $sub_action = $wi->PTN_mode($cgi->param("sub_action"));
+	my $title=$bb->escape_all($cgi->param("title"));
+########### Add Category  ####################################################
+	if ($action eq "add_category"){
+	    $output_ref->{NEW} = "1";
+	    $output_ref->{TITLE} = $title;
+	    $output_ref->{AFID} = $bb->{afid};
+	    $output_ref->{USER} = $bb->{user};
+########### Edit Category  ####################################################
+	}elsif ($action eq "edit_category"){
+	    my @category = getCategory($bb, $bb->{c_id});
+	    $bb->errorExit('<AF_M text="The category was not found.">') if ($#category<0);
+	    $output_ref->{C_ID} = $bb->{c_id};
+	    $output_ref->{EDIT} = "1";
+	    $output_ref->{TITLE} = $category[0]->{title};
+	    $output_ref->{AFID} = $bb->{afid};
+	    $output_ref->{USER} = $bb->{user};
+	    $output_ref->{CAN_DELETE} = "1" if ($bb->getPermission("category_delete"));
+########### Confirm Category  ####################################################
+	}elsif ($action eq "confirm_category"){
+	    if ($sub_action eq "update"){
+		$output_ref->{UPDATE} = "1";
+		$output_ref->{C_ID} = $bb->{c_id};
+	    }
+	    $output_ref->{CONFIRM} = "1";
+	    $output_ref->{TITLE} = $title;
+	    $output_ref->{AFID} = $bb->{afid};
+	    $output_ref->{USER} = $bb->{user};
+########### Submit Category  ####################################################
+	}elsif ($action eq "submit_category"){
+	    addCategory($bb,$title, $bb->{user}, $bb->{afid});
+	    $output_ref->{SUBMIT} = "1";
+########### Update Category ####################################################
+	}elsif ($action eq "update_category"){
+	    $bb->updateCategoryInfo($bb->{c_id}, $bb->{user}, $bb->{afid}, $title);
+	    $output_ref->{UPDATE} = "1";
+	    $output_ref->{SUBMIT} = "1";
+########### Delete Category ####################################################
+	}elsif ($action eq "delete_category"){
+	    $bb->errorExit('<AF_M text="Access denied">') unless ($bb->getPermission("category_delete"));
+	    my $forum_num = $bb->getColumn("SELECT COUNT(forum_id) FROM $bb->{forum_tb} WHERE category_id = $bb->{c_id}");
+	    $bb->errorExit('<AF_M text="Please delete all forums before delete this category.">') if ($forum_num > 0);
+	    $bb->{dbh}->do("DELETE FROM $bb->{category_tb} WHERE category_id = $bb->{c_id}");
+	    $output_ref->{DELETE} = "1";
+	    $output_ref->{SUBMIT} = "1";
+	}
+	debug_print("bb::Category::show end.");
+}
+
+##############################################
+# addCategory
+##############################################
+sub addCategory {
+    my ($self, $title, $user, $afid) = @_;
+    my $time = time;
+    
+    $self->checkContent($title, $user, $afid, "","","");
+    
+    my @same = $self->getall("SELECT category_id FROM $self->{category_tb} WHERE title='$title'");
+    $self->errorExit('<AF_M text="A category of the proposed name already exists.">') if($#same >= 0);
+
+    $self->{dbh}->do("INSERT INTO $self->{category_tb} (title, timestamp, update_time, user, afid, last_user, last_afid, lock, ord) VALUES ('$title', $time, $time, '$user', '$afid', '$user', '$afid', 0, 0)");
+}
+
+##############################################
+# getNewestCategoryId
+##############################################
+sub getNewestCategoryId {
+  	my ($self) = @_;
+  	my @ret = $self->getall("SELECT MAX(category_id) as category_id FROM $self->{category_tb}");
+  	return $ret[0];
+}
+
+##############################################
+# getCategory
+##############################################
+sub getCategory {
+	my $self = shift;
+	my $c_id = shift;
+	return $self->getall("SELECT * FROM $self->{category_tb} WHERE category_id = $c_id");
+}
+
+}
+1;
Index: affelio/apps/bb/bb/Comment.pm
diff -u /dev/null affelio/apps/bb/bb/Comment.pm:1.1
--- /dev/null	Thu Mar 23 12:46:14 2006
+++ affelio/apps/bb/bb/Comment.pm	Thu Mar 23 12:46:14 2006
@@ -0,0 +1,241 @@
+# Copyright (C) 2006 Affelio Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+
+package bb::Comment;
+{
+    use strict;
+    use Affelio::misc::Debug qw( debug_print);
+
+    use Exporter;
+    @bb::Comment::ISA = "Exporter";
+    @bb::Comment::EXPORT = qw (show handler);
+
+    #######################################################################
+    #handler
+    #######################################################################
+    sub handler{
+	my $cgi = shift;
+	my $bb = shift;
+	my $output_ref = shift;
+	#check access
+	$bb->errorExit('<AF_M text="Access denied">') unless ($bb->getPermission("comment_edit"));
+
+	debug_print("bb::Comment::handler: start.");
+
+	$output_ref->{tmpl_file} = $bb->{afap}->{app__fs_root}."/templates/comment.tmpl";	
+	my $wi = new Affelio::misc::WebInput();
+	my $action = $wi->PTN_mode($cgi->param("action"));
+	$bb->errorExit('<AF_M text="Please specify the forum.">') if ($bb->{f_id} =~ /\D/);
+	$bb->errorExit('<AF_M text="Please specify the Topic.">') if ($bb->{t_id} =~ /\D/ || $bb->{t_id} eq "");
+	$bb->errorExit('<AF_M text="This topic is locked.">') if ($bb->getColumn("SELECT lock FROM $bb->{topic_tb} WHERE topic_id=$bb->{t_id}"));
+	my $r_id = $wi->PTN_num($cgi->param("r_id"));
+	my $reply_title = $bb->escape_all($cgi->param("reply_title"));
+	my $comment = $bb->escape($cgi->param("comment"));
+	my $pwd = $wi->PTN_password($cgi->param("pwd"));
+	my $icon = $wi->PTN_basefilename($cgi->param("icon"));
+
+	if ($action eq "new_comment"){ # Add new comment  #
+	    new_Comment($bb, $output_ref, $reply_title, $comment, $bb->{user}, $bb->{afid}, $pwd);
+	}elsif ($action eq "confirm_comment"){ # Confirm comment  #
+	    confirm_Comment($bb, $output_ref, $reply_title, $comment, $bb->{user}, $bb->{afid}, $pwd, $icon);
+	}elsif ($action eq "submit_comment"){ # Submit comment  #
+	    submit_Comment($bb, $output_ref, $reply_title, $comment, $bb->{user}, $bb->{afid}, $pwd, $icon);
+	}elsif ($action eq "do_delete"){ # delete comment  #
+	    $bb->errorExit('<AF_M text="Access denied">') unless ($bb->getPermission("comment_delete"));
+	    do_Delete($bb, $output_ref, $r_id, $bb->{user}, $bb->{afid}, $pwd);
+	}elsif($action eq "delete_comment"){ # delete mode  #
+	    delete_Comment($bb, $output_ref, $r_id, $bb->{user}, $bb->{afid}, $pwd);
+	} else {
+	    $bb->errorExit('<AF_M text="Error: Unknown access.">');
+	}
+}
+
+##############################################
+# newComment
+##############################################
+sub new_Comment {
+    my ($bb, $output_ref, $reply_title, $comment, $user_name, $afid, $pwd) =@_;
+    $bb->errorExit('<AF_M text="Please input a subject.">') if($reply_title eq "");
+    $bb->errorExit('<AF_M text="Please input your comment.">') if($comment eq "");
+    if ($bb->{pb_user}){
+	$bb->errorExit('<AF_M text="Please input your nickname.">') if($user_name eq "");
+	$bb->errorExit('<AF_M text="Please input a password.">') if($pwd eq "");
+    }
+    $output_ref->{NEW} = "1";
+    $output_ref->{T_ID} = $bb->{t_id};
+    $output_ref->{TITLE} = $reply_title;
+    $output_ref->{COMMENT} = $comment;
+    $output_ref->{USER} = $user_name;
+    $output_ref->{AFID} = $afid;
+}
+
+##############################################
+# confirmComment
+##############################################
+sub confirm_Comment {
+    my ($bb, $output_ref, $reply_title, $comment, $user_name, $afid, $pwd, $icon) =@_;
+    $bb->errorExit('<AF_M text="Please input a subject.">') if($reply_title eq "");
+    $bb->errorExit('<AF_M text="Please input your comment.">') if($comment eq "");
+    if ($bb->{pb_user}){
+	$bb->errorExit('<AF_M text="Please input your nickname.">') if($user_name eq "");
+	$bb->checkPwd($pwd);
+    }
+    if (-f "./resource/face/owner.gif"){
+	$icon = "owner.gif" if ($bb->{afap}->get_visitor_info("type") eq "self" && $icon eq "");
+    }
+
+    $output_ref->{CONFIRM} = "1";
+    $output_ref->{T_ID} = $bb->{t_id};
+    $output_ref->{PB_USER} = $bb->{pb_user};
+    $output_ref->{TITLE} = $reply_title;
+    $output_ref->{COMMENT_SHOW} = $bb->n2br($comment);
+    $output_ref->{COMMENT} = $comment;
+    $output_ref->{USER} = $user_name;
+    $output_ref->{AFID} = $afid;
+    $output_ref->{PWD} = $pwd;
+    $output_ref->{ICON} = $icon;
+}
+
+##############################################
+# submitComment
+##############################################
+sub submit_Comment {
+    my ($bb, $output_ref, $reply_title, $comment, $user_name, $afid, $pwd, $icon) =@_;
+    $bb->errorExit('<AF_M text="Please input a subject.">') if($reply_title eq "");
+    $bb->errorExit('<AF_M text="Please input your comment.">') if($comment eq "");
+    if ($bb->{pb_user}){
+	$bb->errorExit('<AF_M text="Please input your nickname.">') if($user_name eq "");
+	$bb->errorExit('<AF_M text="Please input a password.">') if($pwd eq "");
+    }
+    addComment($bb, $bb->{t_id}, $reply_title, $user_name, $afid, $comment, $pwd, $icon);
+    $output_ref->{SUBMIT} = "1";
+    $output_ref->{T_ID} = $bb->{t_id};
+}
+
+##############################################
+# doDelete
+##############################################
+sub do_Delete {
+    my ($bb, $output_ref, $r_id, $user_name, $afid, $pwd) =@_;
+    $bb->errorExit('<AF_M text="Please specify the comment.">') if ($r_id =~ /\D/ || $r_id eq "");
+    my $reply = getReply($bb, $bb->{t_id}, $r_id);
+    if ($bb->{afap}->get_visitor_info("type") eq "self"){
+	deleteReply($bb, $bb->{t_id}, $r_id);
+    }else{
+	if($bb->{pb_user} eq "0") {
+	    if ($reply->{pwd} eq "" && $reply->{afid} eq $afid){
+		deleteReply($bb, $bb->{t_id}, $r_id);
+	    }else{
+		$bb->errorExit('<AF_M text="Authentication error.">');
+	    }
+	} elsif($reply->{pwd} ne ""){
+	    if ($bb->{pb_user}){
+		$bb->errorExit('<AF_M text="Please input your nickname.">') if($user_name eq "");
+		$bb->checkPwd($pwd);	  
+	    }
+	    if (crypt($pwd,$reply->{pwd}) eq $reply->{pwd}){
+		deleteReply($bb, $bb->{t_id}, $r_id);		
+	    }else{
+		$bb->errorExit('<AF_M text="Authentication error.">');
+	    }
+	}
+    }
+    
+    $output_ref->{DONE_DELETE} = "1";
+    $output_ref->{T_ID} = $bb->{t_id};
+}
+
+##############################################
+# deleteComment
+##############################################
+sub delete_Comment {
+    my ($bb, $output_ref, $r_id, $afid) =@_;
+    $bb->errorExit('<AF_M text="Please specify the comment.">') if ($r_id =~ /\D/ || $r_id eq "");
+    my $reply = getReply($bb, $bb->{t_id}, $r_id);
+    if ($bb->{afap}->get_visitor_info("type") eq "self"){
+	$output_ref->{PWD} = "0";
+    }else{
+	if ($bb->{pb_user} eq "0"){
+	    if ($reply->{pwd} eq "" && $reply->{afid} eq $afid){
+		$output_ref->{PWD} = "0";
+	    } else{
+		$bb->errorExit('<AF_M text="Authentication error.">');
+	    }
+	}elsif($reply->{pwd} ne ""){
+	    $output_ref->{PWD} = "1";
+	}
+    }
+    $output_ref->{CONFIRM_DELETE} = "1";
+    $output_ref->{T_ID} = $bb->{t_id};
+    $output_ref->{R_ID} = $r_id;
+    $output_ref->{USER} = $reply->{user};
+    $output_ref->{TITLE} = $reply->{title};
+    $output_ref->{COMMENT} = $reply->{comment};
+    $output_ref->{AFID} = $reply->{afid};
+}
+
+##############################################
+# addComment
+##############################################
+sub addComment {
+    my ($self, $topic_id, $title, $user, $afid, $comment, $pwd, $icon) = @_;
+    my $time = time;
+    my $crypt = "";
+    $crypt = $self->cryptPwd($pwd)	if ($pwd ne "");
+    $self->checkContent($title, $user, $afid, $comment, $icon, $pwd);
+    my $reply_tb = "AFuser_bb_$self->{afap}->{install_name}_reply_".$topic_id;
+    my @same = $self->getall("SELECT reply_id FROM $reply_tb WHERE title = '$title' AND user = '$user' AND comment = '$comment'");
+    $self->errorExit('<AF_M text="A same comment already exists.">') if($#same >= 0);
+    
+    $self->{dbh}->do("INSERT INTO $reply_tb (title, user, afid, comment, icon, pwd, timestamp) VALUES ('$title', '$user', '$afid', '$comment', '$icon', '$crypt', $time)");
+    
+    $self->{dbh}->do("UPDATE $self->{topic_tb} SET posts = posts+1 WHERE topic_id = $topic_id");
+    my $forum_id = $self->getColumn("SELECT forum_id FROM $self->{topic_tb} WHERE topic_id = $topic_id");
+    $self->{dbh}->do("UPDATE $self->{forum_tb} SET posts = posts+1, last_user = '$user', last_afid = '$afid', update_time = $time WHERE forum_id = $forum_id");
+
+    $self->{dbh}->do("UPDATE $self->{topic_tb} SET last_user = '$user', last_afid = '$afid', update_time = $time WHERE topic_id = $topic_id");
+    
+    $self->{afap}->post_news($title, "", $user,
+		     $self->{afap}->get_site_info("web_root") . "/apps/". 
+		     $self->{afap}->{install_name} . "/view_topic.cgi?t_id=".$topic_id);
+    $comment =~ s/<br[^>]*>/\n/g;
+    $self->sendBbMail("$userさんが掲示板に書き込みました。\n\n-----\n$title\n$comment\n\n$self->{afap}->{app__web_root}/view_topic.cgi?t_id=$topic_id", $title);
+}
+
+
+##############################################
+# deleteReply
+##############################################
+sub deleteReply {
+    my ($self, $topic_id, $reply_id) = @_;
+    my $reply_tb = "AFuser_bb_$self->{afap}->{install_name}_reply_".$topic_id;
+    $self->{dbh}->do("UPDATE $reply_tb SET user = NULL, afid = NULL, title = NULL, icon = NULL, comment = '\<AF_M text=\"Deleted\"\>' WHERE reply_id = $reply_id");
+}
+
+##############################################
+# getReply
+##############################################
+sub getReply {
+    my ($self, $topic_id, $reply_id) = @_;
+    my $reply_tb = "AFuser_bb_$self->{afap}->{install_name}_reply_".$topic_id;
+    my @ret = $self->getall("SELECT * FROM $reply_tb WHERE reply_id = $reply_id");
+    return $ret[0];
+}
+
+
+}
+1;
Index: affelio/apps/bb/bb/Forum.pm
diff -u /dev/null affelio/apps/bb/bb/Forum.pm:1.1
--- /dev/null	Thu Mar 23 12:46:14 2006
+++ affelio/apps/bb/bb/Forum.pm	Thu Mar 23 12:46:14 2006
@@ -0,0 +1,239 @@
+# Copyright (C) 2006 Affelio Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+
+package bb::Forum;
+{
+    use strict;
+    use Affelio::misc::Debug qw( debug_print);
+
+    use Exporter;
+    @bb::Forum::ISA = "Exporter";
+    @bb::Forum::EXPORT = qw (show handler);
+
+    #######################################################################
+    #handler
+    #######################################################################
+    sub handler{
+	my $cgi = shift;
+	my $bb = shift;
+	my $output_ref = shift;
+	
+	debug_print("bb::Forum::handler: start.");
+
+	#check access
+	$bb->errorExit('<AF_M text="Access denied">') unless ($bb->getPermission("forum_edit"));
+
+	$output_ref->{tmpl_file} = $bb->{afap}->{app__fs_root}."/templates/forum.tmpl";	
+	my $wi = new Affelio::misc::WebInput();
+	my $action = $wi->PTN_mode($cgi->param("action"));
+	my $new_category = $wi->PTN_num($cgi->param("new_category"));
+	$bb->errorExit('<AF_M text="Please specify the category.">') if ($bb->{c_id} =~ /\D/);
+	my $title = $bb->escape_all($cgi->param("title"));
+	my $description = $bb->escape($cgi->param("description"));
+	my $pwd = $wi->PTN_password($cgi->param("pwd"));
+	my $close_forum = $bb->getPermission("forum_delete") ? "1" : "0";
+
+	if ($action eq "add_forum"){ # Add new forum #
+	    new_Forum($bb, $output_ref, $bb->{c_id}, $title, $description, $bb->{afid}, $bb->{user});
+	}elsif ($action eq "confirm_forum"){ # Confirm forum info #
+	    confirm_Forum($bb, $output_ref, $bb->{c_id}, $title, $description, $bb->{afid}, $bb->{user}, $pwd);
+	}elsif ($action eq "submit_forum"){ # Submit forum #
+	    submit_Forum($bb, $output_ref, $bb->{c_id}, $title, $description, $bb->{afid}, $bb->{user}, $pwd);
+	}elsif ($action eq "edit_forum"){ # edit forum #
+	    edit_Forum($bb, $output_ref, $bb->{afid});
+	}elsif ($action eq "update_forum"){ # update forum #
+	    update_Forum($bb, $output_ref, $new_category, $title, $description, $bb->{afid}, $bb->{user}, $pwd);
+	}elsif ($action eq "delete_forum"){ # delete forum #
+	    delete_Forum($bb, $output_ref, $bb->{user}, $bb->{afid}, $pwd);
+	}else {
+	    $bb->errorExit('<AF_M text="Error: Unknown access.">');
+	}
+	
+}
+
+##############################################
+# newForum
+##############################################
+sub new_Forum {
+    my ($bb, $output_ref, $c_id, $title, $description, $afid, $user)=@_;
+    $output_ref->{NEW}		= "1";
+    $output_ref->{C_ID}		= $c_id;
+    $output_ref->{TITLE}	= $title;
+    $output_ref->{DESCRIPTION}	= $description;
+    $output_ref->{PB_USER}	= $bb->{pb_user};
+    $output_ref->{AFID}		= $afid;
+    $output_ref->{USER}		= $user;
+}
+
+##############################################
+# confirmForum
+##############################################
+sub confirm_Forum {
+    my ($bb, $output_ref, $c_id, $title, $description, $afid, $user, $pwd)=@_;
+    $bb->errorExit('<AF_M text="Please input a title.">') if ($title eq "");
+    $bb->errorExit('<AF_M text="Please input a description.">') if ($description eq "");
+    $bb->errorExit('<AF_M text="Please input your nickname.">') if ($user eq "");
+    $bb->checkPwd($pwd) if ($bb->{pb_user} eq "1");
+
+    $output_ref->{CONFIRM}	= "1";
+    $output_ref->{C_ID}		= $c_id;
+    $output_ref->{TITLE}		= $title;
+    $output_ref->{DESCRIPTION_SHOW}= $bb->n2br($description);
+    $output_ref->{DESCRIPTION}	= $description;
+    $output_ref->{PB_USER}	= $bb->{pb_user};
+    $output_ref->{AFID}		= $afid;
+    $output_ref->{PWD}		= $pwd;
+    $output_ref->{USER}		= $user;
+}
+
+##############################################
+# submitForum
+##############################################
+sub submit_Forum {
+    my ($bb, $output_ref, $c_id, $title, $description, $afid, $user, $pwd)=@_;
+    $bb->errorExit('<AF_M text="Please input a title.">') if ($title eq "");
+    $bb->errorExit('<AF_M text="Please input a description.">') if ($description eq "");
+    $bb->errorExit('<AF_M text="Please input your nickname.">') if ($user eq "");
+    $bb->errorExit('<AF_M text="Please input a password.">') if ($pwd eq "" && $bb->{pb_user});
+    
+    my $forum_id = addForum($bb, $c_id, $title, $description, $user, $afid, $pwd);
+    $bb->updateCategoryInfo($c_id, $user, $afid);
+    $output_ref->{DONE}	= "1";
+    $output_ref->{F_ID}	= $forum_id;
+    $output_ref->{MSG}	= "New forum was created.";
+}
+
+##############################################
+# editForum
+##############################################
+sub edit_Forum {
+    my ($bb, $output_ref, $afid)=@_;
+    $bb->errorExit('<AF_M text="Please specify the forum.">') if ($bb->{f_id} =~ /\D/ || $bb->{f_id} eq "");
+    my $forum = $bb->getForum($bb->{f_id});
+    my $auth=0;
+    my $can_delete=$bb->getPermission("forum_delete");
+    if ($bb->{afap}->get_visitor_info("type") eq "self"){
+	$output_ref->{PWD} = "0";
+    }elsif ($bb->{pb_user} eq "0"){
+	if ($forum->{pwd} eq "" && $forum->{afid} eq $afid){
+	    $output_ref->{PWD} = "0";
+	} else {
+	    $bb->errorExit('<AF_M text="Authentication error.">');
+	}
+    }elsif($forum->{pwd} ne ""){
+	$output_ref->{PWD} = "1";
+    }
+
+    my @categories = $bb->getAllCategories;
+    my @category_list;
+    foreach(@categories) {
+	my $selected = 1 if ($_->{category_id} == $forum->{category_id});
+	push @category_list,
+	{
+	    C_ID	=>	$_->{category_id},
+	    TITLE	=>	$_->{title},
+	    SELECTED    =>      $selected,
+	};
+    }
+    $forum->{description} =~ s/<br[^>]*>/\n/g;
+    $output_ref->{EDIT} = "1";
+    $output_ref->{CAN_DELETE} = $can_delete;
+    $output_ref->{F_ID} = $bb->{f_id};
+    $output_ref->{USER} = $forum->{user};
+    $output_ref->{TITLE} = $forum->{title};
+    $output_ref->{DESCRIPTION} = $forum->{description};
+    $output_ref->{AFID} = $forum->{afid};
+    $output_ref->{CATEGORY_LIST} = \@category_list;
+}
+
+##############################################
+# updateForum
+##############################################
+sub update_Forum {
+    my ($bb, $output_ref, $new_category, $title, $description, $afid, $user, $pwd)=@_;
+    $bb->errorExit('<AF_M text="Please specify the forum.">') if ($bb->{f_id} =~ /\D/ || $bb->{f_id} eq "");
+    my $forum = $bb->getForum($bb->{f_id});
+    my $time = time;
+    $bb->errorExit('<AF_M text="Authentication error.">') unless ($bb->checkAuthentication($bb->{pb_user}, $user, $afid, $pwd, $forum->{afid}, $forum->{pwd}));
+
+    # Do update
+    $bb->checkContent($title, $user, $afid, $description, "", "");
+    my @same = $bb->getall("SELECT forum_id FROM $bb->{forum_tb} WHERE title='$title'");
+    $bb->errorExit('<AF_M text="A forum of the proposed name already exists.">') if($#same >= 1);
+    $bb->{dbh}->do("UPDATE $bb->{forum_tb} SET category_id = $new_category, title='$title', description='$description', user = '$user', afid = '$afid', timestamp = $time WHERE forum_id = $bb->{f_id}");
+
+    $output_ref->{DONE} = "1";
+    $output_ref->{MSG} = "The forum was updated.";
+}
+
+##############################################
+# deleteForum
+##############################################
+sub delete_Forum {
+    my $bb = shift;
+    my $output_ref= shift;
+    my $user= shift;
+    my $afid=shift;
+    my $pwd=shift;
+    $bb->errorExit('<AF_M text="Access denied">') unless ($bb->getPermission("forum_delete"));
+    $bb->errorExit('<AF_M text="Please specify the forum.">') if ($bb->{f_id} =~ /\D/ || $bb->{f_id} eq "");#
+    my $forum = $bb->getForum($bb->{f_id});
+    $bb->errorExit('<AF_M text="Authentication error.">') unless ($bb->checkAuthentication($bb->{pb_user}, $user, $afid, $pwd, $forum->{afid}, $forum->{pwd}));
+
+    my $topic_num = $bb->getColumn("SELECT COUNT(topic_id) FROM $bb->{topic_tb} WHERE forum_id = $bb->{f_id}");
+    $bb->errorExit('<AF_M text="Please delete all topics before delete this forum.">') if ($topic_num > 0);
+    $bb->{dbh}->do("DELETE FROM $bb->{forum_tb} WHERE forum_id = $bb->{f_id}");
+    $output_ref->{DONE} = "1";
+    $output_ref->{MSG} = "The forum was deleted.";
+}
+
+##############################################
+# addForum
+##############################################
+sub addForum {
+    my ($self, $category_id,$title, $description, $user, $afid, $pwd) = @_;
+    my $time = time;
+    my $crypt="";
+
+    $category_id = $self->escape($category_id, 'int');
+    $title = $self->escape_all($title);
+    $user = $self->escape_all($user);
+    $afid = $self->escape_all($afid);
+    $description = $self->escape($description);
+    $pwd = $self->escape_all($pwd);
+    $crypt = $self->cryptPwd($pwd)	if ($pwd ne "");
+    $self->checkContent($title, $user, $afid, $description, "", $pwd);
+   
+    my @same = $self->getall("SELECT forum_id FROM $self->{forum_tb} WHERE title='$title'");
+    $self->errorExit('<AF_M text="A forum of the proposed name already exists.">') if($#same >= 0);
+    
+    $self->{dbh}->do("INSERT INTO $self->{forum_tb} (category_id, title, description, timestamp, update_time, user, afid, pwd, last_user, last_afid, topics, posts, status, lock, ord) VALUES ($category_id, '$title', '$description', $time, $time, '$user', '$afid', '$crypt', '$user', '$afid', 0, 0,0,0,0)");
+    my $forum_id=$self->getColumn("SELECT MAX(forum_id) FROM $self->{forum_tb} WHERE category_id = $category_id");
+
+    $self->{afap}->post_news($title, "", $user,
+		     $self->{afap}->get_site_info("web_root") . "/apps/". 
+		     $self->{afap}->{install_name} . "/view_forum.cgi?f_id=".$forum_id);
+
+    $description =~ s/<br[^>]*>/\n/g;
+    $self->sendBbMail("新しいフォ−ラム「$title」が$userさんによって作成されました。\n\n-----\n$description\n\n$self->{afap}->{app__web_root}/view_forum.cgi?f_id=$forum_id", $title);
+
+    return $forum_id;
+}
+
+
+}
+1;
Index: affelio/apps/bb/bb/Help.pm
diff -u /dev/null affelio/apps/bb/bb/Help.pm:1.1
--- /dev/null	Thu Mar 23 12:46:14 2006
+++ affelio/apps/bb/bb/Help.pm	Thu Mar 23 12:46:14 2006
@@ -0,0 +1,40 @@
+# Copyright (C) 2006 Affelio Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+
+package bb::Help;
+{
+    use strict;
+    use Exporter;
+    @bb::Help::ISA = "Exporter";
+    @bb::Help::EXPORT = qw (handler);
+
+
+    #######################################################################
+    #handler
+    #######################################################################
+    sub handler{
+	my $cgi = shift;
+	my $bb = shift;
+	my $output_ref = shift;
+	
+	$output_ref->{tmpl_file}
+	= $bb->{afap}->{app__fs_root}."/templates/owner/admin_help.tmpl";
+}
+
+
+}
+1;
Index: affelio/apps/bb/bb/PrefSet.pm
diff -u /dev/null affelio/apps/bb/bb/PrefSet.pm:1.1
--- /dev/null	Thu Mar 23 12:46:14 2006
+++ affelio/apps/bb/bb/PrefSet.pm	Thu Mar 23 12:46:14 2006
@@ -0,0 +1,81 @@
+# Copyright (C) 2006 Affelio Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+
+package bb::PrefSet;
+{
+    use strict;
+    use Affelio::misc::Debug qw( debug_print);
+
+    use Exporter;
+    @bb::PrefSet::ISA = "Exporter";
+    @bb::PrefSet::EXPORT = qw (show handler);
+
+
+    #######################################################################
+    #handler
+    #######################################################################
+    sub handler{
+	my $cgi = shift;
+	my $bb = shift;
+	my $output_ref = shift;
+	
+	debug_print("bb::PrefSet::handler: start.");
+	$output_ref->{tmpl_file}
+	= $bb->{afap}->{app__fs_root}."/templates/owner/admin_general.tmpl";
+	my $wi = new Affelio::misc::WebInput();
+	my $action = $wi->PTN_mode($cgi->param("action"));
+
+	if ($action eq "update"){
+	    my $title = $bb->escape_all($cgi->param("title"));
+	    my $email = $cgi->param("email");
+	    my $max_topics = $wi->PTN_num($cgi->param("max_topics"));
+	    my $max_comments = $wi->PTN_num($cgi->param("max_comments"));
+	    my $num_topics = $wi->PTN_num($cgi->param("num_topics"));
+	    my $num_comments = $wi->PTN_num($cgi->param("num_comments"));
+	    my $max_sbjlen = $wi->PTN_num($cgi->param("max_sbjlen"));
+	    my $max_textlen = $wi->PTN_num($cgi->param("max_textlen"));
+	    
+	    $bb->errorExit('<AF_M text="Please input data correctly.">') if ($max_topics =~ /\D/ || $max_comments =~ /\D/ || $num_topics =~ /\D/ || $num_comments =~ /\D/ || $max_sbjlen =~ /\D/ || $max_textlen =~ /\D/);
+	    $title = $bb->escape_all($title);
+    
+	    # updatePreference
+	    $bb->{dbh}->do("UPDATE $bb->{pref_tb} SET value = '$title' WHERE key = 'title'");
+	    $bb->{dbh}->do("UPDATE $bb->{pref_tb} SET value = '$email' WHERE key = 'email'");
+	    $bb->{dbh}->do("UPDATE $bb->{pref_tb} SET value = '$max_topics' WHERE key = 'max_topics'");
+	    $bb->{dbh}->do("UPDATE $bb->{pref_tb} SET value = '$max_comments' WHERE key = 'max_comments'");
+	    $bb->{dbh}->do("UPDATE $bb->{pref_tb} SET value = '$num_topics' WHERE key = 'num_topics'");
+	    $bb->{dbh}->do("UPDATE $bb->{pref_tb} SET value = '$num_comments' WHERE key = 'num_comments'");
+	    $bb->{dbh}->do("UPDATE $bb->{pref_tb} SET value = '$max_sbjlen' WHERE key = 'max_sbjlen'");
+	    $bb->{dbh}->do("UPDATE $bb->{pref_tb} SET value = '$max_textlen' WHERE key = 'max_textlen'");
+	}
+	my %pref = $bb->getPreference;
+
+	$output_ref->{TITLE} = $pref{"title"};
+	$output_ref->{EMAIL} = $pref{"email"};
+	$output_ref->{MAX_TOPICS} = $pref{"max_topics"};
+	$output_ref->{MAX_COMMENTS} = $pref{"max_comments"};
+	$output_ref->{NUM_TOPICS} = $pref{"num_topics"};
+	$output_ref->{NUM_COMMENTS} = $pref{"num_comments"};
+	$output_ref->{MAX_SBJLEN} = $pref{"max_sbjlen"};
+	$output_ref->{MAX_TEXTLEN} = $pref{"max_textlen"};
+
+	debug_print("bb::PrefSet::show end.");
+}
+
+
+}
+1;
Index: affelio/apps/bb/bb/SetPermission.pm
diff -u /dev/null affelio/apps/bb/bb/SetPermission.pm:1.1
--- /dev/null	Thu Mar 23 12:46:14 2006
+++ affelio/apps/bb/bb/SetPermission.pm	Thu Mar 23 12:46:14 2006
@@ -0,0 +1,102 @@
+# Copyright (C) 2006 Affelio Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+
+package bb::SetPermission;
+{
+    use strict;
+    use Affelio::misc::Debug qw( debug_print);
+
+    use Exporter;
+    @bb::SetPermission::ISA = "Exporter";
+    @bb::SetPermission::EXPORT = qw (show handler);
+
+
+    #######################################################################
+    #handler
+    #######################################################################
+    sub handler{
+	my $cgi = shift;
+	my $bb = shift;
+	my $output_ref = shift;
+	
+	debug_print("bb::SetPermission::handler: start.");
+
+	$output_ref->{tmpl_file}
+	= $bb->{afap}->{app__fs_root}."/templates/owner/set_permission.tmpl";
+	my $wi = new Affelio::misc::WebInput();
+	my $action = $wi->PTN_mode($cgi->param("action"));
+
+	my $user = $bb->{afap}->get_visitor_info("nickname");
+	my $afid = $bb->{afap}->get_visitor_info("afid");
+
+	my @perm_input;
+	
+	my @category_edit =   $cgi->param('category_edit');
+	my @category_delete = $cgi->param('category_delete');
+	my @category_status = $cgi->param('category_status');
+
+	my @forum_edit =   $cgi->param('forum_edit');
+	my @forum_delete = $cgi->param('forum_delete');
+	my @forum_status = $cgi->param('forum_status');
+
+	my @topic_edit =   $cgi->param('topic_edit');
+	my @topic_delete = $cgi->param('topic_delete');
+	my @topic_status = $cgi->param('topic_status');
+
+	my @comment_edit =   $cgi->param('comment_edit');
+	my @comment_delete = $cgi->param('comment_delete');
+	if ($action eq "submit"){
+	    updatePermission($bb,"category_edit", \@category_edit);
+	    updatePermission($bb,"category_delete", \@category_delete);
+	    updatePermission($bb,"category_status", \@category_status);
+	    updatePermission($bb,"forum_edit", \@forum_edit);
+	    updatePermission($bb,"forum_delete", \@forum_delete);
+	    updatePermission($bb,"forum_status", \@forum_status);
+	    updatePermission($bb,"topic_edit", \@topic_edit);
+	    updatePermission($bb,"topic_delete", \@topic_delete);
+	    updatePermission($bb,"topic_status", \@topic_status);
+	    updatePermission($bb,"comment_edit", \@comment_edit);
+	    updatePermission($bb,"comment_delete", \@comment_delete);
+	    $output_ref->{MSG} = '<AF_M text="Permission settings were updated.">'; 
+	}
+
+	my @perm = $bb->getall("SELECT * FROM $bb->{permission_tb}");
+	my @perm_list;
+	foreach (@perm) {
+	    push @perm_list,
+	    {
+		KEY	=>	$_->{key},
+		SUPER   =>      $_->{super},
+		USER    =>      $_->{user},
+	    };
+	}
+	$output_ref->{PERM_LIST} = \@perm_list;
+	debug_print("bb::SetPermission::show end.");
+}
+
+sub updatePermission {
+    my $self = shift;
+    my $key = shift;
+    my $value = shift;
+    my $super = (@$value[0] =~ /S/ || @$value[1] =~ /S/) ? "1" : "0";	
+    my $user =  (@$value[0] =~ /U/ || @$value[1] =~ /U/) ? "1" : "0";	
+
+    $self->{dbh}->do("UPDATE $self->{permission_tb} SET super = $super, user = $user WHERE key = '$key'");
+}
+
+}
+1;
Index: affelio/apps/bb/bb/SpamFilter.pm
diff -u /dev/null affelio/apps/bb/bb/SpamFilter.pm:1.1
--- /dev/null	Thu Mar 23 12:46:14 2006
+++ affelio/apps/bb/bb/SpamFilter.pm	Thu Mar 23 12:46:14 2006
@@ -0,0 +1,74 @@
+# Copyright (C) 2006 Affelio Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+
+package bb::SpamFilter;
+{
+    use strict;
+    use Affelio::misc::Debug qw( debug_print);
+
+    use Exporter;
+    @bb::SpamFilter::ISA = "Exporter";
+    @bb::SpamFilter::EXPORT = qw (show handler);
+
+
+    #######################################################################
+    #handler
+    #######################################################################
+    sub handler{
+	my $cgi = shift;
+	my $bb = shift;
+	my $output_ref = shift;
+	
+	debug_print("bb::SpamFilter::handler: start.");
+
+	$output_ref->{tmpl_file}
+	= $bb->{afap}->{app__fs_root}."/templates/owner/spam.tmpl";
+	my $wi = new Affelio::misc::WebInput();
+	my $action = $wi->PTN_mode($cgi->param("action"));
+      
+	if ($action eq "add_spam_key"){
+	    my $spam_key = $bb->escape_all($cgi->param("spam_key"));
+	    if ($spam_key ne ""){
+		my @same = $bb->getall("SELECT keyword FROM $bb->{spam_tb} WHERE keyword = '$spam_key'");
+		unless($#same >= 0) {
+		    $bb->{dbh}->do("INSERT INTO $bb->{spam_tb} (keyword) VALUES ('$spam_key')");
+		}	
+	    }
+	}elsif ($action eq "remove_spam_key"){
+	    my $spam_id = $wi->PTN_num($cgi->param("spam_keys"));
+	    $bb->{dbh}->do("DELETE FROM $bb->{spam_tb} WHERE spam_id = $spam_id");
+	}
+	my @key_list;
+	my @spam_keys;
+	@spam_keys = $bb->getall("SELECT * FROM $bb->{spam_tb}");
+	$output_ref->{HAS_KEY} = '0';
+	if (@spam_keys > 0 ){
+	    $output_ref->{HAS_KEY}='1';
+	    foreach(@spam_keys) {
+		push @key_list,
+		{
+		    S_ID => $_->{spam_id},
+		    KEYWORD	=>	$_->{keyword},
+		};
+	    }
+	    $output_ref->{KEY_LIST} = \@key_list;
+	}
+	debug_print("bb::SpamFilter::show end.");
+}
+
+}
+1;
Index: affelio/apps/bb/bb/Top.pm
diff -u /dev/null affelio/apps/bb/bb/Top.pm:1.1
--- /dev/null	Thu Mar 23 12:46:14 2006
+++ affelio/apps/bb/bb/Top.pm	Thu Mar 23 12:46:14 2006
@@ -0,0 +1,117 @@
+# Copyright (C) 2006 Affelio Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+
+package bb::Top;
+{
+use strict;
+use utf8;
+use Affelio::misc::Debug qw( debug_print);
+
+use Exporter;
+ @ bb::Top::ISA = "Exporter";
+ @ bb::Top::EXPORT = qw (show handler);
+
+
+    #######################################################################
+    #handler
+    #######################################################################
+    sub handler{
+	my $cgi = shift;
+	my $bb = shift;
+	my $output_ref = shift;
+	
+	debug_print("bb::Top::handler: start.");
+	$output_ref->{tmpl_file}
+	= $bb->{afap}->{app__fs_root}."/templates/index.tmpl";
+	
+    ####### Show Category,Forum List ######################################
+	my %pref = $bb->getPreference;
+	my @categories_param;
+	my @categories;
+	my @forums_param;
+	my @forums;
+	my $i=0;
+	my $j=0;
+	my $forum_edit = $bb->getPermission("forum_edit");
+
+	@categories = $bb->getAllCategories;
+	$output_ref->{PAGE_TITLE} = $pref{'title'};
+	$output_ref->{HAS_CATEGORY} = $#categories+1;
+	$output_ref->{CATEGORY_EDIT} = "1" if ($bb->getPermission("category_edit") && !$bb->{pb_user});
+	
+
+	foreach(@categories) {
+	    @forums = $bb->getall("SELECT * FROM $bb->{forum_tb} WHERE category_id = $_->{category_id} ORDER BY update_time DESC");
+	    foreach(@forums) {
+		my ($sec, $min, $hour, $mday, $mon, $year) = localtime($_->{update_time});
+		$mon+=1;
+		$year+=1900;
+		my $abst;
+		utf8::decode($_->{description});
+		if (length($_->{description})>80){
+		    $abst = substr($_->{description},0,79)."...";
+		}else{
+		    $abst = $_->{description};
+		}		
+		utf8::encode($abst);
+		push @forums_param,
+		{
+			C_ID	=>	$_->{category_id},
+			F_ID	=>	$_->{forum_id},
+			TITLE	=>	$_->{title},
+			DESCRIPTION =>  $bb->n2br($abst),
+			USER	=>	$_->{user},
+			AFID	=>	$bb->getUserURI($_->{afid}),
+			TOPICS  =>  $_->{topics},
+			POSTS  =>  $_->{posts},
+			YEAR	=>	$year,
+			MONTH	=>	$mon,
+			DAY	=>	$mday,
+			TIME	=>	sprintf("%02d:%02d", $hour, $min),
+			LAST_USER =>$_->{last_user},
+			LAST_AFID =>$bb->getUserURI($_->{last_afid}),
+		};
+		$j++;
+	    }
+
+	    my $category_edit="1" if ($bb->getPermission("category_edit") && $bb->{afid} eq $_->{afid});
+	    $category_edit   ="1" if ($bb->{afap}->get_visitor_info("type") eq "self");
+	    my $msg="";
+	    if ($#forums+1 == 0){
+		$msg = 'Please add a new forum.';
+	    }
+	    push @categories_param,
+	    {
+		C_ID => $_->{category_id},
+		FORUM => [@forums_param[$i..($j-1)]],
+		TITLE	=>	$_->{title},   
+		HAS_FORUM => $#forums+1,
+		FORUM_EDIT => $forum_edit,
+		CATEGORY_EDIT => $category_edit,
+		MSG => $msg,
+	    };
+
+	    $i=$j;
+	}
+	$output_ref->{CATEGORIES} = \@categories_param;
+
+	debug_print("bb::Top::show end.");
+    }
+
+}
+1;
+
Index: affelio/apps/bb/bb/Topic.pm
diff -u /dev/null affelio/apps/bb/bb/Topic.pm:1.1
--- /dev/null	Thu Mar 23 12:46:14 2006
+++ affelio/apps/bb/bb/Topic.pm	Thu Mar 23 12:46:14 2006
@@ -0,0 +1,297 @@
+# Copyright (C) 2006 Affelio Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+
+package bb::Topic;
+{
+    use strict;
+    use Affelio::misc::Debug qw( debug_print);
+
+    use Exporter;
+    @bb::Topic::ISA = "Exporter";
+    @bb::Topic::EXPORT = qw (show handler);
+
+    #######################################################################
+    #handler
+    #######################################################################
+    sub handler{
+	my $cgi = shift;
+	my $bb = shift;
+	my $output_ref = shift;
+	#check access
+	$bb->errorExit('<AF_M text="Access denied">') unless ($bb->getPermission("topic_edit"));
+
+	debug_print("bb::Topic::handler: start.");
+
+	my $wi = new Affelio::misc::WebInput();
+	my $action = $wi->PTN_mode($cgi->param("action"));
+	my $new_forum = $wi->PTN_num($cgi->param("new_forum"));
+	$bb->errorExit('<AF_M text="Please specify the forum.">') if ($bb->{f_id} =~ /\D/ || $bb->{f_id} eq "");
+	my $title = $bb->escape_all($cgi->param("title"));
+	my $description = $bb->escape($cgi->param("description"));
+	my $status = $wi->PTN_num($cgi->param("status"));
+	my $pwd = $wi->PTN_password($cgi->param("pwd"));
+	my $status_edit = $bb->getPermission("topic_status") ? "1" : "0";
+	my $topic_delete = $bb->getPermission("topic_delete") ? "1" : "0";
+	$output_ref->{tmpl_file} = $bb->{afap}->{app__fs_root}."/templates/topic.tmpl";	
+	
+########### Add new topic  ####################################################
+	if ($action eq "add_topic"){
+	    add_Topic($bb, $output_ref, $title, $description, $bb->{afid}, $bb->{user}, $status_edit);
+########### Confirm topic  ####################################################
+	}elsif ($action eq "confirm_topic"){
+	    confirm_Topic($bb, $output_ref, $title, $description, $bb->{afid}, $bb->{user}, $status_edit, $status, $pwd);
+########### Submit topic  ####################################################
+	}elsif ($action eq "submit_topic"){
+	    submit_Topic($bb, $output_ref, $title, $description, $bb->{afid}, $bb->{user}, $status_edit, $status, $pwd);
+########### Edit topic mode ####################################################
+	}elsif ($action eq "edit_topic"){
+	    edit_Topic($bb, $output_ref, $bb->{afid}, $status_edit);
+	}else{
+	    $bb->errorExit('<AF_M text="Please specify the topic.">') if ($bb->{t_id} =~ /\D/ || $bb->{t_id} eq "");
+	    my $topic = $bb->getTopic($bb->{t_id});
+	    $bb->errorExit('<AF_M text="Authentication error.">') unless ($bb->checkAuthentication($bb->{pb_user}, $bb->{user}, $bb->{afid}, $pwd, $topic->{afid}, $topic->{pwd}));
+
+	    # Do update
+	    if($action eq "do_update"){
+		updateTopic($bb, $new_forum, $bb->{t_id}, $title, $description, $topic->{icon}, $bb->{user}, $bb->{afid},  $status, $topic->{lock});
+		$output_ref->{DONE} = "1";
+		$output_ref->{T_ID} = $bb->{t_id};
+		$output_ref->{MSG} = "The topic was updated.";
+
+		# Lock/unlock topic
+	    }elsif($action eq "lock" && $status_edit){
+		updateTopic($bb, $new_forum, $bb->{t_id}, $topic->{title}, $topic->{description}, $topic->{icon}, $bb->{user}, $bb->{afid},  $topic->{status}, abs($topic->{lock}-1));
+		if ($topic->{lock}){
+		    $output_ref->{MSG}="The topic was unlocked.";
+		}else{
+		    $output_ref->{MSG}="The topic was locked.";
+		}
+		$output_ref->{DONE} = "1";
+		$output_ref->{T_ID} = $bb->{t_id};
+		# Confirm delete topic
+	    }elsif($action eq "confirm_delete" && $topic_delete){
+		    $output_ref->{CONFIRM_DELETE} = "1";
+		    $output_ref->{T_ID} = $bb->{t_id};
+		    $output_ref->{F_ID} = $bb->{f_id};
+		    $output_ref->{PB_USER} = "1" if ($bb->{pb_user});
+		    $output_ref->{PWD} = $pwd;
+		    $output_ref->{USER} = $bb->{user};
+		    $output_ref->{MSG} = "Do you really delete this article?";
+		# Do delete
+	    }elsif($action eq "do_delete" && $topic_delete){
+		deleteTopic($bb, $bb->{t_id},$bb->{f_id});
+		$output_ref->{DONE} = "1";
+		$output_ref->{T_ID} = $bb->{t_id};
+		$output_ref->{MSG} = "The topic was deleted.";
+	    } else {
+		$bb->errorExit('<AF_M text="Error: Unknown access.">');
+	    }
+	}
+	debug_print("bb::Topic::handler: end.");
+}
+
+sub add_Topic {
+    my ($bb, $output_ref, $title, $description, $afid, $user, $status_edit) =@_;
+    $output_ref->{NEW}		=	"1";
+    $output_ref->{F_ID}		=	$bb->{f_id};
+    $output_ref->{TITLE}	=	$title;
+    $output_ref->{DESCRIPTION}	=	$description;
+    $output_ref->{STATUS_EDIT}	=	$status_edit;
+    $output_ref->{PB_USER}	=	$bb->{pb_user};
+    $output_ref->{AFID}		=	$afid;
+    $output_ref->{USER}		=	$user;
+}
+
+sub confirm_Topic {
+    my ($bb, $output_ref, $title, $description, $afid, $user, $status_edit, $status, $pwd) =@_;
+    $bb->errorExit('<AF_M text="Please input a title.">') if ($title eq "");
+    $bb->errorExit('<AF_M text="Please input a description.">') if ($description eq "");
+    $bb->errorExit('<AF_M text="Please input your nickname.">') if ($user eq "");
+    $bb->checkPwd($pwd) if ($bb->{pb_user} eq "1");
+    my $status_str;
+    if ($status eq "0"){
+	$status_str = '<AF_M text="Default">';
+    }elsif ($status eq "1"){
+	$status_str = '<AF_M text="Sticky">';
+    }elsif ($status eq "2"){
+	$status_str = '<AF_M text="Announcement">';
+    }    
+
+    $output_ref->{CONFIRM}	=	"1";
+    $output_ref->{F_ID}		=	$bb->{f_id};
+    $output_ref->{TITLE}	=	$title;
+    $output_ref->{DESCRIPTION_SHOW}=	$bb->n2br($description);
+    $output_ref->{DESCRIPTION}	=	$description;
+    $output_ref->{STATUS}	=	$status;
+    $output_ref->{STATUS_STR}	=	$status_str;
+    $output_ref->{STATUS_EDIT}	=	$status_edit;
+    $output_ref->{PB_USER}	=	$bb->{pb_user};
+    $output_ref->{AFID}		=	$afid;
+    $output_ref->{PWD}		=	$pwd;
+    $output_ref->{USER}		=	$user;
+}
+
+sub submit_Topic {
+    my ($bb, $output_ref, $title, $description, $afid, $user, $status_edit, $status, $pwd) =@_;
+    $bb->errorExit('<AF_M text="Please input a title.">') if ($title eq "");
+    $bb->errorExit('<AF_M text="Please input a description.">') if ($description eq "");
+    $bb->errorExit('<AF_M text="Please input your nickname.">') if ($user eq "");
+    $bb->errorExit('<AF_M text="Please input a password.">') if ($pwd eq "" && $bb->{pb_user});
+
+    my $icon="";
+    $status=0 unless ($status_edit);
+    my $topic_id=addTopic($bb, $bb->{f_id}, $title, $description, $icon,$user, $afid, $pwd, $status);
+
+    my $current_forum = $bb->getForum($bb->{f_id});
+    $bb->updateCategoryInfo($current_forum->{category_id}, $user, $afid);
+    $bb->createReplyTable($topic_id);
+
+    $output_ref->{DONE}	=	"1";
+    $output_ref->{T_ID}	=	$topic_id;
+    $output_ref->{MSG}	=	"New Topic was created.";
+}
+
+sub edit_Topic {
+    my ($bb, $output_ref, $afid, $status_edit) =@_;
+    $bb->errorExit('<AF_M text="Please specify the topic.">') if ($bb->{t_id} =~ /\D/ || $bb->{t_id} eq "");
+    my $topic = $bb->getTopic($bb->{t_id});
+    my $auth=0;
+    my $can_delete = 1 if ($bb->getPermission("topic_delete"));
+
+    if ($bb->{afap}->get_visitor_info("type") eq "self"){
+	$output_ref->{PWD} = "0";
+    }elsif ($bb->{pb_user} eq "0"){
+	if ($topic->{pwd} eq "" && $topic->{afid} eq $afid){
+	    $output_ref->{PWD} = "0";
+	} else {
+	    $bb->errorExit('<AF_M text="Authentication error.">');
+	}
+    }elsif($topic->{pwd} ne ""){
+	$output_ref->{PWD} = "1";
+    }
+    
+    my $current_forum = $bb->getForum($bb->{f_id});
+    my @forums = $bb->getall("SELECT * FROM $bb->{forum_tb} WHERE category_id = $current_forum->{category_id} ORDER BY forum_id");
+    my @forums_list;
+    foreach(@forums) {
+	my $selected = 1 if ($_->{forum_id} == $bb->{f_id});
+	push @forums_list,
+	{
+	    F_ID	=>	$_->{forum_id},
+	    TITLE	=>	$_->{title},
+	    SELECTED    =>      $selected,
+	};
+    }
+    $topic->{description} =~ s/<br[^>]*>/\n/g;
+    $output_ref->{EDIT} = "1";
+    $output_ref->{T_ID} = $bb->{t_id};
+    $output_ref->{F_ID} = $bb->{f_id};
+    $output_ref->{USER} = $topic->{user};
+    $output_ref->{TITLE} = $topic->{title};
+    $output_ref->{DESCRIPTION} = $topic->{description};
+    $output_ref->{AFID} = $topic->{afid};
+    $output_ref->{STATUS_EDIT} = $status_edit;
+    $output_ref->{STATUS} = $topic->{status};
+    $output_ref->{CAN_DELETE} = $can_delete;
+    $output_ref->{FORUM_LIST} = \@forums_list;
+}
+
+##############################################
+# addTopic
+##############################################
+
+sub addTopic {
+    my ($self, $forum_id,$title, $description, $icon,$user, $afid, $pwd,$status) = @_;
+    my $time = time;
+    my $crypt="";
+    my $num_topics = 0;
+    my $num_posts = 0;
+    $crypt = $self->cryptPwd($pwd)	if ($pwd ne "");
+    $self->checkContent($title, $user, $afid, $description, $icon, $pwd);
+    
+    my @same = $self->getall("SELECT topic_id FROM $self->{topic_tb} WHERE title='$title'");
+    $self->errorExit('<AF_M text="A topic of the proposed name already exists.">') if($#same >= 0);
+    
+    $self->{dbh}->do("INSERT INTO $self->{topic_tb} (forum_id, title, description, icon, user, afid, pwd, last_user, last_afid, view, posts, status, lock,timestamp, update_time) VALUES ($forum_id, '$title', '$description', '$icon', '$user', '$afid', '$crypt', '$user', '$afid', 0, 0, $status, 0, $time, $time)");
+    
+    my $topic_id=$self->getColumn("SELECT MAX(topic_id) FROM $self->{topic_tb} WHERE forum_id = $forum_id");
+
+    $num_topics = $self->getColumn("SELECT count(forum_id) FROM $self->{topic_tb} WHERE forum_id=$forum_id");
+    $num_posts = $self->getColumn("SELECT sum(posts) FROM $self->{topic_tb} WHERE forum_id=$forum_id");
+    $num_posts = $num_posts+$num_topics;
+    $self->{dbh}->do("UPDATE $self->{forum_tb} SET topics = $num_topics, posts = $num_posts, last_user = '$user', last_afid = '$afid', update_time = $time WHERE forum_id = $forum_id");
+
+    $self->{afap}->post_news($title, "", $user,
+		     $self->{afap}->get_site_info("web_root") . "/apps/". 
+		     $self->{afap}->{install_name} . "/view_topic.cgi?t_id=".$topic_id);
+    $description =~ s/<br[^>]*>/\n/g;
+    $self->sendBbMail("新しいトピック「$title」が$userさんによって作成されました。\n\n-----\n$description\n\n$self->{afap}->{app__web_root}/view_topic.cgi?t_id=$topic_id", $title);
+    
+    return $topic_id;
+}
+
+
+##############################################
+# updateTopic
+##############################################
+
+sub updateTopic {
+    my ($self, $forum_id, $topic_id,$title, $description, $icon,$user, $afid, $status,$lock) = @_;
+    my $time = time;
+    $self->checkContent($title, $user, $afid, $description, $icon, "");
+    
+    my @same = $self->getall("SELECT topic_id FROM $self->{topic_tb} WHERE title='$title'");
+    $self->errorExit('<AF_M text="A topic of the proposed name already exists.">') if($#same >= 1);
+    
+    my $forum_old = $self->getColumn("SELECT forum_id FROM $self->{topic_tb} WHERE topic_id = $topic_id");
+    $self->{dbh}->do("UPDATE $self->{topic_tb} SET forum_id = $forum_id, title='$title', description='$description', icon='$icon', status=$status, lock=$lock, user = '$user', afid = '$afid', timestamp = $time WHERE topic_id = $topic_id");
+    if ($forum_old ne $forum_id){
+	updateForumCount($self,$forum_old);
+	updateForumCount($self,$forum_id);
+    }
+#    $description =~ s/<br[^>]*>/\n/g;
+#    $self->sendBbMail("トピック「$title」の内容が$userさんによって更新されました。\n\n-----\n$description\n\n$self->{afap}->{app__web_root}/view_topic.cgi?t_id=$topic_id", $title);
+
+    return $topic_id;
+}
+
+##############################################
+# deleteTopic
+##############################################
+
+sub deleteTopic {
+    my ($self, $topic_id, $forum_id) = @_;
+    my $reply_tb = "AFuser_bb_$self->{afap}->{install_name}_reply_".$topic_id;
+    $self->{dbh}->do("DELETE FROM $self->{topic_tb} WHERE topic_id = $topic_id");
+    $self->{dbh}->do("DROP TABLE $reply_tb");
+    updateForumCount($self,$forum_id);
+}
+
+##############################################
+# updateForumCount
+##############################################
+sub updateForumCount {
+    my ($self, $forum_id) = @_;
+    my $num_topics = $self->getColumn("SELECT count(topic_id) FROM $self->{topic_tb} WHERE forum_id=$forum_id");
+    my $num_posts = $self->getColumn("SELECT sum(posts) FROM $self->{topic_tb} WHERE forum_id=$forum_id");
+    $num_posts += $num_topics;
+    $self->{dbh}->do("UPDATE $self->{forum_tb} SET topics = $num_topics, posts = $num_posts WHERE forum_id = $forum_id");
+
+}
+
+}
+1;
Index: affelio/apps/bb/bb/ViewForum.pm
diff -u /dev/null affelio/apps/bb/bb/ViewForum.pm:1.1
--- /dev/null	Thu Mar 23 12:46:14 2006
+++ affelio/apps/bb/bb/ViewForum.pm	Thu Mar 23 12:46:14 2006
@@ -0,0 +1,147 @@
+# Copyright (C) 2006 Affelio Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+
+package bb::ViewForum;
+{
+    use strict;
+    use utf8;
+    use Affelio::misc::Debug qw( debug_print);
+
+    use Exporter;
+    @bb::ViewForum::ISA = "Exporter";
+    @bb::ViewForum::EXPORT = qw (show handler);
+
+
+    #######################################################################
+    #handler
+    #######################################################################
+    sub handler{
+	my $cgi = shift;
+	my $bb = shift;
+	my $output_ref = shift;
+	
+	debug_print("bb::ViewForum::handler: start.");
+
+	$bb->errorExit('<AF_M text="Please specify the forum.">') if ($bb->{f_id} =~ /\D/ || $bb->{f_id} eq "");
+	$output_ref->{tmpl_file}
+	= $bb->{afap}->{app__fs_root}."/templates/view_forum.tmpl";
+
+	my %pref = $bb->getPreference;
+	my @topic_list;
+	my @topics;
+	my $icon;
+	my $last_user;
+	my $last_afid;
+	my $current_forum = $bb->getForum($bb->{f_id});
+	my $category = $bb->getColumn("SELECT title FROM $bb->{category_tb} WHERE category_id=$current_forum->{category_id}");
+	my $can_add="";
+	my $can_edit="";
+	my $opt_msg="";
+	$can_add=1 if ($bb->getPermission("topic_edit"));
+	if ($bb->getPermission("forum_edit")){
+	    if ($bb->{pb_user} eq "0"){
+		if ($current_forum->{pwd} eq "" && $current_forum->{afid} eq $bb->{afid}){
+		    $can_edit = 1;
+		} 
+	    }elsif($current_forum->{pwd} ne ""){
+		$can_edit = 1;
+	    }
+	}
+	$can_edit=1 if ($bb->{afap}->get_visitor_info("type") eq "self");
+
+########### Get Topic List ####################################################
+	@topics = $bb->getall("SELECT * FROM $bb->{topic_tb} WHERE forum_id = $bb->{f_id} ORDER BY status DESC, update_time DESC");
+	if ($#topics+1 >= int($bb->getColumn("SELECT value FROM $bb->{pref_tb} WHERE key = 'max_topics'"))){
+	    $can_add = "";
+	    $opt_msg = '<AF_M text="This forum was cloesd. Please make a new forum.">';
+	}
+
+########### Get current time ####################################################
+	my ($sec, $min, $hour, $mday, $mon, $year) = localtime($current_forum->{timestamp});
+	$mon+=1;
+	$year+=1900;
+
+########### Set forum info ####################################################
+	$output_ref->{PAGE_TITLE}	=	$pref{"title"};
+	$output_ref->{F_ID}		=	$bb->{f_id};
+	$output_ref->{CATEGORY} 	=	$category;
+	$output_ref->{FORUM_NAME}	=	$current_forum->{title};
+	$output_ref->{FORUM_DESCRIPTION}= $bb->n2br($current_forum->{description});
+	$output_ref->{AFID}		=	$bb->getUserURI($current_forum->{afid});
+	$output_ref->{MODERATOR}	=	$current_forum->{user};
+	$output_ref->{YEAR}		=	$year;
+	$output_ref->{MONTH}		=	$mon;
+	$output_ref->{DAY}		=	$mday;
+	$output_ref->{TIME}		=	sprintf("%02d:%02d", $hour, $min);
+	$output_ref->{CAN_ADD}		=	$can_add;
+	$output_ref->{CAN_EDIT} 	=	$can_edit;
+	$output_ref->{OPT_MSG}		=	$opt_msg;
+	$output_ref->{HAS_TOPIC}	=	$#topics+1;
+
+########### Set Topic List ####################################################
+	foreach(@topics) {
+	    my $abst;
+	    my ($sec, $min, $hour, $mday, $mon, $year) = localtime($_->{update_time});
+	    $mon+=1;
+	    $year+=1900;
+	    if($_->{status} == 1){
+		$icon="sticky";
+	    }elsif($_->{status} == 2){
+		$icon="announce";
+	    }else{
+		$icon="normal";
+	    }
+	    if ($_->{lock} == 1){
+		$icon.="_lock";
+	    }
+	    $icon.=".gif";
+	    if ($_->{posts}<1) {
+		$last_user=$_->{user};
+		$last_afid=$_->{afid};
+	    }
+	    utf8::decode($_->{description});
+	    if (length($_->{description})>50){
+		$abst = substr($_->{description},0,50)."...";
+	    }else{
+		$abst = $_->{description};
+	    }
+	    utf8::encode($abst);
+	    
+	    push @topic_list,
+	    {
+		T_ID		=>	$_->{topic_id},
+		TITLE		=>	$_->{title},
+		ABST		=>	$bb->n2br($abst),
+		POSTS		=>	$_->{posts},
+		USER		=>	$_->{user},
+		AFID		=>	$bb->getUserURI($_->{afid}),
+		VIEWS		=>	$_->{view},
+		YEAR		=>	$year,
+		MONTH		=>	$mon,
+		DAY			=>	$mday,
+		TIME		=>	sprintf("%02d:%02d", $hour, $min),
+		LAST_USER	=>	$_->{last_user},
+		LAST_AFID	=>	$bb->getUserURI($_->{last_afid}),
+		ICON		=>	$icon,
+	    };
+	}
+	
+	$output_ref->{TOPIC_LIST} = \@topic_list;
+}
+
+}
+1;
Index: affelio/apps/bb/bb/ViewTopic.pm
diff -u /dev/null affelio/apps/bb/bb/ViewTopic.pm:1.1
--- /dev/null	Thu Mar 23 12:46:14 2006
+++ affelio/apps/bb/bb/ViewTopic.pm	Thu Mar 23 12:46:14 2006
@@ -0,0 +1,224 @@
+# Copyright (C) 2006 Affelio Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+
+package bb::ViewTopic;
+{
+    use strict;
+    use Affelio::misc::Debug qw( debug_print);
+
+    use Exporter;
+    @bb::ViewTopic::ISA = "Exporter";
+    @bb::ViewTopic::EXPORT = qw (show handler);
+
+
+    #######################################################################
+    #handler
+    #######################################################################
+    sub handler{
+	my $cgi = shift;
+	my $bb = shift;
+	my $output_ref = shift;
+	debug_print("bb::ViewTopic::handler: start.");
+
+	my $wi = new Affelio::misc::WebInput();
+	my $page = $wi->PTN_num($cgi->url_param("page"));
+	$page=1 if ($page eq "");
+	$bb->errorExit('<AF_M text="Please specify the page correctly.">') if ($page =~ /\D/);
+	$bb->errorExit('<AF_M text="Please specify the topic.">') if ($bb->{t_id} =~ /\D/ || $bb->{t_id} eq "");
+	$bb->errorExit('<AF_M text="The topic was not found.">') if (!(my $current_topic = $bb->getTopic($bb->{t_id})));
+	my %pref = $bb->getPreference;
+	my @reply_list;
+	my @replies;
+	my $can_reply="";
+	my $opt_msg="";
+	my $current_forum = $bb->getForum($current_topic->{forum_id});
+	my $current_category = getCategory($bb, $current_forum->{category_id});
+	$output_ref->{tmpl_file}
+	= $bb->{afap}->{app__fs_root}."/templates/view_topic.tmpl";
+	
+	addViewCountTopic($bb, $bb->{t_id});
+	
+####### Can you reply to this topic?  ##########################################
+	$can_reply="1" if ($bb->getPermission("comment_edit"));
+	if ($current_topic->{lock}) {
+	    $can_reply = "";
+	    $opt_msg = '<AF_M text="This topic is locked.">';
+	}
+	
+####### Can you edit this topic?  ##############################################
+	my $can_edit="";
+	if ($bb->getPermission("topic_edit")){
+	    if ($bb->{pb_user} eq "0"){
+		if ($current_topic->{pwd} eq "" && $current_topic->{afid} eq $bb->{afid}){
+		    $can_edit = 1;
+		} 
+	    }elsif($current_topic->{pwd} ne ""){
+		$can_edit = 1;
+	    }
+	}
+	$can_edit=1 if ($bb->{afap}->get_visitor_info("type") eq "self");
+	
+####### Get current time  ######################################################
+	my ($sec, $min, $hour, $mday, $mon, $year) = localtime($current_topic->{timestamp});
+	$mon+=1;
+	$year+=1900;
+	my $reply_tb = "AFuser_bb_$bb->{afap}->{install_name}_reply_".$bb->{t_id};
+	my $rep_count = $bb->getColumn("SELECT count(reply_id) FROM $reply_tb");
+	if ($rep_count >= int($bb->getColumn("SELECT value FROM $bb->{pref_tb} WHERE key = 'max_comments'"))){
+	    $can_reply = "";
+	    $opt_msg = '<AF_M text="This topic was cloesd. Please make a new topic.">';
+	}
+	
+########### Set page index  ####################################################
+	use integer;
+	my @page_index;
+	my $num_comments = $bb->getColumn("SELECT value FROM $bb->{pref_tb} WHERE key = 'num_comments'");
+	my $i = (($rep_count-1)/$num_comments)+1;
+	my $page_num = $i;
+	while ($i>0){
+	    unshift @page_index,
+	    {
+		page => $i,
+		p_id => $i,
+		F_ID => $current_topic->{forum_id},
+		T_ID => $bb->{t_id},
+	    };
+	    $i--;
+	}
+	no integer;
+	@replies = getReplies($bb, $bb->{t_id}, ($page_num-$page)*$num_comments+$num_comments, ($page_num-$page)*$num_comments+1);
+	
+########### Set topic info  ####################################################
+
+	$output_ref->{PAGE_TITLE}	=	$pref{"title"};
+	$output_ref->{CATEGORY} 	=	$current_category->{title};
+	$output_ref->{FORUM}		=	$current_forum->{title};
+	$output_ref->{F_ID}		=	$current_topic->{forum_id};
+	$output_ref->{T_ID}		=	$bb->{t_id};
+	$output_ref->{TOPIC_NAME}	=	$current_topic->{title};
+	$output_ref->{TOPIC_USER}	=	$current_topic->{user};
+	$output_ref->{TOPIC_AFID}	=	$bb->getUserURI($current_topic->{afid});
+	$output_ref->{CAN_EDIT} 	=	$can_edit;
+	$output_ref->{CAN_REPLY}	=	$can_reply;
+	$output_ref->{PB_USER}		=	$bb->{pb_user};
+	$output_ref->{REPLY_TITLE}	=	"RE:$current_topic->{title}";
+	$output_ref->{USER_NAME}	=	$bb->{user};
+	$output_ref->{AFID}		=	$bb->{afid};
+	$output_ref->{OPT_MSG}		=	$opt_msg;
+	$output_ref->{PAGE_INDEX}	=	\@page_index;
+	$output_ref->{YEAR}		=	$year;
+	$output_ref->{MONTH}		=	$mon;
+	$output_ref->{DAY}		=	$mday;
+	$output_ref->{TIME}		=	sprintf("%02d:%02d", $hour, $min);
+	$output_ref->{HAS_REPLY}	=	$#replies+1;
+	$output_ref->{TOPIC_DESCRIPTION}= $bb->n2br($current_topic->{description});
+
+####### Set comments ####################################################
+	foreach(@replies) {
+	    my $can_edit="";
+	    my ($sec, $min, $hour, $mday, $mon, $year) = localtime($_->{timestamp});
+	    $mon+=1;
+	    $year+=1900;
+
+	    if ($bb->getPermission("comment_delete")){	    
+		if ($can_reply){
+		    if ($bb->{pb_user} eq "0"){
+			if ($_->{pwd} eq "" && $_->{afid} eq $bb->{afid}){
+			    $can_edit = 1;
+			} 
+		    }elsif($_->{pwd} ne ""){
+			$can_edit = 1;
+		    }
+		}
+	    }
+	    $can_edit=1 if ($bb->{afap}->get_visitor_info("type") eq "self");
+	    $can_edit="" if ($_->{title} eq "" && $_->{user} eq "" && $_->{afid} eq "");
+	    my $uri = $bb->getUserURI($_->{afid}) unless ($_->{afid} eq "");
+	    
+	    push @reply_list,
+	    {
+		T_ID	=>	$bb->{t_id},
+		R_ID	=>	$_->{reply_id},
+		TITLE	=>	$_->{title},
+		USER	=>	$_->{user},
+		AFID	=>	$uri,
+		COMMENT	=>	$bb->n2br($bb->autolink($_->{comment})),
+		YEAR	=>	$year,
+		MONTH	=>	$mon,
+		DAY		=>	$mday,
+		TIME	=>	sprintf("%02d:%02d", $hour, $min),
+		CAN_EDIT=>	$can_edit,
+		ICON	=>	$_->{icon},
+	    };
+	}
+	$output_ref->{REPLY_LIST} = \@reply_list;
+	
+########### Set face icons ####################################################
+	if ($can_reply){
+	    my @face_list;
+	    my $face_dir = './resource/face';
+	    opendir DIR, "$face_dir";
+	    my @faces  = grep(!/^\.+/, readdir DIR);
+	    close DIR;
+	    
+	    foreach (@faces){
+		if ($_ eq ".") { next; }
+		if ($_ eq "..") { next; }
+		if ($_ eq "CVS") { next; }
+		if ($_ eq "owner.gif") { next; }
+		push @face_list,
+		{
+		    FACE => $_
+		};
+	    }
+	    $output_ref->{FACE_LIST} = \@face_list;
+	}
+}
+
+##############################################
+# addViewCountTopic
+##############################################
+
+sub addViewCountTopic {
+    my ($self, $topic_id) = @_;
+    $topic_id = $self->escape($topic_id, 'int');
+    $self->{dbh}->do("UPDATE $self->{topic_tb} SET view = view+1 WHERE topic_id = $topic_id");
+}
+
+##############################################
+# getCategory
+##############################################
+
+sub getCategory {
+    my ($self, $category_id) = @_;
+    $category_id = $self->escape($category_id, 'int');
+    my @ret = $self->getall("SELECT * FROM $self->{category_tb} WHERE category_id = $category_id");
+    return $ret[0];
+}
+
+##############################################
+# getReplies
+##############################################
+
+sub getReplies {
+    my ($self, $topic_id, $end, $start) = @_;
+    my $reply_tb = "AFuser_bb_$self->{afap}->{install_name}_reply_".$self->{t_id};
+    return $self->getall("SELECT * FROM $reply_tb WHERE reply_id BETWEEN $start AND $end");
+}
+
+}
+1;


Affelio-cvs メーリングリストの案内
Back to archive index