Magento er en e-handelsløsning, dvs. er mer rettet mot å selge produkter enn på lager, logistikk eller finansregnskap som følger med salg. Andre applikasjoner (for eksempel ERP-systemer) er bedre egnet for tilhørende applikasjoner. Derfor, ganske ofte i praksisen med å bruke Magento, oppstår oppgaven med å integrere en butikk med disse andre systemene (for eksempel 1C).
Stort sett kan integrasjon reduseres til datareplikering ved å:
- katalog (produkter, kategorier);
- lagerdata (produktbalanser i varehus og priser);
- klienter;
- bestillinger;
Magento tilbyr en egen klasse med objekter for å manipulere data i databasen -
Kunder og bestillinger replikeres vanligvis i den andre retningen – fra Magento til eksterne ERP-systemer. Derfor er det enklere med dem, på Magento-siden trenger du bare å velge riktige data, og deretter "kuler fløy ut fra vår side".
Prinsipper for å registrere data i en database
For øyeblikket er det ferdig å lage objekter som er lagret i databasen programmatisk i Magento
function __construct (MagentoCmsModelBlockFactory $blockFactory) {
$this->blockFactory = $blockFactory;
}
/** @var MagentoCmsModelBlock $block */
$block = $this->blockFactory->create();
og skriving til databasen gjøres gjennom
function __construct (MagentoCmsApiBlockRepositoryInterface $blockRepo) {
$this->blockRepo = $blockRepo;
}
$this->blockRepo->save($block);
Tilnærmingen "Factory" og "Repository" kan brukes for alle hovedmodeller i Magento 2-domenet.
Grunnleggende produktinformasjon
Jeg ser på en datastruktur som samsvarer med Magento 2.3-versjonen. Den mest grunnleggende informasjonen om produktet er i tabellen catalog_product_entity
(produktregister):
entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_at
Jeg er begrenset til én type produkt (type_id='simple'
), et sett med standardattributter (attribute_set_id=4
) og ignorer attributter has_options
и required_options
. Siden attributtene entity_id
, created_at
и updated_at
genereres automatisk, så, faktisk, for å legge til et nytt produkt, trenger vi bare å stille inn sku
. Jeg gjør dette:
/** @var MagentoCatalogApiDataProductInterfaceFactory $factProd */
/** @var MagentoCatalogApiProductRepositoryInterface $repoProd */
/** @var MagentoCatalogApiDataProductInterface $prod */
$prod = $factProd->create();
$prod->setAttributeSetId(4);
$prod->setTypeId('simple');
$prod->setSku($sku);
$repoProd->save($prod);
og jeg får et unntak:
The "Product Name" attribute value is empty. Set the attribute and try again.
Jeg legger til produktnavnet i forespørselen og får en melding om at attributtet mangler Price
. Etter å ha lagt til prisen, legges produktet til i databasen:
$prod = $factProd->create();
$prod->setAttributeSetId(4);
$prod->setTypeId('simple');
$prod->setSku($sku);
$prod->setName($name);
$prod->setPrice($price);
$repoProd->save($prod);
Produktnavnet er lagret i produkt varchar attributttabell (catalog_product_entity_varchar
), pris - i tabellen catalog_product_entity_decimal
. Før du legger til et produkt, er det tilrådelig å eksplisitt angi at vi bruker den administrative butikkfronten til å importere data:
/** @var MagentoStoreModelStoreManagerInterface $manStore */
$manStore->setCurrentStore(0);
Ytterligere attributter
Å behandle ytterligere produktattributter ved å bruke Magento er en fornøyelse. EAV-datamodell for hovedenheter (se tabell eav_entity_type
) er en av nøkkelfunksjonene til denne plattformen. Vi legger ganske enkelt til de riktige attributtene til produktmodellen:
$prodEntity->setData('description', $desc);
$prodEntity->setData('short_description', $desc_short);
// или
$prodEntity->setDescription($desc);
$prodEntity->setShortDescription($desc_short);
og når du lagrer modellen via repo-objektet:
$repoProd->save($prod);
tilleggsattributter vil også bli lagret i de tilsvarende databasetabellene.
Inventardata
Enkelt sagt - mengden produkt på lager. I Magento 2.3 er strukturer i databasen som beskriver formatet for lagring av lagerdata
/** @var MagentoCatalogModelProduct $prodEntity */
/** @var MagentoCatalogApiProductRepositoryInterface $repoProd */
$inventory = [
'is_in_stock' => true,
'qty' => 1234
];
$prodEntity->setData('quantity_and_stock_status', $inventory);
$repoProd->save($prodEntity);
media
Mediestøtte for et produkt for en kunde i en butikk (e-handel) skiller seg som regel fra mediestøtte for samme produkt for en ansatt i et internt regnskapssystem (ERP). I det første tilfellet er det tilrådelig å vise produktet ansikt til ansikt; i det andre er det nok å gi en generell ide om produktet. Det er imidlertid ganske vanlig å overføre i det minste det primære bildet av et produkt. case
når du importerer data.
Når du legger til et bilde gjennom administrasjonspanelet, lagres bildet først i en midlertidig katalog (./pub/media/tmp/catalog/product
) og kun når du lagrer, flyttes produktet til mediekatalogen (./pub/media/catalog/product
). Når det legges til via administrasjonspanelet, blir bildet også merket 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);
Av en eller annen grunn kobles media først etter først å ha lagret produktet og hentet det fra depotet igjen. Og du må spesifisere attributtet label
når du legger til en oppføring i produktmediegalleriet (ellers får vi et unntak Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516
).
kategori
Ofte kan kategoristrukturen til butikken og backend-applikasjonen eller plasseringen av produkter i dem variere betydelig. Strategier for å migrere data om kategorier og produkter innenfor dem avhenger av mange faktorer. I dette eksemplet holder jeg meg til følgende:
- backend- og butikkkategorier sammenlignes etter navn;
- hvis en kategori importeres som ikke er i butikken, opprettes den under rotkategorien (
Default Category
) og dens videre plassering i butikkkatalogen antas manuelt; - et produkt tildeles en kategori bare når det er opprettet i butikken (første import);
Grunnleggende informasjon om kategorien er i tabellen catalog_category_entity
(katalog over kategorier). Opprette en kategori i Magento:
/** @var MagentoCatalogApiDataCategoryInterfaceFactory $factCat */
/** @var MagentoCatalogApiCategoryRepositoryInterface $repoCat */
$cat = $factCat->create();
$cat->setName($name);
$cat->setIsActive(true);
$repoCat->save($cat);
Kobling av et produkt til en kategori utføres ved å bruke kategori-ID og produkt-SKU:
/** @var MagentoCatalogModelCategoryProductLinkFactory $factCatProdLink */
/** @var MagentoCatalogApiCategoryLinkRepositoryInterface $repoCatLink */
$link = $factCatProdLink->create();
$link->setCategoryId($catMageId);
$link->setSku($prodSku);
$repoCatLink->save($link);
Totalt
Det er ganske enkelt å skrive kode for å legge til et produkt programmatisk til Magento 2. Jeg har kombinert alt nevnt ovenfor til en demomodul "fl32:import:prod
, som importerer produktene beskrevet i JSON-filen "
[
{
"sku": "...",
"name": "...",
"desc": "...",
"desc_short": "...",
"price": ...,
"qty": ...,
"categories": ["..."],
"image_path": "..."
}
]
Bilder for import er i katalogen ./etc/data/img
.
Tiden for å importere 10 produkter ved hjelp av denne metoden er omtrent 10 sekunder på min bærbare datamaskin. Hvis vi utvikler denne ideen videre, er det lett å komme til den konklusjonen at ca 3600 produkter kan importeres i timen, og det kan ta ca 100 timer å importere 30K produkter. Ved å bytte ut en bærbar datamaskin med en server kan du jevne ut situasjonen noe. Kanskje til og med flere ganger. Men ikke i størrelsesordener. Kanskje er denne hastigheten og tregheten til en viss grad en av årsakene til prosjektets fremvekst
En radikal løsning for å øke importhastigheten kan være direkte innføring i databasen, men i dette tilfellet går alle "godbitene" angående utvidbarheten til Magento tapt - du må gjøre alt "avansert" selv. Det er imidlertid verdt det. Hvis det går, vil jeg vurdere tilnærmingen med direkte skriving til databasen i neste artikkel.
Kilde: www.habr.com