Magento2 özellik seçeneğini programlı olarak nasıl ekler (kurulumda değil)


15

İthalatçı modülümde boyut ve renk özellikleri için seçenekler eklemeye çalışıyorum ama nasıl yapmıyorum ...:

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);

Bu rapor bir hata (ı raporlama istisna modifiye OptionMaganger.phpetmek > mesajı özel durum )

Özellik boyutu kaydedilemiyor Uyarı: Tanımsız dizin: 177 numaralı satırdaki /var/www/html/magento2/vendor/magento/module-swatches/Model/Plugin/EavAttribute.php dosyasında silin

  • OptionManagement ve Option _contstructor
  • OptionManagement ile mevcut öğeleri alabilirsiniz, bu yüzden tamam olmalı ..

setLabel()ve setValue()varsayılan, ama ben setData denedim , seçenek örneği yükleyin ve OptionManagement->getItems(...) "tekrar" eklemek için geçmek , ancak hata hala var ...

Herhangi bir fikir, içe aktarma işlemi sırasında EAV Seçeneklerini (renk örnekleri?) Nasıl ekleyebilirim? (modül kurulumunda değil)


Güncelleme :

Başka bir yol seçeneği ekleyebilirsiniz:

$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();
}

Bu şekilde Magento2 atfetmek için bir seçenek kaydedebilir, ama "resmi" yolun ne olduğunu bilmiyorum :)


seçeneği, tamsayı için desteklenmeyen dize olarak herhangi bir değer ekledi
Ajay Patel

Yanıtlar:


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

bildirmek:

protected $_eavSetupFactory;

kurucu:

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;
}

yürütme yöntemi:

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)

}

Kodunuzda ciddi bir hata var: $ option ['value'] [$ value] [0] - $ değeri değil, "option_id" - tamsayı, yeni bir seçenek kümesi 0 için olmalıdır. Bu, tamsayıya, yani numaranız olmayan bir dizeniz varsa, örneğin "siyah" ise 0 olur. Ancak, $ değeriniz "10 Black" gibi bir şeyse, 10'a yayınlanır ve veritabanı varlığını yenisi oluşturmak yerine option_id = 10 ile günceller. Bu, mağaza veritabanınızda ciddi karışıklığa neden olabilir.
A.Maksymiuk

bilgilendirmek için teşekkürler kardeşim. Daha fazla hata bulduysanız cevabımı güncelleyebilirsiniz @ A.Maksymiuk
Ronak Chauhan

Yaptım. Lütfen kabul et, o zaman downvote'umu geri alacağım.
A.Maksymiuk

Onaylandı, ancak herhangi bir cevabın aşağı oyu uygun değil kardeşim, Eğer cevabın sorulduğu gibi ilgili olmadığını veya olmadığını düşünüyorsanız, başka birinin cevabını aşağı oylayamazsınız. @Maksymiuk
Ronak Chauhan

Veri bütünlüğünde ciddi hasara neden olacağı için bu kodu kullanmaya kimseyi uyarmak için yaptım. Bunun yerine, komut dosyanız "42" (boyut) adında yeni bir seçenek ekleyerek, option_id = 42 güncellendi (bu, tamamen farklı bir öznitelik olan mevcut seçenektir). Neyse ki bana test sunucusu ve yeni yeni veritabanı oldu.
A.Maksymiuk

2

Başka bir yol seçeneği ekleyebilirsiniz:

$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();
}

Bu şekilde Magento2 atfetmek için bir seçenek kaydedebilir, ancak "resmi" yolun ne olduğunu bilmiyorum.


Benim yoluma bak. Ben 'resmi' olduğuna inanıyorum
CarComp

çözümünüz yalnızca seçenek tamsayı için çalışmadığında işe yarar
Ajay Patel

neden tamsayı değerler için işe yaramasın ki?
Vincent Teyssier

0

Bir doğrulama sorunu gibi görünüyor. Verilerdeki silme anahtarı arka uçtaki formdan gelir, bu nedenle boş bir silme anahtarı eklemeyi deneyin:

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

Çalışabilir.


Üzgünüm hayır. OptionManager add (..) $ option parametresini yeniden
yürütün

Harika, lütfen sorunuzu çözmek için çözümünüzü bir cevap olarak ekleyin.
MauroNigrele

Kendi soruma cevap veremiyorum ama soruyu güncelledim. Çözümümün bir çözüm olduğunu düşünüyorum ...
Interpigeon

Hey, sorunuzu oldukça yaygın olarak cevaplayabilirsiniz.
MauroNigrele

0

Bu cevabı Ryan H. tarafından önerilen ObjectFactory yöntemlerini kullanarak yeniden yazdım.

Müşteri nesnesinde oluşturduğum bazı öznitelikleri kullanan bir Yardımcı Sınıf haline geldi, ancak fikir, öznitelik seçeneklerini değiştirmek için EAV + ObjectFactories'in nasıl kullanılacağı konusunda orada

<?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 enjekte etmeli ve Object nesnesini enjekte etmemeli, Object nesnelerini oluşturmalısınız. ORM nesnelerine doğrudan enjekte edilmemelidir.
Ryan Hoerr

Hangi ObjectFactory? Orada 50 gibi. \ Magento \ Framework \ Api \ ObjectFactory bakıyorum ama sadece ObjectManager için bir sarıcı gibi görünüyor. Neden sadece nesne yöneticisini uygulayamayacağımdan emin değilim. Bu yeni versiyonda şeylerin sarmalayıcıları için çok fazla sarmalayıcı var.
CarComp

1
Özette konuşuyordum. Fabrikaya, tam olarak 'ObjectFactory' değil, verdiğiniz nesne için enjekte edin. Kullandığınız her bir özel tip için fabrikaya enjekte etmeli ve gerektiğinde oluşturmalısınız. Evet, başlangıçta dağınık görünüyor ... ama bunun için çok iyi sebepler var. Ayrıca, EKG kodu standartlarının tümü ObjectManager'ın doğrudan kullanımını yasaklar. Alan Storm'un tüm konuyu açıklayan makalesine bakın: alanstorm.com/magento_2_object_manager_instance_objects
Ryan Hoerr

Kullanmak istediğim nesnelerin fabrikası yoksa ne yapmalıyım? Örneğin, seçenek yönetimi malzemelerini 'fabrikalaştırmak' için bir yol bulamıyorum. Magento \ Eav \ Model \ AttributeFactory de sadece -> create () yerine garip -> createAttribute (vars) kullanır. Sadece diyorum ki, bir ürünle veya bir şeyle inşa edilmiş bir kategoriyle çalışmadığınızda işler biraz garipleşiyor.
CarComp

1
Tüm nesneler fabrika gerektirmez. Bunu yapanlar için, fabrikadan çıkmış olmayabilir - var olmayan herhangi biri çalışma zamanında (DI nesli ile) veya derleme sırasında oluşturulacaktır. Bağlantı verdiğim makaleyi okuyun. Bununla ilgili herhangi bir şekilde, Magento2 ile çalışmayı öğrenmelisiniz, buna karşı değil. Evet, bir öğrenme eğrisi var. Henüz yapmadıysanız, PhpStorm veya benzer bir IDE almanızı şiddetle tavsiye ederim.
Ryan Hoerr

0

GÜNCELLEME 2016-09-11: Quickshiftin'in belirttiği gibi, bu çözüm M2.1 + için çalışmaz. CategorySetupSınıf dışında kurulum dışında bağımlılık-girişimi yapmak ölümcül bir hata verecektir. Daha sağlam bir çözüm için buraya bakın: /magento//a/103951/1905


Bunun için \Magento\Catalog\Setup\CategorySetupsınıfı kullanın . 1.x ile addAttributeOption()tam olarak aynı şekilde çalışan bir yöntem içerir eav/entity_setup::addAttributeOption(). Orada da yardımcı olabilecek başka bazı öznitelik yöntemleri vardır.

Bu sınıfı bir kurulum işleminin dışında bile istediğiniz zaman almak için bağımlılık enjeksiyonunu kullanabilirsiniz.

özellikle:

/**
 * 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
                ],
            ],
        ]
    );
}

İsterseniz, attributeRepositorysınıfı ortadan kaldırabilir ve getAttribute()doğrudan kullanabilirsiniz categorySetup. Her seferinde varlık türü kimliğini eklemeniz gerekir.


Merhaba Ryan, CategorySetupFactorybir örnek oluşturmak için kullanmaya çalışıyorum.CategorySetup bir den Console\Commandancak dediğim zaman, $factory->setup()önemli bir hatayla oluşur: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
quickshiftin

Ahh, şimdi bunun Magento 2.1'de (kullandığım) çalışmayı durdurduğunu belirttiğiniz konuya rastladım . Kodumu şimdi gözden
geçiriyorum

0

Magento 2 programa spesifik özellik seçeneği ekleyin.

Bu komut dosyasını url'den sonra magento'nun kök dizininde çalıştırın.

$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();
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.