feb 25

Estoy actualizando el diseño de la jerarquía ,diagrama de clases,casos de uso, diagrama de entidad,vistas de componentes, vistas de despliegue y las vistas lógicas de zenphp porque me parece que Umbrella (y no es el tema americano ese del paragüas aguas aguas que tanto éxito tiene por España XD) lo hace estupendamente.

Dejo las capturas y el enlace para descargar el fichero XMI.

Casos de uso: Librerías: Diagrama de clases de zenphp
Diagrama de casos de uso tipo web Esquema de dependencias de librerías extra de zenphp

Todo free ,por supuesto ;)

La siguiente captura es de como está quedando el Scaffolding de zenphp, llamado zen_andamio. He adoptado la idea de Django de utilizar una lista de las últimas acciones con un iconillo al lado para mostrar lo que vamos haciendo…

La idea es: para llamar al scaffolding, añadimos la variable al modelo de datos “$andamio” y puede ser lanzado desde la ruta sin más que poner el nombre del modelo  después de index.php, por ejemplo ,para la captura se llama a index.php/noticias/andamio, las palabras que activan el scaffolding se pueden configurar en /zen.php en la constante ZF_PALABRAS_ANDAMIO, separadas por coma.

Espero que os guste :)

feb 23

Hoy se suponía que iba a estar recogiendo la aceituna pero ayer salimos para desquitarnos un poco a una fiesta de americanas xD asi que imposible varear nada ,entonces he picado un poco de artículo matinal :) por cierto habis visto el Wii Aceitunero?

Cambiando de tema,…esto es un ¡Todo en uno!

Mi reto ha sido hoy sincronizar las tecnologías PHP + mySQL + AJAX + PERL + DHTML en un sólo script.

La idea es:

  • Una ventana con 2iframes, en uno se añaden los ficheros , se envían comprobando el estado con un script PERL/CGI su estado que es actualizado en la ventana en su iframe por medio de AJAX y al llegar a completarse dicha transferencia se envia una señal al segundo iframe que inserta una entrada en la BD con el nuevo fichero.
  • Todo ésto con comprobaciones de sesiones en PHP gracias a zenphp…y Funciona! pero bendito internet explorer, con navegadores como este podemos decir que el trabajo de programador web no está bien pagado ni mucho menos…porque me hace reescribir las aplicaciones 2 veces, …para el ie no es lo mismo :
    parent.document.getElementById(‘frm_Ficheros’).contentDocument.getElementById(‘frmSubeFicheros’);
    que:
    window.fileUpload.window.parent.frm_Ficheros.document
    lo mejor es que tengo el ie4linux y SI me dice donde está el error, y en windows no…es irónico ¿no?

Bueno,como viene siendo habitual, una captura:

Leer el resto de la entrada »

feb 21

Las primeras pruebas del compactador de HTML,JavaScript y CSS integrado en zenphp ,para su uso en la clase zen_plantilla está siendo todo un éxito, aunque el algoritmo es sencillo,ya que es usado para compactar/comprimir los espacios en blanco y demás caracteres sobrantes, puede reemplazarse dicha llamada por otra función como la de la librería: minify.

Un programa de ejemplo es tan sencillo como lo siguiente:

 

<?php
require_once 'zenphp/clases/clase_zen_compactador.php';
$html = file_get_contents('http://www.elpais.es/');
$tamano_antes = mb_strlen($html, '8bit');
$compactador = new zen_compactador(array(
 'mostrar_buffer' => false
));
$html = $compactador->destructor($html);
$tamano_despues = mb_strlen($html, '8bit');
echo 'Con los espacios en blanco eliminados, el tamaño del fichero HTML se reduce de '.
    round($tamano_antes/1024, 2).
    'KB a '.
    round($tamano_despues/1024, 2).
    'KB,ahorramos '.round((1-($tamano_despues/$tamano_antes))*100, 2).
    '%<br />-----------------<br /><br />'.
    $html; 
?>

La salida obtenida es:
——————
Con los espacios en blanco eliminados, el tamaño del fichero HTML se reduce de 133.52KB a 111.55KB,ahorramos 16.46%
—————–

podeis comprobarlo :)
Si no teneis acceso afuera desde el servidor por problemas de firewall, podeis guardar la web a mano o con PERL en un fichero y luego abrirla con

$html = file_get_contents('p1.html');

No necesitamos nada más que obtener la clase desde el repositorio para hacer la prueba XD

feb 21

Con una clase RSS podemos generar contenidos en XML y en función de los parámetros hacer cosas realmente interesantes, así empezar a compartir datos como servicios,gracias a las especificaciones de RSS2.0 de fechas y actualizaciones…

Para dar un ejemplo propongo una función y después algo más complejo…

Leer el resto de la entrada »

feb 20

Decisiones importantes

20 febrero, 2008

Dicen que nuestras decisiones marcan nuestro destino, por eso debemos ser nosotros mismos quienes decidamos en nuestra vida…

Veamos, las decisiones importantes del proyecto actualmente…

  • Usar gettext para los idiomas en la parte del núcleo de zenphp y el editor Poedit para crear los ficheros de idiomas (.po). ¡Es más eficiente que el uso de cadenas y constantes!…
  • Usar PHP/GTK para el generador de aplicaciones en lugar de generar por línea de comandos (cambio de chip)
  • Basar el generador de aplicaciones en modelos XML, así se puede actualizar el generador muy fácilmente, pudiéndose construir incluso un generador de generadores.
  • Diseñar “cartuchos” de aplicaciones como “Portal.XML” que generan con las opciones pasadas una aplicación completa de un portal web

La última decisión la he tomado porque ayer encontré que existen ya mecanismos que pasan de un modelo XMI construido en un editor UML a un conjunto de ficheros de clases de PHP, por lo tanto sería absurdo volver a repetir lo que otros han construido,asi que por lo tanto ,me centro en construir una aplicación PHP/GTK que utilice mi compilador y generador de aplicaciones basado en el paradigma de la programación orientada a aspectos, que lo tengo un poco olvidado :)

Con ello se cumple el objetivo del proyecto de ser un framework de aplicaciones web y ahora estoy con la parte de generador de aplicaciones en PHP/GTK.
Ahí va una captura del editor Poedit en primer plano y Kate al fondo (gracias al uso de un manualillo) :)

Buena práctica!

feb 19

La meta del proyecto es generalizar todos los procesos de creación de una web para que sea más fácil empezar un proyecto de un sitio con todo lo que necesitemos gracias al uso de varias herramientas, la más nueva de ellas es el prototipo de generador con PHP/GTK zenphp, que se basa en la creación de proyectos como el de la Asociación Zen de Andalucía o el Proyecto Splatter. He estado realizando algunas modificaciones para tenerlo todo a punto…

Nuevos cambios:
- modelo de datos
- funciones de ficheros

Lo que podemos hacer ahora con los nuevos cambios es, un listado de imágenes como este:

 

<ul>
  <li>
      <a target="_blank" href="/media/galerias/logo2.jpg">
       <img width="23" height="23" border="0" src="/media/galerias/logo2.jpg"/>
      </a>
      <input type="checkbox" value="logo2.jpg" name="borrar_imgs[]" id="logo2.jpg"/>
  </li>
  <li>
     <a target="_blank" href="/media/galerias/logo3.jpg">
      <img width="23" height="23" border="0" src="/media/galerias/logo3.jpg"/>
     </a>
     <input type="checkbox" value="logo3.jpg" name="borrar_imgs[]" id="logo3.jpg"/>
  </li>
</ul>

asi se pueden ver/seleccionar para borrar, y ahora un mecanismo para añadirlas:

 

<div id="imagenes">
 <input name="imagenes[]" id="imagen" type="file"><br>
</div>
<a href="javascript:anadirImagen();"><img src="img/boton_anadir.gif" border="0"></a>

Se añaden dinámicamente con una función JavaScript simple como esta:

 

 

<script language="JavaScript" type="text/javascript">
var items = 1;
function anadirImagen(){
 div=document.getElementById("imagenes");
 img=document.getElementById("imagen");
 items++;
 itemnuevo="<b><label for=\"imagen"+items+"\"> Nueva Imagen " + items + "</label>: </b>";
 itemnuevo+="<input type=\"file\" id=\"imagen"+items+"\" name=\"imagenes[]";
 itemnuevo+="\"><br>";
 nodonuevo=document.createElement("span");
 nodonuevo.innerHTML=itemnuevo;
 div.insertBefore(nodonuevo,img);
}
</script>

y ahora, lo único que queda es la comunicación con PHP (todo el trabajo ha estado en diseñar el formulario y el JS :)

 

<?php
function guardar_imagenes($actual){
        $errores = "";
        zen___carga_funciones('zen_ficheros');

        if (is_array($_REQUEST['borrar_imgs']))//se marcó alguna imagen para borrar?
         $actual = array_diff($actual,$_REQUEST['borrar_imgs']);
        $array = zen_serializar(array_merge($actual,zen_guardarFicheros("imagenes",ZF_DIR_PPAL.'media/galerias/',$errores)));

        if (!empty($errores)) {
            echo $errores;
            return zen_serializar($actual); //dejar los datos como estaban
        } else {
            return $array;
        }
    }
?>

El parámetro $actual son los datos que tenia, para que no se repitan, entonces podemos obetenerlos de la siguiente forma:

 

<?php
$_REQUEST['listado'] = guardar_imagenes(
 zen_deserializar($aplicacion->bd->seleccion_unica("listado from galerias where idg=".intval($_REQUEST['idg'])))
);
?>
feb 8

Documentos sobre eficiencia

8 febrero, 2008

Las optimizaciones me apasionan, es por eso que he creado un nuevo documento de eficiencia con zenphp:
https://forja.rediris.es/docman/view.php/252/470/optimizacion_web.pdf
Explica las técnicas que usa el framework tanto automática como manualmente y cómo podemos mejorar la eficiencia para obtener un sobresaliente. XD

P.D.: Bueno y no se si os habréis dado cuenta que en la misma columna del blog del selector de temas he puesto un RSS de poemas zen :)

Saludos

feb 3

¿90/10?

Este post es para iniciar el estudio de comprobación de si, realmente se cumple el que una aplicación escrita en PHP siga la regla 90/10 del software, la cual nos dice que un programa pasa el 90% de su tiempo de ejecución en tan sólo un 10% de su código.

Tomando los resultados de un “profiler” PHP y analizadolos podemos ver dónde “vive” el código de nuestra aplicación y de este modo realizar las optimizaciones necesarias…Basándonos en el pasado reciente de un script, podemos predecir con una predicción razonable qué instrucciones y datos utilizará en un futuro próximo, para ello podemos usar la caché de la clase zen_cache ,el sistema de memoria de System V con las llamadas de PHP, guardar datos de consultas en una sesión, etc.

Recordemos que existen dos tipos de localidad
LOCALIDAD ESPACIAL
d(t) + k = d(t+n) con n y k pequeños
“Si se referencia un elemento, los elementos cercanos a él tenderán a ser referenciados pronto”.
Es decir, si estamos accediendo a un array, seguramente volvamos a acceder pronto a él, no tiene sentido hacer un array muy grande, deberíamos optimizar el código para no usar arrays más grandes que uno bidimensional…

“Las direcciones de memoria que se están utilizando suelen ser contiguas”.
Por eso, es mejor utilizar
JUSTIFICACIÓN: Los datos relacionados se almacenan juntos.
Las instrucciones se ejecutan secuencialmente. k = n = 1
LOCALIDAD TEMPORAL
d(t) = d(τ+n) con n pequeño
“Si se referencia un elemento, tenderá a ser referenciados pronto”.
“La información que se usará en un futuro próximo es aproximadamente la misma que se está usando actualmente”.

Para diseñar un sistema óptimo se realizan todas las posibles configuraciones en ficheros .XML que definan el comportamiento para cada parte independientemente, por ejemplo, si quiero disponer de un modelo de datos de noticias con una caché que se actualice sólo, creando un fichero .XML y a la hora de usar el zen_generador, para obtener nuestra aplicación de noticias, añadiré una propiedad para que se inserte una clase zen_cache y su configuración es:

  • que se actualice siempre que se añada/modifique/borre una noticia (o se fuerce a ello)
  • que genere los listados de noticias automáticamente y los guarde en un fichero .HTML que es mucho más rápido que generar todos los listados cada vez que se cargue el script de noticias…
  • que disponga de un administrador con soporte AJAX y un cliente básico
  • que use el tema por defecto de zenphp para mostrar la información de los modelos…

Bueno,resumidamente, es lo que estoy haciendo en estos momentos…

feb 1

En zenphp gracias a la macro zen_ajax.js podemos añadir efectos simplemente con un atributo, el resto es automático.
Para ello ponemos nuestro enlace como es normal con
<a href=”/direccion_al_script_ajax.php/” ajax=”1″ animacion_carga=”slideDown” animacion_descarga=”slideUp” division=”contenido”>Enlace AJAX</a>

Y lo que hará el motor será , convertir el enlace en un enlace ajax que se cargará por el método POST en segundo plano mientras se aplica el efecto de “correr hacia arriba” la división “contenido” ,al recuperar el contenido del fichero php del enlace se coloca dentro de la misma división y se aplica el efecto de “correr hacia abajo” mostrándose ;)

Efectos disponibles: highlight, fade, grow, shrink, fold, blindUp, blindDown, slideUp, slideDown, pulsate, shake, puff, squish, switchOff.

ene 31

Algo complejo se puede hacer más fácil, de hecho es lo que se suele hacer con el proyecto zenphp.

Para, digamos, obtener una serie de datos de la base de datos en una tupla y de esa tupla, procesar un campo filtrándolo con una función y guardándola en otra variable distinta para meterla en la plantilla HTML se hace con dos instrucciones.
<?php
//añadir el campo a la consulta
$this->padre->campos.=", title as titulo_formateado";
//aplicar el filtro
$this->padre->filtros_postprocesamiento = array("titulo_formateado" => "zen_limpiar");
//yatá, 3 líneas con el contenido ya hecho
$contenido['contenido'] = $this->listado(
"resumenes_noticias.html",
"noticias_portada.html","divisiones_noticias");
?>
XDDD
Bueno, lo explico: desde la vista (visualizador zen_html_modelo_datos) HTML le digo al padre, el modelo, q quiero añadir un campo y que quiero que despuées de leer los datos me formatee el título y me lo guarde como la variable titulo_formateado para pasarla a la plantilla del listado…por cada tupla.

No se si más simple se podrá hacer…si tienes alguna duda o quieres mejorarlo, no dudes en lanzar tu comment ;)

Close
E-mail It