dijous, 15 d’octubre del 2009

Estem a wordpress

Amb la incorporació d'un nou col·laborador, l'Arnau, ens hem canviat a wordpress:

Ens trobaràs en un nou blog de picatecles, on tractarem bàsicament temes sobre aplicacions web i CakePHP. Com aquí, vaja, però esperem que amb més freqüència ;)

divendres, 2 d’octubre del 2009

CakePHP sense mod_rewrite

És fàcil que a l'hora d'instal·lar un cake ens trobem amb servidors que no tenen activat el mòdul mod_rewrite i per tant les urls netes, del tipus "www.nomweb.com/controlador/accio" no funcionen.

La primera recomanació és demanar que ens l'activin, ja que fer servir aquest tipus d'URLs fa l'aplicació més elegant i és molt útil pels buscadors.

Si pel motiu que sigui no és possible que ens l'activin, no desesperem. Cake contempla aquesta possibilitat i té una alternativa, utilitzar les "pretty URLs". Canviant un parell de configuracions podrem fer que l'aplicació funcioni amb l'única diferència que les URLs seran del tipus "www.nomweb.com/index.php/controlador/accio".

El manual explica els passos a seguir:
  • A /app/config/core.php, descomentar la linia:
    Configure::write('App.baseUrl', env('SCRIPT_NAME'));
  • Esborrar els arxius .htaccess següents:
    • /.htaccess
    • /app/.htaccess
    • /app/webroot/.htaccess

Amb això hauriem de tenir el tema resolt.

No obstant, oer algún motiu encara pot ser que els enllaços que ens genera Cake no ens funcionin. En aquest cas és possible que ens faci falta afegir un interrogant després de "index.php".

Si així se'ns soluciona el problema és que el nostre servidor ens està dificultant la gestió de la variable "path_info" que és la que es fa servir per construir aquestes URLs.

N'hi ha prou amb modificar la línia que hem descomentat abans i deixar-la d'aquesta manera.
Configure::write('App.baseUrl', env('SCRIPT_NAME').'?');

Així CakePHP ens construirà tots els enllaços amb l'interrogant.

dilluns, 14 de setembre del 2009

AutoLogin Component per a CakePHP

Els components CakePHP et poden facilitar enormement la vida en algunes tasques comunes en les aplicacions web. A més dels components inclosos al nucli de CakePHP, existeixen multitud de components "extra" que poden resultar molt útils -a mi m'ho han estat- i que aniré repassant a mesura que vagi tenint alguns moments.

Començaré per un de molt senzill que, no obstant, acaba sent molt pràctic quan es tracta amb usuaris en una aplicació web. Per aquest aspecte ja comptem amb el AuthComponent de CakePHP, inclòs al nucli i que gestiona l'autenticació d'usuaris. Però, i si volem afegir la opció de identificar-se automàticament (el típic, "recorda'm la pròxima vegada")? Doncs podem implementar-ho nosaltres mateixos utilitzant cookies o bé simplement utilitzar un component desenvolupat per Miles Johnson, l'AutoLogin Component.

En un tres i no res els nostres usuaris podran comptar amb la opció de visitar la nostra aplicació web i automàticament iniciar sessió amb el seu usuari. Tot amb una instal·lació molt fàcil i la possibilitat de configurar diferents aspectes com la durada de la cookie.

dimecres, 2 de setembre del 2009

AuthComponent: Actualitzar la sessió de l'usuari

Ben tornat de les vacances, ja torno a ser aquí per anar deixant cosetes que em semblin interessants. I com no, continuem amb el framework CakePHP.
CakePHP incorpora entre els seus components el component Auth, que si ho desitgem s'encarrega de la identificació d'usuaris de manera fàcil i ràpida. Fins ara només l'havia utilitzat en una aplicació web ja que el component es va incorporar amb la versió 1.2 i les altres aplicacions on havia requerit d'identificació van començar a desenvolupar-se amb la versió 1.1 i utilitzant altres components semblants que feien la mateixa funció i que he conservat encara que les hagi adaptat a noves versions.
Doncs bé, el fet és que m'he trobat amb un petit problema editant la informació d'un usuari que ja havia iniciat sessió a l'aplicació. Si tenim un escenari semblant a:
  • Un usuari s'ha identificat a l'aplicació amb Auth, de manera que tenim les seves dades accessibles mitjançant $this->Auth->read();
  • Les dades són accessibles ràpidament i sense accedir a la BD ja que estan guardades a la sessió.
  • Utilitzem les dades de l'usuari donades per Auth per mostrar certa informació. En el cas que m'ocupa, si l'usuari no està actiu (no ha confirmat encara el seu e-mail), se li mostra un missatge requerint aquesta acció.
  • Si les dades del model es modifiquen, la informació ha de canviar. En el meu exemple, si l'usuari activa el seu compte, s'ha de deixar de mostrar el missatge.
El problema sorgeix quan al canviar les dades del model Usuari, la informació a la sessió segueix inalterable i per tant, és errònia.
La solució passa per modificar la sessió amb les noves dades. He creat una funció que podeu posar al vostre usuaris_controller.php que s'encarrega de fer-ho.
private function _updateDataSession($newdata) {
    $updatedAuth = Set::merge(
        $this->Session->read(sprintf('Auth.%s',$this->Auth->userModel)),
        $newdata
    );
    $this->Session->write(sprintf('Auth.%s', $this->Auth->userModel), $updatedAuth);
}
De manera que des de qualsevol punt del controlador podeu modificar les dades de l'usuari en sessió:

function edit($id = null) {
   [...]
   if ($this->Usuari->save($this->data)) {
     [...]
     $this->_updateDataSession($this->data[$this->Auth->userModel]);
   }
}

function activa($id, $clauActivacio) {
  if ($this->Usuari->saveField('actiu', 1, false)) {
     $this->_updateDataSession(array('actiu'=>1));
  [...]
}

Com a mínim, la funció d'edició segurament apareixerà en la majoria d'aplicacions que facin un mínim ús dels usuaris, així que ja sabeu una manera de resoldre el problema.

dilluns, 6 de juliol del 2009

Errors estúpids

Definiré com errors estúpids aquells que arriben a tocar els ous, normalment perquè m'han fet perdre el temps de manera estúpida, buscant solucions cada cop més rebuscades, quan la causa de l'error era una ximpleria.

allowEmpty, en què quedem?

Inauguro aquests errors estúpids amb un de validació. La propietat allowEmpty en una regla de validació marca si aquell valor pot deixar-se en blanc, independentment de la validació aplicada. En versions anteriors la propietat era ignorada si definies la teva pròpia regla de validació per un camp, de manera que s'havia de controlar a la nova regla definida. Però això va canviar -no sé ben bé en quin moment- i em va donar una estona de mals de cap. Així doncs, a vigilar que la propietat allowEmpty i la regla de validació que es defineixi no siguin contradictòries.

dilluns, 8 de desembre del 2008

Utilitzant counterCache en associacions belongsTo

Una de les novetats que vaig veure revisant la documentació de la versió 1.2 no fa massa va ser que l’associació belongsTo incorporava un nou paràmetre: counterCache. El paràmetre counterCache permet mantenir un atribut amb el comptador de quants models té associat a través de hasMany.

Com utilitzar counterCache? Precisament em va anar perfecte perquè tenia un sistema de noticies amb comentaris i volia mostrar el número de comentaris de les noticies a la portada, així que m’estalvio de fer una consulta amb count o recuperar tots els comentaris amb una join per saber quants comentaris en total té cada noticia. Tenint els següents models:

Noticia hasMany Comentari
Comentari belongsTo Noticia

Al model Comentari la relació belongsTo es defineix amb counterCache com a true.

var $belongsTo = array(
    'Noticia' => array(
            'className' => 'Noticia',
            'counterCache' => true,
     )
);

Afegim el camp comentari_count a la taula de la BD noticies i llestos. Cada cop que s’insereixi (o s’esborri) un comentari, cake s’encarregarà d’actualitzar el camp comentari_count. Fàcil no?

dimecres, 22 d’octubre del 2008

VALID_YEAR versió cakephp 1.2

Estic adaptant a la nova RC3 de cakephp una aplicació web realitzada per la versió 1.1 del framework i, aplicant les noves regles de validació en un model, m’he trobat amb un aspecte amb el que fins ara no m’hi havia topat. A la versió 1.1 hi havia 4 regles que ara estan marcades com a deprecated:

  • VALID_NOT_EMPTY
  • VALID_NUMBER
  • VALID_EMAIL
  • VALID_YEAR

L’equivalent de la primera amb la nova validació de la versió 1.2 és ‘notEmpty’, la segona ‘numeric’, la tercera ‘email’ i la quarta...ei! la quarta com?

La meva primera idea ha estat provar sense èxit amb la regla date

'year' => array('rule' => array('date', 'y'))

Però no accepta un format amb només l’any. Llavors he acabat recorrent a l’expressió regular

'rule' => array('custom', '/^[12][0-9]{3}$/')

'rule' => array('date', null, '/^[12][0-9]{3}$/')

Ambdues opcions fan exactament el mateix –date ignora el segon paràmetre si se li passa una expressió regular-, però potser sembla que passant l’expressió regular a date queda més clar.

Alguna opció millor?