If I knew what I am doing, I would not call investigation
In: desarrollo| p4a| php| software libre| tecnologia| tips
13 May 2009En 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?
) 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!
, 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!
In: chicha| desarrollo| fotos| lugcix| personal| software libre| viajes
11 Abr 2009Bienvenido a este blog de Tecnología, Programación, Linux y demas tonterías de Juan Percy Rojas Cruz (a.k.a. Juanpe), joven programador, usuario y desarrollador de software libre. Este blog no tiene ningun "objetivo final", simplemente contar de las cosas que me están pasando en este momento, descargarme de algunas frustraciones, alojar algunos proyectos personales e intercambiar ideas del amplio mundo de la Tecnología. Este blog tampoco tiene ningún fin lucrativo, la única entrada de capital es la publicidad de adsense, que agradecería si me hicieran algun que otro click ;)