I created a custom module. My module adds the custom attribute to product. Now when I try to add New Product in Magento 2.4.4 , I am getting The "componentType" configuration parameter is required for the "" component. error
Here is My code for InstallData.php
<?php
namespace Vendor\Module\Setup;
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}
*/
public function install(
ModuleDataSetupInterface $setup,
ModuleContextInterface $context
) {
$eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
$eavSetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY,
'mcwarehouse',
[
'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'label' => 'Warehouse',
'input' => 'select',
'source' => \Vendor\Module\Model\Product\Attribute\Source\Warehouse::class,
'backend_model' =>\Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend::class,
'required' => false,
'sort_order' => 50,
'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE,
'group' => 'Product Details',
'is_used_in_grid' => true,
'is_visible_in_grid' => false,
'is_filterable_in_grid' => false
]
);
}
}
The error I got is
1 exception(s):
Exception #0 (Magento\Framework\Exception\LocalizedException): The "componentType" configuration parameter is required for the "" component.
I want create a customer image attribute,so customer and admin can upload, update and delete profile image like avatar. I know how is this possible in magento 1,but not in magento 2
.If anyone have any idea please share. Thanks in advance.
create below module files. It worked on magento 2.1.4
Create : app\code\Sashas\CustomerAttribute\etc\module.xml
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
<module name="Sashas_CustomerAttribute" setup_version="1.0.0">
<sequence>
<module name="Magento_Customer"/>
</sequence>
</module>
</config>
Create: app\code\Sashas\CustomerAttribute\Setup\InstallData.php
<?php
/**
* #author Sashas
* #category Sashas
* #package Sashas_CustomerAttribute
* #copyright Copyright (c) 2015 Sashas IT Support Inc. (http://www.extensions.sashas.org)
*/
namespace Sashas\CustomerAttribute\Setup;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Customer\Model\Customer;
use Magento\Eav\Model\Entity\Attribute\Set as AttributeSet;
use Magento\Eav\Model\Entity\Attribute\SetFactory as AttributeSetFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
/**
* #codeCoverageIgnore
*/
class InstallData implements InstallDataInterface
{
/**
* #var CustomerSetupFactory
*/
protected $customerSetupFactory;
/**
* #var AttributeSetFactory
*/
private $attributeSetFactory;
/**
* #param CustomerSetupFactory $customerSetupFactory
* #param AttributeSetFactory $attributeSetFactory
*/
public function __construct(
CustomerSetupFactory $customerSetupFactory,
AttributeSetFactory $attributeSetFactory
) {
$this->customerSetupFactory = $customerSetupFactory;
$this->attributeSetFactory = $attributeSetFactory;
}
/**
* {#inheritdoc}
*/
public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
/** #var CustomerSetup $customerSetup */
$customerSetup = $this->customerSetupFactory->create(['setup' => $setup]);
$customerEntity = $customerSetup->getEavConfig()->getEntityType('customer');
$attributeSetId = $customerEntity->getDefaultAttributeSetId();
/** #var $attributeSet AttributeSet */
$attributeSet = $this->attributeSetFactory->create();
$attributeGroupId = $attributeSet->getDefaultGroupId($attributeSetId);
$customerSetup->addAttribute(Customer::ENTITY, 'magento_username', [
'type' => 'varchar',
'label' => 'Magento Username',
'input' => 'image',
'required' => false,
'visible' => true,
'user_defined' => true,
'sort_order' => 1000,
'position' => 1000,
'system' => 0,
]);
$attribute = $customerSetup->getEavConfig()->getAttribute(Customer::ENTITY, 'magento_username')
->addData([
'attribute_set_id' => $attributeSetId,
'attribute_group_id' => $attributeGroupId,
'used_in_forms' => ['adminhtml_customer'],
]);
$attribute->save();
}
}
Create : app\code\Sashas\CustomerAttribute\registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Sashas_customerAttribute',
__DIR__
);
?>
I am trying to add the custom attribute to registration form. And i have added the attribute successfully by the following code
class InstallData implements InstallDataInterface
{
/**
* #var EavSetupFactory Magento\Eav\Setup\EavSetupFactory
*/
private $eavSetupFactory;
/**
* #var $_eavConfig Config
*/
protected $eavConfig;
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,
'mobile',
[
'type' => 'varchar',
'label' => 'Mobile',
'input' => 'text',
'required' => false,
'system' => false,
'position' => 100,
'visible' => true,
'user_defined' => true
]
);
$mobile = $this->eavConfig->getAttribute(\Magento\Customer\Model\Customer::ENTITY, 'mobile');
//$forms = ['adminhtml_customer', 'checkout_register', 'customer_account_create', 'customer_account_edit'];
$forms = ['adminhtml_customer'];
$mobile->setData(
'used_in_forms',
$forms
);
$mobile->save();
}
}
And to show at front-end i am using the layout handler customer_account_create with the following code
<referenceContainer name="form.additional.info">
<block class="Namespace\SMS\Block\Active" name="sms_block">
<action method="setTemplate" ifconfig="sms/actions/register" ifvalue="1">
<argument name="template" xsi:type="string">Namespace_SMS::sms/register.phtml</argument>
</action>
</block>
</referenceContainer>
Now it is showing the mobile field during registration. But when i try to create account mobile field value is empty after create account.
Note: I know if i add the 'customer_account_create', 'customer_account_edit' with used_in_form then mobile value save. But after this i can not use a specific template file to render mobile field.
Can you please let me know how can i solve this issue? Thank you very much.
I do not know whether it is 100% correct according to the coding rules. But I have resolved this issue using the observer and little bit changes in InstallData script.
InstallData.php is like this
class InstallData implements InstallDataInterface
{
/**
* Customer setup factory
*
* #var \Magento\Customer\Setup\CustomerSetupFactory
*/
private $customerSetupFactory;
/**
* Init
*
* #param \Magento\Customer\Setup\CustomerSetupFactory $customerSetupFactory
*/
public function __construct(\Magento\Customer\Setup\CustomerSetupFactory $customerSetupFactory) {
$this->customerSetupFactory = $customerSetupFactory;
}
public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
/** #var CustomerSetup $customerSetup */
$customerSetup = $this->customerSetupFactory->create(['setup' => $setup]);
$customerSetup->addAttribute(
\Magento\Customer\Model\Customer::ENTITY,
'mobile',
[
'type' => 'varchar',
'label' => 'Mobile',
'input' => 'text',
'required' => false,
'system' => false,
'position' => 100,
'visible' => true,
'user_defined' => true
]
);
$customerSetup->updateAttribute('customer', 'mobile', 'is_used_for_customer_segment', '1');
//$forms = ['adminhtml_customer', 'checkout_register', 'customer_account_create', 'customer_account_edit'];
$forms = ['adminhtml_customer'];
$attribute = $customerSetup->getEavConfig()->getAttribute('customer', 'mobile');
$attribute->setData('used_in_forms', ['adminhtml_customer']);
$attribute->addData([
'attribute_set_id' => 1,
'attribute_group_id' => 1
]);
$attribute->save();
$setup->endSetup();
}
}
then events.xml is like this
<?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="customer_register_success">
<observer name="sMSHandleCustomerSaveAfter" instance="\Namepace\SMS\Observer\CustomerRegisterObserver" />
</event>
</config>
And the observer is like this
class CustomerRegisterObserver implements ObserverInterface
{
/**
* #var \Magento\Customer\Model\CustomerFactory
*/
protected $_customerFactory;
function __construct(CustomerFactory $customerFactory)
{
$this->_customerFactory = $customerFactory;
}
public function execute(Observer $observer)
{
$customerData = $observer->getCustomer();
if($_POST['mobile']) {
$customer = $this->_customerFactory->create()->load($customerData->getId());
$customer->setData('mobile', $_POST['mobile']);
$customer->save();
}
}
}
IF someone is looking for the solution, nearly to the #Abbas answer, but modified in observer part:
<?php
namespace {Vendor}\Module\Observer;
use Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\Event\ObserverInterface;
class CustomerRegisterObserver implements ObserverInterface
{
/**
* #var \Magento\Customer\Model\CustomerFactory
*/
protected $_customerFactory;
protected $_customerRepository;
function __construct(
\Magento\Customer\Model\CustomerFactory $customerFactory,
\Psr\Log\LoggerInterface $logger
) {
$this->_customerFactory = $customerFactory;
$this->_logger = $logger;
}
public function execute(EventObserver $observer)
{
//$this->_logger->info("Observer CustomerRegisterObserver Loaded !");
$event = $observer->getEvent();
$customerData = $event->getCustomer();
if($_POST['mobile']) {
$customer = $this->_customerFactory->create()->load($customerData->getId());
$customer->setData('mobile', $_POST['mobile']);
$customer->save();
}
}
}
I am using ajax validation for unique field and it's not working.
In my usercontroller it works but in this sitecontroller doesn't.
Can anyone help me for this?
This is my Controller
<?php
namespace frontend\controllers;
use Yii;
use yii\base\InvalidParamException;
use yii\web\BadRequestHttpException;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use common\models\LoginForm;
use frontend\models\PasswordResetRequestForm;
use frontend\models\ResetPasswordForm;
use frontend\models\SignupForm;
use frontend\models\User;
use frontend\models\UserSeacrh;
use frontend\models\ContactForm;
use yii\widgets\ActiveForm;
/**
* Site controller
*/
class SiteController extends Controller
{
/**
* #inheritdoc
*/
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout', 'signup'],
'rules' => [
[
'actions' => ['signup'],
'allow' => true,
'roles' => ['?'],
],
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
/**
* Displays homepage.
*
* #return mixed
*/
public function actionIndex()
{
return $this->render('index');
}
/**
* Logs in a user.
*
* #return mixed
*/
public function actionLogin()
{
if (!Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
return $this->goBack();
} else {
return $this->render('login', [
'model' => $model,
]);
}
}
/**
* Displays contact page.
*
* #return mixed
*/
public function actionContact()
{
$model = new ContactForm();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
if ($model->sendEmail(Yii::$app->params['adminEmail'])) {
Yii::$app->session->setFlash('success', 'Thank you for contacting us. We will respond to you as soon as possible.');
} else {
Yii::$app->session->setFlash('error', 'There was an error sending email.');
}
return $this->refresh();
} else {
return $this->render('contact', [
'model' => $model,
]);
}
}
/**
* Displays about page.
*
* #return mixed
*/
public function actionAbout()
{
return $this->render('about');
}
/**
* Signs user up.
*
* #return mixed
*/
public function actionSignup()
{
$model = new SignupForm();
if ($model->load(Yii::$app->request->post())) {
if ($user = $model->signup()) {
if (Yii::$app->getUser()->login($user)) {
return $this->goHome();
}
}
}
return $this->render('signup', [
'model' => $model,
]);
}
public function actionValidation()
{
$model = new User();
if(Yii::$app->request->isAjax && $model->load(Yii::$app->request->post()))
{
Yii::$app->response->format = 'json';
return ActiveForm::validate($model);
}
}
/**
* Requests password reset.
*
* #return mixed
*/
public function actionRequestPasswordReset()
{
$model = new PasswordResetRequestForm();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
if ($model->sendEmail()) {
Yii::$app->session->setFlash('success', 'Check your email for further instructions.');
return $this->goHome();
} else {
Yii::$app->session->setFlash('error', 'Sorry, we are unable to reset password for email provided.');
}
}
return $this->render('requestPasswordResetToken', [
'model' => $model,
]);
}
/**
* Resets password.
*
* #param string $token
* #return mixed
* #throws BadRequestHttpException
*/
public function actionResetPassword($token)
{
try {
$model = new ResetPasswordForm($token);
} catch (InvalidParamException $e) {
throw new BadRequestHttpException($e->getMessage());
}
if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) {
Yii::$app->session->setFlash('success', 'New password was saved.');
return $this->goHome();
}
return $this->render('resetPassword', [
'model' => $model,
]);
}
}
This is my model
<?php
namespace frontend\models;
use Yii;
/**
* This is the model class for table "user".
*
* #property integer $id
* #property string $username
* #property string $name
* #property string $lastname
* #property string $email
* #property integer $phone
* #property string $notes
* #property string $company
* #property string $password_hash
* #property string $auth_key
* #property integer $status
* #property integer $created_at
* #property integer $updated_at
* #property string $country
* #property string $state
* #property string $city
* #property string $language
* #property integer $salary
* #property string $hiredate
* #property string $birthday
* #property string $address
* #property string $dismission
*/
class User extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'user';
}
public function fields()
{
return [
'id','status'
];
}
/**
* #inheritdoc
*/
public function rules()
{
return [
['username', 'unique'],
[['username', 'name', 'lastname', 'email', 'phone', 'password_hash'], 'required'],
[['phone', 'status', 'created_at', 'updated_at', 'salary'], 'integer'],
[['hiredate', 'birthday', 'dismission'], 'safe'],
[['username', 'name', 'lastname', 'email', 'notes', 'company', 'password_hash', 'auth_key', 'country', 'state', 'city', 'language', 'address'], 'string', 'max' => 100],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'username' => 'Username',
'name' => 'Name',
'lastname' => 'Lastname',
'email' => 'Email',
'phone' => 'Phone',
'notes' => 'Notes',
'company' => 'Company',
'password_hash' => 'Password Hash',
'auth_key' => 'Auth Key',
'status' => 'Status',
'created_at' => 'Created At',
'updated_at' => 'Updated At',
'country' => 'Country',
'state' => 'State',
'city' => 'City',
'language' => 'Language',
'salary' => 'Salary',
'hiredate' => 'Hiredate',
'birthday' => 'Birthday',
'address' => 'Address',
'dismission' => 'Dismission',
];
}
}
This is my view
<?php
/* #var $this yii\web\View */
/* #var $form yii\bootstrap\ActiveForm */
/* #var $model \frontend\models\SignupForm */
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use yii\helpers\ArrayHelper;
use frontend\models\Countries;
use frontend\models\States;
use frontend\models\Cities;
use yii\helpers\Url;
$this->title = 'Signup';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-signup">
<h1><?= Html::encode($this->title) ?></h1>
<p>Please fill out the following fields to signup:</p>
<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(['id' => 'form-signup', 'enableAjaxValidation' => true, 'validationUrl' => Url::toRoute('site/validation')]); ?>
<?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?>
<?= $form->field($model, 'name')->textInput(['autofocus' => true]) ?>
<?= $form->field($model, 'lastname')->textInput(['autofocus' => true]) ?>
<?= $form->field($model, 'email') ?>
<?= $form->field($model, 'phone')->textInput(['autofocus' => true]) ?>
<?= $form->field($model, 'company')->textInput(['autofocus' => true]) ?>
<?= $form->field($model, 'password_hash')->passwordInput()->label('Password') ?>
<?= $form->field($model, 'country')->dropDownList(ArrayHelper::map(Countries::find()->all(),'id','name'),
[
'prompt' => 'Страна',
'onchange' => '
$.post( "../states/lists?id='.'"+$(this).val(), function( data ) {
$( "select#signupform-state" ).html( data );
});'
]); ?>
<?= $form->field($model, 'state')->dropDownList([],
[
'prompt' => 'Регион',
'onchange' => '
$.post( "../cities/lists?id='.'"+$(this).val(), function( data ) {
$( "select#signupform-city" ).html( data );
});'
]); ?>
<?= $form->field($model, 'city')->dropDownList([],[ 'prompt' => 'Город' ]); ?>
<?= $form->field($model, 'language')->dropDownList([
'1' => 'Русский',
'2' => 'English',
'3' => 'Turkce',
]); ?>
<div class="form-group">
<?= Html::submitButton('Signup', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
</div>
SiteController.php
public function actionSignup()
{
$model = new SignupForm();
if ($model->load(Yii::$app->request->post())) {
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
return \yii\bootstrap\ActiveForm::validate($model);
}
if ($user = $model->signup()) {
if (Yii::$app->getUser()->login($user)) {
return $this->goHome();
}
}
}
return $this->render('signup', [
'model' => $model,
]);
}
SignUpForm.php
public function rules()
{
return [
['username', 'filter', 'filter' => 'trim'],
['username', 'required'],
['username', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This username has already been taken.'],
['username', 'string', 'min' => 2, 'max' => 255],
['email', 'filter', 'filter' => 'trim'],
['email', 'required'],
['email', 'email'],
['email', 'string', 'max' => 255],
['email', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This email address has already been taken.'],
['password', 'required'],
['password', 'string', 'min' => 6],
];
}
/**
* Signs user up.
*
* #return User|null the saved model or null if saving fails
*/
public function signup()
{
if (!$this->validate()) {
return null;
}
$user = new User();
$user->username = $this->username;
$user->email = $this->email;
$user->setPassword($this->password);
$user->generateAuthKey();
return $user->save() ? $user : null;
}
signup.php
<?php $form = ActiveForm::begin(['id' => 'form-signup', 'enableAjaxValidation' => true]); ?>
I am importing some customers with :
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customerFactory = $objectManager->create('\Magento\Customer\Model\CustomerFactory');
$customer = $objectManager->create('Magento\Customer\Model\Customer')->setWebsiteId(1)->loadByEmail('customrr#custom.com');
try {
if(!empty($customer->getData('email')))
{
$customer->setAttr1(1); // Attr1 = Name of the custom Attribute
$customer->setAttr2(2); // Attr2 = Name of the custom Attribute
}
else
{
$customer = $customerFactory->create()->setWebsiteId(1);
}
$customer->setLastname("Lastname");
$customer->setFirstname("Firsty");
.....
$customer->save();
The customer is saved with all his standard attributes correctly but my new attributes won't be saved anyway. I've also tried :
$customer->setCustomAttribute('Attr1','value');
but this didn't work too.
The custom Attribute are shown correclty in Magentos 2 backoffice and the values are saved correctly too if creating a customer manually.
Have you tried:
$customer-> setData('Attr1','value');
and don't forget to save and log the information:
try {
$customer->save();
} catch (\Exception $e) {
// log exception so you can debug the issue if there is one
}
<?php
namespace Custom\Module\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]);
$eavSetup->addAttribute(\Magento\Customer\Model\Customer::ENTITY, 'custom_attribute', [
'label' => 'Label',
'system' => 0,
'position' => 720,
'sort_order' => 720,
'visible' => true,
'note' => '',
'type' => 'int',
'input' => 'boolean',
'source' => 'Magento\Eav\Model\Entity\Attribute\Source\Boolean',
'backend' => \Custom\Module\Model\Customer\Attribute\Backend\DoWHatEver::class,
]
);
$attribute = $this->getEavConfig()->getAttribute(\Magento\Customer\Model\Customer::ENTITY, 'custom_attribute');
$attribute->addData([
'is_user_defined' => 1,
'is_required' => 0,
'default_value' => 0,
'used_in_forms', ['adminhtml_customer']
])->save();
}
public function getEavConfig()
{
return $this->eavConfig;
}
}