Creare un nuovo object_action eliminazione in generator Symfony 1.4 di
-
23-09-2019 - |
Domanda
Sto usando Symfony 1.4 / generator di Doctrine.
C'è un elenco di domande e mi piacerebbe essere in grado di eseguire un object_action personalizzato su ciascuno di loro.
Quello che sto cercando è quello di mimare l'azione oggetto _delete
ma facendo qualche calcolo prima.
Così ho creato una nuova azione:
public function executeListDeleteAndRecalculate(sfWebrequest $request)
{
// Do the calculation
// Then delete the question
}
E sto aggiungendolo al mio generator.yml:
object_actions:
delete_and_recalculate: ~
la nuova azione mostra nel generatore di amministrazione, ma la parte di eliminazione non funziona.
Ho provato un sacco di cose per farlo funzionare:
- Una volta che tutti i calcoli è stato fatto, in primo luogo ho cercato di riorientare l'azione
questionActions/delete
. - Ho provato anche a copiare il codice
executeDelete
alla mia nuova azione.
Ma ogni volta che ottengo il famigerato
500 | Internal Server Error | sfValidatorErrorSchema _csrf_token [Required.]
Quindi immagino Symfony sta facendo un po 'di magia prima di poter realmente eliminare un oggetto.
Sai cosa mi manca e qual è il modo migliore per attuare una sorta deleteAndRecalculate di azione?
Modifica
Naturalmente se rimuovere il tutto $request->checkCSRFProtection();
funziona bene. Ma suppongo che sia abbastanza importante quindi mi piacerebbe trovare una soluzione più bella.
Soluzione
Questo perché il collegamento delete
dal generatore di amministrazione usa un token per prevenire gli attacchi CSRF.
In sostanza, si stabilisce un gettone nella sessione e in un campo nascosto di una forma quindi controlla loro uno contro l'altro in merito alla richiesta. Questo è possibile perché il link delete
nel generatore di amministrazione è in realtà un (javascript generato) forma (questo è fatto per aggiungere un campo nascosto sf_method
per simulare il comportamento REST).
Per ulteriori informazioni su come funziona CSRF e può essere evitato, si può leggere più avanti Wikipedia: http://en.wikipedia.org/wiki/Cross-site_request_forgery
Che cosa si può fare è utilizzare lo stesso tipo di legame, devi solo passare un parametro method
per link_to
per per generare una forma, dare un'occhiata alla linea di lib/generator/sfModelGeneratorHelper.class.php
32 per vedere come è fatto nel admin-gen.
Si potrebbe quindi eseguire $request->checkCSRFProtection()
nel metodo executeDeleteAndRecalculate
, e procedere con quello che vuoi fare, tra cui l'eliminazione l'oggetto a mano.
Per generare correttamente il link, si dovrebbe aggiungere un metodo linkToDeleteAndRecalculate
nella classe Helper del modulo (che dovrebbe trovarsi nel file lib/${YourModule}GeneratorHelper.class.php
della directory modulo) e aggiungere il seguente codice (direttamente preso e adattato da sfModelGeneratorHelper
):
public function linkToDeleteAndRecalculate($object, $params)
{
if ($object->isNew())
{
return '';
}
return '<li class="sf_admin_action_delete">'.link_to(__($params['label'], array(), 'sf_admin'), 'delete_and_recalculate', $object, array('method' => 'delete', 'confirm' => !empty($params['confirm']) ? __($params['confirm'], array(), 'sf_admin') : $params['confirm'])).'</li>';
}
Si prega di notare che è necessario modificare il percorso (ho messo delete_and_recalculate
di default, ma si potrebbe desiderare di prefisso con il nome del modulo) dalla chiamata link_to
.
È possibile quindi utilizzare il delete_and_recalculate
quasi come un metodo integrato dal generator (e passarlo un'etichetta dal generator.yml
per esempio)
Ora che era l'hard-way.
Il modo più semplice sarebbe quella di sottoscrivere l'evento admin.delete_object
, dal modulo di pre-esecuzione per esempio, e per il vostro lavoro vi: -)