Magento est une solution de commerce électronique, c'est-à-dire plus axé sur la vente de produits que sur les ventes d'accompagnement d'entrepôt, de logistique ou de comptabilité financière. D'autres applications (comme les systèmes ERP) conviennent mieux aux compagnons. Par conséquent, assez souvent dans la pratique de l'utilisation de Magento, la tâche d'intégrer un magasin avec ces autres systèmes (par exemple, avec 1C) se pose.
Dans l'ensemble, l'intégration peut être réduite à la réplication des données par:
- catalogue (produits, catégories);
- données d'inventaire (stocks de produits dans les entrepôts et prix);
- aux clients;
- les commandes;
Magento pour la manipulation des données dans la base de données propose une classe d'objets distincte - les référentiels . En raison des spécificités de Magento, l'ajout de données à la base de données via des référentiels est facile à coder, mais cela se produit, disons, pas rapidement. Dans cette publication, je considère les principales étapes de l'ajout par programme d'un produit à Magento 2 d'une manière "classique" - en utilisant des classes de repo.
Les clients et les commandes sont généralement répliqués de l'autre côté - de Magento aux systèmes ERP externes. Par conséquent, c'est plus simple avec eux, du côté de Magento, il vous suffit de sélectionner les données appropriées, puis " les balles tirées de notre côté ".
Principes d'écriture des données dans la base de données
À l'heure actuelle, la création d'objets stockés dans la base de données par programmation dans Magento se fait via Factory :
function __construct (\Magento\Cms\Model\BlockFactory $blockFactory) { $this->blockFactory = $blockFactory; } $block = $this->blockFactory->create();
et écrire dans la base de données via le référentiel :
function __construct (\Magento\Cms\Api\BlockRepositoryInterface $blockRepo) { $this->blockRepo = $blockRepo; } $this->blockRepo->save($block);
L'approche Factory et Repository peut être utilisée pour tous les principaux modèles du domaine Magento 2.
J'envisage une structure de données correspondant à Magento 2.3. Les informations produit les plus élémentaires se catalog_product_entity
dans la table catalog_product_entity
(registre de produits):
entity_id attribute_set_id type_id sku has_options required_options created_at updated_at
Je type_id='simple'
limite type_id='simple'
un type de produit ( type_id='simple'
), un ensemble d' attribute_set_id=4
par défaut ( attribute_set_id=4
) et has_options
required_options
attributs has_options
et required_options
. Étant donné que les attributs entity_id
, created_at
et updated_at
sont générés automatiquement, il nous suffit donc de spécifier sku
pour ajouter un nouveau produit. Je fais ça:
$prod = $factProd->create(); $prod->setAttributeSetId(4); $prod->setTypeId('simple'); $prod->setSku($sku); $repoProd->save($prod);
et obtenez une exception:
The "Product Name" attribute value is empty. Set the attribute and try again.
J'ajoute le nom du produit à la demande et je reçois un message indiquant que l'attribut Price
est manquant. Après avoir ajouté le prix, le produit tombe dans la base de données:
$prod = $factProd->create(); $prod->setAttributeSetId(4); $prod->setTypeId('simple'); $prod->setSku($sku); $prod->setName($name); $prod->setPrice($price); $repoProd->save($prod);
Le nom du produit est stocké dans la table des attributs varchar du produit ( catalog_product_entity_varchar
), le prix est stocké dans la table catalog_product_entity_decimal
. Avant d'ajouter un produit, il est conseillé d'indiquer explicitement que nous utilisons une vitrine administrative pour importer des données:
$manStore->setCurrentStore(0);
Attributs supplémentaires
Le traitement des attributs de produit supplémentaires avec Magento est un plaisir. Le modèle de données EAV pour les entités principales (voir le tableau eav_entity_type
) est l'une des principales caractéristiques de cette plate-forme. Ajoutez simplement les attributs appropriés au modèle de produit:
$prodEntity->setData('description', $desc); $prodEntity->setData('short_description', $desc_short);
et lors de l'enregistrement du modèle via l'objet repo:
$repoProd->save($prod);
des attributs supplémentaires seront également stockés dans les tables de base de données correspondantes.
Données d'inventaire
D'une manière simple - la quantité de produit en stock. Dans Magento 2.3, les structures de base de données décrivant le format de stockage des données d'inventaire sont considérablement différentes de ce qu'elles étaient auparavant. Cependant, l'ajout de quantités de produits en stock via un modèle de produit n'est pas beaucoup plus difficile que l'ajout d'autres attributs:
$inventory = [ 'is_in_stock' => true, 'qty' => 1234 ]; $prodEntity->setData('quantity_and_stock_status', $inventory); $repoProd->save($prodEntity);
En règle générale, le support média pour un produit pour un client dans un magasin (commerce électronique) est différent du support média pour le même produit pour un employé dans un système de comptabilité interne (ERP). Dans le premier cas, il est souhaitable de montrer le "visage du produit", dans le second - il suffit de donner une idée générale du produit. Néanmoins, le transfert d'au moins l'image principale du produit est un case
assez courant lors de l'importation de données.
Lors de l'ajout d'une image via le panneau d'administration, l'image est d'abord enregistrée dans le répertoire temporaire ( ./pub/media/tmp/catalog/product
) et uniquement lorsque le produit est enregistré est déplacé vers le répertoire multimédia ( ./pub/media/catalog/product
). De plus, lors de l'ajout via le small_image
administration, l'image est définie sur les small_image
image
, small_image
, thumbnail
, swatch_image
.
$imagePathRelative = $this->imagePlaceToTmpMedia($imagePath); $product = $repoProd->get($sku); $gallery['images'][] = [ 'file' => $imagePathRelative, 'media_type' => 'image' 'label' => '' ]; $product->setData('media_gallery', $gallery); $product->setData('image', $imagePathRelative); $product->setData('small_image', $imagePathRelative); $product->setData('thumbnail', $imagePathRelative); $product->setData('swatch_image', $imagePathRelative); $hndlGalleryCreate->execute($product);
Pour une raison quelconque, le support n'est lié qu'après avoir préalablement enregistré le produit et l'avoir reçu à nouveau du référentiel. Et vous devez spécifier l'attribut label
lors de l'ajout d'une entrée à la galerie multimédia du produit (sinon, nous obtenons l'exception d' Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516
défini Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516
).
Les catégories
Souvent, la structure des catégories de magasins et des applications dorsales ou le placement de produits dans celles-ci peut varier considérablement. Les stratégies de transfert de données sur les catégories et les produits qu'elles contiennent dépendent de nombreux facteurs. Dans cet exemple, je m'en tiens aux points suivants:
- les catégories de backend et de store sont comparées par nom;
- si une catégorie est importée qui ne se trouve pas dans le magasin, elle est créée sous la catégorie racine (catégorie
Default Category
) et son positionnement ultérieur dans le catalogue du magasin est supposé manuellement; - un produit n'est affecté à une catégorie que lorsqu'il est créé dans un magasin (première importation);
Les informations de base sur les catégories se catalog_category_entity
dans la table catalog_category_entity
(catalogue de catégories). Créer une catégorie dans Magento:
$cat = $factCat->create(); $cat->setName($name); $cat->setIsActive(true); $repoCat->save($cat);
Le produit est affecté à une catégorie par ID de catégorie et SKU de produit:
$link = $factCatProdLink->create(); $link->setCategoryId($catMageId); $link->setSku($prodSku); $repoCatLink->save($link);
Total
Écrire du code pour ajouter un produit à Magento 2 par programmation est très facile. Tout ce qui précède, je l'ai réduit au module de démonstration " flancer32 / mage2_ext_demo_import ". Il n'y a qu'une seule commande console fl32:import:prod
dans le fl32:import:prod
, qui importe les produits décrits dans le fichier JSON " ./etc/data/products.json ":
[ { "sku": "...", "name": "...", "desc": "...", "desc_short": "...", "price": ..., "qty": ..., "categories": ["..."], "image_path": "..." } ]
Les images à importer se trouvent dans le répertoire ./etc/data/img
.
Le temps d'importation de 10 produits de cette manière est d'environ 10 secondes sur mon ordinateur portable. Si nous développons davantage cette idée, il est facile de conclure qu'environ 3 600 produits peuvent être importés par heure, et environ 30 heures peuvent être prises pour importer des produits 100K. Le remplacement d'un ordinateur portable par un serveur vous permet de quelque peu atténuer la situation. Peut-être même parfois. Mais pas par ordre de grandeur. Peut-être vitesse la lenteur est dans une certaine mesure l'une des raisons de l'émergence du projet magento / async-import .
Une décision cardinale d'augmenter la vitesse d'importation peut être d'écrire directement dans la base de données, mais dans ce cas, tous les "petits pains" concernant l'extensibilité de Magento sont perdus - vous devez tout faire vous-même "avancé". Cependant, cela en vaut la peine. Si cela fonctionne, je considérerai l'approche avec enregistrement direct dans la base de données dans le prochain article.