Archive: cakePhp

Píldora – Traducción de fechas en cakephp 2.0.

 

cakePhp

Si usamos el Helper Form para construir nuestro formularios, cuando tenemos un campo fecha, los meses no salen en inglés. ¿Como traducir esto?

Primero fijarnos en el Helper Form, como están construidos los textos traducibles

__d('cake', 'January');

Viendo en el código vemos que el archivo que va a buscar las traducciones no es el default.po ( como en otras versiones de cakePhp, sino uno llamado cake.po, habría que crear este archivo con las traducciones de todos los meses o descargar el que tengo hecho.

El último paso para que esto funcione, es configurar el cakePhp para que el idioma definido sea castellano.

Para probar ponemos el siguiente código en el controlador que necesitemos esa traducción.

Configure::write('Config.language', 'spa');

Píldora – Usar paginación con varios modelos en cakephp.

 

cakePhp

A veces en cakePhp nos encontramos con que queremos usar varios modelos en un mismo controlador, y paginar los modelos.
y como es algo que me ha surgido varias veces, y siempre me tengo que para a pensar, lo dejo colgado en el blog, como una pequeña píldora.

Decimos que queremos usar dos modelos.

public $uses = array( 'User', 'Profile');

En lo que siempre fallo es que pongo $this->paginate(); pero si hay varios modelos tengo que decir que modelo quiero paginar, sino por defecto siempre será el primero en la array $uses.

un ejemplo:

public function Profile() {
		$this->Profile->recursive = -1;
		$this->set('profile', $this->paginate('Profile'));
}

Componente REST para cakePhp

 

cakePhp, Código

Buenas, acabo de subir un componente RESTfull para cakePhp en mi cuenta de github https://github.com/deldan/RestAndCurl-component-cakePhp

¿Como hacerlo funcionar?

Descargar los dos componentes y guardarlos en la carpeta app/controller/components de tu proyecto cakePhp

Llamalo en el controlador que se necesite, como con cualquier componente

var $components=array('Curl', 'Restclient');

Y crear las llamadas REST

Dejo un pequeño ejemplo de conexión y llamada a la api de 11870.com con estos componentes


//uri REST
$uri = "http://api.11870.com/api/v2/search";

//parametro de busqueda
 $params['q'] = $search;

 //parametro ciudad
 $params['ls'] = $city;

//parametro categoria
 $params['category'] = $tipo;

 //params
 $params['fields'] = 'title,summary,link';
 $params['oauth_token'] = '**********************';
 $params['oauth_token_secret'] = '**********************';
 $params['appToken'] = '**********************';

 // REST call
 $result = $this->Restclient->get($uri, $params, 'xml');

Cambiar url navegador desde Ajax en cakePhp (location.hash)

 

cakePhp

Cuando usamos Ajax,  y cargamos información, no se refresca nuestra url.
A veces nos interesa que si sea así, que nuestra url cambié.

Una manera sencilla de hacerlo en cakePhp

echo $ajax->link(
‘ver Usuario’,
array(‘controller’ => ‘User’, ‘action’ => ‘ver/’.$id),

array(‘update’ => ‘ver_usuario’, ‘complete’ => ‘window.location.hash = “usuario”‘)
);

Lo que tenemos en window.location.hash es lo que luego saldrá en nuestra url tipo:  http://localhost/user/ver#usuario

Imagen Preloader con Ajax y Cakephp

 

cakePhp

En un anterior post comentaba como crear formularios Ajax en Php. Está vez necesitaba un link en vez d eun formulario, pero además con una imagen con el típico preloader, mientras procesaba los datos, y fue más sencillo de lo esperado. aquí os dejó el código, el secreto está en el “indicator”.

Código html, donde se mostrá el resultado, la imagen que se mostrará al hacer el preload.

resultados

Código php, donde ultilzamos el helper ajax.

//debe estar declarado el ajax helper var $helpers = array('Ajax');
 $ajax->link('El navegador confirmará antes de enviar la respuesta ajax', array( 'controller' => 'ajax', 'action' => 'add', 5 ), array( 'update' => 'add5', 'indicator' => 'loading'));

FirePHP para cakePHP

 

cakePhp

Primero decir que firePHP es complemento  de firebug para firefox, ¿en que nos facilita la vida? nos ahorra tener que sacar por pantalla echos, o var_dump(), esto es extremadamente útil cuando un proyecto web en php ya está en subido, y hay usuarios conectados.

Pasos a seguir para poder utilizar firePHP en Cakephp:
He sacado la parte de como instalarlo de: http://www.utoxin.name/2009/02/cakephp-firephp/.

Requerimientos:

Vamos a preparar cakePHP para el correcto funcionamiento de firePHP.

Lo primero que debemos haces es descomprimir la biblioteca principal de firePHP que hemos descargado, dentro de la carpeta lib, copiar la carpeta FirePHPCore, en “app/vendors/”.

Copiamos el archivo dbo_source.php de “cake/lib/models/datasources” y lo pegamos en “app/models/datasources/”, buscamos dentro del archivo la función showLog() y la cambiamos por la siguiente.

function showLog($sorted = false) {
	if ($sorted) {
		$log = sortByKey($this->_queriesLog, 'took', 'desc', SORT_NUMERIC);
	} else {
		$log = $this->_queriesLog;
	}

	if ($this->_queriesCnt > 1) {
		$text = 'queries';
	} else {
		$text = 'query';
	}

	if (PHP_SAPI != 'cli') {
		$summary = "{$this->_queriesCnt} {$text} took {$this->_queriesTime} ms";

		$body = array();
		$body[] = array("Nr", "Query", "Error", "Affected", "Num. rows", "Took (ms)");
		foreach ($log as $k => $i) {
			$body[] = array(($k + 1), $i['query'], $i['error'], $i['affected'], $i['numRows'], $i['took']);
		}

		fb(array($summary, $body), FirePHP::TABLE);
	} else {
		foreach ($log as $k => $i) {
			print (($k + 1) . ". {$i['query']} {$i['error']}\n");
		}
	}
}

Ahora debemos pegar el siguiente código en “app/config/bootstrap.php”.

App :: import ( 'Vendor' , 'FirePHP' , array ( 'file' => 'FirePHPCore/FirePHP.class.php' ));
function fb() {
	$debug = Configure::read('debug');
	if ($debug) {
		$ob_setting = ini_get('output_buffering');
		if (!$ob_setting) {
			ob_start();
		}

		$instance = FirePHP::getInstance(true);
		$args = func_get_args();
		return call_user_func_array(array($instance, 'fb'), $args);
	} else {
		return true;
	}
}

Ahora crearemos un componente para poderlo utilizar en todos nuestros controladores, app/controllers/components/fire_p_h_p.php y copiamos el siguiente código:

class FirePHPComponent {
	private $instance;

	public function __construct() {
		$ob_setting = ini_get('output_buffering');
		if (!$ob_setting) {
			ob_start();
		}
		$this->instance = FirePHP::getInstance(true);
		$this->instance->setEnabled(Configure::read('debug'));
	}

	public function __call($name, $args) {
		return call_user_func_array(array($this->instance, $name), $args);
	}
}

Ya estaría instalado, vamos a probarlo, primero deberiamos llamar al componente en el controlador donde queramos usarlo.

var $components = array('FirePHP');

También dejo una pequeña idea de como usarlo en el controlador.

public function index() {
                $users = $this->Users->AllUsers();
		$this->FirePHP->error($users,'array users');
	}

Estamos simulado que recogemos todos los usuarios de la base de datos en una variable $users, la salida será un array, como habíamos comentado, la idea era no tener que poner var_dump o echos. Ahora en pantalla no nos saldrá nada, pero si vamos a la consola de firebug, vermos ahí nuestra array reflejada con el nombre de error array users.

Decidokit beta lanzado!

 

cakePhp, Novedades

Buenas este es un anunció que me agrada dar.
Un proyecto interno de bonzzay la empresa que tengo con otros 3 socios, ha sido lanzado.
Se llama decidokit, la idea es simple, que el mundo decido por ti.

Sí quereis hechar un vistazo, y ayudarnos a mejorarlo.  Si no sabes aún que teléfono comprarte quizás la gente pueda ayudarte a decidirte. decidokit.com

multilenguaje en cakephp (Internationalization & Localization)

 

cakePhp, Emprendedor

La primera parte que es internacionalización, es muy importante tenerla prevista antes de empezar un proyecto en cakephp, lo que hago en cualquier proyecto por muy grande o pequeño que sea es dejarlo preparado.

Es fácil dejarlo listo para traducir, en vez de poner los textos sin más, hacelo de la siguiente manera.

__('texto para traducir', true);

Ya lo tenemos preparado por si nos piden multilenguaje en un futuro. Ahora si lo necesitamos hacer, el siguiente paso es crear los archivos con tantos idiomas se requiera, por ejemplo de ingles y español.

Crearíamos las siguientes carpetas y archivos dentro de la carpeta locale:
eng/LC_MESSAGES/default.po
esp/LC_MESSAGES/default.po

Ahora viene la parte que mas me ha costado, y más divertida, pasar el script que coge todos los textos traducibles, y crea archivos con las palabras a traducir . El script lo lanzo desde eclipse, os dejo un pantallazo de la configuración para lanzar el script.

Crea varios archivos, solo hay que abrir estos archivos, copiar lo que hay y pegarlo dento de los archivos que hemos creado default.po
Para editar los archivos .po os recomiendo el editor poedit, desde aquí ya se traduce con facilidad.

Ya tenemos una parte muy importante, podríamos cambiar de idioma copiando lo siguiente en app_controller.php

Configure::write('Config.language', 'esp');

o

Configure::write('Config.language', 'eng');

Ahora entramos en la segunda parte Localización.
Hay muchas maneras de hacerlo, os voy a presentar una sencilla, cuando estoy en la página en inglés tener el link para pasarla a castellano y viceversa.

En config/route.php copiar el siguiente código, para reconocer el idioma:

Router::connect('/:language/:controller/:action/*',
                       array(),
                       array('language' => '[a-z]{3}'));

En app_controller.php necesitamos definir el idioma predefinido, llamar a los componenetes cookie y session, ver y guardar en cookie el idioma que queremos.

$lang='esp';
Configure::write('Config.language', $lang);

class AppController extends Controller {

	var $helpers = array('Html', 'Form', 'Ajax','Javascript','Bonzzay');
	var $components = array('Session', 'Cookie'); 

	function beforeFilter() {
	    $this->_setLanguage();
	} 

	function _setLanguage() {

	    if ($this->Cookie->read('lang') && !$this->Session->check('Config.language')) {
	        $this->Session->write('Config.language', $this->Cookie->read('lang'));
	    }
	    else if (isset($this->params['language']) && ($this->params['language']
	             !=  $this->Session->read('Config.language'))) {     

	        $this->Session->write('Config.language', $this->params['language']);
	        $this->Cookie->write('lang', $this->params['language'], false, '20 days');
	    }
	}

}

Lo último que nos falta hacer es poner el link para cambiar el idioma, pero debemos saber en que idiomas estamos para saber que link poner, asi que primero vamos al controlador o en el mismo app_controller y ponemos el siguiente código, que recoge, que tenemos como lenguaje definido en cookie y lo envia a vista.

function beforeRender() {
		$idioma = $this->Cookie->read('lang');
		$this->set('idioma',$idioma);
	}

Recojo en vista el idioma definido y según el idioma definido tengo un link u otro.

$this->languageswitch($idioma);
function languageswitch($idioma){
		$content ="";
		if($idioma == 'esp'){
			$content .= $this->Html->link(__("English",true), array('language'=>'eng'));
		}else if($idioma == 'eng'){
			$content .= $this->Html->link(__("English",true), array('language'=>'esp'));
		}else{
			$content .= $this->Html->link(__("English",true), array('language'=>'eng'));
		}
		return $content;
	}

Bueno esto ya estaría, espero haberme explicado bien, se que son muchas cosas, muchos conceptos, pero leyendo antes el cookbook de cakephp, ayuda entender mejor como funciona.

Formulario Ajax en Cakephp

 

cakePhp

Algo que a veces queremos hacer, es al tener un formulario, ver los datos enviados desde el formulario si refrescar la página.
Un ejemplo de como hacerlo añadiendo un album, con un campo nombre.

Hay dos cosas a tener en cuenta, el envio del formulario es ajax, pero tambien el div donde cargaremos los resultados es ajax.

$content .= $this->Ajax->div('calendars');
foreach ($calendars as $calendar){
$content .=$interestDestination["InterestDestination"]["name"];
}
$content .=  $this->Ajax->divEnd('calendars');

$content .= $this->Ajax->form('/calendars', 'post', array('update' => 'calendars'));
$content .= $this->Form->input('name', array('label' => 'Agregar Nuevo Grupo:', 'error' => __('Nombre no valido', true)));
$content .= $this->Form->submit('Añadir',array('escape'=>false));
$content .= $this->Form->end();

return $content

Podemos ver que el update del form tiene el mismo nombre que le div Ajax, está observación es importante ya que el formulaior hace la llamada a este div, y esté div es el que se refrescará sin tener que refrescar toda la página.

En el controlador deberemos tener en cuenta, el añadir var $helpers = array(‘Ajax’);

Y también en la función en este caso “calendars” que ejecutamos desde nuestro formulario, deberemos hacer un render a la página donde se encuentra el mismo formulario.
Por ejemplo si nuestro formulario está en nuestro index $this->render(‘index’, ‘ajax’);

Helpers cakephp

 

cakePhp

Una de las cosas que utilizo en mis vistas en cakephp son los helpers.

¿Para que sirve?
Lo que hago yo es hacer un helper de una tématica ( ejemplo album de imagenes), asi lo tengo más organizado.

Mi controlador llama a mi vista, y la vista llama a una función el helper pasando las variables necesarias de la siguiente manera.


echo $imageHelper->viewImageComponent($image,$albums);

para que me funcione esta manera de hacerlo necesito tener creado mi helper en views/helpers/image_helper.php
y debemos también decir que vamos a usar este helper, esto lo hacemos en /app_controller.php
añadir lo siguiente, o modificarla.


class AppController extends Controller {
	var $helpers = array('Html', 'Form', 'ImageHelper');
}

De esta manera si mi proyecto es grande, puedo estar modificando mis vistas desde un solo archivo, y tenelo más organizado.