0

I need to create an extension that will store options of multiselect customer attribute in the database, and I can add through database new options. There are many answers of how to create multiselect customer attribute, and all of them show how to store options in the file, but none how to store in the database. I tried to find similar functionality in magento2, but customer doesn't have multiselect attribute.

InstallData.php:

namespace Vendor\Extension\Setup;

use Magento\Eav\Model\Config;
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,
        Config $eavConfig
    ) {
        $this->eavSetupFactory = $eavSetupFactory;
        $this->eavConfig = $eavConfig;
    }

    public function install(
        ModuleDataSetupInterface $setup,
        ModuleContextInterface $context
    ) {
        $eavSetup = $this->eavSetupFactory->create(["setup" => $setup]);

        //magento 2 create customer dropdown attribute programmatically

        $eavSetup->addAttribute(
            \Magento\Customer\Model\Customer::ENTITY,
            "custom_multiselect",
            [
                "label" => "Customer multiselect segment",
                "system" => 0,
                "position" => 800,
                "sort_order" => 800,
                "visible" => true,
                "note" => "",
                "type" => "text",
                "input" => "multiselect",
                "source" => "Vendor\Extension\Model\Source\Custommultiselect",
            ]
        );

        $this->getEavConfig()
            ->getAttribute("customer", "custom_multiselect")
            ->setData("is_user_defined", 1)
            ->setData("is_required", 0)
            ->setData("default_value", 22)
            ->setData("used_in_forms", [
                "adminhtml_customer",
                "checkout_register",
                "customer_account_create",
                "customer_account_edit",
                "adminhtml_checkout",
            ])
            ->save();
    }

    public function getEavConfig()
    {
        return $this->eavConfig;
    }
}

Custommultiselect.php

namespace Vendor\Extension\Model\Source;

class Custommultiselect extends
    \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
{
    public function getAllOptions()
    {
        if ($this->_options === null) {
            $this->_options = [
                ["value" => "1", "label" => __("default")],

                ["value" => "2", "label" => __("Test")],

                ["value" => "3", "label" => __("Test2")]
            ];
        }

        return $this->_options;
    }

    public function getOptionText($value)
    {
        foreach ($this->getAllOptions() as $option) {
            if ($option["value"] == $value) {
                return $option["label"];
            }
        }
        return false;
    }
}

So basically I need to store: default, Test, Test2 in the database, for example here eav_attribute_option

Any help would be appreciated.

1 Answer 1

0

Use this one

<?php
namespace Vendor\Extension\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;
use Magento\Eav\Model\Config;

class InstallData implements InstallDataInterface
{
    private $eavSetupFactory;

    public function __construct(EavSetupFactory $eavSetupFactory, Config $eavConfig)
    {
        $this->eavSetupFactory = $eavSetupFactory;
        $this->eavConfig = $eavConfig;
    }

    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);

        $eavSetup->addAttribute(
            \Magento\Customer\Model\Customer::ENTITY,
            'custom_multiselect',
            [
                'type' => 'text',
                'label' => 'Delivery Day',
                'input' => 'multiselect',
                'required' => false,
                'visible' => true,
                'user_defined' => false,
                'sort_order' => 106,
                'position' => 104,
                'system' => false,
                'backend' => 'Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend',
                'source' => 'Vendor\Extension\Model\Source\Custommultiselect'
            ]
        );
        $custom_multiselect = $this->eavConfig->getAttribute(\Magento\Customer\Model\Customer::ENTITY, 'custom_multiselect');
        $custom_multiselect->setData(
            'used_in_forms',
            ['adminhtml_customer_address', 'customer_address_edit', 'customer_register_address','adminhtml_customer']
        );
        $custom_multiselect->addData([
            'attribute_set_id' => 1,
            'attribute_group_id' => 1
        ]);        
        $custom_multiselect->save();

    }
}

Custommultiselect.php

<?php

namespace Vendor\Extension\Model\Entity\Attribute\Source;

use Magento\Eav\Model\Entity\Attribute\Source\AbstractSource;

class Deliverydate extends AbstractSource
{
    public function getAllOptions()
    {
        return [
            'monday' => [
                'label' => 'Monday',
                'value' => 'monday'
            ],
            'tuesday' => [
                'label' => 'Tuesday',
                'value' => 'tuesday'
            ],
            'wednesday' => [
                'label' => 'Wednesday',
                'value' => 'wednesday'
            ],
            'thursday' => [
                'label' => 'Thursday',
                'value' => 'thursday'
            ],
            'friday' => [
                'label' => 'Friday',
                'value' => 'friday'
            ],
            'saturday' => [
                'label' => 'Saturday',
                'value' => 'saturday'
            ],
            'sunday' => [
                'label' => 'Sunday',
                'value' => 'sunday'
            ]
        ];
    }
}

In customer

enter image description here

and in database entity_id 28

enter image description here

To add options from database you need to do it like this

<?php

namespace Vendor\Extension\Model\Entity\Attribute\Source;

use Magento\Eav\Model\Entity\Attribute\Source\AbstractSource;
use Magento\Framework\App\ResourceConnection;

class Deliverydate extends AbstractSource
{
    protected $resourceConnection;

    public function __construct(ResourceConnection $resourceConnection)
    {
        $this->resourceConnection = $resourceConnection;
    }

    public function getAllOptions()
    {
        $options = [];
        $connection = $this->resourceConnection->getConnection();
        $tableName = $this->resourceConnection->getTableName('custom_delivery_options');
        
        $select = $connection->select()
            ->from($tableName, ['value', 'label']);
        
        $results = $connection->fetchAll($select);
        
        foreach ($results as $row) {
            $options[$row['value']] = [
                'label' => $row['label'],
                'value' => $row['value']
            ];
        }

        return $options;
    }
}

in di.xml

<type name="Magento\Eav\Model\Entity\Attribute\Source\AbstractSource">
    <arguments>
        <argument name="deliverydate" xsi:type="object">Vendor\Extension\Model\Entity\Attribute\Source\Deliverydate</argument>
    </arguments>
</type>

In db my options are like this

enter image description here

3
  • Thank you for your answer, is it possible to add options from the database? For example, after installation, I have 7 options and can I add new options in the database, so user could choose them?
    – Herecomes
    Commented Jul 19 at 12:07
  • @Herecomes code updated to get options from db
    – Kareem k
    Commented Jul 19 at 12:29
  • Thank you, i didn't tested your solution, I just replaced "source" => "Vendor\Extension\Model\Source\Custommultiselect" to "source" => "Magento\Eav\Model\Entity\Attribute\Source\Table" but will check your answer as a solution.
    – Herecomes
    Commented Jul 22 at 9:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.