高級模塊示例
高級模塊示例 - 論壇
Section titled “高級模塊示例 - 論壇”一個綜合的”論壇”模塊,展示高級模式:多個實體類型、關係、複雜管理界面和通知。
forum/├── xoops_version.php├── class/│ ├── Repository/│ │ ├── ForumRepository.php│ │ ├── TopicRepository.php│ │ └── PostRepository.php│ ├── Entity/│ │ ├── Forum.php│ │ ├── Topic.php│ │ └── Post.php│ ├── Service/│ │ ├── ForumService.php│ │ └── TopicService.php│ └── Handler/│ └── NotificationHandler.php├── templates/│ ├── forum_list.html│ ├── topic_view.html│ └── admin/dashboard.html└── sql/mysql.sql-- 論壇CREATE TABLE `xoops_forum_forums` ( `forum_id` INT AUTO_INCREMENT PRIMARY KEY, `forum_name` VARCHAR(255) NOT NULL, `forum_description` TEXT, `forum_order` INT, `forum_created` INT NOT NULL);
-- 主題CREATE TABLE `xoops_forum_topics` ( `topic_id` INT AUTO_INCREMENT PRIMARY KEY, `topic_forum_id` INT NOT NULL, `topic_author_id` INT NOT NULL, `topic_title` VARCHAR(255) NOT NULL, `topic_post_count` INT DEFAULT 1, `topic_view_count` INT DEFAULT 0, `topic_created` INT NOT NULL, FOREIGN KEY (`topic_forum_id`) REFERENCES `xoops_forum_forums`(`forum_id`));
-- 帖子CREATE TABLE `xoops_forum_posts` ( `post_id` INT AUTO_INCREMENT PRIMARY KEY, `post_topic_id` INT NOT NULL, `post_forum_id` INT NOT NULL, `post_author_id` INT NOT NULL, `post_content` LONGTEXT NOT NULL, `post_created` INT NOT NULL, FOREIGN KEY (`post_topic_id`) REFERENCES `xoops_forum_topics`(`topic_id`));
-- 訂閱CREATE TABLE `xoops_forum_subscriptions` ( `subscription_id` INT AUTO_INCREMENT PRIMARY KEY, `subscription_user_id` INT NOT NULL, `subscription_topic_id` INT NOT NULL, UNIQUE (`subscription_user_id`, `subscription_topic_id`));<?phpclass Topic{ private $id; private $forumId; private $authorId; private $title; private $postCount = 1; private $viewCount = 0; private $createdAt;
// Getters and setters... public function getId() { return $this->id; } public function setId($id) { $this->id = $id; return $this; }
public function getForumId() { return $this->forumId; } public function setForumId($id) { $this->forumId = $id; return $this; }
public function getTitle() { return $this->title; } public function setTitle($t) { $this->title = $t; return $this; }
public function getPostCount() { return $this->postCount; } public function incrementPostCount() { $this->postCount++; return $this; }
public function getViewCount() { return $this->viewCount; } public function incrementViewCount() { $this->viewCount++; return $this; }}?>具有關係的 Repository
Section titled “具有關係的 Repository”<?phpclass TopicRepository{ private $db;
public function __construct($connection) { $this->db = $connection; }
public function getWithAuthorInfo($id) { $sql = "SELECT t.*, u.uname as author_name FROM " . $this->db->prefix('forum_topics') . " t LEFT JOIN " . $this->db->prefix('users') . " u ON t.topic_author_id = u.uid WHERE t.topic_id = ?";
$stmt = $this->db->prepare($sql); $stmt->bind_param('i', $id); $stmt->execute();
return $stmt->get_result()->fetch_assoc(); }
public function getByForumWithStats($forumId, $limit = 20, $offset = 0) { $sql = "SELECT t.*, u.uname as author_name, COUNT(p.post_id) as post_count FROM " . $this->db->prefix('forum_topics') . " t LEFT JOIN " . $this->db->prefix('users') . " u ON t.topic_author_id = u.uid LEFT JOIN " . $this->db->prefix('forum_posts') . " p ON t.topic_id = p.post_topic_id WHERE t.topic_forum_id = ? GROUP BY t.topic_id ORDER BY t.topic_created DESC LIMIT ?, ?";
$stmt = $this->db->prepare($sql); $stmt->bind_param('iii', $forumId, $offset, $limit); $stmt->execute();
$result = $stmt->get_result(); $topics = []; while ($row = $result->fetch_assoc()) { $topics[] = $row; }
return $topics; }}?>Service 層
Section titled “Service 層”<?phpclass TopicService{ private $topicRepository; private $postRepository; private $notificationHandler;
public function __construct( TopicRepository $topicRepository, PostRepository $postRepository, NotificationHandler $notificationHandler ) { $this->topicRepository = $topicRepository; $this->postRepository = $postRepository; $this->notificationHandler = $notificationHandler; }
public function createTopic($forumId, $userId, $title, $content) { // 驗證 if (strlen($title) < 3) { throw new \InvalidArgumentException('Title too short'); }
// 創建主題 $topic = new Topic(); $topic->setForumId($forumId) ->setAuthorId($userId) ->setTitle($title) ->setCreatedAt(new \DateTime());
$topicId = $this->topicRepository->save($topic);
// 創建第一個帖子 $this->postRepository->createPost($topicId, $forumId, $userId, $content);
// 通知訂閱者 $this->notificationHandler->notifyNewTopic($topicId);
return $topicId; }
public function getTopicWithPosts($topicId, $page = 1, $perPage = 20) { // 獲取具有作者信息的主題 $topic = $this->topicRepository->getWithAuthorInfo($topicId);
if (!$topic) { throw new \RuntimeException('Topic not found'); }
// 增加視圖計數 $topic['topic_view_count']++; $this->topicRepository->updateViewCount($topicId, $topic['topic_view_count']);
// 獲取帖子 $offset = ($page - 1) * $perPage; $posts = $this->postRepository->getByTopicId($topicId, $perPage, $offset);
return [ 'topic' => $topic, 'posts' => $posts, 'page' => $page, 'totalPages' => ceil($topic['topic_post_count'] / $perPage), ]; }}?>此示例演示:
- 實體關係 - 論壇包含主題,主題包含帖子
- 複雜查詢 - 帶有用戶信息和統計數據的連接
- Service 協調 - 多個服務協同工作
- 數據聚合 - 帖子計數、視圖計數
- 通知 - 訂閱的事件驅動通知
- 類似事務的操作 - 創建帶有初始帖子的主題
另見:
- ../Patterns/Repository-Pattern 用於複雜查詢
- ../Patterns/Service-Layer 用於服務協調
- ../Patterns/DTO-Pattern 用於數據傳輸
標籤: #examples #advanced-module #complex-example #relationships #module-development