Magento自定义模块InstallData无法创建客户自定义属性问题求助
步骤1:清理残留旧数据
你仅删除了setup_module表记录,但eav_attribute表中可能已经存在my_telephone属性,InstallData只会在属性不存在时执行创建,所以先执行以下SQL清理无效数据,避免安装逻辑被跳过:
-- 查询属性是否存在 SELECT * FROM eav_attribute WHERE attribute_code = 'my_telephone' AND entity_type_id = (SELECT entity_type_id FROM eav_entity_type WHERE entity_type_code = 'customer'); -- 如果有返回结果,执行删除(替换<attribute_id>为查询到的ID) DELETE FROM eav_attribute WHERE attribute_id = <attribute_id>; DELETE FROM customer_entity_int WHERE attribute_id = <attribute_id>; -- 确认模块安装记录已删除 DELETE FROM setup_module WHERE module = 'Vendor_RewardPoints';
步骤2:修正InstallData.php代码
主要修正属性类型错误(电话号码不适合用int存储),补充前台可见配置,补全适配的表单场景:
<?php namespace Vendor\RewardPoints\Setup; use Magento\Customer\Setup\CustomerSetupFactory; use Magento\Customer\Model\Customer; use Magento\Eav\Model\Entity\Attribute\SetFactory as AttributeSetFactory; use Magento\Framework\Setup\InstallDataInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; class InstallData implements InstallDataInterface { protected $customerSetupFactory; private $attributeSetFactory; public function __construct( CustomerSetupFactory $customerSetupFactory, AttributeSetFactory $attributeSetFactory ) { $this->customerSetupFactory = $customerSetupFactory; $this->attributeSetFactory = $attributeSetFactory; } public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context) { $customerSetup = $this->customerSetupFactory->create(['setup' => $setup]); $customerEntity = $customerSetup->getEavConfig()->getEntityType('customer'); $attributeSetId = $customerEntity->getDefaultAttributeSetId(); $attributeSet = $this->attributeSetFactory->create(); $attributeGroupId = $attributeSet->getDefaultGroupId($attributeSetId); $customerSetup->addAttribute(Customer::ENTITY, 'my_telephone', [ 'type' => 'varchar', 'label' => 'My telephone', 'input' => 'text', 'required' => false, 'visible' => true, 'user_defined' => true, 'sort_order' => 1000, 'is_used_in_grid' => 1, 'is_visible_in_grid' => 1, 'is_filterable_in_grid' => 1, 'is_searchable_in_grid' => 1, 'visible_on_front' => true, 'position' => 1000, 'length' => 20, 'default' => '', 'system' => 0, ]); $attribute = $customerSetup->getEavConfig()->getAttribute(Customer::ENTITY, 'my_telephone') ->addData([ 'attribute_set_id' => $attributeSetId, 'attribute_group_id' => $attributeGroupId, 'used_in_forms' => ['adminhtml_customer', 'customer_account_create', 'customer_account_edit'], ]); $attribute->save(); } }
步骤3:新增后台客户编辑页展示配置
Magento 2.2及以上版本需要单独配置UI组件才能在后台客户编辑页展示属性,新增文件app/code/Vendor/RewardPoints/view/base/ui_component/customer_form.xml:
<?xml version="1.0" encoding="UTF-8"?> <form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd"> <fieldset name="customer"> <field name="my_telephone" formElement="input"> <settings> <dataType>text</dataType> <label translate="true">My telephone</label> <visible>true</visible> <required>false</required> </settings> </field> </fieldset> </form>
步骤4:新增前台表单适配逻辑
如果需要在注册页、个人中心编辑页展示和保存该属性,需要补充以下配置:
4.1 新增布局配置
- 注册页布局文件:
app/code/Vendor/RewardPoints/view/frontend/layout/customer_account_create.xml
<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="form.additional.info"> <block class="Magento\Framework\View\Element\Template" name="my.telephone.register" template="Vendor_RewardPoints::field/my_telephone.phtml"/> </referenceContainer> </body> </page>
- 个人中心编辑页布局文件:
app/code/Vendor/RewardPoints/view/frontend/layout/customer_account_edit.xml
<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="form.additional.info"> <block class="Magento\Framework\View\Element\Template" name="my.telephone.edit" template="Vendor_RewardPoints::field/my_telephone_edit.phtml"/> </referenceContainer> </body> </page>
4.2 新增模板文件
- 注册页模板:
app/code/Vendor/RewardPoints/view/frontend/templates/field/my_telephone.phtml
<div class="field my_telephone"> <label class="label" for="my_telephone"><span><?= $block->escapeHtml(__('My telephone')) ?></span></label> <div class="control"> <input type="text" name="my_telephone" id="my_telephone" value="<?= $block->escapeHtmlAttr($block->getFormData()->getMyTelephone()) ?>" title="<?= $block->escapeHtmlAttr(__('My telephone')) ?>" class="input-text"> </div> </div>
- 个人中心编辑页模板:
app/code/Vendor/RewardPoints/view/frontend/templates/field/my_telephone_edit.phtml
<div class="field my_telephone"> <label class="label" for="my_telephone"><span><?= $block->escapeHtml(__('My telephone')) ?></span></label> <div class="control"> <input type="text" name="my_telephone" id="my_telephone" value="<?= $block->escapeHtmlAttr($block->getCustomer()->getCustomAttribute('my_telephone')?->getValue()) ?>" title="<?= $block->escapeHtmlAttr(__('My telephone')) ?>" class="input-text"> </div> </div>
4.3 新增属性保存逻辑
新增事件配置文件app/code/Vendor/RewardPoints/etc/frontend/events.xml,处理前台提交的属性值保存:
<?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="save_my_telephone_register" instance="Vendor\RewardPoints\Observer\SaveMyTelephoneRegister"/> </event> <event name="customer_save_before"> <observer name="save_my_telephone_edit" instance="Vendor\RewardPoints\Observer\SaveMyTelephoneEdit"/> </event> </config>
对应观察者类自行实现逻辑,从请求参数中获取my_telephone值赋值给客户对象即可。
步骤5:重新执行安装命令
bin/magento setup:upgrade bin/magento cache:flush # 生产环境需额外执行编译命令 bin/magento setup:di:compile bin/magento setup:static-content:deploy -f
内容的提问来源于stack exchange,提问作者user2217288
相关产品推荐
相关产品推荐

