2016-05-03 12 views
6

मेरे पास एक इकाई Product है। मेरे उत्पाद में विभिन्न भाषाओं में कई नाम हो सकते हैं। फ्रेंच में एक नाम, अंग्रेजी में एक नाम, आदि। मैं एक स्वचालित अनुवाद का उपयोग नहीं करना चाहता।Symfony3: ऑब्जेक्ट्स की सरणी से भरा विकल्प प्रकार फ़ील्ड

उपयोगकर्ता को उत्पाद फ़ॉर्म में नाम लिखना होगा और इसी भाषा का चयन करना होगा। वह बहुत सारे नाम जोड़ सकता है क्योंकि वह एक ऐड बटन के लिए धन्यवाद चाहता है।

सभी भाषाएं व्यवस्थापक उपयोगकर्ता (किसी अन्य रूप में) द्वारा बनाई गई हैं। तो, Language भी एक संस्था है जिसका नाम (पूर्व: अंग्रेजी) और एक कोड (पूर्व: एन) है।

मैंने एंटिटी ProductName बनाया है जिसमें एक नाम और एक भाषा है (जो उत्पाद के रूप में उपयोगकर्ता लिखता है)।

उस स्थिति में, मुझे इकाई ProductName एंटिटी Language के साथ संबद्ध करने की आवश्यकता नहीं है। मुझे बस भाषा कोड चाहिए।

/** 
* @ORM\Column(name="Language_Code", type="string", length=2) 
*/ 
private $language; 

मेरे उत्पाद फार्म (ProductType) कई नाम जोड़ने के लिए एक CollectionType क्षेत्र है: तो, मेरी ProductName इकाई में, मैं इस संपत्ति है।

// Form/ProductType.php 

    ->add('infos',  CollectionType::class, array(
     'entry_type' => ProductInfosType::class, 
     'allow_add'  => true, 
     'allow_delete' => true, 
     'prototype'  => true, 
     'label'   => false, 
     'mapped'  => false 
    )) 

और ProductInfosType प्रपत्र 2 फ़ील्ड होते हैं:

// Form/ProductInfosType.php 

     ->add('name',   TextType::class, array(
      'attr'    => array('size' => 40) 
     )) 
     ->add('language',  EntityType::class, array(
      'placeholder'  => '', 
      'class'    => 'AppBundle:Language', 
      'choice_label'  => 'code', 
      'attr'    => array('class' => 'lang'), 
      'query_builder'  => function (EntityRepository $er) { 
       return $er->createQueryBuilder('l')->orderBy('l.code', 'ASC'); 
      } 
     )) 

तो, जब मैं अपने प्रपत्र पृष्ठ पर जाओ, मैं एक ब्लॉक है जो एक इनपुट पाठ फ़ील्ड (नाम) और कुछ चुने हुए क्षेत्र शामिल है (भाषा)। चुनिंदा क्षेत्र इस तरह है:

<select id="product_infos_0_language" required="required" name="product[infos][0][language]"> 
    <option value=""></option> 
    <option value="DE">DE</option> 
    <option value="EN">EN</option> 
    <option value="ES">ES</option> 
    <option selected="selected" value="FR">FR</option> 
</select> 

इस बिंदु पर, सब कुछ अच्छी तरह से काम करता है। मैंने एक एड बटन बनाया है ताकि उपयोगकर्ता अन्य नाम, आदि ...

पर, लेकिन जब मैं फॉर्म सबमिट करता हूं, जब मैं अपने उत्पाद नियंत्रक में फॉर्म डेटा जांचता हूं, तो मैंने देखा कि यह मेरे अनुरूप नहीं है। डेटाबेस में स्टोर करना चाहते हैं।

print_r($form->get('infos')->getData()); 

// returns : 
Array 
(
    [0] => AppBundle\Entity\ProductName Object 
     ( 
      [language:AppBundle\Entity\ProductName:private] => AppBundle\Entity\Language Object 
       (
        [code:AppBundle\Entity\Language:private] => FR 
        [name:AppBundle\Entity\Language:private] => Français 
       ) 

      [name:AppBundle\Entity\ProductName:private] => Ceinture lombaire LombaSkin 
     ) 
) 

क्या मैं चाहते हैं:

Array 
(
    [0] => AppBundle\Entity\ProductName Object 
     ( 
      [language:AppBundle\Entity\ProductName:private] => FR  
      [name:AppBundle\Entity\ProductName:private] => Ceinture lombaire LombaSkin 
     ) 
) 

मैं भाषा वस्तु नहीं करना चाहती लेकिन सीधे भाषा कोड!

यही कारण है कि मुझे लगता है कि मुझे ProductNameType रूप में EntityField का उपयोग नहीं करना चाहिए, लेकिन ChoiceType फ़ील्ड।

मैं पसंद क्षेत्र में डीबी में संग्रहीत सभी भाषाओं को कैसे लोड कर सकता हूं? मुझे आशा है कि इस स्पष्टीकरण अधिक समझ में आता है ;-)

+0

यदि मैं अच्छी तरह से समझता हूं: क्या आपने '__toString()' विधि बनाने की कोशिश की है जो आपकी 'कोड' इकाई 'भाषा' इकाई को वापस लाती है? – Delphine

+0

नहीं। मुझे नहीं लगता कि यह मेरी मदद करता है। मेरी भाषा का कोड पहले से ही एक स्ट्रिंग है। पूर्व: नाम = अंग्रेजी और कोड = एन। जब मैं अपना फॉर्म सबमिट करता हूं तो ऑब्जेक्ट प्राप्त करने के बजाय, मुझे बस उस सूची को चाहिए जो मैंने अपनी सूची में चुना था। – Felurian

+0

मुझे वास्तव में समझ में नहीं आता है कि – Delphine

उत्तर

6

मैं इस पोस्ट का हल धन्यवाद पाया: Passing data to buildForm() in Symfony 2.8/3.0

ProductController.php: createForm() विधि में एक विकल्प के रूप कस्टम डेटा पास।

// ... 

// build the form 
$em = $this->getDoctrine()->getManager(); 
$product = new Product(); 
$languages = $em->getRepository('AppBundle:Language')->findAllOrderedByCode(); 

$form = $this->createForm(ProductType::class, $product, array(
    'languages' => $languages 
)); 

ProductType रूप:

$builder->add('infos', CollectionType::class, array(
    'entry_type' => ProductInfosType::class, 
    'entry_options' => array('languages' => $options['languages']), 
    'allow_add'  => true, 
    'allow_delete' => true, 
    'prototype'  => true, 
    'label'   => false, 
    'by_reference' => false 
)); 

: में विकल्प तो समाधानकर्ता

public function configureOptions(OptionsResolver $resolver) { 
    $resolver->setDefaults(array(
     'data_class' => 'AppBundle\Entity\Product', 
     'languages' => null 
    )); 
} 

कस्टम डेटा पास, buildForm() समारोह में, CollectionType क्षेत्र में एक entry_options विकल्प जोड़ने ProductInfosType फॉर्म: ओ में कस्टम डेटा पास करें ptions रिसोल्वर (ProductForm में के रूप में बिल्कुल वैसा ही)

public function configureOptions(OptionsResolver $resolver) { 
    $resolver->setDefaults(array(
     'data_class' => 'AppBundle\Entity\ProductName', 
     'languages' => null 
    )); 
} 

अब, आप दो विकल्प हैं: या तो आप चाहते हैं कि आपके प्रपत्र संस्थाओं या साधारण तार देता है।

मेरे उदाहरण में, मुझे बस भाषा कोड चाहिए (जैसे एफआर, एन, इत्यादि)।

केस 1:

// Form/ProductInfosType.php 

// ... 

// Convert array of objects in an array of strings 
$choices = array(); 
foreach ($options['languages'] as $lang) { 
    $code = $lang->getCode(); 
    $choices[$code] = $code; 
} 

$builder->add('language', ChoiceType::class, array(
    'placeholder'  => '', 
    'choices'   => $choices 
)); 

// returns : 
Array 
(
    [0] => AppBundle\Entity\ProductName Object 
     ( 
      [name:AppBundle\Entity\ProductName:private] => Ceinture lombaire LombaSkin 
      [language:AppBundle\Entity\ProductName:private] => FR  
     ) 
) 

केस 2:: फ़ॉर्म पोस्ट किया जाता है केवल भाषा कोड लौट लौट भाषा इकाई जब प्रपत्र पोस्ट किया जाता है:

// Form/ProductInfosType.php 

// ... 

$builder->add('language', ChoiceType::class, array(
    'placeholder'  => '', 
    'choices'   => $options['languages'], 
    'choice_label'  => 'code', 
    'choice_value'  => 'code' 
)); 

// returns : 
Array 
(
    [0] => AppBundle\Entity\ProductName Object 
     ( 
      [name:AppBundle\Entity\ProductName:private] => Ceinture lombaire LombaSkin 
      [language:AppBundle\Entity\ProductName:private] => AppBundle\Entity\Language Object 
       (
        [code:AppBundle\Entity\Language:private] => FR 
        [name:AppBundle\Entity\Language:private] => Français 
       )  
     ) 
) 
इस के साथ

समाधान, इकाई प्रबंधक को तर्क के रूप में पास करने के लिए हमें सेवा के रूप में अपना फॉर्म बनाने की आवश्यकता नहीं है। सभी नियंत्रक और फॉर्म विकल्प में प्रबंधित किया जाता है।

1

आप EntityType की choice_value का उपयोग करना चाहिए है।

'choice_value' => function ($language) { 
    return $language->getCode(); 
}, 

संपादित करें: अपने संपादित पढ़ने के बाद, आप वास्तव में सही हो, EntityType लेकिन ChoiceType प्रयोग नहीं करते। choices को पॉप्युलेट करने के लिए, मुझे लगता है कि आपको निर्भरता इंजेक्शन का उपयोग करके अपने फॉर्म के अंदर LanguageRepository इंजेक्ट करना चाहिए, और फिर सभी भाषा कोड लाने के लिए अपने रिपोजिटरी में एक क्वेरी बनाएं।

+0

नहीं, मेरे पास पहले से ही मेरे चयन विकल्पों के मान के रूप में कोड हैं। यह मेरे रूप का डेटा नहीं बदलता है। – Felurian

+0

मैंने अपनी समस्या को बेहतर तरीके से समझाने के लिए अपनी पोस्ट संशोधित की ;-) – Felurian

+0

ठीक है, फिर मैंने अपना जवाब भी संपादित किया। – Terenoth

संबंधित मुद्दे