Tag: laravel

Oracle Driver para Laravel 4|5|6|7 (Linux server)

Para empezar a utilizar una base de datos de Oracle necesitaremos tener instalado la extensión para PHP oci8.

Si no la tenemos instalada tendremos que hacer los siguientes pasos:

Instalar Oracle Instant Client

Necesitaremos “instantclient-basic” y “instantclient-devl” instalados en nuestro sistema para montar la extensión de oci8.

cd /usr/src
wget https://download.oracle.com/otn_software/linux/instantclient/19600/oracle-instantclient19.6-basic-19.6.0.0.0-1.x86_64.rpm
wget https://download.oracle.com/otn_software/linux/instantclient/19600/oracle-instantclient19.6-devel-19.6.0.0.0-1.x86_64.rpm
yum localinstall oracle-instantclient19.6-basic-19.6.0.0.0-1.x86_64.rpm
yum localinstall oracle-instantclient19.6-devel-19.6.0.0.0-1.x86_64.rpm

Procedemos a la instalación de la extensión oci8

pecl73 install oci8

Cuando nos pida la ruta de instalación del Oracle Instant Client colocaremos «instantclient» y la ruta donde lo tengamos instalado de la siguiente forma:

instantclient,/usr/lib/oracle/19.6/client64/lib

Modificamos el php.ini añadiendo la extensión

php -i | grep "Loaded Configuration File"
nano / vim /url_configuration_file/php.ini
extension=oci8.so

Reiniciamos php

systemctl restart tuVersionPhp

Verificamos la extensión oci8

php --ri oci8

Podemos encontrarnos que al hacer php -v nos muestre un error:

PHP Warning: PHP Startup: Unable to load dynamic library ‘oci8.so’ (tried: /usr/local/lib/php/extensions/tu_carpeta_de_extensiones/oci8.so

Este error puede deberse a que habrá dependencias de la librería compartida que no estén instaladas en nuestro sistema. Para verificar esto utilizaremos el siguiente comando:

ldd /usr/local/lib/php/extensions/tu_carpeta_de_extensiones/oci8.so

Datatables con Laravel 6

Para sacarle partido a DataTables en Laravel, vamos a hacer una integración utilizando la librería original y un paquete especialmente creado por  Arjay Angeles (Yajra) que nos facilitará el manejo de la opción server-side de datatables.

Ya sabemos que DataTables es un plugin de jQuery para renderizar tablas de forma sencilla y con muchas funcionalidades. Por lo que, necesitaremos incluir jQuery en nuestro proyecto.

Instalación yajra/laravel-datatables

Para el uso de Datatables en Laravel, vamos a utilizar este paquete que nos facilitará mucho las cosas: jQuery DataTables API for Laravel 4|5|6

Lo instalamos vía composer

composer require yajra/laravel-datatables-oracle:"~9.0"

Toda la documentación la podemos obtener en https://yajrabox.com/docs/laravel-datatables/master/installation

Instalación DataTables

Instalaremos la librería de datatables utilizando NPM Node.JS

npm install --save datatables.net-dt

Para utilizarlo vamos a entrar a nuestro app.js e incluiremos

// DataTables
import dt from 'datatables.net-dt';

¿Listos para trabajar?

Vamos a utilizar nuestro modelo User para este ejemplo. En mi tabla tengo los datos que voy a mostrar a continuación, pero si quieres seguir el ejemplo con los datos que tienes en tu modelo, solamente tienes que cambiar las columnas de la tabla HTML y los datos del recurso.

Vamos a añadir en el documento a renderizar la estructura básica de HTML (views\users\index.blade.php)

<table id="users-table" class="table table-hover table-primary w-100">
    <thead>
        <tr>
            <th>ID</th>
            <th>Nombre</th>
            <th>Apellidos</th>
            <th>Sexo</th>
            <th>Email</th>
        </tr>
    </thead>
    <tbody></tbody>
</table>

Necesitaremos generar una URL para obtener los datos del recurso (routes\web.php)

Route::get('users/list', ['as' => 'users.list', 'uses' => 'UserController@usersList']);

Para la llamada a recuperar datos, añadiremos la utilización de la librería en el controlador (app\Http\Controllers\UserController.php)

use Yajra\DataTables\Facades\DataTables;

En el mismo controlador, crearemos un método userList() que recuperará los datos con una consulta y utilizaremos la función datatables (PHP) para crear una respuesta de tipo JSON.


/**
 * Devuelve el listado en JSON de los usuarios
 *
 * @param User $user
 * @param Request $request
 * @return void
 */
public function usersList(User $user, Request $request){

    // Usuarios
    return datatables($user->get())->toJson();
}

Ahora volvemos a abrir resources\js\app.js y añadiremos la función datatables (JS) que nos renderizará los datos en la tabla. Para hacer la llamada, utilizamos una propiedad (columns) con las columnas correspondientes.

¡Mucho Ojo! Tienen que ser el mismo número de columnas que el “thead” de la tabla HTML.

$('#users-table').DataTable({
    processing: true,
    serverSide: true,
    language: {
        "url": "//cdn.datatables.net/plug-ins/1.10.20/i18n/Spanish.json"
    },
    ajax: {
        url: "/users/list",
        dataSrc: "data",
        type: "GET"
    },
    columns: [
        { data: 'id' },
        { data: 'nombre' },
        { data: 'apellidos' },
        { data: 'sexo' },
        { data: 'email' }
    ],
});

Yo estoy usando VueJS para trabajar. Vamos a utilizar el hook mounted y dentro de ella la función vm.$nextTick que lo que hará es accionar el código una vez se haya renderizado la vista completa.

if ($('#users-index').length > 0) {
    const users_index = new Vue({
        el: '#users-index',
        data: {
            usersTable: null
        },
        mounted() {
            this.$nextTick(function() {
                // Código que se ejecutará solo después de
                // haber renderizado la vista completa

                this.getDataTableUsers()
            })
        },
        methods: {
            getDataTableUsers: function() {
                this.usersTable = $('#users-table').DataTable({
                    processing: true,
                    serverSide: true,
                    language: {
                        "url": "//cdn.datatables.net/plug-ins/1.10.20/i18n/Spanish.json"
                    },
                    ajax: {
                        url: "/users/list",
                        dataSrc: "data",
                        type: "GET"
                    },
                    columns: [
                        { data: 'id' },
                        { data: 'nombre' },
                        { data: 'apellidos' },
                        { data: 'sexo' },
                        { data: 'email' }
                    ],
                });
            }
        }
    })
}

Si no estás utilizando VUE, puedes utilizar jQuery y accionar la renderización.

$(document).ready(function() {
    var table = $('#users-table').DataTable({
        processing: true,
        serverSide: true,
        language: {
            "url": "//cdn.datatables.net/plug-ins/1.10.20/i18n/Spanish.json"
        },
        ajax: {
            url: "/users/list",
            dataSrc: "data",
            type: "GET"
        },
        columns: [
            { data: 'id' },
            { data: 'nombre' },
            { data: 'apellidos' },
            { data: 'sexo' },
            { data: 'email' }
        ],
    });
});

Crear Helpers personalizados en Laravel 6

Los «helpers» son métodos o funciones de ayuda que nos facilitan acciones de modificación o tratamiento de datos.

Laravel ya tiene unos helpers definidos que pueden ayudarte. Pero, ¿Y si necesitas definir tus propias funciones de ayuda?

¿Qué tipo de funciones querrías definir en este archivo?

Por ejemplo, podríamos necesitar una función que reciba por parámetro una fecha con formato año/mes/día (Y/m/d) y darle el formato de día/mes/año (d/m/Y).

Para ello vamos a crear nuestro archivo y lo publicaremos en app/helpers.php

Dentro añadiremos la función de ayuda:

<?php
/**
 * Función que nos devuelve la fecha formateada en Español 
 *
 * @param [type] $date
 * @return void
 */
function formatDateToEsp($date){

    return date("d/m/Y", strtotime($date));

}

Para cargar los helpers en nuestra aplicación, vamos a abrir el archivo composer.json, buscamos la clave autoload y ahí añadiremos una nueva clave «files» que contendrá dentro la ruta de nuestro archivo helpers.php:

"autoload": {
        "psr-4": {
            "App\\": "app/"
        },
        "files": [
            "App/helpers.php"
        ],
        "classmap": [
            "database/seeds",
            "database/factories"
        ]
    },

Una vez aplicado, abriremos nuestra consola en la carpeta raíz y escribiremos composer dump-autoload.

$ composer dump-autoload
Generating optimized autoload files

Una vez terminado podremos revisar en nuestro composer.lock las líneas añadidas:

"autoload": {
                "files": [
                    "src/Illuminate/Foundation/helpers.php",
                    "src/Illuminate/Support/helpers.php"
                ],
                "psr-4": {
                    "Illuminate\\": "src/Illuminate/"
                }
            },

Ahora podremos aplicar esta función, por ejemplo, a un listado de datos:

<table class="table align-items-center table-flush">
	<thead class="thead-light">
		<tr>
			<th scope="col">ID</th>
			<th scope="col">FECHA</th>
		</tr>
	</thead>
	<tbody>
		@foreach ($datos as $dato)
			<tr>
				<td>{{ $dato->id }}</td>
				<td>{{ formatDateToEsp($dato->fecha) }}</td>
			</tr>
		@endforeach
	</tbody>
</table>

FECHA SIN FORMATEAR

FECHA FORMATEADA CON FUNCIÓN HELPER

Subconsultas con Laravel 6

Una de las mejoras de Laravel 6 es la utilización de subconsultas utilizando la potencia de Eloquent.

Gracias a esta nueva «feature» de Laravel podremos añadir datos desde tablas distintas en pocos pasos.

A continuación dejo algunos ejemplos útiles:

Ejemplos

Imaginemos que tenemos una tabla de usuarios y de logs.

Queremos ver el último log de cada usuario:

use App\Usuario; 
use App\LogUsuario; 

return Usuario::addSelect(['log_ult_fecha' => LogUsuario::select('fecha') 
->whereColumn('usuario_id', 'log_usuario.id') 
->orderBy('fecha', 'desc') 
->limit(1)])->get();

Ahora queremos que ademas de la fecha del log, nos devuelva el texto guardado con la información:

use App\Usuario; 
use App\LogUsuario; 

$ultimoLogUsuarios = [
'log_ult_fecha' => LogUsuario::select('fecha') 
    ->whereColumn('usuario_id', 'log_usuario.id') 
    ->orderBy('fecha', 'desc') 
    ->limit(1),
'log_ult_info' => LogUsuario::select('info') 
    ->whereColumn('usuario_id', 'log_usuario.id') 
    ->orderBy('fecha', 'desc') 
    ->limit(1)
];
return Usuario::addSelect($ultimoLogUsuarios)->get();

En este último ejemplo observamos que podemos añadir cuantas columnas requiramos agrupándolas en el array que espera el método estático addSelect. Podemos utilizar todos los modelos que necesitemos relacionando las claves necesarias y las condiciones que deseemos.

Esto nos puede dar una idea de las posibilidades que nos ofrece esta nueva característica.

Por ejemplo podríamos crear un método relacional dentro del modelo de UsuarioCon este mismo ejemplo pude pasar de usar unas Vistas de SQL SERVER  a utilizar el potencial de Eloquent y realizar la misma acción.

En algún caso pensé en realizar las consultas a estas vistas, pero ya que en su momento decidí exportar todo un sistema antiguo a utilizar el backend de Laravel 6, decidí hacerlo desde cero y experimentar con las nuevas herramientas que ofrece el nuevo Laravel. Es la mejor decisión que he tomado y deberías tomar si es tu caso.

namespace App;

use Illuminate\Database\Eloquent\Model;

class Usuario extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'usuarios';

    /**
    * Recupera el Ultimo Log del Usuario
    */
    public function UsuarioUltimoLog($estado = 3)
    {

        $ultimoLogUsuarios = [
            'log_ult_fecha' => LogUsuario::select('fecha') 
                ->whereColumn('usuario_id', 'log_usuario.id') 
                ->orderBy('fecha', 'desc') 
                ->limit(1),
            'log_ult_info' => LogUsuario::select('info') 
                ->whereColumn('usuario_id', 'log_usuario.id') 
                ->orderBy('fecha', 'desc') 
                ->limit(1)
        ];

        return Usuario::addSelect($ultimoLogUsuarios)
            ->where('estado', $estado)
            ->orderBy('id','DESC')
            ->paginate(15);
    }
}

Laravel 6

Voy a comenzar un nuevo proyecto y para ello he planteado utilizar la última versión de Laravel:

composer create-project --prefer-dist laravel/laravel blog

Laravel Framework 6.8.0  ( Según mi consola php artisan –version)

¿Por qué utilizar esta versión?

La última versión de Laravel ya cuenta con muchas mejoras y correcciones de errores de versiones anteriores. No supone un riesgo a la hora de probar e instalar una aplicación de 0 ya que tenemos toda la documentación a mano.

¿Y si queremos pasar de la versión 5 a la versión 6? En este caso, como es obvio, tenemos que documentarnos bien sobre las diferencias entre versiones y compatibilidades con paquetes ya instalados en versiones anteriores. Lo bueno es que los desarrolladores se han tomado su tiempo para dejar toda la documentación a mano y así poder pasar de la versión 5 a la 6.

 

Alguna de las últimas mejoras que considero importantes en esta última versión:

Versión LTS (Long term support en castellano Soporte de largo plazo)

Para la versión 6 los desarrolladores proveerán de corrección de errores (Bug Fixes)  durante 2 años (hasta el 3 de septiembre de 2021) y correcciones de seguridad durante 3 años (hasta el 3 de septiembre de 2022)

Mejoras de Eloquent Subqueries

Laravel 6 presenta nuevas mejoras para dar más dinamismo a nuestras consultas (queries). Ahora se podrán hacer subconsultas (subqueries) utilizando pocas líneas.

return Destination::addSelect(['last_flight' => Flight::select('name')
->whereColumn('destination_id', 'destinations.id')
->orderBy('arrived_at', 'desc')
->limit(1)
])->get();

Este ejemplo nos devolvería una consulta de un modelo Destination (Destino del Vuelo) añadiendo una subconsulta de model Flight (Vuelo) para devolvernos los datos de todos los destinos y sus vuelos relacionados ordenados por la llegada (arrived_at) más reciente.

Laravel UI

Laravel nos ofrecía en versiones anteriores esqueleto frontend (frontend scaffolding) con Bootstrap y Vue. En la versión 6 de Laravel esto ya no es así, ya que lo han extraído a un paquete de Composer laravel/ui. Al igual que esto, también se ha extraído el frontend de autenticación que antes llamabamos con el comando make:auth.

Para poder añadir el scaffolding ahora tendremos que hacerlo vía composer y el comando ui de Artisan:

composer require laravel/ui --dev

php artisan ui vue --auth

Excepciones con Ignition

Laravel 6 cuenta con Ignition integrado, una nueva forma de ver las excepciones visualmente. Creado por Freek Van der Herten and Marcel Pociot, Ignition nos ofrece una mejora en el manejo de errores añadiendo soluciones en el acto por pantalla, editar código, compartir excepciones y una mejorada UX.

Podemos ver en este ejemplo el manejador de excepciones de Larvel 5 y la nueva de Laravel 6 con Ignition

Laravel 5

Laravel 6

Gestión de Resultados RaceChipAragon.com

Gestor de Resultados Online

RaceChipAragón.com es una empresa que cronometra tiempos de eventos deportivos (running, trail, btt), dando servicio como cronometradores certificados en España. Sus clientes directos son organizadores y los indirectos los atletas que participan en los eventos deportivos, los cuales son los interesados principales en ver los tiempos que realiza cada uno de ellos.

Para gestionar los tiempos he creado un sistema de gestión de clasificaciones utilizando el framework de LARAVEL para gestionar todo el backend de la sección de Resultados.

El usuario puede crear, editar y eliminar eventos. Por cada evento se pueden gestionar las clasificaciones utilizando una importación con EXCEL y/o con archivos PDF.

Cuando se suben los archivos Excel el nombre de cada columna se añade como título de las columnas que se muestran en el listado. Se pueden habilitar o deshabilitar columnas y por cada columna añadir un filtro para que los inscritos puedan utilizarlo.

La página es responsive gracias a Bootstrap 4 y además es capaz de redimensionarse automáticamente en modo iframe utilizando un plugin especifico para ello, evitando que el iframe se muestre con un alto estático.

Podemos verla dentro de la sección https://www.racechiparagon.com/resultados-de-cronometrajes

Cuando publicamos los resultados veremos un listado de los eventos que estén habilitados:

Listado Eventos - RacechipAragon.com

Por cada evento gestionado podemos generar clasificaciones tanto subiendo un Excel como utilizando archivos PDF:

Clasificaciones - RacechipAragon.com

Instalar Laravel 5.5 en 1and1

Para crear nuestro proyecto con Laravel en 1and1.com necesitamos revisar que nuestro servicio contratado cumple los requisitos mínimos.

  • PHP >= 7.0.0
  • OpenSSL PHP Extension
  • PDO PHP Extension
  • Mbstring PHP Extension
  • Tokenizer PHP Extension
  • XML PHP Extension

En principio la mayoría de estos requisitos los cumplimos. Pero puede ser que la versión de PHP no la tengamos bien configurada. Para ello sigue los pasos de Cambiar la Configuración de PHP en 1and1.

 

Una vez revisado estos puntos vamos a proceder a crear nuestra carpeta de proyecto. Simplemente puedes entrar con el Filezilla y crearla en el raíz o dentro de la carpeta clickandbuilds. No importa donde sea, lo importante es que recuerdes donde lo has creado.

Instalar Composer en 1and1

Nos conectaremos vía SSH con nuestras credenciales vía PUTTY. Las podemos encontrar en la misma sección de «Hosting» en el menú de 1and1 y suelen ser las mismas de acceso FTP.

Una vez dentro buscamos nuestra carpeta de proyecto e instalamos el composer con el siguiente comando:

curl -sS https://getcomposer.org/installer | /usr/bin/php7.1-cli

NOTA: Utilizo la versión 7.1 porque la 7.0 no se encontraba en mi directorio bin. Puedes comprobar si tienes esta versión instalada listando los archivos del directorio: ls -l /usr/bin/ | grep "php7"

Esto nos descargará el composer.phar que es un ejecutable de php para buscar las dependencias de nuestro proyecto.

Ahora ejecutamos el composer por primera vez: /usr/bin/php7.1-cli composer.phar

Para mantenernos actualizados podemos hacerlo con la opción selfupdate: /usr/bin/php7.1-cli composer.phar selfupdate

Crea una BBDD en 1and1

En el menú de la izquierda entramos a la pestaña de «Base de Daots Mysql». Las bases de datos se crean con un nombre que proporciona 1and1. No es personalizable, pero puedes añadir una descripción para diferenciarlas. Introduce tu contraseña y recuerda que esta debe ser lo más segura posible. 1and1 ya nos da un nivel de seguridad según la clave que introducimos.

El proceso de creación tardará unos minutos. Puedes ver el estado de creación en la lista de BBDD.

 

Crear Proyecto Laravel

Puedes crear tu proyecto Laravel en LOCAL (TU PC) o directamente en el servidor conectandonos vía SSH utilizando el composer.

Yo prefiero hacerlo desde LOCAL para trabajar en el entorno habitual de DESARROLLO y PRODUCCIÓN.   (Ver instalación)

Una vez instalado, súbelo a la carpeta de tu proyecto en 1and1 vía Filezilla.

Suponiendo que ya conoces el archivo de conexión .env de laravel, continuaremos con la modificación de éste.

Ya que utilizamos nuestra base de datos en MySql, buscamos la línea de conexión y modificaremos los datos con los que nos da 1and1 para conectarnos a nuestra BBDD de PRODUCCIÓN. Estos datos los puedes encontrar haciendo clic en el nombre de la bbdd dentro del listado.

DB_CONNECTION=mysql
DB_HOST=db709977146.db.1and1.com
DB_PORT=3306
DB_DATABASE=db709977146
DB_USERNAME=dbo709977146
DB_PASSWORD=»Password que has introducido al crearla«

Crear Dominio / Subdominio

Para probar que nuestro proyecto funciona tenemos que hacer que un dominio o subdominio apunte a nuestra carpeta del proyecto.

Entramos a la zona de dominios y buscamos el enlace para crear un subdominio.

 

Una vez se haya creado, entramos a la configuración del subdominio y hacemos clic en el enlace «Ajustar directorio de espacio web». Aquí nos mostrará las carpetas que tenemos en nuestro espacio web. Seleccionamos la de nuestro proyecto, buscamos la carpeta public y la seleccionamos. (Esta configuración también tardará lo suyo)

Si todo ha ido bien, al colocar el nombre de nuestro subdominio veremos que nos mostrará la página de inicio de nuestro nuevo proyecto Laravel.