2016-10-17 16 views
0

私はIPアドレスとIP範囲を保存しているプロジェクトに取り組んでいます。現在、私のRangeエンティティは2つのIPアドレスエンティティ(ネットワークとブロードキャストエンティティ)への参照を持ち、ホストに対するOneToMany関係を持っています。 IPアドレスエンティティは、IP範囲に対するManyToOne関係を持ちます。これはオプションです。私は新しいIP範囲を作成するときにSymfony3永続生成エンティティ

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

    // relations to other tables 
    /** 
    * @var IPAddress 
    * @ORM\OneToOne(targetEntity="AppBundle\Entity\IPAddress", cascade={"persist", "remove"}, orphanRemoval=true) 
    * @ORM\JoinColumn(name="network", referencedColumnName="id", nullable=false) 
    */ 
    private $network; 
    /** 
    * @var IPAddress 
    * @ORM\OneToOne(targetEntity="AppBundle\Entity\IPAddress", cascade={"persist", "remove"}, orphanRemoval=true) 
    * @ORM\JoinColumn(name="broadcast", referencedColumnName="id", nullable=false) 
    */ 
    private $broadcast; 
    /** 
    * @var array 
    * @ORM\OneToMany(targetEntity="AppBundle\Entity\IPAddress", mappedBy="ipRangeId") 
    */ 
    private $hosts; 

    // entity variables 
    /** 
    * @var string 
    * @ORM\Column(name="description", type="string", length=50, nullable=false) 
    */ 
    private $description; 
    /** 
    * @var int 
    * @ORM\Column(name="cidr", type="smallint", nullable=false, options={"unsigned"=true}) 
    */ 
    private $cidr; 
    /** 
    * @var string 
    * @ORM\Column(name="notes", type="text", length=65535, nullable=true) 
    */ 
    private $notes; 

    // getters and setters not shown 
} 

私の現在の流れ:

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

    // relations to other tables 
    /** 
    * @var IPRange 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\IPRange", inversedBy="hosts", cascade={"persist", "remove"}) 
    * @ORM\JoinColumn(name="ip_range_id", referencedColumnName="id", nullable=true) 
    */ 
    private $ipRangeId; 

    // entity variables 
    /** 
    * @var mixed 
    * @ORM\Column(name="ip_address", type="binary", length=16, nullable=false, unique=true) 
    * @SIAssert\IpPacked(version="all") 
    */ 
    private $ipAddress; 
    /** 
    * @var string 
    * @ORM\Column(name="ip_address_text", type="string", length=50, nullable=false) 
    */ 
    private $ipAddressText; 
    /** 
    * @var int 
    * @ORM\Column(name="cidr", type="smallint", nullable=false, options={"unsigned"=true}) 
    */ 
    private $cidr; 
    /** 
    * @var mixed 
    * @ORM\Column(name="gateway", type="binary", length=16, nullable=false) 
    */ 
    private $gateway; 
    /** 
    * @var string 
    * @ORM\Column(name="gateway_text", type="string", length=50, nullable=false) 
    */ 
    private $gatewayText; 
    /** 
    * @var int 
    * @ORM\Column(name="type", type="smallint", options={"unsigned"=true}) 
    */ 
    private $type; 
    /** 
    * @var string 
    * @ORM\Column(name="description", type="string", length=50) 
    */ 
    private $description; 

    // getters and setters not shown 
} 

そして、私のIP範囲エンティティ:ここ

は、私のIPアドレスエンティティである

  • は、新たに生成しますIP範囲エンティティ(表示形式)
  • フォームから情報を取得
  • IP範囲エンティティの場合はnullを持つIPアドレスのエンティティ(ネットワークとブロードキャストIPアドレスエンティティが作成されていないため、IPアドレスの範囲は、まだ、永続化されません)
  • は私のIP範囲エンティティ
  • は、そのIDと書き換えを取得存続生成有効なIP範囲エンティティを持つ私のすべてのIPアドレスエンティティ

プログラムでエンティティを作成するには多くの手順が必要なので、私は何かを間違っているはずです。

これを行うには、より効率的な方法がありますか?編集

が...私のフォームタイプを追加...

マイIPRangeType:

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
     ->add('description', TextType::class, array(
      'required' => true, 
      'label' => 'Description:', 
      'label_attr' => array(
       'class' => 'text-right middle', 
      ), 
     )) 
     ->add('notes', TextareaType::class, array(
      'required' => false, 
      'label' => 'Notes:', 
      'label_attr' => array(
       'class' => 'text-right middle', 
      ), 
     )) 
     ->add('cidr', ChoiceType::class, array(
      'required' => true, 
      'multiple' => false, 
      'expanded' => false, 
      'choices' => array (
       'IPv4' => [ 
        '/30 (255.255.255.252)' => 30, 
        '/29 (255.255.255.248)' => 29, 
        '/28 (255.255.255.240)' => 28, 
        '/27 (255.255.255.224)' => 27, 
        '/26 (255.255.255.192)' => 26, 
        '/25 (255.255.255.128)' => 25, 
        '/24 (255.255.255.0)' => 24, 
        '/23 (255.255.254.0)' => 23, 
        '/22 (255.255.252.0)' => 22, 
        '/21 (255.255.248.0)' => 21, 
        '/20 (255.255.240.0)' => 20, 
       ], 
       'IPv6' => [ 
        '/64 network' => 64, 
       ] 
      ), 
      'label' => 'CIDR (subnet):', 
      'label_attr' => array(
       'class' => 'text-right middle', 
      ), 
     )) 
     ->add('network', IPAddressType::class, array(
      'required' => true, 
     )) 
     ->add('gateway_select', ChoiceType::class, array(
      'mapped' => false, 
      'required' => true, 
      'multiple' => false, 
      'expanded' => false, 
      'choices' => array (
       '- enter in valid IP and CIDR -' => 0, 
      ), 
      'label' => 'Gateway:', 
      'label_attr' => array(
       'class' => 'text-right middle', 
      ), 
     )) 
     ->add('json_data', HiddenType::class, array(
      'mapped' => false, 
     )) 
    ; 
} 

マイIPAddressType:

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
     ->add('ipAddress', TextType::class, array(
      'required' => true, 
      'label' => 'IP Address:', 
      'label_attr' => array(
       'class' => 'text-right middle', 
      ), 
     )) 
     ->add('cidr', ChoiceType::class, array(
      'required' => true, 
      'multiple' => false, 
      'expanded' => false, 
      'choices' => array (
       'IPv4' => [ 
        '/30 (255.255.255.252)' => 30, 
        '/29 (255.255.255.248)' => 29, 
        '/28 (255.255.255.240)' => 28, 
        '/27 (255.255.255.224)' => 27, 
        '/26 (255.255.255.192)' => 26, 
        '/25 (255.255.255.128)' => 25, 
        '/24 (255.255.255.0)' => 24, 
        '/23 (255.255.254.0)' => 23, 
        '/22 (255.255.252.0)' => 22, 
        '/21 (255.255.248.0)' => 21, 
        '/20 (255.255.240.0)' => 20, 
       ], 
       'IPv6' => [ 
        '/64 network' => 64, 
       ] 
      ), 
      'label' => 'CIDR (subnet):', 
      'label_attr' => array(
       'class' => 'text-right middle', 
      ), 
     )) 
     ->add('gateway', TextType::class, array(
      'required' => true, 
      'label' => 'Gateway:', 
      'label_attr' => array(
       'class' => 'text-right middle', 
      ), 
     )) 
     ->add('type', ChoiceType::class, array(
      'required' => true, 
      'multiple' => false, 
      'expanded' => false, 
      'choices' => IPAddress::TYPE, 
      'label' => 'Address Type:', 
      'label_attr' => array(
       'class' => 'text-right middle', 
      ), 
     )) 
     ->add('description', TextType::class, array(
      'required' => true, 
      'label' => 'Description:', 
      'label_attr' => array(
       'class' => 'text-right middle', 
      ), 
     )) 
    ; 

    $builder->get('ipAddress') 
     ->addModelTransformer(new IPToStringTransformer()); 

    $builder->get('gateway') 
     ->addModelTransformer(new IPToStringTransformer()); 
} 

答えて

0

は非常にラウンドアバウトを鳴らします。私は、一般的なアプローチとしてやってくれることをあなたに細かく説明します。

1つのIpAddressTypeともう1つのIpRangeTypeを呼び出す2つのフォームタイプを作成します。あなたはIpAddressで目的を共有しているので、1つのタイプだけが必要です。すべて同じデータです。

だから、次のようになりますあなたのフォームタイプ:

(これはsymfony 2.3の構文である - しかし、アプローチは同じである - そこにあなたが新しいバージョンを持っている場合、いくつかの違いになります)

class IpRangeType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('description'); 
     $builder->add('cidr'); // and other single fields 

     $builder->add('network', new IpAddressType()); 
     $builder->add('broadcast', new IpAddressType()); 
     $builder->add('hosts', 'collection', ['type' => new IpAddressType()]); 
    } 

    public function getName() 
    { 
     return 'ip_range'; 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'YourBundle\Entity\IpRange', 
     )); 
    } 
} 

サブフォームタイプ。次に、あなたのコントローラで

class IpAddressType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('ipAddress'); 
     $builder->add('ipAddressText'); // etc etc 
    } 

    public function getName() 
    { 
     return 'ip_address'; 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'YourBundle\Entity\IpAddress', 
     )); 
    } 
} 

$ipRange = new IpRange(); 
$em = $this->getDoctrine()->getManager(); 
$form = $this->createForm(new IpRangeType(), $ipRange); 
$form->handleRequest($request); 
if ($form->isValid()) { 
    $em->persist($ipRange); 
    $em->flush(); 
    return $this->redirect($this->generateUrl('your_success_route')); 
} 

それはシンプルでなければなりません。

注:IpRange $ hostsプロパティで少なくともcascade = persistを設定する必要があります。そうしないと、IpAddressアイテムがコレクションに追加されたままになりません。

ipAddressエンティティは、IpRangeネットワーク、ブロードキャスト、およびホストプロパティで個々のアイテムを永続化する必要がないため、カスケード永続性があるため、自動的に親エンティティに関連付けられます。

あなたのホストエントリを追加するために、このアプローチを実行する必要があります:

http://symfony.com/doc/current/form/form_collections.html

また、一般的にフォームのドキュメントを見てください、あなたがあれば実体「を生成」する必要はありませんフォームは正しく(非常に特別な場合を除いて)正しく行われます。

フォームが正しく実装されていると、フォームにデータが追加された完全なエンティティが返されます。&が有効であることを確認するだけです。ここではフォームの送信を処理するための

ドキュメント:私はホストの可変数に着いたとき、私はこれをやって考えられhttp://symfony.com/doc/current/forms.html#handling-form-submissions

+0

は、しかし、私は4096のたIPAddressエントリへのエンドユーザーまでを表示したくない実現しました。私は上記の私のタイプコードを追加し、私はIPAddressタイプとしてネットワークを持っています。 CollectionTypeを再訪して、それが役立つかどうかを確認します。 – profm2

関連する問題