lunes, 30 de noviembre de 2015

17 - Tutorial de Laravel 5 - CRUD Update (Sistema de comentarios)




En esta parte del Tutorial de Laravel 5, continuamos con el sistema de comentarios agregando la opción de editarlos. En la vista home se han realizado algunas modificaciones para las opciones "Eliminar" y "Editar", para mejorar la accesibilidad al usuario se han integrado unas ventanas modal (Bootstrap) para cada una de ellas.

El código que interviene en este capítulo es el siguiente:

Se adaptan las opciones "Eliminar" y "Editar" para el uso de ventanas modal, el código completo de la vista "home" es el siguiente:

@extends('layouts.home')

@section('content')
<h1>Bienvenid@s a la aplicación Laravel</h1>
<hr />
@if (Session::has('status'))
	<div class="bg-success" style="padding: 20px;">
		{{Session::get('status')}}
	</div>
	<hr />
@endif
@if (Session::has('error'))
	<div class="bg-danger" style="padding: 20px;">
		{{Session::get('error')}}
	</div>
	<hr />
@endif
@if (Auth::check())
	<form method="post" action="{{url('user/createcomment')}}">
		{{csrf_field()}}
		<div class="form-group">
			<div class="row">
				<div class="col-md-1">
					<img src="{{url(Auth::user()->perfiles)}}" class='img-responsive' style='max-width: 60px' />
					<strong>{{Auth::user()->name}}</strong>
				</div>
				<div class="col-md-6">
					<textarea name="comment" class="form-control"></textarea>
					<br />
					<button type="submit" class="btn btn-primary">Publicar</button>
				</div>
			</div>
		</div>
	</form>
	<hr />
        <?php 
        $comments = App\Comments::select()->orderBy('id', 'desc')->get();
        $modal = 0;
        foreach($comments as $comment):
            $user = App\User::select()->where('id', '=', $comment->id_user)->first();
        ?>
        <div class="row">
            <div class="col-md-1">
                <img src='{{url($user->perfiles)}}' class='img-responsive' style='max-width: 60px' />
                <strong>{{$user->name}}</strong>
            </div>
            <div class='col-md-6'>
               {{$comment->comment}} 
               <br />
               <i>Fecha: {{$comment->date}} · Hora: {{$comment->time}}</i>
               
               
               
               @if($comment->id_user == Auth::user()->id)
               <hr />
                <!-- Botón que abre la ventana modal eliminar -->
                <button type="button" class="btn btn-danger" data-toggle="modal" data-target="#deleteComment{{$modal}}">
                  Eliminar
                </button>

                <!-- Ventana modal para eliminar -->
                <div class="modal fade" id="deleteComment{{$modal}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
                  <div class="modal-dialog" role="document">
                    <div class="modal-content">
                      <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
                        <h4 class="modal-title" id="myModalLabel">¿Realmente quieres eliminar este comentario?</h4>
                      </div>
                      <div class="modal-body">
                        <form method="post" action="{{url('user/deletecomment')}}">
                            {{csrf_field()}}
                            <input type="hidden" name="id_comment" value="{{$comment->id}}" />
                            <button type="submit" class="btn btn-danger">Eliminar</button>
                        </form>
                      </div>
                      <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
                      </div>
                    </div>
                  </div>
                </div>

                <!-- Botón para abrir la ventana modal de editar -->
                <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#editComment{{$modal}}">
                  Editar
                </button>

                <!-- Ventana modal editar -->
                <div class="modal fade" id="editComment{{$modal}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
                  <div class="modal-dialog" role="document">
                    <div class="modal-content">
                      <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
                        <h4 class="modal-title" id="myModalLabel">Editar comentario</h4>
                      </div>
                      <div class="modal-body">
                        <form method="post" action="{{url('user/editcomment')}}">
                            {{csrf_field()}}
                            <div class="form-group">
                            <textarea name="comment" rows="10" class="form-control">{{$comment->comment}}</textarea>
                            </div>
                            <input type="hidden" name="id_comment" value="{{$comment->id}}" />
                            <button type="submit" class="btn btn-primary">Editar</button>
                        </form>
                      </div>
                      <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
                      </div>
                    </div>
                  </div>
                </div>
                <?php $modal++ ?>
               @endif
            </div>
        </div>
        <hr />
        <?php endforeach ?>
@else
	<hr />
	<p class="bg-info" style="padding: 20px;">Para poder publicar comentarios tienes que <a href="{{url('auth/login')}}">iniciar sesión</a></div>
	<hr />
@endif
@stop


Como se puede ver, en el nuevo formulario para Editar se agregan un textarea (comment) con el contenido actual del comentario y un campo oculto (id_comment) con el id del comentario. A continuación creamos la acción en el controlador UserController, esta acción se llama editComment ...

    public function editComment(Request $request){
        $rules = ['id_comment' => 'integer'];
        $comment = e($request->comment);
        $validator = Validator::make($request->all(), $rules);
        if ($validator->fails()){
            return redirect('home')->with('error', 'Ha ocurrido un error');
        } else{
            if (Comments::where('id', '=', $request->id_comment)
                    ->where('id_user', '=', Auth::user()->id)
                    ->update(['comment' => $comment])){
                return redirect('home')->with('status', 'Enhorabuena comentario editado correctamente');
            }else{
                return redirect('home')->with('error', 'Ha ocurrido un error');
            }
        }
    }


Como se puede en esta acción se valida el campo oculto (id_comment) para aceptar sólo valores del tipo integer, si la validación falla se redirecciona a "home" con un mensaje flash de error, de lo contrario, se realiza una condición, si la actualización se ha llevado a cabo con éxito, se redirecciona con un "status", de lo contrario con un "error".

Otra cosa importante es modificar el modelo "Comments" para agregar una propiedad ($timestamps) con valor false que permita ignorar la columna "update_at", ya que al hacer uso del método "update()", este incluye en la consulta esta columna por defecto. Abrir "Comments.php" que se encuentra en la carpeta "app" y agregar a la clase la siguiente propiedad:

public $timestamps = false;


Por último conectaremos esta acción a una nueva ruta en routes.php ...

Route::post('user/editcomment', 'UserController@editComment');