PHP강좌/[라라벨]게시판만들기강좌

[라라벨+mysql]게시판 만들기 강좌 #18. 게시물 수정하기

에스크리토 2024. 7. 30. 16:40
반응형

수정하기 페이지를 edit라고 따로 만들어도 되지만 기존 write.blade.php를 조금 수정해서(콘트롤러나 라우터도) 사용해 보는 걸로 수정페이지를 만들어 보려고 한다.

 

우선 보기 페이지에 수정 버튼을 다는 것부터 해보자.

 

/resources/views/boards/view.blade.php

@extends('boards.layout')

@section('header')
    @include('boards.toptitle', ['toptitle'=>'게시판 보기', 'multi'=>$boards->multi])
@endsection

@section('content')

    <table class="table table-striped table-hover">
        <tbody>
            <tr>
                <th width="200">제목</th>
                <td>{{ $boards->subject }}</td>
            </tr>
            <tr>
                <td colspan="2">글쓴이 : {{ $boards->userid }} / 조회수 : {{ number_format($boards->cnt) }} / 등록일 : {{ $boards->regdate }}</td>
            </tr>
            <tr>
                <th width="200">내용</th>
                <td>{!! nl2br($boards->content) !!}</td>
            </tr>
            @if(count($attaches)>0)
            <tr>
                <th width="200">첨부 이미지</th>
                <td>
                    <div class="row row-cols-1 row-cols-md-6 g-4" id="attachFiles" style="margin-left:0px;">
                    @foreach ($attaches as $att)
                    <div id='af_{{ $att->id }}' class='card h-100' style='width:120px;margin-right: 10px;margin-bottom: 10px;'><a href="#" onclick="window.open('/boards/imgpop/{{ $att->filename }}','imgpop','width=600,height=400,scrollbars=yes');"><img src='/images/{{ $att->filename }}' width='100' /></a></div>
                    @endforeach
                    </div>
                </td>
            </tr>
            @endif
        </tbody>
    </table>
    <div align="right">
        @auth()
            @if($boards->userid==auth()->user()->userid)
                <a href="/boards/write/{{ $boards->multi }}/{{ $boards->bid }}"><button type="button" class="btn btn-secondary">수정</button></a>
                <a href="/boards/delete/{{ $boards->bid }}" class="btn btn-secondary" onclick="return confirm('삭제하시겠습니까?');">삭제</a>
            @endif
        @endauth
        <a href="/boards/{{ $boards->multi }}/?page={{ $boards->pagenumber }}" class="btn btn-primary">목록</a>
    </div>
    @endsection    

 

수정 버튼을 볼 수 있는 사람은 해당 게시물을 작성한 사람만 볼 수 있다. 삭제 버튼도 마찬가지다. 링크를 보면 글 작성시 썼던 /boards/wirte를 그대로 썼고 뒤에 $boards->bid를 붙여서 보내도록 했다. 이걸 라우터에서 어떻게 받는지 해보자.

 

/routes/web.php

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\BoardController;
use App\Http\Controllers\MemberController;

Route::get('/', function () {
    return view('welcome');
});

//게시판
Route::get('/boards/{multi?}', [BoardController::class, 'index'])->name('boards.index');
Route::get('/boards/show/{id}/{page}', [BoardController::class, 'show'])->name('boards.show');

Route::middleware('auth') -> group(function (){
    Route::get('/boards/write/{multi}/{bid?}', [BoardController::class, 'write'])->name('boards.write');
    Route::post('/boards/create', [BoardController::class, 'create'])->name('boards.create');
    Route::post('/boards/saveimage', [BoardController::class, 'saveimage'])->name('boards.saveimage');
    Route::post('/boards/deletefile', [BoardController::class, 'deletefile'])->name('boards.deletefile');
    Route::get('/boards/imgpop/{imgfile}', [BoardController::class, 'imgpop'])->name('boards.imgpop');
    Route::post('/boards/update', [BoardController::class, 'update'])->name('boards.update');
});

//회원
Route::get('/login', [MemberController::class, 'login'])->name('auth.login');
Route::get('/signup', [MemberController::class, 'signup'])->name('auth.signup');
Route::post('/signupok', [MemberController::class, 'signupok'])->name('auth.signupok');
Route::post('/emailcheck', [MemberController::class, 'emailcheck'])->name('auth.emailcheck');
Route::post('/loginok', [MemberController::class, 'loginok']) -> name('auth.loginok');
Route::post('/logout', [MemberController::class, 'logout']) -> name('auth.logout');

 

기존엔 wirte뒤에 multi만 있었지만 bid를 추가했다. bid?라고 해준것은 값이 있을 수도 있고 없을 수도 있기때문이다.(글쓰기와 글수정)

 

콘트롤러도 여기에 맞춰서 수정해 주어야 한다.

 

/app/Http/Controllers/BoardController.php


    public function write($multi,$bid=null)
    {
        if(auth()->check()){
            $boards = array();
            $attaches = array();
            $bid = $bid??0;
            if($bid){
                $boards = Board::findOrFail($bid);
                $attaches = FileTables::where('pid',$bid)->where('status',1)->where('code','boardattach')->get();
                return view('boards.write', ['multi' => $multi, 'bid' => $bid, 'boards' => $boards, 'attaches' => $attaches]);
            }else{
                return view('boards.write', ['multi' => $multi, 'bid' => $bid, 'boards' => $boards, 'attaches' => $attaches]);
            }
        }else{
            return redirect()->back()->withErrors('로그인 하십시오.');
        }
    }

 

$bid가 있을 수도 있고 없을 수도 있기때문에 디폴트값은 null이다. 그 아래에 보면 bid가 없으면 0으로 하도록 돼 있는데 이걸 $bid=0으로 해도 된다.

 

$bid가 있으면 수정이므로 게시판 정보와 첨부파일 정보를 보내줘야 한다. 뷰에 어떤값을 보냈는지 눈여겨 봐두자. 이번엔 뷰페이지를 수정한다. write.blade.php를 수정해보자.

 

/resources/views/boards/write.blade.php

@extends('boards.layout')

@section('header')
    <?php
        if($bid){
            $btitle = "수정";
        }else{
            $btitle = "쓰기";
        }
    ?>
    @include('boards.toptitle', ['toptitle'=>'게시판 '.$btitle, 'multi'=>$multi])
@endsection

@section('content')
<br />
    <form method="post" action="/boards/create" enctype="multipart/form-data">
        @csrf
        @method('post')
        <input type="hidden" name="pid" id="pid" value="{{ $bid??time() }}">
        <input type="hidden" name="bid" id="bid" value="{{ $bid??0 }}">
        <input type="hidden" name="code" id="code" value="boardattach">
        <input type="hidden" name="attcnt" id="attcnt" value="0">
        <input type="hidden" name="imgUrl" id="imgUrl" value="">
        <div class="form-group">
            <div class="col-md-12">
                <input type="text" name="subject" id="subject" class="form-control input-lg" placeholder="제목을 입력하세요." value="{{ $boards->subject??'' }}" />
            </div>
        <br />
        </div>
        <div class="form-group">
            <div class="col-md-12">
                <textarea class="form-control" id="content" name="content" rows="5" placeholder="내용을 입력하세요.">{{ $boards->content??'' }}</textarea>
            </div>
        </div>
        <br />
        <div class="form-group">
            @if($attaches)
                <div id="attach_site" class="col-md-12">
                    <div class="row row-cols-1 row-cols-md-6 g-4" id="attachFiles" style="margin-left:0px;">
                        @foreach ($attaches as $att)
                            @if($att)
                                <div id="af_{{ $att->id }}" class='card h-100' style='width:120px;margin-right: 10px;margin-bottom: 10px;'><img src="/images/{{ $att->filename }}" width='100' /><div class='card-body'><button type='button' class='btn btn-warning' onclick="deletefile('{{ $att->filename }}','{{ $att->id }}')">삭제</button></div></div>
                            @endif
                        @endforeach
                    </div>
                </div>
            @else
                <div id="attach_site" class="col-md-12">
                    <div class="row row-cols-1 row-cols-md-6 g-4" id="attachFiles" style="margin-left:0px;">
                    </div>
                </div>
            @endif
            <div class="col-md-12">
                    <input type="file" name="afile" id="afile" multiple accept="image/*" multiple class="form-control" aria-label="Large file input example">
            </div>
        </div>
        <br />
        <br />
        <div class="form-group">
            @if($bid)
                <div class="col-md-12 text-center">
                    <button type="button" name="edit" class="btn btn-primary input-lg" onclick="updatesubmit()">수정</button>
                </div>
            @else
                <div class="col-md-12 text-center">
                    <button type="button" name="edit" class="btn btn-primary input-lg" onclick="sendsubmit()">등록</button>
                </div>
            @endif
        </div>
    </form>
<script>

    $("#afile").change(function(){
        var formData = new FormData();
        var attcnt=$("#attcnt").val();
        var files = $('#afile').prop('files');
        var totcnt=parseInt(attcnt)+parseInt(files.length)

        if(totcnt>5){
            alert('5개까지만 등록할 수 있습니다.');
            return false;
        }

        for(var i=0; i < files.length; i++) {
            attachFile(files[i]);
        }
    });  

    function attachFile(file) {
        var formData = new FormData();
        var pid = $("#pid").val();
        var code = $("#code").val();
        formData.append("file", file);
        formData.append("uptype", "attach");
        formData.append("pid", pid);
        formData.append("code", code);
        $.ajax({
            headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
            url: '{{ route('boards.saveimage') }}',
            data: formData,
            cache: false,
            contentType: false,
            processData: false,
            dataType : 'json' ,
            type: 'POST',
            success: function (return_data) {
    //          console.log(JSON.stringify(return_data));
                if(return_data.result=='fail'){
                    alert(return_data.msg);
                    return false;
                }else{
                    //var img="<img src='"+data+"' width='50'><br>";
                    var html = "<div id='af_"+return_data.fid+"' class='card h-100' style='width:120px;margin-right: 10px;margin-bottom: 10px;'><img src='/images/"+return_data.fn+"' width='100' /><div class='card-body'><button type='button' class='btn btn-warning' onclick=\"deletefile('"+return_data.fn+"', '"+return_data.fid+"')\">삭제</button></div></div>";
                        $("#attachFiles").append(html);
                   
                    var rcnt=parseInt(attcnt)+1;
                    $("#attcnt").val(rcnt);
                    var attachFile=$("#attachFile").val();
                    if(attachFile){
                        attachFile=attachFile+",";
                    }
                    $("#attachFile").val(attachFile+return_data.fn);
                }
            }
            , beforeSend: function () {
                var width = 0;
                var height = 0;
                var left = 0;
                var top = 0;
                width = 50;
                height = 50;

                top = ( $(window).height() - height ) / 2 + $(window).scrollTop();
                left = ( $(window).width() - width ) / 2 + $(window).scrollLeft();

                if($("#div_ajax_load_image").length != 0) {
                        $("#div_ajax_load_image").css({
                                "top": top+"px",
                                "left": left+"px"
                        });
                        $("#div_ajax_load_image").show();
                }
                else {
                        $('body').append('<div id="div_ajax_load_image" style="position:absolute; top:' + top + 'px; left:' + left + 'px; width:' + width + 'px; height:' + height + 'px; z-index:9999;" class="spinner-border" role="status"><span class="visually-hidden">Loading...</span></div>');
                }

        }
            , complete: function () {
                        $("#div_ajax_load_image").hide();
        }
        });

    }

    function deletefile(fn,fid){
        var pid = $("#pid").val();
        var code = $("#code").val();
        var data = {
            fn : fn,
            pid : pid,
            code : code
        };
        $.ajax({
            headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
            type: 'post',
            url: '{{ route('boards.deletefile') }}',
            dataType: 'json',
            data: data,
            success: function(data) {
                alert("삭제했습니다.");
                $("#af_"+fid).hide();
            },
            error: function(data) {
                console.log("error" +JSON.stringify(data));
            }
        });
    }


    function sendsubmit(){
        var subject=$("#subject").val();
        var content=$("#content").val();
        var pid = $("#pid").val();
        var code = $("#code").val();
        var data = {
            multi : '{{ $multi }}',
            subject : subject,
            content : content,
            pid : pid,
            code : code
        };
        $.ajax({
            headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
            type: 'post',
            url: '{{ route('boards.create') }}',
            dataType: 'json',
            enctype: 'multipart/form-data',
            data: data,
            success: function(data) {
                location.href='/boards/show/'+data.bid+'/1';
            },
            error: function(data) {
                console.log("error" +data);
            }
        });
    }

    function updatesubmit(){
        var subject=$("#subject").val();
        var content=$("#content").val();
        var bid='{{ $bid }}';
        var data = {
            subject : subject,
            content : content,
            bid : bid
        };
        $.ajax({
            headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
            type: 'post',
            url: '{{ route('boards.update') }}',
            dataType: 'json',
            enctype: 'multipart/form-data',
            data: data,
            success: function(data) {
                location.href='/boards/show/'+data.bid+'/1';
            },
            error: function(data) {
                console.log("error" +data);
            }
        });
    }
</script>    
@endsection

 

소스가 좀 길다. 어쨌든 수정이니까 게시판에 등록했던 내용들을 가져와서 다시 뿌려주는 것이 기본이라고 보면 된다. 그리고 그 값들을 수정하면 다시 업데이트 시켜주어야 한다. 업데이트에 관한 라우터와 콘트롤러도 등록해보자.

 

라우터는 위에서 이미 등록했으니 콘트롤러만 추가해보겠다.

 

/app/Http/Controllers/BoardController.php

public function update(Request $request)
    {
        $form_data = array(
            'subject' => $request->subject,
            'content' => $request->content
        );

        if(auth()->check()){
            $boards = Board::findOrFail($request->bid);
            if(Auth::user()->userid==$boards->userid){
                Board::where('bid', $request->bid)->update($form_data);
                return response()->json(array('msg'=> "succ", 'bid'=>$request->bid), 200);
            }else{
                return response()->json(array('msg'=> "fail", 200));
            }
        }
    }

 

업데이트 하기 전에 본인이 쓴 글인지 한번더 체크한다. 업데이트 하는 방식은 어렵지 않다.

 

 

위에 자유 게시판 수정이라고 나와야 되고 아래 버튼도 수정이라고 나와야 한다. 물론 업데이트도 잘 돼야하겠다. 그리고 그냥 등록 버튼을 눌렀을때는 아래와 같이 나와야 한다.

 

너무 길어져서 삭제는 다음에 하도록 하겠다.

반응형