社区版只能在后台创建产品属性,其他的比如customer
/category
属性只能用代码来创建。
因为product
/customer
/category
都是eav模型结构,所以要创建属性。也就是把属性存到对应的eav属性值表里去。
比如customer
属性,是varchar
的话,它的属性值就保存在customer_entity_varchar
里。
虽然eav_entity_type
表里也有order
/invoice
/creditmemo
/shipment
这些实体。
但是这几个实体 不是把属性值存到对应的属性值表里 而是当作字段存在实体表里的。
比如order
的属性是直接保存在sales_order
表里的。
可能是magento官方觉得order
/invoice
/creditmemo
/shipment
这些实体没必要搞那么麻烦 没必要保存到对应的属性值表里 就直接保存在实体表里了。
所以你如果要想创建order
属性的话,直接创建字段就行了,具体的可以谷歌下。
我还是在插件Zou_Demo
里写代码,因为这插件已经装过了,所以代码需要写在Setup/UpgradeData.php
里。相当于是升级数据脚本。
我需要创建的属性清单为:
实体 | 属性code | 属性label | 属性值类型(type) | 前台显示类型(input) | 备注 |
---|---|---|---|---|---|
product | colours_and_materials | Colours And Materials | text | textarea文本框 | 需要开启所见即所得编辑器 |
product | subtitle | Subtitle | varchar | text输入框 | |
category | display_small_image | Display Small Image | int | select下拉框 | |
category | small_image | Small Image | varchar | image图片 | |
customer | customer_code | Customer Code | varchar | text输入框 |
好了,开始写代码了。
第一步 写升级脚本代码
<?php
namespace Zou\Demo\Setup;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\UpgradeDataInterface;
// use Magento\Framework\Setup\SchemaSetupInterface;
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\Quote\Setup\QuoteSetupFactory;
use Magento\Sales\Setup\SalesSetupFactory;
use Magento\Catalog\Setup\CategorySetupFactory;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
/**
* @codeCoverageIgnore
*/
class UpgradeData implements UpgradeDataInterface
{
protected $salesSetupFactory;
/**
* @var CustomerSetupFactory
*/
protected $customerSetupFactory;
protected $schemaSetup;
private $categorySetupFactory;
private $eavSetupFactory;
private $attributeSetFactory;
protected $quoteSetupFactory;
public function __construct(
SalesSetupFactory $salesSetupFactory,
CustomerSetupFactory $customerSetupFactory,
AttributeSetFactory $attributeSetFactory,
CategorySetupFactory $categorySetupFactory,
EavSetupFactory $eavSetupFactory,
QuoteSetupFactory $quoteSetupFactory
// SchemaSetupInterface $schemaSetup
) {
$this->customerSetupFactory = $customerSetupFactory;
$this->attributeSetFactory = $attributeSetFactory;
$this->categorySetupFactory = $categorySetupFactory;
$this->eavSetupFactory = $eavSetupFactory;
$this->quoteSetupFactory = $quoteSetupFactory;
$this->salesSetupFactory = $salesSetupFactory;
// $this->schemaSetup = $schemaSetup;
}
/**
* {@inheritdoc}
*/
public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
if (version_compare($context->getVersion(), '0.1.1', '<')) {
//代码写在这里
}
$setup->endSetup();
}
代码写在:
if (version_compare($context->getVersion(), '0.1.1', '<')) {
//代码写在这里
}
这个0.1.1
是什么意思呢?
因为我这插件当前版本是
0.1.0
,(不清楚的可以看插件的module.xml
)。
如果你不把版本号改高点的话,代码是不会执行进来的,因为数据库setup_module
表里的Zou_Demo
记录的版本还是0.1.0
。
你把module.xml
的版本改高后,系统才会识别到你有数据来更新,才会执行进来。执行没问题的话,系统就会把setup_module
表里的Zou_Demo
的版本改成0.1.1
。
所以我这里的意思是:当版本为0.1.1
的时候就执行这里的代码。
具体代码如下:
public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
if (version_compare($context->getVersion(), '0.1.1', '<')) {
$attributes = array(
'subtitle' => array(
'type' => 'varchar',
'label' => 'Subtitle',
'input' => 'text',
),
'colours_and_materials' => array(
'type' => 'text',
'label' => 'Colours And Materials',
'input' => 'textarea',
'wysiwyg_enabled'=>true, //这个用来开启所见即所得编辑器的.要text类型才行。
'group'=>'Content'//放到Content组下面去,后台产品编辑页面会看到`Content`这个组的
)
);
$this->createProductAttribute($setup, $attributes);
$attributes = array(
'small_image' => array(
'type' => 'varchar',
'label' => 'Small Image',
'input' => 'image',
'group'=>'Content', //放到Content组下面去,后台分类编辑页面会看到`Content`这个组的
'sort_order'=>6, //给属性设置排序,越大就放在越后面
'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE,
'backend' => 'Magento\Catalog\Model\Category\Attribute\Backend\Image'
),
'display_small_image' => array(
'type' => 'int',
'label' => 'Display Small Image',
'input' => 'boolean',//这个boolean就是0和1这2个选项,magento会转换成select下拉框
'group'=>'Content',//放到Content组下面去,后台分类编辑页面会看到`Content`这个组的
'sort_order' => 9,//给属性设置排序,越大就放在越后面
'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE,
),
);
$this->createCategoryAttribute($setup, $attributes);
$attributes = array(
'customer_code' => array(
'type' => 'varchar',
'label' => 'Customer Code',
'input' => 'text',
)
);
$this->createCustomerAttribute($setup, $attributes);
}
$setup->endSetup();
}
注意:我这里封装了创建属性的函数。具体代码见插件demo。
第二步 修改module.xml
的版本号
代码写完后,就修改module.xml
,把版本号改成0.1.1
。
如果不改这里的版本号的话,系统是不是会执行的。具体原因我上面有写。
<?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="Zou_Demo" schema_version="0.1.1" setup_version="0.1.1">
...
第三步 执行升级数据的命令
php bin/magento setup:upgrade
没报错的话 就说明已经升级数据成功了。
打开数据库eav_attribute
表就可以看到最新添加的属性了。
第四步 测试
产品属性:
- 直接打开后台产品新建/编辑页面就可以看到新添加的属性了
分类属性:
- 后台分类新建/编辑页面没有新添加的属性,需要写
ui_component
代码
vim 插件目录/view/adminhtml/ui_component/category_form.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<fieldset name="content">
<field name="display_small_image">
<argument name="data" xsi:type="array">
<item name="options" xsi:type="object">Magento\Eav\Model\Entity\Attribute\Source\Boolean</item>
<item name="config" xsi:type="array">
<item name="sortOrder" xsi:type="number">33</item>
<item name="dataType" xsi:type="string">string</item>
<item name="formElement" xsi:type="string">select</item>
<item name="label" xsi:type="string" translate="true">Display Small Image</item>
<item name="default" xsi:type="number">0</item>
</item>
</argument>
</field>
<field name="small_image">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="dataType" xsi:type="string">string</item>
<item name="source" xsi:type="string">category</item>
<item name="label" xsi:type="string" translate="true">Small Image</item>
<item name="visible" xsi:type="boolean">true</item>
<item name="formElement" xsi:type="string">fileUploader</item>
<item name="elementTmpl" xsi:type="string">ui/form/element/uploader/uploader</item>
<item name="previewTmpl" xsi:type="string">Magento_Catalog/image-preview</item>
<item name="required" xsi:type="boolean">false</item>
<item name="sortOrder" xsi:type="number">34</item>
<item name="uploaderConfig" xsi:type="array">
<item name="url" xsi:type="url" path="catalog/category_image/upload"/>
</item>
</item>
</argument>
</field>
</fieldset>
</form>
customer属性:
- 直接打开后台customer新建/编辑页面 就可以看到新添加的属性了
具体的代码见插件demo
https://gitee.com/zouhongzhao/magento2-action-extension-demo
<?php
namespace Zou\Demo\Setup;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\UpgradeDataInterface;
// use Magento\Framework\Setup\SchemaSetupInterface;
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\Quote\Setup\QuoteSetupFactory;
use Magento\Sales\Setup\SalesSetupFactory;
use Magento\Catalog\Setup\CategorySetupFactory;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
/**
* @codeCoverageIgnore
*/
class UpgradeData implements UpgradeDataInterface
{
protected $salesSetupFactory;
/**
* @var CustomerSetupFactory
*/
protected $customerSetupFactory;
protected $schemaSetup;
private $categorySetupFactory;
private $eavSetupFactory;
private $attributeSetFactory;
protected $quoteSetupFactory;
public function __construct(
SalesSetupFactory $salesSetupFactory,
CustomerSetupFactory $customerSetupFactory,
AttributeSetFactory $attributeSetFactory,
CategorySetupFactory $categorySetupFactory,
EavSetupFactory $eavSetupFactory,
QuoteSetupFactory $quoteSetupFactory
// SchemaSetupInterface $schemaSetup
) {
$this->customerSetupFactory = $customerSetupFactory;
$this->attributeSetFactory = $attributeSetFactory;
$this->categorySetupFactory = $categorySetupFactory;
$this->eavSetupFactory = $eavSetupFactory;
$this->quoteSetupFactory = $quoteSetupFactory;
$this->salesSetupFactory = $salesSetupFactory;
// $this->schemaSetup = $schemaSetup;
}
/**
* {@inheritdoc}
*/
public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
if (version_compare($context->getVersion(), '0.1.1', '<')) {
$attributes = array(
'subtitle' => array(
'type' => 'varchar',
'label' => 'Subtitle',
'input' => 'text',
),
'colours_and_materials' => array(
'type' => 'text',
'label' => 'Colours And Materials',
'input' => 'textarea',
'wysiwyg_enabled'=>true, //这个用来开启所见即所得编辑器的.要text类型才行。
'group'=>'Content'//放到Content组下面去,后台产品编辑页面会看到`Content`这个组的
)
);
$this->createProductAttribute($setup, $attributes);
$attributes = array(
'small_image' => array(
'type' => 'varchar',
'label' => 'Small Image',
'input' => 'image',
'group'=>'Content', //放到Content组下面去,后台分类编辑页面会看到`Content`这个组的
'sort_order'=>6, //给属性设置排序,越大就放在越后面
'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE,
'backend' => 'Magento\Catalog\Model\Category\Attribute\Backend\Image'
),
'display_small_image' => array(
'type' => 'int',
'label' => 'Display Small Image',
'input' => 'boolean',//这个boolean就是0和1这2个选项,magento会转换成select下拉框
'group'=>'Content',//放到Content组下面去,后台分类编辑页面会看到`Content`这个组的
'sort_order' => 9,//给属性设置排序,越大就放在越后面
'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE,
),
);
$this->createCategoryAttribute($setup, $attributes);
$attributes = array(
'customer_code' => array(
'type' => 'varchar',
'label' => 'Customer Code',
'input' => 'text',
)
);
$this->createCustomerAttribute($setup, $attributes);
}
$setup->endSetup();
}
function createCustomerAttribute($setup,$attributes) {
$customerSetup = $this->customerSetupFactory->create(['resourceName' => 'customer_setup','setup' => $setup]);
$customerEntity = $customerSetup->getEavConfig()->getEntityType('customer');
$attributeSetId = $customerEntity->getDefaultAttributeSetId();
$attributeGroupId = $this->attributeSetFactory->create()->getDefaultGroupId($attributeSetId);
$aScope = \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL;
foreach ($attributes as $code=>$_attribute){
if(isset($_attribute['type']) && $_attribute['type']
&& isset($_attribute['input']) && $_attribute['input']
&& isset($_attribute['label']) && $_attribute['label']
){
$input = $_attribute['input'];
if ($input == "boolean") {
$_attribute['source'] = "Magento\Eav\Model\Entity\Attribute\Source\Boolean";
}
$customerSetup->addAttribute(
\Magento\Customer\Model\Customer::ENTITY,
$code,
[
'type' => $_attribute['type'],
'label' => $_attribute['label'],
'input' => $_attribute['input'],
'backend' => isset($_attribute['backend'])?$_attribute['backend']:null,
'required' => isset($_attribute['required'])?$_attribute['required']:false,
'global' => isset($_attribute['global'])?$_attribute['global']:$aScope,
'source' => isset($_attribute['source'])?$_attribute['source']:'',
'wysiwyg_enabled'=>isset($_attribute['wysiwyg_enabled'])?$_attribute['wysiwyg_enabled']:false,
'visible' => true,
'user_defined' => true,
'sort_order' => isset($_attribute['sort_order'])?$_attribute['sort_order']:1000,
'position' => isset($_attribute['sort_order'])?$_attribute['sort_order']:1000,
'system' => 0,
]
);
// more used_in_forms ['adminhtml_checkout','adminhtml_customer','adminhtml_customer_address','customer_account_edit','customer_address_edit','customer_register_address']
$customerAttribute = $customerSetup->getEavConfig()->getAttribute(Customer::ENTITY, $code)
->addData([
'attribute_set_id' => $attributeSetId,
'attribute_group_id' => $attributeGroupId,
'used_in_forms' => ['adminhtml_customer','customer_account_edit','customer_account_create'],
]);
$customerAttribute->save();
}
}
}
function createProductAttribute($setup,$attributes) {
$eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
$aScope = \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL;
foreach ($attributes as $code=>$_attribute){
if(isset($_attribute['type']) && $_attribute['type']
&& isset($_attribute['input']) && $_attribute['input']
&& isset($_attribute['label']) && $_attribute['label']
){
$input = $_attribute['input'];
if ($input == "boolean") {
$_attribute['source'] = "Magento\Eav\Model\Entity\Attribute\Source\Boolean";
}
$eavSetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY, $code, [
'group' => isset($_attribute['group'])?$_attribute['group']:'General',
'type' => $_attribute['type'],
'label' => $_attribute['label'],
'input' => $_attribute['input'],
'backend' => isset($_attribute['backend'])?$_attribute['backend']:null,
'required' => isset($_attribute['required'])?$_attribute['required']:false,
'sort_order' => isset($_attribute['sort_order'])?$_attribute['sort_order']:1000,
'user_defined' => isset($_attribute['user_defined'])?$_attribute['user_defined']:true,
'global' => isset($_attribute['global'])?$_attribute['global']:$aScope,
'used_in_product_listing' => true,
'visible' => true,
'source' => isset($_attribute['source'])?$_attribute['source']:'',
'wysiwyg_enabled'=>isset($_attribute['wysiwyg_enabled'])?$_attribute['wysiwyg_enabled']:false,
'default' => isset($_attribute['default'])?$_attribute['default']:null
]
);
}
}
}
function createCategoryAttribute($setup,$attributes) {
$categorySetup = $this->categorySetupFactory->create(['setup' => $setup]);
$aScope = \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL;
foreach ($attributes as $code=>$_attribute){
if(isset($_attribute['type']) && $_attribute['type']
&& isset($_attribute['input']) && $_attribute['input']
&& isset($_attribute['label']) && $_attribute['label']
){
$input = $_attribute['input'];
if ($input == "boolean") {
$_attribute['source'] = "Magento\Eav\Model\Entity\Attribute\Source\Boolean";
}
$categorySetup->addAttribute(
\Magento\Catalog\Model\Category::ENTITY, $code, [
'group' => isset($_attribute['group'])?$_attribute['group']:'General Information',
'type' => $_attribute['type'],
'label' => $_attribute['label'],
'input' => $_attribute['input'],
'backend' => isset($_attribute['backend'])?$_attribute['backend']:null,
'required' => isset($_attribute['required'])?$_attribute['required']:false,
'sort_order' => isset($_attribute['sort_order'])?$_attribute['sort_order']:1000,
'user_defined' => isset($_attribute['user_defined'])?$_attribute['user_defined']:true,
'global' => isset($_attribute['global'])?$_attribute['global']:$aScope,
'used_in_product_listing' => isset($_attribute['used_in_product_listing'])?$_attribute['used_in_product_listing']:true,
'is_used_in_grid' => isset($_attribute['is_used_in_grid'])?$_attribute['is_used_in_grid']:true,
'is_visible_in_grid' => isset($_attribute['is_visible_in_grid'])?$_attribute['is_visible_in_grid']:false,
'is_filterable_in_grid' => isset($_attribute['is_filterable_in_grid'])?$_attribute['is_filterable_in_grid']:true,
'visible' => true,
'source' => isset($_attribute['source'])?$_attribute['source']:'',
'wysiwyg_enabled'=>isset($_attribute['wysiwyg_enabled'])?$_attribute['wysiwyg_enabled']:false,
'default' => isset($_attribute['default'])?$_attribute['default']:null
]
);
}
}
}
function removeAttribute($setup, $codes = array(), $type = 'product'){
$entityTypeCode = false;
switch ($type) {
case 'category':
$entityTypeCode = \Magento\Catalog\Model\Category::ENTITY;
break;
case 'customer':
$entityTypeCode = \Magento\Customer\Model\Customer::ENTITY;
break;
case 'product':
$entityTypeCode = \Magento\Catalog\Model\Product::ENTITY;
break;
default:
$entityTypeCode = false;
break;
}
if($entityTypeCode && $codes){
if(!is_array($codes)){
$codes = array($codes);
}
$eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
//$entityTypeId = $eavSetup->getEntityType($entityTypeCode);
foreach ($codes as $code){
$eavSetup->removeAttribute($entityTypeCode, $code);
}
}
}
}
复制
如果本文档还不能解决你的问题的话,先谷歌一下,不懂的再问我。