2016-10-17 5 views
0

Я работаю над проектом, сохраняющим IP-адреса и IP-диапазоны. В настоящее время мой объект Range имеет ссылки на два объекта IP-адреса (сетевые и широковещательные объекты) и имеет отношение OneToMany к хостам. Объект IP-адреса имеет отношение ManyToOne к диапазону IP, что необязательно.Symfony3 сохраняющиеся сгенерированные объекты

Вот мой IP-адрес объект:

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 объект Range:

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 
} 

Мой текущий поток, когда я создаю новый IP диапазон:

  • генерировать новый Объект диапазона IP (форма отображения)
  • получить информацию из формы
  • генерирует IP-объекты Адресных с нулем для объекта IP Range (Диапазон IP еще не сохранены, поскольку сеть и широковещательных IP-объекты адресов не созданы)
  • сохраняются моего IP-объекта
  • Range получить этот идентификатор и рерайт все мои объекты 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

Звуки очень карусель. Я подробно расскажу вам, что я буду делать в качестве общего подхода.

Я бы создал два типа форм, вызывая один тип IpAddressType и другой IpRangeType. Поскольку вы используете общие цели в IpAddress, вам нужен только один тип, это все те же данные.

Так ваш тип форма будет выглядеть примерно так:

(это 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')); 
} 

Это должно быть просто.

Примечание: вам нужно будет установить не менее cascade = persist на свойство IpRange $ hosts, иначе оно не будет сохраняться в элементах IpAddress, добавленных в коллекцию.

Из-за того, что каскады сохраняются в сетях IpRange, вещании и хостах, вам не нужно сохранять отдельные элементы, объекты ipAddress будут автоматически связаны с родительским объектом.

Вам нужно будет следовать этому подходу для добавления записи узлов:

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

Также, пожалуйста, посмотрите на документацию формы в целом, вы никогда не должны должны «генерировать» объект, если форма выполнена правильно (за исключением особых случаев).

Правильно внедренная форма должна возвращать ваши полные сущности с данными, добавленными в форму, и все, что вам нужно сделать, это подтвердить & persist.

Docs для обработки формы представления здесь: http://symfony.com/doc/current/forms.html#handling-form-submissions

+0

Я считал это делать, однако, когда я попал в переменном число хостов, я понял, что я не хочу, чтобы показать конечный пользователь до 4096 Ipaddress записей. Я добавил свой код типа выше, и у меня есть сеть как тип IPAddress. Я вернусь к CollectionType, чтобы узнать, поможет ли это. – profm2

Смежные вопросы