Blog

Desplegar el sistema de archivos en un TreePanel

Nov 12, 2009 | Español | By Crysfel | 16 Comments

He recibido muchos mensajes solicitándome el código necesario para poder leer el sistema de archivos en el servidor e integrarlo a un TreePanel para que el usuario pueda administrar sus archivos, en este tutorial explico paso a paso como lograr esta integración.

Desplegar el sistema de archivos en un TreePanel
Author: Crysfel

I'm a software developer with 6+ years of experience, when I'm not developing software I may be writing a tutorial, you can follow me on twitter

El día de hoy veremos cómo leer el contenido de una carpeta en el servidor (utilizando PHP) para luego poder desplegar esa información en un TreePanel utilizando Ajax para ir cargando dinámicamente el contenido de las carpetas.

Sistema de archivos en un TreePanel

Desplegando el sistema de archivos en un TreePanel

Material de apoyo

Para continuar es necesario descargar el material de apoyo, el contiene unos íconos y algunos archivos que desplegaremos en el TreePanel, es necesario que copies todos estos archivos a un servidor Web y cambiar la ruta de la librería ExtJS si es necesario.

Leyendo el contenido de una carpeta

Voy a utilizar PHP para leer el contenido de la carpeta “files” la cual viene con el material de apoyo, dentro de esta carpeta existen varios archivos los cuales serán desplegados en un TreePanel. Vamos a editar el archivo “get-files.php” (viene en el material de apoyo) y escribiremos lo siguiente:

$root = 'files/';	//step 1
$node = isset($_REQUEST['node'])?$_REQUEST['node']:""; //step 2

En el paso uno se define la ruta de la carpeta que será expuesta al usuario, aquí podemos definir cualquier carpeta que necesitemos exponer, por ejemplo “/home/john/docs” o también “c:\users\john\docs”, para este ejemplo usaremos “files/” la cual debe estar en el mismo nivel que nuestro archivo “get-files.php”.

En el segundo paso se está tomando el parámetro “node”, este parámetro contendrá la ruta dentro de la carpeta “files” que deseamos desplegar, recordemos que usaremos Ajax para ir cargando dinámicamente el contenido de cada carpeta conforme el usuario vaya navegando, esto es importante porque de esta manera haremos que nuestra aplicación solo cargue la información que el usuario solicita y por lo tanto mejoraremos el rendimiento.

Ahora escribiremos lo siguiente:

if(strpos($node, '..') !== false){
    die('Nice try buddy.');
}

¡El código anterior es importantísimo! Ya que busca dentro de la variable “node” que no exista la secuencia de caracteres “..” ya que de existir un usuario malintencionado podría leer archivos que no debería poder ver, por ejemplo las credenciales de nuestra base de datos o cualquier otro archivo importante.

Una vez que nos aseguramos que el parámetro “node” viene limpio nos preparamos para leer los archivos de la ruta que el usuario ha solicitado.

$nodes = array();
$d = dir($root.$node);		//step 1
while($f = $d->read()){		//step 2
    if($f == '.' || $f == '..' || substr($f, 0, 1) == '.') continue;	//step 3

    if(is_dir($root.$node.'/'.$f)){			//step 4
        array_push($nodes,array('text'=>$f, 'id'=>$node.'/'.$f));
    }else{
        array_push($nodes, array('text'=>$f, 'id'=>$node.'/'.$f, 'leaf'=>true,'iconCls'=>getIcon($f)));
    }
}
$d->close();			//step 5

En el paso uno usamos la función “dir” para abrir el directorio solicitado, primero asignamos la ruta principal y luego le concatenamos la ruta que el usuario solicitó.

En el paso dos mediante un ciclo “while” leemos todos los archivos contenidos en el directorio que abrimos en el paso uno y colocamos cada archivo en la variable “f”.

El paso tres es necesario para que no mostremos los directorios o archivos ocultos.

En el paso cuatro verificamos que estamos agregándole al arreglo “nodes” la información de cada archivo, para eso primero verificamos que tipo de archivo es, si es un directorio o carpeta solamente le asignamos el texto que desplegará y el identificador que tendrá, puedes ver que como ID le asignamos la ruta que enviará al servidor, por otro lado, si no es un directorio le asignamos la propiedad “leaf:true” al nodo que estamos creando y también le asignamos la clase CSS que contendrá al icono correspondiente.

En el paso cinco cerramos el directorio que leímos anteriormente.

Ahora necesitamos definir la función “getIcon” de la siguiente manera:

function getIcon($name){
	if (preg_match("/\.png$/", $name) || preg_match("/\.jpg$/", $name) || preg_match("/\.gif$/", $name)) {
		return 'jpg-icon';
	}else if (preg_match("/\.xls$/", $name) || preg_match("/\.xlsx$/", $name)) {
		return 'xls-icon';
	}else if (preg_match("/\.ppt$/", $name) || preg_match("/\.pptx$/", $name)) {
		return 'ppt-icon';
	}else if (preg_match("/\.doc$/", $name) || preg_match("/\.docx$/", $name)) {
		return 'doc-icon';
	}else{
		return 'unknow-icon';
	}
}

Esta función recibe el nombre de un archivo y mediante una condición verificamos la terminación o “extensión” para poder asignarle el icono correspondiente, si no encuentra ninguna extensión le asignaremos un icono genérico.

En el material de apoyo he creado las clases CSS necesarias, ya hemos hablado de cómo cambiar los íconos a los nodos anteriormente.

.xls-icon{background:transparent url(icons/page_excel.png) 0 0 no-repeat !important;}
.ppt-icon{background:transparent url(icons/page_white_powerpoint.png) 0 0 no-repeat !important;}
.doc-icon{background:transparent url(icons/page_word.png) 0 0 no-repeat !important;}
.jpg-icon{background:transparent url(icons/picture.png) 0 0 no-repeat !important;}
.unknow-icon{background:transparent url(icons/page_white.png) 0 0 no-repeat !important;}

Por último necesitamos generar el JSON con la información que hemos obtenido.

//print the data
echo json_encode($nodes);

Si ejecutas el archivo “get-files.php” en tu navegador debería regresarte la siguiente información:

[{"text":"docs","id":"\/docs"},{"text":"music","id":"\/music"},{"text":"pictures","id":"\/pictures"}]

Recordemos que cuando utilizamos el componente TreePanel lo más importante es la información que éste contiene, hasta ahora solamente hemos creado la parte dinámica del nuestro ejemplo, pasemos a crear la parte visual.

Creación del TreePanel

Hemos estudiado anteriormente como crear un TreePanel, realmente no tiene nada complicado ya que la parte complicada ya la hemos hecho y ahora si estamos listos para escribir el siguiente código dentro del archivo “tree-files.js”:

var tree = new Ext.tree.TreePanel({
	border: false,
	autoScroll:true,
	dataUrl:'get-files.php',
	root: new Ext.tree.AsyncTreeNode({
		id:'.',
		text: 'User files'
	})
});

Lo más importante aquí es el identificador que le asigné al nodo “root”, el ID es el parámetro que por defecto el TreePanel envía al servidor cuando se hace una petición Ajax, por lo tanto el primer directorio que necesito que sea desplegado es el principal, por esta razón le asigné un punto ya que la ruta generada en el servidor es la siguiente para este caso:

// root = files/
// node = .
//root+node = files/.
$d = dir($root.$node);

Lo siguiente es renderizar el TreePanel en la pantalla, para esto usaré una ventana de la siguiente manera:

var win = new Ext.Window({
	title:'Reading files example',
	layout:'fit',
	width:300,
	height:400,
	items: tree
});
win.show();

Sistema de archivos en un TreePanel

Pantalla inicial, todavía no cargamos la información hasta que el usuario la solicite

Ahora, si damos clic sobre cualquier carpeta automáticamente se realizará una llamada Ajax al servidor y este nos regresará los archivos necesarios.

Sistema de archivos en un TreePanel

Haciendo la petición Ajaxl

Sistema de archivos en un TreePanel

Desplegando los nuevos archivos

Conclusiones

Hemos visto como exponer el contenido de una carpeta ubicada en nuestro servidor, utilizar el componente TreePanel es muy sencillo, más adelante veremos como interactuar con este componente, agregaremos algunos eventos y permitiremos que el usuario pueda mover los nodos de un lugar a otro.

Estamos contentos de recibir sus comentarios, sugerencias o críticas, recuerda seguirnos en Twitter (@quizzpot) para estar pendiente de las actualizaciones que hacemos, cada vez iremos avanzando en la complejidad de nuestros tutoriales, pero primero necesitamos poner firmes las bases.

16 Responses to “Desplegar el sistema de archivos en un TreePanel”

  • Manolo Nov 12, 2009

    Una y otra vez, temas muy interesantes, pero seguimos sin poder hacer nada integrando lo que ya sabemos. El crud realmente falta y pareciera que no quieres enseñar hacer uno y que uno se vea forzado a pagar el curso, CLARO que estas en todo tu derecho de hacerlo, pero entonces que hipócrita es que digas esto:
    http://www.quizzpot.com/2009/02/hola-mundo/

    • Crysfel Nov 12, 2009

      Hola Manolo, gracias por dejar tus “inquietudes”, para allá vamos, pero como dije en la conclusión del post:

      “cada vez iremos avanzando en la complejidad de nuestros tutoriales, pero primero necesitamos poner firmes las bases”

      Saludos :D

  • Leonardo Vizcaya Nov 12, 2009

    Mi Pregunta Manolo, ¿Porque no investigas, aprendes y lo haces tu, para que lo publiques?, así lo ayudas y dejas de criticar tanto sin aportar.

  • Imfael Nov 14, 2009

    Aprende a caminar antes de volar…

  • Osvaldo Aguilar Nov 25, 2009

    Manolo, creo que se te fue la mano, todos hemos aprendido muchisimo con estos tutoriales de quizzpot, te aseguro que si tratas un poquito, y unes todo lo que Crysfel a puesto en este sitio.puedes hacer el crud sin problemas. No esperes que te lo pongan en la boca.

  • Bladimir Balbin Dec 12, 2009

    Muy bien muy bueno el tutorial. Pregunto en un tree panel se pueden tener varios root?

    • Crysfel Dec 14, 2009

      No, pero puedes simularlo! en una ocación hice los siguiente:

      Oculté el root y le agregué tres ramas principales desde el principio, luego cada rama tenía sus propios nodos, simulando ser tres roots, aunque en realidad eran tres ramas con el root oculto.

      saludos

  • Maria de Jesus Jan 19, 2010

    Si yo lo de php lo hice en java (servlet) en el js en la parte de dataUrl:’get-files.php’, debo de poner el nombre de la clase (getFiles.class) o debe ser el .java?

    • Crysfel Jan 19, 2010

      mmmm…. debe apuntar a la url que configuras en el mapping de tu servlet ;)

  • Maria de Jesus Jan 19, 2010

    Solo la ruta?, es que bueno como ahi se especifica el archivo con su extension por eso preguntaba, por cierto otra cosa en el archivo de php viene esta linea:

    echo json_encode($nodes);

    Ahi tengo duda lo que pasa es que yo no he manejado JSON asi que no se como traducir eso en java.

    • Crysfel Jan 19, 2010

      Existen librerías en Java para realizar eso, aunque si no las has usado nunca puedes formar tu el JSON, te recomiendo leer sobre el uso de los servlets, googlea un poco al respecto.

      saludos

    • Maria de Jesus Jan 19, 2010

      Muchisimas gracias he encontrado google-gson ^o^ saludos.

  • Galatea Mar 02, 2010

    INCREIBLEMENTE ESPECTACULAR….. muy dichosa el ver que los ejemplos que explicas todos funcionan, obviamente gracias al material que pones a disposicion para hacer mas facil el aprendizaje.

  • Ditmar May 24, 2010

    Gracias Crysfel, por compatir tu conocimiento, no sabes cuanto me has ayudado hasta ahora

  • Dorius Jun 06, 2010

    Como puedo hacer para que cada vez que despliego un nodo no me guarde en cache el contenido, esto me resulta necesario, ya que según voy agregando registros a la base de datos necesito que el nodo se actualize, y el codigo lo tengo en dos páginas distintas en una agrego y en la otra muestro el tree panel.

  • Dorius Jun 06, 2010

    en otras palabras necesito que al desplegar el nodo, me envie la petición siempre, no solo la primera ves.

Leave a Reply







Updates

RSS

Subscribe to our feeds to receive updates of our newest posts and free tutorials.

Site search

Maybe we have what you need, would you like to search first?

Donations

Would you buy me a cup of coffee? I am sharing my knowledge and time with you, help this project grow. Thank you!