Sqlite en app híbrida $ionic framework cordova

En este post vamos a explicar de manera sencilla como usar acceso a base de datos Sqlite en una aplicación híbrida en ionic V.1

Para ello debemos instalar ionic framework. Una vez instalado en nuestro PC tendremos acceso por línea de comandos al Ionic Client, desde MSDOS podremos ejecutar las siguientes instrucciones para crear un proyecto en blanco

Recordad que en el navegador no funciona este plugin, pora poder realizar las pruebas podemos controlar si la app se está ejecutando en un browser y en ese caso usar WebSql, de esta manera la app funcionará y podremos hacer las pruebas necesarias, una vez tengamos “funcionalidad para probar” podemos pasar la app a nuestro dispositivo y hacer las pruebas necesarias.

Aquí el código para crear nuestro proyecto, ionic cuenta con varios templates, nosotros usaremos el “blank”, ya que de momento no necesitamos nada más.

ionic start testsqlite blank
cd testsqlite
ionic platform add android
ionic platform add ios

Una vez en nuestro directorio del proyecto, y cargados los platformas, instalamos el plugin

cordova plugin add https://github.com/brodysoft/Cordova-SQLitePlugin.git

Hay varias versiones, pero las pruebas que hemos realizado han sido con este en concreto. Si al instalar el plugin os da problemas de descarga al usar conectar con git, podéis probar de usar GitCMD, debéis instalarlo y ejecutarlo ya que es un CommandShell.

Para que el plugin funcione correctamente, necesitaremos instalar el archivo “ng-cordova.min.js” en el directorio www/js de nuestra aplicación

Este archivo lo debéis cargar en el index.html, justo en la línea antes de la carga de “cordova.js”, ejemplo:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
        <title>Test Sqlite Plugin</title>
        <link href="lib/ionic/css/ionic.css" rel="stylesheet">
        <link href="css/style.css" rel="stylesheet">
        <script src="lib/ionic/js/ionic.bundle.js"></script>
        <script src="js/ng-cordova.min.js"></script>
        <script src="cordova.js"></script>
        <script src="js/app.js"></script>

Ahora en nuestro archivo app.js que es donde indicamos que libs queremos cargar, services, etc… añadimos la ngCordova lib

angular.module('starter', ['ionic', 'ngCordova'])

En este punto ya podemos usar nuestra BD Sqlite, para ello, podemos añadir después del deviceReady del app.js las siguientes líneas

if (window.cordova && window.SQLitePlugin) {  
    alert("Podemos usar SqlLITE !!");
    db = window.sqlitePlugin.openDatabase({name:'testsqlite.db', key:'test', iosDatabaseLocation:'Documents'});
    db.transaction(function(tx) {
        tx.executeSql('CREATE TABLE IF NOT EXISTS personas (nombre, puntos)');
        tx.executeSql('INSERT INTO personas VALUES (?,?)', ['Usuario 1', 200]);
        tx.executeSql('INSERT INTO personas VALUES (?,?)', ['Usuario 2', 100]);
    }, function(error) {
        console.log('ERROR: ' + error.message);
    }, function() {
       alert('Datos generados correctamente');
       console.log('Datos generados correctamente');
    });
                                 
    db.transaction(function(tx) {
        tx.executeSql('SELECT count(*) AS contador FROM personas', [], function(tx, rs) {
           console.log('Registros encontrados: ' + rs.rows.item(0).contador);
           alert('Registros encontrados: ' + rs.rows.item(0).contador);
        }, function(tx, error) {
           console.log('Error: ' + error.message);
        });
    });
} 
else {
   // si no podemos usar el plugin sqlite
   db = window.openDatabase("APSNetMobileDb", "1.0", "testsqlite.db", 100 * 1024 * 1024); 
   alert("usamos WebSQL(DB)");
}

En este código lo que hacemos es crear varias consultas de pruebas, las primeras, crean la tabla personas, y añaden 2 registros a la BD, después hacemos una query para obtener el número de registros que hay, a partir de aquí ya podemos hacer updates, deletes, etc…

Lo ideal es crear un service para gestionar la conexión a la BD, crear métodos por ejemplo de ‘create’, ‘open’, ‘drop’, etc… también getPersonas(), por ejemplo que devuelva la lista de registros, controle si hay errores en la query, de esta manera tendremos el código bien estructurado.

No dejes de visitarnos en http://www.softinline.com

Logs diarios en Laravel 4.2

A veces necesitamos consultar los logs de aplicación para detectar errores pasados o ver que sucedió X día a X hora.
Para esta tarea es importante o aconsejable poder tener los logs separados por días, de esta manera podemos acotar la búsqueda y el archivo de logs no crece desmesuradamente, llegando a tener en algunos casos archivos de log de unos cuantos Mb.
En caso de archivos muy grandes se puede descargar el archivo y utilizar alguna herramienta de split para dividirlo por ejemplo en archivos más pequeños de 10Mb, pero lo ideal es poder editar el archivo ‘online’ desde filezilla o winscp con un editor tipo notepad++ para facilitarnos la vida.
Lo único que habría que hacer es cambiar la config del archivo app/start/global.php

$logFile = 'log-'.php_sapi_name().'.txt';
Log::useDailyFiles(storage_path().'/logs/'.$logFile);

Crear middleware Laravel 5 para configurar según dominio

En este post, vamos a explicar una forma para poder configurar algunos parámetros de vuestra web / aplicación, según el dominio donde se esté ejecutando. Por ejemplo en algunos casos podemos cargar un CSS o personalizar el logo, etc… para ello nos interesa por ejemplo conocer en que dominio se está ejecutando la web y cargar una config desde MySQL con algunos parámetros.

Vamos a ver un ejemplo sencillo

Lo primero es crear nuestro middleWare, en este ejemplo lo llamaremos checkDomain

$ php artisan make:middleware CheckDomain

Al ejecutar este comando, tendremos en nuestra carpeta App/Http/Middleware un archivo llamado CheckDomain.php con el siguiente código

<?php
 
namespace App\Http\Middleware;
 
use Closure;
 
class CheckDomain
{
    /**
     * Run the request filter.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request);
    }
 
}

Ahora vamos a comprobar en que dominio se está ejecutando nuestra web / aplicación, buscaremos en una tabla MySQL y lo guardaremos en una variable de sesión para poder realizar ‘operaciones’ o configurar algún parámetro en función de ese valor. Para eso usaremos el siguiente código en nuestro middleware

   /**
     * Run the request filter.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {     
        $domain = $request->getHost();
            
        $platform = \App\Platform::select()
          ->where('domain', '=', $domain)
          ->first();

        if($platform) {
           Session::set('domain', $domain);
        }

        return $next($request);
    }

Con éste código buscamos el dominio registrado en una tabla MySQL ‘domains’ con un campo ‘domain’, aquí podemos hacer varias comprobaciones como por ejemplo que el registro no esté marcado como deshabilitado, etc, etc, etc…
Una vez obtenido el registro lo guardamos tal cual serializado en la sesión.

Para que nuestro código funcione, debemos indicar a Laravel que rutas usaran ese middleware para verificar el dominio, normalmente lo ideal es usarlo en todas, así pues lo añadiremos al grupo ‘web’ de nuestro archivo kernel.php

    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        // aquí añadimos nuestro middleware
        'checkDomain' => \App\Http\Middleware\CheckDomain::class,
    ];

En los templates, por ejemplo podemos cargar un css diferente verficando el campo css de la tabla domain y que tenemos almacenado en nuestro objeto de session

  <stylesheet src="/css/{{ Session::get('domain')->css }}" />

Servidor HTTP con nodeJS

En este post explicamos como crear un servidor HTTP con nodeJS, en nuestro caso usamos este servidor para enviar notificaciones a todos los usuarios conectados a nuestra web, para ello usamos nodeJS, un cliente PHP que envía mensajes y socket.io para conectar con el servidor nodeJS y recibir dichos mensajes.
En esta primera entrada mostraremos como crear el servidor.

Instalamos nodeJs en nuestro PC

creamos un archivo llamado por ejemplo httpServer.js, que contenga el siguiente código

    // include lib
    var http = require("http");

    // create server
    var server = http.createServer(function (req, res) {              

        // headers to secure request origin            
        res.setHeader('Access-Control-Allow-Credentials', true);
        res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
        res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
                    
        // full body
        var body='';
        
        // request on data
        req.on('data', function (data) {            
            body +=data;
        });
        
        // request on end
        req.on('end',function(){


             // our code
             ...........

        }); 

    });

En el siguiente código, lo que hacemos es, primeramente cargamos la librería, puedes incluirla en el proyecto usando package.json, creamos el servidor y definidos algunas reglas de seguridad del origen de las peticiones.
Mientras nos llegue información la vamos guardando dentro de la variable body y cuando finaliza la recepción de datos, capturamos el evento ‘end’, del request que nos han solicitado, en este punto es donde procesamos la petición (en nuestro caso lo que recibimos es un array codificado en json con la info de lo que hay que comunicar por ej: un array de emails de usuario o id’s, el mensaje, el tipo de comunicado, etc…)

En próxmimos artículos mostraremos como trabajar con BD MySQL, como usar un archivo .ini de configuración y usar socket.io para enviar mensajes.

podeís visitarnos en www.softinline.com

Conferencia del fundador de Wallapop y LetsBonus

El equipo de softinline estuvo en la sala Moritz de Barcelona en la conferencia del fundador de Wallapop y LetsBonus para hablar de su experiencia como emprendador y fundador de varias compañías de éxito.
Un placer y consejos muy valiosos. 😉

IMG_1444[1]

Navegación web usando AJAX

En este post vamos a proponer un sistema de navegación usando AJAX y el hash del objeto location de javascript.
La idea es detectar el cambio de la URL, cargar el contenido necesario mediante una llamada AJAX y mantener la URL para que en caso de refrescar el navegador (F5) se mantenga en la página que estábamos.

Para ello simplemente debemos usar esta función

$(window).on('hashchange', function() {
    var url = location.hash.replace('#', '');
    load(url, '.content');
});

con esto detectaremos el cambio de la url usando ‘#’ por ejemplo, las rutas podrían ser dominio.com/#usuarios para obtener el listado de usuario o dominio.com/#ventas

la función “load”, lo que hará es hacer una petición ajax a nuestro dominio ‘dominio.com/usuarios’, sin el hash y el resultado de esta petición lo cargará en un div que tiene la clase ‘.content’

Otra cosa que nos puede ayudar es capturar los submits de todos los forms de nuestra web, para ello, podemos usar el siguiente código

    $(document).on('submit', function(event) {
        console.log('Event -> ',event);                        
        $.ajax({
            method: event.target.method,
            url: event.target.action.replace('#', ''),
            success: function(data) {
                if(data.redirect != '') {
                    location.hash = data.redirect;
                }
            },
            error: function (xhr, ajaxOptions, thrownError) {
                alert('Error');
            }
        });        
        event.preventDefault();
    });

En este ejemplo capturamos el evento submit, miramos en el objecto event, las propiedades de quien generó el evento, normalmente será un formulario, tenemos event.target.method para hacer la petición por GET o POST, tenemos el event.target.action para saber la URL (a la que quitermos el hash por si lo tuviera).

La idea es que al hacer la petición, desde nuestro PHP, podamos devolver diferentes cosas a realizar, por ejemplo, en este caso, nuestro PHP devuelve un array con el estado, ‘true / false’, y un parámetro que es redirect y que indica si debe cargar alguna otra cosa, en este caso recibe una url, al ponerla en el localtion.hash, se fuerza una petición ajax para cargar otra página.

Esto nos puede ir bien para por ejemplo al dar de alta un usuario, queremos que después cargue de nuevo el listado, pues en php devolveremos por ejemplo

    return [
        'response' => true,
        'redirect' => '#users',
    ];

Nos devolvera true y a parte un redirect -> #users.

Ahora sólo haría falta gestionar los forms para serializar y enviar imágenes, procesar radio buttons, etc… y con un poco de programación, podréis montar un sistema de navegación AJAX 100% rápido y sencillo.

Podéis visitarnos en www.softinline.com

Optimizar la carga de archivos javascript con gulp

JavaScript
JavaScript

En este post, vamos a explicar de forma rápida como optimizar la carga de archivos js de nuestra web. Para ello vamos a utilizar gulp, lo que nos permitirá “empaquetar” todos nuestros js’s en uno sólo, de esta manera aceleramos la carga y el código queda ‘ofuscado’. La idea es que en el entorno de desarrollo tengamos los archivos normales para poder debuggar, pero una vez pasado el código a producción, ejecutar el comando correspondiente para que nos genere por ejemplo un ‘build.js’

Hay que tener algunas cosas:

A la hora de realizar la compactación, es preferible no compactar archivos que ya estén con extensión .min.js, se aconseja usar los archivos sin minimizar para evitar problemas.

Otro factor a tener en cuenta es el orden de carga, al declarar la config, podemos indicar el orden por lo que tenemos que asegurarnos que por ejemplo jQuery carga antes que los plugins que lo necesitan.

Bueno, manos a la obra, lo primero que necesitamos es instalar el gestor de paquetes npm en nuestro PC

npm install -g gulp

Podemos comprobar que tenemos instalado gulp con el siguiente comando

gulp -v

Ahora nos ubicamos en nuestro proyecto y ejecutamos el siguiente comando

npm init

Esto nos genera un archivo package.json con la descripción del proyecto, info y los paquetes npm que vamos a usar, de momento estará vacío.

Instalamos gulp y los paquetes necesarios ejecutando los siguientes comandos

npm install gulp
npm install gulp-uglify
npm install gulp-concat

Ahora si abrimos el archivos package.json que se creó, veremos que ha añadido las dependencias necesarias.

Vamos a crear nuestro archivos buildgulp.js y pondremos el siguiente código

/*
* Carga de dependencias
*/
var gulp = require('gulp'),
  concat = require('gulp-concat'),
  uglify = require('gulp-uglify');

/*
* Config de tarea buildjs
*/
gulp.task('buildjs', function () {
  gulp.src([
      'js/jquery.js',
      'js/jquery-ui.js',
      'js/dir1/file1.js',
      'js/dir2/file2.js',
   ])
  .pipe(concat('build.js'))
  .pipe(uglify())
  .pipe(gulp.dest('js/build/'))
});

Como podéis observar, indicamos que archivos queremos “empaquetar”, se pueden usar comodines, por ejemplo /dir/*.js, en este ejemplo hemos preferido indicar archivo por archivo en un array, de esta manera nos aseguramos el orden en que los archivos son empaquetados. Una vez los empaqueta, se genera un archivo dentro de /js/build que se llamará build.js y que contendrá todos nuestros scripts JS

Ejecutamos el comando gulp buildjs

Ahora sólo tendremos que asegurarnos que dependiendo del entorno donde este la aplicación (dev, test, production), cargaramos los scripts por separado o llamando al build.js.

Comentaros que a parte de estas tareas gulp incorpora multitud de módulos que permiten ejecutar tareas de forma automática encadenadas, se podría por ejemplo borrar un directorio de archivos temporales, unificar js, unificar css, renombrar archivos, borrar caché, etc.. todo ello encadenado con el comando ‘pipe‘ tal y como podéis ver en el código.

Cualquier duda podéis contactar con nosotros o visitar nuestra web en http://www.softinline.com

Instalar WordPress en una instalación PHP/Laravel

Para poder instalar un wordpress en un dominio con una web o aplicación hecha en laravel, la mejor opción es hacerlo dentro del directorio /public de nuestra aplicación. Para ello podemos crear por ejemplo un directorio /public/blog donde podemos ubicar la instalación de wordpress.

El problema que nos podemos encontrar es a la hora de hacer las peticiones ya que Laravel por defecto captura todas las requests y las procesa usando su .htaccess.

Para ello sólo bastará añadir la siguiente línea a nuestro .htaccess de Laravel y dejarlo de la siguiente manera

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On

    // aquí está la magia, excluye cualquier cosa que sea referente a nuestro blog
    RewriteCond $1 !^(blog/^)

    # Redirect Trailing Slashes...
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

Sólo tendríamos que cambiar !^(blog/^), poniendo en lugar de ‘blog’ la carpeta donde hemos instalado nuestro wordpress.

Recuerda que wordpress tiene su propio .htaccess para gestionar las url amigables, revisad que lo tenéis en el directorio adecuado y es correcto.

Podéis visitarnos en www.softinline.com

¿Cómo migrar una aplicación web a un framework?

Hoy día el uso de frameworks suelen ahorrarnos bastante trabajo, no obstante, aún solemos encontrar aplicaciones antiguas o aplicaciones que hicimos hace ya unos años cuando el uso de estos frameworks no estaba tan extendido.

Es en estos momentos cuando nos decimos ‘¿por qué no habré usado un framework?’, en este post, vamos a proponer un sistema que puede variar según la aplicación que queramos migrar, este tipo de migración, afecta a la carga de resources (jss, css, imágenes, etc..), a la carga de libs (includes de php), a peticiones AJAX a nuestra aplicación, a $_SESSIONS, etc… lo ideal será tener un entorno separado donde poder realizar las pruebas.

El principio en el que se basa este tipo de migración, es capturar todas las peticiones a nuestra aplicación a través del framework, si la ruta solicitada la tenemos migrada, mostrar la nueva versión y si la petición no corresponde con ninguna ruta migrada, proceder con el sistema antiguo.

Para ello, hemos instalado un framework (para este ejemplo hemos usado Laravel 4.2), dentro de las carpetas del framework hay una que es la ‘public’, donde podemos ubicar la aplicación antigua, para el ejemplo, la hemos puesto dentro de un directorio llamado ‘old’.

Una vez tenemos este sólo nos falta configurar nuestro archivo de rutas, en laravel ‘routes.php’, en este hemos hecho lo siguiente:

// rutas capturadas con el framework y usando el nuevo sistema
Route::get('/users', 'UsersController@index');
Route::get('/users/{id}/edit', 'UsersController@edit');
Route::post('/users/{id}/edit', 'UsersController@edit');
Route::post('/users/{id}/delete', 'UsersController@delete');

// todas las demás rutas pasarán por este código
Route::any('{all}', function(){
    $path = public_path().'/old/';
    chdir($path);
    error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED ^ E_STRICT);
    $tmp = explode('?', $_SERVER['REQUEST_URI']);
    $file = str_replace('/','',$tmp[0]);
    if($file == "") {
        $file = 'index.php';
    }
    require_once $file;
})->where('all', '.*');

En este caso lo que hacemos es en caso de no pasar la ruta a través del framework, ubicarnos en el directorio old, desactivar algunos mensajes de error, etc… y cargar el archivo indicado, aplicaciones antiguas a veces tienen un index.php, login.php, header.php, pues en este caso miramos que archivo cargar.

A parte de la forma de cargar archivos, habrá que hacer que el login del sistema viejo haga automáticamente el login en el nuevo sistema (variables de sesión, etc…) y que el nuevo sistema también haga el login en el sistema viejo.

Evidentemente hay que valorar cada aplicación ya que depende de como se programó habrá que modificar más o menos, la idea es migrar de forma modular a través de este sistema y poder mantener las 2 versiones durante el proceso de migración sin que el usuario final tenga que entrar en 2 aplicaciones, etc…

Esperamos vuestros comentarios o dudas.
Podéis visitarnos en www.softinline.com