arka uçtan ürünü düzenlerken özel alanı özel veritabanı tablosuna nasıl kaydedebilirim?


11

Arka uçtaki ürün formunda özel sekme görüntülemek için özel bir modül oluşturdum. Bu çözümü kullandım .

Şimdi sekmesinde özel veritabanı tablosuna kaydetmek için özel alanlar ekliyorum. söyle<input type="text" name="my_new_field" value="123">

Ayrıca aşağıdaki gibi yönetici ürünü kaydetmek için özel bir denetleyici oluşturdu.

In etc / di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Controller\Adminhtml\Product\Save" type="Namespace\Module\Controller\Adminhtml\Rewrite\Product\Save" />
</config>

Ve Controller / Adminhtml / Rewrite / Product / Save.php içinde

<?php

    namespace Namespace\Module\Controller\Adminhtml\Rewrite\Product;

    class Save extends \Magento\Catalog\Controller\Adminhtml\Product\save
    {

        public function execute()
        {
            echo "hello"; print_r($_POST); die;

            return parent::execute();
        }
    }

Şimdi executefonksiyonda POST değeri bekliyorum my_new_field. Ama anlamıyorum. Bunu aldıktan sonra verileri özel tabloya kaydetmek için özel sorgular kullanacağım.

Ne yanlış yapıyorum ya da başka bir yöntem kullanmalıyım?

Güncelleme: 26 Ağu.

Zaman kısıtlamaları olduğu için ürün sekmesinden veri kaydetmek için Ajax formu kullandım. @ William-oakley'nin cevabını kabul ettim. Şimdi @mageworx'un cevabına eklediği gibi, bunun bunu yapmanın standart bir yolu olmadığını.

Daha fazla geliştirmede UI form standart kullanımını kullanmak istiyorum. Benim sorum, UI form standardını kullanarak ürün düzenlemesine nasıl özel sekme ekleneceği ve özel alanların özel tabloya veya başka bir şekilde nasıl kaydedileceği.


1
Hey, bu özel kaydetme alanı için Observer'da CatalogueProductSaveBefore.php dosyasını kullanabilirsiniz.
Payal Patel

Yanıtlar:


14

Sadece "açık" bir giriş alanı kullanabilirsiniz, aşağıdaki özelliği eklemeniz yeterlidir:

data-form-part="product_form"

yani:

<input data-form-part="product_form" type="text" name="my_new_field" value="123">

Daha sonra girişiniz için POST verilerini alabilirsiniz.


7

Yukarıdaki çözüm tam olarak doğru değil. Bir alanı "çıplak" html öğesi olarak ekliyorsunuz ve ürün formu, kendine özgü özellikleri olan bir kullanıcı arayüzü biçimidir. Özel bir sınıf ( vendor/magento/module-ui/view/base/web/js/form/form.js) alanların toplanmasından ve bir form gönderildiğinde bunların doğrulanmasından sorumludur. Ayrıca, bu sınıf, bu UI formuyla ilgili olmayan veya additional fieldstüm alanlarınız gibi olmayan alanları kaçırmalıdır . Alanınızın denetleyiciye gönderileceğinden emin olmak için aşağıdaki adlandırmayı kullanmalısınız:

input type="text" name="product[my_new_field]" value="123"

Ancak bu tamamen doğru değildir, çünkü doğru çözüm UI form kullanım standartlarından sapmak ve yerel elemanlarını ve bileşenlerini kullanmak değildir. Bu durumda böyle bir şey için endişelenmemelisiniz çünkü her şey otomatik olarak işlenecektir.

İşlemi anlamak için UI form verilerini depolamanın ana yöntemini kontrol edebilirsiniz:

/**
 * Submits form
 *
 * @param {String} redirect
 */
submit: function (redirect) {
    var additional = collectData(this.additionalFields),
        source = this.source;

    _.each(additional, function (value, name) {
        source.set('data.' + name, value);
    });

    source.save({
        redirect: redirect,
        ajaxSave: this.ajaxSave,
        ajaxSaveType: this.ajaxSaveType,
        response: {
            data: this.responseData,
            status: this.responseStatus
        },
        attributes: {
            id: this.namespace
        }
    });
},

Bu koddan da görebileceğiniz gibi, tüm alanlarını içeren bir html formu gönderilmez. Ancak, gönderilir this.sourceve this.additionalFieldsöğeniz yanlış bildirildiği için öğenize dahil edilmez.

08.23.2016'dan GÜNCELLEŞTİRME

İşte blogumuzdan nasıl alan kümesi ekleyeceğinize dair örnek. Aşağıdaki bağlantıyı kullanarak makalenin tamamını okuyabilirsiniz:

Kaynak: UI formuna alanlı bir alan kümesi eklemenin kolay bir yolu :

İçeriği ekleyin: eklenmesi için UI formu meta verileri ve sanal tür.

Bir dosya oluşturun app/code/Vendor/Product/etc/adminhtml/di.xml. İçine bir değiştirici yerleştireceğiz:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool">
        <arguments>
            <argument name="modifiers" xsi:type="array">
                <item name="custom-fieldset" xsi:type="array">
                    <item name="class" xsi:type="string">Vendor\Product\Ui\DataProvider\Product\Form\Modifier\CustomFieldset</item>
                    <item name="sortOrder" xsi:type="number">10</item>
                </item>
            </argument>
        </arguments>
    </virtualType>
</config>

Şimdi, app/code/Vendor/Product/Ui/DataProvider/Product/Form/Modifier/CustomFieldset.phpürün düzenleme sayfası için özel bir alan kümesiyle değiştirici dosyasını ( ) oluşturun ve alanlarla doldurun:

<?php
namespace Vendor\Product\Ui\DataProvider\Product\Form\Modifier;

use Magento\Catalog\Model\Locator\LocatorInterface;
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
use Magento\Framework\Stdlib\ArrayManager;
use Magento\Framework\UrlInterface;
use Magento\Ui\Component\Container;
use Magento\Ui\Component\Form\Fieldset;
use Magento\Ui\Component\Form\Element\DataType\Number;
use Magento\Ui\Component\Form\Element\DataType\Text;
use Magento\Ui\Component\Form\Element\Input;
use Magento\Ui\Component\Form\Element\Select;
use Magento\Ui\Component\Form\Element\MultiSelect;
use Magento\Ui\Component\Form\Field;

class CustomFieldset extends AbstractModifier
{

    // Components indexes
    const CUSTOM_FIELDSET_INDEX = 'custom_fieldset';
    const CUSTOM_FIELDSET_CONTENT = 'custom_fieldset_content';
    const CONTAINER_HEADER_NAME = 'custom_fieldset_content_header';

    // Fields names
    const FIELD_NAME_TEXT = 'example_text_field';
    const FIELD_NAME_SELECT = 'example_select_field';
    const FIELD_NAME_MULTISELECT = 'example_multiselect_field';

    /**
     * @var \Magento\Catalog\Model\Locator\LocatorInterface
     */
    protected $locator;

    /**
     * @var ArrayManager
     */
    protected $arrayManager;

    /**
     * @var UrlInterface
     */
    protected $urlBuilder;

    /**
     * @var array
     */
    protected $meta = [];

    /**
     * @param LocatorInterface $locator
     * @param ArrayManager $arrayManager
     * @param UrlInterface $urlBuilder
     */
    public function __construct(
        LocatorInterface $locator,
        ArrayManager $arrayManager,
        UrlInterface $urlBuilder
    ) {
        $this->locator = $locator;
        $this->arrayManager = $arrayManager;
        $this->urlBuilder = $urlBuilder;
    }

    /**
     * Data modifier, does nothing in our example.
     *
     * @param array $data
     * @return array
     */
    public function modifyData(array $data)
    {
        return $data;
    }

    /**
     * Meta-data modifier: adds ours fieldset
     *
     * @param array $meta
     * @return array
     */
    public function modifyMeta(array $meta)
    {
        $this->meta = $meta;
        $this->addCustomFieldset();

        return $this->meta;
    }

    /**
     * Merge existing meta-data with our meta-data (do not overwrite it!)
     *
     * @return void
     */
    protected function addCustomFieldset()
    {
        $this->meta = array_merge_recursive(
            $this->meta,
            [
                static::CUSTOM_FIELDSET_INDEX => $this->getFieldsetConfig(),
            ]
        );
    }

    /**
     * Declare ours fieldset config
     *
     * @return array
     */
    protected function getFieldsetConfig()
    {
        return [
            'arguments' => [
                'data' => [
                    'config' => [
                        'label' => __('Fieldset Title'),
                        'componentType' => Fieldset::NAME,
                        'dataScope' => static::DATA_SCOPE_PRODUCT, // save data in the product data
                        'provider' => static::DATA_SCOPE_PRODUCT . '_data_source',
                        'ns' => static::FORM_NAME,
                        'collapsible' => true,
                        'sortOrder' => 10,
                        'opened' => true,
                    ],
                ],
            ],
            'children' => [
                static::CONTAINER_HEADER_NAME => $this->getHeaderContainerConfig(10),
                static::FIELD_NAME_TEXT => $this->getTextFieldConfig(20),
                static::FIELD_NAME_SELECT => $this->getSelectFieldConfig(30),
                static::FIELD_NAME_MULTISELECT => $this->getMultiSelectFieldConfig(40),
            ],
        ];
    }

    /**
     * Get config for header container
     *
     * @param int $sortOrder
     * @return array
     */
    protected function getHeaderContainerConfig($sortOrder)
    {
        return [
            'arguments' => [
                'data' => [
                    'config' => [
                        'label' => null,
                        'formElement' => Container::NAME,
                        'componentType' => Container::NAME,
                        'template' => 'ui/form/components/complex',
                        'sortOrder' => $sortOrder,
                        'content' => __('You can write any text here'),
                    ],
                ],
            ],
            'children' => [],
        ];
    }

    /**
     * Example text field config
     *
     * @param $sortOrder
     * @return array
     */
    protected function getTextFieldConfig($sortOrder)
    {
        return [
            'arguments' => [
                'data' => [
                    'config' => [
                        'label' => __('Example Text Field'),
                        'formElement' => Field::NAME,
                        'componentType' => Input::NAME,
                        'dataScope' => static::FIELD_NAME_TEXT,
                        'dataType' => Number::NAME,
                        'sortOrder' => $sortOrder,
                    ],
                ],
            ],
        ];
    }

    /**
     * Example select field config
     *
     * @param $sortOrder
     * @return array
     */
    protected function getSelectFieldConfig($sortOrder)
    {
        return [
            'arguments' => [
                'data' => [
                    'config' => [
                        'label' => __('Options Select'),
                        'componentType' => Field::NAME,
                        'formElement' => Select::NAME,
                        'dataScope' => static::FIELD_NAME_SELECT,
                        'dataType' => Text::NAME,
                        'sortOrder' => $sortOrder,
                        'options' => $this->_getOptions(),
                        'visible' => true,
                        'disabled' => false,
                    ],
                ],
            ],
        ];
    }

    /**
     * Example multi-select field config
     *
     * @param $sortOrder
     * @return array
     */
    protected function getMultiSelectFieldConfig($sortOrder)
    {
        return [
            'arguments' => [
                'data' => [
                    'config' => [
                        'label' => __('Options Multiselect'),
                        'componentType' => Field::NAME,
                        'formElement' => MultiSelect::NAME,
                        'dataScope' => static::FIELD_NAME_MULTISELECT,
                        'dataType' => Text::NAME,
                        'sortOrder' => $sortOrder,
                        'options' => $this->_getOptions(),
                        'visible' => true,
                        'disabled' => false,
                    ],
                ],
            ],
        ];
    }

    /**
     * Get example options as an option array:
     *      [
     *          label => string,
     *          value => option_id
     *      ]
     *
     * @return array
     */
    protected function _getOptions()
    {
        $options = [
            1 => [
                'label' => __('Option 1'),
                'value' => 1
            ],
            2 => [
                'label' => __('Option 2'),
                'value' => 2
            ],
            3 => [
                'label' => __('Option 3'),
                'value' => 3
            ],
        ];

        return $options;
    }
}

Ön izleme

Veri kaydetme vendor/magento/module-catalog/Controller/Adminhtml/Product/Save.php , ana yürütme yönteminde ürün denetleyici dosyasının içinde gerçekleşir. Her şey doğru şekilde yapılmışsa, verilerimiz bu yöntemin giriş verilerinde doğru bir şekilde görüntülenecektir:

Ön izleme

Ürününüzün en başından bu özelliklere sahip olmaması durumunda, bunları manuel olarak kaydetmeniz gerekir. Bunu gözlemcide yapabilirsiniz.

İlk olarak, app/code/Vendor/Product/etc/adminhtml/events.xmldosyayı dosyada bildirin (form ön uçta olmadığından adminhtml kapsamını kullanıyoruz):

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="catalog_product_save_after">
        <observer name="save_example_data" instance="Vendor\Product\Observer\ProductSaveAfter" />
    </event>
</config>

Ardından, örnek özelliğinde işaret ettiğimiz gözlemcinin sınıfını oluşturun app/code/Vendor/Product/Observer/ProductSaveAfter.php:

<?php
namespace Vendor\Product\Observer;

use \Magento\Framework\Event\ObserverInterface;
use \Magento\Framework\Event\Observer as EventObserver;
use Vendor\Product\Ui\DataProvider\Product\Form\Modifier\CustomFieldset;

class ProductSaveAfter implements ObserverInterface
{

    /**
     * @param EventObserver $observer
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        /** @var \Magento\Catalog\Model\Product $product */
        $product = $observer->getEvent()->getProduct();
        if (!$product) {
            return;
        }

        $exampleTextField = $product->getData(CustomFieldset::FIELD_NAME_TEXT);
        $exampleSelectField = $product->getData(CustomFieldset::FIELD_NAME_SELECT);
        $exampleMultiSelectField = $product->getData(CustomFieldset::FIELD_NAME_MULTISELECT);

        // Manipulate data here
    }
}

Gözlemcideki veriler:

Ön izleme

Şimdi, kendi modelinizi gözlemciden arayabilir ve verileri kaydedebilir veya istediğiniz gibi değiştirebilirsiniz.

Dikkatli ol! Modelinizin kaydedilmesi ürün tasarrufuna bağlıysa, özyinelemeye yol açabilir.


UI form alanlarını nasıl ekleyebilirim?
HungryDB

1
@HungryDB yukarıdaki cevabı güncelledik ve blogumuzdaki makaleye bağlantı ekledik. Burada nasıl bir alan kümesi oluşturulacağını okuyabilirsiniz.
MageWorx

3
Cevabınız için teşekkürler @mageworx. Zaman kısıtlamaları olduğu gibi verileri kaydetmek için ajax form yöntemini kullanmaya karar verdim. Zaman aldığımda kesinlikle yönteminizi deneyeceğim.
HungryDB

peki bu verileri veritabanına nasıl kaydedebilirim?
Chi

Cevap için teşekkürler. Bu yöntem çalışıyor. Özel bir seçim alanı ekledim ve değer, gözlemciyi kullanarak tabloma kaydedilir.Ama aynı ürünü düzenlerken değerlerim seçildiği gibi görüntülenmiyor. Lütfen yardım et .
Vindhuja

2

Ürün alanını özel tabloya kaydetmek için katman fiyat mantığını takip edebilirsiniz. Magento, katman fiyatını arka uç özel modeli yardımıyla kurtaracak. Özel alanımız / özenimiz için aynı mantığı takip edebiliriz. Özel tablodaki özniteliği kaydetmek için, özel özniteliği oluşturmanız ve buna arka uç modeli sağlamanız gerekir. Arka uç modeli, özniteliği doğrulayacak ve kaydedecek ve geri çekecektir. Aşağıdaki adımları takip edebilirsiniz.

1. Adım. Ürün özelliğini oluşturun

<?php 
namespace Magentoins\TestAttribute\Setup; 
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;


class InstallData implements InstallDataInterface

{    
    private $eavSetupFactory; 
    public function __construct(EavSetupFactory $eavSetupFactory)
    {
        $this->eavSetupFactory = $eavSetupFactory;
    }

    /**
     * {@inheritdoc}
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
     */
    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        /** @var EavSetup $eavSetup */
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);

        /**
         * Add attributes to the eav/attribute
         */

        $eavSetup->addAttribute(
            \Magento\Catalog\Model\Product::ENTITY,
            'test_attribute',
            [
                'type' => 'int',
                'backend' => 'Magentoins\TestAttribute\Model\Product\Attribute\Backend\TestAttribute',
                'frontend' => '',
                'label' => 'Test Attribute',
                'input' => '',
                'class' => '',
                'source' => '',
                'global' => \Magento\Catalog\Model\Resource\Eav\Attribute::SCOPE_GLOBAL,
                'visible' => true,
                'required' => false,
                'user_defined' => false,
                'default' => 0,
                'searchable' => false,
                'filterable' => false,
                'comparable' => false,
                'visible_on_front' => false,
                'used_in_product_listing' => true,
                'unique' => false,
                'apply_to' => ''
            ]
        );
    }
}

2. Adım. Doğrulamaya yardımcı olacak ve özellik değerini kaydedip alacak olan ürün özel özelliği için arka uç modeli oluşturun

<?php
namespace Magentoins\TestAttribute\Model\Product\Attribute\Backend;

class TestAttribute extends \Magento\Catalog\Model\Product\Attribute\Backend\Tierprice
{
  protected $_productAttributeBackendTestAttribute;
  /**
   * Website currency codes and rates
   *
   * @var array
   */
  protected $_rates;

  protected $_helper;

  protected $eavConfig;

  public function __construct(
      \Magento\Directory\Model\CurrencyFactory $currencyFactory,
      \Magento\Store\Model\StoreManagerInterface $storeManager,
      \Magento\Catalog\Helper\Data $catalogData,
      \Magento\Framework\App\Config\ScopeConfigInterface $config,
      \Magento\Framework\Locale\FormatInterface $localeFormat,
      \Magento\Catalog\Model\Product\Type $catalogProductType,
      \Magento\Customer\Api\GroupManagementInterface $groupManagement,
      \Magento\Catalog\Model\ResourceModel\Product\Attribute\Backend\Tierprice $productAttributeTierprice,
      \Magentoins\TestAttribute\Model\ResourceModel\Product\Attribute\Backend\TestAttribute $productAttributeBackendFixedprices,
      \Magentoins\TestAttribute\Helper\Data $helperData,
      \Magento\Eav\Model\Config $eavConfig
  ) {
    parent::__construct(
        $currencyFactory,
        $storeManager,
        $catalogData,
        $config,
        $localeFormat,
        $catalogProductType,
        $groupManagement,
        $productAttributeTierprice
    );
    $this->_productAttributeBackendTestAttribute = $productAttributeBackendTestAttribute;    

  }

  /**
   * Retrieve resource instance
   *
   */
  protected function _getResource()
  {
    return $this->_productAttributeBackendTestAttribute;
  }

  public function getAttribute()
  {
    $attribute = $this->eavConfig->getAttribute('catalog_product', 'test_attribute');
    return $attribute;
  }
  /**
   * Validate test_attribute data
   *
   */
  public function validate ($object)
  {
    $attribute = $this->getAttribute();
    $attr = $object->getData($attribute->getName());
    if (empty($attr)) {
      return true;
    }    

    return true;
  }

  /**
   * Assign test_attribute to product data   
   */
  public function afterLoad ($object)
  {
    /*$data is from your custom table*/
    $data = $this->_getResource()->loadTestAttributeData($object->getId(), $websiteId);
    $object->setData($this->getAttribute()->getName(), $data);
    $object->setOrigData($this->getAttribute()->getName(), $data);

    $valueChangedKey = $this->getAttribute()->getName() . '_changed';
    $object->setOrigData($valueChangedKey, 0);
    $object->setData($valueChangedKey, 0);

    return $this;
  }

  /**
   * After Save Attribute manipulation 
   */
  public function afterSave ($object)
  {
    $websiteId = $this->_storeManager->getStore($object->getStoreId())->getWebsiteId();
    $isGlobal = $this->getAttribute()->isScopeGlobal() || $websiteId == 0;

    $testAttribute = $object->getData($this->getAttribute()->getName());

    /*Save attribute value in custom table with the help of resource model*/

    $this->_getResource()->saveTestAttributeData($testAttribute);

    return $this;
  }

  public function beforeSave ($object)
  {
    parent::beforeSave($object);        
  }

}

Adım 2. Özel tablodan özellik değerini kaydetmek ve almak için kaynak modeli

<?php
namespace Magentoins\TestAttribute\Model\ResourceModel\Product\Attribute\Backend;

use Magento\Catalog\Model\ResourceModel\Product\Attribute\Backend\Tierprice;

/**
 * @author
 */
class TestAttribute extends Tierprice
{
    /**
     * Initialize connection and define main table
     *
     * @return void
     */
    protected function _construct()
    {
        $this->_init('magentoins_product_entity_testAttribute', 'value_id');
    }

    /**
     * Load Fixed Prices for product
     *
     * @param int $productId
     * @return Designnbuy_Fixedprices_Model_Mysql4_fixedprices
     */
    public function loadTestAttributeData($productId, $websiteId = null)
    {
        $connection = $this->getConnection();
        $columns = array (
            'test_attribute' => $this->getIdFieldName()            
        );
        $select = $connection->select()
            ->from($this->getMainTable(), $columns)
            ->where('entity_id=?', $productId)
            ->order('order');

        if (!is_null($websiteId)) {
            if ($websiteId == '0') {
                $select->where('website_id=?', $websiteId);
            } else {
                $select->where('website_id IN(?)', array ('0', $websiteId
                ));
            }
        }

        return $connection->fetchAll($select);
    }

    public function saveTestAttributeData(\Magento\Framework\DataObject $attributeObject)
    {
        $connection = $this->getConnection();
        $data = $this->_prepareDataForTable($attributeObject, $this->getMainTable());

        if (!empty($data[$this->getIdFieldName()])) {
            $where = $connection->quoteInto($this->getIdFieldName() . ' = ?', $data[$this->getIdFieldName()]);
            unset($data[$this->getIdFieldName()]);
            $connection->update($this->getMainTable(), $data, $where);
        } else {
            $connection->insert($this->getMainTable(), $data);
        }
        return $this;
    }
}
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.