admin-settings.php
<?php
add_action('admin_menu', 'forum_settings_menu');
function forum_settings_menu() {
add_menu_page('Forum Settings', 'Forum Settings', 'manage_options', 'forum-settings', 'forum_settings_page');
add_submenu_page('forum-settings', 'フォーラム管理', 'フォーラム管理', 'manage_options', 'forum-manage', 'forum_manage_page');
}
function forum_settings_page() {
if (isset($_POST['save_settings'])) {
update_option('points_per_like', intval($_POST['points_per_like']));
update_option('max_posts_per_thread', intval($_POST['max_posts_per_thread']));
$titles = [];
foreach ($_POST['title_points'] as $i => $points) {
if (!empty($points) && !empty($_POST['title_names'][$i])) {
$titles[] = [
'points' => intval($points),
'title' => sanitize_text_field($_POST['title_names'][$i])
];
}
}
update_option('forum_titles', $titles);
}
$points_per_like = get_option('points_per_like', 1);
$max_posts_per_thread = get_option('max_posts_per_thread', 100);
$titles = get_option('forum_titles', [
['points' => 0, 'title' => '初心者'],
['points' => 20, 'title' => '中級者'],
['points' => 50, 'title' => '上級者'],
['points' => 100, 'title' => 'フォーラムマスター']
]);
?>
<div class="wrap">
<h1>フォーラム設定</h1>
<form method="post">
<label>いいねごとのポイント:
<input type="number" name="points_per_like" value="<?php echo esc_attr($points_per_like); ?>" min="1">
</label><br>
<label>スレッドごとの最大投稿数:
<input type="number" name="max_posts_per_thread" value="<?php echo esc_attr($max_posts_per_thread); ?>" min="1">
</label><br>
<h2>称号設定</h2>
<div id="titles-container">
<?php foreach ($titles as $i => $t) : ?>
<div class="title-row">
<input type="number" name="title_points[]" value="<?php echo esc_attr($t['points']); ?>" min="0">
<input type="text" name="title_names[]" value="<?php echo esc_attr($t['title']); ?>">
<button type="button" class="remove-title">削除</button>
</div>
<?php endforeach; ?>
</div>
<button type="button" id="add-title">称号を追加</button><br>
<input type="submit" name="save_settings" value="保存" class="button-primary">
</form>
</div>
<script>
jQuery(document).ready(function($) {
$('#add-title').on('click', function() {
$('#titles-container').append('<div class="title-row"><input type="number" name="title_points[]" min="0"><input type="text" name="title_names[]"><button type="button" class="remove-title">削除</button></div>');
});
$(document).on('click', '.remove-title', function() {
$(this).closest('.title-row').remove();
});
});
</script>
<?php
}
function forum_manage_page() {
global $wpdb;
if (isset($_POST['add_forum'])) {
$forum_name = sanitize_text_field($_POST['forum_name']);
$wpdb->insert("{$wpdb->prefix}forum_forums", ['forum_name' => $forum_name]);
}
if (isset($_POST['delete_forum'])) {
$forum_id = intval($_POST['forum_id']);
$wpdb->delete("{$wpdb->prefix}forum_forums", ['id' => $forum_id]);
}
$forums = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}forum_forums");
?>
<div class="wrap">
<h1>フォーラム管理</h1>
<form method="post">
<label>フォーラム名: <input type="text" name="forum_name" required></label>
<input type="submit" name="add_forum" value="追加" class="button-primary">
</form>
<h2>登録済みフォーラム</h2>
<ul>
<?php foreach ($forums as $forum) : ?>
<li>
<?php echo esc_html($forum->forum_name); ?>
<form method="post" style="display:inline;">
<input type="hidden" name="forum_id" value="<?php echo $forum->id; ?>">
<input type="submit" name="delete_forum" value="削除" class="button-secondary">
</form>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php
}
database.php
<?php
function my_forum_install() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$sql_forums = "CREATE TABLE {$wpdb->prefix}forum_forums (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
forum_name VARCHAR(255) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) $charset_collate;";
$sql_threads = "CREATE TABLE {$wpdb->prefix}forum_threads (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
forum_id BIGINT(20) UNSIGNED NOT NULL,
thread_title VARCHAR(255) NOT NULL,
author_id BIGINT(20) UNSIGNED NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
post_count INT DEFAULT 0,
last_poster_id BIGINT(20) UNSIGNED,
PRIMARY KEY (id),
FOREIGN KEY (forum_id) REFERENCES {$wpdb->prefix}forum_forums(id) ON DELETE CASCADE
) $charset_collate;";
$sql_posts = "CREATE TABLE {$wpdb->prefix}forum_posts (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
thread_id BIGINT(20) UNSIGNED NOT NULL,
parent_post_id BIGINT(20) UNSIGNED DEFAULT NULL,
content TEXT NOT NULL,
author_id BIGINT(20) UNSIGNED NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
post_number INT NOT NULL,
likes INT DEFAULT 0,
PRIMARY KEY (id),
FOREIGN KEY (thread_id) REFERENCES {$wpdb->prefix}forum_threads(id) ON DELETE CASCADE
) $charset_collate;";
$sql_points = "CREATE TABLE {$wpdb->prefix}forum_points (
user_id BIGINT(20) UNSIGNED NOT NULL,
points INT DEFAULT 0,
title VARCHAR(255) DEFAULT '初心者',
PRIMARY KEY (user_id)
) $charset_collate;";
$sql_likes = "CREATE TABLE {$wpdb->prefix}forum_likes (
user_id BIGINT(20) UNSIGNED NOT NULL,
post_id BIGINT(20) UNSIGNED NOT NULL,
PRIMARY KEY (user_id, post_id),
FOREIGN KEY (post_id) REFERENCES {$wpdb->prefix}forum_posts(id) ON DELETE CASCADE
) $charset_collate;";
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
dbDelta($sql_forums);
dbDelta($sql_threads);
dbDelta($sql_posts);
dbDelta($sql_points);
dbDelta($sql_likes);
}
like-functions.php
<?php
add_action('wp_ajax_add_like', 'add_like_callback');
function add_like_callback() {
$post_id = intval($_POST['post_id']);
// いいね数を更新し、ポイントを加算
wp_die();
}
notification-functions.php
<?php
function add_notification_button() {
echo '<a href="' . site_url('/notifications') . '">通知</a>';
}
add_action('wp_footer', 'add_notification_button');
thread-functions.php
<?php
// includes/thread-functions.php
function create_forum_thread() {
if (isset($_POST['create_thread']) && is_user_logged_in()) {
global $wpdb;
$forum_id = intval($_POST['forum_id']);
$thread_title = sanitize_text_field($_POST['thread_title']);
$first_post = sanitize_textarea_field($_POST['first_post']);
$user_id = get_current_user_id();
$result = $wpdb->insert(
"{$wpdb->prefix}forum_threads",
[
'forum_id' => $forum_id,
'thread_title' => $thread_title,
'author_id' => $user_id,
'created_at' => current_time('mysql'),
'post_count' => 1,
'last_poster_id' => $user_id
]
);
if ($result === false) {
wp_die('スレッド作成エラー: ' . $wpdb->last_error);
}
$thread_id = $wpdb->insert_id;
$post_result = $wpdb->insert(
"{$wpdb->prefix}forum_posts",
[
'thread_id' => $thread_id,
'content' => $first_post,
'author_id' => $user_id,
'post_number' => 1,
'created_at' => current_time('mysql')
]
);
if ($post_result === false) {
wp_die('投稿作成エラー: ' . $wpdb->last_error);
}
$points_per_post = 1;
$wpdb->query("INSERT INTO {$wpdb->prefix}forum_points (user_id, points) VALUES ($user_id, $points_per_post) ON DUPLICATE KEY UPDATE points = points + $points_per_post");
update_user_title($user_id);
if ($thread_id) {
wp_redirect(site_url("/thread-page/?forum_id=$forum_id&thread_id=$thread_id"));
exit;
} else {
wp_die('スレッドID取得に失敗しました');
}
}
}
add_action('init', 'create_forum_thread');
function create_forum_post() {
if (isset($_POST['submit_post']) && is_user_logged_in()) {
global $wpdb;
$thread_id = intval($_POST['thread_id']);
$content = sanitize_textarea_field($_POST['content']);
$user_id = get_current_user_id();
$parent_post_id = !empty($_POST['parent_post_id']) ? intval($_POST['parent_post_id']) : null;
$post_count = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}forum_posts WHERE thread_id = $thread_id");
$max_posts = get_option('max_posts_per_thread', 100);
if ($post_count >= $max_posts) {
echo '<p class="error">このスレッドの投稿数が上限(' . $max_posts . ')に達しました。</p>';
return;
}
$post_number = $post_count + 1;
$result = $wpdb->insert(
"{$wpdb->prefix}forum_posts",
[
'thread_id' => $thread_id,
'content' => $content,
'author_id' => $user_id,
'parent_post_id' => $parent_post_id,
'post_number' => $post_number,
'created_at' => current_time('mysql')
]
);
if ($result === false) {
wp_die('投稿エラー: ' . $wpdb->last_error);
}
$wpdb->update(
"{$wpdb->prefix}forum_threads",
['post_count' => $post_count + 1, 'last_poster_id' => $user_id],
['id' => $thread_id]
);
$points_per_post = 1;
$wpdb->query("INSERT INTO {$wpdb->prefix}forum_points (user_id, points) VALUES ($user_id, $points_per_post) ON DUPLICATE KEY UPDATE points = points + $points_per_post");
update_user_title($user_id);
$forum_id = $wpdb->get_var("SELECT forum_id FROM {$wpdb->prefix}forum_threads WHERE id = $thread_id");
wp_redirect(site_url("/thread-page/?forum_id=$forum_id&thread_id=$thread_id"));
exit;
}
}
add_action('init', 'create_forum_post');
function delete_forum_thread() {
if (isset($_POST['delete_thread']) && current_user_can('manage_options')) {
global $wpdb;
$thread_id = intval($_POST['thread_id']);
$wpdb->delete("{$wpdb->prefix}forum_threads", ['id' => $thread_id]);
wp_redirect(site_url('/forum-page/')); // スレッド一覧ページにリダイレクト
exit;
}
}
add_action('init', 'delete_forum_thread');
function display_my_forum($atts) {
ob_start();
global $wpdb;
$threads = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}forum_threads");
include plugin_dir_path(__FILE__) . '../templates/forum-list.php';
return ob_get_clean();
}
add_shortcode('my_forum', 'display_my_forum');
// includes/thread-functions.php
function display_my_thread($atts) {
ob_start();
global $wpdb;
$forum_id = intval($_GET['forum_id'] ?? 0);
$thread_id = intval($_GET['thread_id'] ?? 0);
if ($forum_id && $thread_id) {
$thread = $wpdb->get_row(
$wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}forum_threads WHERE forum_id = %d AND id = %d",
$forum_id,
$thread_id
)
);
if ($thread) {
$posts = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}forum_posts WHERE thread_id = {$thread->id} ORDER BY post_number");
include plugin_dir_path(__FILE__) . '../templates/thread-view.php';
} else {
echo '<p>スレッドが見つかりません。</p>';
}
} else {
echo '<p>スレッドを指定してください。</p>';
}
return ob_get_clean();
}
add_shortcode('my_thread', 'display_my_thread');
user-functions.php
<?php
function can_user_post($user_id) {
return current_user_can('read');
}
function restrict_access($user_id, $thread_id) {
// 特定のユーザーグループに対する制限ロジック
}
コメント