Magento je řešení pro e-commerce, tzn. se více zaměřuje na prodej produktů než na skladování, logistiku nebo finanční účetnictví doprovázející prodej. Jiné aplikace (například ERP systémy) jsou vhodnější pro doprovodné aplikace. Proto v praxi používání Magento často vyvstává úkol integrovat obchod s těmito jinými systémy (například 1C).
Celkově lze integraci zredukovat na replikaci dat:
- katalog (produkty, kategorie);
- inventární údaje (zůstatky produktů ve skladech a ceny);
- klienti;
- objednávky;
Magento nabízí samostatnou třídu objektů pro manipulaci s daty v databázi -
Zákazníci a objednávky se obvykle replikují opačným směrem – od Magenta k externím ERP systémům. Proto je to s nimi jednodušší, na straně Magento stačí vybrat příslušná data a poté „kulky vylétly z naší strany".
Principy záznamu dat do databáze
V současné době je vytváření objektů uložených v databázi programově v Magentu provedeno prostřednictvím
function __construct (MagentoCmsModelBlockFactory $blockFactory) {
$this->blockFactory = $blockFactory;
}
/** @var MagentoCmsModelBlock $block */
$block = $this->blockFactory->create();
a zápis do databáze se provádí přes
function __construct (MagentoCmsApiBlockRepositoryInterface $blockRepo) {
$this->blockRepo = $blockRepo;
}
$this->blockRepo->save($block);
Přístup „Factory“ a „Repository“ lze použít pro všechny hlavní modely v doméně Magento 2.
Základní informace o produktu
Dívám se na datovou strukturu, která odpovídá verzi Magento 2.3. Nejzákladnější informace o produktu jsou v tabulce catalog_product_entity
(registr produktů):
entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_at
Jsem omezen na jeden typ produktu (type_id='simple'
), sada výchozích atributů (attribute_set_id=4
) a ignorovat atributy has_options
и required_options
. Od atributů entity_id
, created_at
и updated_at
jsou generovány automaticky, pak ve skutečnosti pro přidání nového produktu stačí nastavit sku
. Dělám to:
/** @var MagentoCatalogApiDataProductInterfaceFactory $factProd */
/** @var MagentoCatalogApiProductRepositoryInterface $repoProd */
/** @var MagentoCatalogApiDataProductInterface $prod */
$prod = $factProd->create();
$prod->setAttributeSetId(4);
$prod->setTypeId('simple');
$prod->setSku($sku);
$repoProd->save($prod);
a dostávám výjimku:
The "Product Name" attribute value is empty. Set the attribute and try again.
Do požadavku přidám název produktu a zobrazí se mi zpráva, že atribut chybí Price
. Po přidání ceny je produkt přidán do databáze:
$prod = $factProd->create();
$prod->setAttributeSetId(4);
$prod->setTypeId('simple');
$prod->setSku($sku);
$prod->setName($name);
$prod->setPrice($price);
$repoProd->save($prod);
Název produktu je uložen v tabulce atributů varchar produktu (catalog_product_entity_varchar
), cena - v tabulce catalog_product_entity_decimal
. Před přidáním produktu je vhodné výslovně uvést, že k importu dat používáme administrativní výlohu:
/** @var MagentoStoreModelStoreManagerInterface $manStore */
$manStore->setCurrentStore(0);
Další atributy
Zpracování dalších atributů produktu pomocí Magento je potěšením. Datový model EAV pro hlavní entity (viz tabulka eav_entity_type
) je jednou z klíčových funkcí této platformy. Jednoduše přidáme příslušné atributy do modelu produktu:
$prodEntity->setData('description', $desc);
$prodEntity->setData('short_description', $desc_short);
// или
$prodEntity->setDescription($desc);
$prodEntity->setShortDescription($desc_short);
a při ukládání modelu přes objekt repo:
$repoProd->save($prod);
další atributy budou také uloženy v odpovídajících databázových tabulkách.
Údaje o zásobách
Jednoduše řečeno - množství produktu na skladě. V Magento 2.3 jsou struktury v databázi, které popisují formát pro ukládání skladových dat
/** @var MagentoCatalogModelProduct $prodEntity */
/** @var MagentoCatalogApiProductRepositoryInterface $repoProd */
$inventory = [
'is_in_stock' => true,
'qty' => 1234
];
$prodEntity->setData('quantity_and_stock_status', $inventory);
$repoProd->save($prodEntity);
média
Mediální podpora produktu pro klienta na prodejně (e-commerce) se zpravidla liší od mediální podpory stejného produktu pro zaměstnance v interním účetním systému (ERP). V prvním případě je vhodné ukázat produkt tváří v tvář, ve druhém stačí poskytnout obecnou představu o produktu. Přenést alespoň primární image produktu je však zcela běžné. case
při importu dat.
Při přidávání obrázku přes admin panel se obrázek nejprve uloží do dočasného adresáře (./pub/media/tmp/catalog/product
) a pouze při ukládání se produkt přesune do adresáře médií (./pub/media/catalog/product
). Po přidání prostřednictvím panelu administrátora je obrázek také označen 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);
Z nějakého důvodu je médium propojeno až po prvním uložení produktu a jeho opětovném načtení z úložiště. A musíte zadat atribut label
při přidávání záznamu do galerie médií produktu (jinak dostaneme výjimku Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516
).
kategorie
Často se může výrazně lišit struktura kategorií obchodu a backendové aplikace nebo umístění produktů v nich. Strategie migrace dat o kategoriích a produktech v nich závisí na mnoha faktorech. V tomto příkladu se držím následujícího:
- kategorie backend a store jsou porovnány podle názvu;
- pokud je importována kategorie, která není v obchodě, pak je vytvořena pod kořenovou kategorií (
Default Category
) a jeho další umístění v katalogu prodejen se předpokládá ručně; - produkt je zařazen do kategorie až při jeho vytvoření v obchodě (první import);
Základní informace o kategorii jsou v tabulce catalog_category_entity
(katalog kategorií). Vytvoření kategorie v Magento:
/** @var MagentoCatalogApiDataCategoryInterfaceFactory $factCat */
/** @var MagentoCatalogApiCategoryRepositoryInterface $repoCat */
$cat = $factCat->create();
$cat->setName($name);
$cat->setIsActive(true);
$repoCat->save($cat);
Propojení produktu s kategorií se provádí pomocí ID kategorie a SKU produktu:
/** @var MagentoCatalogModelCategoryProductLinkFactory $factCatProdLink */
/** @var MagentoCatalogApiCategoryLinkRepositoryInterface $repoCatLink */
$link = $factCatProdLink->create();
$link->setCategoryId($catMageId);
$link->setSku($prodSku);
$repoCatLink->save($link);
Celkem
Psaní kódu pro programové přidání produktu do Magento 2 je docela snadné. Vše výše uvedené jsem spojil do demo modulu “fl32:import:prod
, který importuje produkty popsané v souboru JSON "
[
{
"sku": "...",
"name": "...",
"desc": "...",
"desc_short": "...",
"price": ...,
"qty": ...,
"categories": ["..."],
"image_path": "..."
}
]
Obrázky pro import jsou v katalogu ./etc/data/img
.
Čas na import 10 produktů pomocí této metody je na mém notebooku asi 10 sekund. Pokud tuto myšlenku dále rozvineme, snadno dojdeme k závěru, že lze dovézt asi 3600 produktů za hodinu a import 100 30 produktů může trvat asi XNUMX hodin. Nahrazení notebooku serverem vám umožní situaci poněkud vyhladit. Možná i několikrát. Ale ne řádově. Možná je tato rychlost a pomalost do jisté míry jedním z důvodů vzniku projektu
Radikálním řešením pro zvýšení rychlosti importu by mohl být přímý vstup do databáze, ale v tomto případě jsou všechny „dobroty“ ohledně rozšiřitelnosti Magenta ztraceny – vše budete muset udělat „pokročile“ sami. Nicméně to stojí za to. Pokud to vyjde, budu uvažovat o přístupu s přímým zápisem do databáze v příštím článku.
Zdroj: www.habr.com