symfony - 使用自定义策略限制某些使用 Sonata 的用户的操作
问题描述
当当前用户不是当前对象的所有者但确实具有用于编辑它的 ADMIN 角色时,我想使用表单删除一些操作,例如“DELETE”。
我想将此行为应用于列表(复选框)或编辑对象时。
我目前使用我在 Admin 类中使用的选民,例如:
protected function configureFormFields(FormMapper $formMapper){
if($this->isCurrentRoute('edit') && !$this->getConfigurationPool()->getContainer()->get('security.authorization_checker')->isGranted('edit', $this->getSubject()))
throw new AccessDeniedHttpException();
...
}
我用自己的逻辑检查的地方。但我不知道如何使用我的选民来删除删除操作。
我首先尝试使用自己的逻辑删除 configureRoutes 上的操作,但没有成功。另外,我读到由于缓存问题,这是一个糟糕的选择。
解决方案
我终于成功了,但我不确定这是最好的解决方案。
我使用我的选民来管理我自己的逻辑。在我的管理实体中,我覆盖了“编辑”模板。
class ProjectAdmin extends AbstractAdmin
{
...
public function getTemplate($name)
{
switch ($name) {
case 'edit':
return 'Sonata/ProjectAdmin/edit.html.twig';
break;
default:
return parent::getTemplate($name);
break;
}
}
...
}
我创建了我的模板templates/Sonata/ProjectAdmin/edit.html.twig
其中包含:
{% extends 'SonataAdminBundle:CRUD:base_edit.html.twig' %}
{% use 'SonataExtends/base_edit_form.html.twig' with form as parentForm %}
{% block form %}
{{ block('parentForm') }}
{% endblock %}
然后我复制/粘贴vendor/sonata-project/admin-bundle/src/Ressources/views/CRUD/base_edit_form.html.twig
到templates/SonataExtends/base_edit_form.html.twig
我更换了块:
{% if admin.hasRoute('delete') and admin.hasAccess('delete', object) %}
{{ 'delete_or'|trans({}, 'SonataAdminBundle') }}
<a class="btn btn-danger" href="{{ admin.generateObjectUrl('delete', object) }}">
<i class="fa fa-minus-circle" aria-hidden="true"></i> {{ 'link_delete'|trans({}, 'SonataAdminBundle') }}</a>
{% endif %}
打电话给我的选民:
{% if admin.hasRoute('delete') and is_granted('delete', object) %}
{{ 'delete_or'|trans({}, 'SonataAdminBundle') }}
<a class="btn btn-danger" href="{{ admin.generateObjectUrl('delete', object) }}">
<i class="fa fa-minus-circle" aria-hidden="true"></i> {{ 'link_delete'|trans({}, 'SonataAdminBundle') }}</a>
{% endif %}
唯一的区别is_granted('delete', object)
是admin.hasAccess('delete', object)
正如我所说,这可能不是最好的方法,所以谢谢你纠正我。但是我没有设法覆盖 admin.hasAccess('delete', object) 的逻辑。对于其他管理类,我只需要使用我的getTemplate
函数来使用这个逻辑。
PS:我还在我的管理类中添加了这段代码来管理删除操作:
public function preRemove($project){
if (false === $this->getConfigurationPool()->getContainer()->get('security.authorization_checker')->isGranted('delete', $project)) {
throw new AccessDeniedHttpException();
}
}
推荐阅读
- c - 在单个管道中进行多次读取和写入
- ruby - 如何将数据从另一个 ruby 文件添加到一个 ruby 文件
- c++ - 为什么 &(arr+1) 无法编译
- javascript - 直接从成员函数访问成员变量时,为什么会出现 ReferenceError?
- python - 如何从另一个类中为一个类的对象设置动画?
- node.js - 无法从 FileSaver/Blob 与 Node 的 fs 获得相同的结果
- shell - 提取txt文件的最后一个重复部分
- c# - Typeahead.js 调用 ASP.Net 核心 API
- c++ - 如何在 GDI+ 中使用 stock-objects
- ios - 是否可以为 iOS、模拟器和 * 和 * Mac 创建一个胖框架?