2012-09-17 14 views
15

मैं सिम्फनी 2 और डॉक्टर 2 के साथ ई-कॉमर्स बंडल बना रहा हूं। मैं असीमित सुविधाओं के लिए उत्पाद सुविधाओं और उत्पाद मूल्यों के लिए ईएवी दृष्टिकोण लागू कर रहा हूं। इसके लिए, मेरे पास तीन मूलभूत संस्थाएं हैं: उत्पाद, फ़ीचरकिंड और फ़ीचर वैल्यूज।ईएवी रिटर्न किए गए मानों के साथ सिम्फनी 2 फॉर्म डायनामिक चॉइस फील्ड

  • FeatureKind एक OneToMany यूनिडायरेक्शनल रिश्ते के साथ FeatureValues ​​साथ जुड़ा हुआ है।
  • उत्पाद फ़ीचरकिंड से कई लोगों के साथ जुड़ा हुआ है।

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

निम्नलिखित तीन इकाइयां, नियंत्रक और फॉर्म कोड और मेरे कोड का परिणाम निम्नलिखित हैं।

नोट: मैंने इसे कम रखने के लिए कोड से अतिरिक्त चीजें हटा दी हैं।

Product.php

namespace Webmuch\ProductBundle\Entity; 

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

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

    /** 
    * @ORM\ManyToMany(targetEntity="FeatureKind", inversedBy="product", cascade={"persist"}) 
    * @ORM\JoinTable(name="product_featurekind") 
    **/ 
    private $featurekind; 
} 

FeatureKind.php

namespace Webmuch\ProductBundle\Entity; 

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

    /** 
    * @ORM\Column(name="name", type="string", length=50) 
    */ 
    protected $name; 

    /** 
    * @ORM\ManyToMany(targetEntity="FeatureValue") 
    * @ORM\JoinTable(name="feature_kind_value", 
    *  joinColumns={@ORM\JoinColumn(name="kind_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@ORM\JoinColumn(name="value_id", referencedColumnName="id", unique=true)} 
    *  ) 
    **/ 
    protected $values; 
} 

FeatureValue.php

namespace Webmuch\ProductBundle\Entity; 

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

    /** 
    * @ORM\Column(name="value", type="string", length=100) 
    */ 
    protected $value; 
} 

ProductController.php

public function newAction(Request $request) 
{ 
    $entity = new Product(); 
    $em = $this->getDoctrine()->getEntityManager(); 
    $features = $em->getRepository('ProductBundle:FeatureKind')->findAll(); 

    foreach($features as $feature) 
    { 
     $featurekind = new FeatureKind(); 
     $featurekind->setTitle($feature->getTitle()); 
     foreach($feature->getValue() as $value){ 
      $featurekind->getValue()->add($value); 
     } 
     $entity->getFeaturekind()->add($featurekind); 
    } 

    $form = $this->createForm(new ProductType(), $entity); 

    if ('POST' === $request->getMethod()) { 
     $form->bindRequest($request); 
     if ($form->isValid()) { 
      $em->persist($entity); 
      $em->flush(); 

      return $this->redirect($this->generateUrl('product_show', array(
       'id' => $entity->getId() 
      ))); 
     } 
    } 
    return $this->render('ProductBundle:Product:new.html.twig', array(
     'form' => $form->createView() 
    )); 
} 

ProductType.php

namespace Webmuch\ProductBundle\Form; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilder; 

class ProductType extends AbstractType 
{ 
    public function buildForm(FormBuilder $builder, array $options) 
    { 
     $builder 
      ->add('featurekind', 'collection', array('type' => new FeatureKindType())) 
      ->getForm(); 
     } 

    public function getDefaultOptions(array $options) 
    { 
     return array(
      'data_class' => 'Webmuch\ProductBundle\Entity\Product', 
      'required' => true 
     ); 
    } 

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

FeatureKindType.php

namespace Webmuch\ProductBundle\Form; 

class FeatureKindType extends AbstractType 
{ 
    public function buildForm(FormBuilder $builder, array $options) 
    { 
     $builder 
      ->add('title') 
      ->add('value','collection', array(
               'type' => new FeatureValueType(), 
               'allow_add'=>true)) 
      ->getForm(); 
    } 

    public function getDefaultOptions(array $options) 
    { 
     return array(
      'data_class' => 'Webmuch\ProductBundle\Entity\FeatureKind', 
     ); 
    } 

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

This is my form result.

संपादित करें:

मैं काम के कुछ दिनों के बाद, मैं अब एक साधारण के साथ फंस कर रहा हूँ सुविधाओं की सरणी और उनके संबंधित एकाधिक मान:

Array 
(
    [Color] => Array 
     (
      [Red] => Red 
      [Green] => Green 
     ) 

    [Size] => Array 
     (
      [Large] => Large 
      [Medium] => Medium 
      [Small] => Small 
     ) 

    [Sleeve Style] => Array 
     (
      [Half Sleeved] => Half Sleeved 
      [Full Sleeved] => Full Sleeved 
      [Cut Sleeves] => Cut Sleeves 
     ) 

) 

मैं इस प्रकार रूप बनाने की कोशिश की है: $ this-> विकल्प सरणी शामिल हैं।

$builder 
    ->add('name') 
    ->add('slug') 
    ->add('active') 
; 

foreach ($this->choices as $choice) { 
    $builder->add('featurekind', 'choice', array(
     'required' => 'false', 
     'choices' => $choice, 
     'empty_value' => 'Choose an option', 
     'empty_data' => null 
    )); 
} 

$builder->getForm(); 

ऊपर संपत्ति $ featurekind पर काम नहीं करता। मैं त्रुटि मिलती है:

Notice: Object of class Doctrine\Common\Collections\ArrayCollection could not be converted to int in /vagrant/project/vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceList.php line 457 

अगर फॉर्म फील्ड किसी भी संयुक्त राष्ट्र से जुड़े संपत्ति से जुड़ा हुआ है, उदाहरण के लिए हालांकि: $ नाम, यह अभी भी केवल एक ही फॉर्म फील्ड पाश के अंतिम यात्रा के लिए बनाता है।

मैं विकल्पों में से बाहर हूं।

+0

आपने अपना फ़ीचरकिंड टाइप –

+0

मेरा बुरा नहीं दिखाया। मैंने अभी इसे जोड़ा धन्यवाद! – Aayush

+0

और अब आपने फ़ीचरवैल्यू टाइप नहीं दिखाया है। आप क्या प्राप्त करना चाहते हैं? फ़ीचरकिंड नाम वाला एक लेबल और फिर सभी संभावित फीचर मानों के साथ एक ड्रॉप डाउन? –

उत्तर

3

आप जो करना चाहते हैं वह आपकी वर्तमान संरचना के साथ नहीं किया जा सकता है। मुझे समझाने की कोशिश करें: फीचरकिंड फीचरवैल्यू के साथ कई रिश्तों में से एक है। इसका मतलब है कि आपके पास "रंग" प्रकार हो सकता है जिसमें मूल्य "लाल", "गुलाबी" आदि हो सकते हैं .. यह ठीक है। लेकिन आपकी उत्पाद इकाई में फ़ीचरकिंड ऑब्जेक्ट्स का संग्रह है, इसलिए इसमें "रंग", "आकार" इत्यादि जैसी एक सूची हो सकती है ... लेकिन (यह सबसे महत्वपूर्ण हिस्सा है) इसका कोई विशिष्ट मूल्य एसिगिनिग करने का कोई तरीका नहीं है इन प्रकारों में: ऐसी कोई संपत्ति नहीं है जिसमें प्रत्येक प्रकार के लिए विशिष्ट मूल्य है। मुझे आशा है कि आप इसे कम कर सकते हैं, यह समझाना थोड़ा मुश्किल है।

आप क्या करने की जरूरत:

अपने FeatureValue और FeatureKind वर्गों को परिभाषित करें वे कर रहे हैं बस के रूप में। उदाहरण के रंग के लिए, मूल्य::

namespace Webmuch\ProductBundle\Entity; 

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

    /** 
    * @ManyToOne(targetEntity="Product", inversedBy="features") 
    **/ 
    private $product; 

    /** 
    * @ORM\ManyToOne(targetEntity="FeatureKind") 
    **/ 
    protected $kind; 

    /** 
    * @ORM\ManyToOne(targetEntity="FeatureValue") 
    **/ 
    protected $value; 
} 

इस इकाई प्रकार के जोड़े संभालता है:

एक नई इकाई है जो एक तरह की और एक उत्पाद के लिए एक मूल्य के बीच एक संबंध संभालती परिभाषित लाल

अंत में, अपने आदेश, प्रपत्र पेश करने के लिए के रूप में आप चाहते हैं answe में दिए गए निर्देशों के समान कुछ करने में,

namespace Webmuch\ProductBundle\Entity; 

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

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

    /** 
    * @ORM\OneToMany(targetEntity="FeatureKindValue", mappedBy="product") 
    **/ 
    private $features; 
} 

तब: उत्पाद इकाई इस नए प्रकार की संपत्ति है इस stackoverflow करने के लिए आर question

+0

उत्तर के लिए धन्यवाद, मैं चला गया है और अपनी विधि की कोशिश की लेकिन यह काम नहीं करता है।यदि आप छवि देखते हैं, तो मेरे पास पहले से सही प्रकार से जुड़े मेरे फॉर्म के भीतर सामने के मोर्चे पर सभी सही मान हैं। मुझे बस सभी मूल्यों के साथ एक पसंद क्षेत्र के लिए लेबल बनाने के लिए आवश्यक है। यह एक उत्पाद बनाएगा जिसमें आकार होगा: बड़ा और रंग: उदाहरण के लिए हरा। – Aayush

+0

मैं फिर इन उत्पादों में से कई बनाउंगा और उन्हें मास्टर प्रोडक्ट से कनेक्ट कर दूंगा और फिर कई कनेक्टेड उत्पाद इकाइयों के सभी मानों से एक विकल्प फ़ील्ड बनाउंगा। यह प्रश्न केवल एक उप-उत्पाद फ़ॉर्म के बारे में पूछता है जिसमें पहले से ही सभी मान हैं, लेकिन टेक्स्ट फ़ील्ड के रूप में, मैं उन्हें पसंद फ़ील्ड के रूप में चाहता हूं। – Aayush

+0

मैं उत्तर के बारे में बता सकता हूं और इस तरह की पूरी अवधारणा नहीं ले रहा हूं। कृपया मुझे बताये। एक बार फिर धन्यवाद। – Aayush

1

सामान इस तरह की मुश्किल हो सकता है, लेकिन आप अपने FeatureKindType कक्षा में this approach उपयोग कर सकते हैं:

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder->addEventListener(
     FormEvents::PRE_SET_DATA, 
     function (DataEvent $event) use ($builder) { 
      /* @var FormBuilderInterface $builder */ 
      $form = $event->getForm(); 
      /* @var FeatureKind $data */ 
      $data = $event->getData(); 
      if ($data !== null) { 
       $form->add(
        $builder->getFormFactory()->createNamed(
         'values', 
         'entity', 
         null, 
         array(
          'label' => $data->getName(), 
          'class' => 'WebmuchProductBundle:FeatureValue', 
         ) 
        ) 
       ); 
      } 
     } 
    ); 
} 

मन आप, मैं में प्रपत्र पोस्ट और संस्थाओं को बचाने के लिए प्रयास नहीं किया है आपका मामला, लेकिन फॉर्म अब FeatureKind का नाम लेबल के रूप में प्रदर्शित करता है और संबंधित FeatureKindValues युक्त ड्रॉपडाउन चयन का चयन करता है।

मैं इस परियोजना का उपयोग अपनी परियोजना में करता हूं, और यह मेरे लिए काम करता है।