I have created a multi-select EAV Attribute for my customers with a custom source model. However, whenever I browse to the customers management page or call getSource on the attribute, I get a class does not exist error for the source model. Am I missing something?
Sample exception:
Exception #0 (ReflectionException): Class Wizbusiness/CustomerSubscriptions/Model/Config/Source/ProductTags does not exist
Exception #0 (ReflectionException): Class Wizbusiness/CustomerSubscriptions/Model/Config/Source/ProductTags does not exist
#0 <path>/vendor/magento/framework/Code/Reader/ClassReader.php(19): ReflectionClass->__construct('Wizbusiness/Cus...')
#1 <path>/vendor/magento/framework/ObjectManager/Definition/Runtime.php(44): Magento\Framework\Code\Reader\ClassReader->getConstructor('Wizbusiness/Cus...')
#2 <path>/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php(71): Magento\Framework\ObjectManager\Definition\Runtime->getParameters('Wizbusiness/Cus...')
#3 <path>/vendor/magento/framework/ObjectManager/ObjectManager.php(57): Magento\Framework\ObjectManager\Factory\Dynamic\Developer->create('Wizbusiness/Cus...', Array)
#4 <path>/vendor/magento/framework/Validator/UniversalFactory.php(36): Magento\Framework\ObjectManager\ObjectManager->create('Wizbusiness/Cus...', Array)
#5 <path>/vendor/magento/module-eav/Model/Entity/Attribute/AbstractAttribute.php(538): Magento\Framework\Validator\UniversalFactory->create('Wizbusiness/Cus...')
#6 <path>/vendor/magento/module-customer/Model/AttributeMetadataConverter.php(66): Magento\Eav\Model\Entity\Attribute\AbstractAttribute->getSource()
...
For your reference module files: app/code/Wizbusiness/CustomerSubscriptions/Model/Config/Source/ProductTags.php:
<?php
namespace Wizbusiness\CustomerSubscriptions\Model;
/**
* Tags copied from products
*
* @author Wizbusiness
*/
class ProductTags extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
{
public function toArray()
{
return [];
}
/**
* Options getter
* @return array
*/
final public function toOptionArray()
{
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$model = $objectManager->get('Magento\Catalog\Model\Product');
$attribute = $model->getAttribute('tags');
return $attribute->getAllOptions();
}
/**
* @return array
*/
public function getAllOptions()
{
return $this->toOptionArray();
}
/**
* Get a text for option value
*
* @param string|integer $value
* @return string|bool
*/
public function getOptionText($value)
{
foreach ($this->getAllOptions() as $option) {
if ($option['value'] == $value) {
return $option['label'];
}
}
return false;
}
/**
* Retrieve flat column definition
*
* @return array
*/
public function getFlatColumns()
{
$attributeCode = $this->getAttribute()->getAttributeCode();
return [
$attributeCode => [
'unsigned' => false,
'default' => null,
'extra' => null,
'type' => Table::TYPE_INTEGER,
'nullable' => true,
'comment' => 'Custom Attribute Options ' . $attributeCode . ' column',
],
];
}
}
app/code/Wizbusiness/CustomerSubscriptions/Setup/InstallData.php:
<?php
namespace Wizbusiness\CustomerSubscriptions\Setup;
use Magento\Customer\Model\Customer;
use Magento\Customer\Setup\CustomerSetup;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Catalog\Model\Resource\Eav\Attribute;
class InstallData implements InstallDataInterface
{
/**
* @var CustomerSetupFactory
*/
private $customerSetupFactory;
public function __construct(CustomerSetupFactory $customerSetupFactory)
{
$this->customerSetupFactory = $customerSetupFactory;
}
/**
* Upgrades data for a module
*
* @param ModuleDataSetupInterface $setup
* @param ModuleContextInterface $context
* @return void
*/
public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
$customerSetup = $this->customerSetupFactory->create(['setup' => $setup]);
/** @var CustomerSetup $customerSetup */
$customerSetup->addAttribute(
Customer::ENTITY,
'subscribedtags',
[
'type' => 'text',
'input' => 'multiselect',
'label' => 'Subscribed Tags',
'required' => 0,
'system' => 0, // <-- important, otherwise values aren't saved.
// @see Magento\Customer\Model\Metadata\CustomerMetadata::getCustomAttributesMetadata()
'position' => 100,
'filterable' => true,
'source' => 'Wizbusiness/CustomerSubscriptions/Model/Config/Source/ProductTags',
'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL,
]
);
$used_in_forms=array();
$used_in_forms[]="adminhtml_customer";
$used_in_forms[]="checkout_register";
$used_in_forms[]="customer_account_create";
$used_in_forms[]="customer_account_edit";
$used_in_forms[]="adminhtml_checkout";
$customerSetup->getEavConfig()->getAttribute('customer', 'subscribedtags')
->setData('used_in_forms', $used_in_forms)
->setData("is_used_for_customer_segment", true)
->setData("is_user_defined", 1)
->save();
$setup->endSetup();
}
}
app/code/Wizbusiness/CustomerSubscriptions/etc/module.xml:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Wizbusiness_CustomerSubscriptions" setup_version="0.0.11" />
</config>
app/code/Wizbusiness/CustomerSubscriptions/registration.php:
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Wizbusiness_CustomerSubscriptions',
__DIR__
);