Créez une nouvelle action_objet de suppression dans le générateur d'administration de Symfony 1.4
-
23-09-2019 - |
Question
J'utilise le générateur d'administration de Symfony 1.4/Doctrine.
Il y a une liste de questions et j'aimerais pouvoir effectuer une object_action personnalisée sur chacune d'elles.
Ce que je cherche, c'est d'imiter le _delete
action de l'objet mais en faisant quelques calculs avant cela.
J'ai donc créé une nouvelle action :
public function executeListDeleteAndRecalculate(sfWebrequest $request)
{
// Do the calculation
// Then delete the question
}
Et je l'ajoute à mon générateur.yml :
object_actions:
delete_and_recalculate: ~
la nouvelle action s'affiche dans le générateur d'administration mais la partie suppression ne fonctionne pas.
J'ai essayé pas mal de choses pour que ça marche :
- Une fois tous les calculs effectués, j'ai d'abord essayé de rediriger vers le
questionActions/delete
action. - J'ai aussi essayé de copier le
executeDelete
codez ma nouvelle action.
Mais chaque fois que je reçois le fameux
500 | Erreur interne du serveur | sfValidatorErrorSchema _csrf_token [Obligatoire.]
Je suppose donc que Symfony fait de la magie avant de supprimer un objet.
Sais-tu ce qui me manque et quelle est la meilleure façon d’implémenter une action de type deleteAndRecalculate ?
Modifier:
Bien sûr, si je supprime le $request->checkCSRFProtection();
tout fonctionne très bien.Mais je suppose que c'est assez important donc j'aimerais trouver une solution plus jolie.
La solution
C'est parce que le delete
Le lien du générateur d'administrateur utilise un jeton pour empêcher les attaques CSRF.
Fondamentalement, il définit un jeton dans votre session et dans un champ caché d'un formulaire, puis les vérifie les uns par rapport aux autres lors de la demande.Ceci est possible parce que le delete
Le lien dans le générateur d'administration est en fait un formulaire (généré par javascript) (ceci est fait pour ajouter un sf_method
champ caché pour simuler le comportement REST).
Pour plus d'informations sur le fonctionnement du CSRF et sur ses possibilités de prévention, vous pouvez lire plus loin sur Wikipédia : http://en.wikipedia.org/wiki/Cross-site_request_forgery
Ce que vous pouvez faire, c'est utiliser le même type de lien, il vous suffit de passer un method
paramètre à link_to
pour qu'il génère un formulaire, jetez un oeil à lib/generator/sfModelGeneratorHelper.class.php
ligne 32 pour voir comment cela se fait dans le fichier admin-gen.
Vous exécuteriez alors $request->checkCSRFProtection()
dans ton executeDeleteAndRecalculate
et procédez à ce que vous voulez faire, y compris la suppression manuelle de l'objet.
Pour générer correctement le lien, vous ajouteriez un linkToDeleteAndRecalculate
méthode dans la classe Helper de votre module (qui doit se trouver dans la lib/${YourModule}GeneratorHelper.class.php
fichier de votre répertoire de module) et ajoutez le code suivant (directement repris et adapté de 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>';
}
Attention, il faut changer d'itinéraire (j'ai mis delete_and_recalculate
par défaut mais vous souhaiterez peut-être le préfixer avec le nom de votre module) à partir du link_to
appel.
Vous pourrez alors utiliser votre delete_and_recalculate
presque comme une méthode intégrée du générateur d'administration (et transmettez-lui une étiquette du generator.yml
Par exemple)
Maintenant, c'était la voie la plus difficile.
Le plus simple serait de s'abonner au admin.delete_object
événement, depuis la pré-exécution de votre module par exemple, et vers votre travail là-bas :-)