Para criar a estrutura de comentários para artigos no padrão MVC, vou seguir a arquitetura básica de uma aplicação MVC, garantindo a sanitização dos dados no controlador e utilizando getters e setters no modelo. Como você mencionou, faremos a sanitização de forma manual inicialmente, e posteriormente podemos discutir a inclusão de bibliotecas open source para melhorar o processo de sanitização, caso necessário.
A estrutura será semelhante à que já existe no seu projeto de gerenciamento de artigos, mas será aplicada à funcionalidade de comentários.
App ├── src │ ├── Controller │ │ ├── CommentController.php │ ├── Model │ │ ├── Comment.php │ ├── View │ │ ├── CommentView.php ├── config │ └── database.php ├── public │ └── index.php └── vendor
Comment.php
Aqui criaremos a classe Comment que representará a tabela de comentários no banco de dados. Utilizaremos getters e setters para garantir a validação dos dados antes de armazená-los no banco.
<?php namespace App\Model; class Comment { private $id; private $article_id; private $author; private $content; private $created_at; // Getters and Setters public function getId(){return $this->id;} public function setId($id){$this->id = $id;} public function getArticleId(){return $this->article_id;} public function setArticleId($article_id) { if (is_numeric($article_id)) { $this->article_id = $article_id; } } public function getContent(){return $this->content;} public function setContent($content){$this->content = htmlspecialchars(trim($content), ENT_QUOTES, 'UTF-8');} public function getCreatedAt(){return $this->created_at;} public function setCreatedAt($created_at){$this->created_at = $created_at;} } }
CommentController.php)
Aqui implementamos a lógica para criar, editar, deletar e listar comentários, além de sanitizar os dados no controlador antes de processá-los.
<?php namespace App\Controller; use App\Model\Comment; use App\Service\DatabaseService; class CommentController { private $db; public function __construct() { $this--->db = DatabaseService::getConnection(); } // Create a new comment public function create($data) { $comment = new Comment(); // Sanitize input $article_id = filter_var($data['article_id'], FILTER_SANITIZE_NUMBER_INT); $author = filter_var($data['author'], FILTER_SANITIZE_STRING); $content = filter_var($data['content'], FILTER_SANITIZE_STRING); // Set data using getters and setters $comment->setArticleId($article_id); $comment->setAuthor($author); $comment->setContent($content); $comment->setCreatedAt(date('Y-m-d H:i:s')); // Insert into database $stmt = $this->db->prepare("INSERT INTO tbl_comments (article_id, author, content, created_at) VALUES (?, ?, ?, ?)"); $stmt->bind_param("isss", $article_id, $author, $content, $comment->getCreatedAt()); if ($stmt->execute()) { return "Comment added successfully!"; } else { return "Failed to add comment."; } } // Read comments by article public function getCommentsByArticle($article_id) { $article_id = filter_var($article_id, FILTER_SANITIZE_NUMBER_INT); $stmt = $this->db->prepare("SELECT * FROM tbl_comments WHERE article_id = ?"); $stmt->bind_param("i", $article_id); $stmt->execute(); $result = $stmt->get_result(); $comments = []; while ($row = $result->fetch_assoc()) { $comments[] = $row; } return $comments; } // Delete a comment public function delete($id) { $id = filter_var($id, FILTER_SANITIZE_NUMBER_INT); $stmt = $this->db->prepare("DELETE FROM tbl_comments WHERE id = ?"); $stmt->bind_param("i", $id); if ($stmt->execute()) { return "Comment deleted successfully!"; } else { return "Failed to delete comment."; } } }
CommentView.php
A CommentView.php será responsável por renderizar os comentários para o usuário, listando-os abaixo do artigo e fornecendo um formulário para adicionar novos comentários.
?php namespace LibrarySystem\View; class CommentView { public static function renderCommentForm($article_id) { echo ' <form action="/comment/create" method="POST"> <input type="hidden" name="article_id" value="' . htmlspecialchars($article_id) . '"> <label for="author">Author:</label> <input type="text" name="author" required> <label for="content">Comment:</label> <textarea name="content" required></textarea> <button type="submit">Add Comment</button> </form>'; } public static function renderComments($comments) { foreach ($comments as $comment) { echo ' <div class="comment"> <p><strong>' . htmlspecialchars($comment['author']) . ':</strong></p> <p>' . htmlspecialchars($comment['content']) . '</p> <small>Posted on: ' . htmlspecialchars($comment['created_at']) . '</small> </div>'; } } }
A tabela tbl_comments no banco de dados terá a seguinte estrutura:
tbl_comments
CREATE TABLE tbl_comments ( id INT AUTO_INCREMENT PRIMARY KEY, article_id INT NOT NULL, author VARCHAR(255) NOT NULL, content TEXT NOT NULL, created_at DATETIME NOT NULL, FOREIGN KEY (article_id) REFERENCES tbl_articles(id) );
5. Roteamento No arquivo de roteamento (supondo que já esteja implementado), você pode definir as seguintes rotas: $router->post('/comment/create', 'CommentController@create'); $router->get('/article/{id}/comments', 'CommentController@getCommentsByArticle'); $router->post('/comment/{id}/delete', 'CommentController@delete'); Considerações Finais Sanitização Manual: No controlador, usamos a função filter_var() para sanitizar os dados antes de passá-los ao modelo. Bibliotecas Open Source: Existem bibliotecas como HTMLPurifier para uma sanitização mais avançada de HTML e inputs de usuários. Podemos avaliar a implementação dessas bibliotecas caso o código atual precise de melhorias.
No arquivo de roteamento (supondo que já esteja implementado), você pode definir as seguintes rotas:
$router->post('/comment/create', 'CommentController@create'); $router->get('/article/{id}/comments', 'CommentController@getCommentsByArticle'); $router->post('/comment/{id}/delete', 'CommentController@delete');
filter_var()
HTMLPurifier