jueves, 3 de diciembre de 2015

21 - Tutorial de Laravel 5 - Public Profile (Perfil público de usuario)




En este capítulo del Tutorial de Laravel 5 veremos un supuesto en el cual tenemos que crear un perfil público de usuario, a partir, de la aplicación desarrollada hasta el momento.

Lo primero será crear una nueva ruta en la cual se muestre el perfil, esta ruta se la agregaremos a los nombres de usuario que aparecen en las vistas home.blade.php y search.blade.php.

En home.blade.php estas modificaciones las haremos en la sección para públicar comentarios y en la sección en la que se muestran los comentarios. Código completo de la vista home.blade.php ...

@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><a href="{{url('home/user/'.Auth::user()->id)}}">{{Auth::user()->name}}</a></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')->simplePaginate(5);
        $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><a href="{{url('home/user/'.$user->id)}}">{{$user->name}}</a></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 ?>
        <div class='text-center'>
        <?php /*Nuevo*/ $comments->setPath('') ?>
        <?php echo $comments->render() ?>
           <p>Página {{$comments->currentPage()}}</p>
        </div>
        <br /><br /><br /><br />
@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


En la vista search.blade.php esta modificación será realizada sólo en la sección donde se muestran los comentarios:

@extends('layouts.home')
@section('search', $search)
@section('content')
<h3>Resultado de la búsqueda: {{$search}}</h3>
@if (isset($message))
<div class='bg-warning' style='padding: 20px'>
    {{$message}}
</div>
@endif
<hr />
@if (isset($comments))
<?php 
        $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><a href="{{url('home/user/'.$user->id)}}">{{$user->name}}</a></strong>
            </div>
            <div class='col-md-6'>
               {{$comment->comment}} 
               <br />
               <i>Fecha: {{$comment->date}} · Hora: {{$comment->time}}</i>
               
               
               @if(isset(Auth::user()->id))
               @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
      @endif
            </div>
        </div>
        <hr />
        <?php endforeach ?>
        <?php
        $currentPage = $comments->currentPage(); //Página actual
        $maxPages = $currentPage + 3; //Máxima numeración de páginas
        $firstPage = 1; //primera página
        $lastPage = $comments->lastPage(); //última página
        $nextPage = $currentPage+1; //Siguiente página
        $forwardPage = $currentPage-1; //Página anterior
        $comments->setPath('');
        ?>
<ul class="pagination">
        <!-- Botón para navegar a la primera página -->
        <li class="@if($currentPage==$firstPage){{'disabled'}}@endif">
                <a href="@if($currentPage>1){{$comments->url($firstPage)}}@else{{'#'}}@endif" class='btn'>Primera</a>
        </li>
        <!-- Botón para navegar a la página anterior -->
        <li class="@if($currentPage==$firstPage){{'disabled'}}@endif">
                <a href="@if($currentPage>1){{$comments->url($forwardPage)}}@else{{'#'}}@endif" class='btn'>«</a>
        </li>
        <!-- Mostrar la numeración de páginas, partiendo de la página actual hasta el máximo definido en $maxPages -->
        @for($x=$currentPage;$x<$maxPages;$x++)
                @if($x <= $lastPage)
                <li class="@if($x==$currentPage){{'active'}}@endif">
                        <a href="{{$comments->url($x)}}" class='btn'>{{$x}}</a>
                </li>
                @endif
        @endfor
        <!-- Botón para navegar a la pagina siguiente -->
        <li class="@if($currentPage==$lastPage){{'disabled'}}@endif">
                <a href="@if($currentPage<$lastPage){{$comments->url($nextPage)}}@else{{'#'}}@endif" class='btn'>»</a>
        </li>
        <!-- Botón para navegar a la última página -->
        <li class="@if($currentPage==$lastPage){{'disabled'}}@endif">
                <a href="@if($currentPage<$lastPage){{$comments->url($lastPage)}}@else{{'#'}}@endif" class='btn'>Última</a>
        </li>
</ul>
@endif
@stop


A continuación crearemos la nueva ruta en routes.php, en esta ruta capturaremos el id del usuario, el id es validado para aceptar sólo números enteros:

Route::get("home/user/{id}", "HomeController@user")->where(['id' => '[0-9]+']);


A continuación crearemos la nueva acción "user" en HomeController, pero antes importaremos la clase user al controlador: use App\User;, en la nueva acción realizaremos una consulta buscando al usuario a través del id enviado, si el usuario no existe redireccionamos atrás, de lo contrario mostramos una nueva vista "user" y le pasamos la información del usuario.

    public function user($id){
        $user = User::select()
                ->where('id', '=', $id)
                ->first();
        if (count($user) == 0){
            return redirect()->back();
        }
        else{
            return View('home.user')->with('user', $user);
        }
    }


A continuación crearemos la nueva vista "user.blade.php" en la carpeta "home" con el siguiente código:

@extends('layouts.home')
@section('content')
<h1>Perfil público de <a href="{{url('home/user/'.$user->id)}}">{{$user->name}}</a></h1>
<img src="{{url($user->perfiles)}}" class="img-responsive" style="max-width: 150px" />
<hr />
@if(Session::has('status'))
 <div class="bg-info" 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
<!-- Si el usuario está autenticado -->
@if (Auth::check())
 <!-- Y este es su id de perfil posibilitar la creación de comentarios -->
 @if($user->id == Auth::user()->id)
 <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><a href="{{url('home/user/'.Auth::user()->id)}}">{{Auth::user()->name}}</a></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 />
 @endif
@endif
 <!-- Seleccionar los comentarios del usuario -->
 <?php 
  $modal = 0;
  $comments = App\Comments::where('id_user', '=', $user->id)->orderBy('id', 'desc')->simplePaginate(5);
  foreach($comments as $comment):
 ?>
  <div class="row">
            <div class="col-md-1">
                <img src='{{url($user->perfiles)}}' class='img-responsive' style='max-width: 60px' />
                <strong><a href="{{url('home/user/'.$user->id)}}">{{$user->name}}</a></strong>
            </div>
            <div class='col-md-6'>
               {{$comment->comment}} 
               <br />
               <i>Fecha: {{$comment->date}} · Hora: {{$comment->time}}</i>
      
      <!-- Si el usuario está autenticado, es decir, la propiedad id existe -->
      @if(isset(Auth::user()->id))
      <!-- Si el usuario está autenticado agregar las opciones editar y eliminar cuando visite en su perfil -->
               @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
      @endif
   </div>
  </div>
  <hr />
 <?php endforeach ?>
 
 <!-- Agregar la paginación simple -->
 <div class='text-center'>
 <?php /*Nuevo*/ $comments->setPath('') ?>
 <?php echo $comments->render() ?>
    <p>Página {{$comments->currentPage()}}</p>
 </div>
 <br /><br /><br /><br />

@stop



En el perfil público de usuario se realizan distintas comprobaciones, una de ellas es verificar si el perfil pertenece al usuario actualmente autenticado, de ser así, se le incluye el formulario para crear comentarios y a la lista de comentarios las opciones de editar y eliminar.

Otra cosa, es el manejo de las variables flash 'status' y 'error' al inicio de la vista, esto permitirá que si el usuario realiza alguna acción como crear, editar o eliminar se le muestra esa información. Para que esto ocurra habrá que realizar unas pequeñas modificaciones en las acciones createComment, deleteComment y editComment del controlador UserController, modificando las redirecciones, en lugar de redireccionar a "home", redireccionar atrás con el método "back()", simplemente tenemos que reemplazar:

return redirect('home')->...


Por ...

return redirect()->back()->...


Otra cosa es mostrar la opción de ir al perfil público en el panel del usuario, abrir la vista "user.blade.php" de la carpeta "user" e incluirla ...

    <li><a href="{{url('home/user/'.Auth::user()->id)}}">Ir a mi perfil público</a></li>