Archivo de la categoría: OpenSource & Linux

Open Source & Linux

Un rápido y sencillo CRUD desde Drupal con Auto Admin

Drupal Perú

Este proyecto para fines didácticos lo llamaremos DrupCrud, una aplicación del tipo CRUD (create, read, update and delete) dentro de nuestro Drupal.

Es prequisito ya tener instalado y más o menos conocido a nuestros monstrito Drupal.

Obtenemos drush:

wget http://ftp.drupal.org/files/projects/drush-All-versions-3.0.tar.gz
gunzip -c drush-All-versions-3.0.tar.gz | tar xopf -

Podemos crear un alias para acceder cómodamente a drush, para lograrlo agregamos la siguiente línea:

alias drush='<RUTA DE DRUSH>/drush'

al archivo ~/.bashrc

nano ~/.bashrc

Desde la terminal nos ubicamos en el directorio donde hemos instalado drupal:

cd /var/www/<DIRECTORIO DRUPAL>

Necitamos de los módulos Schema y Auto Admin.

Schema

Introduced in Drupal 6, the Schema API allows modules to declare their database tables in a structured array (similar to the Form API) and provides API functions for creating, dropping, and changing tables, columns, keys, and indexes.

The Schema module provides additional Schema-related functionality not provided by the core Schema API that is useful for module developers. Currently, this includes:

* Schema documentation: hyperlinked display of the schema’s embedded documentation explaining what each table and field is for.
* Schema structure generation: the module examines the live database and creates Schema API data structures for all tables that match the live database.
* Schema comparison: the module compares the live database structure with the schema structure declared by all enabled modules, reporting on any missing or incorrect tables.

Note for MySQL users: The Schema module requires MySQL 5. Prior versions of MySQL do not support the INFORMATION_SCHEMA database that the Schema module uses to inspect the database.

Auto Admin

Auto Admin is a module targeted at developers that generates administration pages for database tables automatically. Using its drush commands it is possible to create list, add, edit and delete pages for multiple tables in a matter of minutes. One-to-many and many-to-one relationships are supported.

Auto Admin is good at managing data for custom modules whose data structure does not fit as node types. It lets you get of the ground and writing «the fun stuff» really, really quick.

Le solicitamos a drush que descargue y ubique adecuadamente los módulos Schema y Auto Admin. Podemos colocar el parámetro -d para mostrar aún más información incluyendo los mensajes internos.

drush -d dl schema autoadmin

Y los habilitamos:

drush pm-enable schema autoadmin

Ahora creamos las tablas que necesitemos. En este punto el tutorial se vuelve más específico para ser más sencillo de entender. Trabajaremos con un caso de ejemplo: Una aplicación CRUD para un directorio de bandas cada una identificada con un país.

CREATE TABLE `bands` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
  `country_id` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `country_id` (`country_id`)
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `countries` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(24) COLLATE utf8_unicode_ci DEFAULT NULL,
  `band_count` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Y creamos el módulo bands, basta con crear un par de archivos en la ruta

/var/www/<RUTA DE DRUPAL>/sites/all/modules/bands

bands.module

<?php
// $Id$
/**
 * @file
 * Module for managing of bands information.
 * This module provides basic managing for band information
 */

bands.info

;$Id$
name = "Bands"
description = "Displays infomration about bands"
core = 6.x
php = 5.3

Buena parte del trabajo lo dejamos en las manos de Dios… digo, de drush. Pero no podrá ser posible sin antes arreglar un problema de incompatibilidad entre la actual versión de drush y auto admin. Creamos un archivo de configuración para drush:

cp <RUTA DE DRUSH>/examples/example.drushrc.php /var/www/<RUTA DE DRUPAL>/sites/default/drushrc.php

En el archivo drushrc.php, descomentamos la siguiente línea:

# $options['allow-spaces-in-commands'] = 1;

Nos queda como tarea actualizar el código de Auto Admin porque:

// DEPRECATED: Allow command names to contain spaces.
// This feature will be removed shortly; drush-3 will
// require commands to be named with dashes instead of
// spaces (e.g. «cache-clear» instead of «cache clear»).
// During the transition period, uncomment the line below
// to allow commands with spaces to be used.

Felices de la vida, que drush realice el trabajo sucio:

drush autoadmin generate bands bands countries --write

Se habrán creado dos archivos:

bands.autoadmin.inc: Agregamos las relaciones necesarias (‘relations’).

<?php
// $Id

/**
 * @file
 * Auto Admin schemas for bands module.
 *
 * @tables {bands}, {countries}
 */

/**
 * Implementation of hook_autoadmin_schema().
 */
function bands_autoadmin_schema() {
  // Auto Admin schema for {bands} table
  $autoadmin_schema['bands'] = array(
    'alias' => 'name',
    'inline_filter' => FALSE,
    'path' => 'admin/content/bands',
    'title' => t('Bands'),
    'title_plural' => t('Bands'),
    'fields' => array(
      'id' => array(
        'autoadmin_type' => 'primary_key',
        'title' => t('Id'),
        'title_plural' => t('Ids'),
      ),
      'name' => array(
        'autoadmin_type' => 'varchar',
        'title' => t('Name'),
        'title_plural' => t('Names'),
      ),
      'country_id' => array(
        'autoadmin_type' => 'int',
        'title' => t('Country'),
        'title_plural' => t('Countries'),
      ),
    ),
    'relations' => array(
      'countries' => array(
        'type' => 'has_one',
        'local_key' => 'country_id',
        'foreign_key' => 'id',
      ),
    ),
  );

  // Auto Admin schema for {countries} table
  $autoadmin_schema['countries'] = array(
    'alias' => 'name',
    'inline_filter' => FALSE,
    'path' => 'admin/content/countries',
    'title' => t('Countries'),
    'title_plural' => t('Countries'),
    'fields' => array(
      'id' => array(
        'autoadmin_type' => 'primary_key',
        'title' => t('Id'),
        'title_plural' => t('Ids'),
      ),
      'name' => array(
        'autoadmin_type' => 'varchar',
        'title' => t('Name'),
        'title_plural' => t('Names'),
      ),
      'band_count' => array(
        'autoadmin_type' => 'int',
        'title' => t('Band Count'),
        'title_plural' => t('Band Counts'),
      ),
    ),
    'relations' => array(
      'bands' => array(
        'type' => 'has_many',
        'local_key' => 'id',
        'foreign_key' => 'country_id',
      ),
    ),
  );

  return $autoadmin_schema;
}

bands.install: Podemos establecer las descripciones de tablas y campos.

<?php
// $Id

/**
 * @file
 * Install file for bands module.
 *
 * @tables {bands}, {countries}
 */

/**
 * Implementation of hook_install().
 */
function bands_install() {
  // Create tables.
  drupal_install_schema('bands');
}

/**
 * Implementation of hook_uninstall().
 */
function bands_uninstall() {
  // Remove tables.
  drupal_uninstall_schema('bands');
  menu_rebuild();
}

/**
 * Implementation of hook__schema().
 */
function bands_schema() {
  // Database schema for {bands} table.
  $schema['bands'] = array(
    'description' => t('Directory of bands'),
    'fields' => array(
      'id' => array(
        'description' => t('TODO: please describe this field!'),
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'name' => array(
        'description' => t('Name of the band'),
        'type' => 'varchar',
        'length' => '64',
        'not null' => FALSE,
      ),
      'country_id' => array(
        'description' => t('TODO: please describe this field!'),
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => FALSE,
      ),
    ),
    'primary key' => array('id'),
    'indexes' => array(
      'country_id' => array('country_id'),
    ),
  );
  
  // Database schema for {countries} table.
  $schema['countries'] = array(
    'description' => t('List of countries'),
    'fields' => array(
      'id' => array(
        'description' => t('TODO: please describe this field!'),
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'name' => array(
        'description' => t('Name of the country'),
        'type' => 'varchar',
        'length' => '24',
        'not null' => FALSE,
      ),
      'band_count' => array(
        'description' => t('TODO: please describe this field!'),
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => FALSE,
      ),
    ),
    'primary key' => array('id'),
  );
  
  return $schema;
}

Habilitamos el módulo:

drush pm-enable bands

Listo. Vemos cómo quedó:

Lista de países:

CRUD on Drupal with Auto Admin

Lista de bandas, observar que se muestra el nombre del país al que pertence:

CRUD on Drupal with Auto Admin

Vista de ingreso de nuevas bandas:

CRUD on Drupal with Auto Admin

El país al que pertenecen las bandas se puede seleccionar de un combobox con las opciones descriptivas:

CRUD on Drupal with Auto Admin

Observaciones:

  • Los IDs son los elementos que realizan el enlace pero no son adecuados para las interfaces por lo que se emplean los nombres o descripciones en texto.
  • Tengo entendido que cosas mucho más avanzadas se pueden hacer utilizando CCK, Views. O con una herramienta y módulos específicos para el mapeo de tablas de base de datos como Doctrine.

Agradecimientos especiales a Rune Kaagaard (_rune), creador de Auto Admin.

Limpiar el caché de Drupal con drush

Drupal Perú

drush es algo muy bonito que potencia a Drupal. Puedes realizar tareas desde línea de comando y ahorrar muchísimo tiempo.

En esta ocasión comparto con todos ustedes la instrucción para limpiar el caché de Drupal:

drush cache-clear

drush nos preguntará a través de la terminal el tipo de limpieza que deseamos que se realice:

Enter a number to choose which cache to clear.
  [0] : Cancel
  [1] : all
  [2] : theme
  [3] : menu
  [4] : css+js

Podemos ingresar 1 para una limpieza total:

1
'all' cache was cleared                                              [success]

Hasta la próxima!

Actualización 17 de junio 2010 – 9:33 AM
El buen @YourAwesomeST tuitea la versión aún más reducida del comando:

drush cc

Podemos encontrar estos métodos abreviados al ejecutar drush sin parámetro alguno.

Nos Vemos!

Cargar datos desde un archivo CSV

MySQL

Hoy tuve lista una aplicación para la cual sólo me faltaba recargar la información inicial en una tabla de la base de datos. Los datos se encuentran inicialmente en un archivo CSV ( [en] comma separated values = [es] valores separados por coma ).

Podemos emplear la siguiente sintaxis:

LOAD DATA LOCAL INFILE '<RUTA>/<ARCHIVO>'
INTO TABLE <NOMBRE  DE TABLA>
FIELDS TERMINATED BY <CARACTER>
LINES TERMINATED BY <CARACTER>
(<CAMPO1>, <CAMPO2>);

Ejemplo:

LOAD DATA LOCAL INFILE '/home/adagio/files/reggaebands/bands-name-country_code.csv'
INTO TABLE bands
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
(name, country_code);

El sistema me informó que habían 3 warnings. Procedo a inspeccionarlos con el siguiente comando:

show warnings;

Veo que tienen que ver con el separador de valores y la primera línea que ha sido truncada. El caso del separador se debía a que empleo valores que contienen una coma («,»). Así que reemplazo el caracter de separación en el script SQL de coma a punto y coma; realizo lo mismo en el archivo CSV. Y para evitar que se procese la primera línea empleo el parámetro IGNORE LINES. Antes de ejecutar la sentencia limpio los registros con delete y reinicio el puntero del valor autoincrementable.

DELETE FROM bands;
TRUNCATE TABLE bands;

Ahora sí la sentencia SQL final y correcta:

LOAD DATA LOCAL INFILE '/home/adagio/files/reggaebands/bands-name-country_code.csv'
INTO TABLE bands
FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\n'
IGNORE 1 LINES
(name, country_code);

Nos vemos pronto!

Fuentes:

MySQL 5.0 Reference Manual: LOAD DATA INFILE Syntax
scriptygoddess: Reset autoincrement value in mysql table