No existe ninguna imagen

Posts Tagged ‘imágenes’

Como crear un sistema para subir imágenes usando Dreamweaver, PHP y MySQL

Domingo, julio 4th, 2010

Puedes ver la segunda parte de este artículo aquí

En el tiempo que llevo participando en la sección de Editores Web de Foros del Web la duda de cómo subir archivos al servidor  (imágenes principalmente) vía http usando Dreamweaver ha surgido múltiples veces. Mi respuesta has sido siempre la misma: “No se puede subir archivos usando funciones de Dreamweaver solamente“. Esta todavía es la realidad, por lo menos hasta el día de hoy que redacto este artículo, aunque reciente alguien volvió a preguntar lo mismo y decidí responder como siempre respondo ese tipo de preguntas: haciendo todo lo que se pueda hacer usando funciones de DW y, el resto, trabajando el código lo mas claramente posible. En este caso decidí expandir un poco mi respuesta con un ejemplo más conciso aquí en mi blog.

En este tutorial estaré discutiendo como acoplar el código PHP necesario al código ya creado por Dreamweaver, osea, no entraré en detalles acerca del HTML/CSS. Tengo pensado hacer una serie de tutoriales de “buenas prácticas” al momento de usar HTML y CSS pronto y ahí pienso abundar más ese tema.

Dicho esto, este es el HTML:

<form id="form1" enctype="multipart/form-data" method="post">
  <label for="imagen">nombre</label>
  <input id="nombre" name="nombre" type="text" />
  <label for="imagen">imagen</label>
  <input id="imagen" name="imagen" type="file" />
  <span class="enviar"><input id="enviar" name="enviar" type="submit" value="Enviar" /></span>
  <input id="tipo" name="tipo" type="hidden" value="general" />
</form>

Lo importante aquí es el hecho que he escogido multipart/form-data como valor del atributo “enctype” del formulario. Esto permitirá al formulario enviar el archivo en la cabecera HTML. Puedes escoger este tipo de enctype seleccionando el formulario y escogiendo esa opción en el menú de Enctype:

También he incluido un input oculto llamado “tipo”. No es algo que normalmente haga, pero esta vez he utilizado las mismas tablas MySQL que de otro post.  De esa forma pudo usar una sola tabla de imágenes y clasificar las mismas según el tipo o la categoría a la que pertenezcan. El archivo SQL lo he incluido en el archivo para descargar.

El CSS es también bastante sencillo ya que no es el foco de este tutorial:

#form1{
	padding: 10px;
	width:250px;
	margin:0 auto;
	background: #F5F5F5;
	border: 1px solid #CCCCCC;
}
#form1 label{display:block;font-weight:bold;padding:5px 0;}
.enviar{display:block; padding:10px 0 5px;text-align:center;}

Hacemos una carpeta para las imágenes y la ponemos en la raíz (root) de nuestro sitio (site) y le damos permisos para leer y escribir (777). Yo la he llamado “imagenes” (Acuérdense que no pueden usar acentos ni eñes (ñ) en los nombres de los archivos, ya sea HTML, imágenes, etc.):

Empezamos creando un “Recordset” escogiendo la tabla de las imágenes.  (Yo tengo DW en inglés, pero espero que sea evidente en la imagen lo que estoy haciendo). En el panel de “applications” vamos a la pestaña de Bindings, hacemos click en el signo de más (+) y escogemos “Recordset (Query)”:

Una vez en la ventana de Recordset se especifica la siguiente información:

  1. El nombre de tu recordset
  2. Tu conexión
  3. La tabla archivos (si usas la tabla creada por el archivo sql que provisto en este tutorial)
  4. Escoges todas las columnas
  5. El filtro que escogeremos es el tipo_archivo. Esta la igualaremos al valor “general”, el cual es el que enviamos en el input “tipo”
  6. En el ‘Sort’ escogemos organizar los “records” de acuerdo a la fecha de manera descendiente para que se muestre primero la última imagen que se subió.

Una vez creado el recordset arrastramos el campo del nombre del archivo al cuerpo de la página. Vamos a hacer un listado de las imágenes que hemos subido al servidor:

Luego creamos la imagen dinámica. Insertamos un “image placeholder”, no importa el tamaño por ahora. Para escoger el source (src) le escogemos el placeholder y le damos click al icono de la carpeta en el panel de propiedades:

Cuando salga la ventana de “Select Image Source” escoges “Data Source” y seleccionas el campo “archivo_archivo” de la base de datos. En ese campo se almacenará en nuevo nombre que le daremos a la imagen. También necesitas añadir “imagenes/”  al principio del campo URL. Esa es la ruta de la carpeta donde almacenaremos las imágenes. No se recomienda almacenar la ruta de las imágenes en la base de datos ya que, si se necesita cambiar la ruta después, tendríamos que cambiar todos los records de la base de datos. En este caso sólo necesitamos cambiar la ruta en el script.

Metemos tanto el nombre como la imagen en una lista (<ul>) escogiendo ambos y dándole al botón de “unordered list”:

El HTML debe ser el siguiente:

<ul>
	<li><img src="imagenes/<?php echo $row_Recordset1['archivo_archivos']; ?>" alt="" /> <?php echo $row_Recordset1['nombre_archivos']; ?></li>
</ul>

Con ven el “alt” de la imagen está vacío. Para proveer una información alternativa de la imagen podemos usar el mismo nombre:

<ul>
	<li><img src="imagenes/<?php echo $row_Recordset1['archivo_archivos']; ?>" alt="<?php echo $row_Recordset1['nombre_archivos']; ?>" /> <?php echo $row_Recordset1['nombre_archivos']; ?></li>
</ul>

Necesitamos hacer dos cosas mas con la lista: 1- hacer que se repitan los elementos conforme con el número de imágenes que se han subido y 2- hacer que la lista solo se muestre si existen imágenes que se han subido.

1- Escogemos el <li> (podemos usar el “code inspector”:

y en panel de Data le damos un comportamiento de repetir. Una vez salga la ventana de repetir escoges el único recordset que existe en la página y escoges enseñar todos los records (no haremos paginación para este ejemplo)

2- Escogemos la lista (el ul , usamos el “code inspector”), y en la panel de Data le damos un comportamiento de mostrar si el recordset no está vacío. Escoges el único recordset y le das al botón de OK:

El HTML se debe ver como sigue:

<?php if ($totalRows_Recordset1 > 0) { // Show if recordset not empty ?>
<ul>
    <?php do { ?>
	<li><img src="imagenes/<?php echo $row_Recordset1['archivo_archivos']; ?>" alt="<?php echo $row_Recordset1['nombre_archivos']; ?>" height="100" /> <?php echo $row_Recordset1['nombre_archivos']; ?></li>
      <?php } while ($row_Recordset1 = mysql_fetch_assoc($Recordset1)); ?></ul>
<?php } // Show if recordset not empty ?>

En este caso le damos un alto a la imagen de 100 pixels para que aparezca pequeña. Usualmente uso la clase PHPImagen de okram para crear los thumbnails, pero eso es algo no explicaré como hacerlo en este tutorial.

Ya que tenemos el listado preparado podemos agregar el comportamiento del “insert”. Vale la pena mencionar que se puede hacer de dos formas, usando el panel de “Application” como también con en las herramientas  de “Data” en el panel de “insert”:

1 – Aplicación: Sever Behaviors -> Signo de mós (+) Insert Record

2 – Data: Botón de Insert -> Insert Record:

Una vez en la ventana de “insert record” seleccionas lo siguiente:

  1. El formulario del insert
  2. Tu conexión.
  3. La tabla de archivos o la que estés usando para almacenar la información de las imágenes.
  4. Las columnas de la base de datos (Columns) tienes que hacerlas coincidir con el valor del formulario (Value). En este caso sólo hacemos coincidir dos de ellos: di_tipo = tipo y nombre_archivo = nombre. Los otros campos los agregaremos después de procesar la imagen

Este debe ser el código PHP resultante del insert:

if ((isset($_POST["MM_insert"])) && ($_POST["MM_insert"] == "form1")) {

  $insertSQL = sprintf("INSERT INTO archivos (tipo_archivos, nombre_archivos) VALUES (%s, %s)",
                       GetSQLValueString($_POST['tipo'], "text"),
                       GetSQLValueString($_POST['nombre'], "text"));

  mysql_select_db($database_Juaniq_codigo_con, $Juaniq_codigo_con);
  $Result1 = mysql_query($insertSQL, $Juaniq_codigo_con) or die(mysql_error());
}

Ahora a esa parte le añadimos la parte PHP que se encarga de procesar las imágenes. Después de:

if ((isset($_POST["MM_insert"])) && ($_POST["MM_insert"] == "form1")) {

Se agrega el siguiente código:

////////////// Parte añadida 1 //////////////

  //carpteta donde vamos a guardar la imagen
  $carpeta = 'imagenes/';
  //recibimos el campo de imagen
  $imagen = $_FILES['imagen']['tmp_name'];
  //guardamos el nombre original de la imagen en una variable
  $nombrebre_orig = $_FILES['imagen']['name'];
  //el proximo codigo es para ver que extension es la imagen
  $array_nombre = explode('.',$nombrebre_orig);
  $cuenta_arr_nombre = count($array_nombre);
  $extension = strtolower($array_nombre[--$cuenta_arr_nombre]);
  //creamos nuevo nombre para que tenga nombre unico
  $nombre_nuevo = time().'_'.rand(0,100).'.'.$extension;
  //nombre nuevo con la carpeta
  $nombre_nuevo_con_carpeta = $carpeta.$nombre_nuevo;
  //por fin movemos el archivo a la carpeta de imagenes
  $mover_archivos = move_uploaded_file($imagen , $nombre_nuevo_con_carpeta);
  //de damos permisos 777
  chmod($nombre_nuevo_con_carpeta,0777);

  ///////////////////////////////////////////

El código lo he comentado lo mejor posible para que se pueda entender que hace cada línea. También, la consulta MySQL, osea, donde dice:

$insertSQL = sprintf("INSERT INTO archivos (tipo_archivos, nombre_archivos) VALUES (%s, %s)",

Se cambia por los siguiente:

// se agrega "archivo_archivos, extension_archivos y la fecha" a la consulta y dos extra %s separados por comas
  $insertSQL = sprintf("INSERT INTO archivos (tipo_archivos, nombre_archivos, archivo_archivos, extension_archivos, fecha_archivos) VALUES (%s, %s, %s, %s, NOW())",

Aquí hemos añadido los campos archivo_archivos, extension_archivos y fecha_archivos a la consulta, dos extra %s para que los valores del sprintf creado por DW correspondan con los campos agregados y también la función “NOW()” de MySQL para que se  inserte la fecha que cuando se subió el archivo. Por último, agregamos los dos valores al que correspondan con los campos en el sprintf. Después de:

GetSQLValueString($_POST['nombre'], "text")

Y antes del paréntesis y el punto y coma agregamos:

GetSQLValueString($nombre_nuevo, "text"),
GetSQLValueString($extension, "text")

El código completo del insert queda así:

if ((isset($_POST["MM_insert"])) && ($_POST["MM_insert"] == "form1")) {

  ////////////// Parte añadida 1 //////////////

  //carpteta donde vamos a guardar la imagen
  $carpeta = 'imagenes/';
  //recibimos el campo de imagen
  $imagen = $_FILES['imagen']['tmp_name'];
  //guardamos el nombre original de la imagen en una variable
  $nombrebre_orig = $_FILES['imagen']['name'];
  //el proximo codigo es para ver que extension es la imagen
  $array_nombre = explode('.',$nombrebre_orig);
  $cuenta_arr_nombre = count($array_nombre);
  $extension = strtolower($array_nombre[--$cuenta_arr_nombre]);
  //creamos nuevo nombre para que tenga nombre unico
  $nombre_nuevo = time().'_'.rand(0,100).'.'.$extension;
  //nombre nuevo con la carpeta
  $nombre_nuevo_con_carpeta = $carpeta.$nombre_nuevo;
  //por fin movemos el archivo a la carpeta de imagenes
  $mover_archivos = move_uploaded_file($imagen , $nombre_nuevo_con_carpeta);
  //de damos permisos 777
  chmod($nombre_nuevo_con_carpeta,0777);

  ///////////////////////////////////////////

   // se agrega "archivo_archivos, extension_archivos y la fecha" a la consulta y dos extra %s separados por comas
  $insertSQL = sprintf("INSERT INTO archivos (tipo_archivos, nombre_archivos, archivo_archivos, extension_archivos, fecha_archivos) VALUES (%s, %s, %s, %s, NOW())",
					   GetSQLValueString($_POST['tipo'], "text"),
					   GetSQLValueString($_POST['nombre'], "text"),
					   ////////////// Parte añadida //////////////
					   GetSQLValueString($nombre_nuevo, "text"),
					   GetSQLValueString($extension, "text"))
					   ///////////////////////////////////////////
					   ;

  mysql_select_db('NOMBRE DE TU DATABASE', 'NOMBRE DE TU CONNECCION AQUI');
  $Result1 = mysql_query($insertSQL, 'INCLUIR TU CONNECCION AQUI') or die(mysql_error());

}

Y listo. Una vez finalizado el sistema se le puede aplicar el HTML/CSS que sea necesario. Algo adicional (y muy recomendado) que podemos hacer es limitar los tipos de archivos que los usuarios van a subir para que solamente puedan subir imágenes. Esto lo podemos hacer creando un Array con los valores de las extensiones que son permitidas. De esa forma podremos comparar los valores del array con el archivo subido por el usuario. En este caso permitimos los siguientes archivos :jpg, jpeg, gif y png. Este es el array:

$archivos_disp_ar = array('jpg', 'jpeg', 'gif', 'png');

Validamos el tipo de archivo de esta forma:

//validamos la extension
if(!in_array($extension, $archivos_disp_ar)) $error = "Este tipo de archivo no es permitido";

Después usamos una condicional para ver si la variable $error está vacía o no. Al final el código queda así:

if ((isset($_POST["MM_insert"])) && ($_POST["MM_insert"] == "form1")) {

  ////////////// Parte añadida 1 //////////////
  //array de archivos disponibles
  $archivos_disp_ar = array('jpg', 'jpeg', 'gif', 'png');
  //carpteta donde vamos a guardar la imagen
  $carpeta = 'imagenes/';
  //recibimos el campo de imagen
  $imagen = $_FILES['imagen']['tmp_name'];
  //guardamos el nombre original de la imagen en una variable
  $nombrebre_orig = $_FILES['imagen']['name'];
  //el proximo codigo es para ver que extension es la imagen
  $array_nombre = explode('.',$nombrebre_orig);
  $cuenta_arr_nombre = count($array_nombre);
  $extension = strtolower($array_nombre[--$cuenta_arr_nombre]);

  //validamos la extension
  if(!in_array($extension, $archivos_disp_ar)) $error = "Este tipo de archivo no es permitido";

  if(empty($error)){

	  //creamos nuevo nombre para que tenga nombre unico
	  $nombre_nuevo = time().'_'.rand(0,100).'.'.$extension;
	  //nombre nuevo con la carpeta
	  $nombre_nuevo_con_carpeta = $carpeta.$nombre_nuevo;
	  //por fin movemos el archivo a la carpeta de imagenes
	  $mover_archivos = move_uploaded_file($imagen , $nombre_nuevo_con_carpeta);
	  //de damos permisos 777
	  chmod($nombre_nuevo_con_carpeta,0777);

	  ///////////////////////////////////////////

	   // se agrega "archivo_archivos, extension_archivos y la fecha" a la consulta y dos extra %s separados por comas
	  $insertSQL = sprintf("INSERT INTO archivos (tipo_archivos, nombre_archivos, archivo_archivos, extension_archivos, fecha_archivos) VALUES (%s, %s, %s, %s, NOW())",
						   GetSQLValueString($_POST['tipo'], "text"),
						   GetSQLValueString($_POST['nombre'], "text"),
						   ////////////// Parte añadida //////////////
						   GetSQLValueString($nombre_nuevo, "text"),
						   GetSQLValueString($extension, "text"))
						   ///////////////////////////////////////////
						   ;

	  mysql_select_db('NOMBRE DE TU DATABASE', 'NOMBRE DE TU CONNECCION AQUI');
	  $Result1 = mysql_query($insertSQL, 'INCLUIR TU CONNECCION AQUI') or die(mysql_error());
	}
}

Para mostrar el error cuando la condición se cumpla ponemos esto encima de la forma:

<?php if(!empty($error)) echo $error; ?>

El próximo tutorial relacionado a este será como borrar los records de la base de datos y las imágenes físicas.

Puedes ver la segunda parte de este artículo aquí

jFileBrowser para TinyMCE . Sube y maneja archivos usando TinyMCE, PHP y MySQL

Viernes, marzo 5th, 2010

jFileBrowser_thumb

Desde hace tiempo tenía el deseo de compartir este plugin. Viene al caso decir que yo uso TinyMCE como editor web del C.M.S. costumizado que ofrezco a mis clientes. El editor es excelente, pero tiene un gran problema: El plugin para subir/editar archivos  no es gratis. Tanto MCImageManager como MCFileManager son soluciones de pago. Después de múltiples fracasos tratando de implementar soluciones gratis decidí tratar de hacer un plugin yo mismo. También me gustaba la idea de almacenar las rutas de las imágenes y otro tipo de información en una base de datos. De esta manera podría fácilmente agregar un buscador, o mayor organización a los archivos, algo que cuesta un poco más de trabajo (por lo menos para mí) al trabajar directamente con archivos del ftp.

Yo no estoy acostumbrado a trabajar con javascript pero, afortunadamente, TinyMCE posee excelente documentación sobre como crear un plugin. Debido a mi limitado conocimiento de javascript no pude hacer algunas cosas como usar ajax al mostrar contenido, pero aún así quedé bastante contento con el resultado.

Debo agradecer a okram por crear las librerías PHPPaging y PHPImagen, las cuales no sólo he usado en este pluging, sino también en muchos de mis proyectos.  Gracias también a Mark James por sus exelentes íconos.

Características del plugin:

  • Creación de directorios virtuales
  • Subir varios tipos de archivos
    • Imágenes (jpg, gif y png)
    • Documentos PDF
    • Documentos Word
    • Documentos Excel
    • Documentos PowerPoint
    • Documentos .txt
  • Creación automática de thumbnails para la organización (PHPImagen)
  • Uso de paginación de los directorios y archivos (PHPPaging)
  • Vistas de thumbnails y listado de los archivos
  • Búsqueda por nombre de archivo

Requerimientos:

  • PHP5 o más reciente
  • MySQL 4 o más reciente
  • Librería GD para PHPImagen

Lista de cosas a mejorar:

  • Cambiar navegación y la forma de mostrar contenido a Ajax
  • Poder subir múltiples archivos
  • Poder subir y crear thumbnails a videos

Instalación:

  1. Descomprimir el archivo zip en la carpeta de tiny_mce/plugin
  2. Crear las tablas en tu base de datos MySQL. Usa el archivo jFileBrowser.sql provisto en el zip.
  3. Encuenta el archivo include/config.inc.php y cambia las siguientes lineas por tu información de tu base de datos
    $sql_db = 'Base_de_datos';
    $sql_user = 'Usuario';
    $sql_password = 'Password';
    
  4. Agrega lo sigiente en tu tinyMCE.init():
    añade jfilebrowse a la lista de plugins

    plugins : "jfilebrowser"
    

    añade jfilebrowse a la lista de botones

    theme_advanced_buttons1 : "jfilebrowser"
    
  5. Cambiar los permisos de la carpeta:
    tiny_mce/plugins/jfilebrowser/archivos/

    a 777, osea, que se pueda leer y escribir.