Magento 2: hilberên rasterast di databasê de derxînin

В gotara berê Min pêvajoya anîna hilberan li Magento 2 bi awayê asayî - bi navgîniya model û depoyan vegot. Rêbaza asayî xwedan leza hilberandina daneyê pir kêm e. Laptopa min di çirkeyê de bi qasî yek hilberek hilberand. Di vê domandinê de, ez rêyek alternatîf dihesibînim ku hilberek derxîne - bi ketina rasterast a databasê, bi derbaskirina mekanîzmayên standard Magento 2 (model, kargeh, depo). Rêzeya gavên ji bo importkirina hilberan dikare bi her zimanê bernamesaziyê yê ku dikare bi MySQL re bixebite were adapte kirin.

Disclaimer: Magento ji bo fonksiyonek amade ye data import û, bi îhtîmaleke mezin, ew ê bes ji we re be. Lêbelê, heke hûn hewceyê kontrolek bêkêmasî ya li ser pêvajoya importê hewce ne, ne bi amadekirina pelê CSV-ê ji bo tiştê ku we heye, bi xêr hatî pisîkê.

Magento 2: hilberên rasterast di databasê de derxînin

Koda ku ji nivîsandina her du gotaran pêk tê dikare di modula Magento de were dîtin "flancer32/mage2_ext_demo_import". Li vir hin qedexeyên ku min şopandin hene ku koda modula demo hêsan bikim:

  • Berhem tenê têne afirandin, nayên nûve kirin.
  • Yek embar
  • Tenê navên kategoriyan, bêyî strukturên wan, têne derxistin
  • Strukturên daneyê bi guhertoya 2.3 re tevdigerin

JSON ji bo importkirina hilberek yekane:

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

Pêşniyara qonaxên sereke yên importê

  • qeydkirina hilberê bixwe
  • girêdana di navbera hilber û malperê de
  • taybetmendiyên hilberê bingehîn (EAV)
  • Daneyên envanterê (hejmara hilberê di stokê de)
  • medya (wêne)
  • girêdana bi kategoriyên katalogê

Registration Product

Agahdariya hilberê ya bingehîn dikare di nav de were dîtin 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`)
)

Agahdariya herî hindik a ku ji bo afirandina têketinek di tomariya hilberê de hewce dike ev e:

  • attribute_set_id
  • sku

biserre:

  • type_id - Ger em wê diyar nekin, wê hingê dê "hêsan" were bikar anîn

Ji bo ku rasterast li databasê binivîsim, ez adapterê DB-ya Magento bixwe bikar tînim:

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

Piştî tomarkirina hilberê bi catalog_product_entity ew di panela rêveberiyê de, di tora hilberê de xuya dibe (Katalog / Berhemên).

Magento 2: hilberên rasterast di databasê de derxînin

Têkiliya di navbera hilber û malperê de

Têkiliya hilberê bi malperê re diyar dike ku dê hilber li pêşiyê li kîjan firotgehan û pêşangehan peyda bibe.

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: hilberên rasterast di databasê de derxînin

Taybetmendiyên hilberê yên bingehîn

Berhema ku nû hatî tomarkirin hêj navek an şiroveyek tune ye. Ev hemû bi rê ve tê kirin taybetmendiyên EAV. Li vir navnîşek taybetmendiyên hilberê bingehîn hene ku ji bo ku hilber li pêşiyê rast were xuyang kirin hewce ne:

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

Taybetmendiyek veqetandî li hilberek bi vî rengî tê zêdekirin (hûrguliyên wergirtina nasnav û celebê taybetmendiyê ji koda wê têne derxistin):

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

Bi karanîna koda taybetmendiyê, em nasnameya wê û celebê daneyê diyar dikin (datetime, decimal, int, text, varchar), dûv re daneyên pencereya îdarî li tabloya guncan binivîsin (store_id = 0).

Piştî ku taybetmendiyên jorîn li hilberê zêde bikin, hûn vê wêneyê di panelê rêveberiyê de digirin:

Magento 2: hilberên rasterast di databasê de derxînin

Daneyên envanterê

Ji guhertoya 2.3-ê di Magento-yê de dest pê dike, du komên tabloyên paralel hene ku hilanîna agahdariya depoyê (hejmara hilberê) peyda dikin:

  • cataloginventory_*: avahiya kevn;
  • inventory_*: avahiya nû (MSI - Enventory Pir Çavkaniyê);

Pêdivî ye ku hûn daneya tomarê li her du avahiyan zêde bikin, ji ber avahiya nû hîn bi tevahî ji ya kevin ne serbixwe ye (pir îhtîmal e ku ji bo default embar di avahiya nû de tabloyek tê de heye cataloginventory_stock_status dema inventory_stock_1).

cataloginventory_

Dema ku Magneto 2.3 bicîh dikin di destpêkê de me 2 têketin hene store_website, ku bi du malperan re têkildar e - xerîdar îdarî û sereke:

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

Mêz cataloginventory_stock me tenê yek têketin heye:

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

Ango, di avahiya meya kevn de tenê yek "ambar" heye (stock) û ew bi malpera îdarî ve girêdayî ye. Zêdekirina yên nû bi navgîniya panela rêveberiyê sources/stocks di MSI de (avahiyeke nû) di nav de têketinên nû dernakeve cataloginventory_stock.

Daneyên envanterê yên derbarê hilberên di avahiya kevn de di destpêkê de di tabloyan de têne tomar kirin:

  • cataloginventory_stock_item
  • cataloginventory_stock_status

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

enventory_

Di destpêkê de, avahiyek nû ya ji bo hilanîna daneyên depoyê 1 "dihewîne.çavkaniyê"(inventory_source):

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

û yek"warehouse"(inventory_stock):

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

«Çavkaniya» hilanîna laşî ya hilberan nîşan dide (qeyda hevrêzên laşî û navnîşana posteyê dihewîne). "Embar"yekîtiyek mantiqî ya çend "çavkaniyan" e (inventory_source_stock_link)

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

di asta ku tê de girêdana bi kanala firotanê re çêdibe (inventory_stock_sales_channel)

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

Li gorî avahiya daneyê dadbar kirin, cûrbecûr kanalên firotanê têne hesibandin, lê ji hêla xwerû ve tenê pêwendiya "embar"-"malpera"(girêdana malperê koda malperê dişopîne - base).

Yek "warehouse"Dikare bi çend kesan ve were girêdan"çavkaniyên"û yek"çavkaniyê"- ji çendan re"embarên"(têkiliya pir-bi-gelek). Îstîsnayên xwerû ne"çavkaniyê"And"warehouse". Ew ji nû ve bi saziyên din ve nayên girêdan (sînorkirin di asta kodê de - xeletî "Nikare lînka têkildar bi Çavkaniya Pêşniyaz an Stocka Pêşnuma ve hilîne"). Zêdetir hûrguliyên di derbarê strukturên MSI de li Magento 2 dikarin di gotarê de werin dîtin "Pergala rêveberiya wargehê ku CQRS û Çavkaniya Bûyerê bikar tîne. Mînakkirin".

Ez ê veavakirina xwerû bikar bînim û hemî agahdariya envanterê li çavkaniyê zêde bikim default, ku di kanala firotanê de bi malperê re bi kodê ve girêdayî ye base (bi dawiya pêşîn a dikanê re têkildar e - binêre 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);
}

Piştî ku di panela rêveberê de daneyên depoyê li hilberê zêde bikin, hûn vê wêneyê digirin:

Magento 2: hilberên rasterast di databasê de derxînin

Medya

Dema ku "bi destan" wêneyek bi navgîniya panela rêveberiyê ve li hilberek zêde dike, agahdariya têkildar di tabloyên jêrîn de têne nivîsandin:

  • catalog_product_entity_media_gallery: qeydkirina medyayê (wêne û pelên vîdyoyê);
  • catalog_product_entity_media_gallery_value: girêdana medyayê bi berhem û pêşangehan re (herêmîkirin);
  • catalog_product_entity_media_gallery_value_to_entity: girêdana medyayê tenê bi hilberan re (dibe ku naveroka medyaya xwerû ya ji bo hilberê);
  • catalog_product_entity_varchar: Rolên ku wêne tê de têne bikar anîn li vir têne tomar kirin;

û wêneyên xwe li pelrêçê têne tomar kirin ./pub/media/catalog/product/x/y/ko x и y - Tîpên yekem û duyemîn ên navê pelê wêneyê. Mînakî, pel image.png divê wekî xilas bibe ./pub/media/catalog/product/i/m/image.png, da ku platform dema ku hilberên ji katalogê vedibêje wê wekî wêneyek bikar bîne.

Qeyd tê de hatî şandin ./pub/media/catalog/product/ pelê medyayê (pêvajoya danîna pelê bixwe di vê gotarê de nayê nîqaş kirin):

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

Dema ku tê qeyd kirin, pelek medyayê ya nû nasnameyek tê veqetandin.

Em pelê medyaya qeydkirî ji bo pêşangeha xwerû bi hilbera têkildar re têkildar dikin:

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

Em pelê medyaya qeydkirî bi hilbera têkildar re bêyî ku bi tu firotgehê ve girêdayî bin ve girêdidin. Ne diyar e ku bi rastî ev dane li ku derê têne bikar anîn û çima ne gengaz e ku meriv xwe bigihîne daneyên tabloya berê, lê ev tablo heye û dema ku wêneyek li hilberê were zêdekirin data li ser tê nivîsandin. Îcar ew e.

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

Pelek medyayê dikare bi rolên cihêreng were bikar anîn (koda taybetmendiyê ya têkildar di nav parantezê de tê destnîşan kirin):

  • Bingeh(image)
  • Wêne biçûk (small_image)
  • Thumbnail (thumbnail)
  • Swatch Image (swatch_image)

Girêdana rolan bi pelek medyayê re tam tiştê ku diqewime ye catalog_product_entity_varchar. Koda girêdanê dişibe koda "Taybetmendiyên hilberê yên bingehîn".

Piştî ku di panela rêveberiyê de wêneyek li hilberê zêde bike, wusa xuya dike:

Magento 2: hilberên rasterast di databasê de derxînin

Kategorî

Tabloyên sereke yên ku daneyan li gorî kategoriyê vedihewîne:

  • catalog_category_entity: qeyda kategoriyan;
  • catalog_category_product: girêdana di navbera hilber û kategoriyan de;
  • catalog_category_entity_*: Nirxên taybetmendiya EAV;

Di destpêkê de, di serîlêdanek Magento ya vala de, tomara kategoriyê 2 kategorî dihewîne (min navên stûnan kurt kir: 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|

Kategoriya bi id=1 koka tevahiya kataloga Magento ye û ne di panela rêveberiyê de ne jî li ser rûpelê pêşîn peyda nabe. Kategorî bi id=2 (Kategoriya Default) ji bo dikana sereke ya malpera sereke kategoriya root e (Store Malpera Sereke) dema ku serîlêdan tête danîn hate afirandin (binêre. Rêvebir / Firotan / Hemî Firotan). Wekî din, kategoriya root ya firotgehê bixwe jî li pêşiyê tune, tenê binkategoriyên wê hene.

Ji ber ku mijara vê gotarê hîn jî daneyên li ser hilberan îtxal dike, ez ê gava ku kategoriyan biafirînim rasterast têketina databasê bikar nekim, lê ez ê dersên ku ji hêla Magento bixwe ve hatine peyda kirin (model û depo) bikar bînim. Têketina rasterast a databasê tenê ji bo girêdana hilbera hatî import bi kategoriyek re tê bikar anîn (kategorî bi navê xwe ve tête hev kirin, û id kategoriyê di dema hevgirtinê de tê wergirtin):

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

Piştî lê zêdekirina girêdanek hilberek li kategoriyên "Kategorî 1" û "Kategorî 2", hûrguliyên hilberê di panela rêveberiyê de tiştek wusa xuya dike:

Magento 2: hilberên rasterast di databasê de derxînin

Çalakiyên pêvek

Piştî ku ketina daneyê qediya, hûn hewce ne ku gavên din ên jêrîn biqedînin:

  • Indeksa daneyan: di konsolê de bang bikin ./bin/magento indexer:reindex;
  • ji bo hilberan/kategoriyan URL-yên ji nû ve çêdikin: hûn dikarin pêvekê bikar bînin "elgentos / nûjen-katalog-url«

Hilberên di panelê rêveberiyê de piştî pêkanîna çalakiyên din:

Magento 2: hilberên rasterast di databasê de derxînin

û li pêş:

Magento 2: hilberên rasterast di databasê de derxînin

Nîqaş

Heman berhevoka hilberan (10 perçe) wekî di gotara berê de bi kêmî ve rêzek mezinahiyê zûtir tê import kirin (1 çirke li hember 10). Ji bo ku hûn bilez texmîn bikin, hûn hewceyê hejmareke mezin a hilberan in - çend sed, an jî çêtir bi hezaran. Lêbelê, tevî piçûkek piçûk a daneya têketinê jî, em dikarin encam bidin ku karanîna amûrên ku ji hêla Magento ve têne peyda kirin (model û depo) girîng e (Ez tekez dikim - pir!) lezkirina pêşveçûna fonksiyona pêwîst, lê di heman demê de girîng (ez tekez dikim - pir!) leza ku dane têkevin databasê kêm bikin.

Di encamê de av şil bû û ev ne eşkere ye. Lêbelê, naha koda min heye ku ez pê re bilîzim û dibe ku ez bigihîjim hin encamên balkêş.

Source: www.habr.com

Add a comment