반응형

댓글을 수정하는 것이 쉽지 않다. 댓글을 수정할때 댓글에 첨부 이미지가 있는 경우도 있고 없는 경우도 있다. 없는 경우엔 파일을 첨부할 수 있게 해야 하고 있는 경우엔 기존 파일을 삭제하고 다시 등록할 수 있도록 해주어야 한다. 해보자. 

 

댓글을 쓸 수 있는 화면부터 수정해보자.

 

/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>&nbsp;<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>&nbsp;<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>&nbsp;<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;
            }
    }

   
}

설마 위 두 파일이 어디 있지? 라고 생각하는 사람은 없겠지...

 

그리고 댓글을 입력 후 수정해본다.

 

댓글에 이미지를 첨부한 후 수정을 눌렀을때 화면이다. 여기서 기존 이미지를 삭제하고 새로운 이미지를 첨부한다.

 

이렇게 수정후 댓글수정 버튼을 클릭한다.

 

그러면 새로운 이미지가 첨부되고 댓글 내용이 수정된 댓글이 등록된다.

 

조금 어렵지만 찬찬히 따라해보자.

반응형

+ Recent posts