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.

È stato utile?

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: -)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top