Archivo

Archivo del autor

New version sfUploadFilePlugin (for Symfony 1.4) / Nueva versión sfUploadFilePlugin (para Symfony 1.4)

Lunes, 17 de Mayo de 2010 Henry Vallenilla Sin comentarios

Los cambios realizados en el plugin permiten ajustar la configuración de la imagen en el modulo o en la aplicación (Leer Readme)

DependeciassfThumbnailPlugin

Instalación

1) Descarga el paquete: sfUploadFilePlugin

2) Existen dos maneras de configuración:

2.1) En el módulo o los módulos donde se vaya a usar el helper debe crearse el archivo module.yml
en la carpeta config de dicho módulo. La estructura para que el helper funcione es la siguiente:

all:
configuration:
upload_images:
# Número de copias
copies:   NUMERO DE COPIAS "DEBE COINCIDIR CON LA CANTIDAD DE TAMAÑOS"
size_1:   {pref_1: small, image_width_1: #, image_height_1: #}
size_N:   {pref_N: """, image_width_N: #, image_height_N: #}

2.2) En el app.yml de la aplicación:

all:
upload_images:
nombre_modulo:
copies:   NUMERO DE COPIAS "DEBE COINCIDIR CON LA CANTIDAD DE TAMAÑOS"
size_1:   {pref_1: small, image_width_1: #, image_height_1: #}
size_N:   {pref_N: """, image_width_N: #, image_height_N: #}

3) Se agregó otro parámetro ($inModule) que debe ser TRUE si la configuración depende del modulo, ó, FALSE si la configuración está en la aplicación.

loadFiles($file->getOriginalName(), $file->getTempname(), 0,
sfConfig::get('app_directory_upload'), $Model->getId(), $inModule);

De esta manera se cargan los archivo al directorio especifico.
Pero esto no lo es todo, al momento de edición del registro y selecciono una nueva imagen debo borrar
la anterior. Para esto, en el método doSave de su FormClass Model ó en la función que estén usando
para guardar los cambios, se debe incluir lo siguiente:

protected function doSave($con = null)
{
// Si hay un nuevo archivo por subir y ya mi registro tiene un archivo asociado entonces,
if ($this->getObject()->getImage() && $this->getValue('image'))
{
// recorro y elimino
$configParam = sfConfig::get('mod_MODULE_configuration_upload_images');
for($i=1;$i<=$configParam['copies'];$i++)
{
// Elimino las fotos de la carpeta
if(is_file(sfConfig::get('app_directory_poster').$configParam['size_'.$i]['pref_'.$i].'_'.$this->getObject()->getImage()))
{
unlink(sfConfig::get('app_directory_poster').$configParam['size_'.$i]['pref_'.$i].'_'.$this->getObject()->getImage());
}
}
}
return parent::doSave($con);
}}

Saludos,
Henry Vallenilla (Programador Web en Php)
Henry Vallenilla
Symfony Developer
Email/Gtalk: henryvallenilla@gmail.com
Skype: hvallenilla
Caracas - Venezuela
www.matatigre.com

Categories: Symfony Tags:

Modificación de jq_sortable_element del helper de jQuery - Symfony 1.4

Jueves, 6 de Mayo de 2010 Henry Vallenilla 2 comentarios

Queremos crear una galería de imágenes, muy bien !!!, pero además queremos que dicha galería permita mover las imágenes de una posición a otra. Trabajando con jQuery, este nos ofrece el jq_sortable_element(), de mi parte no logré que este me funcionara como viene documentado en el nuevo plugin sfJqueryReloadedPlugin, por lo que me dí la tarea de crear mi propio jq_sortable_element. El siguiente código lo agregar en tu jQueryHelper.php.

/**

 * Makes the elements matching the jQuery selector '$selector'
 * sortable by drag-and-drop and makes an AJAX call whenever
 * the sort order has changed. By default, the action called gets
 * the serialized sortable
 * element as parameters.
 *
 * Example:
 *
 '@order',
 *   )) ?>
 * Additional options can be passed in the $options associative array
 * and will be sent to jquery as parameters. For example:
 * 'handle' => 'span' specifies that span elements within the
 * sortable element are the element the user actually clicks on
 *  (although entire first-generation child elements of the
 * sortable element get reordered as a result).
 *
 * Added by hvallenilla@aberic.com
 * This Function has been modified by Henry Vallenilla
 */
function jq_sortable_element($selector, $options = array(),
$messenger = "response", $messageWait = "Wait...",
$messageSuccess = "Saved", $messageError = "Error")
{
	// Cargamos los js requeridos
        sfContext::getInstance()->getResponse()->addJavascript
('/js/jq/jquery.ui.widget.js');
        sfContext::getInstance()->getResponse()->addJavascript
('/js/jq/jquery.ui.mouse.js');
        sfContext::getInstance()->getResponse()->addJavascript
('/js/jq/jquery.ui.sortable.js');
	$options = _parse_attributes($options);
	$options['url'] = url_for($options['url']);
        $options['type'] = 'POST';
        $options = json_encode($options);
	$result = ‹‹‹EOM
       $(document).ready(
        function()
          {
            $('#$selector').sortable(
            {
              update: function(e, ui)
              {
                var serial = jQuery('#$selector').sortable('serialize'
, {});
                var options = $options;
                options['data'] = serial;
                //$.ajax(options);
                $(function(){
                    $.ajax({
                      type: "POST",
                      url: options["url"],
                      data: options["data"],
                      dataType: "script",
                      beforeSend: function(objeto){
                            $("#$messenger").html('$messageWait');
                            $("#$messenger").animate({
                                opacity: 100,
                              }, 1500 );
                      },
                      success: function(msg){
                            $("#$messenger").html('$messageSuccess');
                            $("#$messenger").animate({
				opacity: 0,
                            }, 1200 );
                      },
                      error: function(objeto){
                            $("#$messenger").html("$messageError");
                      }

                    });
                });
              }
            } );
          });
EOM;
        return javascript_tag($result);
}

Es requerido tener los archivos jquery.ui.widget.js, jquery.ui.mouse.js y jquery.ui.sortable.js.

El próximo paso es trabajar en nuestro modulo.

TemplateSuccess.php<?php if ($Posters->getNbResults()): ?>

<tr>

<td align=”center”>

<div style=”margin:0 auto; margin-left: 15px;” id=”image_poster” >

<?php foreach ($Posters as $Poster): ?>

<div id=”elemento_<?php echo $Poster->getIdPoster();?>” class=”contentPicture”>

<div class=”imagePoster”>

<?php if(is_file(sfConfig::get(’app_directory_poster’).’view_’.$Poster->getImage())):?>

<?php echo image_tag(’/uploads/posters/view_’.$Poster->getImage(),’ alt=”" title=”" class=”"  ’)  ?>

<?php else:?>

<?php echo image_tag(’no_image_available.gif’,'width=”200px” height=”180px” ‘)  ?>

<?php endif;?>

</div>

</div>

<?php endforeach; ?>

</div>

</td>

</tr>

<?php endif ?>

<!–  Colocar al final –>

<?php echo jq_sortable_element(’image_poster’, array(
‘url’ => ‘module/changePosition’,
‘only’ => ‘contentPicture’,
),
‘response’,
‘<div class=”load”>Arranging positions … </div><br />’,
‘<div class=”load”>Positions saved</div><br />’
) ?>

Css:

.contentPicture {
   float:left;
   width:210px;
   height:230px;
   margin: 3px;
   padding:6px;
   background-color:#f5f7f9;
   border-right: #b9cede solid 1px;
   border-bottom: #b9cede solid 1px;
   text-align:center;
   cursor: move;
}

.right-element{position: absolute;right: 0;width: 15%;text-align:
 right; /* depends on element width */}
.load{background-color: #7cb7e3;padding: 4px;color: #FFFFFF;}

Lo más probable que al ejecutar la acción, la estructura de su plantilla este descuadrada, ya queda de parte de cada quien acomodarlo a su manera, ya que quite muchas estilos personales de mi módulo para darle un toque sencillo y fácil de comprender.

action.class.php

public function executeChangePosition(sfWebRequest $request)
  {
    foreach ($request->getParameter('elemento') as $position => $id)
    {
        /** Update position **/
        $poster = PosterPeer::retrieveByPK($id);
        $poster->setPosition($position);
        $poster->save();
    }
  }

Al seguir todos estos pasos, podrá posicionar sus imágenes en el orden que desee. Es importante señalar que a la estructura de la tabla deben agregar un nuevo campo, Ej. POSITION, este será el que controle qué imagen es primera y cual es la última

Hasta ola próxima entrega. Saludos

Henry Vallenilla (Programador Web en Php)

Henry Vallenilla
Symfony Developer
Email/Gtalk: henryvallenilla@gmail.com
Skype: hvallenilla
Caracas - Venezuela
www.matatigre.com

Categories: Symfony Tags:

sfUploadFilePlugin (for symfony 1.4)

Viernes, 30 de Abril de 2010 Henry Vallenilla 2 comentarios

Saludos amigos symfonycos, revisando mi post anterior decidí darle ciertas mejoras creando un plugin para la carga de imágenes. Este plugin, provee un helper con una sola función.

DependeciassfThumbnailPlugin

Instalación

1) Descarga el paquete: sfUploadFilePlugin

2) En el módulo o los módulos donde se vaya a usar el helper debe crearse el archivo module.yml en la carpeta config de dicho módulo. La estructura para que el helper funcione es la siguiente:

all:
# Número de copias
num_copies:  2
# Definicion de los tamaños para las imagenes contenidas en este
modulo. Estas se leeran dinámicamente
# Es obligatorio que existan tantos prefijos como número de copias
usted haya configurado
size:
pref_1:          small
image_width_1:   75
image_height_1:  75

pref_2:          big
image_width_2:   150
image_height_2:  150
.....................................
pref_n:          prefijo_de_la_imagen
image_width_n:   valor_width
image_height_n:  valor_heght
.....................................

3) Habilitar el plugin y cargar el helper en el archivo config/ProjectConfiguration.class.php

class ProjectConfiguration extends sfProjectConfiguration
{
public function setup()
{
$this->enablePlugins('sfPropelPlugin', 'sfLynxUploadFilePlugin',
'sfThumbnailPlugin');
sfProjectConfiguration::getActive()->loadHelpers('uploadFile');
}
}

4) Elimine la cache con  ./symfony cc
5) Si todos estos pasos fueron ejecutados secuencialmente y con exito; el plugin debe estar instalado correctamente.

uploadFile Helpers documentation

A continuación se presenta la sintaxis completa para cargar imágenes con el Helper
En tu funcion proccessForm despues de guardar los datos del nuevo registro agregar:

// Detecto si hay una nueva imagen
if($form->getValue('image'))
{
$file = $form->getValue('image');
$Model = ModelPeer::retrieveByPK($Model->getId());
// Aqui cargo la imagen con la funcion loadFiles de mi Helper
$fileUploaded = loadFiles($file->getOriginalName(),
$file->getTempname(),
 0,sfConfig::get('app_directory_upload'),
sfConfig::get("mod_MI_MODULO_sizes_image_big_width"),
sfConfig::get("mod_MI_MODULO_sizes_image_big_height"),
$Model->getId());

$Model->setImage($fileUploaded);
$Model->save();
}

De esta manera se cargan las imágenes al directorio especifico.
Pero esto no lo es todo, al momento de edición del registro y selecciono una nueva imagen debo borrar la imagen anterior. Para esto, en el método doSave de su FormClass Model ó en la función que esten usando para guardar los cambios, se debe incluir lo siguiente:

protected function doSave($con = null)
{
// Si hay un nuevo archivo por subir y ya mi registro tiene una imagen
asociado entonces,
if ($this->getObject()->getImage() && $this->getValue('image'))
{
// recorro y elimino
for($i=1;$i<=sfConfig::get('mod_distributor_num_copies');$i++)
{
// Elimino las fotos de la carpeta
if(is_file(sfConfig::get('app_directory_upload').
sfConfig::get('mod_MI_MODULO_size_pref_'.$i).'_'.
$this->getObject()->getImage()))
{
unlink(sfConfig::get('app_directory_upload').sfConfig::get
('mod_MI_MODULO_size_pref_'.$i).'_'.$this->getObject()->getImage());

}
}
}
return parent::doSave($con);
}

Ahora solo queda poner a correr tu módulo y cargar todas las imagenes que quieras.

Hasta la próxima,

Henry Vallenilla (Programador Web en Php)

Henry Vallenilla
Symfony Developer
Email/Gtalk: henryvallenilla@gmail.com
Skype: hvallenilla
Caracas - Venezuela
www.matatigre.com

Categories: Symfony Tags:

Symfony 1.4 - Consultas específicas con propel

Miércoles, 28 de Abril de 2010 Henry Vallenilla Sin comentarios

Saludos a los amigos symfonycos; innovando con sf 1.4, de seguro se les ha presentado el problema de que las consultas que realizabas con versiones anteriores de Symfony ahora no funcionan.

En el siguiente código v sf 1.4. muestro la manera correcta de realizar nuestras consultas especificas.

public static function getUrlDistributor($idDistributor)
{

$c = new Criteria();
//Eliminamos la columnas de seleccion en caso de que esten definidas
$c->clearSelectColumns();
//Se Agregan las Columnas necesarias
$c->addSelectColumn(self::FIEL-NAME;
//Filtros
$c->add(self::FIELD-NAME, $idDistributor,Criteria::EQUAL);
$rs = self::doSelectStmt($c);
//Se recuperan los registros y se genera arreglo
while($res = $rs->fetch())
{
$data['TU-VALOR'] = $res['FIELD-NAME'];
}
if (!empty($data)){
return $data;
}else{
return false;
}

}

Asi de sencillo, hasta el próximo tips.

Se despide,

Henry Vallenilla
Symfony Developer
Skype: hvallenilla
Email/Gtalk: henryvallenilla@gmail.com
Caracas - Venezuela
www.matatigre.com

Categories: Symfony Tags:

How to add image uploading to your forms with Symfony 1.4 using sfThumbnailPlugin / Cómo agregar carga de imágenes a los formularios con Symfony 1.4 utilizando sfThumbnailPlugin

Miércoles, 28 de Abril de 2010 Henry Vallenilla 2 comentarios

En este ejemplo mi Form se llama DistributorForm, asi que en la configuración del mismo, inmerso en las otras validaciones coloco:

 public function configure()
    {
.................
................
// Widget File Editable
$this->widgetSchema['distributor_image'] = new sfWidgetFormInputFile
Editable(array('file_src' => sfConfig::
get('app_directory_distributor').
$this->getObject()->getDistributorImage(),
          'is_image'  => true,
          'edit_mode' => !$this->isNew(),
        ));

// Validator para el File
$this->validatorSchema['distributor_image'] = new sfValidatorFile
(array(
     'required'   => false,
     'max_size'   => 1048576,
      'mime_types' => array('image/jpeg','image/pjpeg',
'image/png','image/gif'),
 ));

$this->validatorSchema['distributor_image']->
setMessage('max_size','The max value is %max_size% Kb.');
$this->validatorSchema['distributor_image']->
setMessage('mime_types','Error mime types %mime_type%.');
...............
................
}

Seguido las funciones doSave y updateObject

protected function doSave ( $con = null )
    {
        $upload = $this->getValue('distributor_image');
        if ( $upload )
	{
            $filename = 'distributor_'.$this->getObject()->
getIdDistributor().
$upload->getExtension($upload->getOriginalExtension());
	    $filepath = sfConfig::get('app_directory_distributor').
$filename;
            $oldfilepath = sfConfig::get('app_directory_distributor').
$this->getObject()->getDistributorImage();
	    if (is_file($oldfilepath))
	    {
                unlink($oldfilepath);
	    }
            $thumbnail = new sfThumbnail(sfConfig::
get("mod_distributor_sizes_image_big_width"),
 sfConfig::get("mod_distributor_sizes_image_big_height"),
true, true, 75, 'sfGDAdapter');
            $thumbnail->loadFile($upload->getTempname());
	    $thumbnail->save($filepath);
        }
	return parent::doSave($con);
    }

    public function updateObject($values = null)
    {
        $object = parent::updateObject($values);
        $object->setDistributorImage(str_replace(
sfConfig::get('app_directory_distributor'), '',
$object->getDistributorImage()));
        return $object;
    }

Es importante mencionar que si se está creando un nuevo registro, el formato de la imagen se crea erroneo, por lo que debemos modificarlo despues de realiza el registro. Esto lo hacemos en la funcion processForm de action.class.php.

Despues de $form->save();

if($form->getValue('distributor_image'))
{
// Restablesco el nombre del archivo y renombro el archivo
$Distributor = DistributorPeer::retrieveByPK($Distributor->getIdDistributor());
$fileName = explode(".",$Distributor->getDistributorImage());
$ext = strtolower($fileName[1]);
if($ext == "jpeg")
{
$ext="jpg";
}
rename(sfConfig::get('app_directory_distributor').
$Distributor->getDistributorImage() ,
sfConfig::get('app_directory_distributor')."distributor_".
$Distributor->getIdDistributor().".".$ext);

$Distributor->setDistributorImage('distributor_'.
$Distributor->getIdDistributor().'.jpg');

$Distributor->save();

}

Espero les sea de gran ayuda,

Henry Vallenilla
Symfony Developer
Skype: hvallenilla
Email/Gtalk: henryvallenilla@gmail.com
Caracas - Venezuela
www.matatigre.com

Categories: Symfony Tags:

Uso de múltiples bases de datos en Symfony con Propel y Organizar el modelo en una estructura de subpaquetes

Jueves, 7 de Enero de 2010 Henry Vallenilla Sin comentarios

A continuación, explicaré como organizar mi PROJECT_DIR/config/databases.yml para múltiples conexiones.

   all:
     propel:
       class:          sfPropelDatabase
       param:
         dsn:          mysql://USERNAME:PASSWORD@DB_HOST_1/DB_NAME

     dataBases2:
       class:          sfPropelDatabase
       param:
         dsn:          mysql://USERNAME:PASSWORD@DB_HOST_2/DB_NAME

Dada esta estructura de mi databases.yml, me obliga a modificar el archivo PROJECT_DIR/config/propel.ini para al momento de realizar symfony propel-build-schema xml con el fin de que se generen los schema.xml que necesito para los distintos modelos del proyecto. Recomiendo cambiar el nombre del esquema por cada conexión que exista, Ejemplo: dataBases2.schema.xml

Lo principal a tener en cuenta es que siempre debe existir una conexión denominada “propel”. Esto es necesario para ciertas cosas, para que funcione correctamente el comando “symfony propel-build-model”, etc especialmente desde los usos schema.yml que el nombre de conexión.

Ahora, cuando vayas a realizar una consulta, sólo tienes que decirle a Propel qué conexión va a utilizar. De forma predeterminada, Propel utiliza la conexión “propel”; Aquí es donde se usa de las dos conexiones definidas en el archivo PROJECT_DIR/config/databases.yml descrito anteriormente:

$c = new Criteria();
$articles = ArticlePeer::doSelect($c, Propel::getConnection('dataBases2'));

Organizar el modelo en una estructura de subpaquetes

La manera de organizar nuestro modelo, es con los schema.xml que generemos; es muy sencillo.

Debemos modificar el atributo package de nuestro schema.xml; este indica la ruta donde se guardan las clases generadas automáticamente. Su valor por defecto es lib/model/, pero se puede modificar
para organizar el modelo en una estructura de subpaquetes. Si por ejemplo no se quieren
mezclar en el mismo directorio las clases del núcleo de la aplicación con las clases
de un sistema de estadísticas, se pueden definir dos esquemas diferentes con los paquetes

lib.model.aberic y lib.model.matatigre

Por último ejecuta el comando symfony propel-build-model y listo.

Un Saludo Cordial

Henry Vallenilla
Desarrollador Symfony
Caracas - Venezuela
Visita - www.matatigre.com

Momentos Aberic 2009

Martes, 15 de Diciembre de 2009 Henry Vallenilla Sin comentarios
Categories: De Interés, ¿Qué pasa en Aberic? Tags:

Symfony 1.0 - Select Tag

Martes, 15 de Diciembre de 2009 Henry Vallenilla Sin comentarios

La mejor forma de construir un select->

<?php echo select_tag('id_portfolio',
objects_for_select(PortfolioPeer::doSelect(new Criteria()),
'getIdPortfolio','__toString',
$sf_request->getParameter('id_portfolio'),
array('include_custom' => 'By Company'))) ?>

Saludos,

Henry Vallenilla
Caracas - Venezuela
Visita - www.matatigre.com

Categories: Symfony Tags:

Symfony - Problemas con la ruta del FCKEditor

Jueves, 3 de Septiembre de 2009 Henry Vallenilla Sin comentarios

Este es un problema que no se presenta con mucha frecuencia, pero bue, suele suceder. Resulta que en mi servidor local, el modulo que usa fckeditor funciona perfectamente, pero cuando lo subí al dominio, y cargaba el mismo módulo salía un error como este.

You must install FCKEditor to use this helper (see rich_text_fck_js_dir settings).

Tenía instalado el fckeditor ? SI
Tenía habilitado el fckeditor en el settings.yml de tu aplicación ? SI
all:
.settings:
rich_text_fck_js_dir:   js/fckeditor

El problema que se me presentó fue que mi carpeta web del proyecto en el servidor final se llama htdocs y por ende la variable symfony sfConfig::get(’sf_web_dir’), no sé porque seguía apuntando a web. Es un problema de configuración, y que estaba también ocasionado otros problemas como para enviós de correos, visualización de imágenes, etc. La solución rápida que le conseguí fue redeclararlas en el app/frontend/config/config.php; quedando así.

sfConfig::add(array(
      'sf_web_dir'      => SF_ROOT_DIR.'/htdocs',
      'sf_upload_dir'   => SF_ROOT_DIR.'/htdocs/'.sfConfig::get('sf_upload_dir_name'),
    ));

En los próximos anuncios explicaré como configurar la ruta de dicha carpeta.

Saludos,

Henry Vallenilla
Programador Senior
Caracas, Venezuela
www.aberic.com / www.matatigre.com

Categories: Symfony Tags:

Symfony en PlayStation 3

Miércoles, 26 de Agosto de 2009 Henry Vallenilla Sin comentarios

Comparto este enlace para aquellos amigos que tiene un PlayStation 3 y usan Symfony. Pensaron alguna vez  en programar con Symfony en un PS3·

http://demenzia.net/2007/08/21/linux-and-symfony-on-a-ps3
Categories: Symfony Tags: