2014-01-09 19 views
-1

這裏就是我試圖完成:如何過濾形式的實體將選擇基於ACL的

我有一個簡單的應用程序,管理產品和類別的實體。這些CRUD由SonataAdmin管理。

我的Product實體與Category實體(多對一關聯)相關聯。我想要的是,當Sonata的CRUD顯示創建產品的表單時,在類別選擇中,它只列出用戶擁有EDIT訪問控制條目的類別。

下面是一些代碼來說明這一點:

Product實體

<?php 

namespace Acme\DemoBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 

/** 
* Product 
* 
* @ORM\Table() 
* @ORM\Entity 
* @ORM\HasLifecycleCallbacks() 
*/ 
class Product 
{ 

    /** 
    * @var integer id 
    * 
    * @ORM\Id 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="name", type="string", length=255) 
    */ 
    private $name; 

    /** 
    * @var float 
    * 
    * @ORM\Column(name="price", type="float") 
    */ 
    private $price; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="description", type="text") 
    */ 
    private $description; 

    /** 
    * @ORM\ManyToOne(targetEntity="Category", inversedBy="products") 
    * @ORM\JoinColumn(name="category_id", referencedColumnName="id") 
    */ 
    protected $category; 

    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /*Getters and setters 
    ... 
    */ 
} 

Category實體

<?php 

namespace Acme\DemoBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Doctrine\Common\Collections\ArrayCollection; 

/** 
* Category 
* 
* @ORM\Table() 
* @ORM\Entity 
*/ 
class Category 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Id 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="name", type="string", length=255) 
    */ 
    private $name; 

    /** 
    * @ORM\OneToMany(targetEntity="Product", mappedBy="category") 
    */ 
    protected $products; 

    public function __construct() 
    { 
     $this->products = new ArrayCollection(); 
    } 

    /*Getters and setters 
    ... 
    */ 
} 

ProductAdmin索納塔CRUD

<?php 

namespace Acme\DemoBundle\Admin; 

use Symfony\Component\Security\Acl\Domain\ObjectIdentity; 
use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity; 
use Symfony\Component\Security\Acl\Permission\MaskBuilder; 

use Sonata\AdminBundle\Admin\Admin; 
use Sonata\AdminBundle\Datagrid\ListMapper; 
use Sonata\AdminBundle\Datagrid\DatagridMapper; 
use Sonata\AdminBundle\Form\FormMapper; 

class ProductAdmin extends Admin 
{ 

    // Fields to be shown on create/edit forms 
    protected function configureFormFields(FormMapper $formMapper) 
    { 
     $formMapper 
      ->add('name', 'text', array('label' => 'Product name')) 

      // HOWTO FILTER THESE ??? 
      ->add('category', 'entity', array('class' => 'Acme\DemoBundle\Entity\Category')) 

      ->add('price') 
      ->add('description') 
     ; 
    } 

    /* More here, but kept short for the example 
    ... 
    */ 

} 

我想是在ProductAdmin::configureFormFields whithin調用檢查ACL來->add('category', 'entity', array('class' => 'Acme\DemoBundle\Entity\Category'))

任何幫助非常感謝的一種方式。 FL。

回答

1

解決方案將過濾您的實體列表與您的字段query_builder選項(doc is here),但我不確定如何創建一個查詢生成器ACL過濾。

另一個(?更好的)解決方案,我看到的是:

  1. 申報表單服務(doc
  2. 注入的安全上下文的依賴與任何其他的Dependance需要
  3. 請求列表Category你想要在你的表格中使用注入服務
  4. 用實體字段的choices選項設置你的表格類別,將它的Category列表作爲數組(doc

作品是否應...

+0

依賴注入的解決方案似乎是很好的,但我還有最後一個問題(接受答案之前)。在編輯表單的情況下,我需要能夠根據編輯對象的ACL禁用某些字段。 (例如,只有當用戶作爲該類別的「編輯」權限時才允許更改產品類別)。這將需要訪問Admin :: getForm調用中的編輯對象,這在奏鳴曲的Admin類中似乎不是這種情況。任何想法 ? –

+1

好吧,我發現他適合我的需求:它被稱爲FormEventSubscriber:http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html –

0

我在寫這個答案只是爲了讓F.L. commentmaphe answer站起來,因爲這是他自己的問題的解決,對我有很大的幫助。

symfony的食譜有記錄的答案: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html

該文件描述瞭如何解決在需要動態表單許多常見問題。我在此引用文檔的介紹:

很多時候,表單不能靜態創建。在這個條目中,你會 學習如何基於三個常見的用例來定製您的形式:

  1. 自定義表單基於底層數據

    例如:您有一個「產品」的形式並且需要根據正在編輯的基礎產品的數據來修改/添加/刪除 字段。

  2. 如何基於用戶數據

    實例可以動態生成表單:您創建一個「好友留言」的形式,並需要建立一個 下拉僅包含那些朋友與當前 身份驗證的用戶的用戶。

  3. 動態生成用於提交的表單

    實施例:一個登記表上,則有應填充動態基於在 「國家」字段中的值是「國家」字段和 「狀態」字段。

相關問題