Magento 2: enpòte pwodwi dirèkteman nan baz done a

В atik anvan Mwen dekri pwosesis la nan enpòte pwodwi nan Magento 2 nan fason nòmal la - atravè modèl ak depo. Metòd nòmal la gen yon vitès trè ba pwosesis done. Laptop mwen an te pwodwi apeprè yon pwodwi pou chak segonn. Nan kontinyasyon sa a, mwen konsidere yon fason altènatif enpòte yon pwodwi - pa antre dirèk nan baz done a, contournement estanda Magento 2 mekanis yo (modèl, faktori, depo). Sekans etap pou enpòte pwodwi yo ka adapte ak nenpòt langaj pwogramasyon ki ka travay avèk MySQL.

Avètisman: Magento gen fonctionnalités pare pou enpòte done epi, gen plis chans, li pral ase pou ou. Sepandan, si ou bezwen plis kontwòl nèt sou tout pwen sou pwosesis enpòte, pa limite pou prepare yon fichier CSV pou sa ou genyen, akeyi pou chat.

Magento 2: enpòte pwodwi dirèkteman nan baz done a

Kòd ki soti nan ekri tou de atik yo ka wè nan modil Magento "flancer32/mage2_ext_demo_import". Men kèk restriksyon mwen te swiv pou senplifye kòd modil Demo a:

  • Pwodwi yo sèlman kreye, pa mete ajou.
  • Yon sèl depo
  • Se sèlman non kategori yo enpòte, san yo pa estrikti yo
  • Estrikti done yo konfòme yo ak vèsyon 2.3

JSON pou enpòte yon sèl pwodwi:

{
  "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"
}

Apèsi sou etap prensipal yo nan enpòte

  • enskripsyon nan pwodwi nan tèt li
  • koneksyon ant pwodwi ak sit entènèt
  • atribi debaz pwodwi yo (EAV)
  • done envantè (kantite pwodwi nan stock)
  • medya (foto)
  • koneksyon ak kategori katalòg

Enskripsyon pwodwi

Ou ka jwenn enfòmasyon debaz sou pwodwi nan 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`)
)

Enfòmasyon minimòm ki nesesè pou kreye yon antre nan rejis pwodwi a se:

  • attribute_set_id
  • sku

adisyonèl:

  • type_id - si nou pa presize li, Lè sa a, 'senp' yo pral itilize

Pou ekri dirèkteman nan baz done a, mwen itilize adaptè DB Magento tèt li:

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;
}

Apre enskripsyon pwodwi a ak catalog_product_entity li vin vizib nan panèl admin, nan kadriyaj pwodwi a (Katalòg/Pwodwi).

Magento 2: enpòte pwodwi dirèkteman nan baz done a

Relasyon ant pwodwi ak sit entènèt

Asosyasyon an nan pwodwi a ak sit la detèmine nan ki magazen ak montre pwodwi a ap disponib nan devan an.

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);
}

Magento 2: enpòte pwodwi dirèkteman nan baz done a

Atribi debaz pwodwi yo

Pwodwi ki fèk anrejistre a poko gen yon non oswa yon deskripsyon. Tout bagay sa a se fè nan Atribi EAV. Isit la se yon lis atribi debaz pwodwi ki nesesè pou pwodwi a ka parèt kòrèkteman sou devan an:

  • name
  • price
  • description
  • short_description
  • status
  • tax_class_id
  • url_key
  • visibility

Yon atribi separe yo ajoute nan yon pwodwi tankou sa a (detay yo nan jwenn idantifyan an ak kalite atribi a nan kòd li yo omisyon):

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);
    }
}

Sèvi ak kòd atribi a, nou detèmine id li ak kalite done (datetime, decimal, int, text, varchar), Lè sa a, ekri done yo pou fenèt administratif la nan tablo ki apwopriye a (store_id = 0).

Apre ou fin ajoute atribi ki anwo yo nan pwodwi a, ou jwenn foto sa a nan panèl admin:

Magento 2: enpòte pwodwi dirèkteman nan baz done a

Done envantè

Kòmanse soti nan vèsyon 2.3 nan Magento, gen de seri paralèl tab ki bay depo enfòmasyon envantè (kantite pwodwi):

  • cataloginventory_*: ansyen estrikti;
  • inventory_*: nouvo estrikti (MSI - Multi Source Inventory);

Ou bezwen ajoute done envantè nan tou de estrikti, paske nouvo estrikti a poko konplètman endepandan de ansyen an (li trè posib ke pou default depo nan estrikti nan nouvo yon tab ki enplike cataloginventory_stock_status kòm inventory_stock_1).

catalogueinventory_

Lè nou deplwaye Magneto 2.3 okòmansman nou gen 2 antre nan store_website, ki koresponn ak de sit - administratif ak kliyan prensipal:

website_id|code |name        |sort_order|default_group_id|is_default|
----------|-----|------------|----------|----------------|----------|
         0|admin|Admin       |         0|               0|         0|
         1|base |Main Website|         0|               1|         1|

Tablo cataloginventory_stock nou gen yon sèl antre:

stock_id|website_id|stock_name|
--------|----------|----------|
       1|         0|Default   |

Sa vle di, nan ansyen estrikti nou an gen yon sèl "depo" (stock) epi li lye ak sit entènèt administratif la. Ajoute nouvo nan panèl admin sources/stocks nan MSI (nouvo estrikti) pa lakòz nouvo antre nan cataloginventory_stock.

Done envantè sou pwodwi nan ansyen estrikti a okòmansman anrejistre nan tablo:

  • cataloginventory_stock_item
  • cataloginventory_stock_status

catalogueinventory_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);
}

cataloginventory_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);
}

envantè_

Okòmansman, nouvo estrikti pou estoke done envantè gen 1 "sous'(inventory_source):

source_code|name          |enabled|description   |latitude|longitude|country_id|...|
-----------|--------------|-------|--------------|--------|---------|----------|...|
default    |Default Source|      1|Default Source|0.000000| 0.000000|US        |...|

ak youn"depo'(inventory_stock):

stock_id|name         |
--------|-------------|
       1|Default Stock|

«Sous» reprezante depo fizik pou pwodwi yo (dosye a gen kowòdone fizik ak adrès postal). "Depo"se yon inyon lojik nan plizyè "sous" (inventory_source_stock_link)

link_id|stock_id|source_code|priority|
-------|--------|-----------|--------|
      1|       1|default    |       1|

nan nivo kote koneksyon ak chanèl lavant la rive (inventory_stock_sales_channel)

type   |code|stock_id|
-------|----|--------|
website|base|       1|

Jije pa estrikti done a, yo sipoze divès kalite lavant chanèl, men pa default sèlman koneksyon an "aksyon"-"sit entènèt"(Lyen ki mennen nan sit entènèt la swiv kòd sit entènèt la - base).

Youn"depo"kapab lye ak plizyè"sous"ak youn"sous"-a plizyè"depo"(relasyon anpil-a-anpil). Eksepsyon yo se default "sous"Ak"depo". Yo pa relye ak lòt antite (limitasyon nan nivo kòd - erè a "Pa ka sove lyen ki gen rapò ak Default Sous oswa Default Stock"). Ou ka jwenn plis detay sou estrikti MSI nan Magento 2 nan atik la "Sistèm jesyon depo lè l sèvi avèk CQRS ak Evènman Sourcing. Design".

Mwen pral sèvi ak konfigirasyon default la epi ajoute tout enfòmasyon envantè nan sous la default, ki patisipe nan chanèl lavant ki asosye ak sit entènèt la ak kòd la base (korespondan ak fen devan magazen an - gade 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);
}

Apre ou fin ajoute done envantè nan pwodwi a nan panèl admin, ou jwenn foto sa a:

Magento 2: enpòte pwodwi dirèkteman nan baz done a

Medya

Lè "manyèlman" ajoute yon imaj nan yon pwodwi atravè panèl admin, enfòmasyon ki enpòtan yo ekri nan tablo sa yo:

  • catalog_product_entity_media_gallery: rejis medya (imaj ak dosye videyo);
  • catalog_product_entity_media_gallery_value: lyen medya ak pwodwi ak vitrin (lokalizasyon);
  • catalog_product_entity_media_gallery_value_to_entity: ki lye medya ak pwodwi sèlman (sitou kontni medya default pou pwodwi a);
  • catalog_product_entity_varchar: Wòl yo itilize imaj la yo estoke isit la;

ak imaj yo tèt yo yo sove nan anyè a ./pub/media/catalog/product/x/y/kote x и y — premye ak dezyèm lèt non fichye imaj la. Pou egzanp, dosye image.png ta dwe sove kòm ./pub/media/catalog/product/i/m/image.png, se konsa ke platfòm la ka itilize li kòm yon imaj lè dekri pwodwi ki soti nan katalòg la.

Enskri afiche nan ./pub/media/catalog/product/ Fichye medya (pwosesis pou mete dosye a li menm pa diskite nan atik sa a):

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;
}

Lè w anrejistre, yon nouvo fichye medya yo bay yon idantifyan.

Nou asosye dosye medya ki anrejistre a ak pwodwi ki koresponn lan pou devan magazen default la:

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);
}

Nou asosye dosye medya anrejistre a ak pwodwi ki koresponn lan san nou pa mare nan okenn devan magazen. Li pa klè ki kote egzakteman done sa yo itilize ak poukisa li enposib jwenn aksè nan done ki nan tablo anvan an, men tab sa a egziste epi done yo ekri nan li lè yo ajoute yon foto nan pwodwi a. Se konsa, se li.

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);
}

catalogue_product_entity_varchar

Ou ka itilize yon fichye medya ak diferan wòl (kòd atribi ki koresponn lan endike nan parantèz):

  • baz(image)
  • Ti imaj (small_image)
  • Miniature (thumbnail)
  • Swatch imaj (swatch_image)

Relye wòl nan yon dosye medya se egzakteman sa k ap pase nan catalog_product_entity_varchar. Kòd obligatwa a sanble ak kòd ki nan "Atribi debaz pwodwi yo".

Apre ou fin ajoute yon imaj nan pwodwi a nan panèl administratè a, li sanble sa a:

Magento 2: enpòte pwodwi dirèkteman nan baz done a

Категории

Tablo prensipal ki gen done pa kategori:

  • catalog_category_entity: enskri kategori;
  • catalog_category_product: koneksyon ant pwodwi ak kategori;
  • catalog_category_entity_*: valè atribi EAV;

Okòmansman, nan yon aplikasyon Magento vid, rejis kategori a gen 2 kategori (mwen diminye non kolòn yo: 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|

Kategori ki gen id=1 se rasin tout katalòg Magento a epi li pa disponib ni nan panèl admin ni nan paj devan an. Kategori ak id=2 (Kategori Default) se kategori rasin pou magazen prensipal sit la (Prensipal sit entènèt magazen) kreye lè aplikasyon an deplwaye (gade. Admin / Magazen / Tout Magazen). Anplis, kategori rasin magazen an li menm tou pa disponib nan devan an, se sèlman sous-kategori li yo.

Depi sijè atik sa a toujou ap enpòte done sou pwodwi yo, mwen pa pral sèvi ak antre dirèk nan baz done a lè m ap kreye kategori, men mwen pral sèvi ak klas Magento yo bay li menm (modèl ak depo). Antre dirèk nan baz done a itilize sèlman pou asosye pwodwi enpòte a ak yon kategori (kategori a matche ak non li, epi yo jwenn id kategori a pandan matche):

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);
}

Apre ou fin ajoute yon lyen pwodwi nan kategori "Kategori 1" ak "Kategori 2", detay pwodwi yo nan panèl administratè a gade yon bagay tankou sa a:

Magento 2: enpòte pwodwi dirèkteman nan baz done a

Aksyon adisyonèl

Yon fwa enpòte done a fini, ou bezwen ranpli etap adisyonèl sa yo:

  • Indexing done: rele nan konsole a ./bin/magento indexer:reindex;
  • rejenerasyon URL pou pwodwi/kategori: ou ka itilize ekstansyon "elgentos/regenerate-catalog-urls«

Pwodwi nan panèl admin apre ou fin fè lòt aksyon:

Magento 2: enpòte pwodwi dirèkteman nan baz done a

ak devan an:

Magento 2: enpòte pwodwi dirèkteman nan baz done a

Rezime

Se menm seri pwodwi (10 moso) tankou nan atik anvan an enpòte omwen yon lòd nan grandè pi vit (1 segonn kont 10). Pou plis presizyon estime vitès la, ou bezwen yon pi gwo kantite pwodwi - plizyè santèn, oswa pi byen ankò dè milye. Sepandan, menm avèk yon ti gwosè done antre, nou ka konkli ke itilizasyon zouti Magento yo bay (modèl ak depo) enpòtan anpil (mwen mete aksan sou - anpil!) akselere devlopman nan fonksyonalite ki nesesè yo, men an menm tan an anpil (mwen mete aksan sou - anpil!) redwi vitès done yo antre nan baz done a.

Kòm yon rezilta, dlo a te tounen mouye epi sa a se pa yon revelasyon. Sepandan, kounye a mwen gen kòd la yo jwe ak petèt vini nan kèk konklizyon ki pi enteresan.

Sous: www.habr.com