Usando symfony 1.2 e Doctrine 1.0 problemi con le equal nested relation

Non so se vi è mai capitato di avere a che fare con le cosiddette “equal nested relation”. Queste relazioni tra oggetti sono quelle relazioni che possono essere tradotte (per quanto riguarda il database) con un “auto join” su una stessa tabella.

Un esempio pratico lo potete trovare fra gli esempi del sito dell’ORM Doctrine : Equal Nested Relation.

In uno dei miei progetti (Symfony 1.2, Doctrine 1.0) ho dovuto usare un esempio analogo, ma invece che utenti collegati fra loro con una relazione molti a molti, dovevo collegare più ticket. Una volta messo tutto in piedi e creato le classi necessarie ho fatto qualche prova e mi è spuntato questo errore:

500 | Internal Server Error
Doctrine_Connection_Mysql_Exception SQLSTATE23000: Integrity constraint violation: 1062 Duplicate entry 'N-N' for key 1

Inizialmente ho cercato una soluzione che potesse dipendere dalle configurazioni del file schema.yml che usavo e poi soluzioni che potessero riguardare qualsiasi altra cosa. Dopo quasi due giorni a sbattere la testa su questo problema sono andato al PHPDay2009 a cui avrebbe partecipato anche Jonathan Wage, ovviamente ripromettendomi di chiedere direttamente a lui!!

Fortunatamente c’è stata occasione di parlargli e Jonathan è stato più che gentile tanto da aiutarmi e mettersi a provare a trovare una soluzione lì per lì per il mio problema. Dopo circa un’ora siamo arrivati a capire dov’era il problema. Poi a pezzi e bocconi siamo arrivati ad una soluzione nelle successive 24 ore!

La patch da utilizzare è scaricabile da qui. Ricordo che questa NON È UNA SOLUZIONE DEFINITIVA. E’ piuttosto un workaround al problema!! Un ticket relativo a questa soluzione è stato aperto qui.

Sembra che questo problema sia risolto utilizzando symfony 1.3 e doctrine 1.1, quindi aspettiamo con ansia la prossima uscita di symfony che include sfDoctinePlugin con doctrine 1.1!

Come utilizzare punti nelle URL

Quando in un progetto si utilizzano url contenenti punti, in una installazione standard di symfony, si otterrà dal server web un errore 404: questo perché verrà cercato dal server stesso un file piuttosto che ridirigere la richiesta al motore di routing di symfony.
Facciamo un esempio pratico:
routing.yml:
test:
url: /test/:title
param: { module: test, action: index }

/modules/test/templates/indexSuccess.php:
<?php echo $sf_params->get('title'); ?>

Ora se visitiamo la seguente url http://localhost/test/abc apparirà a video la scritta abc.
Se invece utilizziamo quest’altra url http://localhost/test/a.b.c il risultato sarà un errore 4040 “The requested URL /test/a.bc was not found on this server.”.

Per evitare questo comportamento si deve mettere mano al file .htaccess presente nella directory web del nostro progetto per un veloce hack, commentando la prima regola di rewriting in questo modo:

# we skip all files with .something
#RewriteCond %{REQUEST_URI} \..+$
#RewriteCond %{REQUEST_URI} !\.html$
#RewriteRule .* - [L]

In questa maniera ricaricando l’url http://localhost/test/a.b.c si otterrà nel browser il risultato voluto, cioè la stringa “a.b.c”

Confrontare due campi della stessa tabella con Propel

Con il criteria di Propel non è possibile ancora confrontare due campi della stessa tabella, ma solo il campo con un valore. Questa feature sarà probabilmente implementata nella versione 2.0.

Nel frattempo vi propongo questo trick per confrontare tra loro i campi Campo1 e Campo2 della tabella Tabella

1
2
3
$c = new Criteria();
 
$c->add(Tabella.Campo1, Tabella.Campo1.' = '.Tabella.Campo2, Criteria:CUSTOM);

Naturalmente al posto di “.’ = ‘ .” potere inserire l’operatore che vi serve (=, <>, !=, <, >, etc.)