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

Detalles del Modelo Visualizador VS MVC

Acabo de estar mirando el nuevo modelo de datos de Joomla 1.5 junto con su controladores y vistas…es interesante sin embargo complicado y necesitas tener el manual cerca (a “mano” :D) porque no sabes nada de nada al estar dentro de una vista…si estás en una vista tipo “blog” de una categoría, cómo puedes conseguir la sección a la que pertenece? En algunos foros se discute el tema, acabando por hacer un nuevo y completo módulo o extensión también llamado para cubrir las necesidades…sólo por necesitar un identificador? …como veis parece absurdo tener una división que no te da libertad y crea más confusión…

En zenphp está el modelo de datos donde están todos los datos que está comunicado con punteros con el resto de modelos de la aplicación y por otro lado está, asociado al modelo ,el visualizador, nunca perdemos nada de vista y todo es parametrizable y accesible fácilmente, casi no tenemos ni que usar el manual o la documentación…veis la pauta? notais la diferencia? ahi radica la potencia de hacer algo simple y que funciona…

Saludos!

Operaciones automáticas del generador de aplicaciones

Para construir una aplicación el generador toma una serie de modelos de ficheros necesarios como base para completar la estructura del sistema.

La estructura del generador se puede ver en el siguiente diagrama:
Diagrama de clases del generador de aplicaciones PHP-GTK2 para zenphp
La macro zen_generador_gtk.php lanza la ventana principal (GtkWindow,PHP-GTK2:GtkWindow) que usa la clase zen_fabrica_gtk para “fabricar” todos los componentes de la ventana principal, asociándole los eventos que se agrupan en la clase zen_eventos_ventana_principal, de forma que tenemos siempre un puntero en todas las clases a ésta ventana principal que sirve para localizar cualquier componente,clase o método que necesitemos desde cualquier lugar, asi, se construyen los modelos de las estructuras de datos como las de los árboles con una clase info_configuracion_arbol asociada a la “fábrica”, que sólo inciarse, en su constructor lee las definiciones del fichero de configuración XML del generador, y genera los menús en el GtkMenuBar llamado zen_menu_gtk existiendo la posibilidad de definir nuestros propios menus de usuario, los eventos se asocian directamente y son “atrapados” por medio de la función “public function evento_menu($nombre) ;” de la clase zen_eventos_ventana_principal, sólo hemos de añadir nuestro “caso” al resto para que se ejecuten las órdenes que necesitemos…

Queda mencionar la última conexión con la fábrica, que estoy desarrollando, el generador GTK se conecta con el generador POA para compilar y aplicar los “aspectos” en los que se basa, esto es, nuestros modelos y ayudantes definidos en el cartucho, los visualizadores asociados, las bases de datos configuradas en la aplicación,etc. Esto se hace con el zen_generador_poa, asociado a la fábrica Gtk de forma que carga el motor de zenphp y conecta las 3 partes del proyecto a través del paradigma orientado a aspectos. Tras compilar, generar y construir todo el sistema de aplicaciones, se muestra el mensaje de confirmación. Ya se puede copiar el directorio de salida al directorio web y si todo estaba bien definido, probar la aplicación…

Quizás algo interesante es zen_ventana_mysql_admin , un administrador de bases de datos MySQL, podemos definir en el XML de nuestro cartucho el acceso a varios servidores y mediante la aplicación al hacer doble click sobre dicha línea de configuración conectarremos al servidor especificado para realizar las tareas que consideremos oportunas fácilmente.