【问题标题】:Create a new delete object_action in Symfony 1.4's admin generator在 Symfony 1.4 的管理生成器中创建一个新的 delete object_action
【发布时间】:2011-01-10 08:45:04
【问题描述】:

我正在使用 Symfony 1.4/Doctrine 的管理生成器。

有一个问题列表,我希望能够对每个问题执行自定义 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(); 一切正常。但我认为这很重要,所以我想找到一个更漂亮的解决方案。

【问题讨论】:

    标签: symfony1 symfony-1.4 admin-generator


    【解决方案1】:

    这是因为来自管理员生成器的 delete 链接使用令牌来防止 CSRF 攻击。

    基本上,它会在您的会话和表单的隐藏字段中设置一个令牌,然后根据请求将它们相互检查。这是可能的,因为管理生成器中的 delete 链接实际上是一个(javascript 生成的)表单(这样做是为了添加一个 sf_method 隐藏字段来模拟 REST 行为)。

    有关 CSRF 如何工作以及如何预防的更多信息,您可以在 Wikipedia 上进一步阅读:http://en.wikipedia.org/wiki/Cross-site_request_forgery

    您可以使用相同的链接,只需将method 参数传递给link_to 即可生成表单,请查看lib/generator/sfModelGeneratorHelper.class.php 第32 行了解它是如何完成的在 admin-gen 中。

    然后您将在您的executeDeleteAndRecalculate 方法中执行$request->checkCSRFProtection(),然后继续您想做的任何事情,包括手动删除对象。

    要正确生成链接,您需要在模块的 Helper 类中添加一个 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>';
    }
    

    请注意,您必须从 link_to 调用更改路由(我已默认设置 delete_and_recalculate,但您可能希望在其前面加上您的模块名称)。

    然后您可以使用您的 delete_and_recalculate,几乎就像管理生成器中的内置方法一样(例如,将来自 generator.yml 的标签传递给它)

    现在这很难。

    简单的方法是订阅admin.delete_object 事件,例如,从您的模块的预执行中订阅您的工作:-)

    【讨论】:

    • 感谢您的回答。但是,即使我尝试复制 linkToDelete 创建链接的方式,我也无法生成创建表单的 onclick javascript 事件。而且我也找不到 _delete 对象操作在哪里完成。关于“简单方法”:我认为这行不通,因为我也想保留默认的“删除”操作。
    • 好的,我已经用如何生成链接的说明编辑了我的答案,这有帮助吗?
    • 我快到了,在我点击链接之前一切似乎都正常。我不知道我在 backend/config/routing.yml 中写的路线有什么问题(见这里:pastie.org/798862)。但我得到一个 404 “操作“supprimer_et_recalculer/33”不存在。”
    • 你的 routing.yml 中是否还有默认的 /:module/:action 路由?如果是,并且如果它在您的自定义路由之前,那么 symfony 将优先匹配它。如果没有,那么完整的跟踪可能会有所帮助,我猜你的完整 routing.yml 也是如此:-)
    猜你喜欢
    • 2011-06-21
    • 1970-01-01
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 2011-09-01
    相关资源
    最近更新 更多