jueves 24 de julio de 2008

Pequeñísima guía para crear un widget (1)

Consideramos un widget como un elemento que nos permite visualizar un conjunto de datos de una determinada forma.

La creación de un widget en p4a se diferencia poco de la creación de una clase cualquiera pero existen unos cuantos puntos que tendremos que tener en cuenta.

En esta breve guía se comentan widgets realizados como extensión de la clase p4a_widget y que nos permite heredar métodos para activarlo, ocultarlo, etc..

En este micro-tutorial realizaremos un widget que nos permitirá visualizar un campo numérico en formato "termómetro". Haremos que para un número entre 0 y 10 nos aparezca una linea vertical con una escala de valores (0 verde y 10 rojo) que podremos utilizar, por ejemplo, para canviar mostrar una prioridad, un porcentaje de ocupación, ...

El constructor.

Lo primero que realizaremos será reescribir el constructor para poder efectuar ciertas inicializaciones propias de nuestro widget pondremos el valor por defecto ($this->_valor) aunque es superfluo puesto que lo podríamos haber hecho en la definición.

El constructor siempre tiene que recibir el nombre del widget por parámetro.

public function __construct($name)
{
parent::__construct($name);
$this->_value = 0;
return $this;
}


El método GetAsString

Este método es muy importante y lo que debemos conseguir es montar el código HTML, a partir de los valores de nuestro widget.

El código HTML del widget debe quedar incluido en un tag div en el que asignaremos la id del widget. Esta particularidad es indispensable porque serà cómo AJAX identificará el objeto. Para obtener el identificador utilizamos el método heredado $this->getId(). Una forma habitual de comenzar este método sería :

$id = $this->getId();
if (!$this->isVisible()) {
return "<div id='$id' class='hidden'</div>";
}


ya que si no es visible sólo hay que generar el tag <div> hidden

A continuación vendría, en nuestro caso, la generación de una tabla HTML de una fila y columna con los colores que toquen y creamos la variable local $temormetro con este código.

En este punto podríamos finalizar el método de una forma similar a:


return "< div id="$id">$termometro/div>";



pero no tendríamos las propiedades HTML y que nos proporciona el método heredado composeStringProperties():

$propietats = $this->composeStringProperties();
return "
getWidth() . "; height: " . $this->Height() . "' $propietats >$termometro
";

Métodos auxiliares

Necesitaremos realizar una serie de métodos para configurar el widget y, también para recoger información de él.

En nuestro caso realizaremos dos métodos uno para asignarle un valor (setValue) y otro para leerlo (getValue)

Cómo lo utilizamos

En la máscara que utilizemos el widget haríamos:

$this->build('Termometro','termo')
->setValue(2);

y
 $this->termo->setValue(xxx);
para modificarlo o
$x = $this->termo->getValue()
para consultar que valor tiene.


Y ahora que...


- En el próximo post explicaremos cómo interactuar con el widget de forma que cuando clickemos sobre una valor del termómetro se dispare un evento...

- Para practicar: añade nuevos métodos para cambiar el ancho, informar el mapa de colores, indicar el mínimo y el máximo, que el termómetro sea vertical u horizontal...

El código del widget

class Termometro extends p4a_widget
{
// Escala de colores
private $_colores = array('darkgreen','green','lime','greenyellow','YellowGreen','yellow','gold','orange','OrangeRed','red','crimson');

// sin color
private $_sincolor = 'gray';

// ancho de la columna
private $_ancho = 25;

// Valor del widget
private $_valor = 0;

// Métodos auxiliares propios del widget
// Asignar un valor al widget
public function setValue($valor)
{
if ($valor <>_valor = 0;
elseif ($valor > 10) $this->_valor = 10;
else $this->_valor = round($valor,0);
return $this;
}
// Recuperar el valor del widget
public function getValue()
{
return $this->_valor;
}

// Constructor
public function __construct($name)
{
parent::__construct($name);
$this->_value = 0;
return $this;
}

// Generar el HTML del widget
public function getAsString()
{
$id = $this->getId();
if (!$this->isVisible()) {
return "
";
}

// Aqui generamos la tabla con 1 columna y 10 filas
$termometro = '';
for ($i=10; $i>=0; $i--) {
$color = ($i > $this->_valor)?$this->_sincolor:$this->_colores[$i];
$termometro .= '';
}
$termometro .= '
_ancho.'px">
';

// Las propiedades HTML del widget
$propietats = $this->composeStringProperties();
// Montamos el widget
$widget = "
getWidth() . "; height: " . $this->getHeight() . "' $ propietats >$termometro
";
return $widget;
}
}

jueves 3 de julio de 2008

TIP 2: Definiendo relaciones

En las aplicaciones que desarrollamos nos encontramos que las relaciones entre dos tablas hemos de repetirlas en múltiples ocasiones con los consiguientes problemas que pueden aparecer de errores y, sobre todo, mantenimiento.

Este post intenta aportar una forma enfocar este problema realizando una extensión de la clase p4a_db_source donde se definen y enumeran las relaciones para que luego puedan ser referenciadas desde cualquier máscara.

Manos a la obra…

Para definir una relación se precisará indicar la p4a_db_source con la que se relaciona, el tipo de relación, la condición y los campos que se utilizará. Habitualmente utilizamos el método addJoin indicando la condición y la correspondencia de nombre de campos.


1. Expandimos la clase p4a_db_source con un nuevo método (setRelation) que tomará la definición de la relación y la aplicará a la db_source.


class Ext_dbsource extends p4a_db_source
{
/*
* En el array _Relations se identificará la relación y..
* - la dbsource amb la que se relaciona
* - el tipo de join
* - la condicion
* - el nombre de los campos
*/

protected $_Relations = array();

public function setRelation($relname)
{
$wrelname = strtolower($relname);

//Si la relación está definida

if (array_key_exists($wrelname, $this->_Relations)) {
$r = $this->_Relations[$wrelname];
$method = "addJoin{$r[1]}";
$this->$metode($tbl, $r[3],$r[3]);
$this->load();
}
}
}

2. Definimos una clase para nuestras db_source. Para cada p4a_db_source se definirá una clase que contenga estas relaciones. Supongamos que tenemos la tabla "empleados" y que tiene una relación 1:n con la tabla de "empresas" ). La db_source sería:

class Empleados extends Ext_dbsource
{
protected $_Relations =
array('TrabajaPara',
array('empresas', // tabla
'INNER', // tipo join
'empleados.id_empresa = empresa.id', // condicion
'nombre_empresa'=>'empleador' // campos
)
);
}


3. Cuando utilizamos en nuestras máscaras la tabla y la relación lo haríamos:
$this->build('Empleados','dbempleados');
$this->dbempleados->setRelation('TrabajaPara');
Nota. El código aquí escrito tiene como objetivo ilustrar la idea y puede contener errores.

Salutacions.

lunes 19 de mayo de 2008

P4A 3 tiene liberación candidata 2 (RC)

Hay un montón de cosas que hablar hoy, comencemos.

IMPORTANTE: SF 2008 COMMUNITY CHOICE AWARDS
Por favor toma 1 minuto para votar P4A a la categoría "Mejor Herramienta o Utilidad para Desarrolladores" (puedes nominar a P4A para otras categorías pero pensamos que el sugerido es el correcto).

LA LIBERACIÓN
Esta no es mas que una liberación de corrección de errores, aqui esta la lista de cambios:
  • Fue resuelto un error con el método P4A_Field::getAsCheckBox().
  • Cuando el valor de P4A_Field viene desde POST, P4A::main() ahora chequea si el campo esta activado.
  • Fueron sincronizadas las traducciones.

Descargar P4A 3.0.0-rc2

P4A WEBSITE
Nos tomó algún tiempo trabajar con el sitio web y agregar algunas caracteristicas cool, en primer lugar una buena sección de screenshots, gracias a jQuery y los plugins jCarousel y lightbox.
Aquí un screenshot de la nueva página:

Asegurate de ver la nueva página en
http://p4a.sourceforge.net/
En la nueva barra de enlaces encontrarás la constantemente actualizada referencia del código y el enlace a la herramienta de traducción y todo lo que necesitas para vivir en el mundo P4A.

P4A WIKI
La nueva wiki está instalada y disponible aquí:
http://p4a.crealabsfoundation.org/wiki/ esta completamente vacía pero puedes comenzar registrándote y discutiremos que publicar y como hacerlo en los próximos días.
PS: la wiki no esta enlazada desde la pagina principal aun, estamos esperando por algunos contenidos para hacerlo.

MISCELÁNEO
  • Estamos trabajando en la licencia comercial y esperamos tenerla lista pronto.
  • Parece que la liberación del nuevo jQuery y jQuery UI será en unos días, si esto es así esteremos contentos de incluirlo en P4A 3.
  • Estoy seguro que olvido algo :-)
Hasta pronto y a difundirlo al mundo!!!

NOTA (dcarrero): Esta traducción fue realizada el día 19 por enfermedad, espero que no les haya molestado.

martes 6 de mayo de 2008

P4A 3 tiene liberación candidata (RC)

Tiempo para liberar algunos bugfixes y preparar para la liberación estable, hemos tenido que recortar jQuery UI( y el drag &drop de P4A_DB_Navigator) desde nuestra hoja porque parece que jQuery UI no será liberada pronto y no podemos esperar más.

De todas formas aquí esta la lista de cambios:

  • El método saveUploads() fue movido desde P4A_Mask a P4a_Data_Source.
  • El segundo parámetro del método P4A::quote() ahora es falso por defecto, resolviendo algunos problemas con P4A_Data_Field::getSQLValue() y getSQLNewValue().
  • Cuando P4A_DB_Source necesita un valor entre comillas ahora usa P4A_DB->quote() con autoquote activado.
  • En el método P4A_DB::quote(), si autoquote esta activado, siempre encierra el valor con comillas simples.
  • jQuery::form fue actualizado a 2.0.8.
  • jQuery::iFixPNG fue actualizado a 2.1.
  • El CSS de P4A_Menu fue cambiado un poco resolviendo un bug con IE6 (escondido muy rápido).
  • Los movimientos de P4A_DB_Navigator están desactivados (debido a la no liberación de jQuery UI) por lo que ahora todos los movimientos permitidos son errores.
Vamos a dejar el resto de esta liberación para algunas semanas, durante este tiempo trabajaremos en la documentación y el sitio web, arreglando los bugs que eventualmente salgan. Si todo sale sin problemas, como espero, simplemente sincronizaremos las traducciones y liberaremos como 3.0.0 final.
Ahora puedes Descargar P4A 3.0.0-rc1, por favor ayudanos con las traducciones y reporta todos los errores que encuentres! Muchas gracias !

jueves 10 de abril de 2008

10mo preview para P4A 3, mejoras importantes y optimizaciones

La fase de prueba está pasando, por lo tanto, unas pequeñas modificaciones se realizaron en muchas partes del código P4A.
  • Una de las cosas importantes para los desarrolladores es que ahora todos los métodos P4A_DB puede utilizar la característica "vinculante" que viene con Zend Framework / PDO.
  • Otras mejoras se lograron P4A si ejecuta en servidores Windows
  • FCKEditor se ha actualizado a la nueva y brillante liberación 2,6 y otras bibliotecas también se actualizaron.
Pero lo más maravilloso es la mejora Javascript / CSS lazy loading. Tenemos muchos javascript pesados con P4A (FCKEditor, el seleccionador de fechas, etc.) y algunas veces su aplicación no las usa... ahora cada componente se carga solo cuando se necesita y sus aplicaciones se iniciaran y correrán mas rápido!
En cualquier caso, revisemos la lista de cambios:
  • Fue resuelto un bug con P4A_Field::getAsRadio() (en las labels se puede hacer clic).
  • Fue agregada la función global P4A_Rmdir_Recursive().
  • El método P4A_Data_Field::setSequence() no agrega más el “_seq” en postfix.
  • El método P4A_DB::nextSequenceId() agrega el “_seq” de postfix dependiendo de la db que esta usando.
  • Fue agregado un respaldo SQL para PostgreSQL al ejemplo products_catalogue.
  • El respaldo para MySQL para products_catalogue fue renombrado a db_dump_mysql.sql.
  • La función global P4A_Quote_SQL_Value() fue eliminada.
  • Fue agregado el método P4A_DB::quote() (es un envoltorio para el método Zend_DB quote).
  • Los métodos P4A_DB::get*(), fetch*(), query*() ahora soportan un array de parametros vinculantes.
  • Las reglas de auto detección P4A_ROOT_PATH fueron cambiadas un poco para la compatibilidad con servidores Windows.
  • La función global P4A_Strip_Double_Backslashes() fue agregada.
  • Las reglas de auto detección P4A_UPLOADS_DIR fueron cambiadas un poco para la compatibilidad con servidores Windows.
  • El CSS para la etiqueta (label) de P4A_Fieldset fue cambiado para la compatibilidad con Safari 3.1.
  • El CSS de P4A_Label fue cambiado un poco para mantener la compatibilidad entre navegadores.
  • El CSS de P4A_Field::getasText() ahora tiene por defecto un ancho (150px).
  • Fue resuelto un error con el método P4A_I18N::mergeTranslation().
  • FCKEditor fue actualizado a 2.6.
  • jQuery::UI::datepicker fue actualizado a 3.4.3.
  • javascript/css lazy loading fue implementado, todos los js/css dependientes de los widget son cargados solo perdiendo un monto de KB en el inicio.
  • El CSS de impresion fue eliminado.
  • Las traducciones fueron sincronizadas.
  • El mensaje "Loading..." ahora puede ser traducido.

Ahora puedes Download P4A 2.99.9, por favor ayudanos con las traducciones y reporta todos los errores que encuentres! Muchas gracias !

PD: Recuerda mantener tus ojos en P4A TV!
PPD: difundelo al mundo :-)

Entrada original:
http://tinyurl.com/5cfcpr

viernes 4 de abril de 2008

TIP 1: Menú con elementos anidados

Dentro del grupo de usuarios de p4a en español, Eddie nos ha colaborado con esta manera de hacer un menú con un array, permitiendo la mantención y legibilidad del código.

class Program extends P4A {

public function __construct() {
parent::_construct();

$menu =& $this->build("P4A_Menu", "menu");

$items = array(
"catalogos" => array("Catálogos", array(
"seguridad" => array(null, array(
"usuarios" => array(null, null),
"perfiles" => array(null, null),
"modulos" => array("Módulos", null),
"elementos" => array(null, null),
"-" => array(null, null),
"bitacora" => array("Bitácora", null))),
"plantilla" => array(null, array(
"careas" => array("Áreas", null),
"departamentos" => array(null, null),
"niveles" => array(null, null),
"plazas" => array(null, null),
"- " => array(null, null),
"puestos" => array(null, null))),
"nomina" => array("Nómina", array(
"periodos" => array(null, null),
"empleados" => array(null, null))),
"-" => array(null, null),
"tipos" => array(null, array(
"t_areas" => array("Áreas", null),
"nominas" => array("Nóminas", null),
"t_periodos" => array("Periodos", null),
"t_eventos" => array("Eventos", null))))),
"herramientas" => array(null, null),
"procesos" => array(null, null),
"reportes" => array(null, array(
"r_plantilla" => array("Plantilla de Personal (resumen)", null))));

$this->agregaMenu($menu, $items);
}

private function agregaMenu($menu, $items) {
foreach ($items as $nombre => $propiedades) {
$item =& $menu->addItem($nombre);
if($nombre === "-") {
$item->setLabel(str_repeat("-", 20));
} else {
if ($propiedades[0]) {
$item->setLabel($propiedades[0]);
}

if (is_array($propiedades[1])) {
$this->agregaMenu($item, $propiedades[1]);
}
else {
$item->implement("onClick", $this, "muestraMascara");
}
}
}
}

public function muestraMascara() {
$this->openMask($this->active_object->getName());
}
}
Puedes ver el código en la siguiente dirección:

http://p4aenespanol.pastebin.com/m64682c5c

Creo que el código se explica bastante bien, esperamos que sea útil.
Y esperamos sus comentarios !!!

Saludos.

jueves 3 de abril de 2008

Multiples bases de datos en nuestras aplicaciones

Hoy Fabrizio ha publicado un screencast importante, como conectar nuestra aplicación a múltiples bases de datos en nuestras aplicaciones.

Este screencast muestra la definición de las constantes en el archivo index.php, como se puede ver a continuación.

define("P4A_DSN", 'pgsql://p4a:p4a@localhost/p4a_products_catalogue')

Donde podemos definir nuestra conexión a la base de datos, ya sea esta en Mysql, Postgresql, Oracle o Sqlite.

Además llama la atención, el uso de la función P4a_Db_Source::setDSN(), mírenlo y prueben en su servidor.

De esta forma:

$this->build("p4a_db_source","brands")
->setDSN("pgsql://p4a:p4a@localhost/p4a_products_catalogue")
->setTable("brands")
->addOrder("description")
->load();


http://p4a.crealabsfoundation.org/tv/2008/04/02/multidatabase.html


Saludos a todos

Pronto comenzaremos con algunos tips.