Mostrando entradas con la etiqueta CakePHP. Mostrar todas las entradas
Mostrando entradas con la etiqueta CakePHP. Mostrar todas las entradas

miércoles, 19 de junio de 2013

CakePHP: Warning: _cake_core_ cache was unable to write 'cake_dev_en-us' ...


Este error me dio al acceder el sitio después de clonar una copia fresca del framework:

Warning: _cake_core_ cache was unable to write 'cake_dev_en-us' to File cache in /var/www/html/cakephp/lib/Cake/Cache/Cache.php on line 310 Warning: /var/www/html/cakephp/app/tmp/cache/persistent/ is not writable in /var/www/html/cakephp/lib/Cake/Cache/Engine/FileEngine.php on line 337


Evidentemente es un error de permisos que solucioné cambiando el usuario owner del proyecto al del servidor web que en este caso es 'apache':

chown -R apache:apache /var/www/html/cakephp

sábado, 1 de junio de 2013

CakePHP: Warning: strtotime(): It is not safe to rely on the system's timezone settings.


Recién copié un proyecto que tenía de CakePHP a una máquina virtual y comencé a tener este mensaje de warning:


Warning: strtotime(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Los_Angeles' for 'PDT/-7.0/DST' instead in /path/to/cake/lib/Cake/Cache/CacheEngine.php on line 45 Warning: strtotime(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Los_Angeles' for 'PDT/-7.0/DST' instead in /path/to/cake/lib/Cake/Cache/CacheEngine.php on line 45 


La solución más rápida es ubicar el archivo de 'core.php': /path/to/cake/app/Config/core.php y descomentar esta línea:

/**
 * Uncomment this line and correct your server timezone to fix 
 * any date & time related errors.
 */
date_default_timezone_set('UTC');

lunes, 5 de noviembre de 2012

CakePHP: Salvar y Mostrar

En este pequeño código muestro como guardar los datos de un formulario, en este caso correspondientes a un anuncio, e inmediatamente redirigir a la página para ver los datos guardados.

<?php

//...

class AnunciosController extends AppController {
  
 public function add() {  
        if ($this->request->is('post')) {
         if ($this->Anuncio->save($this->request->data)) {
              $this->Session->setFlash('El anuncio fue guardado: ');
              $inserted_id = $this->Anuncio->id;              
              $this->redirect(array('action' => 'view', $inserted_id ));
         } else {
             $this->Session->setFlash('No se pudo guardar el anuncio');
         }
  }
  // ...
    }
    
 // ...
 
 public function view($id) {
        $this->Anuncio->id = $id;
        $this->set('anuncio', $this->Anuncio->read());
    }    
}

La línea clave es la que hace el redireccionamiento. Aquí tocó quebrarme bastante la cabeza para determinar como pasaba el id del recién insertado anuncio.

miércoles, 19 de septiembre de 2012

CakePHP: Plugin para subir imágenes

Al fin pude descifrar una manera de subir imágenes en CakePHP 2.0. Probé este plugin de Jose Gonzalez y me funcionó adecuadamente. Puedo subir imágenes que se guardan en una estructura de carpetas fácilmente consultable por el identificador del modelo que se guarda en la base de datos. A parte genera los thumbnails en los tamaños que uno le defina.

Estos fueron los pasos que seguí:

1. Bajar el plugin.Se puede descargar el zip o bajar el código del repositorio de GitHub.

2. Se copia el código en la carpeta /app/Plugin/Upload (dejar la carpeta renombrada con Upload u otro nombre más amigable).

3. Se edita el "bootstrap.php" (/app/Config/) agregando la línea para habilitar el plugin:
CakePlugin::load('Upload');

4. En la base de datos, en la tabla donde se guarda la referencia a la foto, agregamos dos columnas: una para el identificador de la foto, y otra para el identificador del directorio:

CREATE TABLE  `mi_db`.`anuncios` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `titulo` varchar(45) NOT NULL,
  `id_foto` varchar(15) DEFAULT NULL,
  `dir` varchar(250) DEFAULT NULL,
)

5. En el modelo se configura las opciones para la subida de la imagen:

class Anuncio extends AppModel {
     
    public $actsAs = array(
        'Upload.Upload' => array(
            'id_foto' => array(
                'fields' => array(
                    'dir' => 'dir'
                ),                
                'thumbnailSizes' => array(
      'big' = '200x200',
                    'small' =>'120x120',
                    'thumb' =>'80x80'
                ),
                'thumbnailMethod'=> 'php'
            )
        )
    );
}

Observese que se configura los nombre de las columnas que configuramos en la tabla de nuestra base de datos, los tamaños de los thumbnails, y el método para crear los thumbnails (aquí uso php pues es una extensión que viene ya instalado por defecto en la mayoría de los ambientes de desarrollo tipo WAMP).

 6. Agrego el código de la vista:

<?php
 echo $this->Form->create('Anuncio', array('type' => 'file'));
 echo $this->Form->input('id_foto', array('type' => 'file', 'label' => 'Foto'));
 echo $this->Form->input('dir', array('type' => 'hidden'));
 echo $this->Form->end('Guardar Anuncio');
?>

7. ¡Listo! Las imágenes son guardadas dentro de 'webroot/files' (la ruta se puede configurar).


lunes, 23 de julio de 2012

CakePHP: Carga dinámica de select input con JSON

Continuando con mis experiencias en este aprendizaje del framework CakePHP, quiero poner a disposición una receta en la cual tardé bastante en encontrar y personalizar, de cómo preparar una carga dinámica de un select box a partir de una selección anterior.

En este ejemplo cargo las opciones de raza a partir de una selección previa de una especie.

Ingredientes:


1. Función en el controlador para listar las especies (primer select box):

public function add() {  
   if ($this->request->is('post')) {
       // Código para salvar el anuncio.
    } else {
        $especie = new Especie();         
        $especies = $especie->find('list', array(       
     'fields' => array('Especie.id', 'Especie.nombre')
 ));
        $this->set('especies', $especies);         
    }
}

2. Código del formulario:
Form->create('Anuncio');
 
 echo $this->Form->input('especie', array(
     'type'    => 'select',
     'options' => $especies,
     'empty'   => 'Elija una especie'
 ));
 echo $this->Form->input('raza', array(
     'type'    => 'select',
     'empty' => 'Elija una especie'
 ));    
 echo $this->Form->end('Guardar Anuncio');
?>

3. Función en el controlador para retornar un JSON con las razas pertenecientes a la especie:

    public function getRazasByEspecie() {
     if ($this->request->is('ajax')) { 
      $idEspecie = $this->params['data']['idEspecie'];
       
      $raza = new Raza();
      $razas = $raza->find('all',array(
       'fields' => array('Raza.id', 'Raza.nombre'), 
       'conditions'=>array('Raza.id_especie'=>$idEspecie)));
      
      $this->RequestHandler->respondAs('json');
      $this->autoRender = false;      
      echo json_encode ( $razas );      
     }
    }

Preparación:

Agregar el código JavaScript que una (binding) la siguente lógica al evento de modificación del primer select box. La función hace un llamado Ajax al controlador para pedir las razas. Estas son retornadas en formato JSON el cual es procesado para agregar las nuevas opciones del segundo select box.
$(document).ready(function(){

 $('#AnuncioEspecie').change(function(){
  var selected = $(this).val();
    
  $.ajax({
   type: "POST",
   url: '/Anuncios/getRazasByEspecie',
   data: "idEspecie="+selected,
   dataType: 'json',
   success: function(data){
    
    $('#AnuncioRaza option').remove();
    var $el = $("#AnuncioRaza");
    if (data.length > 1) {
     $el.append($("")
       .attr("value", -1).text("Elija una raza"));
    }
    $.each(data, function(i,items){
     $el.append($("")
       .attr("value", items.Raza.id).text(items.Raza.nombre));          
    });    
   }
  });
 });
});


Consumase al gusto :D!

miércoles, 27 de junio de 2012

CakePHP: Llenando un combo box

Aca estoy iniciando con mis primeros pasos en este framework que hasta el momento pinta muy bien. La documentación que existe en el sitio oficial donde exponen un caso de ejemplo desarrollando un blog es verdaderamente muy útil. Solamente me quedé un poco atascado en el desarrollo de mi propio ejemplo queriendo llenar un combo box.

En mi caso quería tener una pantalla para agregar una mascota seleccionando la raza a la que pertenece.  Para ello necesito poder mostrar las razas que se encuentran en una tabla aparte de la de mascotas.

Al final la solución que encontré fue la de importar la clase modelo "Raza" para poder hacer un "find" y mandar los resultados a la vista utilizando una notación especial para que se ajuste bien a un combo box.

Controlador

<?php
App::import('Model', 'Raza');

class MascotasController extends AppController {
    public $helpers = array('Html', 'Form');
    
    public function add() {  
        if ($this->request->is('post')) {
           // Código para salvar la mascota.
        } else {
            $raza = new Raza();          
            $razas = $raza->find('list', array(       
                  'fields' => array('Raza.id', 'Raza.nombre')
            ));
            $this->set('razas', $razas);         
        }
    }
}

Vista

<h1>Agregar Mascota</h1>
<?php
echo $this->Form->create('Mascota');
echo $this->Form->input('nombre');
echo $this->Form->input('raza', array(
    'type'    => 'select',
    'options' => $razas,
    'empty'   => false
));
echo $this->Form->end('Guardar Mascota');
?>