2012-07-23 13 views
18

में कई से अधिक रिश्तों को कैसे कार्यान्वित किया जाए मैं सोनाटामीडियाबंडल को किसी अन्य इकाई से जोड़ने की कोशिश कर रहा हूं: उत्पाद संबंधों के साथ कईToMany।सोनाटा मीडिया बंडल

स्कीमा और संबंध अच्छी तरह से बनाए गए हैं।

हालांकि, जब मैं एक नया उत्पाद संपादित या निर्माण करता हूं, तो मैं एक बटन जोड़ने का प्रयास करता हूं जहां मैं मीडिया लाइब्रेरी के माध्यम से एक मीडिया फ़ाइल खोज सकता हूं और एक नई फ़ाइल अपलोड करने के लिए एक बटन खोज सकता हूं।

एक रिश्ता OneToMany के लिए, यह आसानी से जोड़कर Admin\ProductAdmin::configureFormFields में किया जाता है:

->add('image', 'sonata_type_model_list', array(
        'required' => false 
       ), array(
        'link_parameters' => array(
         'context' => 'default', 
         'provider' => 'sonata.media.provider.image' 
        ) 
       )) 

तो मैं एक ही 3 आइकन के रूप में वे पहले से ही (SonataMediaBundle की गैलरी में इस्तेमाल किया गया पुस्तकालय, से जोड़ने के लिए लिंक अपलोड और हटाना)

लेकिन संबंध पर ManyToMany यह संभव नहीं है! क्योंकि हर बार जब मैं मीडिया चुनता हूं, तो यह पिछले एक को बदल देता है। तो मैं कई मीडिया प्रकारों का चयन नहीं कर सकता।

मैं गैलरी के रूप में (galleryHasMedia)

->add('galleryHasMedias', 'sonata_type_collection', array(
      'by_reference' => false 
     ), array(
      'edit'  => 'inline', 
      'inline' => 'table', 
      'sortable' => 'position', 
      'link_parameters' => array('context' => $context) 
     )) 

हालांकि, यह वास्तव में जटिल है उसी तरह का उपयोग करने पर सोचा। मैं कई मीडिया फ़ाइलों को एकाधिक संस्थाओं के माध्यम से एकाधिक मीडिया फ़ाइलों को चुन या अपलोड कैसे कर सकता हूं?

+0

'-> जोड़ें ('छवि', 'sonata_type_model', सरणी ('आवश्यक' => झूठी, 'एकाधिक' => सत्य) के बारे में क्या? –

+0

आप नमूना डेमो [** '@ सोनाटा-मीडिया-अपलोड-एकाधिक-छवियों '**] प्राप्त कर सकते हैं (https://github.com/dianuj89/sonata-media-upload-multiple-images) –

उत्तर

18

:

/** 
* @ORM\ManyToOne(targetEntity="Application\Sonata\MediaBundle\Entity\Gallery") 
* @ORM\JoinColumn(name="image", referencedColumnName="id") 
*/ 
private $images; 

और फिर अपने रूप में, आप की तरह कुछ के साथ अपने ऑब्जेक्ट में एक गैलरी से जोड़ने के लिए सक्षम हो जाएगा , लेकिन मैंने इसे समझ लिया है।

सबसे पहले, आप कई से अधिक रिश्ते के बजाय एक-से-कई/कई-से-एक संबंध (मध्यवर्ती इकाई का उपयोग करके) चुनना चाहेंगे। क्यूं कर? क्योंकि यह position कॉलम जैसे अतिरिक्त कॉलम की अनुमति देता है। इस तरह आप छवियों को किसी भी तरह से पुन: व्यवस्थित कर सकते हैं। कई से अधिक रिश्तों में, लिंक तालिका में केवल दो कॉलम होते हैं: आईडी संबंधित फाइलों का है।

Doctrine documentation से:

(...) अक्सर आप एक संघ, जिस स्थिति में आप एक संघ वर्ग परिचय के साथ अतिरिक्त गुण संबद्ध करना चाहते हैं। नतीजतन, सीधा कई से कई संगठन गायब हो जाते हैं और 3 भाग लेने वाले वर्गों के बीच एक-से-कई/कई-से-एक संगठनों द्वारा प्रतिस्थापित किया जाता है।

तो मैं अपने उत्पाद मैपिंग फ़ाइल को यह कहा: (के रूप में आप देख सकते हैं मैं अपने विन्यास फाइल प्रारूप के रूप में YAML उपयोग कर रहा हूँ)

oneToMany: 
    images: 
     targetEntity: MyBundle\Entity\ProductImage 
     mappedBy: product 
     orderBy: 
      position: ASC 

और मैं एक नया ProductImage मैपिंग फ़ाइल बनाया:

MyBundle\Entity\ProductImage: 
    type: entity 
    table: product_images 
    id: 
     id: 
      type: integer 
      generator: { strategy: AUTO } 
    fields: 
     position: 
      type: integer 
    manyToOne: 
     product: 
      targetEntity: MyBundle\Entity\Product 
      inversedBy: images 
     image: 
      targetEntity: Application\Sonata\MediaBundle\Entity\Media 

कमांड लाइन (php app/console doctrine:generate:entities MyBundle) का उपयोग करके मैंने संबंधित इकाइयों को बनाया/अपडेट किया (Product और ProductImage)।

अगला, मैंने व्यवस्थापक कक्षाएं बनाई/अपडेट कीं। ProductAdmin.php:

class ProductAdmin extends Admin 
{ 
    protected function configureFormFields(FormMapper $formMapper) 
    { 
     $formMapper 
      // define other form fields 
      ->add('images', 'sonata_type_collection', array(
       'required' => false 
      ), array(
       'edit' => 'inline', 
       'inline' => 'table', 
       'sortable' => 'position', 
      )) 
     ; 
    } 

ProductImageAdmin.php:

class ProductImageAdmin extends Admin 
{ 
    protected function configureFormFields(FormMapper $formMapper) 
    { 
     $formMapper 
      ->add('image', 'sonata_type_model_list', array(
       'required' => false 
      ), array(
       'link_parameters' => array(
        'context' => 'product_image' 
       ) 
      )) 
      ->add('position', 'hidden') 
     ; 
    } 

सेवाओं के रूप में उन दोनों को जोड़ने के लिए मत भूलना। यदि आप डैशबोर्ड पर ProductImage फॉर्म को प्रदर्शित नहीं करना चाहते हैं, तो show_in_dashboard: false टैग जोड़ें। (आप यह कैसे करते हैं कॉन्फ़िगरेशन प्रारूप (yaml/xml/php) पर निर्भर करता है)

इसके बाद मेरे पास व्यवस्थापक फ़ॉर्म सही तरीके से काम कर रहा था, हालांकि मुझे अभी भी उत्पादों को सहेजने की कोशिश करने में कुछ समस्याएं थीं। मुझे सभी समस्याओं को ठीक करने के लिए निम्न चरणों का पालन करना पड़ा:

सबसे पहले, मुझे उत्पाद इकाई के लिए कैस्केड लगातार संचालन को कॉन्फ़िगर करना पड़ा। फिर, यह कैसे करें आपके कॉन्फ़िगरेशन प्रारूप पर निर्भर करता है। मैं YAML उपयोग कर रहा हूँ, इसलिए images एक-से-अनेक संबंध में, मैं झरना संपत्ति कहा:

oneToMany: 
    images: 
     targetEntity: MyBundle\Entity\ProductImage 
     mappedBy: product 
     orderBy: 
      position: ASC 
     cascade: ["persist"] 

कि यह मिल गया काम कर (या इसलिए मैंने सोचा कि), लेकिन मैंने देखा है कि डेटाबेस में product_idNULL पर सेट किया गया था। मैं prePersist() और preUpdate()ProductAdmin वर्ग के लिए विधियां जोड़कर इस हल:

public function prePersist($object) 
{ 
    foreach ($object->getImages() as $image) { 
     $image->setProduct($object); 
    } 
} 

public function preUpdate($object) 
{ 
    foreach ($object->getImages() as $image) { 
     $image->setProduct($object); 
    } 
} 

... और Product संस्था की addImages() विधि करने के लिए एक पंक्ति कहा:

public function addImage(\MyBundle\Entity\ProductImage $images) 
{ 
    $images->setProduct($this); 
    $this->images[] = $images; 

    return $this; 
} 

यह मेरे लिए काम किया, अब मैं अपने उत्पादों से/छवियों को जोड़, बदल सकता हूं, पुन: व्यवस्थित कर सकता हूं, इत्यादि।

+0

सुंदर उत्तर, आपका प्रीपेर्सिस्ट और प्रीअपडेट फ़ंक्शन का उपयोग सही है। – marijnz0r

3

आपको मीडियाबंडल गैलरी पर भरोसा करने की आवश्यकता है। अपने इकाई में आप कुछ की तरह: मैं आप के रूप में ही समस्या थी

->add('images', 'sonata_type_model_list', array('required' => false), array('link_parameters' => array('context' => $context))) 
संबंधित मुद्दे