ืžื’'ื ื˜ื• 2: ื™ื™ื‘ื•ื โ€‹โ€‹ืžื•ืฆืจื™ื ื™ืฉื™ืจื•ืช ืœื‘ืกื™ืก ื”ื ืชื•ื ื™ื

ะ’ ืžืืžืจ ืงื•ื“ื ืืช ืชื”ืœื™ืš ื™ื™ื‘ื•ื โ€‹โ€‹ื”ืžื•ืฆืจื™ื ืœืžื’'ื ื˜ื• 2 ืชื™ืืจืชื™ ื‘ื“ืจืš ื”ืจื’ื™ืœื” โ€“ ื“ืจืš ื“ื’ืžื™ื ื•ืžืื’ืจื™ื. ืœืฉื™ื˜ื” ื”ืจื’ื™ืœื” ื™ืฉ ืžื”ื™ืจื•ืช ืขื™ื‘ื•ื“ ื ืชื•ื ื™ื ื ืžื•ื›ื” ืžืื•ื“. ื”ืžื—ืฉื‘ ื”ื ื™ื™ื“ ืฉืœื™ ื™ื™ืฆืจ ื‘ืขืจืš ืžื•ืฆืจ ืื—ื“ ื‘ืฉื ื™ื™ื”. ื‘ื”ืžืฉืš ื–ื” ืื ื™ ืฉื•ืงืœ ื“ืจืš ื—ืœื•ืคื™ืช ืœื™ื™ื‘ื ืžื•ืฆืจ - ื‘ื›ื ื™ืกื” ื™ืฉื™ืจื” ืœื‘ืกื™ืก ื”ื ืชื•ื ื™ื, ืขืงื™ืคืช ืžื ื’ื ื•ื ื™ ืžื’'ื ื˜ื• 2 ื”ืกื˜ื ื“ืจื˜ื™ื™ื (ื“ื’ืžื™ื, ืžืคืขืœื™ื, ืžืื’ืจื™ื). ื ื™ืชืŸ ืœื”ืชืื™ื ืืช ืจืฆืฃ ื”ืฉืœื‘ื™ื ืœื™ื™ื‘ื•ื โ€‹โ€‹ืžื•ืฆืจื™ื ืœื›ืœ ืฉืคืช ืชื›ื ื•ืช ืฉื™ื›ื•ืœื” ืœืขื‘ื•ื“ ืขื MySQL.

ื›ืชื‘ ื•ื™ืชื•ืจ: ืœืžื’'ื ื˜ื• ื™ืฉ ืคื•ื ืงืฆื™ื•ื ืœื™ื•ืช ืžื•ื›ื ื” ืขื‘ื•ืจ ื™ื™ื‘ื•ื โ€‹โ€‹ื ืชื•ื ื™ื ื•ืกื‘ื™ืจ ืœื”ื ื™ื— ืฉื–ื” ื™ืกืคื™ืง ืœืš. ืขื ื–ืืช, ืื ืืชื” ืฆืจื™ืš ืฉืœื™ื˜ื” ืžืœืื” ื™ื•ืชืจ ืขืœ ืชื”ืœื™ืš ื”ื™ื™ื‘ื•ื, ืœื ืจืง ื”ื›ื ืช ืงื•ื‘ืฅ CSV ืœืžื” ืฉื™ืฉ ืœืš, ื‘ืจื•ืš ื”ื‘ื ืœื—ืชื•ืœ.

ืžื’'ื ื˜ื• 2: ื™ื™ื‘ื•ื โ€‹โ€‹ืžื•ืฆืจื™ื ื™ืฉื™ืจื•ืช ืœื‘ืกื™ืก ื”ื ืชื•ื ื™ื

ื ื™ืชืŸ ืœืจืื•ืช ืืช ื”ืงื•ื“ ื”ื ื•ื‘ืข ืžื›ืชื™ื‘ืช ืฉื ื™ ื”ืžืืžืจื™ื ื‘ืžื•ื“ื•ืœ Magento "flancer32/mage2_ext_demo_import". ื”ื ื” ื›ืžื” ื”ื’ื‘ืœื•ืช ืฉืคืขืœืชื™ ื‘ื”ืŸ ื›ื“ื™ ืœืคืฉื˜ ืืช ืงื•ื“ ืžื•ื“ื•ืœ ื”ื”ื“ื’ืžื”:

  • ืžื•ืฆืจื™ื ื ื•ืฆืจื™ื ืจืง, ืœื ืžืขื•ื“ื›ื ื™ื.
  • ืžื—ืกืŸ ืื—ื“
  • ืจืง ืฉืžื•ืช ืงื˜ื’ื•ืจื™ื•ืช ืžื™ื•ื‘ืื™ื, ืœืœื ื”ืžื‘ื ื” ืฉืœื”ื
  • ืžื‘ื ื™ ื ืชื•ื ื™ื ืชื•ืืžื™ื ืœื’ืจืกื” 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 - ืื ืœื ื ืฆื™ื™ืŸ ื–ืืช, ื™ื™ืขืฉื” ืฉื™ืžื•ืฉ ื‘'ืคืฉื•ื˜'

ื›ื“ื™ ืœื›ืชื•ื‘ ื™ืฉื™ืจื•ืช ืœืžืกื“ ื”ื ืชื•ื ื™ื, ืื ื™ ืžืฉืชืžืฉ ื‘ืžืชืื ื”-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 ื–ื” ื”ื•ืคืš ืœื”ื™ื•ืช ื’ืœื•ื™ ื‘ืคืื ืœ ื”ื ื™ื”ื•ืœ, ื‘ืจืฉืช ื”ืžื•ืฆืจ (ืงื˜ืœื•ื’/ืžื•ืฆืจื™ื).

ืžื’'ื ื˜ื• 2: ื™ื™ื‘ื•ื โ€‹โ€‹ืžื•ืฆืจื™ื ื™ืฉื™ืจื•ืช ืœื‘ืกื™ืก ื”ื ืชื•ื ื™ื

ืงืฉืจ ื‘ื™ืŸ ืžื•ืฆืจ ืœืืชืจ

ื”ืฉื™ื•ืš ืฉืœ ื”ืžื•ืฆืจ ืœืืชืจ ืงื•ื‘ืข ื‘ืื™ืœื• ื—ื ื•ื™ื•ืช ื•ืชืฆื•ื’ื•ืช ื”ืžื•ืฆืจ ื™ื”ื™ื” ื–ืžื™ืŸ ื‘ื—ื–ื™ืช.

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

ืžื’'ื ื˜ื• 2: ื™ื™ื‘ื•ื โ€‹โ€‹ืžื•ืฆืจื™ื ื™ืฉื™ืจื•ืช ืœื‘ืกื™ืก ื”ื ืชื•ื ื™ื

ืชื›ื•ื ื•ืช ืžื•ืฆืจ ื‘ืกื™ืกื™ื•ืช

ืœืžื•ืฆืจ ืฉื ืจืฉื ืœืื—ืจื•ื ื” ืื™ืŸ ืขื“ื™ื™ืŸ ืฉื ืื• ืชื™ืื•ืจ. ื›ืœ ื–ื” ื ืขืฉื” ื‘ืืžืฆืขื•ืช ืชื›ื•ื ื•ืช EAV. ืœื”ืœืŸ ืจืฉื™ืžื” ืฉืœ ืชื›ื•ื ื•ืช ืžื•ืฆืจ ื‘ืกื™ืกื™ื•ืช ื”ื“ืจื•ืฉื•ืช ืขืœ ืžื ืช ืฉื”ืžื•ืฆืจ ื™ื•ืฆื’ ื‘ืฆื•ืจื” ื ื›ื•ื ื” ื‘ื—ื–ื™ืช:

  • 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: ื™ื™ื‘ื•ื โ€‹โ€‹ืžื•ืฆืจื™ื ื™ืฉื™ืจื•ืช ืœื‘ืกื™ืก ื”ื ืชื•ื ื™ื

ื ืชื•ื ื™ ืžืœืื™

ื”ื—ืœ ืžื’ืจืกื” 2.3 ื‘ืžื’'ื ื˜ื•, ื™ืฉื ืŸ ืฉืชื™ ืงื‘ื•ืฆื•ืช ืžืงื‘ื™ืœื•ืช ืฉืœ ื˜ื‘ืœืื•ืช ื”ืžืกืคืงื•ืช ืื—ืกื•ืŸ ืฉืœ ืžื™ื“ืข ืžืœืื™ (ื›ืžื•ืช ื”ืžื•ืฆืจ):

  • 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

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

ืกื˜ื˜ื•ืก_ืžืœืื™_ืงื˜ืœื•ื’

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 ื‘ืžื’'ื ื˜ื• 2 ื ื™ืชืŸ ืœืžืฆื•ื ื‘ืžืืžืจ "ืžืขืจื›ืช ื ื™ื”ื•ืœ ืžื—ืกืŸ ื‘ืืžืฆืขื•ืช CQRS ื•- Event Sourcing. ืœึฐืขึทืฆึตื‘".

ืื ื™ ืืฉืชืžืฉ ื‘ืชืฆื•ืจืช ื‘ืจื™ืจืช ื”ืžื—ื“ืœ ื•ืื•ืกื™ืฃ ืืช ื›ืœ ืžื™ื“ืข ื”ืžืœืื™ ืœืžืงื•ืจ 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);
}

ืœืื—ืจ ื”ื•ืกืคืช ื ืชื•ื ื™ ืžืœืื™ ืœืžื•ืฆืจ ื‘ืคืื ืœ ื”ื ื™ื”ื•ืœ, ืืชื” ืžืงื‘ืœ ืืช ื”ืชืžื•ื ื” ื”ื‘ืื”:

ืžื’'ื ื˜ื• 2: ื™ื™ื‘ื•ื โ€‹โ€‹ืžื•ืฆืจื™ื ื™ืฉื™ืจื•ืช ืœื‘ืกื™ืก ื”ื ืชื•ื ื™ื

ืžื“ื™ื”

ื›ืืฉืจ ืžื•ืกื™ืคื™ื ืชืžื•ื ื” ืœืžื•ืฆืจ "ื™ื“ื ื™ืช" ื“ืจืš ืคืื ืœ ื”ื ื™ื”ื•ืœ, ื”ืžื™ื“ืข ื”ืจืœื•ื•ื ื˜ื™ ื ืจืฉื ื‘ื˜ื‘ืœืื•ืช ื”ื‘ืื•ืช:

  • 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, ื›ื“ื™ ืฉื”ืคืœื˜ืคื•ืจืžื” ืชื•ื›ืœ ืœื”ืฉืชืžืฉ ื‘ื” ื›ืชืžื•ื ื” ื‘ืขืช ืชื™ืื•ืจ ืžื•ืฆืจื™ื ืžื”ืงื˜ืœื•ื’.

ื”ื”ืจืฉืžื” ืคื•ืจืกื ื‘ ./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;
}

ื›ืืฉืจ ื ืจืฉื, ืœืงื•ื‘ืฅ ืžื“ื™ื” ื—ื“ืฉ ืžื•ืงืฆื” ืžื–ื”ื”.

ืื ื• ืžืฉื™ื™ื›ื™ื ืืช ืงื•ื‘ืฅ ื”ืžื“ื™ื” ื”ืจืฉื•ื ืœืžื•ืฆืจ ื”ืžืชืื™ื ืขื‘ื•ืจ ื—ืœื•ืŸ ื”ืจืื•ื•ื” ืฉืœ ื‘ืจื™ืจืช ื”ืžื—ื“ืœ:

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

ืื ื• ืžืงืฉืจื™ื ืืช ืงื•ื‘ืฅ ื”ืžื“ื™ื” ื”ืจืฉื•ื ืœืžื•ืฆืจ ื”ืžืชืื™ื ืžื‘ืœื™ ืœื”ื™ื•ืช ืงืฉื•ืจ ืœื—ืœื•ืŸ ืจืื•ื•ื” ื›ืœืฉื”ื•. ืœื ื‘ืจื•ืจ ื”ื™ื›ืŸ ื‘ื“ื™ื•ืง ื ืขืฉื” ืฉื™ืžื•ืฉ ื‘ื ืชื•ื ื™ื ื”ืืœื” ื•ืžื“ื•ืข ืื™ ืืคืฉืจ ืœื’ืฉืช ืœื ืชื•ื ื™ื ืžื”ื˜ื‘ืœื” ื”ืงื•ื“ืžืช, ืื‘ืœ ื”ื˜ื‘ืœื” ื”ื–ื• ืงื™ื™ืžืช ื•ื”ื ืชื•ื ื™ื ื ื›ืชื‘ื™ื ืืœื™ื” ื›ืฉืžื•ืกื™ืคื™ื ืชืžื•ื ื” ืœืžื•ืฆืจ. ืื– ื–ื”ื• ื–ื”.

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. ื”ืงื•ื“ ื”ืžื—ื™ื™ื‘ ื“ื•ืžื” ืœืงื•ื“ ื‘-"ืชื›ื•ื ื•ืช ืžื•ืฆืจ ื‘ืกื™ืกื™ื•ืช".

ืœืื—ืจ ื”ื•ืกืคืช ืชืžื•ื ื” ืœืžื•ืฆืจ ื‘ืคืื ืœ ื”ื ื™ื”ื•ืœ ื–ื” ื ืจืื” ื›ืš:

ืžื’'ื ื˜ื• 2: ื™ื™ื‘ื•ื โ€‹โ€‹ืžื•ืฆืจื™ื ื™ืฉื™ืจื•ืช ืœื‘ืกื™ืก ื”ื ืชื•ื ื™ื

ืงื˜ื’ื•ืจื™ื•ืช

ื˜ื‘ืœืื•ืช ืขื™ืงืจื™ื•ืช ื”ืžื›ื™ืœื•ืช ื ืชื•ื ื™ื ืœืคื™ ืงื˜ื’ื•ืจื™ื•ืช:

  • catalog_category_entity: ืจื™ืฉื•ื ืงื˜ื’ื•ืจื™ื•ืช;
  • catalog_category_product: ื—ื™ื‘ื•ืจ ื‘ื™ืŸ ืžื•ืฆืจื™ื ื•ืงื˜ื’ื•ืจื™ื•ืช;
  • catalog_category_entity_*: ืขืจื›ื™ ืชื›ื•ื ืช EAV;

ื‘ืชื—ื™ืœื”, ื‘ืืคืœื™ืงืฆื™ื™ืช ืžื’'ื ื˜ื• ืจื™ืงื”, ืจื™ืฉื•ื ื”ืงื˜ื’ื•ืจื™ื•ืช ืžื›ื™ืœ 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 ื”ื™ื ื”ืฉื•ืจืฉ ืฉืœ ื›ืœ ืงื˜ืœื•ื’ ืžื’'ื ื˜ื• ื•ืื™ื ื” ื–ืžื™ื ื” ืœื ื‘ืคืื ืœ ื”ื ื™ื”ื•ืœ ื•ืœื ื‘ืขืžื•ื“ ื”ืจืืฉื•ืŸ. ืงื˜ื’ื•ืจื™ื” ืขื 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", ืคืจื˜ื™ ื”ืžื•ืฆืจ ื‘ืคืื ืœ ื”ื ื™ื”ื•ืœ ื ืจืื™ื ื‘ืขืจืš ื›ืš:

ืžื’'ื ื˜ื• 2: ื™ื™ื‘ื•ื โ€‹โ€‹ืžื•ืฆืจื™ื ื™ืฉื™ืจื•ืช ืœื‘ืกื™ืก ื”ื ืชื•ื ื™ื

ืคืขื•ืœื•ืช ื ื•ืกืคื•ืช

ืœืื—ืจ ื”ืฉืœืžืช ื™ื™ื‘ื•ื โ€‹โ€‹ื”ื ืชื•ื ื™ื, ืขืœื™ืš ืœื‘ืฆืข ืืช ื”ืฉืœื‘ื™ื ื”ื ื•ืกืคื™ื ื”ื‘ืื™ื:

  • ืื™ื ื“ืงืก ื ืชื•ื ื™ื: ื”ืชืงืฉืจ ื‘ืžืกื•ืฃ ./bin/magento indexer:reindex;
  • ื™ืฆื™ืจืช ื›ืชื•ื‘ื•ืช URL ืžื—ื“ืฉ ืขื‘ื•ืจ ืžื•ืฆืจื™ื/ืงื˜ื’ื•ืจื™ื•ืช: ืืชื” ื™ื›ื•ืœ ืœื”ืฉืชืžืฉ ื‘ืชื•ืกืฃ "elgentos/regenerate-catalog-urlsยซ

ืžื•ืฆืจื™ื ื‘ืคืื ืœ ื”ื ื™ื”ื•ืœ ืœืื—ืจ ื‘ื™ืฆื•ืข ืคืขื•ืœื•ืช ื ื•ืกืคื•ืช:

ืžื’'ื ื˜ื• 2: ื™ื™ื‘ื•ื โ€‹โ€‹ืžื•ืฆืจื™ื ื™ืฉื™ืจื•ืช ืœื‘ืกื™ืก ื”ื ืชื•ื ื™ื

ื•ื‘ื—ื–ื™ืช:

ืžื’'ื ื˜ื• 2: ื™ื™ื‘ื•ื โ€‹โ€‹ืžื•ืฆืจื™ื ื™ืฉื™ืจื•ืช ืœื‘ืกื™ืก ื”ื ืชื•ื ื™ื

ืชืงืฆื™ืจ

ืื•ืชื• ืกื˜ ืžื•ืฆืจื™ื (10 ื—ืชื™ื›ื•ืช) ื›ืžื• ื‘ื›ืชื‘ื” ื”ืงื•ื“ืžืช ืžื™ื•ื‘ื ืœืคื—ื•ืช ื‘ืกื“ืจ ื’ื•ื“ืœ ืžื”ื™ืจ ื™ื•ืชืจ (ืฉื ื™ื™ื” ืื—ืช ืœืขื•ืžืช 1). ื›ื“ื™ ืœื”ืขืจื™ืš ื‘ืฆื•ืจื” ืžื“ื•ื™ืงืช ื™ื•ืชืจ ืืช ื”ืžื”ื™ืจื•ืช, ืืชื” ืฆืจื™ืš ืžืกืคืจ ื’ื“ื•ืœ ื™ื•ืชืจ ืฉืœ ืžื•ืฆืจื™ื - ื›ืžื” ืžืื•ืช, ืื• ื˜ื•ื‘ ื™ื•ืชืจ ืืœืคื™ื. ืขื ื–ืืช, ื’ื ืขื ื’ื•ื“ืœ ื›ื” ืงื˜ืŸ ืฉืœ ื ืชื•ื ื™ ืงืœื˜, ืื ื• ื™ื›ื•ืœื™ื ืœื”ืกื™ืง ืฉื”ืฉื™ืžื•ืฉ ื‘ื›ืœื™ื ืฉืžืกืคืงืช Magento (ืžื•ื“ืœื™ื ื•ืžืื’ืจื™ื) ื”ื•ื ืžืฉืžืขื•ืชื™ (ืื ื™ ืžื“ื’ื™ืฉ - ื”ืจื‘ื”!) ืœื”ืื™ืฅ ืืช ืคื™ืชื•ื— ื”ืคื•ื ืงืฆื™ื•ื ืœื™ื•ืช ื”ื ื“ืจืฉืช, ืืš ื‘ื• ื–ืžื ื™ืช ื‘ืื•ืคืŸ ืžืฉืžืขื•ืชื™ (ืื ื™ ืžื“ื’ื™ืฉ - ื”ืจื‘ื”!) ืœื”ืคื—ื™ืช ืืช ื”ืžื”ื™ืจื•ืช ืฉื‘ื” ื ืชื•ื ื™ื ื ื›ื ืกื™ื ืœืžืกื“ ื”ื ืชื•ื ื™ื.

ื›ืชื•ืฆืื” ืžื›ืš ื”ืชื‘ืจืจ ืฉื”ืžื™ื ืจื˜ื•ื‘ื™ื ื•ืœื ืžื“ื•ื‘ืจ ื‘ื’ื™ืœื•ื™. ืขื ื–ืืช, ืขื›ืฉื™ื• ื™ืฉ ืœื™ ืืช ื”ืงื•ื“ ืœืฉื—ืง ืื™ืชื• ื•ืื•ืœื™ ืœื”ื’ื™ืข ืœื›ืžื” ืžืกืงื ื•ืช ืžืขื ื™ื™ื ื•ืช ื™ื•ืชืจ.

ืžืงื•ืจ: www.habr.com