Magento 2: manafatra vokatra mivantana ao anaty angon-drakitra

Π’ lahatsoratra teo aloha Nofaritako tamin'ny fomba mahazatra ny fizotran'ny fanafarana vokatra ao amin'ny Magento 2 - amin'ny alΓ lan'ny modely sy fitahirizana. Ny fomba mahazatra dia manana hafainganam-pandehan'ny fanodinana data tena ambany. Namokatra vokatra iray isan-tsegondra teo ho eo ny solosainako. Amin'ity tohiny ity dia mihevitra fomba hafa hanafatra vokatra aho - amin'ny fidirana mivantana amin'ny angon-drakitra, mandingana ny mekanika Magento 2 mahazatra (modely, orinasa, tahiry). Ny filaharan'ny dingana hanafatra vokatra dia azo ampifanarahana amin'ny fiteny fandaharana izay afaka miasa amin'ny MySQL.

Disclaimer: Magento dia manana fiasa efa vita ho an'ny fanafarana data ary azo inoana fa ho ampy ho anao izany. Na izany aza, raha mila fanaraha-maso feno kokoa amin'ny fizotran'ny fanafarana ianao, tsy voafetra amin'ny fanomanana rakitra CSV ho an'izay anananao, tongasoa eto amin'ny saka.

Magento 2: manafatra vokatra mivantana ao anaty angon-drakitra

Ny kaody vokatry ny fanoratana lahatsoratra roa dia azo jerena ao amin'ny Module Magento "flancer32/mage2_ext_demo_import". Ireto misy fameperana vitsivitsy narahiko mba hanatsorana ny code module demo:

  • Ny vokatra dia noforonina fotsiny fa tsy nohavaozina.
  • Trano fanatobiana entana iray
  • Anaran'ny sokajy ihany no nafarana, tsy misy rafitra
  • Ny rafitra data dia mifanaraka amin'ny dikan-teny 2.3

JSON amin'ny fanafarana vokatra tokana:

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

Fijerena ireo dingana lehibe amin'ny fanafarana

  • fisoratana anarana ny vokatra mihitsy
  • fifandraisana eo amin'ny vokatra sy ny tranokala
  • toetra vokatra fototra (EAV)
  • angon-drakitra (habetsan'ny vokatra amin'ny tahiry)
  • media (sary)
  • fifandraisana amin'ny sokajy catalog

Fisoratana anarana vokatra

Ny fampahalalana fototra momba ny vokatra dia azo jerena ao amin'ny 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`)
)

Ny fampahalalana kely indrindra ilaina mba hamoronana fidirana ao amin'ny rejisitra vokatra dia:

  • attribute_set_id
  • sku

fanampiny:

  • type_id - raha tsy mamaritra izany isika dia 'tsotra' no hampiasaina

Raha hanoratra mivantana amin'ny angon-drakitra dia mampiasa ny adaptatera DB an'ny Magento aho:

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

Taorian'ny fisoratana anarana ny vokatra amin'ny catalog_product_entity dia hita ao amin'ny tontonana admin, ao amin'ny takelaka vokatra (Catalog/Products).

Magento 2: manafatra vokatra mivantana ao anaty angon-drakitra

Fifandraisana eo amin'ny vokatra sy ny tranokala

Ny fikambanan'ny vokatra miaraka amin'ny tranokala dia mamaritra hoe aiza ny fivarotana sy fampisehoana ny vokatra ho hita eo anoloana.

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: manafatra vokatra mivantana ao anaty angon-drakitra

Toetra vokatra fototra

Tsy mbola manana anarana na famaritana ny vokatra vao nisoratra anarana. Izany rehetra izany dia vita Ireo singa mifandraika amin'ny EAV. Ity ny lisitr'ireo toetra fototra ilaina amin'ny vokatra mba hanehoana tsara ny vokatra eo anoloana:

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

Misy toetra misaraka manampy amin'ny vokatra toy izao (ny antsipirian'ny fahazoana ny famantarana sy ny karazana toetra avy amin'ny kaody dia nesorina):

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

Amin'ny fampiasana ny kaody toetra, dia mamaritra ny id sy ny karazana angona (datetime, decimal, int, text, varchar), dia soraty ao amin'ny latabatra mifanentana ny data ho an'ny varavarankely administratif (store_id = 0).

Aorian'ny fampidirana ireo toetra etsy ambony amin'ny vokatra dia azonao ity sary ity ao amin'ny tontonana admin:

Magento 2: manafatra vokatra mivantana ao anaty angon-drakitra

Angon-drakitra momba ny fitahirizana

Manomboka amin'ny version 2.3 ao amin'ny Magento, misy tabilao roa mifanitsy izay manome fitehirizana vaovao momba ny fanisana (habetsan'ny vokatra):

  • cataloginventory_*: rafitra taloha;
  • inventory_*: rafitra vaovao (MSI - Multi Source Inventory);

Mila manampy angon-drakitra amin'ny rafitra roa ianao, satria ny rafitra vaovao dia mbola tsy mahaleo tena tanteraka amin'ny taloha (tena azo inoana fa ho an'ny default trano fanatobiana entana ao amin'ny rafitra vaovao misy latabatra cataloginventory_stock_status toy ny inventory_stock_1).

cataloginventory_

Rehefa mampiasa Magneto 2.3 isika dia manana fidirana 2 amin'ny voalohany store_website, izay mifanandrify amin'ny tranokala roa - mpanjifa administratif sy lehibe:

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

LOHA cataloginventory_stock tokana ihany ny fidiranay:

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

Izany hoe ao amin'ny rafitra tranainy misy antsika dia tsy misy afa-tsy "trano fanatobiana entana" (stock) ary mifandray amin'ny tranokalam-pitantanana izany. Manampy vaovao amin'ny alΓ lan'ny tontonana admin sources/stocks ao amin'ny MSI (rafitra vaovao) dia tsy miteraka fidirana vaovao cataloginventory_stock.

Ny angon-drakitra momba ny vokatra ao amin'ny rafitra taloha dia voarakitra amin'ny tabilao voalohany:

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

inventory_

Tamin'ny voalohany, ny rafitra vaovao amin'ny fitehirizana angon-drakitra dia misy 1 "loharano"(inventory_source):

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

ary iray"fivarotana"(inventory_stock):

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

Β«loharanoΒ» maneho ny fitahirizana ara-batana ho an'ny vokatra (misy fandrindrana ara-batana sy adiresy mailaka ny rakitra). "Warehouse"dia firaisana lojika misy" loharano "(inventory_source_stock_link)

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

amin'ny ambaratonga misy ny fifandraisana amin'ny fantsona fivarotana (inventory_stock_sales_channel)

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

Raha tsaraina amin'ny firafitry ny angon-drakitra, karazana fantsona fivarotana isan-karazany no raisina, fa ny fifandraisana ihany "tahiry"-"tranonkala"(Ny rohy mankany amin'ny tranokala dia manaraka ny kaody tranonkala - base).

iray"fivarotana"afaka mifandray amin'ny maro"loharanom-baovao"ary iray"loharano"- ho maromaro"trano fanatobiana entana"(fifandraisana betsaka amin'ny maro). Ny exceptions dia default "loharano"Ary"fivarotana". Tsy ampifandraisina amin'ny sampana hafa izy ireo (famerana amin'ny haavon'ny kaody - ny fahadisoana "Tsy afaka mitahiry rohy mifandraika amin'ny Loharano Default na Stock Default"). Ny antsipiriany bebe kokoa momba ny rafitra MSI ao amin'ny Magento 2 dia azo jerena ao amin'ny lahatsoratra "Rafitra fitantanana trano fanatobiana entana mampiasa CQRS sy Event Sourcing. Design".

Hampiasa ny fanamafisam-peo default aho ary hampiditra ny fampahalalana momba ny fitahirizana rehetra amin'ny loharano default, izay tafiditra ao amin'ny fantsona fivarotana mifandray amin'ny tranokala miaraka amin'ny code base (mifanaraka amin'ny faran'ny fivarotana - jereo 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);
}

Aorian'ny fampidirana ny angon-drakitra momba ny vokatra ao amin'ny tontonana admin dia azonao ity sary ity:

Magento 2: manafatra vokatra mivantana ao anaty angon-drakitra

Media

Rehefa "manampy" sary amin'ny vokatra amin'ny alΓ lan'ny tontonana admin dia voasoratra ao amin'ireto tabilao manaraka ireto ny fampahalalana mifandraika amin'izany:

  • catalog_product_entity_media_gallery: rejisitry ny haino aman-jery (sary sy rakitra video);
  • catalog_product_entity_media_gallery_value: fampifandraisana ny haino aman-jery amin'ny vokatra sy ny fampirantiana (localization);
  • catalog_product_entity_media_gallery_value_to_entity: fampifandraisana ny haino aman-jery amin'ny vokatra ihany (azo inoana fa ny votoatin'ny haino aman-jery ho an'ny vokatra);
  • catalog_product_entity_varchar: Tehirizina eto ny anjara asa ampiasana ny sary;

ary ny sary mihitsy no voatahiry ao amin'ny lahatahiry ./pub/media/catalog/product/x/y/izay x ΠΈ y - ny litera voalohany sy faharoa amin'ny anaran'ny rakitra sary. Ohatra, ny rakitra image.png tokony hovonjena ho ./pub/media/catalog/product/i/m/image.png, mba ahafahan'ny sehatra mampiasa azy ho sary rehefa mamaritra ny vokatra avy amin'ny katalaogy.

Misoratra anarana ao ./pub/media/catalog/product/ rakitra media (tsy resahina ato amin'ity lahatsoratra ity ny fizotran'ny fametrahana ilay rakitra):

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

Rehefa misoratra anarana dia asiana identifier ny rakitra media vaovao.

Ampifandraisinay amin'ny vokatra mifanaraka amin'izany ny rakitra media voasoratra anarana ho an'ny trano fivarotana mahazatra:

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

Ampifandraisinay amin'ny vokatra mifanaraka amin'izany ny rakitra media voasoratra anarana nefa tsy mifamatotra amin'ny fivarotana rehetra. Tsy fantatra mazava hoe aiza marina no ampiasana an'io data io ary nahoana no tsy azo atao ny miditra amin'ny angona avy amin'ny latabatra teo aloha, fa misy io tabilao io ary ny angon-drakitra dia voasoratra ao rehefa misy sary ampiana ny vokatra. Dia izay no izy.

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

Ny rakitra media dia azo ampiasaina miaraka amin'ny andraikitra samihafa (ny fehezan-dalΓ na mifandraika amin'izany dia aseho ao anaty fononteny):

  • fototra(image)
  • Sary kely (small_image)
  • Thumbnail (thumbnail)
  • Swatch Image (swatch_image)

Ny fampifandraisana ny anjara andraikitra amin'ny rakitra media dia tena mitranga ao catalog_product_entity_varchar. Ny kaody mifamatotra dia mitovy amin'ny kaody ao amin'ny "Toetra vokatra fototra".

Rehefa avy nampiditra sary tamin'ny vokatra tao amin'ny tontonana admin dia toa izao:

Magento 2: manafatra vokatra mivantana ao anaty angon-drakitra

sokajy

Tabilao lehibe misy angona araka ny sokajy:

  • catalog_category_entity: rejisitry ny sokajy;
  • catalog_category_product: fifandraisana eo amin'ny vokatra sy ny sokajy;
  • catalog_category_entity_*: Sanda toetra EAV;

Tamin'ny voalohany, amin'ny fampiharana Magento tsy misy na inona na inona, ny rejisitra sokajy dia misy sokajy 2 (nohafoheziko ny anaran'ny tsanganana: 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|

Ny sokajy misy id=1 no fototry ny katalaogy Magento manontolo ary tsy hita ao amin'ny tontonana admin na eo amin'ny pejy voalohany. Sokajy misy id=2 (Default Sokajy) dia ny sokajy faka ho an'ny tranombarotra lehibe an'ny tranokala (Main Site Store) noforonina rehefa apetraka ny fampiharana (jereo. Admin / Fivarotana / Fivarotana rehetra). Ankoatr'izay, ny sokajy fototry ny magazay ihany koa dia tsy hita eo anoloana, fa ny zana-tsipìkany ihany.

Koa satria ny lohahevitr'ity lahatsoratra ity dia mbola manafatra data momba ny vokatra, tsy hampiasa ny fidirana mivantana amin'ny angon-drakitra aho rehefa mamorona sokajy, fa hampiasa ireo kilasy nomen'i Magento mihitsy (modely sy tahiry). Ny fidirana mivantana amin'ny angon-drakitra dia tsy ampiasaina afa-tsy hampifandray ny vokatra nafarana amin'ny sokajy iray (ny sokajy dia mifanandrify amin'ny anarany, ary ny id sokajy dia alaina mandritra ny fampifanarahana):

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

Rehefa avy nampiditra rohy vokatra amin'ny sokajy "sokajy 1" sy "sokajy 2", ny antsipirian'ny vokatra ao amin'ny tontonana admin dia toa izao:

Magento 2: manafatra vokatra mivantana ao anaty angon-drakitra

Hetsika fanampiny

Rehefa vita ny fanafarana data dia mila mamita ireto dingana fanampiny manaraka ireto ianao:

  • indexing data: antsoy ao amin'ny console ./bin/magento indexer:reindex;
  • fanavaozana URL ho an'ny vokatra / sokajy: azonao ampiasaina ny fanitarana "elgentos/regenerate-catalog-urlsΒ«

Vokatra ao amin'ny tontonana admin rehefa avy nanao hetsika fanampiny:

Magento 2: manafatra vokatra mivantana ao anaty angon-drakitra

ary eo anoloana:

Magento 2: manafatra vokatra mivantana ao anaty angon-drakitra

famintinana

Ny fitambaran'ny vokatra (seza 10) mitovy amin'ny ao amin'ny lahatsoratra teo aloha dia nafarana haingana kokoa (1 segondra versus 10). Mba hanombanana marina kokoa ny hafainganam-pandeha dia mila vokatra betsaka kokoa ianao - an-jatony, na an'arivony. Na izany aza, na dia amin'ny angon-drakitra fampidirana kely toy izany aza, dia afaka manatsoaka hevitra isika fa ny fampiasana ny fitaovana nomen'i Magento (modely sy repository) dia manan-danja (manantitrantitra aho - be!) manafaingana ny fivoaran'ny fampiasa ilaina, fa amin'ny fotoana iray ihany koa (tsindriako - be!) ahena ny hafainganam-pandehan'ny fidirana amin'ny angona.

Vokany, lena ny rano ary tsy fanambarana akory izany. Na izany aza, manana ny kaody hilalaovana aho izao ary mety ho tonga amin'ny fanatsoahan-kevitra mahaliana kokoa.

Source: www.habr.com