Manual avanzado para Laravel


Manual de laravel

Crear Una migración desde la consola
Dentro del proyecto ejecutar el comando
php artisan make:migration nombredelamigracion --create=nombredelatabla

Ejecutar las migraciones
El siguiente comando lo que hara sera crear las tablas y relaciones que se hayan especificado en la migracion

php aritsan migrate

Crear un modelo
php artisan make:model Category

Autenticacion
Crear sistema de autenticacion login, registro, reseteo de clave, es una librería externa
php artisan make:auth

Crear controlador

php artisan make:controler nombrecontrolador

Mensaje flash
Es una libreria externa para mostrar mensajes tipo warning, danger, susses.

https://github.com/laracasts/flash


Filtros a tablas

Tutorial de como crear un filtro para las tablas

https://www.youtube.com/watch?v=IcLaNHxGTrs



Ejecutar un solo Seed 

php artisan db:seed --class=ProfesionCliente

En el caso de que erroje errores como de que la clase no existe ejecutar

composer update
composer dump-autoload

Usar Model Factories

Los model factories es una apoyo a los seeds, el model factories se encarga de generar un numero de registros aleatorios para un modelo que a su vez se almacenan en la tabla que corresponde al modelo.

La ruta es database/factories/ModelFactory.php

Se crea algo como esto para el modelo usuarios

$factory->define(App\User::class, function (Faker\Generator $faker) {
    static $password;

    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'password' => $password ?: $password = bcrypt('secret'),
        'remember_token' => str_random(10),
    ];
});


y ahora para poder ejecutar esto se hace desde un seed que se halla creado. Dentro del sedd se coloca algo como esto:

public function run()
    {
        //primero recibe el modelo luego la cantidad
        factory(App\User::class,20)->create();
    }


y listo ahora solo se ejecuta el comando php artisan db:seed para correr los seeds y los registros se debieron haber creado en la base de datos.

seeds y model factory en laravel

Pero tambien se pueden crear de cualquier cosa ya que el model factory tiene varios atributos, por ejemplo el siguiente model factory que lo arme para un modelo y tabla de pagos:

$factory->define(App\Pago::class,function(Faker\Generator $faker){
  return [
    'tipo_targeta'=>$faker->creditCardType,
    'numero_targeta'=>$faker->creditCardNumber,
    'color'=>$faker->safeColorName
  ];

Es decir en el siguiente link que es del repositorio del creador del componente https://github.com/fzaninotto/Faker#fakerprovideren_uscompany se puede encotnrar varios atributos uno simplemente va tomado el atrbiuto que necesite, es como ir a la tienda y armar un combo 😎.


Crear un coomando

php artisan make:command SendEmails


Obtener modelos de query
para obtener el o los modelos de un query where como por ejemplo

$modelosquequiero = modelo::where('id',2);

Se utiliza el metodo get(); quedando de la siguiente forma

$modelosquequiero = modelo::where('id',2)->get();

Crear API REST
se modifica las rutas en api.php con
 Route::resource laravel establece una rutas por defecto

Route::resource('kaseya','SasAdminApi', [
  'only'=>['index','store','update']
]);


RUTAS

Expresiones regulares
Para tener una mayor seguridad se pueden aplicar expresiones regulares a las rutas para que solo sean accedidas si cumple en patron de Regex.

Para ello se utiliza el metodo where


Route::get('{proveedor}', [
    'uses'=>'Auth\RegisterController@redirectToProvider',
    'as'=>'.redirect'
  ])->where(['proveedor'=>'^(google||facebook||linkedin)$']);

En la anterior ruta solo pueden accer cuando se manda el parámetro de google, facebook o linkedin el resto se daria la excepción NotFoundHttpException


Generar excepciones HTTP

Se puede obligar a generar excepciones http para que el usuario vea el error en el navegador con la función abort(). 

Utilizándolo de la siguiente manera

abort(400,'memsanej')

El 400 es el codio del error en este caso de pagina no encontrada.

Generar Logs

Los logs son importante a las hora de detectar fallas para su rápida solución.
Los se pueden consultar en storage/log/laravel.log.

Tipos de logs ordenados de mas critico a menos:
Log::emergency($message); 
Log::alert($message); 
Log::critical($message); 
Log::error($message); 
Log::warning($message); 
Log::notice($message); 
Log::info($message); 
Log::debug($message);



Vaciar Cache


Ocurren ocasiones en las no aparece un error que todo esta bien, uno revisa linea a linea el código y todo esta al pelo. Pero sigue apareciendo un error esto puede deberse a que el navegador o laravel tiene ese error en cache. Para poder solucionarlo desde laravel se pueden ejecutar los siguientes comandos.

composer dump-autoload 

Este comando recomiendo lo usen cuando se realiza algun cambio al .env para que la configuracion de laravel se actualice.

Ahora también se puede ejecutar el comando 

php artisan config:cache

Que este comando limpiar los archivos de configuración y vistar que laravel tiene almacenado dentro de la carpeta bootstrap. Recomiendo ejecutar este comando cuando el error es directamente en una vista o controlador.

En ultimas si nada fuciona recomiendo usar el comando 

php artisan cache:clear


Y ya en ultima instancia, es maximo que he llegado es ejecutando esta linea dentro de tinker:

Cache::flush();


Scopes o ambitos

Los ámbitos en laravel son simplemente funciones que permiten evitar la repetición de código. En este caso se explicara los ámbitos locales, los cuales se definen en el modelo.

dentro del modelo se define una función, anteponiendo al nombre la palabra scope. Ademas esta función tiene que recibir un parámetros llamado $query.

Digamos que tengo el modelo de usuario y tengo que repetir varias veces un query hacia este mdelo en diferentes partes del proyecto.

Es en este momento donde se puede usar los scopes, si quiero obtener lo usuarios activos el scope quedaria asi:


public function scopeActivos($query){
 return $query->where('state',1);
}

Ahora para usar este scope se usa de la siguiente forma.


User::Activos()->get()

Así obtendré todos los usuarios activos

Modelos

Proteger campos
Para proteger campos de nuestro modelo para que no se inserten datos en campos que por ejemplo son auto incrementales o son forenkey se le agrega el siguiente atributo al modelo

protected $guarded = [''];

Simplemente en el arreglo se agregan las columnas que no se van a poder insertar en masa, basicamente es el contrario del fillable , ya que es una lista negra de los capos que no se permiten insertar. Nota: No se puede usa fillable y guarded al mismo tiempo.


Eliminacion logica

La eliminacion logica consiste solo en cambiar el estado de un registro, estoy es muy util para la persistencia de datos de igual forma es recomendado que los registros de una base de datos nunca se borren.

para implementar la eliminacion logica en laravel se hace de la siguiente manera.

Primero es necesario agregar lo siguiente a la migracion
$table->softDeletes();

luego al modelo se le agrega lo siguiente:

use Illuminate\Database\Eloquent\SoftDeletes;
use SoftDeletes;

y listo básicamente en la tabla del modelo se crea un capo llamado deleted_at entonces si se hace un destroy laravel simplemente lo que ara sera agregar en este campo la fecha de la eliminación.

Ahora para restaurar alguno de estos registros se hace de la siguiente manera.

Product::withTrashed()->find(1)->restore();

En el ejemplo mi modelo se llama producto utilizo withTrashed para que solo obtenga los registros eliminado y luego con find le aplico el filtro pasandole el id del registro a restaurar y por ultimo obiamente el metodo restore

Obtener datos viejos


Con la ayuda de laravel podemos auto-rellenar un input de un formulario que ha fallado. Por ejemplo cuando se tienen varios inputs el usuario envia el formulario pero ingresa un dato mal, al pasar esto se debe retornar nuevamente al formulario pero se quiere que los datos que ingreso el usuario asi sean mal ya este llenados en el input, para conseguir ellos se utiliza old 

ejemplo

<input name="description" type="text" value="{{ old('username') }}" />

por ultimo en el controlador que redirige nuevamente a la vista es necesario agregar ->withInput(), si antes de llegar al controlador se tiene un validados no es necesario poner nada en el controlador el validados lo hace ademas si se usa laravel Colective no es necesario poner el old.

Ejemplo del controlador
return redirect()->back()->withInput();


Mostrar Errores de campos

Esto es util para los formulacios ya que se muestra el error del campo abajo de este, para ello se usa la variable $errors la cual comprobando si existe el campo es por que existe un error si existe, se obtiene el valor de la primera ocurrencia en el array de errores.

<div class="form-group">
    <input type="password" name="password" placeholder="Contraseña..." class="form-control" id="form-password">
    @if($errors->has('email'))        <strong>{{$errors->first('password')}}</strong>
    @endif</div>

Requests

Validacion
Si se quiere que solo un requests también sea usado por un rol en especifico a parte de hacerlo con un middelware para ellos se puede usar lo siguiente para ellos en lugar de retornar 

/**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

Se puede usar

public function authorize()
    {
        return Auth::users()->rol()->id == 1;
    }

Lo que solo autoriza el uso del requests para los usuario que tengan el rol 1


Schedule

Estos son las tareas que se puede programas para que laravel por medio de un cron ejecute dichas tareas, es muy util en caso de que queramos que se envien correos a media noche o una fecha en especifico o etc.

El archivo de cron seria algo como esto 

* * * * * php /var/www/html/proyecto/artisan schedule:run >> /dev/null 2>&1

Limpiar cache

En ocasiones se necesita acceder a las variables de entorno del archivo .env de laravel pero no se puede acceder a ellas o cuando se accede a ellas retorna un valor nulo, para solucionar ello es necesario ejecutar los siguiente comandos.

composer dump
php artisan config:clear
php artisan cache:clear



Eventos y listener

El patrón de diseño Observador es implementado en laravel y llamado en el framework como los eventos y listener. Este patron puede se aplicado en el framework a los controladores, a los modelos por ejemplo cuando se crea se actualiza, se elimina etc.

Eventos en los modelos

 

Los modelos ya viene con la funcionalidad para inyectarles observadores gracias al trait HasEvents, este trait permite a cualquier modelo añadirle observadores, inyectarle un observador que se encargue de manejar todos los eventos del modelo, obtener los eventos del modelo, añadirle eventos, y muchas otras cosas mas que si las desean ver el trait esta en la siguiente ruta Illuminate\Database\Eloquent\Concerns\HasEvents.

Para este ejemplo lo que quiero es que el modelo usuario tenga un observador que maneje todos los eventos del modelo, por defecto los modelos tiene los siguientes eventos observables.

[
'retrieved', 'creating', 'created', 'updating',
'updated', 'deleting', 'deleted', 'saving',
'saved', 'restoring', 'restored',
]


Sin embargo se le pueden reemplazar los eventos observables o añadir.

Bueno lo primero para mi ejemplo lo que voy a hacer es crearme una clase que contenga esos métodos o los que yo quiera que se ejecute algo.

use App\User;
/**
 * Description of UserModelObserver
 *
 * @author Juan Diaz - FuriosoJack <http://blog.furiosojack.com/> 
 */
class UserModelObserver
{
    public function saving(User $user)
    {
        dd("hola mundo");
    }
    
    public function memu()
    {
        dd("me mundo");
    }
}

Mi clase se ve algo como esto. Y lo que espero que pase es que cuando el modelo se este guardando se muestre el hola mundo para ello es necesario inyectarle esta clase al modelo.

Por eso nos vamos a EventServiceProvider y en el metodo boot hago algo como esto

\App\User::Observe(\App\Repository\Patterms\Oberver\UserModelObserver::class);


do ahora si en cualquier parte del proyecto ejecuto el metodo save del modelo se dispara el evento saving y por consiguiente el hola mundo.

//Esto dispararia el evento
        $user = new \App\User();
        $user->name = "juan";
        $user->save();


El ejemplo anterior funciona con los eventos por defecto, pero que hay si se quiere añadir un evento personalizado al modelo. Para ello como el trait HasEvents hace un array merge con los eventos que tiene por defecto y el atributo  observables entonces lo que se puede hacer es sobreescribir el dicho atributo y en formar de array añadir los eventos que queremos que se disparen. Quedando el modelo algo asi 

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    protected $observables = ['memu'];

Ahora solo hay que disparar el evento, en este caso yo me voy a crear un método en el modelo el cual sera el que dispare el evento quedando asi el el modelo

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    protected $observables = ['meming'];
    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
    
    public function memu()
    {       
        
        $this->fireModelEvent('meming',false);
    }


entonces si yo ejecuto esto 

$user = new \App\User();        
 $user->memu();

Pues se dispara el evento que es un dd("me mundo")

Eventos en los controladores

Lo primero es abrir la clase EventServiceProvider y modificar el atributo 

protected $listen

en este atributo aparecerán unos listener por defecto

'App\Events\Event' => [
            'App\Listeners\EventListener',
        ],

Eso se quita y en micaso necesito 3 eventos y un listen por cada evento quedando algo asi

'App\Events\RunIntance' => [
              'App\Listeners\PushNotificationRunIntance',
          ],
          'App\Events\StopIntance' => [
              'App\Listeners\PushNotificationStopIntance',
          ],
          'App\Events\RestartIntance' => [
              'App\Listeners\PushNotificationRestartIntance',
          ],


Ahora se debe saber que un evento puede tener varios listeners, luego se corre el comando
php artisan even:generate el cual se encargara de generar los eventos y los listeners por consiguiente se crearan dos carpetas en el proyecto
Carpeta events y listener laravel

Por ultimo es necesario comenzar a configurar para ellos en mi caso lo primero es configurar el evento, para un evento necesito pasarle un objeto de tipo usuario que a su vez el evento se lo pasara al listener el cual es el encargado de hacer toda la lógica.

Entonces lo primeor es necesaro crear un atributo al evento entonces de la siguiente manera entonces el evento quedaria asi:

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use App\Instancia;
class RunInstance
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public $user;
    public function __construct(User $user)
    {
        $this->user= $user;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('channel-name');
    }
}




Y el listner queda de la siguiente manera

<?php

namespace App\Listeners;

use App\Events\RunInstance;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Log;
use App\Components\Push;
use App\Components\Firebase;
class PushNotificationRunInstance
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  RunIntance  $event
     * @return void
     */
    public function handle(RunInstance $event)
    {
      $user = $event->user;
//Aca va la logica     
}
}


Y en el listener se hace toda la logica necesario ya sea enviar correos etc. Para finalizar solo es necesario poner el evento en el controlador  de la siguiente manera
event(new RunInstance($instancia));


Llamar Comandos desde el controlador


Es posible ejecutar un comando que se a hecho con anterioridad para ellos se hace son la siguiente linea

Artisan::call('generate:bills');

Ocultar los atributos de un modelo 

Esto es útil cuando se hace una serialización del modelo a formato json y queremos ocultar algunos de los atributos para que no salgan en el json generado, para ello es necesario definir un atributo en el modelo 

protected $hidden = ['password'];


En este ejemplo se oculta el atributo password, al ser una arreglo se pueden agregar los otros campos que se quieran ocultar.

https://www.youtube.com/watch?v=iKRLrJXNN4M

Intencion de redireccion

Con el metoo intendent de redirect es posible redireccionar al usuario a la ruta a donde se dirijia antes de que fuera redireccionado a la ruta actual, como cuando usuario se termina su sesion y va hacia las publicaciones pero como ya se termino su sesion es redireccionado a la pagiana de autenticacion cuando este ingresa sus datos y todo es correcto es redireccionado a la pagina a donde se dirijia antes de autenticarse.
if(Auth::guard('alianza')->attemp($credential, $request->get('remember'))){
    return reidrect()->intendent(route('alianzas.login.index'));}



Añadir input luego de una redireccion

Esto es util cuando se quire redireccionar un usuario y que la redireccion exista una session donde esten dos atributos que serian los inputs que el usuario ingreso al momentos de hacer la petición del formulario y luego recuperar estos dos campos en la vista si se quiere mostrar.

return reidrect()->back()
    ->withInput($request->only('email','remember'));

0 Comentarios