2017-11-16 21 views
2

私はSF 3.3プロジェクトでEasyAdminを使用していますが、EasyAdminの構築方法とは異なる何かを達成する必要があります。あなたはユーザーが複数のGroupingRoleにすることができ気づくかもしれませんがオーバーライドメソッドまたはEventListener:作成プロセスを停止し、EasyAdminで初めて警告を表示しますか?

enter image description here

次の絵を見てみましょう。その情報に挑戦を持つことである:

  • チェックユーザーは基準が条件を満たしている場合は、「ユーザAがすでにGroupingRole Aに割り当てられている」という警告メッセージを表示し、他のGroupingRole
  • に割り当てられている場合レコードが作成されないようにします。 (このメッセージは、ポップアップ、javascriptアラート、またはBootstrapからの警告である可能性があります(EAは既にそれを使用しているため)
  • 「変更を保存」をもう一度クリックすると、レコードが作成されます。私はこのアプローチで達成したい何

は、ユーザーが他のグループにすでにあるが、彼を止めるためのレコードを作成していない管理者に警告することです。私にはわからない何

class AdminController extends BaseAdminController 
{ 
    /** 
    * Check if the users has been assigned to any group 
    */ 
    protected function prePersistGroupingRoleEntity($entity) 
    { 
     $usersToGroupRoleEntities = $this->em->getRepository('CommonBundle:UsersToGroupRole')->findAll(); 
     $usersToGroupRole   = []; 

     /** @var UsersToGroupRole $groupRole */ 
     foreach ($usersToGroupRoleEntities as $groupRole) { 
      $usersToGroupRole[$groupRole->getGroupingRoleId()][] = $groupRole->getUsersId(); 
     } 

     $usersInGroup = []; 

     /** @var Users $userEntity */ 
     foreach ($entity->getUsersInGroup() as $userEntity) { 
      foreach ($usersToGroupRole as $group => $users) { 
       if (\in_array($userEntity->getId(), $users, true)) { 
        $usersInGroup[$group][] = $userEntity->getId(); 
       } 
      } 
     } 

     $groupingRoleEnt = $this->em->getRepository('CommonBundle:GroupingRole'); 
     $usersEnt  = $this->em->getRepository('CommonBundle:Users'); 

     $message = []; 
     foreach ($usersInGroup as $group => $user) { 
      foreach($user as $usr) { 
       $message[] = sprintf(
        'The user %s already exists in %s group!', 
        $usersEnt->find($usr)->getEmail(), 
        $groupingRoleEnt->find($group)->getName() 
       ); 
      } 
     } 
    } 
} 

は、レコードが作成され、代わりにするために停止する方法である:

は、私はちょうどそのエンティティのprePersistメソッドをオーバーライドすることにより、(下記参照)、すでにそれの一部を達成してい2回目のボタンをクリックして初めて警告が表示され、警告が表示されるので、レコードを作成できるようにする必要があります。

私にいくつかのアイデアや提案がありますか?

UPDATE:ここで上に表示されたコードに加えて、エンティティ情報

を追加するようなプロセスに関与するエンティティである。

/** 
* @ORM\Entity 
* @ORM\Table(name="grouping_role") 
*/ 
class GroupingRole 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(name="id", type="integer",unique=true,nullable=false) 
    * @ORM\GeneratedValue 
    */ 
    private $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="role_name", type="string", nullable=false) 
    */ 
    private $name; 

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

    /** 
    * @var ArrayCollection 
    * 
    * @ORM\ManyToMany(targetEntity="Schneider\QuoteBundle\Entity\Distributor", inversedBy="groupingRole") 
    * @ORM\JoinTable(name="grouping_to_role", 
    * joinColumns={ 
    *  @ORM\JoinColumn(name="grouping_role_id", referencedColumnName="id") 
    * }, 
    * inverseJoinColumns={ 
    *  @ORM\JoinColumn(name="DistributorID", referencedColumnName="DistributorID", nullable=false) 
    * } 
    *) 
    * 
    * @Assert\Count(
    *  min = 1, 
    *  minMessage = "You must select at least one Distributor" 
    *) 
    */ 
    private $distributorGroup; 

    /** 
    * @var ArrayCollection 
    * 
    * @ORM\ManyToMany(targetEntity="CommonBundle\Entity\Users", inversedBy="usersGroup") 
    * @ORM\JoinTable(name="users_to_group_role", 
    * joinColumns={ 
    *  @ORM\JoinColumn(name="grouping_role_id", referencedColumnName="id") 
    * }, 
    * inverseJoinColumns={ 
    *  @ORM\JoinColumn(name="users_id", referencedColumnName="users_id", nullable=false) 
    * } 
    *) 
    * 
    * @Assert\Count(
    *  min = 1, 
    *  minMessage = "You must select at least one user" 
    *) 
    */ 
    private $usersInGroup; 

    /** 
    * Constructor 
    */ 
    public function __construct() 
    { 
     $this->distributorGroup = new ArrayCollection(); 
     $this->usersInGroup  = new ArrayCollection(); 
    } 
} 

/** 
* @ORM\Entity() 
* @ORM\Table(name="users_to_group_role") 
*/ 
class UsersToGroupRole 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Id() 
    * @ORM\Column(type="integer",nullable=false) 
    * @Assert\Type(type="integer") 
    * @Assert\NotNull() 
    */ 
    protected $usersId; 

    /** 
    * @var int 
    * 
    * @ORM\Id() 
    * @ORM\Column(type="integer", nullable=false) 
    * @Assert\Type(type="integer") 
    * @Assert\NotNull() 
    */ 
    protected $groupingRoleId; 
} 
+0

'prePersist'の代わりにフォーム検証を使うのはどうですか?条件付きで進行を防ぐことができます。 – yceruto

+0

@ycerutoこれに関する例がありますか?私は一見とアイデアを取ることができる何か? – ReynierPM

+0

この場合、2回目のクリック後に許可したいので、検証制約のようには聞こえません...ロジックを処理する専用ルートを作成することをお勧めします。次に、フォームの隣にメッセージを表示するには、ajaxで呼び出します。 –

答えて

2

EasyAdminBundleにフォーム検証アプローチを使用して少し例:

class AdminController extends EasyAdminController 
{ 
    // ... 

    protected function create<EntityName>EntityFormBuilder($entity, $view) 
    { 
     $builder = parent::createEntityFormBuilder($entity, $view); 

     $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) { 
      $data = $event->getData(); 

      $flag = false; 
      if (isset($data['flag'])) { 
       $flag = $data['flag']; 
       unset($data['flag']); 
      } 
      $key = md5(json_encode($data)); 

      if ($flag !== $key) { 
       $event->getForm()->add('flag', HiddenType::class, ['mapped' => false]); 
       $data['flag'] = $key; 
       $event->setData($data); 
      } 
     }); 

     return $builder; 
    } 

    protected function get<EntityName>EntityFormOptions($entity, $view) 
    { 
     $options = parent::getEntityFormOptions($entity, $view); 

     $options['validation_groups'] = function (FormInterface $form) { 
      if ($form->has('flag')) { 
       return ['Default', 'CheckUserGroup']; 
      } 

      return ['Default']; 
     }; 

     $options['constraints'] = new Callback([ 
      'callback' => function($entity, ExecutionContextInterface $context) { 
       // validate here and adds the violation if applicable. 

       $context->buildViolation('Warning!') 
        ->atPath('<field>') 
        ->addViolation(); 
      }, 
      'groups' => 'CheckUserGroup', 
     ]); 

     return $options; 
    } 
} 

PRE_SUBMITイベントが検証前にトリガーされることに注意してくださいプロセスが起こる。

flagフィールドはフォームの送信時に最初に追加されるため、検証グループCheckUserGroupが追加され、コールバック制約がそのジョブを実行します。後で、提出されたデータにflagハッシュが含まれている場合(データが変更されない場合)、flagフィールドは追加されないため、検証グループは追加されず、エンティティも保存されます最初の違反)。

また、ターゲットエンティティのカスタムフォームタイプ内でこれをすべて実行することもできます。

+0

これは魅力的なように動作していますが、私は "ユーザーは 'u1'と' u2'をクリックして保存し、バリデーションのトリガーをクリックして別のグループに存在すると言いますが、その後 'u3'を追加して保存をクリックするとフラグが既にセットされているのでこの回避策をスキップしてください。 – ReynierPM

+2

まあ、最初にデータを送信したハッシュキーのようにフラグフィールドに情報を追加することができます。次回データが変更されたときにフラグフィールドが一致するまで(データ変更なし)スキップされ、検証も行われます。 – yceruto

+0

更新された回答を参照してください。 – yceruto

関連する問題