반응형
댓글을 수정하는 것이 쉽지 않다. 댓글을 수정할때 댓글에 첨부 이미지가 있는 경우도 있고 없는 경우도 있다. 없는 경우엔 파일을 첨부할 수 있게 해야 하고 있는 경우엔 기존 파일을 삭제하고 다시 등록할 수 있도록 해주어야 한다. 해보자.
댓글을 쓸 수 있는 화면부터 수정해보자.
/app/Views/board_view.php
<h3 class="pb-4 mb-4 fst-italic border-bottom" style="text-align:center;">
- 게시판 보기 -
</h3>
<article class="blog-post">
<h2 class="blog-post-title"><?php echo $view->subject;?></h2>
<p class="blog-post-meta"><?php echo $view->regdate;?> by <a href="#"><?php echo $view->userid;?></a></p>
<hr>
<p>
<?php echo $view->content;?>
</p>
<br>
<?php
if(isset($view->fs)){
$vfs = explode(",",$view->fs);
foreach($vfs as $img){
if(isset($img)){
?>
<img src="<?php echo base_url('/uploads/'.$img);?>">
<?php
}
}
}?>
<hr>
<p style="text-align:right;">
<?php
if(isset($_SESSION['userid'])==$view->userid){
?>
<a href="/modify/<?php echo $view->bid;?>"><button type="button" class="btn btn-primary">수정</button><a>
<a href="/delete/<?php echo $view->bid;?>"><button type="button" class="btn btn-warning">삭제</button><a>
<?php }?>
<a href="/board"><button type="button" class="btn btn-primary">목록</button><a>
</p>
</article>
<hr>
<div style="margin-top:30px;">
<form class="row g-3">
<input type="hidden" name="file_table_id" id="file_table_id" value="">
<div class="col-md-8">
<textarea class="form-control" placeholder="댓글을 입력해주세요." id="memo" style="height: 60px"></textarea>
</div>
<div class="col-md-2">
<button type="button" class="btn btn-secondary" id="memo_button">댓글등록</button>
</div>
<div class="col-md-2" id="memo_image">
<div class="btn btn-warning" id="filebutton" onclick="$('#upfile').click();">사진첨부</div>
<input type="file" name="upfile" id="upfile" style="display:none;" />
</div>
</form>
</div>
<div id="memo_place">
<?php
if(isset($memoArray)){
foreach($memoArray as $ma){
?>
<div class="card mb-4" id="memo_<?php echo $ma->memoid?>" style="max-width: 100%;margin-top:20px;">
<div class="row g-0">
<div class="col-md-12">
<div class="card-body">
<p class="card-text">
<?php
if($ma->filename){
?>
<img src="/uploads/<?php echo $ma->filename;?>" style="max-width:90%;">
<?php }?>
<br>
<?php echo $ma->memo;?></p>
<p class="card-text"><small class="text-muted"><?php echo $ma->userid;?> / <?php echo $ma->regdate;?></small></p>
<p class="card-text" style="text-align:right"><button type="button" class="btn btn-secondary btn-sm memo_reply" mid="<?php echo $ma->memoid?>">답글</button>
<?php if(isset($_SESSION['userid']) and $_SESSION['userid']==$ma->userid){?>
<a href="javascript:;" onclick="memo_modify(<?php echo $ma->memoid?>)"><button type="button" class="btn btn-secondary btn-sm">수정</button></a> <a href="javascript:;" onclick="memo_del(<?php echo $ma->memoid?>)"><button type="button" class="btn btn-secondary btn-sm">삭제</button></a>
<?php }?>
</p>
</div>
</div>
</div>
</div>
<?php }
}
?>
</div>
<script>
$("#memo_button").click(function () {//댓글등록 버튼을 클릭시
var file_table_id = $("#file_table_id").val();
var data = {
memo : $('#memo').val() ,
bid : <?php echo $view->bid;?>,
file_table_id : file_table_id
};
if(!data.memo){
alert('댓글을 입력하세요.');
return false;
}
$.ajax({
async : false ,
type : 'post' ,
url : '/memo_write' ,
data : data ,
dataType : 'html' ,
error : function() {} ,
success : function(return_data) {
if(return_data=="login"){
alert('로그인 하십시오.');
return;
}else if(return_data=="memo"){
alert('댓글을 입력하세요.');
return;
}else{
$('#memo').val('')
$("#file_table_id").val('');
$("#f_"+file_table_id).hide();
$("#filebutton").show();
$("#memo_place").prepend(return_data);
}
}
});
});
$("#upfile").change(function(){//댓글에 이미지 첨부시
var files = $('#upfile').prop('files');
for(var i=0; i < files.length; i++) {
attachFile(files[i]);
}
$('#upfile').val('');
});
function attachFile(file) {
var formData = new FormData();
var modify_memoid = $("#modify_memoid").val();//댓글을 입력하는 중인지 댓글을 수정하는지 구분자
formData.append("savefile", file);
$.ajax({
url: '/save_image_memo',
data: formData,
cache: false,
contentType: false,
processData: false,
dataType : 'json' ,
type: 'POST',
success: function (return_data) {
if(return_data.result=='success'){
var html = "<div class='col' id='f_"+return_data.fid+"'><div class='card h-100'><img src='/uploads/"+return_data.savename+"' class='card-img-top'><div class='card-body'><button type='button' class='btn btn-warning' onclick='memo_file_del("+return_data.fid+")'>삭제</button></div></div></div>";
if(modify_memoid){//댓글 수정시
$("#modify_file_table_id").val(return_data.fid);
$("#upfile").hide();
$("#filebutton_"+modify_memoid).hide();
$("#memo_image_"+modify_memoid).html(html);
}else{//댓글 입력시
$("#file_table_id").val(return_data.fid);
$("#upfile").hide();
$("#filebutton").hide();
$("#memo_image").append(html);
}
}else{
if(return_data.data=="login"){
alert('로그인 하십시오.');
return;
}
}
}
});
}
function memo_file_del(fid){//댓글에 첨부이미지가 있는 경우에 첨부이미지를 삭제할때
var modify_memoid = $("#modify_memoid").val();
if(!confirm('삭제하시겠습니까?')){
return false;
}
var data = {
fid : fid
};
$.ajax({
async : false ,
type : 'post' ,
url : '/memo_file_delete' ,
data : data ,
dataType : 'json' ,
error : function() {} ,
success : function(return_data) {
if(return_data.result=="no"){
alert('삭제하지 못했습니다. 관리자에게 문의하십시오.');
return;
}else{
if(modify_memoid){//댓글 수정시 삭제
$("#filebutton_"+modify_memoid).show();
$("#modify_file_table_id").val('');
}else{//댓글 입력시 삭제
$("#filebutton").hide();
$("#file_table_id").val('');
}
$("#f_"+fid).hide();
$("#upfile").hide();
}
}
});
}
function memo_del(memoid){
if(!confirm('삭제하시겠습니까?')){
return false;
}
var data = {
memoid : memoid
};
$.ajax({
async : false ,
type : 'post' ,
url : '/memo_delete' ,
data : data ,
dataType : 'json' ,
error : function() {} ,
success : function(return_data) {
if(return_data.result=="login"){
alert('로그인 하십시오.');
return;
}else if(return_data.result=="my"){
alert('본인이 작성한 글만 삭제할 수 있습니다.');
return;
}else if(return_data.result=="fail"){
alert('삭제하지 못했습니다. 관리자에게 문의하십시오.');
return;
}else if(return_data.result=="nodata"){
alert('변수값이 없거나 해당되는 메모가 없습니다.');
return;
}else{
$("#memo_"+memoid).hide();
}
}
});
}
function memo_modify(memoid){//댓글수정버튼 클릭시
var data = {
memoid : memoid
};
$.ajax({
async : false ,
type : 'post' ,
url : '/memo_modify' ,
data : data ,
dataType : 'html' ,
error : function() {} ,
success : function(return_data) {
if(return_data=="my"){
alert('본인이 작성한 글만 수정할 수 있습니다.');
return;
}else{
$("#memo_"+memoid).html(return_data);
}
}
});
}
function memo_modify_update(memoid){//댓글 수정 후 저장할때
var modify_file_table_id = $("#modify_file_table_id").val();
var data = {
memoid : memoid,
modify_file_table_id : modify_file_table_id,
memo_text : $("#memo_text_"+memoid).val()
};
$.ajax({
async : false ,
type : 'post' ,
url : '/memo_modify_update' ,
data : data ,
dataType : 'html' ,
error : function() {} ,
success : function(return_data) {
if(return_data=="my"){
alert('본인이 작성한 글만 수정할 수 있습니다.');
return;
}else{
$("#memo_"+memoid).html(return_data);
}
}
});
}
</script>
memo_modify()함수와 memo_modify_update()함수를 추가했다. 그 외에 다른 함수들도 댓글 수정의 경우를 위해 조금 수정했다. 기존 파일이 있으면 위 파일로 덮어 쓰자.
라우트에 등록하자.
<?php
namespace Config;
// Create a new instance of our RouteCollection class.
$routes = Services::routes();
// Load the system's routing file first, so that the app and ENVIRONMENT
// can override as needed.
if (is_file(SYSTEMPATH . 'Config/Routes.php')) {
require SYSTEMPATH . 'Config/Routes.php';
}
/*
* --------------------------------------------------------------------
* Router Setup
* --------------------------------------------------------------------
*/
$routes->setDefaultNamespace('App\Controllers');
$routes->setDefaultController('Home');
$routes->setDefaultMethod('index');
$routes->setTranslateURIDashes(false);
$routes->set404Override();
// The Auto Routing (Legacy) is very dangerous. It is easy to create vulnerable apps
// where controller filters or CSRF protection are bypassed.
// If you don't want to define all routes, please use the Auto Routing (Improved).
// Set `$autoRoutesImproved` to true in `app/Config/Feature.php` and set the following to true.
// $routes->setAutoRoute(false);
/*
* --------------------------------------------------------------------
* Route Definitions
* --------------------------------------------------------------------
*/
// We get a performance increase by specifying the default
// route since we don't have to scan directories.
//게시판
$routes->get('/', 'Home::index');
$routes->get('/board', 'Board::list');
$routes->get('/boardWrite', 'Board::write');
$routes->match(['get', 'post'], 'writeSave', 'Board::save');
$routes->get('/boardView/(:num)', 'Board::view/$1');
$routes->get('/modify/(:num)', 'Board::modify/$1');
$routes->get('/delete/(:num)', 'Board::delete/$1');
$routes->post('/save_image', 'Board::save_image');
$routes->post('/file_delete', 'Board::file_delete');
//댓글
$routes->match(['get', 'post'], '/memo_write', 'MemoController::memo_write');
$routes->post('/save_image_memo', 'MemoController::save_image_memo');
$routes->post('/memo_file_delete', 'MemoController::memo_file_delete');
$routes->post('/memo_delete', 'MemoController::memo_delete');
$routes->post('/memo_modify', 'MemoController::memo_modify');
$routes->post('/memo_modify_update', 'MemoController::memo_modify_update');
//member
$routes->get('/login', 'MemberController::login');
$routes->get('/logout', 'MemberController::logout');
$routes->match(['get', 'post'], '/loginok', 'MemberController::loginok');
/*
* --------------------------------------------------------------------
* Additional Routing
* --------------------------------------------------------------------
*
* There will often be times that you need additional routing and you
* need it to be able to override any defaults in this file. Environment
* based routes is one such time. require() additional route files here
* to make that happen.
*
* You will have access to the $routes object within that file without
* needing to reload it.
*/
if (is_file(APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php')) {
require APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php';
}
그리고 라우트에 등록한대로 컨트롤러에 등록하자.
<?php
namespace App\Controllers;
use App\Models\BoardModel;//사용할 모델을 반드시 써줘야한다.
class MemoController extends BaseController
{
public function memo_write()
{
if(!isset($_SESSION['userid'])){
return "login";
exit;
}
$db = db_connect();
$memo=$this->request->getVar('memo');
$bid=$this->request->getVar('bid');
$file_table_id=$this->request->getVar('file_table_id');
$sql="INSERT INTO memo
(bid, userid, memo, status)
VALUES(".$bid.", '".$_SESSION['userid']."', '".$memo."', 1)";
$rs = $db->query($sql);
$insertid=$db->insertID();
//error_log ('['.__FILE__.']['.__FUNCTION__.']['.__LINE__.']['.date("YmdHis").']'.print_r($file_table_id,true)."\n", 3, './php_error_'.date("Ymd").'.log');
if(!empty($file_table_id)){//첨부한 파일이 있는 경우에만
$uq="update file_table set bid=".$bid.", memoid=".$insertid." where fid=".$file_table_id;
$uqs = $db->query($uq);
$fquery="select * from file_table where status=1 and fid=".$file_table_id;
$rs2 = $db->query($fquery);
$imgarea = "<img src='/uploads/".$rs2->getRow()->filename."' style='max-width:90%'>";
}else{
$imgarea="";
}
$return_data = "<div class=\"card mb-4\" id=\"memo_".$insertid."\" style=\"max-width: 100%;margin-top:20px;\">
<div class=\"row g-0\">
<div class=\"col-md-12\">
<div class=\"card-body\">
<p class=\"card-text\">".$imgarea."<br>".$memo."</p>
<p class=\"card-text\"><small class=\"text-muted\">".$_SESSION['userid']." / now</small></p>
<p class=\"card-text\" style=\"text-align:right\"><a href=\"javascript:;\" onclick=\"memo_modify(".$insertid.")\"><button type=\"button\" class=\"btn btn-secondary btn-sm\">수정</button></a> <a href=\"javascript:;\" onclick=\"memo_del(".$insertid.")\"><button type=\"button\" class=\"btn btn-secondary btn-sm\">삭제</button></a></p>
</div>
</div>
</div>
</div>";
return $return_data;
}
public function save_image_memo()
{
$db = db_connect();
if(!isset($_SESSION['userid'])){
$retun_data = array("result"=>"fail", "data"=>"login");
return json_encode($retun_data);
exit;
}
$file = $this->request->getFile('savefile');
if($file->getName()){
$filename = $file->getName();
//$filepath = WRITEPATH. 'uploads/' . $file->store();
$newName = $file->getRandomName();
$filepath = $file->store('memo/', $newName);
}
if(isset($filepath)){
$sql2="INSERT INTO file_table
(bid, userid, filename, type)
VALUES('', '".$_SESSION['userid']."', '".$filepath."', 'memo')";
$rs2 = $db->query($sql2);
$insertid=$db->insertID();
}
$retun_data = array("result"=>"success", "fid"=>$insertid, "savename"=>$filepath);
return json_encode($retun_data);
}
public function memo_file_delete()
{
$db = db_connect();
$fid=$this->request->getVar('fid');
$query = "select * from file_table where type='memo' and fid=".$fid;
$rs = $db->query($query);
if(unlink('uploads/'.$rs->getRow()->filename)){
$query2= "delete from file_table where type='memo' and fid=".$fid;
$rs2 = $db->query($query2);
$retun_data = array("result"=>"ok");
return json_encode($retun_data);
}else{
$retun_data = array("result"=>"no");
return json_encode($retun_data);
}
}
public function memo_delete()
{
if(!isset($_SESSION['userid'])){//로그인여부
$retun_data = array("result"=>"login");
return json_encode($retun_data);
exit;
}
$db = db_connect();
$memoid=$this->request->getVar('memoid');
$query = "select * from memo where memoid=".$memoid;
$rs = $db->query($query);
if($memoid and $rs->getRow()->memoid){//memoid가 있는지 또는 메모가 테이블에 있는지
if($rs->getRow()->userid==$_SESSION['userid']){//본인이 작성한 메모인지
$query2= "delete from memo where memoid=".$memoid;
if($rs2 = $db->query($query2)){//삭제했는지
$query3 = "select * from file_table where type='memo' and bid=".$rs->getRow()->bid." and memoid=".$memoid;
$rs3 = $db->query($query3);
if(isset($rs3->getRow()->filename) and unlink('uploads/'.$rs3->getRow()->filename)){
$query4= "delete from file_table where fid=".$rs3->getRow()->fid;
$rs4 = $db->query($query4);
}
$retun_data = array("result"=>"ok");
return json_encode($retun_data);
exit;
}else{
$retun_data = array("result"=>"fail");
return json_encode($retun_data);
exit;
}
}else{
$retun_data = array("result"=>"my");
return json_encode($retun_data);
exit;
}
}else{
$retun_data = array("result"=>"nodata");
return json_encode($retun_data);
exit;
}
}
public function memo_modify()//댓글 수정 버튼을 눌렀을때 작동
{
$db = db_connect();
$memoid=$this->request->getVar('memoid');
$query = "select * from memo where memoid=".$memoid;
$rs = $db->query($query);
if($rs->getRow()->userid==$_SESSION['userid']){//본인이 작성한 메모인지
$query3 = "select * from file_table where type='memo' and memoid=".$memoid;
$rs3 = $db->query($query3);
$html = "<form class=\"row g-3\">
<input type=\"hidden\" id=\"modify_memoid\" value=\"".$memoid."\">
<input type=\"hidden\" id=\"modify_file_table_id\" value=\"\">
<div class=\"col-md-8\" style=\"padding:10px;\">
<textarea class=\"form-control\" id=\"memo_text_".$rs->getRow()->memoid."\" style=\"height: 60px\">".$rs->getRow()->memo."</textarea>
</div>
<div class=\"col-md-2\" style=\"padding:10px;\">
<button type=\"button\" class=\"btn btn-secondary\" onclick=\"memo_modify_update(".$rs->getRow()->memoid.")\" >댓글수정</button>
</div>";
if(isset($rs3->getRow()->fid)){
$html .= "<div class=\"col-md-2\" style=\"padding:10px;\" id=\"memo_image_".$memoid."\">
<div style=\"display:none;\" class=\"btn btn-warning\" id=\"filebutton_".$memoid."\" onclick=\"$('#upfile').click();\">사진첨부</div>
<input type=\"file\" name=\"upfile\" class=\"upfile\" id=\"upfile_".$memoid."\" style=\"display:none;\" />
<div class=\"col\" id=\"f_".$rs3->getRow()->fid."\"><div class=\"card h-100\"><img src=\"/uploads/".$rs3->getRow()->filename."\" class=\"card-img-top\"><div class=\"card-body\"><button type=\"button\" class=\"btn btn-warning\" onclick=\"memo_file_del(".$rs3->getRow()->fid.")\">삭제</button></div></div></div>
</div>";
}else{
$html .= "<div class=\"col-md-2\" style=\"padding:10px;\" id=\"memo_image_".$memoid."\">
<div class=\"btn btn-warning\" id=\"filebutton_".$memoid."\" onclick=\"$('#upfile').click();\">사진첨부</div>
<input type=\"file\" name=\"upfile\" id=\"upfile\" style=\"display:none;\" />
</div>";
}
$html .= "</form>";
echo $html;
}else{
echo "my";
exit;
}
}
public function memo_modify_update()//댓글을 수정 후 저장할때 작동
{
$db = db_connect();
$memoid=$this->request->getVar('memoid');
$memo_text=$this->request->getVar('memo_text');
$modify_file_table_id=$this->request->getVar('modify_file_table_id');
$query = "select * from memo where memoid=".$memoid;
$rs = $db->query($query);
if($rs->getRow()->userid==$_SESSION['userid']){//본인이 작성한 메모인지
$uq="update memo set memo='".$memo_text."' where memoid=".$memoid;
$uqs = $db->query($uq);
if(!empty($modify_file_table_id)){//첨부한 파일이 있는 경우에만
$uq="update file_table set bid=".$rs->getRow()->bid.", memoid=".$memoid." where fid=".$modify_file_table_id;
$uqs = $db->query($uq);
}
$query3 = "select * from file_table where type='memo' and memoid=".$memoid;
$rs3 = $db->query($query3);
if(!empty($rs3->getRow()->filename)){//첨부한 파일이 있는 경우에만
$imgarea = "<img src='/uploads/".$rs3->getRow()->filename."' style='max-width:90%'>";
}else{
$imgarea="";
}
$return_data = "<div class=\"row g-0\">
<div class=\"col-md-12\">
<div class=\"card-body\">
<p class=\"card-text\">".$imgarea."<br>".$memo_text."</p>
<p class=\"card-text\"><small class=\"text-muted\">".$_SESSION['userid']." / now</small></p>
<p class=\"card-text\" style=\"text-align:right\"><a href=\"javascript:;\" onclick=\"memo_modify(".$memoid.")\"><button type=\"button\" class=\"btn btn-secondary btn-sm\">수정</button></a> <a href=\"javascript:;\" onclick=\"memo_del(".$memoid.")\"><button type=\"button\" class=\"btn btn-secondary btn-sm\">삭제</button></a></p>
</div>
</div>
</div>";
return $return_data;
}else{
echo "my";
exit;
}
}
}
설마 위 두 파일이 어디 있지? 라고 생각하는 사람은 없겠지...
그리고 댓글을 입력 후 수정해본다.
댓글에 이미지를 첨부한 후 수정을 눌렀을때 화면이다. 여기서 기존 이미지를 삭제하고 새로운 이미지를 첨부한다.
이렇게 수정후 댓글수정 버튼을 클릭한다.
그러면 새로운 이미지가 첨부되고 댓글 내용이 수정된 댓글이 등록된다.
조금 어렵지만 찬찬히 따라해보자.
반응형
'PHP강좌 > [CI4]게시판만들기강좌' 카테고리의 다른 글
[PHP+CI4+mysql]회원 전용 게시판 만들기 강좌 #26. 댓글 삭제하기 (0) | 2022.12.26 |
---|---|
[PHP+CI4+mysql]회원 전용 게시판 만들기 강좌 #25. 댓글에 이미지첨부하고 삭제하기 (0) | 2022.12.07 |
[PHP+CI4+mysql]회원 전용 게시판 만들기 강좌 #24. Ajax로 댓글 달기 (0) | 2022.12.02 |
[PHP+CI4+mysql]회원 전용 게시판 만들기 강좌 #23. Ajax를 이용한 게시물 수정과 업로드 갯수 제한 (0) | 2022.11.21 |
[PHP+CI4+mysql]회원 전용 게시판 만들기 강좌 #22. Ajax를 이용한 다중 파일 첨부 (0) | 2022.11.21 |