NF2 - Framework Laravel

De wikiserver
Dreceres ràpides: navegació, cerca

ESTRUCTURA DIRECTORIOS

=RUTAS BÁSICAS

Dentro de Routers->Web

Route::get('mundo', function () {
    return 'Hello World';
});

Creamos un controlador vacio, App->http->Controller->

php artisan make:controller MoviesController --plain
en route
Route::get('/ejemplo', 'PeliculasController@index');
en controlador
public function index(){

echo "hola Julio";

}


//verbos HTTP múltiples
Route::match(['get', 'post'], '/', function () {
    //
});

//verbos HTTP cualquiera
Route::any('/', function () {
    //
});


//dentro de la misma vista
Route::get('/show/{id?}',function($id="122"){

    return $id;
    
    })->name('show');


Route::get('/par-o-impar-{numero}',function($numero){    // no hace falta usar '/'

return $numero;

//return redirect()->to('/show/3');  -> te redirije a la ruta que le indicas 
//return redirect()->route('show')  -> te redirije a la ruta que tiene el nombre asignado en el name.
//return redirect()->route('show',['id' => '222'])  -> en caso de pasarle algun parámetro
} )->where(['number' => '[\d]+']);    // de esta forma añadimos una expresion regular para que solo puedan introducir numeros


Route::get('user/{name?}', function ($name = 'John') {  //$name=null
    return $name;
});

Restricciones con Expresiones Regulares

Route::get('user/{name}', function ($name) {
    //
})->where('name', '[A-Za-z]+');   //nomes poden passar lletres miníscules o Majúscules como mínim una volta 

Route::get('user/{id}', function ($id) {
    //
})->where('id', '[0-9]+');

Route::get('user/{id}/{name}', function ($id, $name) {
    //
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);   //le pasamos un array en caso de más de un elemento.


Route::group(['prefix'=>'admin'],function(){  // en el navegador puedes poner /admin/modificar-usuario  o  /admin/insertar-usuario
    
    Route::get('modificar-usuario',function(){

    return "modifica usuario";

    });


    Route::get('insertar-usuario',function(){

    return "insertar usuario";

    });

});

RELACIONES

Se deben de hacer las relaciones de la base de datos en las migraciones y también en los modelos para facilitar a Eloquent las consultas.

Relaciones Uno a Muchos Migraciones

un usuario tiene muchos post y un post lo tiene un usuario

//tabla Categories
  Schema::create('categories', function (Blueprint $table) {
            $table->increments('id')->unsigned();
            $table->text('nombre');
            $table->mediumText('masInfo');
            $table->timestamps();
        });

//tabla Posts


    Schema::create('posts', function (Blueprint $table) {
            $table->increments('id')->unsigned();
            $table->integer('category_id')->unsigned();
            $table->text('titulo');
            $table->mediumText('descripcion');
            $table->timestamps();
            //relaciones
            $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade')->onUpdate('cascade');
            //category_id hace referencia a la tabla categories y el borrado y la actualización es en cascada.
        });


Para las relaciones NxM Muchos a Muchos. Un post puede tener muchas Etiquetas y una etiqueta puede tener muchos Posts, por tanto habrá que crear una tabla auxiliar.

//Tabla Post
 Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');

           // $table->integer('user_id')->unsigned();
           // $table->integer('category_id')->unsigned();
            
            $table->string('name',128)->unique();
            $table->string('slug',128)->unique();

            $table->mediumText('excerpt')->nullable();
            $table->text('body');
            $table->enum('status',['PUBLISHED','DRAFT'])->default('DRAFT');

            $table->string('file', 128)->nullable();

            $table->timestamps();

            //relaciones
            //$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade');
            //$table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade')->onUpdate('cascade');

        });

//tabla Tags

Schema::create('tags', function (Blueprint $table) {
            $table->increments('id');

            $table->string('name',128);
            $table->string('slug',128)->unique();

            $table->timestamps();
        });


//tabla auxiliar

  Schema::create('post_tag', function (Blueprint $table) {
            $table->increments('id');

            $table->integer('post_id')->unsigned();
            $table->integer('tag_id')->unsigned();

            $table->timestamps();

             //relaciones
             $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade')->onUpdate('cascade');
             $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade')->onUpdate('cascade');
 
        });


CRUD

Creas la tabla

php artisan make:migration create_blogs_table --create=blogs


Luego en la migración creas los campos para la base de datos

Schema::create('blogs', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('blog_title');
$table->text('blog_content');
$table->timestamps();
});

Generas las rutas insertando el fichero Web

Route::resource('blogs','blogController');

//Para listar las rutas, en terminal 

php artisan route:list -v

Creamos el modelo

php artisan make:model Blog

//dentro del modelo 
class Blog extends Model
{
protected $fillable = ['blog_title', 'blog_content'];

//¿Qué atributos deberías incluir en dicho array?

//Aquellos que consideres sensibles y que no deberían modificarse o asignarse en cierta forma, el más típico es el id, el cual normalmente no se modifica ni se asigna de forma manual.
}

Creamos Controlador

php artisan make:controller blogController --resource
1.index()

2.create()

3.store()

4.show()

5.edit()

6.update()

7.destroy()

https://www.expertsphp.com/laravel-6-crud-create-read-update-delete-generator-for-beginners-with-example/

//creamos la migracion que es la tabla en la base de datos "datos"

Schema::create('datos', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('nombre');
            $table->text('descripcion');
            $table->timestamps();
        });

//creamos el modelo "Dato" que es la Entidad que vamos a trabajar y dentro ponemos los datos que queremos proteger.

protected $fillable = ['nombre', 'descripcion'];

añadimos las rutas
public function index(){

    $datos=Dato::all();

    return view('index',['datos'=>$datos]);
   } 

//en la vista
@forelse ($datos as $item)
<li> {{$item->nombre}} {{$item->descripcion}} <a href="{{ route('editar', $item->id)}}" >Edit</a>
   <form action="{{ route('borrar', $item->id)}}" method="post">
        @csrf
        @method('DELETE')
        <button type="submit">borrar</button>
    </form>
 </li>
@empty
<li>NO HAY NADA </li>
@endforelse


public function almacenar(Request $request){

//LA MEJOR FORMA DE INSERTAR DATOS ya que se hace la comprobación de los campos obligatorios para que no hagan inyeccion y luego inserta.
    $datos=request()->validate([
        'nombre'=>'required|max:25', 
        'descripcion'=>'required']
    );

    Dato::create($datos);

    return redirect()->route('index');
 //return back(); //te redirecciona a la misma página
   } 

//en la vista


@if ($errors->any())
    <ul>
        @foreach ($errors->all() as $error)
        <li>{{ $error }}</li>
        @endforeach
    </ul>
<br/>
@endif
<form method="post" action="{{ route('almacenar') }}">
    <div>
        @csrf
        <label for="name">Nombre:</label>
        <input type="text" name="nombre" />
    </div>
    <div>
        <label for="price">Descripcion:</label>
        <input type="text" name="descripcion" />
    </div>

    <button type="submit">Crear</button>
</form>


public function editar($id){

    $dato = Dato::findOrFail($id);  //como no está el dato si nos equivocamos de id nos muestra la página de error 404, podemos crear uno personalizado en la view->errors->404.blade.php , creamos carpeta "errors"


    return view('editar', compact('dato'));
   } 


//en la vista de Editar

@if ($errors->any())
        <div class="alert alert-danger">
            <strong>Whoops!</strong> There were some problems with your input.<br><br>
            <ul>
                @foreach ($errors->all() as $error)
                    <li>{{ $error }}</li>
                @endforeach
            </ul>
        </div>
    @endif

<form method="post" action="{{ route('actualizar', $dato) }}">  //No es necesario especificar el Id ya que la nueva versión laravel ya busca dentro del Objeto
          <div > 
              @method('PATCH')
              @csrf
              
              <label for="name">nombre:</label>
              <input type="text"  name="nombre" value="{{ $dato->nombre }}"/>
          </div>
          <div >
              <label for="descripcion">descripcion</label>
              <input type="text"  name="descripcion" value="{{ $dato->descripcion }}"/>
          </div>
         
          <button type="submit" >Actualizar</button>
      </form>
  </div>
</div>

//hacer el actualizar

public function actualizar(Request $request, $id){

         $validacion=$request->validate([
        'nombre' => 'required',
        'descripcion' => 'required',
        ]);
       
       $datos = Dato::find($id);   //podremos utilizar findOrFail($id) para que en caso de no encontrar no falle
        $datos->nombre = $request->get('nombre');  //$request->nombre;    //$request->input('nombre');
        $datos->descripcion = $request->get('descripcion');  //$request->descripcion;     //$request->input('descripcion'); 

        $datos->update();
        
        
        // Dato::whereId($id)->update($validacion); //otra opción

       //return redirect()->route('index');
      
    } 

//$request->input() es un array


//en el controlador borrar

    public function borrar($id){

        $dato = Dato::findOrFail($id);
        
        $dato->delete();
    
        return redirect()->route('index');
       }


//rutas en Web
Route::get('/index', 'DatosController@index')->name('index');
Route::post('/almacenar', 'DatosController@almacenar')->name('almacenar');
Route::get('/editar/{id}', 'DatosController@editar')->name('editar');
Route::patch('/actualizar/{id}', 'DatosController@actualizar')->name('actualizar');
Route::delete('/borrar/{id}', 'DatosController@borrar')->name('borrar');


//PAGINAR

en controlador de index
        $datos=Dato::latest()->paginate(3);
y en vista debajo de forelse 

{{$datos->links()}}


//en el momento que insertamos datos dentro de la tabla y queremos mostrar los datos de forma más humana.
<ul>
  @forelse ($datos as $item)
              <li>  {{$item->title}}  {{$item->created_at->diffForHumans() }} </li>  
            @empty
                <li>NO HAY NADA </li>
            @endforelse
        </ul>


//obtener datos.

use app\Dato; 

$datos=Dato::get();
$datos=Dato::orderBy('nombre','DESC')->get();
$datos=Dato::latest('created_at')->get();   //muestra los últimos que se han añadido


https://styde.net/como-trabajar-con-form-requests-en-laravel/ Para mantener el código limpio y no tener que poner php artisan make:request CreateDatosRequest


MENSAJES FLASH

//cuando en una página queremos enviar un mensaje flahs podemos poner

return back()->with('status','hemos recibido el mensaje'); //guardamos un mensaje flash

//luego en la misma pagina (back) ponemos una condicion en blade si hay mensaje de sesion muestra sino formulario.
 @if(session('status'))
{{session('status')}}
@else
 formulario
@endif

//como vamos a repetir este codigo en muchos lados, podemos ponerlo en un fichero partial (resources-views-partial) y luego en el codigo lo sustituimos por @include en el editar.blade.php

AUTENTIFICACIÓN Crear usuario en versiones anteriores a 6

php artisan make:auth

Laravel 6

composer require laravel/ui

php artisan ui vue --auth

Después podremos ver que en las rutas Web ha creado Auth::routes();

Dentro app->http->Auth cambiamos las rutas de register y login cambiando ruta a /

Quitamos la ruta /home dentro de las rutas en web

"para borrar la sesion podemos borrar el fichero dentro storage->framework->session como prueba"


@auth    //sirve para mostrar en caso de estar autentificado, estar logeado
{{auth()->user()->name}}
@endauth
//tambien cambiar la ruta de middleware en caso de estar autentificado y volver hacer login peta y te manda a home por tanto cambiar a raiz.

//usar directiva @guest- invitado. en caso de no estar logueado no muestra @guest <a href="Plantilla:Route('login')>Login</a> @else //LOGOUT <a href="Plantilla:Route('logout')" onclick="event.preventDefault(); document.getElementById('logout-form').submit();"> Logout </a>

 <form id="logout-form" action="Plantilla:Route('logout')" method="POST" style="display: none;">
   Plantilla:Csrf field()
 </form>

@endguest

//deshabilitar registro , vamos a Web y modificamos ruta

Auth::routes(['register'=>false]);

para saber si está logeado en el Controlador

use Illuminate\Support\Facades\Auth;

if(Auth::check()){ 
 return "estas logeado";
}else { 
 return "no estas logeado";
}

En el caso que querramos bloquear al usuario por intentos de ingresos fallidos y penalizar el tiempo a la hora de volver autenficarte, bastará con añadir el controlador por defecto app->http->Controller->auth-> LoginController


class LoginController extends Controller
{
   
    use AuthenticatesUsers;

    public $maxAttempts = 2;   //número máximo de intentos
    public $decayMinutes = 2;  //tiempo que durará el bloqueo


MIDDLEWARE- filtran las peticiones http, en nuestro caso que compruebe si el usuario está autentificado o no. Son puertas que una peticion de usuario tiene que pasar antes de llegar al controlador que tiene la logica a la que el usuario intenta acceder. dos formas:

1) añadir a la ruta dentro de Web ->middleware('auth');
Route::get('/insertar','MoviesController@insertar')->name('insertar')->middleware('auth');

2) Dentro del controlador añadimos dentro del constructor
public __construct(){
  $this->middleware('auth')->only('create', 'edit'); //y con esto especificamos que redirija a login en caso de entrar a create y no está logeado.
//  $this->middleware('auth')->except('create', 'edit');  // lo contrario, bloquea a todos los metodos/controladores excepto el create y edit que podrán acceder.
}