Symfony, Doctrine e validatori

Ultimamente mi è capitato di lavorare con Doctrine all’interno di un progetto symfony e di dover validare dei campi in input rispetto ad una classe del mio modello. Per particolari accorgimenti nella selezione degli input accettati mi sono trovato di fronte ad un problema che mi ha fatto perdere un po’ di tempo e che non sono riuscito a capire subito da cosa dipendesse. Lo segno qui per chi si trovasse nella mia stessa situazione.

Per la validazione degli input ho utilizzato sfValidatorDoctrineChoiceMany, che già valida gli input rispetto ad una classe del modello

$this->validatorSchema['users_list'] = new sfValidatorDoctrineChoiceMany(array('model' => 'User');

La particolarità a cui mi sono trovato di fronte è quella in cui i valori accettati in input dovevano essere validati rispetto ad un sottoinsieme di quelli contenuti nel mio modello. Seguendo la guida trovata sul sito di symfony aggiungo il parametro ‘query’ al mio validatore.

1
2
3
4
5
6
7
$q = Doctrine_Query::create()
->from('User u')
->where('u.name = '.$name);
 
...
 
$this->validatorSchema['users_list'] = new sfValidatorDoctrineChoiceMany(array('model' => 'User' ,'query' => $q));

A questo punto però mi sono trovato di fronte all’errore

500 | Internal Server Error | Doctrine_Exception

Couldn't find class a

Non avendo nessuna classe (né alias) ‘a’ definita nel modello mi sono girato un po’ i log che vengono forniti da symfony e ho scoperto che sfValidatorDoctrineChoiceMany, durante il cleaning dei valori in input, esegue la query aggiungendo un’opzione al ‘where’:

sfValidatorDoctrineChoiceMany.class.php

1
2
3
4
5
6
7
8
...
$a = $this->getOption('alias');
$q = is_null($this->getOption('query')) ? Doctrine_Query::create()->from($this->getOption('model') . ' ' . $a) : $this->getOption('query');
 
$q = $q->andWhereIn($a . '.' . $this->getColumn(), $values);
 
$objects = $q->execute();
...

Questo comportamento è giusto per il classico meccanismo di Doctrine di inserire un alias quando si esegue una query del tipo

1
2
3
$this->status_list = Doctrine::getTable('User')
    ->createQuery('a')
    ->execute();

ma non lo è quando si genera una query leggermente più complessa.

La soluzione di questo problema è molto semplice ma non così banale, almeno dal mio punto di vista. Basta infatti aggiungere al validatore l’opzione ‘alias’

1
$this->validatorSchema['users_list'] = new sfValidatorDoctrineChoiceMany(array('model' => 'User', 'alias' => '' ,'query' => $q));

Spero che questo appunto possa darvi una mano se mai vi troverete di fronte alla mia stessa situazione.

Buono “sviluppo” a tutti!