Tomar un archivo remoto y guardarlo en nuestro servidor de modo aútomatico

Si estamos trabajando con un cliente conectado a proveedores, y necesitamos  desarrollar alguna api que importa un archivo remoto, de modo automático  y lo guarde  para después trabajar con él, una forma sencilla de hacerlo, seria esta:

$dia = date("m.d.y");
$hora = date("H.i.s");
$filepath = 'http://dirección_remota';  
  //fijamos la hora a la que queremos iniciar el proceso de importacion para que el scheduler la vea 
if ($hora === "13:16")  // hora que deseamos hacer la importacion 
        {  $guardar = Storage::disk('importados')->put($dia.'_'.$hora.'_nuevoarchivo', file_get_contents($filepath));  }  

 Si ahora queremos retornar ese último archivo guardado, podemos dirigirnos a su posición en la carpeta storage, y escoger el último asi:

$archivo = \Storage::disk('importados')->files()->end();

A partir de aquí podríamos, trabajar con la variable archivo.

Y listo, esto es todo.

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias.

…..lo que realmente importa no es lo que te da la vida, sino lo que haces con ello….

¿Crear y almacenar clases?

Laravel trabaja con clases que generalmente se guardan en repositorios desde el cual son llamadas. Esta estructura requiere que ademas de conocer la organizacion del framework, comprendamos su enfoque para crear, almacenar y gestionar las claves.

Puede parecer para muchos complicado, pero es una estructura que desde mi punto de vista esta enfocada a componentes como parte de un todo, de ahi la necesidad de entenderla adecuadamente

Crear una clase

Las clases en Laravel se crean dentro de la carpeta App, usando psr-4. Basta con crear un archivo en una dirección dentro de App y comenzaremos a tener una clase reconocida, por la aplicación:

Creamos el archivo Conexión dentro de una carpeta nueva llamada Personalizado

  App/Personalizado/Conexión.php 

Y luego colocamos la clase con sus métodos y/o atributos. En nuestro caso estamos creando una clase que sustituirá los valores de conexión a la bd en el archivo env.

 class Conexion
 {
    public function conectar()
    {
         return 'conecto';
 }
 } 

Una vez creado, la clase principal que se encuentra ubicada en “App\Personalizado\Conexion\conexion.php”, tendrá como namespace y que es el que podrá ser usado desde cualquier lugar de la aplicación, o sea hacer bind, este:

 App\Personalizado\conexion 

Para que el bind funcione, son necesarios unos pasos más. Lo siguiente que haremos será crear el Service Provider de la clase.

Lo haremos con Artisan desde la consola:

 php artisan make:provider ConexionServiceProvider 

Lo que sigue es registrar la clase en el método register() del  ConexionServiceProvider, haciendo el adecuado bind.

  public function register()
     {
         //registramos la clase
         \App::bind('Conexion');
     }  

Y finalmente registramos ConexionServiceProvider en el fichero de configuración, que  se encuentra en la ruta config/app.php, agregando la clase, dentro del array de providers:

  /*
          * Application Service Providers...
          */
         App\Providers\AppServiceProvider::class,
         App\Providers\AuthServiceProvider::class,
         …………
          /*
          * Clases Propias añadidas...
          */
         App\Providers\ConexionServiceProvider::class,
   

Nos faltaría comprobar que nuestra clase es accesible, podemos hacer diferentes pruebas, como llamar la clase desde una ruta o correr una prueba con Tinker.

Comencemos con Tinker, llamándolo desde la consola:

  >>>php artisan tinker 

Una vez abierto, llamamos la clase, y la corremos :

  Psy Shell v0.9.12 (PHP 7.2.3 — cli) by Justin Hileman
 >>> use App\Personalizado\Conexion; 

La instanciamos :

 >>> $h =new Conexion();
 => App\Personalizado\Conexion {#3106} 

Y llamamos la funcion:

 >>> $h->conectar();
 => "conecto"
 >>>                         

Salimos de Tinker, con control +C.

Tambien podemos probarlo en el sistema de rutas de Laravel.

 Route::get('conectando', function(){
     if(class_exists('App\Personalizado\Conexion'))
     dd('hallada');
     else dd(' no hallada');
 }
 ); 

Si accedemos ahora a la ruta conectando deberíamos ver escrita la palabra hallada.

Ahora, nuestra clase esta lista y disponible para ser usada.

Y listo, esto es todo.

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias.

…., si avanzo sígueme, si me detengo empújame, si retrocedo mátame…….

Crear un comando en Laravel

logo laravel

Crear comandos que nos permiten ejecutar acciones manuales desde la consola,  es una herramienta que necesitamos mas comúnmente de lo que parece, hablo por mi experiencia.

El desarrollo me he exigido que además de las herramientas de testeo, en muchos casos correr directamente comandos de Artisan, para comprobar el funcionamiento en vivo de funciones o métodos construidos, como parte del proceso de creación de una aplicación.

En este ejemplo muestro como crear un comando Artisan,  que va a conectarse a un base de datos y hacer una inserción según un momento determinado en ella.

Llamaremos a nuestro comando importar.

En la consola dentro del root de nuestro proyecto creamos el comando:

 php artisan make:command Importar 

Esto creará nuestro comando, si vamos ahora a la ruta

app/Console/Commands/importar.php, 

el archivo Commands, que se crea al correr

make:command 

tendrá dentro los datos del comando creado.Dentro del comando hay varias zonas importantes:

La primera es la  variable  $signature, que es donde daremos el nombre con que llamaremos al comando en la consola

  protected $signature = 'importar'; 

La  segunda es la variable descripción, allí escribiremos la descripción de la razon de ser del comando que aparecerá cuando listemos los comandos de Artisan

protected $description = 'Insertar productos en la Base de datos';

La tercera zona importante es la función handle en la cual desarrollaremos la lógica.

   public function handle()
     {//

    $archivos =  \Storage::disk('listos')->files(); 
    $ultimo =  end($archivos);
    $contenido_Exp = \Storage::disk('listos')->get($ultimo);

    $contenido_Exp = json_decode($contenido_Exp);
    //dd($contenido_Exp[2]->codigo);
                   /* 
                    ->get(); */
    //dd($archivo);


    function hora_exportar($sitio, $hora)
    {
      $hora = date("H.i.s");
      $hora_deseada  = DB::table('sitios')->hora_deseada;
      if ($hora === $hora_deseada){
        $sitio = DB::table('sitios')->nombre;
        $host = DB::table('sitios')->host_conex;
        $username = DB::table('sitios')->usuario_bd;
        $passwd = DB::table('sitios')->pass_bd;
        $dbname = DB::table('sitios')->nombre_bd; 
      }

     }


    /*
    $host ="154.53….";
    $username =  "admin_bd ";
    $passwd= "Hlnv68?";
    $dbname= "bd_pt";*/


   // $consulta = ;
    $enlace = mysqli_connect($host,$username,$passwd,$dbname);
  /*  if ($mysqli_ping($enlace)){
        printf("conexion bien");
    }
    else{ printf("error de conexion");}
    mysqli_close($enlace);*/
    if(!$enlace){
        echo "Error no se pudo conectar".PHP_EOL;
        echo "Errno de depuracion:".msqli_connect_errno().PHP_EOL;
        echo "Errno de depuracion:".msqli_connect_error().PHP_EOL;
        exit;
    }
    echo "realizada conexion exitosa".PHP_EOL;
    echo "info del host:".msqli_get_host($enlace).PHP_EOL;
    mysqli_close($enlace);


   //insertamos en nuestra bd los datos de la ultima exportacion  
  $insertar_exportacion = DB::table('importaciones')->insert([
              'users_id' => 1,
              'estados_id' => '3',
              'proveedores_id' =>'1',
              'sitios_id' => $ultimo,
              'url_archivo'  => $url,
              'nombre_archivo'  => $url,
              'tipo_archivo'  =>$tipo,
              'tamaño'  =>'1',

             ]);
}

En nuestro ejemplo tenemos una columna en la bd llamada hora deseada, que compareremos con la hora actual del servidor, si el valor es igual  ejecutaremos la consulta.

El ultimo paso para que el comando funcione es declararlo en el  archivo kernel.php dentro de la ruta App/Console, dentro de los comandos protegidos

protected $commands = [
     //     Commands\Importar::class, ]; 

Y en la función Schedule, tenemos la opción de configurar la ejecución  su ejecución periódicamente,  podríamos también colocar una  tarea en el servidor de llamar esta función, a una hora especifica,  en nuestro caso la colocaremos aquí diaria.  

protected function schedule(Schedule $schedule)
     {
          $schedule->command('Importar')
                 ->daily();
     }

Esto es todo, no obstante debemos decir que la recomendación de  Laravel es que los comandos sean ligeros para no cargar demasiado la ejecución del sistema en si y como una buena  práctica de programación.

La mejor opción es aprovechar la reusabilidad, y utilizar ese mismo código dentro de un controlador,  ejecutándolo de  modo periódico, y así dejar la ejecución del comando solo para tareas manuales.

Y listo, esto es todo.

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias.

…todo lo que se contiene,  termina  desbordándose……

Creando un componente en Laravel

¿Por que crear componentes?

Laravel es un framework basado en componentes y esta es una  de sus características y quizás la mas importante de todas,   que lo hace tan útil, sencillo y potente a la vez.

Los componentes dicho de forma rápida son un conjunto de funciones, scripts  y/u otros elementos que pueden  que crean una funcionalidad y que son reusables.

Piensa en una pieza de ropa  o un accesorio femenino que puedes combinar(usar), con varias otras prendas, sin que pierda funcionalidad, y para diferentes ocasiones y tantas veces como quieras.

Hay diferentes tipos de componentes, voy a centrarme hoy en construir uno en Blade el gestor de plantillas Blade.

Un componente en Blade,  cumple la misma función que la combinación entre las directrices section y layouts, por tanto es una alternativa a esta, digamos más moderna.

Consta de dos variables, el component y el slot. Mientras que el component es la estructura general,  slot es la parte dinámica  que inyectaremos en el.

Crear un componente

El primer paso para crear un componente Blade, considerando que va a estar relacionado con las vistas, es colocarlo dentro del área que tiene que ver con las capas(layouts) de las vistas, así que en la ruta resources/views/layouts, creamos una carpeta llamada componentes.

Luego crearemos un  archivo, que contendrá la lógica del componente.

El compenente, que vamos a construir, va a llamarse curric_autor, y se encargará de mostrar  una pequeña nota al final de cada articulo que publiquemos en nuestro blog.

Estará colocado a la izquierda de la página, e incluirá la  foto del autor y un pequeño texto  con su descripción.

 A este archivo lo nombraremos curric_autor.php y lo  guardaremos en la carpeta componentes que hemos creado.

El próximo paso es escribir nuestro código, el cual podría ser este:

 <divclass = flex-row comd-6>
 <div class=d- flexjustify-content-end col-md-9>
 <spanclass= text-justify> Amante del codigo, y de las mascotas  con garras.</span>
 <divclass="text-center col-md-3">
<imgsrc="..."class="rounded"alt="...">
</div>
</div>
</div> 

Una vez creado el componente podemos usarlo de diferente modo:

Podemos llamarlos desde nuestra vista e inyectarlo  en la vista siguiendo las directivas @ de Blade.

  @component('layouts.components.curric_autor')
 @endcomponent 

Con esto será suficiente, pero ¿que sucede si en el blog publica más de un autor y por tanto los datos que usamos necesitan ser extraidos dinámicamente de la base de datos?

Tendriamos entonces que qñadir en el codigo del componente  variables necesarias para  que recojan esta dinámica, y lo haríamos  con $autor que representará al modelo autor que posee varios atributos, lema, avatar_alt y avatar, y para añadirlos seria asi:

  <div class = flex-row col-md-6  >
 <div class=d- flexjustify-content-end col-md-9>
 <spanclass= text-justify> {{$autor->lema}}.</span>
 <divclass="text-center col-md-3">
<imgsrc="{{$autor->avatar}}..."class="rounded"alt=" {{$autor->avatar_alt}}">
</div>
</div>
</div> 

Una alternativa es que no extraigamos valores de la base de datos y solo necesitemos introducir variables que llevan valores estaticos.

 <div class = flex-row col-md-6  >
 <div class=d- flexjustify-content-end col-md-9>
 <spanclass= text-justify> {{$autor}}.</span>
 <divclass="text-center col-md-3">
<imgsrc="{{$avatar}}..."class="rounded"alt=" {{$avatar_alt}}">
</div>
</div>
</div>
  

Ahora al llamar el componente desde la vista añadiríamos la directiva slot que es la encargada de traernos el valor de esas variables.

 @component('layouts.components.navbar')
 @slot('autor')
 colocamos aquí el valor 
 @endslot
 @slot('avatar')
 colocamos aquí el valor 
 @endslot
 @endcomponent
 @slot('avatar_alt')
 colocamos aquí el valor 
 @endslot 

Esto pudiéramos hacerlo también de otro modo, gracias a la ductilidad de Laravel. Esta via por cierto es un poco más robusta.
Para ello declararemos, nuestro componente en el proveedor de servicios de Laravel, en su función boot()

Antes de hacer esto debemos decirle al proveedor de servicios que vamos a usar una instancia de la fachada Blade, asi que tendremos que incluir al inicio la sentencia.

 use Illuminate\Support\Facades\Blade;

//Luego podemos ya incluir en la función boot, lo siguiente:

 Blade::component('layouts.components.curric_autor,'autor'); 

Con esto le estamos diciendo a Laravel primero donde se encuentra el componente, y segundo nombre que utulizaremos para llamarlo, entendemos entonces que la  estructura es:

(ruta o namespace del componente, alias del componente)

Entonces, ahora podremos llamar al componente, desde cualquier lugar con la directriz @y su alias, en nuestro caso será:

@autor

Quedando el modo de llamar a nuestro componente como:

@autor(['autor'=>'valor', 'avatar'=>'valor', 'avatar_alt'=>'valor',]) @endautor

Y listo, esto es todo.

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias.

….un sueño es casi todo  y más que  nada, más que todo al soñarlo, casi nada después……