2010-01-28 47 views
3

我正在使用Symfony 1.4/Doctrine的管理生成器。在Symfony 1.4的管理生成器中创建一个新的删除object_action

有一个问题的列表,我希望能够在他们每个人上执行自定义object_action。

我在找的是模仿_delete对象操作,但在此之前做一些计算。

所以我创建了一个新的动作:

public function executeListDeleteAndRecalculate(sfWebrequest $request) 
    { 
    // Do the calculation 

    // Then delete the question 
    } 

而且我将它添加到我的generator.yml:

object_actions: 
    delete_and_recalculate: ~ 

新的动作显示在管理发电机,但删除部分没有按没有工作。

我尝试了一堆东西,使其工作:

  • 一旦所有的计算是这样做,我第一次尝试重定向到questionActions/delete行动。
  • 我也尝试将executeDelete代码复制到我的新操作中。

但每次我得到的臭名昭著的

500 |内部服务器错误| sfValidatorErrorSchema _csrf_token [必需]

所以我猜的Symfony实际上是删除对象之前做一些魔法。

你知道我在想什么吗?实现deleteAndRecalculate类型的动作的最佳方式是什么?

编辑:

当然,如果我删除$request->checkCSRFProtection();一切工作就好了。但我认为这很重要,所以我想找一个更漂亮的解决方案。

回答

4

这是因为来自管理生成器的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中完成的。

这样,你会在你的executeDeleteAndRecalculate方法执行$request->checkCSRFProtection(),并且与任何你想做的事,包括手工删除对象进行。

要正确生成的链接,你会在辅助类的模块添加linkToDeleteAndRecalculate方法(即应当处于在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事件,从你的模块的预执行,例如,和你的工作有:-)

+0

谢谢您的回答。 但是,即使我尝试复制linkToDelete创建链接的方式,我无法生成创建窗体的onclick javascript事件。而且我也无法找到它为_delete对象操作完成的地方。 关于“简单的方法”:我不认为这将工作,因为我想保持默认的“删除”行为。 – 2010-01-28 14:28:01

+0

好的,我已经编辑了我的答案,指导如何生成链接,这有帮助吗? – 2010-01-28 14:49:24

+0

我几乎在那里,一切似乎都没事,直到我点击链接。我不知道我在后端/ config/routing.yml中写的路线有什么问题(请参阅http://pastie.org/798862)。但是我得到一个404“Action”supprimer_et_recalculer/33“不存在。” – 2010-01-28 15:27:51

相关问题