कैसे Magento2 विशेषता विकल्प प्रोग्रामेटिक रूप से जोड़ें (सेटअप में नहीं)


15

मैं अपने आयातक मोडुल में आकार और रंग विशेषताओं के विकल्प जोड़ने का प्रयास करता हूं लेकिन मैं ऐसा नहीं करता ...:

private function addOption($attributeCode, $value)
{
    $ob = $this->_objectManager;      
    /* @var $m \Magento\Eav\Model\Entity\Attribute\OptionManagement */
    $m = $this->optionManagement;
    /* @var $option \Magento\Eav\Model\Entity\Attribute\Option */
    $option = $this->attributeOption;

    $option->setLabel($value);      
    $option->setValue($value);

    $m->add(\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE,
            $attributeCode,
            $option);

यह एक त्रुटि की रिपोर्ट करता है (मैंने अपवाद अपवादOptionMaganger.php को अपवाद पर भेज दिया-> संदेश )

विशेषता का आकार नहीं बचा सकता नोटिस: अपरिभाषित सूचकांक: लाइन में 177 पर /var/www/html/magento2/vendor/magento/module-swatches/Model/Plugin/EavAttribute/php पर हटाएं

  • विकल्प प्रबंधन और विकल्प से आते हैं _contstructor
  • OptionManagement के साथ मैं मौजूदा आइटम पुनः प्राप्त कर सकता हूं, इसलिए ठीक होना चाहिए।

setLabel()और setValue()डिफ़ॉल्ट हैं, लेकिन मैंने setData , लोड विकल्प उदाहरण और OptionManagement->getItems"फिर से" जोड़ने के लिए पास करने की कोशिश की , लेकिन त्रुटि अभी भी मौजूद है ...

कोई भी विचार, मैं आयात प्रक्रिया के दौरान ईएवी विकल्प (स्वैच?) को कैसे जोड़ सकता हूं? (मोडुल सेटअप में नहीं)


अपडेट करें :

अन्य तरीके से मैं विकल्प जोड़ सकता हूं:

$attributeCode = 137; /* on size, 90 on color ... */

$languageValues[0]='Admin Label'; 

$languageValues[1]='Default Store Label - XXXXL';
$ob = $this->_objectManager;

private function addOption($attributeCode,$languageValues){
$ob = $this->_objectManager;
/* @var $attr \Magento\Eav\Model\Entity\Attribute */
$attr = $ob->create('\Magento\Eav\Model\Entity\Attribute'); 
$attr->load($attributeCode); 
$option = []; 
$option['value'][$languageValues[0]] = $languageValues; 
$attr->addData(array('option' => $option));
$attr->save();
}

इस तरह से Magento2 विशेषता के लिए एक विकल्प बचा सकता है, लेकिन मुझे नहीं पता कि "आधिकारिक" तरीका क्या है :)


विकल्प ने पूर्णांक के लिए समर्थित स्ट्रिंग के रूप में कोई मूल्य नहीं जोड़ा
अजय पटेल

जवाबों:


2
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Store\Model\StoreManagerInterface;

घोषित:

protected $_eavSetupFactory;

निर्माता:

public function __construct(
    \Magento\Eav\Setup\EavSetupFactory $eavSetupFactory,
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeFactory,
    \Magento\Framework\ObjectManagerInterface $objectmanager,
    ModuleDataSetupInterface $setup,
    \Magento\Catalog\Model\ProductFactory $productloader
) {
    $this->_eavSetupFactory = $eavSetupFactory;
    $this->_storeManager = $storeManager;
    $this->_attributeFactory = $attributeFactory;
    $this->_objectManager = $objectmanager;
    $this->setup = $setup;
    $this->_productloader = $productloader;
}

मेथोड निष्पादित करें:

public function execute(EventObserver $observer)
{
    /** @var $brand \Ktpl\Brand\Model\Brand */
    $brand = $observer->getEvent()->getBrand();
    $option_id = "";

    $data = [];
    $attribute_arr = [$brand['brand_id'] => $brand['brand_title']];
    $optionTable = $this->setup->getTable('eav_attribute_option');
    $attributeInfo=$this->_attributeFactory->getCollection()
           ->addFieldToFilter('attribute_code',['eq'=>"shop_by_brand"])
           ->getFirstItem();

    $attribute_id = $attributeInfo->getAttributeId();

    $eavAttribute = $this->_objectManager->create('Magento\Eav\Model\Config');

    $option=array();
    $option['attribute_id'] = $attributeInfo->getAttributeId();
    $option['value'] = array(0=>array()); // 0 means "new option_id", other values like "14" means "update option_id=14" - this array index is casted to integer

    $storeManager = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface');
    $stores = $storeManager->getStores();
    $storeArray[0] = "All Store Views";       

    foreach ($stores  as $store) {
        $storeArray[$store->getId()] = $store->getName();
    }


    if (empty($brand['optionId'])) {
        foreach($attribute_arr as $key => $value){
            $option['value'][0][0]=$value;
                foreach($storeArray as $storeKey => $store){
                    $option['value'][0][$storeKey] = $value;
                }                
        }
    }
    else
    {
        foreach($attribute_arr as $key => $value){
                foreach($storeArray as $storeKey => $store){
                    $option['value'][$brand['optionId']][$storeKey] = $value;
                }                
        }
    }

    $eavSetup = $this->_eavSetupFactory->create();
    $eavSetup->addAttributeOption($option)

}

आपके पास अपने कोड में गंभीर त्रुटि है: $ विकल्प ['मूल्य'] [$ मूल्य] [०] - यह $ मूल्य नहीं होना चाहिए, लेकिन "विकल्प_आईडी" - पूर्णांक, नए एक विकल्प सेट के लिए ०. यह एक पूर्णांक के लिए डाला जाता है, इसलिए यदि आपके पास कोई संख्‍या नहीं है, जैसे कि "काला" तो यह 0 सही होगा। लेकिन अगर आपका $ मूल्य "10 ब्लैक" जैसा कुछ है, तो यह 10 तक पहुंच जाएगा और डेटाबेस इकाई को नए के बजाय बनाने के लिए option_id = 10 के साथ अपडेट करेगा। यह आपके दुकान डेटाबेस में गंभीर गड़बड़ी पैदा कर सकता है।
.मक्षसिमुक

भाई को सूचित करने के लिए धन्यवाद। अगर आपको कोई त्रुटि मिलती है तो आप मेरे उत्तर @ A.aksymiuk
रौनक चौहान

ने करदी। कृपया स्वीकार करें, फिर मैं अपने पतन का बदला लूंगा।
एम। सिक्सिमिक

स्वीकृत, लेकिन किसी भी उत्तर को डाउन-वोट करना उचित तरीका नहीं है, यदि आपको लगता है कि उत्तर संबंधित नहीं है या नहीं पूछा गया है, तो आप किसी के उत्तर को डाउन-वोट नहीं कर सकते। @ ए.मासिकमुक
रौनक चौहान

मैंने इस कोड का उपयोग करने के लिए किसी को भी चेतावनी देने के लिए ऐसा किया, क्योंकि इससे डेटा अखंडता को गंभीर नुकसान होगा। उदाहरण के लिए "42" (आकार) नाम के नए विकल्प को जोड़ने के बजाय आपकी स्क्रिप्ट अपडेट की गई option_id = 42 (जो पूरी तरह से अलग विशेषता का मौजूदा विकल्प था)। सौभाग्य से यह मुझे परीक्षण सर्वर और नए नए डेटाबेस पर खुशी देता है।
मा.कसिमियुक

2

अन्य तरीके से मैं विकल्प जोड़ सकता हूं:

$attributeCode = 137; /* on size, 90 on color ... */

$languageValues[0]='Admin Label'; 

$languageValues[1]='Default Store Label - XXXXL';
$ob = $this->_objectManager;



private function addOption($attributeCode,$languageValues){
$ob = $this->_objectManager;
/* @var $attr \Magento\Eav\Model\Entity\Attribute */
$attr = $ob->create('\Magento\Eav\Model\Entity\Attribute'); 
$attr->load($attributeCode); 
$option = []; 
$option['value'][$languageValues[0]] = $languageValues; 
$attr->addData(array('option' => $option));
$attr->save();
}

इस तरह से Magento2 विशेषता के लिए एक विकल्प बचा सकता है, लेकिन मुझे नहीं पता कि "आधिकारिक" तरीका क्या है।


मेरी राह देखिए। मेरा मानना ​​है कि यह 'आधिकारिक' है
CarComp

आपका समाधान कार्य है, लेकिन केवल तभी जब विकल्प विकल्प पूर्णांक के लिए काम नहीं करते हैं
अजय पटेल

यह पूर्णांक मानों के लिए काम क्यों नहीं करेगा?
विन्सेन्ट Teyssier

0

एक मान्यता मुद्दा लगता है। डेटा की डिलीट कुंजी बैकएंड में फॉर्म से आती है, इसलिए इस तरह से एक खाली डिलीट की को जोड़ने का प्रयास करें:

$option->setData('delete','');

यह काम कर सकता है।


दुख की बात है नहीं। OptionManager ऐड (..) $ विकल्प पैरामीटर को फिर से तैयार करता है और 'डिलीट' की कोरी खाली छोड़ देता है, मुझे नहीं पता क्यों ... लेकिन मुझे एक और तरीका मिला ....
Interpigeon

महान, कृपया प्रश्न हल करने के उत्तर के रूप में अपना समाधान जोड़ें।
मौरोनिग्रेले

मैं अपने खुद के सवाल का जवाब नहीं दे सकता, लेकिन मैंने सवाल को अपडेट किया। मुझे लगता है कि मेरा समाधान एक समाधान है ...
Interpigeon

अरे, आप अपने सवाल का जवाब दे सकते हैं बहुत आम है।
मौरोनिग्रेले

0

मैंने रेयान एच द्वारा सुझाए गए ऑब्जेक्टफिटिंग विधियों का उपयोग करके इस पूरे उत्तर को फिर से लिखना शुरू कर दिया।

यह हेल्पर क्लास होने के कारण समाप्त हो गया, जो मैंने ग्राहक ऑब्जेक्ट पर बनाई गई कुछ विशेषताओं का उपयोग किया था, लेकिन विचार यह है कि ईएवी + ऑब्जेक्टफैक्टरीज का उपयोग करने के लिए कैसे विशेषता विकल्पों में हेरफेर किया जाए।

<?php


namespace Stti\Healthday\Helper {
    use Magento\Eav\Model\Entity\AttributeFactory;
    use Magento\Eav\Model\Entity\Attribute\OptionFactory;
    use Magento\Eav\Model\Entity\Attribute\OptionManagementFactory;
    use Magento\Framework\App\Helper\AbstractHelper;
    use Magento\Framework\App\Helper\Context;
    use Magento\Eav\Model\Entity\Attribute;
    use Stti\Healthday\Model\RelationFactory;


    /**
     * Eav data helper
     */
    class Data extends AbstractHelper {

        protected $optionFactory;

        protected $attributeFactory;

        protected $relationFactory;

        protected $optionManagementFactory;

        public function __construct(Context $context, AttributeFactory $attributeFactory, OptionFactory $optionFactory,
            RelationFactory $relationFactory,
            OptionManagementFactory $optionManagementFactory) {
            $this->optionFactory = $optionFactory;
            $this->attributeFactory = $attributeFactory;
            $this->optionFactory = $optionFactory;
            $this->relationFactory = $relationFactory;
            $this->optionManagementFactory = $optionManagementFactory;
            parent::__construct($context);
        }

        public function addRelationsHelper($answerJson, $attributeCode) {
            // IMPORTANT: READ THIS OR THE CODE BELOW WONT MAKE SENSE!!!!
            // Since magento's attribute option model was never meant to
            // hold guids, we'll be saving the guid as the label. An option_id will
            // get created, which can then be saved to the relationship table.  Then
            // the label in the attribute_option table can be changed to the actual 'word'
            // by looking up all of the options, matching on the guid, and doing a replace.
            // At that point, there will be a 1:1 relation between guid, option_id, and the 'word'



            // Get the attribute requested
            $attribute = $this->attributeFactory->create();
            $attribute  = $attribute->loadByCode("customer", $attributeCode);

            $answers = json_decode($answerJson, true);

            // Prepare vars
            //$setup = new Mage_Eav_Model_Entity_Setup('core_setup');
            $prekeys = array();
            $prevalues = array();

            foreach ($answers as $answer) {
                $prekeys[] = $answer['Key'];
                $prevalues[] = $answer['Value'];
            }

            // load up all relations
            // generate an array of matching indexes so we can remove
            // them from the array to process
            $collection = $this->relationFactory->create()->getCollection();

            $removalIds = array();
            foreach ($collection as $relation) {
                // if the item is already in the magento relations,
                // don't attempt to add it to the attribute options
                for($cnt = 0; $cnt < sizeof($answers); $cnt++) {
                    if ($relation['stti_guid'] == $prekeys[$cnt]) {
                        $removalIds[] = $cnt;
                    }
                }
            }

            // Remove the values from the arrays we are going to process
            foreach($removalIds as $removalId) {
                unset($prekeys[$removalId]);
                unset($prevalues[$removalId]);
            }

            // "reindex" the arrays
            $keys = array_values($prekeys);
            $values = array_values($prevalues);

            // prepare the array that will be sent into the attribute model to
            // update its option values
            $updates = array();
            $updates['attribute_id'] = $attribute->getId();

            // This section utilizes the DI generated OptionFactory and OptionManagementFactory
            // to add the options to the customer attribute specified in the parameters.
            for($cnt = 0; $cnt < sizeof($keys); $cnt++) {
                $option = $this->optionFactory->create();
                $option->setLabel($keys[$cnt]);
                $this->optionManagementFactory->create()->add("customer", $attributeCode, $option);
            }

            // After save, pull all attribute options, compare to the 'keys' array
            // and create healthday/relation models if needed
            $relationIds = $attribute->getOptions();
            $updatedAttributeCount = 0;
            $options = array();
            $options['value'] = array();

            for($cnt = 0; $cnt < sizeof($keys); $cnt++) {

                $option_id = 0;
                foreach($relationIds as $relationId) {
                    if ($relationId->getLabel() == $keys[$cnt]) {
                        $option_id = $relationId['value'];
                        break;
                    }
                }
                if ($option_id > 0) {
                    // Create the healthday relation utilizing our custom models DI generated ObjectFactories
                    $relation = $this->relationFactory->create();
                    $relation->setAttributeId($attribute->getId());
                    $relation->setOptionId($option_id);
                    $relation->setSttiGuid($keys[$cnt]);
                    $relation->save();

                    // Rename the attribute option value to the 'word'
                    $options['value'][$option_id][] = $values[$cnt];
                    $updatedAttributeCount++;
                }
            }

            if ($updatedAttributeCount > 0) {
                $attribute->setData('option', $options);
                $attribute->save();
            }

            // Save the relationship to the guid
            return $updatedAttributeCount;
        }
    }
}

1
आपको ObjectFactory इंजेक्षन किया जाना चाहिए और उस से ऑब्जेक्ट के उदाहरण बनाने के लिए, ऑब्जेक्ट को खुद इंजेक्ट नहीं करना चाहिए। ORM ऑब्जेक्ट को सीधे इंजेक्ट नहीं किया जाना है।
रयान होर

कौन सी वस्तु 50 की तरह Theres। मैं \ Magento \ Framework \ Api \ ObjectFactory पर देख रहा हूँ, लेकिन यह सिर्फ ObjectManager के लिए एक आवरण की तरह लग रहा है। मुझे यकीन नहीं है कि मैं सिर्फ ऑब्जेक्टमैनेजर को ही लागू क्यों नहीं करूंगा। इस नए संस्करण में चीजों के रैपर के लिए कई रैपर थे।
CarComp

1
मैं सार में बोल रहा था। अपने दिए गए ऑब्जेक्ट के लिए फैक्ट्री को इंजेक्ट करें, वस्तुतः 'ऑब्जेक्टफैक्ट्री' नहीं। आपको प्रत्येक विशिष्ट प्रकार के उपयोग के लिए कारखाने को इंजेक्ट करना चाहिए, और उन्हें आवश्यकतानुसार बनाना चाहिए। हां, यह पहले गड़बड़ लगता है ... लेकिन इसके बहुत अच्छे कारण हैं। इसके अलावा, ईसीजी कोड मानक सभी लेकिन ObjectManager के प्रत्यक्ष उपयोग को प्रतिबंधित करते हैं। एलन स्टॉर्म का लेख देखें जो पूरे विषय की व्याख्या कर रहा है: alanstorm.com/magento_2_object_manager_instance_objects
रयान होएर

जब मैं जिन वस्तुओं का उपयोग करना चाहता हूं, उनका कारखाना नहीं है तो मुझे क्या करना चाहिए? उदाहरण के लिए, मैं विकल्प प्रबंधन सामग्री को 'फ़ैक्टरी' करने का तरीका नहीं खोज सकता। Magento \ Eav \ Model \ AttributeFactory भी सिर्फ के बजाय एक अजीब -> createAttribute (vars) -> create () का उपयोग करता है। मैं सिर्फ यह कह रहा हूं, जब आप किसी उत्पाद, या सामान में निर्मित श्रेणी के साथ काम नहीं करते हैं, तो चीजें थोड़ी अजीब हो जाती हैं।
CarComp

1
सभी वस्तुओं को एक कारखाने की आवश्यकता नहीं होगी। ऐसा करने वालों के लिए, फैक्ट्री आउट-ऑफ-द-बॉक्स मौजूद नहीं हो सकती है - जो भी मौजूद नहीं है वह रनटाइम (DI पीढ़ी के साथ), या संकलन के दौरान बनाई जाएगी। मेरे द्वारा जुड़े लेख को पढ़ें। इसके बारे में कोई भी तरीका, आपको Magento2 के साथ काम करना सीखना होगा, इसके खिलाफ नहीं। हां, सीखने की अवस्था है। यदि आप पहले से ही नहीं हैं, तो मैं दृढ़ता से PhpStorm या इसी तरह की IDE लेने की सलाह देता हूं।
रायन होर

0

UPDATE 2016-09-11: जैसा कि क्विकशिफ्टिन ने बताया है, यह समाधान M2.1 + के लिए काम नहीं करता है। CategorySetupसेटअप के बाहर निर्भरता-इंजेक्शन को वर्ग में लाने का प्रयास आपको एक घातक त्रुटि देगा। अधिक मजबूत समाधान के लिए यहां देखें: /magento//a/103951/1905


इसके लिए \Magento\Catalog\Setup\CategorySetupक्लास का इस्तेमाल करें। इसमें एक addAttributeOption()विधि शामिल है , जो ठीक उसी तरह काम करती है जैसे eav/entity_setup::addAttributeOption()1.x में। वहाँ कुछ अन्य विशेषता विधियाँ हैं जो सहायक भी हो सकती हैं।

आप सेटअप प्रक्रिया के बाहर भी, किसी भी समय इस वर्ग को प्राप्त करने के लिए निर्भरता इंजेक्शन का उपयोग कर सकते हैं।

विशेष रूप से:

/**
 * Constructor.
 *
 * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository
 * @param \Magento\Catalog\Setup\CategorySetupFactory $categorySetupFactory
 */
public function __construct(
    \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository,
    \Magento\Catalog\Setup\CategorySetupFactory $categorySetupFactory
) {
    $this->attributeRepository = $attributeRepository;
    $this->categorySetupFactory = $categorySetupFactory;
}

/**
 * Create a matching attribute option
 *
 * @param string $attributeCode Attribute the option should exist in
 * @param string $label Label to add
 * @return void
 */
public function addOption($attributeCode, $label) {
    $attribute = $this->attributeRepository->get($attributeCode);

    $categorySetup = $this->categorySetupFactory->create();
    $categorySetup->addAttributeOption(
        [
            'attribute_id'  => $attribute->getAttributeId(),
            'order'         => [0],
            'value'         => [
                [
                    0 => $label, // store_id => label
                ],
            ],
        ]
    );
}

यदि वांछित है, तो आप attributeRepositoryकक्षा को समाप्त कर सकते हैं और getAttribute()सीधे उपयोग कर सकते हैं categorySetup। आपको हर बार बस इकाई प्रकार आईडी को शामिल करना होगा।


हाय रयान, मैं CategorySetupFactoryएक CategorySetupसे तात्कालिकता का उपयोग करने की कोशिश कर रहा हूँ Console\Command, हालाँकि जब मैं $factory->setup()एक घातक त्रुटि PHP Fatal error: Uncaught TypeError: Argument 1 passed to Magento\Setup\Module\DataSetup::__construct() must be an instance of Magento\Framework\Module\Setup\Context, instance of Magento\Framework\ObjectManager\ObjectManager given
कहता हूँ

आह, मैंने अब इस धागे पर ठोकर खाई है जिसमें आप कहते हैं कि यह Magento 2.1 में काम करना बंद कर रहा है (जो मैं उपयोग कर रहा हूं)। मेरे कोड को अब संशोधित कर रहा है, लेकिन इस आशय के उत्तर पर एक नोट भी डालना सबसे अच्छा है ...
quickshiftin

0

Magento 2 विशिष्ट विशेषता विकल्प प्रोग्रामेटिक रूप से जोड़ें।

इस स्क्रिप्ट को url के बाद magento के रूट डायरेक्टरी में चलाएँ।

$objectManager = \Magento\Framework\App\ObjectManager::getInstance(); // instance of object manager
try{
      $entityType = 'catalog_product';
      $attributeCode = 'manufacturer';
      $attributeInfo = $objectManager->get(\Magento\Eav\Model\Entity\Attribute::class)
                                 ->loadByCode($entityType, $attributeCode);


      $attributeFactory = $objectManager->get('\Magento\Catalog\Model\ResourceModel\Eav\Attribute');

      $attributeId = $attributeInfo->getAttributeId();
      //$manufacturer = $item->{'Manufacturer'};
      $attribute_arr = ['aaa','bbb','ccc','ddd'];

      $option = array();
      $option['attribute_id'] = $attributeId;
      foreach($attribute_arr as $key=>$value){
          $option['value'][$value][0]=$value;
          foreach($storeManager as $store){
              $option['value'][$value][$store->getId()] = $value;
          }
      }
      if ($option) {
        $eavSetupFactory = $objectManager->create('\Magento\Eav\Setup\EavSetup');
        print_r($eavSetupFactory->getAttributeOption());
        die();
        $eavSetupFactory->addAttributeOption($option);
      }
    }catch(Exception $e){
      echo $e->getMessage();
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.