PHP/Modern PHP

[PHP] 게시판 만들기 with MVC - 11 SubReply

DSeung 2023. 12. 28. 14:31

 

이전글 : [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)

이전글 : [PHP] 게시판 만들기 with MVC - 10부 Reply(Update & Delete)

 

대댓글

이제 대댓글 기능을 만들어봅시다

지난 포스팅에서 Controller와 Route 작업은 모두 마쳤습니다.

View와 Model 작업만 하면 끝납니다.

 

View

getSubReplies로 댓글마다의 대댓글 목록을 가져와서 뿌릴 겁니다.

bbs/view/read.php

...
                        <!-- 댓글 섹션 -->
                        <div class="mt-4 card">
                            <div class="card-body">
                                <input type="hidden" class="reply-idx" value="<?= $replyInfo['idx'] ?>"/>
                                <div class="media-body mb-3">
                                    <h5 class="mt-0"><?= $replyInfo['name'] ?></h5>
                                    <p class="mb-0">작성일: <?= $replyInfo['created_at'] ?></p>
                                    <?= nl2br($replyInfo['content']) ?>
                                </div>
                                <button class="btn btn-primary btn-reply-edit" data-bs-toggle="modal"
                                        data-bs-target="#editModal">
                                    수정
                                </button>
                                <button class="btn btn-primary btn-reply-delete" data-bs-toggle="modal"
                                        data-bs-target="#deleteModal">
                                    삭제
                                </button>
                                <button class="btn btn-primary btnSubReply">
                                    대댓글
                                </button>
                            </div>
                        </div>
                        
                        // 추가
                        <?php
                        $subReplies = $reply->getSubReplies($replyInfo['idx']);
                        if ($subReplies) {
                            foreach ($subReplies as $subReplyInfo) {
                                ?>
                                <div class="mt-4 card ml-4">
                                    <div class="card-body">
                                        <input type="hidden" class="reply-idx" value="<?= $subReplyInfo['idx'] ?>"/>
                                        <div class="media-body mb-3">
                                            <h5 class="mt-0"><?= $subReplyInfo['name'] ?></h5>
                                            <p class="mb-0">작성일: <?= $subReplyInfo['created_at'] ?></p>
                                            <?= nl2br($subReplyInfo['content']) ?>
                                        </div>
                                        <button class="btn btn-primary btn-reply-edit" data-bs-toggle="modal"
                                                data-bs-target="#editModal">
                                            수정
                                        </button>
                                        <button class="btn btn-primary btn-reply-delete" data-bs-toggle="modal"
                                                data-bs-target="#deleteModal">
                                            삭제
                                        </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>

 

Script

그러기 위해선 대댓글을 만들 form이 필요합니다.

Js로 대댓글 버튼을 누르면 바로 그 아래의 대댓글을 만들 수 있는 form을 동적으로 추가해 봅시다.

HTMl은 복사하는 게 정신에 이롭습니다.

 

script의 form을 보면 bbs/reply/create로 POST 요청을 하는 걸 알 수 있습니다

저번 포스트에서 분기를 나눈 게 대댓글도 같이 사용하기 위함입니다.

bbs/assets/script/read.js

$(document).ready(function () {
   ...

    // 대댓글 작성 폼 생성 기능
    $(".btnSubReply").click(function (){
        let replyIdx = $(this).parent().find(".reply-idx").val();
        let postIdx = $("#postIdx").val();
        let subReplyFormExist = $("#subReplyForm").length > 0;
        if (subReplyFormExist) {
            $("#subReplyForm").remove();
        }

        $(this).parent().parent().after(
            "<div class=\"mt-4 card ml-4\" id=\"subReplyForm\">\n" +
            "            <div class=\"card-body\">\n" +
            "                <form action=\"/bbs/reply/create\" method=\"post\">\n" +
            "                    <h5>대댓글</h5>\n" +
            "                    <input name=\"post_idx\" type=\"hidden\" class=\"reply-idx\" value=\""+postIdx+"\"/>\n" +
            "                    <div class=\"media-body mb-3\">\n" +
            "                        <input name=\"parent_idx\" type=\"hidden\" name=\"post_idx\" value=\""+replyIdx+"\">\n" +
            "                        <div class=\"form-row\">\n" +
            "                            <div class=\"form-group col-md-6\">\n" +
            "                                <label for=\"name\">Name</label>\n" +
            "                                <input type=\"text\" class=\"form-control\" name=\"name\" placeholder=\"Name을 입력해주세요.\">\n" +
            "                            </div>\n" +
            "                            <div class=\"form-group col-md-6\">\n" +
            "                                <label for=\"password\">Password</label>\n" +
            "                                <input type=\"password\" class=\"form-control\" name=\"pw\"\n" +
            "                                       placeholder=\"Password를 입력해주세요.\">\n" +
            "                            </div>\n" +
            "                        </div>\n" +
            "                        <label for=\"content\">내용:</label>\n" +
            "                        <textarea name=\"content\" class=\"form-control\" id=\"content\" rows=\"3\"></textarea>\n" +
            "                    </div>\n" +
            "                    <button class=\"btn btn-primary\" type=\"submit\">댓글 작성</button>\n" +
            "                </form>\n" +
            "            </div>\n" +
            "        </div>")
    })
});

Model

마지막으로 subReplyCreate와 getSubReplies를 만들어줍시다.

bbs/Model/Reply.php

<?php

namespace Model;

use PDOException;

class Reply extends BaseModel
{	
	...

    /**
     * 대댓글 만들기
     * @param $postIdx
     * @param $parentIdx
     * @param $name
     * @param $pw
     * @param $content
     * @return bool
     */
    public function subReplyCreate($postIdx, $parentIdx, $name, $pw, $content): bool
    {
        try {
            $hashed_pw = password_hash($pw, PASSWORD_DEFAULT);
            $query = "INSERT INTO replies (post_idx, parent_idx, name, pw, content) VALUES (:post_idx, :parent_idx, :name, :pw, :content)";
            return $this->conn->prepare($query)->execute([
                'post_idx' => $postIdx,
                'parent_idx' => $parentIdx,
                'name' => $name,
                'pw' => $hashed_pw,
                'content' => $content
            ]);
        } catch (PDOException  $e) {
            error_log($e->getMessage());
            return false;
        }
    }


    /**
     * 대댓글 목록 가져오기
     * @param $parentIdx
     * @return array
     */
    public function getSubReplies($parentIdx): array
    {
        try {
            $query = "SELECT * FROM replies WHERE parent_idx = :parent_idx ORDER BY idx DESC";
            $stmt = $this->conn->prepare($query);
            $stmt->execute([
                'parent_idx' => $parentIdx,
            ]);
            return $stmt->fetchAll();
        } catch (PDOException $e) {
            error_log($e->getMessage());
            return [];
        }
    }
}

 

결과는 아래와 같습니다.

반응형