代码之家  ›  专栏  ›  技术社区  ›  Guillaume Flandre

在symfony 1.4的管理生成器中创建新的删除对象操作

  •  3
  • Guillaume Flandre  · 技术社区  · 15 年前

    我正在使用symfony 1.4/district的管理生成器。

    这里有一个问题列表,我希望能够对每个问题执行自定义对象操作。

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

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

      public function executeListDeleteAndRecalculate(sfWebrequest $request)
      {
        // Do the calculation
    
        // Then delete the question
      }
    

    我把它添加到生成器中。

    object_actions:
        delete_and_recalculate: ~
    

    新操作将显示在管理生成器中,但删除部分不起作用。

    我尝试了很多方法来让它工作:

    • 当所有计算完成后,我首先尝试重定向到 questionActions/delete 行动。
    • 我还试图复制 executeDelete 我的新动作代码。

    但每次我得到臭名昭著的

    500内部服务器错误| sfvalidatorrorschema验证错误 _ csrf_代币[必需]

    所以我猜symfony在删除一个对象之前会做一些魔术。

    你知道我错过了什么吗? 实现Delete和Calculate类型操作的最佳方法是什么?

    编辑:

    当然,如果我把 $request->checkCSRFProtection(); 一切正常。但我认为这很重要,所以我想找到一个更漂亮的解决方案。

    1 回复  |  直到 15 年前
        1
  •  4
  •   Geoffrey Bachelet    15 年前

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

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

    有关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 默认情况下,但您可能希望在其前面加上模块的名称)来自 林克托 打电话。

    你可以用你的 删除并重新计算 类似于管理生成器中的内置方法(并将标签从 generator.yml 例如)

    现在这是一条艰难的路。

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

    推荐文章