Magento is een e-commerce oplossing, wat betekent dat het meer gericht is op de verkoop van producten dan op de bijbehorende voorraad-, logistieke of financiƫle administratie. Voor bijbehorende taken zijn andere applicaties (bijvoorbeeld ERP-systemen) beter geschikt. Daarom komt het in de praktijk vaak voor dat het nodig is om de winkel te integreren met deze andere systemen (bijvoorbeeld met 1C).
In grote lijnen kan integratie worden teruggebracht tot het repliceren van gegevens voor:
- de catalogus (producten, categorieƫn);
- voorraadgegevens (hoeveelheid producten op voorraad en prijzen);
- klanten;
- bestellingen;
Magento biedt een aparte klasse objecten voor het manipuleren van gegevens in de database ā . Vanwege de specificiteit van Magento is het toevoegen van gegevens aan de database via repositories eenvoudig te coderen, maar gebeurt, laten we zeggen, niet snel. In dit artikel bespreek ik de belangrijkste stappen voor het programmatic toevoegen van een product aan Magento 2 op de āklassiekeā manier ā met gebruik van repo-klassen.
Klanten en bestellingen worden meestal de andere kant op gerepliceerd ā van Magento naar externe ERP-systemen. Daarom is het eenvoudiger met hen, aan de kant van Magento hoef je gewoon de bijbehorende gegevens te selecteren, en dan ā āvan onze kant zijn de kogels afgevuurdĀ«.
Principes voor het schrijven van gegevens in de database
Op dit moment wordt het creƫren van objecten die in de database worden opgeslagen via programmeren in Magento gedaan door middel van :
function __construct (MagentoCmsModelBlockFactory $blockFactory) {
$this->blockFactory = $blockFactory;
}
/** @var MagentoCmsModelBlock $block *//
$block = $this->blockFactory->create();en het opslaan in de database ā via :
function __construct (MagentoCmsApiBlockRepositoryInterface $blockRepo) {
$this->blockRepo = $blockRepo;
}
$this->blockRepo->save($block);De benadering met gebruik van āFactoryā en āRepositoryā kan worden gebruikt voor alle belangrijkste modellen in het domein van Magento 2.
Basisinformatie over het product
Ik bespreek de datastructuur die correspondeert met versie Magento 2.3. De meest basale informatie over een product bevindt zich in de tabel catalog_product_entity (register van producten):
entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_atIk beperk me tot ƩƩn type product (type_id='simple'), een set van standaardattributen (attribute_set_id=4) en negeer de attributen has_options en required_options. Aangezien de attributen entity_id, created_at en updated_at automatisch worden gegenereerd, hebben we in feite alleen het volgende nodig voor het toevoegen van een nieuw product: sku. Ik doe het als volgt:
/** @var MagentoCatalogApiDataProductInterfaceFactory $factProd */
/** @var MagentoCatalogApiProductRepositoryInterface $repoProd */
/** @var MagentoCatalogApiDataProductInterface $prod */
$prod = $factProd->create();
$prod->setAttributeSetId(4);
$prod->setTypeId('simple');
$prod->setSku($sku);
$repoProd->save($prod);en ontvang een uitzondering:
De waarde van het attribuut "Productnaam" is leeg. Stel het attribuut in en probeer het opnieuw.Ik voeg de productnaam toe aan de aanvraag en ontvang een bericht dat de attribuut ontbreekt. Prijs. Na het toevoegen van de prijs wordt het product in de database opgeslagen:
$prod = $factProd->create();
$prod->setAttributeSetId(4);
$prod->setTypeId('simple');
$prod->setSku($sku);
$prod->setName($name);
$prod->setPrice($price);
$repoProd->save($prod);De productnaam wordt opgeslagen in de varchar-attributentabel (catalog_product_entity_varchar), de prijs in de tabel catalog_product_entity_decimal. Voor het toevoegen van een product is het raadzaam om expliciet aan te geven dat we de administratie-interface gebruiken voor het importeren van gegevens:
/** @var MagentoStoreModelStoreManagerInterface $manStore */
$manStore->setCurrentStore(0);Extra attributen
Het verwerken van extra productattributen met Magento is een genoegen. Het EAV-datamodel voor de belangrijkste entiteiten (zie tabel eav_entity_type) is een van de belangrijkste kenmerken van dit platform. Voeg eenvoudig de overeenkomstige attributen toe aan het productmodel:
$prodEntity->setData('description', $desc);
$prodEntity->setData('short_description', $desc_short);
// of
$prodEntity->setDescription($desc);
$prodEntity->setShortDescription($desc_short);en bij het opslaan van het model via het repo-object:
$repoProd->save($prod);zullen de extra attributen ook worden opgeslagen in de bijbehorende database-tabellen.
Voorraadgegevens
Simpel gezegd - de hoeveelheid product op voorraad. In Magento 2.3 wijzen de structuren in de database die het opslaan van voorraadgegevens beschrijven, van wat het vroeger was. Desondanks is het toevoegen van de hoeveelheid product op voorraad via het productmodel niet veel moeilijker dan het toevoegen van andere attributen:
/** @var MagentoCatalogModelProduct $prodEntity */
/** @var MagentoCatalogApiProductRepositoryInterface $repoProd */
$inventory = [
'is_in_stock' => true,
'qty' => 1234
];
$prodEntity->setData('quantity_and_stock_status', $inventory);
$repoProd->save($prodEntity);Media
Over het algemeen verschilt de media-ondersteuning van een product voor de klant in de winkel (e-commerce) van de media-ondersteuning van hetzelfde product voor de medewerker in het interne recordhoudsysteem (ERP). In het eerste geval is het wenselijk om het "product in beeld" te tonen, in het tweede geval is het voldoende om een algemeen beeld van het product te geven. Desondanks is het overbrengen van ten minste de primaire afbeelding van het product een vrij gebruikelijke case bij het importeren van gegevens.
Bij het toevoegen van een afbeelding via de administratie wordt de afbeelding eerst opgeslagen in de tijdelijke map (./pub/media/tmp/catalog/product) en alleen bij het opslaan van het product verplaatst naar de mediamap (./pub/media/catalog/product). Ook worden er bij het toevoegen via de administratie tags aan de afbeelding toegewezen afbeelding, 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);Om de een of andere reden wordt de media alleen gekoppeld na een eerdere opslag van het product en het opnieuw ophalen ervan uit de repository. En het attribuut moet worden opgegeven. label Bij het toevoegen van een record aan de mediagalerij van het product (anders krijgen we een uitzondering Ongedefinieerde index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php op regel 516).
Categorieƫn
Vaak kan de structuur van de winkel-categorieƫn en de backend-applicatie of de plaatsing van producten daarin aanzienlijk verschillen. De strategieƫn voor het migreren van gegevens over categorieƫn en producten hangen van veel factoren af. In dit voorbeeld houd ik me aan het volgende:
- de backend-categorieƫn en de winkelcategorieƫn worden gekoppeld op basis van naam;
- als er een categorie wordt geĆÆmporteerd die nog niet in de winkel bestaat, wordt deze onder de hoofd categorie aangemaakt (
Standaard Categorie) en de verdere positionering in de winkelcatalogus gebeurt handmatig; - de koppeling van een product aan een categorie vindt alleen plaats bij de creatie in de winkel (de eerste import);
De belangrijkste informatie over de categorie bevindt zich in de tabel catalog_category_entity (categoriecatalogus). Het aanmaken van een categorie in Magento:
/** @var MagentoCatalogApiDataCategoryInterfaceFactory $factCat */
/** @var MagentoCatalogApiCategoryRepositoryInterface $repoCat */
$cat = $factCat->create();
$cat->setName($name);
$cat->setIsActive(true);
$repoCat->save($cat);De koppeling van het product aan de categorie gebeurt op basis van de categorie-ID en SKU van het product:
/** @var MagentoCatalogModelCategoryProductLinkFactory $factCatProdLink */
/** @var MagentoCatalogApiCategoryLinkRepositoryInterface $repoCatLink */
$link = $factCatProdLink->create();
$link->setCategoryId($catMageId);
$link->setSku($prodSku);
$repoCatLink->save($link);Total
Het schrijven van code voor het programmatically toevoegen van een product in Magento 2 is eigenlijk niet zo moeilijk. Alles wat hierboven is beschreven, heb ik samengevoegd in een demo-module "". In de module is er maar één console commando fl32:import:prod, dat producten importeert die zijn beschreven in het JSON-bestand "«:
[
{
"sku": "...",
"name": "...",
"desc": "...",
"desc_short": "...",
"price": ...,
"qty": ...,
"categories": ["..."],
"image_path": "..."
}
]Afbeeldingen voor import bevinden zich in de map ./etc/data/img.
De tijd voor het importeren van 10 producten op deze wijze bedraagt ongeveer 10 seconden op mijn laptop. Als je deze gedachte verder ontwikkelt, is het niet moeilijk te concluderen dat je ongeveer 3600 producten per uur kunt importeren, en het kan ongeveer 30 uur duren om 100K producten te importeren. Het vervangen van de laptop door een server kan de situatie iets verbeteren. Misschien zelfs aanzienlijk. Maar niet extreem. Misschien is deze snelheid in zekere zin een van de redenen voor het ontstaan van het project .
Een radicale oplossing voor het verhogen van de importsnelheid kan directe schrijfoperaties in de database zijn, maar in dat geval gaan alle 'voordelen' met betrekking tot de uitbreidbaarheid van Magento verloren ā je moet alles zelf 'uitbreiden'. Niettemin, het is het waard. Als het mogelijk is, zal ik de aanpak van directe schrijfacties in de DB in het volgende artikel overwegen.
Bron: habr.com
