이전글 : [PHP] 게시판 만들기 with MVC - 1부 Migration
이전글 : [PHP] 게시판 만들기 with MVC - 2부 Routing
이전글 : [PHP] 게시판 만들기 with MVC - 3부 View(List & Create)
이전글 : [PHP] 게시판 만들기 with MVC - 4부 Controller
이전글 : [PHP] 게시판 만들기 with MVC - 5부 Pagination
이전글 : [PHP] 게시판 만들기 with MVC - 6부 Read
이전글 : [PHP] 게시판 만들기 with MVC - 7부 Update & Delete
이전글 : [PHP] 게시판 만들기 with MVC - 8부 Lock
이전글 : [PHP] 게시판 만들기 with MVC - 9부 Reply(List & Create)
잡담
이제 댓글 수정, 삭제 기능하고 대댓글 기능만 추가하면 게시판 만들기는 끝날 것 같네요.
티스토리에 @@만들기로 여러 개 했지만 쓰면서도 누군가가 이걸 보고 진짜로 따라 할지가 늘 궁금했습니다.
있다면 좋아요나 댓글로 생존신고 해주시면 감사합니다.
View
댓글 수정 및 삭제를 위한 Modal를 추가할 것입니다.
bbs/view/read.php
<button class="btn btn-primary btnSubReply">
대댓글
</button>
</div>
</div>
<?php
}
// 추가
include_once "part/editModal.php";
include_once "part/deleteModal.php";
}
}
} else {
echo "<script>alert('존재하지 않는 게시물입니다.');history.back();</script>";
}
?>
</div>
<script src="/bbs/assets/script/read.js"></script>
</body>
</html>
bbs/view/part/deleteModal.php
<div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="deleteModalLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<form id="deleteModalForm">
<div class="modal-header">
<h5 class="modal-title" id="deleteModalLabel">댓글 삭제</h5>
<button style="height: 35px;" type="button"
class="btn-close btn btn-primary p-1"
data-bs-dismiss="modal" aria-label="Close">
<span style="width: 23px; height: 23px"
class="material-symbols-outlined">close</span>
</button>
</div>
<input type="hidden" name="reply_idx" class="modal-reply-idx">
<div class="modal-body">
<div class="mb-3">
<label class="form-label">Name:</label>
<p id="deleteModalName"></p>
</div>
<div class="mb-3">
<label for="deleteModalPw" class="form-label">Password:</label>
<input name="pw" type="password" class="form-control" id="deleteModalPw">
</div>
<div class="mb-3">
<label for="editModalContent" class="form-label">내용:</label>
<div id="deleteModalContent"></div>
</div>
</div>
<div class="modal-footer">
<button type="button" id="deleteModalSubmit" class="btn btn-primary">삭제</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
</div>
</form>
</div>
</div>
</div>
bbs/view/part/editModal.php
<div class="modal fade" id="editModal" tabindex="-1" aria-labelledby="editModalLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<form id="editModalForm">
<div class="modal-header">
<h5 class="modal-title" id="editModalLabel">댓글 수정</h5>
<button style="height: 35px;" type="button"
class="btn-close btn btn-primary p-1"
data-bs-dismiss="modal" aria-label="Close">
<span style="width: 23px; height: 23px"
class="material-symbols-outlined">close</span>
</button>
</div>
<input type="hidden" name="reply_idx" class="modal-reply-idx">
<div class="modal-body">
<div class="mb-3">
<label class="form-label">Name:</label>
<p id="editModalName"></p>
</div>
<div class="mb-3">
<label for="editModalPw" class="form-label">Password:</label>
<input type="password" class="form-control" id="editModalPw">
</div>
<div class="mb-3">
<label for="editModalContent" class="form-label">내용:</label>
<textarea name="content" class="form-control" id="editModalContent"
rows="3"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" id="editModalSubmit" class="btn btn-primary" data-bs-dismiss="modal">수정</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
</div>
</form>
</div>
</div>
</div>
Script
Modal에서 데이터 전송을 JavaScript의 Ajax를 통해 비동기로 요청할 것입니다.
이를 위해 script를 작성합니다.
bbs/assets/script/read.js
$(document).ready(function () {
...
// 댓글 수정 모달에 데이터 세팅 기능
$(".btn-reply-edit").click(function () {
let replyIdx = $(this).parent().parent().find(".reply-idx").val();
console.log(replyIdx);
$("#editModal .modal-reply-idx").val(replyIdx);
$.ajax({
url: "/bbs/reply/read",
type: "GET",
data: {
reply_idx: replyIdx
},
success: function (data) {
console.log(data);
if (data.result) {
$("#editModalName").text(data.data.name);
$("#editModalPw").val("")
$("#editModalContent").val(data.data.content);
} else {
alert(data.msg);
}
},
error: function (e) {
alert("에러 발생 : " + e.responseText);
}
})
})
// 댓글 삭제 모달에 데이터 세팅 기능
$(".btn-reply-delete").click(function () {
let replyIdx = $(this).parent().parent().find(".reply-idx").val();
$("#deleteModal .modal-reply-idx").val(replyIdx);
$.ajax({
url: "/bbs/reply/read",
type: "GET",
data: {
reply_idx: replyIdx
},
success: function (data) {
if (data.result) {
$("#deleteModalName").text(data.data.name);
$("#deleteModalPw").val("")
$("#deleteModalContent").text(data.data.content);
} else {
alert(data.msg);
}
},
error: function (e) {
alert("에러 발생 : " + e.responseText);
}
})
})
// 댓글 수정 ajax 기능
$("#editModalSubmit").click(function (){
$.ajax({
url: "/bbs/reply/update",
type: "POST",
data: {
reply_idx: $("#editModal .modal-reply-idx").val(),
pw: $("#editModalPw").val(),
content: $("#editModalContent").val()
},
success: function (data) {
console.log(data);
if (data.result) {
alert(data.msg);
location.reload();
} else {
alert(data.msg);
}
},
error : function (e) {
alert("에러 발생 : " + e.responseText);
}
})
})
// 댓글 삭제 ajax 기능
$("#deleteModalSubmit").click(function (){
$.ajax({
url: "/bbs/reply/delete",
type: "POST",
data: {
reply_idx: $("#deleteModal .modal-reply-idx").val(),
pw: $("#deleteModalPw").val()
},
success: function (data) {
console.log(data);
if (data.result) {
alert(data.msg);
location.reload();
} else {
alert(data.msg);
}
},
error : function (e) {
alert("에러 발생 : " + e.responseText);
}
})
})
});
Route
이제 JS에 보낸 요청을 받을 Route 작업을 합시다.
bbs/Route/ReplyRoute.php
<?php
namespace Route;
use Controller\ReplyController;
class ReplyRoute extends BaseRoute
{
function routing($url): bool
{
$replyController = new ReplyController();
if ($this->routeCheck($url, "reply/create", "POST")) {
$replyController->create();
return true;
} else if ($this->routeCheck($url, "reply/read", "GET")) {
$replyController->read();
return true;
} else if ($this->routeCheck($url, "reply/update", "POST")) {
$replyController->update();
return true;
} else if ($this->routeCheck($url, "reply/delete", "POST")) {
$replyController->delete();
return true;
} else {
return false;
}
}
}
Controller
Route에서 부를 Controller에 Method들을 추가합니다.
bbs/Controller/ReplyController.php
<?php
namespace Controller;
use Model\Reply;
class ReplyController extends BaseController
{
...
/**
* 댓글 데이터 가져오기 담당
* @return void
*/
public function read()
{
$replyIdx = $_GET['reply_idx'];
if ($this->parametersCheck($replyIdx)) {
$this->echoJson($this->reply->read($replyIdx));
} else {
$this->echoJson(['result' => false, 'msg' => '입력 값이 올바르지 않습니다.']);
}
}
/**
* 댓글 수정 기능을 담당
* @return void
*/
public function update()
{
$replyIdx = $_POST['reply_idx'];
$pw = $_POST['pw'];
$content = $_POST['content'];
if ($this->parametersCheck($replyIdx, $pw, $content)) {
$this->echoJson($this->reply->update($replyIdx, $pw, $content));
} else {
$this->echoJson(['result' => false, 'msg' => '입력되지 않은 값이 있습니다.']);
}
}
/**
* 댓글 삭제 기능을 담당
* @return void
*/
public function delete()
{
$replyIdx = $_POST['reply_idx'];
$pw = $_POST['pw'];
if ($this->parametersCheck($replyIdx, $pw)) {
$this->echoJson($this->reply->delete($replyIdx, $pw));
} else {
$this->echoJson(['result' => false, 'msg' => '입력되지 않은 값이 있습니다.']);
}
}
}
Model
이제 마지막으로 Model을 추가합니다.
<?php
namespace Model;
use PDOException;
class Reply extends BaseModel
{
...
/**
* 댓글 데이터 가져오기
* @param $replyIdx
* @return array
*/
public function read($replyIdx): array
{
try {
$query = "SELECT name, content FROM replies WHERE idx = :idx";
$stmt = $this->conn->prepare($query);
$stmt->execute([
'idx' => $replyIdx,
]);
$data = $stmt->fetch();
return [
'result' => (bool)$data,
'data' => $data
];
} catch (PDOException $e) {
error_log($e->getMessage());
return [
'result' => false,
'msg' => '알 수 없는 에러가 발생했습니다, 관리자에게 문의주세요.'
];
}
}
/**
* 댓글 수정
* @param $replyIdx
* @param $pw
* @param $content
* @return array
*/
public function update($replyIdx, $pw, $content): array
{
try {
$query = "SELECT pw FROM replies WHERE idx = :idx";
$stmt = $this->conn->prepare($query);
$stmt->execute([
'idx' => $replyIdx,
]);
$check = $stmt->fetch();
// 비밀번호 체크
if (!$check || !password_verify($pw, $check['pw'])) {
return [
'result' => false,
'msg' => '비밀번호가 일치하지 않습니다.'
];
}
// 업데이트
$query = "UPDATE replies SET content = :content WHERE idx = :idx";
$stmt = $this->conn->prepare($query);
$result = $stmt->execute([
'content' => $content,
'idx' => $replyIdx,
]);
return [
'result' => $result,
'msg' => $result ? '댓글이 수정되었습니다.' : '댓글 수정이 실패했습니다.'
];
} catch (PDOException $e) {
error_log($e->getMessage());
return [
'result' => false,
'msg' => '알 수 없는 에러가 발생했습니다, 관리자에게 문의주세요.'
];
}
}
/**
* 댓글 삭제
* @param $replyIdx
* @param $pw
* @return array
*/
public function delete($replyIdx, $pw): array
{
try {
$query = "SELECT pw FROM replies WHERE idx = :idx";
$stmt = $this->conn->prepare($query);
$stmt->execute([
'idx' => $replyIdx,
]);
$check = $stmt->fetch();
// 비밀번호 체크
if (!$check || !password_verify($pw, $check['pw'])) {
return [
'result' => false,
'msg' => '비밀번호가 일치하지 않습니다.'
];
}
// 삭제
$query = "DELETE FROM replies WHERE idx = :idx";
$stmt = $this->conn->prepare($query);
$result = $stmt->execute([
'idx' => $replyIdx,
]);
return [
'result' => $result,
'msg' => $result ? '댓글이 삭제되었습니다.' : '댓글 삭제를 실패했습니다.'
];
} catch (PDOException $e) {
error_log($e->getMessage());
return [
'result' => false,
'msg' => '알 수 없는 에러가 발생했습니다, 관리자에게 문의주세요.'
];
}
}
...
}
여기까지 따라오셨다면 아래 결과물을 볼 수 있습니다.
만약 프로그램의 흐름도를 이해하지 못하시면 아래 그림을 참고하시면 될 것 같습니다.
'PHP > Modern PHP' 카테고리의 다른 글
[PHP] 게시판 만들기 with MVC - 12 Delete Dummy (0) | 2023.12.28 |
---|---|
[PHP] 게시판 만들기 with MVC - 11 SubReply (0) | 2023.12.28 |
[PHP] 게시판 만들기 with MVC - 9부 Reply(List & Create) (1) | 2023.12.28 |
[PHP] 게시판 만들기 with MVC - 8부 Lock (0) | 2023.12.28 |
[PHP] 게시판 만들기 with MVC - 7부 Update & Delete (0) | 2023.12.27 |