반응형

이전에 수정 버튼을 클릭하면 이동하는 라우트는 만들어 놓았다. 이제 컨트롤러를 조금 수정해 보자.

 

/app/Controllers/Board.php

<?php

namespace App\Controllers;
use App\Models\BoardModel;//사용할 모델을 반드시 써줘야한다.

class Board extends BaseController
{
    public function list()
    {
        $db = db_connect();
        $page    = $this->request->getVar('page') ?? 1;//현재 페이지, 없으면 1
        $perPage = 10;//한 페이지당 출력할 게시물 수
        $startLimit = ($page-1)*$perPage;//쿼리의 limit 시작 부분
        $sql = "select b.*, if((now() - regdate)<=86400,1,0) as newid
        ,(select count(*) from memo m where m.status=1 and m.bid=b.bid) as memocnt
        ,(select m.regdate from memo m where m.status=1 and m.bid=b.bid order by m.memoid desc limit 1) as memodate
        ,(select count(*) from file_table f where f.type='board' and f.status=1 and f.bid=b.bid) as filecnt
        from board b where 1=1";
        $order = " order by bid desc";
        $limit = " limit $startLimit, $perPage";
        $query = $sql.$order.$limit;
        $rs = $db->query($query);
        $rs2 = $db->query($sql);
        $total = $rs2->getNumRows();//전체 게시물수

        $data['list'] = $rs->getResult();
        $data['total'] = $total;
        $data['page'] = $page;
        $data['perPage'] = $perPage;

        $pager = service('pager');//페이저를 호출한다.
        $pager_links = $pager->makeLinks($page, $perPage, $total, 'default_full');
        $data['pager_links'] = $pager_links;//페이징을 구현될 부분을 리턴한다.

        return render('board_list', $data);//view에 리턴
    }

    public function write()
    {
        if(!isset($_SESSION['userid'])){
            echo "<script>alert('로그인하십시오.');location.href='/login'</script>";
            exit;
        }
        return render('board_write');  
    }

    public function save()
    {
        if(!isset($_SESSION['userid'])){
            echo "<script>alert('로그인하십시오.');location.href='/login'</script>";
            exit;
        }
        $db = db_connect();
        $bid=$this->request->getVar('bid');//bid값이 있으면 수정이고 아니면 등록이다.
        $subject=$this->request->getVar('subject');
        $content=$this->request->getVar('content');
        $file_table_id=$this->request->getVar('file_table_id');

        if($bid){
            $query = "select * from board where bid=".$bid;
            $rs = $db->query($query);
            if($_SESSION['userid']==$rs->getRow()->userid){
                $sql="update board set subject='".$subject."', content='".$content."' where bid=".$bid;
                $rs = $db->query($sql);
                if(isset($file_table_id)){//첨부한 이미지가 있으면
                    $fti=explode(',',$file_table_id);
                    foreach($fti as $fi){
                        if(isset($fi)){
                            $sql2="update file_table set bid=".$bid." where fid=".$fi;
                            $rs2 = $db->query($sql2);                
                        }
                    }
                }
                return $this->response->redirect(site_url('/boardView/'.$bid));
            }else{
                echo "<script>alert('본인이 작성한 글만 수정할 수 있습니다.');location.href='/login';</script>";
                exit;
            }
        }

        //$file = $this->request->getFile('upfile');//첨부한 파일의 정보를 가져온다.
        $files = $this->request->getFileMultiple("upfile"); //다중 업로드 파일 정보
        $filepath = array();
        foreach($files as $file){
            if($file->getName()){//파일 정보가 있으면 저장한다.
                $filename = $file->getName();//기존 파일명을 저장할때 필요하다. 여기서는 사용하지 않는다.
                //$filepath = WRITEPATH. 'uploads/' . $file->store(); 매뉴얼에 나와있는 파일 저장 방법이다.여기서는 안쓴다.
                $newName = $file->getRandomName();//서버에 저장할때 파일명을 바꿔준다.
                $filepath[] = $file->store('board/', $newName);//CI4의 store 함수를 이용해 저장한다. 저장한 파일의 경로와 파일명을 리턴, 배열로 저장한다.
            }
        }

        $sql="insert into board (userid,subject,content) values ('".$_SESSION['userid']."','".$subject."','".$content."')";
        $rs = $db->query($sql);
        $insertid=$db->insertID();
        foreach($filepath as $fp){//배열로 저장한 파일 저장 정보를 디비에 입력한다.
            if(isset($fp)){
                $sql2="INSERT INTO file_table
                        (bid, userid, filename, type)
                        VALUES('".$insertid."', '".$_SESSION['userid']."', '".$fp."', 'board')";
                $rs2 = $db->query($sql2);                
            }
        }

        if(isset($file_table_id)){//첨부한 이미지가 있으면
            $fti=explode(',',$file_table_id);
            foreach($fti as $fi){
                if(isset($fi)){
                    $sql2="update file_table set bid=".$insertid." where fid=".$fi;
                    $rs2 = $db->query($sql2);                
                }
            }
        }

        return $this->response->redirect(site_url('/boardView/'.$insertid));
    }

    public function view($bid = null)
    {
        $db = db_connect();
        $query = "select b.*,(select GROUP_CONCAT(filename) from file_table f where f.bid=b.bid and f.type='board') as fs from board b where b.bid=".$bid;
        $rs = $db->query($query);
        $data['view'] = $rs->getRow();
        return render('board_view', $data);  
    }

    public function modify($bid = null)
    {
        $db = db_connect();
        $query = "select * from board b where b.bid=".$bid;
        $rs = $db->query($query);
        if($_SESSION['userid']==$rs->getRow()->userid){
            $data['view'] = $rs->getRow();
            $query3 = "select * from file_table where type='board' and bid=".$bid;
            $rs3 = $db->query($query3);
            $data['fs']=$rs3->getResult();
            return render('board_write', $data);  
        }else{
            echo "<script>alert('본인이 작성한 글만 수정할 수 있습니다.');location.href='/login';</script>";
            exit;
        }
       
    }

    public function delete($bid = null)
    {

        $db = db_connect();
        $query = "select * from board where bid=".$bid;
        $rs = $db->query($query);
        if($_SESSION['userid']==$rs->getRow()->userid){
            $query3 = "select * from file_table where type='board' and bid=".$bid;
            $rs3 = $db->query($query3);
            $fs=$rs3->getResult();
            foreach($fs as $f3){
                unlink('uploads/'.$f3->filename);
            }
            $query4 = "delete from file_table where type='board' and bid=".$bid;
            $rs4 = $db->query($query4);
            $query2 = "delete from board where bid=".$bid;
            $rs2 = $db->query($query2);
            return $this->response->redirect(site_url('/board'));
        }else{
            echo "<script>alert('본인이 작성한 글만 삭제할 수 있습니다.');location.href='/login';</script>";
            exit;
        }
    }

    public function save_image()
    {
        $db = db_connect();
       
        $file = $this->request->getFile('savefile');
            if($file->getName()){
                $filename = $file->getName();
                //$filepath = WRITEPATH. 'uploads/' . $file->store();
                $newName = $file->getRandomName();
                $filepath = $file->store('board/', $newName);
            }

            if(isset($filepath)){
                $sql2="INSERT INTO file_table
                        (bid, userid, filename, type)
                        VALUES('', '".$_SESSION['userid']."', '".$filepath."', 'board')";
                $rs2 = $db->query($sql2);
                $insertid=$db->insertID();                
            }

        $retun_data = array("result"=>"success", "fid"=>$insertid, "savename"=>$filepath);
        return json_encode($retun_data);
    }

    public function file_delete()
    {
        $db = db_connect();
        $fid=$this->request->getVar('fid');
        $file_table_id=$this->request->getVar('file_table_id');
        $query = "select * from file_table where fid=".$fid;
        $rs = $db->query($query);
        if(unlink('uploads/'.$rs->getRow()->filename)){
            $query2= "delete from file_table where fid=".$fid;
            $rs2 = $db->query($query2);
            $file_table_id=str_replace(",".$fid,'',$file_table_id);
        }
       
       
        $retun_data = array("result"=>"ok", "file_table_id"=>$file_table_id);
        return json_encode($retun_data);
    }
}

modify() 부분이다. 게시물을 수정할때 첨부한 이미지들도 수정하는 화면에 뿌려주기 위해서 첨부한 파일들의 정보를 같이 포함시켜서 전송한다.

 

/app/Views/board_write.php

 

    <?php
        $file_table_id=0;
        if(isset($fs)){
            foreach($fs as $ff){
                $file_table_id.=",".$ff->fid;//첨부한 파일의 정보를 입력한다.
            }
        }
    ?>
    <form method="post" action="<?= site_url('/writeSave') ?>" enctype="multipart/form-data">
        <input type="hidden" name="bid" value="<?php echo isset($view->bid)?$view->bid:0;?>">
        <input type="hidden" name="file_table_id" id="file_table_id" value="<?php echo $file_table_id;?>"><!-- 첨부한 파일 아이디-->
        <div class="mb-3">
        <label for="exampleFormControlInput1" class="form-label">이름</label>
            <input type="text" name="username" class="form-control" id="exampleFormControlInput1" placeholder="이름을 입력하세요." value="<?php echo $_SESSION['username']?>">
        </div>
        <div class="mb-3">
        <label for="exampleFormControlInput1" class="form-label">제목</label>
            <input type="text" name="subject" class="form-control" id="exampleFormControlInput1" placeholder="제목을 입력하세요." value="<?php echo isset($view->subject)?$view->subject:'';?>">
        </div>
        <div class="mb-3">
        <label for="exampleFormControlTextarea1" class="form-label">내용</label>
        <textarea class="form-control" id="exampleFormControlTextarea1" name="content" rows="3"><?php echo isset($view->content)?$view->content:'';?></textarea>
        </div>
        <div class="mb-3">
                <input type="file" multiple name="upfile[]" id="upfile" class="form-control form-control-lg" aria-label="Large file input example">
        </div>
        <br />
        <div class="row row-cols-1 row-cols-md-6 g-4" id="imageArea"><!-- 첨부한 이미지 영역-->
        <?php
        if(isset($fs)){
          foreach($fs as $f){
          ?>
            <div class='col' id='f_<?php echo $f->fid;?>'><div class='card h-100'><img src='/uploads/<?php echo $f->filename;?>' class='card-img-top'><div class='card-body'><button type='button' class='btn btn-warning' onclick='file_del(<?php echo $f->fid;?>)'>삭제</button></div></div></div>
          <?php
          }
        }?>
        </div>
        <br />
        <?php
        $btntitle=isset($view->bid)?"수정":"등록";
        ?>
            <button type="submit" class="btn btn-primary"><?php echo $btntitle;?></button>
    </form>

    <script>

$("#upfile").change(function(){
    var file_table_id = $("#file_table_id").val();
    farr = file_table_id.split(',');//첨부한 파일을 나눈다
    var files = $('#upfile').prop('files');
    var maxCnt = 0;
    for(var i=0; i < files.length; i++) {
        maxCnt = parseInt(farr.length)+i;//갯수를 더해준다.
        if(maxCnt>5){
            alert('첨부 이미지는 최대 5개까지 등록 가능합니다.');
            $('#upfile').val('');
            return false;
        }else{
            attachFile(files[i]);
        }
    }

    $('#upfile').val('');

});  

function attachFile(file) {
    var formData = new FormData();
    formData.append("savefile", file);
    $.ajax({
        url:'/save_image',
        data: formData,
        cache: false,
        contentType: false,
        processData: false,
        dataType : 'json' ,
        type: 'POST',
        success: function (return_data) {
                fid = $("#file_table_id").val() + "," + return_data.fid;
                $("#file_table_id").val(fid);
                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='file_del("+return_data.fid+")'>삭제</button></div></div></div>";
                $("#imageArea").append(html);
        }
    });

}

function file_del(fid){

if(!confirm('삭제하시겠습니까?')){
return false;
}
   
var data = {
    fid : fid,
    file_table_id : $("#file_table_id").val()
};
    $.ajax({
        async : false ,
        type : 'post' ,
        url : '/file_delete' ,
        data  : data ,
        dataType : 'json' ,
        error : function() {} ,
        success : function(return_data) {
                $("#file_table_id").val(return_data.file_table_id);
                $("#f_"+fid).hide();
        }
});

}

</script>    

글쓰기화면과 글수정 화면은 어차피 같은 파일을 사용한다. 기존 게시물에 대한 정보가 있다면 그 정보를 넘겨줘서 해당 정보를 수정할 수 있도록 보여주면 된다.

 

새로 글을 등록할때는 insert이고 수정할때는 update가 된다. 콘트롤러의 save() 부분을 잘 살펴보자. $bid에 값이 있으면 수정이고 없으면 새글이라고 작업을 해 놓았다.

 

파일 첨부 갯수를 제한하지 않으면 끝없이 첨부를 하게 되고 그러면 서버에 상당한 부하를 주게 되므로 갯수를 제한한다. 물론 용량도 제한하고 이미지가 아니면 등록 못하게 하는등 작업도 필요하지만  그런건 각자 알아서 해보도록 하자. CI4에서 기본으로 제공하는 것도 있고 php의 내부함수를 이용하는 방법도 있다.

 

삭제하는건 이전에 한게 있으니 그걸보면 된다. 크게 다르지 않다.

 

다음 시간에 ajax를 이용해서 게시물에 댓글을 다는걸 해보도록 하자. 요즘은 게시물보다 더 중요한게 댓글이다. 

 

 

 

반응형

+ Recent posts