CRUD simple [ JAVA + SQLITE + MVC ]


Hace ya mucho tiempo que no eh realizado proyectos con java.
Hoy les presento este pequeño proyecto que realiza todas las funciones de un CRUD utilizando el patrón de diseño arquitectónico MVC(Modelo,Vista,Controlador).

Como instalar PHPStorm en Ubutnu 15.04


PHPStorm se a convertido en mi IDE favorito pero al migrar a Ubuntu pude darme cuenta que la instalación puede llegar a ser un problema. Les voy a mostrar como lo hice.

Instalando JDK(Java Development Kit)


Lo podemos encontrar en: Java SE Downloads

php-excel una ligera alternatva para PHPExcel

PHP


Como sabemos PHPExcel es una potente libreria para importar y exportar hojas de calculo, que apesar de ser muy lenta, es la unica que soporta OpenDocumentXML o los formatos xlsx, docx, etc.
PHPExcel se ve torturado cuando le pedimos que maneje o exporte una gran cantidad de información en varios worksheets.

Navegando por la web encontre varias alterativas, pero después de trabajar con este paquetazo no me sentia conforme con ninguna de las sugeridas.

A pesar de todo no me rendi y pude encontrar a php-excel. Un paquete basado en Spreadsheet_Excel_Writer de PEAR, solo maneja el formato xls y únicamente sirve para exportar.

Ahora para crear una simple hoja de calculo con pocos datos veamos como se vería nuestro código usando PHPExcel:


$excel = new PHPExcel();

//Usamos el worsheet por defecto
$sheet = $excel->getActiveSheet();

//Agregamos un texto a la celda A1
$sheet->setCellValue('A1', 'Prueba');
//Damos formato o estilo a nuestra celda
$sheet->getStyle('A1')->getFont()->setName('Tahoma')->setBold(true)->setSize(8);
$sheet->getStyle('A1')->getBorders()->applyFromArray(array('allBorders' => 'thin'));
$sheet->getStyle('A1')->getAlignment()->setVertical('center')->setHorizontal('center');

$sheet->setCellValue('B1', 'PHPExcel');
//usamos los mismos estilos de A1
$sheet->getStyle('B1')->getFont()->setName('Tahoma')->setBold(true)->setSize(8);
$sheet->getStyle('B1')->getBorders()->applyFromArray(array('allBorders' => 'thin'));
$sheet->getStyle('B1')->getAlignment()->setVertical('center')->setHorizontal('center');

//exportamos nuestro documento
$writer = new PHPExcel_Writer_Excel5($excel);
$writer->save('prueba.xls');

$xls = new Excel_Writer_Workbook('prueba.xls');
Y como se vería usando nuestro paquete en cuestión:


$xls = new Excel_Writer_Workbook('prueba.xls');

//creamos nuestro estilo para títulos
$h1 = $xls->addFormat();
$h1->setBold();
$h1->setSize(8);
$h1->setFontFamily('Tahoma');
$h1->setBorder(1);
$h1->setAlign('center');

//creamos nuestro worksheet
$sheet = $xls->addWorksheet('Worksheet 1');

//Agregamos textos en A1 y B1 con el estilo ya definido en $h1
$sheet->write(0, 0, 'Prueba', $h1);
$sheet->write(0, 1, 'php-excel', $h1);

//exportamos nuestro documento
$xls->close();

Usando php-excel a largo plazo podríamos ahorrarnos muchas lineas de código.

Es importante tener en cuenta que el código de PHPExcel podríamos optimizarlo un poco, pero estas optimizaciones obviamente aumentaran el tiempo de renderización y ejecución.

Veamos nuestro código PHPExcel optimizado (La ejecución tardo 0.25463199615479 micro-segundos):


$excel = new PHPExcel();

//Usamos el worsheet por defecto
$sheet = $excel->getActiveSheet();

//creamos nuestro array con los estilos para titulos
$h1 = array(
 'font' => array('bold' => true, 'size' => 8, 'name' => 'Tahoma'),
 'borders' => array('allborders' => array('style' => 'thin')),
 'alignment' => array('vertical' => 'center', 'horizontal' => 'center')
);

//Agregamos texto en las celdas
$sheet->setCellValue('A1', 'Prueba');
$sheet->setCellValue('B1', 'MatrixDevelopments');

//Damos formato o estilo a nuestras celdas
$sheet->getStyle('A1:B1')->applyFromArray($h1);

//exportamos nuestro documento
$writer = new PHPExcel_Writer_Excel5($excel);
$writer->save('prueba1.xls');
Ahora veamos nuestro codigo php-excel optimizado (La ejecución tardo 0.08405590057373 micro-segundos):


$xls = new Excel_Writer_Workbook('prueba.xls');

//creamos nuestro estilo para titulos
$h1 = $xls->addFormat(array('bold' => 1, 'size' => 8, 'fontFamily' => 'Tahoma', 'border' => 1, 'align' => 'center'));

//creamos nuestro worksheet
$sheet = $xls->addWorksheet('Worksheet 1');

//Agregamos textos en A1 y B1 con el estilo ya definido en $h1
$sheet->write(0, 0, 'Prueba', $h1);
$sheet->write(0, 1, 'MatrixDevelopments', $h1);

//exportamos nuestro documento
$xls->close();
Después de hacer estas pequeñas pruebas, pude comprobar/verificar que php-excel es mas eficiente que PHPExcel.

Todo esto es decisión de cada uno, ustedes deciden con que librería/paquete van trabajar. Cumplí mi parte al compartir este pequeño conocimiento, espero que les sea de utilidad y si les gusto no olviden dejar su comentario y compartan con todo el mundo....!!

ENLACES:
Spreadsheet_Excel_Writer | PEAR
php-excel | Repositorio en GitHub
PHPExcel | Web Oficial
PHPExcel | Repositorio en GitHub

Implementar Entrust usando Middleware's [ Laravel 5 ]


En nuestro post anterior ENTRUST [ Laravel5 ], hablamos de la instalación, configuración y aplicación del paquete.
Ahora vamos a ver como implementarlo en nuestro proyecto usando Middleware's.

Para este tutorial eh usado los siguientes paquetes:

  1. laravel-ide-helper - Paquete de autocompletado de código en IDE's | Enlace
  2. laravel-debugbar - Paquete util al momento de testear nuestro proyecto | Enlace

En el anterior post creamos un usuario, roles, permisos y los asignamos o relacionamos respectivamente.

Creamos una ruta para testear nuestro usuario:

get('test', function () {
    return \App\User::find(4)->load([
        'roles' => function ($q) {
            $q->with('perms');
        }
    ]);
});
Y el front nos retorna:
{
    "id": "4",
    "name": "John Doe",
    "email": "johndoe@doe.com",
    "created_at": "2015-05-25 15:51:42",
    "updated_at": "2015-05-25 15:51:42",
    "roles": [
        {
            "id": "1",
            "name": "admin",
            "display_name": "Administrador de usuarios",
            "description": "Se permite al usuario gestionar y editar otros usuarios",
            "created_at": "2015-05-22 20:40:48",
            "updated_at": "2015-05-22 20:40:48",
            "pivot": {
                "user_id": "4",
                "role_id": "1"
            },
            "perms": [
                {
                    "id": "1",
                    "name": "create-post",
                    "display_name": "Crear Entradas",
                    "description": "crear nuevas entradas del blog",
                    "created_at": "2015-05-25 15:53:47",
                    "updated_at": "2015-05-25 15:53:47",
                    "pivot": {
                        "role_id": "1",
                        "permission_id": "1"
                    }
                },
                {
                    "id": "2",
                    "name": "edit-user",
                    "display_name": "Editar Usuarios",
                    "description": "editar los usuarios existentes",
                    "created_at": "2015-05-25 15:53:47",
                    "updated_at": "2015-05-25 15:53:47",
                    "pivot": {
                        "role_id": "1",
                        "permission_id": "2"
                    }
                }
            ]
        }
    ]
}
Como vemos el Usuario tiene asignado el rol admin el cual tiene 2 permisos: create-post y edit-user; Para usar esta información vamos a crear nuestro middleware.
En nuestra terminal tipeamos:
php artisan make:middleware EntrustMiddleware
Agregamos nuestro Middleware al Kernel del proyecto app/Http/Kernel.php, en el arreglo $routeMiddleware agregamos:
'entrust' => 'App\Http\Middleware\EntrustMiddleware'

Ahora abrimos nuestro archivo app/Http/Middleware/EntrustMiddleware.php:

<?php namespace App\Http\Middleware;

use Closure;

class EntrustMiddleware {

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request);
    }

}
En el constructor de esta clase vamos a inyectar Illuminate\Contracts\Auth\Guard(Usuario autentificado) e Illuminate\Routing\Route(Ruta actual con todas sus caracteristicas) y lo siguiente sera analizar los requerimientos de la ruta:


public function __construct(Guard $auth, Route $route)
{
    /**
     * Información del usuario autentificado
     */
    $this->auth = $auth;

    /**
     * Si en la ruta definimos que necesita roles
     * get('uri',['roles'=>'admin'])
     */
    if(isset($route->getAction()['roles']))
    {
        $this->requireRole = true;
        $this->roles = $route->getAction()['roles'];
    }
    /**
     * Si en la ruta definimos perms
     * get('uri',['perms'=>'create-post'])
     */
    if(isset($route->getAction()['perms']))
    {
        $this->needsPerms = true;
        $this->permissions = $route->getAction()['perms'];
    }
}
Yo cree 2 funciones donde se verifica/analiza si el usuario autentificado cumple los requerimientos de la ruta:


/**
 * Analiza si el usuario autentificado 
 * tiene el(los) rol(es) solicitado(s) en la ruta
 * 
 * @param \Illuminate\Http\Request $request
 * @param \Closure $next
 * @return \Illuminate\Http\RedirectResponse
 */
protected function analiceWithRole($request, $next)
{
    if($this->auth->user()->hasRole($this->roles))
    {
        if($this->needsPerms)
        {
            return $this->analiceWithPerms($request, $next);
        }

        return $next($request);
    }
    else
    {
        Flash::warning('No Tiene permisos suficientes para acceder a este recurso.');

        return redirect()->back(302);
    }
}

/**
 * Analiza si el usuario autentificado
 * tiene los permisos solicitados en la ruta
 * 
 * @param \Illuminate\Http\Request $request
 * @param \Closure $next
 * @return \Illuminate\Http\RedirectResponse
 */
protected function analiceWithPerms($request, $next)
{
    if($this->auth->user()->can($this->permissions))
    {
        return $next($request);
    }
    else
    {
        Flash::warning('No Tiene acceso a este recurso.');

        return redirect()->back(302);
    }
}
Ahora nuestro middleware completo quedaría de esta manera:


<?php namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Routing\Route;
use Laracasts\Flash\Flash;

class EntrustMiddleware
{

    protected $requireRole = false;
    protected $needsPerms = false;

    public function __construct(Guard $auth, Route $route)
    {
        /**
         * Información del usuario autentificado
         */
        $this->auth = $auth;

        /**
         * Si en la ruta definimos que necesita roles
         * get('uri',['roles'=>'admin'])
         */
        if(isset($route->getAction()['roles']))
        {
            $this->requireRole = true;
            $this->roles = $route->getAction()['roles'];
        }

        /**
         * Si en la ruta definimos perms
         * get('uri',['perms'=>'create-post'])
         */
        if(isset($route->getAction()['perms']))
        {
            $this->needsPerms = true;
            $this->permissions = $route->getAction()['perms'];
        }
    }

    /**
     * Handle an incoming request.
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if($this->requireRole)
        {
            return $this->analiceWithRole($request, $next);
        }
        elseif($this->needsPerms)
        {
            return $this->analiceWithPerms($request, $next);
        }
        else
        {
            return $next($request);
        }
    }

    /**
     * Analiza si el usuario autentificado
     * tiene el rol(es) solicitado en la ruta
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure $next
     * @return \Illuminate\Http\RedirectResponse
     */
    protected function analiceWithRole($request, $next)
    {
        if($this->auth->user()->hasRole($this->roles))
        {
            if($this->needsPerms)
            {
                return $this->analiceWithPerms($request, $next);
            }

            return $next($request);
        }
        else
        {
            Flash::warning('No Tiene permisos suficientes para acceder a este recurso.');

            return redirect()->back(302);
        }
    }

    /**
     * Analiza si el usuario autentificado
     * tiene los permisos solicitados
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure $next
     * @return \Illuminate\Http\RedirectResponse
     */
    protected function analiceWithPerms($request, $next)
    {
        if($this->auth->user()->can($this->permissions))
        {
            return $next($request);
        }
        else
        {
            Flash::warning('No Tiene acceso a este recurso.');

            return redirect()->back(302);
        }
    }
}
Con esto tenemos nuestro middleware creado y yo creo que es muy bonito :3 :).
Ahora vamos a usarlo, en nuestro archivo app/Http/routes.php vamos a definir unas cuantas rutas para testear nuestro middelware:


Route::group(['middleware' => ['entrust', 'auth'], 'roles' => 'admin', 'perms' => 'create-post'], function ()
{
    get('dashboardAdmin', function ()
    {
        return "El usuario autentificado tiene el rol de Administrador y tiene permisos para crear post's";
    });
});

Bueno y así de simple resulta la implementación de este paquete a nuestro Front, claro que este es solamente un punto de vista. Seguramente hay mejores programadores que en conjunto podrían crear algo mucho mejor.

Si te perdiste en alguna de la entrada, puedes descargar el código fuente del proyecto en GitHub | Enlace |
No olviden que después de descargar el código deben tipear:
composer install

Espero que les sea de utilidad,
Saludos y hasta la próxima.

PD: No se olviden de dejar algún comentario y también son libres de modificar a su gusto el código

ENTRUST [ Laravel 5 ]


Entrust nos presenta una manera flexible de agregar permisos basados ​​en roles para Laravel 5.

La documentación oficial(en ingles), nos da una vista amplia de lo que podemos hacer con este "paquetazo".

Instalación


Abrimos una consola en la raíz de nuestro proyecto y tipeamos:
composer require zizaco/entrust dev-laravel-5
Luego, en config/app.php al arreglo de 'providers' añadir:
'Zizaco\Entrust\EntrustServiceProvider',
y al arreglo 'aliases' añadir:
'Entrust' => 'Zizaco\Entrust\EntrustFacade',
Ahora veamos como se usa..!!

Configuración


Entrust trae unas configuraciones por defecto (tablas,modelos,etc.), pero si deseas personalizar dichas configuraciones, abriremos una terminal en la raíz de nuestro proyecto y tipeamos:
php artisan vendor:publish
en el archivo config/entrust.php vamos a definir los nombres de nuestras tablas y también de nuestros modelos, en mi caso sera esto:
return array(

    'role' => 'App\Models\Role',

    'roles_table' => 'roles',

    'permission' => 'App\Models\Permission',

    'permissions_table' => 'permissions',

    'permission_role_table' => 'permission_role',

    'role_user_table' => 'role_user',

);
Ahora vamos a generar las migraciones en nuestra terminal tipeamos:
php artisan entrust:migration


Se genera la migración <timestamp>_entrust_setup_tables.php y ahora podemos migrar todo a nuestra base de datos:
php artisan migrate


Después de la migración, cuatro tablas nuevas estarán presentes:

  1. roles - Almacena los roles
  2. permissions - Almacena los permisos
  3. role_user - Almacena las relaciones de muchos-a-muchos entre roles y usuarios
  4. permission_role - Almacena las relaciones de muchos-a-muchos entre roles y permisos

Lo siguiente es crear los modelos que requiere el paquete:

Role


En nuestro archivo de configuración entrust.php definimos los nombres de los modelos, en mi caso cree una carpeta llamada Models. Aquí agregamos el archivo Roles.php

<?php namespace App\Models;

use Zizaco\Entrust\EntrustRole;

class Role extends EntrustRole
{
}

Permission


En la misma carpeta creamos el archivo Permission.php

<?php namespace App;

use Zizaco\Entrust\EntrustPermission;

class Permission extends EntrustPermission
{
}

User


Por ultimo en nuestro modelo User agregamos el trait EntrustUserTrait que trae el paquete.

<?php namespace App;

use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Database\Eloquent\Model;
use Zizaco\Entrust\Traits\EntrustUserTrait;

class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{

    use Authenticatable, CanResetPassword, EntrustUserTrait; // add this trait to your user model

    ...
}

Esto agrega la relación del usuario con sus roles y también varias funciones para comprobar los permisos de dichos roles.

Aplicación


Veamos como asignamos roles y agregamos permisos:

/**
 * Creamos un Rol
 */
$admin = new \App\Models\Role();
$admin->name = 'admin';
$admin->display_name = 'Administrador de usuarios'; // opcional
$admin->description = 'Se permite al usuario gestionar y editar otros usuarios'; // opcional
$admin->save();

/**
 * Creamos un Usuario
 */
$user = new \App\User();
$user->name = 'John Doe';
$user->email = 'johndoe@doe.com';
$user->password = bcrypt('12345');
$user->save();

/**
 * Asignamos el Rol admin al usuario
 * Usando el alias del paquete
 */
$user->attachRole($admin);// podemos enviar el Rol o el id del Rol

/**
 * O usamos Eloquent
 */
$user->roles()->attach($admin->id); //usamos solamente el id del Rol

/**
 * Creamos permisos
 */
$createPost = new \App\Models\Permission();
$createPost->name = 'create-post';
$createPost->display_name = 'Crear Entradas'; // opcional
// Allow a user to...
$createPost->description = 'crear nuevas entradas del blog'; // opcional
$createPost->save();

$editUser = new \App\Models\Permission();
$editUser->name = 'edit-user';
$editUser->display_name = 'Editar Usuarios'; // opcional
// Allow a user to...
$editUser->description = 'editar los usuarios existentes'; // opcional
$editUser->save();

/**
 * Al Rol admin le asignamos los permisos
 */
$admin->attachPermission($createPost); //esto es equivalente a $admin->perms()->sync(array($createPost->id));
$admin->attachPermissions([$createPost, $editUser]); //esto es equivalente a $admin->perms()->sync(array($createPost->id, $editUser->id));

Revisar Roles y Permisos


Para poder comprobar los roles usaremos:

$user->hasRole('owner');   // false
$user->hasRole('admin');   // true
$user->can('edit-user');   // true
$user->can('create-post'); // true

En nuestro próximo tutorial hablaremos de como implementarlo usando middleware's y también mejoraremos unas cuantas lineas de código.

Saludos y hasta la proxima.

Fuente: Zizaco/entrust - GitHub

Artisan + PHPStorm [ Laravel ]


PHPStorm es un IDE asombrosamente increíble, es muy amigo de los framework’s como Symfony,Wordpress,Drupal, Laravel, etc.

Trae soporte para herramientas de línea de comandos, como por ejemplo artisan. Aprendamos como habilitarlo en nuestro proyecto.