Noticias Weblogs Foros Wiki Código

Meta-Info

¿Que es?

Planeta Código es un agregador de weblogs sobre programación y desarrollo en castellano. Si eres lector te permite seguirlos de modo cómodo en esta misma página o mediante el fichero de subscripción.

rss subscripción

Sponsors

Puedes utilizar las siguientes imagenes para enlazar PlanetaCodigo:
planetacodigo

planetacodigo

Si tienes un weblog de programación y quieres ser añadido aquí, envíame un email solicitándolo.

Idea: Juanjo Navarro

Diseño: Albin

Developing my life » desarrollo

Subir archivos usando un widget P4A_Field

Mayo 13th, 2009 - [Enlace local]

En el proyecto que estoy trabajando actualmente usando P4A, tengo una pantalla maestro-detalle en el cual tengo que registrar entre otros datos n-archivos. Si los archivos se registrasen directamente en el maestro entonces no hay problema porque el object P4A_Data_Field que esta enlazado al P4A_DB_Source que a su vez hereda de P4A_Data_Source y este ultimo object es el que maneja los uploads de archivos que se ingresan a través de los P4A_Data_Field tipo “file” mediante su método saveUploads().

Pero como repito todo esto perfecto si el archivo esta directamente en el maestro, pero si esta en el detalle donde no usas P4A_Data_Field, sino widgets P4A_Field, entonces te jodiste, porque solo lo deja en “uploads/tmp”, pero no lo sube al “uploads” o al dir que le pusiste en el setUploadSubpath() . Por qué no lo implementaron para un widget simple y silvestre?, ni idea. Pero no te preocupes, como dijo Ernesto:

Bueno hackear P4A es una tarea complicada pero no imposible.

Asi es vamos a hackear P4A, si no esta implementado porque esperar a que lo hagan, si puedes hacerlo tu, ya tenemos una pista el metodo saveUploads() del P4A_Data_Source ubicado en “ruta_instalacion_p4a/p4a/objects/data_source.php” es el que hace la magia de los uploads, entonces lo que debemos hacer es guiarnos de el y realizar las modificaciones para que funcione para un widget P4A_Field simple y silvestre. Entonces llamaremos al metodo “saveUpload” (que original no? :P ) y lo implementamos/agregamos en el archivo “ruta_instalacion_p4a/p4a/objects/widgets/field.php”, quedando asi:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
	 * Moves uploaded file from P4A_UPLOADS_TMP_DIR to P4A_UPLOADS_DIR
	 * @throws P4A_Exception
	 */
	public function saveUpload()
	{
		$field_type = $this->getType();
		if ($field_type=='file') {
			$new_value  = $this->getNewValue();
			$old_value  = $this->getValue();
			$target_dir = P4A_UPLOADS_DIR . '/' . $this->getUploadSubpath();
 
			if (!is_dir($target_dir)) {
				if (!P4A_Mkdir_Recursive($target_dir)) {
					throw new P4A_Exception("Cannot create directory \"$target_dir\"", P4A_FILESYSTEM_ERROR);
				}
			}
 
			$a_new_value = explode(',', substr($new_value, 1, -1 ));
			$a_old_value = explode(',', substr($old_value, 1, -1 ));
 
			if ($old_value === null) {
				if ($new_value !== null) {
					$a_new_value[0] = P4A_Get_Unique_File_Name($a_new_value[0], $target_dir);
					$new_path = $target_dir . '/' . $a_new_value[0];
					$old_path = P4A_UPLOADS_DIR . '/' . $a_new_value[1];
					if (!rename($old_path, $new_path)) {
						throw new P4A_Exception("Cannot rename file \"$old_path\" to \"$new_path\"", P4A_FILESYSTEM_ERROR);
					}
					$a_new_value[1] = P4A_Strip_Double_Slashes(str_replace(P4A_UPLOADS_DIR , '', $new_path));
					$this->setNewValue('{' . join($a_new_value, ',') . '}');
				} else {
					$this->setNewValue(null);
				}
			} else {
				if ($new_value === null) {
					$path = $target_dir . '/' . $a_old_value[0];
					if (!@unlink($path) and @file_exists($path)) {
						throw new P4A_Exception("Cannot delete file \"$path\"", P4A_FILESYSTEM_ERROR);
					}
					$this->setNewValue(null);
				} elseif ($new_value!=$old_value) {
					$path = $target_dir . '/' . $a_old_value[0];
					if (!@unlink($path) and @file_exists($path)) {
						throw new P4A_Exception("Cannot delete file \"$path\"", P4A_FILESYSTEM_ERROR);
					}
					$a_new_value[0] = P4A_Get_Unique_File_Name($a_new_value[0], $target_dir);
					$new_path = $target_dir . '/' . $a_new_value[0];
					$old_path = P4A_UPLOADS_DIR . '/' . $a_new_value[1];
					if (!@rename($old_path, $new_path)) {
						throw new P4A_Exception("Cannot rename file \"$old_path\" to \"$new_path\"", P4A_FILESYSTEM_ERROR);
					}
					$a_new_value[1] = str_replace(P4A_UPLOADS_DIR , '', $new_path);
					$this->setNewValue('{' . join($a_new_value, ',') . '}');
				}
			}
		}		
	}

Listo ya tenemos nuestro metodo para subir archivos mediante un widget P4A_Field, ahora como lo usamos, un ejemplito:

1
2
3
4
$this->build("p4a_field","txt_miarchivo")
	->setType("file")
	->setUploadSubpath(directorio_especial) // esto siempre y cuando lo quieras subir dentro de un directorio especial dentro del uploads, sino se subira por defecto en el directorio uploads.
	->setLabel("Archivo: ");

Listo ya tenemos nuestro widget creado claro ahi tienes que agregarlo a tu pantalla/form, pero eso ya sabes como hacerlo ;) . Ahora para usar el metodo implementado por nosotros solo invocamos al saveUpload(), asi:

1
2
3
4
5
6
7
public function guardaData()  {
	// procesos que quieras antes
 
	$this->txt_miarchivo->saveUpload();
 
	// procesos que quieras despues
}

Y ya esta! :D , espero les haya servido.

Voy a mandar este parche a los desarrolladores de P4A a ver si lo colocan en el siguiente release, ya que el anterior que mande sobre los mensajes molestos de warnings nunca me respondieron :( , a menos que me haya equivocado de correo.

Es todo por este post, nos leemos!

Comparte y disfruta:

Tambien te puede interesar

» Leer más, comentarios, etc...

Información legal y técnica