Magento 2:從外部來源進口產品

Magento 它是一種電子商務解決方案,這意味著它更側重於產品銷售,而不是相關的倉儲、物流或財務會計。其他應用程式(例如ERP系統)更適合處理這些任務。因此,它在實踐中應用相當廣泛。 Magento возникает задача интеграции магазина с этими другими системами (например, с 1С).

總的來說,整合可以透過以下方式簡化為資料複製:

  • 目錄(產品、類別);
  • 庫存資料(倉庫中的產品餘額和價格);
  • 客戶;
  • 命令;

Magento для манипуляции с данными в базе предлагает отдельный класс объектов — 儲存庫. В силу специфики Magento добавление данных в базу через репозитории легко кодируется, но происходит, скажем так, небыстро. В данной публикации я рассматриваю основные этапы программного добавления в Magento 2 продукта «классическим» способом — с использованием репо-классов.

Клиенты и заказы реплицируются, обычно, в другую сторону — из Magento во внешние ERP-системы. Поэтому с ними попроще, на стороне Magento нужно просто выбрать соответствующие данные, а дальше — «子彈從我們身邊飛出“。

將資料記錄到資料庫的原理

На данный момент создание сохраняемых в базе объектов программным способом в Magento делается через 工廠:

function __construct (MagentoCmsModelBlockFactory $blockFactory) {
    $this->blockFactory = $blockFactory;
}

/** @var MagentoCmsModelBlock $block */
$block = $this->blockFactory->create();

寫入資料庫是透過 知識庫:

function __construct (MagentoCmsApiBlockRepositoryInterface $blockRepo) {
    $this->blockRepo = $blockRepo;
}

$this->blockRepo->save($block);

Подход с использованием «Factory» и «Repository» можно использовать для всех основных моделей в предметной области Magento 2.

產品基本資訊

Я рассматриваю структуру данных, соответствующую версии Magento 2.3. Самая основная информация о продукте находится в таблице catalog_product_entity (產品註冊):

entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_at

我僅限於一種類型的產品(type_id='simple'),一組預設屬性(attribute_set_id=4) 並忽略屬性 has_options и required_options。 既然屬性 entity_id, created_at и updated_at 都是自動生成的,那麼,其實要增加一個新的產品,我們只需要設定 sku。 我這樣做:

/** @var MagentoCatalogApiDataProductInterfaceFactory $factProd */
/** @var MagentoCatalogApiProductRepositoryInterface $repoProd */
/** @var MagentoCatalogApiDataProductInterface $prod */
$prod = $factProd->create();
$prod->setAttributeSetId(4);
$prod->setTypeId('simple');
$prod->setSku($sku);
$repoProd->save($prod);

我得到一個例外:

The "Product Name" attribute value is empty. Set the attribute and try again.

我將產品名稱添加到請求中並收到一條訊息,指出缺少該屬性 Price。 添加價格後,產品將添加到資料庫中:

$prod = $factProd->create();
$prod->setAttributeSetId(4);
$prod->setTypeId('simple');
$prod->setSku($sku);
$prod->setName($name);
$prod->setPrice($price);
$repoProd->save($prod);

產品名稱儲存在產品 varchar 屬性表中(catalog_product_entity_varchar), 價格 - 表中 catalog_product_entity_decimal。 在新增產品之前,建議明確說明我們正在使用管理店面匯入資料:

/** @var MagentoStoreModelStoreManagerInterface $manStore */
$manStore->setCurrentStore(0);

附加屬性

Обработка дополнительных атрибутов продуктов средствами Magento — одно удовольствие. EAV-модель данных для основных сущностей (см. таблицу eav_entity_type)是該平台的主要功能之一。 我們只需將適當的屬性添加到產品模型中即可:

$prodEntity->setData('description', $desc);
$prodEntity->setData('short_description', $desc_short);
// или
$prodEntity->setDescription($desc);
$prodEntity->setShortDescription($desc_short);

透過 repo 物件保存模型時:

$repoProd->save($prod);

附加屬性也將儲存在對應的資料庫表中。

庫存數據

По-простому — количество продукта на складе. В Magento 2.3 структуры в БД, описывающие формат хранения инвентарных данных, 顯著不同 從之前發生的事情來看。 然而,透過產品模型添加產品的庫存數量並不比添加其他屬性困難多少:

/** @var MagentoCatalogModelProduct $prodEntity */
/** @var MagentoCatalogApiProductRepositoryInterface $repoProd */
$inventory = [
    'is_in_stock' => true,
    'qty' => 1234
];
$prodEntity->setData('quantity_and_stock_status', $inventory);
$repoProd->save($prodEntity);

媒體

通常,商店(電子商務)中客戶對產品的媒體支援與內部會計系統(ERP)中員工對相同產品的媒體支援不同。 在第一種情況下,建議面對面展示產品;在第二種情況下,給予產品的整體概念就足夠了。 然而,至少傳輸產品的主圖像是很常見的。 case 導入數據時。

透過管理面板新增影像時,影像首先保存在臨時目錄中(./pub/media/tmp/catalog/product)並且僅在儲存時將產品移至媒體目錄(./pub/media/catalog/product)。 此外,當透過管理面板新增時,影像會被標記 image, small_image, thumbnail, swatch_image.

/** @var MagentoCatalogApiProductRepositoryInterface $repoProd */
/** @var MagentoCatalogModelProductGalleryCreateHandler $hndlGalleryCreate */
/* $imagePath = '/path/to/file.png';  $imagePathRelative = '/f/i/file.png' */
$imagePathRelative = $this->imagePlaceToTmpMedia($imagePath);
/* reload product with gallery data */
$product = $repoProd->get($sku);
/* add image to product's gallery */
$gallery['images'][] = [
    'file' => $imagePathRelative,
    'media_type' => 'image'
    'label' => ''
];
$product->setData('media_gallery', $gallery);
/* set usage areas */
$product->setData('image', $imagePathRelative);
$product->setData('small_image', $imagePathRelative);
$product->setData('thumbnail', $imagePathRelative);
$product->setData('swatch_image', $imagePathRelative);
/* create product's gallery */
$hndlGalleryCreate->execute($product);

由於某種原因,僅在首次保存產品並再次從存儲庫檢索它後才鏈接媒體。 並且需要指定屬性 label 將條目新增至產品媒體庫時(否則我們會得到異常 Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516).

Категории

通常,商店的類別結構和後端應用程式或產品在其中的放置可能會有很大差異。 遷移有關類別和其中產品的資料的策略取決於許多因素。 在此範例中,我堅持以下原則:

  • 後端和商店類別透過名稱進行比較;
  • 如果匯入的類別不在商店中,則會在根類別下建立該類別(Default Category)且其在商店目錄中的進一步定位是手動假定的;
  • 只有當產品在商店中建立時(首次導入),產品才會被分配到類別;

此類別的基本資訊見表 catalog_category_entity (каталог категорий). Создание категории в Magento:

/** @var MagentoCatalogApiDataCategoryInterfaceFactory $factCat */
/** @var MagentoCatalogApiCategoryRepositoryInterface $repoCat */
$cat = $factCat->create();
$cat->setName($name);
$cat->setIsActive(true);
$repoCat->save($cat);

使用類別 ID 和產品 SKU 將產品連結到類別:

/** @var MagentoCatalogModelCategoryProductLinkFactory $factCatProdLink */
/** @var MagentoCatalogApiCategoryLinkRepositoryInterface $repoCatLink */
$link = $factCatProdLink->create();
$link->setCategoryId($catMageId);
$link->setSku($prodSku);
$repoCatLink->save($link);

在總

Написать код для добавления в Magento 2 продукта программным путём весьма несложно. Всё изложенное выше я свёл в демо-модуль «flancer32/mage2_ext_demo_import」。 模組中只有一個控制台命令 fl32:import:prod,導入 JSON 檔案中所描述的產品“./etc/data/products.json“:

[
  {
    "sku": "...",
    "name": "...",
    "desc": "...",
    "desc_short": "...",
    "price": ...,
    "qty": ...,
    "categories": ["..."],
    "image_path": "..."
  }
]

導入的圖片在目錄中 ./etc/data/img.

在我的筆記型電腦上,使用此方法匯入 10 個產品的時間約為 10 秒。 如果我們進一步發展這個想法,很容易得出這樣的結論:每小時大約可以導入3600個產品,導入100K個產品大約需要30個小時。 用伺服器替換筆記型電腦可以讓您在某種程度上緩解這種情況。 甚至可能有好幾次。 但不是幾個數量級。 或許這種快與慢在某種程度上就是這個專案出現的原因之一 magento/非同步導入.

Кардинальным решением для увеличения скорости импорта может стать прямая запись в базу, но в этом случае теряются все «плюшки», касающиеся расширяемости Magento — придётся всё «расширенное» делать самому. Тем не менее, оно того стоит. Если получится, то рассмотрю подход с прямой записью в БД в следующей статье.

來源: www.habr.com

為具有 DDoS 保護、VPS VDS 服務器的站點購買可靠的主機 🔥 購買具備 DDoS 防護的可靠網站寄存服務,包括 VPS 和 VDS 伺服器 | ProHoster