Создайте новое действие delete object_action в генераторе администратора Symfony 1.4.
-
23-09-2019 - |
Вопрос
Я использую генератор администратора Symfony 1.4/Doctrine.
Есть список вопросов, и я хотел бы иметь возможность выполнять собственное object_action для каждого из них.
Я ищу, чтобы имитировать _delete
действие объекта, но перед этим выполнить некоторые вычисления.
Итак, я создал новое действие:
public function executeListDeleteAndRecalculate(sfWebrequest $request)
{
// Do the calculation
// Then delete the question
}
И я добавляю его в свой генератор.yml:
object_actions:
delete_and_recalculate: ~
новое действие отображается в генераторе администратора, но часть удаления не работает.
Я попробовал кучу вещей, чтобы заставить это работать:
- После того, как все расчеты были выполнены, я сначала попытался перенаправить на
questionActions/delete
действие. - Я также пытался скопировать
executeDelete
код для моего нового действия.
Но каждый раз, когда я получаю позорную
500 | Внутренняя ошибка сервера | sfvalidatorerrorschema _csrf_token [требуется.
Итак, я предполагаю, что Symfony творит какое-то волшебство, прежде чем фактически удалить объект.
Знаешь, чего мне не хватает и как лучше всего реализовать действие типа deleteAndRecalculate?
Редактировать:
Конечно, если я удалю $request->checkCSRFProtection();
все работает нормально.Но я предполагаю, что это очень важно, поэтому я хотел бы найти более красивое решение.
Решение
Это потому, что delete
ссылка из генератора администратора использует токен для предотвращения атак CSRF.
По сути, он устанавливает токен в ваш сеанс и в скрытое поле формы, а затем сравнивает их друг с другом по запросу.Это возможно, поскольку delete
Ссылка в генераторе администратора на самом деле представляет собой форму (сгенерированную Javascript) (это сделано для добавления sf_method
скрытое поле для имитации поведения REST).
Для получения дополнительной информации о том, как работает CSRF и как его можно предотвратить, вы можете прочитать далее в Википедии: http://en.wikipedia.org/wiki/Cross-site_request_forgery
Что вы можете сделать, так это использовать ссылку того же типа, вам просто нужно передать method
параметр для link_to
чтобы он сгенерировал форму, посмотрите lib/generator/sfModelGeneratorHelper.class.php
строку 32, чтобы увидеть, как это делается в admin-gen.
Затем вы выполните $request->checkCSRFProtection()
в вашей executeDeleteAndRecalculate
метод и продолжайте делать все, что хотите, включая удаление объекта вручную.
Чтобы правильно сгенерировать ссылку, вы должны добавить linkToDeleteAndRecalculate
в классе Helper вашего модуля (который должен находиться в lib/${YourModule}GeneratorHelper.class.php
файл в каталоге вашего модуля) и добавьте следующий код (взятый и адаптированный непосредственно из 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>';
}
Обратите внимание, что вам придется изменить маршрут (я поставил delete_and_recalculate
по умолчанию, но вы можете добавить к нему префикс имени вашего модуля) из link_to
вызов.
Затем вы можете использовать свой delete_and_recalculate
почти как встроенный метод из генератора администратора (и передать ему метку из generator.yml
например)
Это был трудный путь.
Самый простой способ — подписаться на admin.delete_object
событие, например, из предварительного выполнения вашего модуля и к вашей работе там :-)