В
ข้อจำกัดความรับผิดชอบ: Magento มีฟังก์ชันสำเร็จรูปสำหรับ
โค้ดที่เกิดจากการเขียนทั้งสองบทความสามารถดูได้ในโมดูล Magento "
- สินค้าจัดทำขึ้นเท่านั้น ไม่มีการอัพเดต
- โกดังแห่งหนึ่ง
- นำเข้าเฉพาะชื่อหมวดหมู่เท่านั้น โดยไม่มีโครงสร้าง
- โครงสร้างข้อมูลสอดคล้องกับเวอร์ชัน 2.3
JSON สำหรับการนำเข้าผลิตภัณฑ์เดียว:
{
"sku": "MVA20D-UBV-3",
"name": "Заглушка для пломбировки ВА47-29 IEK",
"desc": "Обеспечение доступа к устройствам ...",
"desc_short": "Заглушка для пломбировки ВА47-29 IEK предназначена для ...",
"price": 5.00,
"qty": 25,
"categories": ["Категория 1", "Категория 2"],
"image_path": "mva20d_ubv_3.png"
}
ภาพรวมของขั้นตอนหลักของการนำเข้า
- การลงทะเบียนผลิตภัณฑ์นั้นเอง
- การเชื่อมต่อระหว่างผลิตภัณฑ์และเว็บไซต์
- คุณลักษณะของผลิตภัณฑ์ขั้นพื้นฐาน (EAV)
- ข้อมูลสินค้าคงคลัง (จำนวนสินค้าในสต็อก)
- สื่อ (ภาพ)
- การเชื่อมต่อกับหมวดหมู่แคตตาล็อก
การลงทะเบียนผลิตภัณฑ์
ข้อมูลผลิตภัณฑ์เบื้องต้นสามารถพบได้ใน catalog_product_entity
:
CREATE TABLE `catalog_product_entity` (
`entity_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Entity Id',
`attribute_set_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Attribute Set ID',
`type_id` varchar(32) NOT NULL DEFAULT 'simple' COMMENT 'Type ID',
`sku` varchar(64) DEFAULT NULL COMMENT 'SKU',
`has_options` smallint(6) NOT NULL DEFAULT '0' COMMENT 'Has Options',
`required_options` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Required Options',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Creation Time',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Update Time',
PRIMARY KEY (`entity_id`),
KEY `CATALOG_PRODUCT_ENTITY_ATTRIBUTE_SET_ID` (`attribute_set_id`),
KEY `CATALOG_PRODUCT_ENTITY_SKU` (`sku`)
)
ข้อมูลขั้นต่ำที่จำเป็นในการสร้างรายการในการลงทะเบียนผลิตภัณฑ์คือ:
attribute_set_id
sku
เพิ่มเติม:
type_id
— หากเราไม่ระบุ ก็จะใช้ 'simple'
หากต้องการเขียนลงฐานข้อมูลโดยตรง ฉันใช้อะแดปเตอร์ DB ของ Magento เอง:
function create($sku, $typeId, $attrSetId)
{
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$table = $this->resource->getTableName('catalog_product_entity');
$bind = [
'sku' => $sku,
'type_id' => $typeId,
'attribute_set_id' => $attrSetId
];
$conn->insert($table, $bind);
$result = $conn->lastInsertId($table);
return $result;
}
หลังจากลงทะเบียนผลิตภัณฑ์กับ catalog_product_entity
จะปรากฏให้เห็นในแผงผู้ดูแลระบบในตารางผลิตภัณฑ์ (แคตตาล็อก/ผลิตภัณฑ์).
ความสัมพันธ์ระหว่างผลิตภัณฑ์และเว็บไซต์
การเชื่อมโยงระหว่างผลิตภัณฑ์กับไซต์จะเป็นตัวกำหนดว่าร้านค้าและการแสดงผลิตภัณฑ์จะมีจำหน่ายที่ด้านหน้าร้านใด
function linkToWebsite($prodId, $websiteId)
{
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$table = $this->resource->getTableName('catalog_product_website');
$bind = [
'product_id' => $prodId,
'website_id' => $websiteId
];
$conn->insert($table, $bind);
}
คุณสมบัติพื้นฐานของผลิตภัณฑ์
สินค้าที่ลงทะเบียนใหม่ยังไม่มีชื่อหรือคำอธิบาย ทั้งหมดนี้ทำผ่าน
name
price
description
short_description
status
tax_class_id
url_key
visibility
มีการเพิ่มแอตทริบิวต์แยกต่างหากให้กับผลิตภัณฑ์เช่นนี้ (รายละเอียดของการรับตัวระบุและประเภทของแอตทริบิวต์จากรหัสจะถูกละเว้น):
public function create($prodId, $attrCode, $attrValue)
{
$attrId = /* get attribute ID by attribute code */
$attrType = /* get attribute type [datetime|decimal|int|text|varchar]) by attribute code */
if ($attrId) {
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$tblName = 'catalog_product_entity_' . $attrType;
$table = $this->resource->getTableName($tblName);
$bind = [
'attribute_id' => $attrId,
'entity_id' => $prodId,
/* put all attributes to default store view with id=0 (admin) */
'store_id' => 0,
'value' => $attrValue
];
$conn->insert($table, $bind);
}
}
เมื่อใช้รหัสแอตทริบิวต์ เราจะกำหนดรหัสและประเภทข้อมูล (datetime
, decimal
, int
, text
, varchar
) จากนั้นเขียนข้อมูลสำหรับหน้าต่างผู้ดูแลระบบลงในตารางที่เหมาะสม (store_id = 0
).
หลังจากเพิ่มคุณสมบัติข้างต้นให้กับผลิตภัณฑ์แล้ว คุณจะได้ภาพนี้ในแผงผู้ดูแลระบบ:
ข้อมูลสินค้าคงคลัง
เริ่มต้นจากเวอร์ชัน 2.3 ใน Magento มีชุดตารางคู่ขนานสองชุดที่ให้การจัดเก็บข้อมูลสินค้าคงคลัง (ปริมาณผลิตภัณฑ์):
cataloginventory_*
: โครงสร้างเก่า;inventory_*
: โครงสร้างใหม่ (MSI - Multi Source Inventory);
คุณต้องเพิ่มข้อมูลสินค้าคงคลังให้กับทั้งสองโครงสร้าง เนื่องจาก โครงสร้างใหม่ยังไม่เป็นอิสระจากโครงสร้างเก่าอย่างสมบูรณ์ (มีแนวโน้มมากที่จะทำเช่นนั้น default
คลังสินค้าในโครงสร้างใหม่ที่เกี่ยวข้องกับตาราง cataloginventory_stock_status
ในขณะที่ inventory_stock_1
).
แคตตาล็อกสินค้าคงคลัง_
เมื่อปรับใช้ Magneto 2.3 ในตอนแรกเรามี 2 รายการ store_website
ซึ่งสอดคล้องกับสองไซต์ - ผู้ดูแลระบบและไคลเอนต์หลัก:
website_id|code |name |sort_order|default_group_id|is_default|
----------|-----|------------|----------|----------------|----------|
0|admin|Admin | 0| 0| 0|
1|base |Main Website| 0| 1| 1|
ตาราง cataloginventory_stock
เรามีเพียงหนึ่งรายการเท่านั้น:
stock_id|website_id|stock_name|
--------|----------|----------|
1| 0|Default |
นั่นคือในโครงสร้างเก่าของเรามี "โกดัง" เพียงแห่งเดียว (stock
) และเชื่อมโยงกับเว็บไซต์ผู้ดูแลระบบ การเพิ่มใหม่ผ่านแผงผู้ดูแลระบบ sources
/stocks
ใน MSI (โครงสร้างใหม่) ไม่ส่งผลให้มีรายการใหม่เข้ามา cataloginventory_stock
.
ข้อมูลสินค้าคงคลังเกี่ยวกับผลิตภัณฑ์ในโครงสร้างเก่าจะถูกบันทึกในตารางตั้งแต่แรก:
cataloginventory_stock_item
cataloginventory_stock_status
แคตตาล็อกinventory_stock_item
function createOldItem($prodId, $qty)
{
$isQtyDecimal = (((int)$qty) != $qty);
$isInStock = ($qty > 0);
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$table = $this->resource->getTableName('cataloginventory_stock_item');
$bind = [
'product_id' => $prodId,
/* we use one only stock in 'cataloginventory' structure by default */
'stock_id' => 1,
'qty' => $qty,
'is_qty_decimal' => $isQtyDecimal,
'is_in_stock' => $isInStock,
/* default stock is bound to admin website (see `cataloginventory_stock`) */
'website_id' => 0
];
$conn->insert($table, $bind);
}
แคตตาล็อกinventory_stock_status
function createOldStatus($prodId, $qty)
{
$isInStock = ($qty > 0);
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$table = $this->resource->getTableName('cataloginventory_stock_status');
$bind = [
'product_id' => $prodId,
/* we use one only stock in 'cataloginventory' structure by default */
'stock_id' => 1,
'qty' => $qty,
'stock_status' => MagentoCatalogInventoryApiDataStockStatusInterface::STATUS_IN_STOCK,
/* default stock is bound to admin website (see `cataloginventory_stock`) */
'website_id' => 0
];
$conn->insert($table, $bind);
}
รายการสิ่งของ_
เบื้องต้นโครงสร้างใหม่ในการจัดเก็บข้อมูลสินค้าคงคลังประกอบด้วย 1"แหล่ง"(inventory_source
):
source_code|name |enabled|description |latitude|longitude|country_id|...|
-----------|--------------|-------|--------------|--------|---------|----------|...|
default |Default Source| 1|Default Source|0.000000| 0.000000|US |...|
และหนึ่ง "คลังสินค้า"(inventory_stock
):
stock_id|name |
--------|-------------|
1|Default Stock|
«Источник» หมายถึงการจัดเก็บทางกายภาพของผลิตภัณฑ์ (บันทึกประกอบด้วยพิกัดทางกายภาพและที่อยู่ทางไปรษณีย์) "คลังสินค้า"เป็นการรวมตัวกันทางตรรกะของ "แหล่งที่มา" หลายแห่ง (inventory_source_stock_link
)
link_id|stock_id|source_code|priority|
-------|--------|-----------|--------|
1| 1|default | 1|
ในระดับที่มีการเชื่อมต่อกับช่องทางการขายเกิดขึ้น (inventory_stock_sales_channel
)
type |code|stock_id|
-------|----|--------|
website|base| 1|
เมื่อพิจารณาจากโครงสร้างข้อมูล ถือว่าช่องทางการขายประเภทต่างๆ แต่โดยค่าเริ่มต้นจะมีเพียงการเชื่อมต่อเท่านั้น”สต็อก"-"เว็บไซต์“(ลิงค์ไปยังเว็บไซต์เป็นไปตามรหัสเว็บไซต์ - base
).
หนึ่ง "คลังสินค้า"สามารถเชื่อมโยงได้หลายแบบ"แหล่งที่มา"และหนึ่ง "แหล่ง" - ถึงหลาย ๆ "คลังสินค้า"(ความสัมพันธ์แบบกลุ่มต่อกลุ่ม) ข้อยกเว้นเป็นค่าเริ่มต้น "แหล่ง"และ"คลังสินค้า". พวกเขาไม่ได้เชื่อมโยงกับเอนทิตีอื่น ๆ อีกครั้ง (ข้อจำกัดในระดับรหัส - ข้อผิดพลาด “ไม่สามารถบันทึกลิงค์ที่เกี่ยวข้องกับแหล่งที่มาเริ่มต้นหรือสต็อกเริ่มต้นได้") รายละเอียดเพิ่มเติมเกี่ยวกับโครงสร้าง MSI ใน Magento 2 สามารถพบได้ในบทความ “
ฉันจะใช้การกำหนดค่าเริ่มต้นและเพิ่มข้อมูลสินค้าคงคลังทั้งหมดลงในแหล่งที่มา default
ซึ่งเกี่ยวข้องกับช่องทางการขายที่เกี่ยวข้องกับเว็บไซต์ด้วยรหัส base
(ตรงกับส่วนหน้าของร้าน - ดู store_website
):
function createNewItem($sku, $qty)
{
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$table = $this->resource->getTableName('inventory_source_item');
$bind = [
'source_code' => 'default',
'sku' => $sku,
'quantity' => $qty,
'status' => MagentoInventoryApiApiDataSourceItemInterface::STATUS_IN_STOCK
];
$conn->insert($table, $bind);
}
หลังจากเพิ่มข้อมูลสินค้าคงคลังให้กับผลิตภัณฑ์ในแผงผู้ดูแลระบบ คุณจะได้ภาพนี้:
สื่อ
เมื่อเพิ่มรูปภาพลงในผลิตภัณฑ์ "ด้วยตนเอง" ผ่านแผงผู้ดูแลระบบ ข้อมูลที่เกี่ยวข้องจะถูกเขียนลงในตารางต่อไปนี้:
catalog_product_entity_media_gallery
: ทะเบียนสื่อ (ไฟล์ภาพและวิดีโอ);catalog_product_entity_media_gallery_value
: การเชื่อมโยงสื่อกับผลิตภัณฑ์และการนำเสนอ (การแปลเป็นภาษาท้องถิ่น)catalog_product_entity_media_gallery_value_to_entity
: การเชื่อมโยงสื่อกับผลิตภัณฑ์เท่านั้น (น่าจะเป็นเนื้อหาสื่อเริ่มต้นสำหรับผลิตภัณฑ์)catalog_product_entity_varchar
: บทบาทที่ใช้รูปภาพจะถูกจัดเก็บไว้ที่นี่
และรูปภาพเหล่านั้นจะถูกบันทึกลงในไดเร็กทอรี ./pub/media/catalog/product/x/y/
ที่ไหน x
и y
— ตัวอักษรตัวแรกและตัวที่สองของชื่อไฟล์ภาพ ตัวอย่างเช่น ไฟล์ image.png
ควรบันทึกเป็น ./pub/media/catalog/product/i/m/image.png
เพื่อให้แพลตฟอร์มสามารถใช้เป็นรูปภาพในการอธิบายผลิตภัณฑ์จากแค็ตตาล็อกได้
Catalog_product_entity_media_gallery
ลงทะเบียนโพสต์ใน ./pub/media/catalog/product/
ไฟล์สื่อ (ขั้นตอนการวางไฟล์นั้นไม่ได้กล่าวถึงในบทความนี้):
function createMediaGallery($imgPathPrefixed)
{
$attrId = /* get attribute ID by attribute code 'media_gallery' */
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$table = $this->resource->getTableName('catalog_product_entity_media_gallery');
$bind = [
'attribute_id' => $attrId,
'value' => $imgPathPrefixed,
/* 'image' or 'video' */
'media_type' => 'image',
'disabled' => false
];
$conn->insert($table, $bind);
$result = $conn->lastInsertId($table);
return $result;
}
เมื่อลงทะเบียน ไฟล์มีเดียใหม่จะถูกกำหนดตัวระบุ
Catalog_product_entity_media_gallery_value
เราเชื่อมโยงไฟล์สื่อที่ลงทะเบียนกับผลิตภัณฑ์ที่เกี่ยวข้องสำหรับหน้าร้านเริ่มต้น:
function createGalleryValue($mediaId, $prodId)
{
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$table = $this->resource->getTableName('catalog_product_entity_media_gallery_value');
$bind = [
'value_id' => $mediaId,
/* use admin store view by default */
'store_id' => 0,
'entity_id' => $prodId,
'label' => null,
/* we have one only image */
'position' => 1,
'disabled' => false
];
$conn->insert($table, $bind);
}
Catalog_product_entity_media_gallery_value_to_entity
เราเชื่อมโยงไฟล์สื่อที่ลงทะเบียนกับผลิตภัณฑ์ที่เกี่ยวข้องโดยไม่เชื่อมโยงกับหน้าร้านใดๆ ไม่ชัดเจนว่าข้อมูลนี้ถูกใช้ที่ใดและเหตุใดจึงไม่สามารถเข้าถึงข้อมูลจากตารางก่อนหน้าได้ แต่มีตารางนี้อยู่และข้อมูลจะถูกเขียนลงไปเมื่อมีการเพิ่มรูปภาพลงในผลิตภัณฑ์ แค่นั้นแหละ.
function createGalleryValueToEntity($mediaId, $prodId)
{
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$table = $this->resource->getTableName('catalog_product_entity_media_gallery_value_to_entity');
$bind = [
'value_id' => $mediaId,
'entity_id' => $prodId
];
$conn->insert($table, $bind);
}
Catalog_product_entity_varchar
ไฟล์สื่อสามารถใช้ได้กับบทบาทที่แตกต่างกัน (รหัสคุณลักษณะที่เกี่ยวข้องจะระบุไว้ในวงเล็บ):
- ฐาน(
image
) - รูปภาพขนาดเล็ก (
small_image
) - ภาพขนาดย่อ (
thumbnail
) - รูปภาพสวอตช์ (
swatch_image
)
การเชื่อมโยงบทบาทกับไฟล์สื่อคือสิ่งที่เกิดขึ้นอย่างแน่นอน catalog_product_entity_varchar
. รหัสการผูกจะคล้ายกับรหัสใน "คุณสมบัติพื้นฐานของผลิตภัณฑ์"
หลังจากเพิ่มรูปภาพให้กับผลิตภัณฑ์ในแผงผู้ดูแลระบบ จะมีลักษณะดังนี้:
หมวดหมู่
ตารางหลักที่มีข้อมูลตามหมวดหมู่:
catalog_category_entity
: ทะเบียนหมวดหมู่;catalog_category_product
: การเชื่อมโยงระหว่างผลิตภัณฑ์และหมวดหมู่catalog_category_entity_*
: ค่าแอตทริบิวต์ EAV;
เริ่มแรกในแอปพลิเคชัน Magento ที่ว่างเปล่า การลงทะเบียนหมวดหมู่ประกอบด้วย 2 หมวดหมู่ (ฉันย่อชื่อคอลัมน์ให้สั้นลง: crt
- created_at
, upd
- updated_at
):
entity_id|attribute_set_id|parent_id|crt|upd|path|position|level|children_count|
---------|----------------|---------|---|---|----|--------|-----|--------------|
1| 3| 0|...|...|1 | 0| 0| 1|
2| 3| 1|...|...|1/2 | 1| 1| 0|
หมวดหมู่ที่มี id=1 เป็นรากของแค็ตตาล็อก Magento ทั้งหมด และไม่มีอยู่ในแผงผู้ดูแลระบบหรือในหน้าแรก หมวดหมู่ที่มี id=2 (เริ่มต้นหมวดหมู่) เป็นหมวดหมู่รูทสำหรับร้านค้าหลักของเว็บไซต์หลัก (ร้านค้าเว็บไซต์หลัก) สร้างขึ้นเมื่อมีการปรับใช้แอปพลิเคชัน (ดู ผู้ดูแลระบบ / ร้านค้า / ร้านค้าทั้งหมด). นอกจากนี้ หมวดหมู่รากของร้านค้ายังไม่มีให้บริการที่ด้านหน้า มีเพียงหมวดหมู่ย่อยเท่านั้น
เนื่องจากหัวข้อของบทความนี้ยังคงนำเข้าข้อมูลเกี่ยวกับผลิตภัณฑ์อยู่ ฉันจะไม่ใช้การป้อนข้อมูลโดยตรงในฐานข้อมูลเมื่อสร้างหมวดหมู่ แต่จะใช้คลาสที่ Magento จัดเตรียมไว้ให้ (โมเดลและที่เก็บ) การป้อนข้อมูลโดยตรงลงในฐานข้อมูลใช้เพื่อเชื่อมโยงผลิตภัณฑ์ที่นำเข้ากับหมวดหมู่เท่านั้น (หมวดหมู่จะถูกจับคู่ตามชื่อ และรหัสหมวดหมู่จะถูกดึงข้อมูลระหว่างการจับคู่):
function create($prodId, $catId)
{
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$table = $this->resource->getTableName('catalog_category_product');
$bind = [
'category_id' => $catId,
'product_id' => $prodId,
];
$conn->insert($table, $bind);
}
หลังจากเพิ่มลิงค์ผลิตภัณฑ์ไปยังหมวดหมู่ “หมวดหมู่ 1” และ “หมวดหมู่ 2” แล้ว รายละเอียดสินค้าในแผงผู้ดูแลระบบจะมีลักษณะดังนี้:
การดำเนินการเพิ่มเติม
เมื่อการนำเข้าข้อมูลเสร็จสมบูรณ์ คุณจะต้องทำตามขั้นตอนเพิ่มเติมต่อไปนี้:
- การจัดทำดัชนีข้อมูล: โทรในคอนโซล
./bin/magento indexer:reindex
; - การสร้าง URL ใหม่สำหรับผลิตภัณฑ์/หมวดหมู่: คุณสามารถใช้ส่วนขยาย “
elgentos/สร้างใหม่-แคตตาล็อก-urls «
ผลิตภัณฑ์ในแผงผู้ดูแลระบบหลังจากดำเนินการเพิ่มเติม:
และที่ด้านหน้า:
สรุป
ชุดผลิตภัณฑ์เดียวกัน (10 ชิ้น) เช่นเดียวกับในบทความก่อนหน้านี้นำเข้าอย่างน้อยลำดับความสำคัญเร็วกว่า (1 วินาทีต่อ 10) หากต้องการประมาณความเร็วได้แม่นยำยิ่งขึ้น คุณต้องมีผลิตภัณฑ์จำนวนมากขึ้น - หลายร้อยรายการหรือดีกว่าหลายพันรายการ อย่างไรก็ตาม แม้ว่าข้อมูลอินพุตจะมีขนาดเล็ก แต่เราก็สามารถสรุปได้ว่าการใช้เครื่องมือที่ Magento มอบให้ (แบบจำลองและแหล่งเก็บข้อมูล) นั้นมีความสำคัญ (ฉันเน้นย้ำ - มาก!) เร่งการพัฒนาฟังก์ชันที่จำเป็น แต่ในขณะเดียวกันก็สำคัญมาก (ฉันเน้นย้ำ - มาก!) ลดความเร็วที่ข้อมูลเข้าสู่ฐานข้อมูล
เป็นผลให้น้ำกลายเป็นเปียกและนี่ไม่ใช่การเปิดเผย อย่างไรก็ตาม ตอนนี้ฉันมีโค้ดให้เล่นแล้ว และบางทีก็ได้ข้อสรุปที่น่าสนใจกว่านี้
ที่มา: will.com