Termék importálás Magento webshopba a Magmi rendszerrel

Tartalom

    • Mi is az a Magmi?
    • A Magmi és a Magento 2.0
    • A Magmi telepítése
    • A Magmi alapbeállítása
    • Magmi plugin-jainak a beállítása
  • Egyszerű termék importálása
  • Hogyan kell csoportos árat (Group Price) importálni?
  • Hogyan kell mennyiség kedvezmény árat (tier prices) beállítani?
  • Hogyan tudom a termékeket hozzárendelni a több website-os áruházban?
  • Hogyan kell importálni?
  • Konfigurálható termék importálása
  • Kötegelt termék importálása
  • Csoportos termék importálása
  • Letölthető termék importálása
  • Virtuális termék importálása
  • Jellemző és jellemzőhalmaz importálása
  • Termékkategóriák importálása
  • Többnyelvű importálás

Mi is az a Magmi?

A Magento egy erőteljes, a legtöbb e-kereskedelemmel kapcsolatos feladat ellátására alkalmas platform. Alapértelmezett kezelőfelülete azonban hagy némi kívánnivalót maga után. A Magmi, azaz a Magento Mass Importer feladata, hogy segítsen ezeknek a réseknek a kitöltésében, és könnyebbé tegye a Magento rendszeren üzemeltetett webáruházunk működtetését.

Gyakran merül fel az igény például arra, hogy egyszerre több száz, vagy akár több ezer termékből álló online katalógus hozzunk létre és kezeljünk, a lehető legegyszerűbb és leghatékonyabb módon. Ennek kivitelezése a Magento kezelőfelületén keresztül, manuális módon egyáltalán nem egyszerű feladat.

A Magmi egy olyan, nyílt forráskódú rendszer, melynek segítségével egy sor olyan import/export opcióhoz férhetünk hozzá, amelyek alapból nem találhatóak meg a Magento rendszerében, ám rendkívül megkönnyíthetik az ilyen, és ehhez hasonló munka elvégzését. Lényegében egy külső felhasználói felület, mely segítségével könnyedén importálhatunk termékeket (akár nagy számban is) egyszerű CSV-fájlokból a Magento alapú webáruházunkba.

Sajnos az adatbázist valamilyen módon mindenképpen nekünk kell kialakítanunk, ami azt jelenti, hogy az ehhez használt .csv kiterjesztésű fájlokat továbbra is nekünk kell létrehoznunk. Ezek a fájlok azonban az MS Excel vagy a LibreOffice Calc segítségével is könnyen szerkeszthetők, a Magmi segítségével pedig gyorsabbá és egyszerűbbé tehetjük az adatbázis feltöltésének feladatát. Legnagyobb erőssége, hogy olyan dolgokat is megtehetünk a segítségével, mint például a képek tömeges importálása, vagy éppen a kategóriák automatikus létrehozása termékeink importáláskor.

A Magmi használatának hátránya mindössze annyi, hogy a már megszokott magento kezelőfelület mellett egy újabb adminisztrációs interfész használatát meg kell tanulnunk, a tapasztalatok szerint azonban ez egyáltalán nem teljesíthetetlen feladat. Az applikáció bőséges dokumentációja ugyanis lépésről lépésre vezet minket végig minden fontos funkción, a fejlesztők pedig még saját Wikit is létrehoztak annak érdekében, hogy segítség a Magmi használata mellett döntő felhasználókat..

A Magmi és a Magento 2.0

Mint azt már nyilván sokan tudják, a Magento 1.x verzióinak hivatalos támogatása 2020 júniusában véget ér. Ez azt jelenti, hogy a keretrendszer 2.0-nál korábbi verziói ettől az időponttól kezdve sem szoftveres, sem pedig biztonsági támogatásban nem részesülnek hivatalosan, így használatuk veszélyessé válik.

A legtöbb e-kereskedő éppen ezért árhatóan a Magento 2.x verzióira vált majd, ezzel a váltással pedig óhatatlanul felmerül a kérdés: mi a helyzet a Magmi-val, ami a Magento 1.x verziói esetében olyan jó szolgálatot tett, ha a webruházba történő importálás és expotálás feladatáról volt szó?

Nos, van egy jó hírünk! A Magmi természetesen a Magento 2.0 verziójához is elérhető, habár bizonyos funkciói egyelőre kevésbé működnek hatékonyan, mint a rendszer korábbi változatai esetében. A Magento 1.x támogatásának megszűnésével azonban várható, hogy a fejlesztők belevetik magukat a Magmi új rendszerrel kompatibilis verziójának tökéletesítésébe, és hamarosan egy minden funkciójában tökéletes, az export és import feladatokat hibátlanul ellátó kiegészítőt köszönthetünk a legújabb Magmi-frissítés személyében.

A Magmi telepítése

A Magmi telepítése

A Magmi telepítése némi gyakorlatot igényel, azonban az interneten rengeteg segédanyagot találhatunk azzal kapcsolatban, hogyan is csináljuk helyesen, és természetesen most mi is azért vagyunk itt, hogy segítsünk.

A cikkben a Magmi 0.7.22 verziójának telepítését és alkalmazását fogjuk bemutatni.

  • Első lépésként töltsük le a Magmi-t a GitHub-ról. A Magento 2.0 verziójával kompatibilis változat az oldalon, ide kattintva érhető el.
  • Ha ez megtörtént, az FTP-kliens segítségével másoljuk fel a magento root könyvtárunkba.
  • Aki régebbi Magmi verziót használ (< 0.7.22) annak ajánlott a Magmi mappát átneveznie, és e mellet még htaccess-es megoldással levédeni a magmi/ root mappáját. Ha ezeket a beállításokat nem végezzük el, akkor bárki elérheti a Magmis felületünket.

 

Magmi plugin-jainak a beállítása

Magmi pluginjainak a beállítása

A Magmi kiegészítőinek beállításai a Configure Current Profile opció alatt, illetve a general és az itemprocessors résznél találhatók.

Mindegyik plugin-nál található egy Info gomb, melyre rákattintva rövid leírást kapunk az adott kiegészítőről. A Documentation gomb (mely nem biztos, hogy minden felhasználónál megjelenik) pedig a Magmi Wiki oldalára visz, ahol részletesebb leírást is találhatunk az adott pugin-ról.

Ha az egyik plugin-t aktiváljuk, megjelenik egy Configure gomb is, melynek megnyomása után be tudjuk állítani a kiegészítőhöz tartozó, fontos beállításokat.

Most minden plugin-ról leírunk pár fontos tudnivalót, a teljes, részletes ismertetőket a plugin-ok fentebb említett dokumentációjában találhatod meg.

Magmi beállítás általános

Remote Agent Plugin v0.0.1

  • Fejlesztette: Dweeves
  • Leírás: ez a plugin lehetővé teszi a távoli rendszeren való működést, akkor használatos, ha a Magmi távoli rendszeren van telepítve
  • Beállításai:
    • HTTP Url for magento base dir: távoli rendszer magento mappa url-je

Attribute Cleanup v0.0.1

  • Fejlesztette: 5byfive GmbH
  • Leírás: ez a plugin eltávolítja azokat a jellemzőket, melyek az adott terméknél nem használunk
  • Beállításai: nincs

Attribute Set Importer v0.0.2

  • Fejlesztette: 5byfive GmbH
  • Leírás: ez a plugin lehetővé teszi a jellemzőhalmazok és jellemzők importálását.
  • Beállításai:
    • Enable attribute import (Engedélyezzük-e a jellemző importálását)
      • CSV import mode: fentebb részletezve (a további beállítások is ugyanazok, mint a CSV options-nál)
      • Set default values for non-existing columns in CSV (JSON): ide kell beírni azokat az értékeket, amelyek mindegyik jellemzőnél ugyanazok, JSON formátumban kell megadni, pl. {“is_user_defined”:1,”is_visible”:1,”default_value”:”Test”}
      • Prune attributes which are not in CSV from database: ha ez be van kapcsolva, akkor először lefutatja a jellemző-importot, majd az összes olyan jellemzőt törli, ami nincs a csv-ben. Ez akkor jó, ha mindig az összes jellemzőt importáljuk és szeretnénk, ha a felesleges jellemzőket a plugin törölné.
      • Don’t touch non-user attributes when pruning (ha a prune attributes be van kapcsolva): Ezt akkor kell használnunk, ha csak azokat a jellemzőket szeretnénk törölni, amik is_user_defined = 1, vagyis a nem rendszer attribútumok. (ezt az egyedi fejlesztések során létrejött jellemzőkre szoktuk állítani)
      • additionally, keep following attributes when pruning, even if not given in CSV (comma-separated): Ebbe a mezőbe azoknak a jellemzőknek a kódját kell beírni (vesszővel elválasztva), amelyeket nem szeretnénk törölni (ezt akkor érdemes használni, ha a csv-ben nem adjuk meg a jellemzőt, de mégse szeretnénk, hogy a rendszer törölje)
      • Delete attributes marked “magmi:delete” = 1: ha ez be van kapcsolva és a csv-ben a magmi:delete oszlop létezik, amelynél 1-es értékre van állítva, akkor azt a jellemzőt törölni fogja
      • Create attributes from CSV which are not in database: ha ez bevan kapcsolva, akkor a plugin létrehozza azokat a jellemzőket, amelyek még nincsenek az adatbázisban. Ha nincs bekapcsolva, akkor a csv-ben lévő jellemzők
      • Update attributes from CSV which are already in database: kapcsoljuk be, ha szeretnénk, hogy frissítse a csv-ben megadott jellemzőket (ami szerepel az adatbázisban)
    • Enable attribute set import: engedélyezzük a jellemzőhalmaz importálását, Az itt található többi beállítás ugyanaz, mint a jellemzőnél.
    • Enable attribute association import: Ezzel tudjuk összepárosítani, hogy melyik jellemző melyik jellemzőcsoportba tartozzon.
      • CSV import mode: fentebb részletezve (a további csv beállítás is ugyanaz, mint a CSV options-nál)
      • Add these attribute associations to given CSV data: ide lehet plusz jellemző párosítást beletenni, vesszővel kell elválasztani ilyen formában: (attribute_set_name,attribute_code,attribute_group_name)

Ehhez tartozó beállítás ugyanaz, mint az előbbiekben leírtaknál.

Import Report Mail Notifier v1.0.0

  • Fejlesztette: Dweeves
  • Leírás: ezzel tudunk jelentést küldeni az importról
  • Beállításai:
    • Email report to: Kinek küldje a jelentést. Vesszővel elválasztva több e-mail címet is megadhatunk.
    • Report sender: küldő e-mail címe
    • Report sender alias: küldő alias-a
    • Subject: tárgy
    • Body: tartalom
    • Attachments: csatolmányok:
      • Attach import log: csatolja-e a jelentés log-ot
      • Attach source CSV: a csv forrást csatolja-e
      • Zip attachments: összecsomagolja-e a csatolmányokat

Magmi Import Url UI v1.0.3

  • Fejlesztette: Dweeves
  • Leírás: ez nem befolyásolja az importot, csak kiírja nekünk, hogy milyen url-en lehet meghívni. Ezeket általában cronjob-okba szokták írni.
  • Beállításai: nincs

Magmi Optimizer v1.0.5

  • Fejlesztette: Dweeves
  • Leírás: ez a plugin indexeket tesz pár olyan táblára, ahol észleli, hogy szükség van rá.
  • Beállításai: nincs

Magmi Magento Reindexer v1.0.3a

  • Fejlesztette: Dweeves
  • Leírás: ez a plugin a Magento-s reindexet hívja meg shell-ből, vagyis reindexelést végez.
  •  Beállításai:
    • PHP CLI command: php cli parancs
    • Indexing : Ki kell választani, hogy melyik index típusokat szeretnék, ha újraindexelné.

On the fly category creator/importer v0.2.5

  • Fejlesztette: Dweeves
  • Leírás: ezzel lehet importáláskor a kategóriákat létrehozni.
  • Beállításai:
    • Assign product to: Melyik kategóriához rendelje a terméket.
      • all categories in tree: az összes kategóriához a kategória fában (pl. Fő kategória/Alkategória/ ebben az esetben mind a 2 kategóriába bele fog tartozni)
      • last category of each branch: itt csak az utolsó szinten lévő kategóriába teszi bele a terméket.
    • Tree level separator: Alkategória elválasztójel (pl. / ebben az estben Kategória 1/Kategória 2)
    • base category tree: főkategória, ezt akkor ajánlott használni, ha mindegyik kategóriánk ugyanabba a főkategóriába tartozik.
    • url ending: url utótag, általában ajánlott a .html végződés

Downloadable products importer v1.0.0.1

  • Fejlesztette: Tangkoko SARL
  • Leírás: ez a plugin importálja a letölthető termékeket
  • Beállításai: Bővebben a „Letölthető termék importálása” résznél foglalkozunk vele

Group Price Importer v0.0.4 info

  • Fejlesztette: Tim Bezhashvyly és Dweeves
  • Leírás: csoportos árakat lehet importálni vele
  • Beállításai:
    A csv-ben ezt az oszlopot kell megadni:
    “group_price:groupName” ahol a groupName a vevőcsoport neve.
    Bővebben kifejtem a „Egyszerű termék importálása” résznél.

Image attributes processor v1.0.33a

  • Fejlesztette: Dweeves és Tommy Goode
  • Leírás: ez a plugin importálja a termékekről készült képeket.
  • Beállításai:
    • Image search path: melyik mappákban keresse a képeket (ezeket előzőleg fel kell tölteni a szerverre, ajánlott a media/import mappa), pontosvesszővel kell elválasztani, ha több mappát szeretnénk megadni
    • Image Renaming: átnevezze-e a képeket; hagyjuk üresen, ha az eredeti fájlnevet szeretnénk megtartani.
      Itt lehet dinamikus változókat használni.
      Ha szeretnénk átnevezni a képet, a következő formátumot javaslom:
      {item.sku}_{meta.attr_code}_{meta.store}.{meta.imagename.ext}
    • Image import mode: importálás módja
      • Keep existing images: ebben az esetben nem írja felül, vagy nem fogja letölteni (távoli url-ről) azokat a képeket, amelyek ugyanazon a néven léteznek.
      • Overwrite Existing Images: felülírja és újra letölti (távoli url-ről) az ugyanazon a néven szereplő képeket.
    • Assing only existing images: (ezt a beállítást nem figyeli a rendszer ebben a verzióban)
      • Import into DB: adatbázisba importálja-e; ezt csak akkor állítsuk Enabled-re, ha be van állítva a Magento-nkba a Media storage.
      • Debug mode: hibakeresés be legyen-e kapcsolva
      • Remote Image root: tavoli képek útvonala (ha nincs, üresen kell hagyni)
      • Remote root Authentication: szükség van-e távoli bejelentkezésre
      • Pre-download check: (ezt a beállítást nem figyeli a rendszer ebben a verzióban)

On the fly indexer v0.2

  • Fejlesztette: Dweeves
  • Leírás: ez a plugin importáláskor ír néhány index táblába (url_rewrites és a category_products)
  • Beállításai:
    • URL endings: url végződések, legyenek-e használva, és ha igen, akkor mik legyen azok.
    • Use Categories in Url: kategoriák legyenek-e az url-ben

Custom Options v0.0.7a

  • Fejlesztette: Pablo és Dweeves
  • Leírás: ezzel a plugin-nal lehet beimportálni a termékekhez az egyedi opciókat
  • Beállításai: a következőképp kell beállítani a csv-ben a custom optionokat:
    Name:Type:Is Required:sort number
    vagyis pl. Size:drop_down:1:1, és a terméksorba pedig pl: Small|Medium|Large
    A többi részletes variációt megtalálhatjuk a plugin dokumentációs oldalán.

Product Deleter v0.0.2

  • Fejlesztette: Dweeves
  • Leírás: ezzel a plugin-nal termékeket lehet törölni
  • Beállításai:
    • Delete Children products: törölje-e az alá tartozó termékeket. Ez a konfigurálható és kötegelt termékeknél lényeges.
      A csv-be új oszlopként fel kell venni a magmi:delete-et, és a törlendő termékeknél 1-re kell állítani.

Product Tags Importer v0.0.3

  • Fejlesztette: Dweeves, Pawel Kazakow
  • Leírás: termék címkéket lehet importálni vele
  • Beállításai:
    csv-ben vesszővel elválasztva kell beírni a címkéket a tags oszlopba

Tier price importer v0.0.9a

  • Fejlesztette: Dweeves, bepixeld
  • Leírás: ezzel lehet mennyiségre vonatkozó, kedvezményes árat importálni
  • Beállításai:
    Bővebben az „Egyszerű termék importálása résznél” foglalkozunk vele.

Weee Tax importer v0.0.5

  • Fejlesztette: Garbocom & Dweeves
  • Leírás: ezzel lehet a Weee-ket, vagyis környezetvédelmi adókat importál
  • Beállításai:
    • Weee Tax Attribute name: a környezetvédelmi adó jellemző kódja
    • Weee Tax Country code: az adó ország kódja (pl. FR)

Column mapper v0.0.3b

  • Fejlesztette: Dweeves
  • Leírás: ezt a plugin-t akkor érdemes használni, ha az import fájlban eltérőek az oszlopok nevei a Magento jellemzőkódoktól.
  • Beállításai:
    • Mapped columns list: ide kell felsorolni, vesszőkel elválasztva a Magento-ban szereplő jellemzőkódokat
    • New name for col X: ide írjuk be az import fájlban szereplő nevét az adott jellemzőnek (ha a Mapped columns listbe újat írunk be, akkor jelenik meg a New name for col …)

SKU Finder v0.0.3

  • Fejlesztette: Dweeves
  • Leírás: ezt a kiegészítőt akkor kell használnunk, ha nem adjuk meg az import fájlunkban az SKU vagyis cikkszám oszlopot, helyette egy másik termékjellemző alapján kell összepárosítani
  • Beállításai:
    • sku find attribute code: a párosítandó jellemző kódja.

Default Values setter v0.0.5

  • Fejlesztette: Dweeves
  • Leírás: ezzel lehet beállítani az olyan értékeket, amelyek mindegyik jellemzőnél ugyanazok, így nem kell az import fájlba beírni
  • Beállításai:
    • Default attribute list: vesszővel elválasztva be kell írni a jellemző kódjait, ahogy a Magento-ban szerepel, majd az alatta lévő oszlopokba pedig az értéket

Magmi Import Limiter v0.0.7

  • Fejlesztette: Dweeves
  • Leírás: ezt akkor kell használni, ha limitálást szeretnénk az importjainkra tenni, vagyis pl. csak bizonyos jellemzőket szeretnénk beimportálni, vagy csak bizonyos sortól sorig használni azokat.
  • Beállításai:
    • Column filter: melyik jellemzőket importáljuk, pl. sku,price,qty
    • Limiter ranges: pl. 1-100, vagyis hogy melyik sortól kezdve meddig importáljon
    • Limiter filters: csak azokat a termékeket importáljuk, amelyek bizonyos szűrési feltételnek megfelelnek,
      pl. sku::00.* – vagyis csak azokat a cikkszámokat importálja, amelyek 00-val kezdődnek
      pl. sku:00.*;;!name::.*blue.* – vagyis a 00-val kezdődő cikkszámokat és a név nem blue-val kezdődik.

Generic mapper v0.0.6a

  • Fejlesztette: Dweeves
  • Leírás: ezzel a plugin-nal a Magento-s értékekkel való értékpárosítást lehet elvégezni. Tipikus jellemző a page_layout és a visibility.
  • Beállításai:
    Ha szeretnénk használni, akkor az adott jellemzőre létre kell hoznunk a jellemző nevével egy csv fájlt a „magmi/plugins/itemprocessors/genericmapper/mappings” könyvtárba, pl. „magmi/plugins/itemprocessors/genericmapper/mappings/is_recurring.csv”
    Ennek a tartalmába be kell az érték párost írni. pl.
    „Yes”,1
    „No”,0
    Részletesebb leírást a plugin dokumentációjában olvashatunk.

Value Replacer v0.0.8a

  • Fejlesztette: Dweeves
  • Leírás: ezzel a plugin-nal jellemzők értékeit tudjuk lecserélni. Dinamikus változókat is használhatunk, vagyis pl. ha az összes termék cikkszámához szeretnénk perfixet tenni, akkor a következőképp kell beírni a mezőbe: prefix-{item.sku}
  • Beállításai:
    • Replaced attributes: fel kell sorolni a jellemzőkódokat, amelyeknél szeretnénk cserélni az értéket (vesszővel elválasztva)
    • New value for X: ide kell beírni az értéket
      További leírás a dokumentációban található.

Value Trimmer for select/multiselect v0.0.3

  • Fejlesztette: Dweeves
  • Leírás: ez a plugin automatikusan levágja az üres helyeket a többszöri vagy sima kiválasztós jellemzők értékénél
  • Beállításai: nincs

Grouped Item processor v1.4.1

  • Fejlesztette: Alpine Consulting, Inc & Dweeves
  • Leírás: ezzel lehet csoportos termékeket importálni
  • Beállításai:
    • Perform simples/group link: összekapcsolja-e az egyszerű termékeket a csoportos termékkel.
    • auto match simples skus before grouped: ezzel tudjuk beállítani, hogy automatikusan keresse-e meg a csoportos termékhez tartozó egyszerű termékeket, ha nem, akkor az import fájlban léteznie kell a „grouped_skus” oszlopnak, ahol pontosvesszővel elválasztva fel kell sorolni a hozzá tartozó egyszerű terméket.
    • Force simples visibility: az egyszerű altermékek láthatóságát állítsa-e, ha igen, akkor mire.

Bundle Item processor v1.1

  • Fejlesztette: Björn Tantau, Dweeves, igi8819
  • Leírás: Kötegelt termékeket importálhatunk vele
  • Beállításai:
    A „Kötegelt termékek importálása” résznél bővebben kitérünk rá, de mindegyik beállítás arra szolgál, hogy beállítsa az értékeket a megadott típushoz, abban az esetben, ha az import fájlban nem írjuk be azokat.

Configurable Item processor v1.3.7a

  • Fejlesztette: Dweeves
  • Leírás: Segítségével onfigurálható termékeket lehet importálhatunk.
  • Beállításai: ugyanazok, mint a csoportos terméknél, melyek fentebb olvashatók.

Cross/Upsell Importer v1.0.3

  • Fejlesztette: Dweeves
  • Leírás: Segítségével cross- és upsell termékeket importálhatunk.
  • Beállításai:
    Az import fájlban két új oszlopot kell beírni:
    us_skus – Upsell
    cs_skus – Cross sell
    Mindkettőnél cikkszámokat kell felsorolni, vesszővel elválasztva.

Product relater v1.0

  • Fejlesztette: Dweeves, jwtechniek
  • Leírás: Segítségével hasonló termékeket impotálhatunk.
  • Beállításai:
    Az import fájlban a re_skus oszlopba kell beírni a cikkszámokat.
    Részletesebb leírást a plugin dokumentációban olvasnhatunk.
    A plugin beállításait a lenti Save Profile gombbal kell elmenteni.

 

Egyszerű termék importálása

Egyszerű-termék-importálás

Első lépésként fontos, hogy konfiguráljuk a plugin-ok legfontosabb beállításait.
Ezután leírjuk, hogyan is kell egy import fájlt létrehozni. Mint ahogy az elején említettük, ezt egy CSV-fájlon keresztül fogjuk bemutatni.

Mielőtt azonban nekikezdenénk, bizonyosodjunk meg róla, hogy van olyan programunk, ami alkalmas a CSV-fájlok kezelésére. Amennyiben még nem rendelkezel ilyennel, azt javasoljuk, hogy szerezd be a következő két, ingyenes program valamelyikét:

  • Open Office (azon belül is a Calc)
  • Libre Office (azon belül is a Calc)

Fontos, hogy a CSV-t mindig UTF-8 beállítással és a megadott elválasztó paraméterekkel kell megnyitnunk/mentenünk.

Magmi CSV szöveg import

Miután megnyitottuk, a következő oszlopokat kell beírni fejlécként a CSV-be:

  • sku: termék cikkszáma, ezzel fogja a rendszer módosításkor beazonosítani a meglévő terméket
  • attribute_set: jellemzőhalmaz neve, ugyanúgy kell beírnunk, mint ahogy a Magento-ban szerepel, pl. Default
  • type: a termék típusa, lehetőségek:
    • simple – egyszerű
    • configurable – konfigurálható
    • downloadable – letölthető
    • bundle – kötegelt
    • grouped – csoportos
    • virtual – virtuális
  • websites: Ez a 0.7.17 verziótól elavulttá vált.
  • store: ide kell beírni, hogy melyik store view-hoz rendeljük hozzá (mindig a store view kódot kell megadnunk). Ezzel lehet a nyelvesítést elvégezni, amit bővebben a „Többnyelvű importálás” résznél fejtünk ki. Ha egy store view-nk van, vagyis egynyelvű az áruházunk, akkor nem kell, hogy szerepeljen az import fájlban. Illetve a képen látszik, hogy admin van beírva a store-nak, ilyenkor ez ugyanaz, mintha be se írtuk volna az oszlopot.
  • categories: ide kell beírni, hogy mely kategóriákhoz rendeljük a terméket (ha nincs bekapcsolva az „On the fly category creator/importer v0.2.5” plugin, akkor a beírt kategóriáknak léteznie kell a rendszerben, még mielőtt importálunk. A beírt adatok szintaxisa:
    • Kategória1
    • Főkategória/Alkategória
    • Kategória1;;Kategória2 – vagyis ha több kategóriába is beletartozik egy árucikk, akkor kettő darab pontosvesszővel kell elválasztani
    • Kategória1/Alkategória1;;Kategória1/Alkategória2;;Kategória2/AlKategória3
  • name: a termék neve
  • description: termék hosszú leírása, html tag-ek engedélyezve vannak
  • short_description: termék rövid leírása, html tag-ek engedélyezve vannak
  • price: a termék ára, itt mindig az alapértelmezett pénznemben kell beírni, adó nélkül (tehát nettó árat), pl. 150
  • special_price: a termék kedvezményes ára, ha nincs, akkor 0
  • special_from_date: ha a terméknek van kedvezményes ára, akkor ide be lehet írni, hogy mikortól legyen akciós (pl. 2016-05-20), ha mindig, akkor üresen kell hagynunk
  • special_to_date: meddig legyen akciós a termék, üresen hagyva a végtelenségig akciós lesz
  • news_from_date: újdonságnak jelölt termék kezdeti dátuma
  • news_to_date: újdonságnak jelölt termék befejezési dátuma
  • qty: ha van készletkezelés, akkor a termék raktáron lévő mennyisége (pl. 5)
  • in_in_stock: van-e raktáron, értékek: 1 – igen, 0 – nem
  • manage_stock: használja-e ennél a terméknél a raktárkezelést (ha használunk raktárkezelést, ki lehet egyes terméknél kapcsolni, hogy legyen-e vagy sem), értékek:1 – igen, 0 – nem
  • use_config_manage_stock: használja-e a rendszerbeállításban megadott raktárkezelést. Ha állítani akarjuk az előbbi manage_stock értéket, akkor itt 0-át kell megadni, hogy ne a rendszerbeállításból olvassa ki az értéket, hanem az ennél a terméknél megadott manage_stock értékből.
  • status: engedélyezve van-e a termék, értékek: 1 – igen, 0 – nem
  • visibility: a termék láthatósága, értékek:

1 – egyedileg nem látható, ezt általában a konfigurálható, csoportos termékeknél szokták használni. Ebben az esetben a termékadatlap sem érhető el, a többinél a termékadatlap elérhető
2 – csak a katalógusban, vagyis a kategória oldalakon látható, a keresésnél nem
3 – Csak a keresésnél látható
4 – Mindenhol látható

  • weight: a termék súlya, pl. 0.5. Ha ezt nem szeretnénk használni, akkor a jellemzőnél át kell tenni, hogy ne legyen kötelező megadni.
  • tax_class_id: az adóosztály id-je vagy a neve, pl. Taxable goods
  • thumbnail: a termék bélyegképe, pl. ball-for-football.png
  • small_image: a termék kis képe
  • image: a termék főképe
  • media_gallery: termékgaléria, itt a képek nevét pontosvesszővel kell elválasztani, pl. ball-for-football.png;ball-for-football2.png

Magmi CSV minta

 

A képeket csak akkor fogja importálni a rendszer, ha a „Image attributes processor v1.0.33a” plugin be van kapcsolva.

Természetesen a többi jellemzőt bele kell írni az import fájlunkba.

A select, vagyis egyszeri kiválasztós jellemzőknél a szöveges értéket kell beírnunk. (pl. a color jellemzőnek a Red szót írhatjuk.)

A többszöri kiválasztós értékeknél ugyanúgy kell tennünk, mint a select-nél, csak ha több értéke van, akkor a Magmi beállításában megadott Multiselect Separator-nál megadott karakterrel kell elválasztanunk (pl. Red|Green|Blue)

Magmi csoportos ár

Hogyan kell csoportos árat (Group Price) importálni?

A csoportos ár importálásához a CSV-fájlba fel kell vennünk egy “group_price:groupName” oszlopot, ahol a gropName a csoport neve, ahogy a Magento-ban szerepel.

Ha több csoporthoz szeretnénk árat importálni, még ha egyformát is, akkor külön oszlopba be kell azt beírnunk.

Ha nem létezik az adott vásárlócsoport, akkor a Magmi létre fogja azt hozni.

Hogyan kell mennyiség kedvezmény árat (tier prices) beállítani?

Az import fájlban egy új oszlopként be kell írnunk a következőt:
tier_price:group1 – ahol a group1 a vásárló csoport nevét jelöli.

Ha szeretnénk, hogy az összes csoportra érvényes legyen, akkor tier_price:_all_
Ha több csoportnak szeretnénk beállítani, akkor ugyanúgy, mint a csoportos árnál, új oszlopban kell felsorolnunk.

A terméksorba pedig:
25:10.00;50:9.00;100:8.00 – ami annyit jelent ebben az esetben, hogy 25 mennyiségnél vagy felette 10-be, 50 felett 9-be, 100 felett pedig 8-ba kerül.

Százalékos kedvezményt is meg lehet adni, ilyenkor pl. 25:85%, vagyis 25 mennyiségnél vagy felette 85 százalékos kedvezményt adunk.

Magmi CSV kedvezmény ár

Hogyan tudom a termékeket hozzárendelni a több website-os áruházban?

Ha olyan áruházat üzemeltetünk, mely egyszerre több weboldallal is rendelkezik, és vannak olyan termékeink, amelyek csak egyes oldalakon érhetők el, akkor a CSV-ben a store oszlopba azokn üzletek a store_view kódjait kell felsorolnunk, amelyekben a termék elérhető. Bemutatom egy példával:

8-Magmi-egyszeru-weboldal-aruhaz

A következő képen látható, hogy van 2 weboldalunk. Mindkettőnél 1 store van, az US store-nál csak angol nyelv, az EU store-nál pedig három nyelv is szerepel.
American English store_view kódja legyen:us, eu store-nál az Engilsh legyen: en, a German: de, a Hungarian pedig: hu.

  • Ha pl. a test 1-es termékünk, csak az us websopban van, akkor a store oszlopba az us kódot írjuk be.
    • Ha pl. az test 2-es termékünk csak az eu storokban szerepel, akkor fel kell sorolni mind a 3 nyelvet, vagyis en,de,hu
    • Ha a termék mindegyiknél szerepel, akkor az admin szót kell beírni.

Magmi egyszerű weboldal áruház csv

A többnyelvűség beállításával a „Többnyelvű importálás” részben bővebben foglalkozunk.
Itt található példa egy egyszerű termék importjára: magmi_simple_example.csv

Hogyan kell importálni?

A Magmi oldalán láthatunk egy Run Magmi feliratot, ott kell kiválasztanunk, hogy melyik profil alapján, milyen módban szeretnénk elvégezni az importálást.

Importálás után szükséges a reindexálás kell (reindex plugin a Magmiban is elérhető), illetve törölni ekll a cache-t a Magento-ban.

  • Update existing items only, skip new ones: csak a már Magento-ban létező termékeket frissíti, az újakat figyelmen kívül hagyja.
  • create new items & update existing ones: újakat is és a meglévőket is frissíti
  • create new items only, skip existing ones: csak az újakat hozza létre

Ezután a run import gombot kell megnyomnunk az importálási folyamat elvégzéséhez.

Konfigurálható termék importálása

A konfigurálható termék importálás funkció eléréséhez be kell kapcsolnunk a „Configurable Item processor” plugin-t. A konfigurálható terméknél most csak az egyszerű termékhez képesti különbségeket foglaljuk össze, mivel a többi beállítás gyakorlatilag megegyezik.

Magmi CSV konfigurálható termék

A konfigurálható termék több egyszerű termékből áll össze. Az import fájlban mindig az egyszerű termékeket kell előre tenni, és utána jön a konfigurálható termék.

Konfigurálható termék importálásakor először is meg kell adnunk, hogy mely jellemzők lesznek választhatóak a vásárlók számára (pl. méret, szín).
Csak „Globális” hatókörű, „Lenyíló” típusú jellemzőt lehet használni konfigurálásra és be is kell, hogy állítsuk a jellemzőnél, hogy konfigurálásra használható.

Fontos továbbá, hogy az a jellemző az adott jellemzőhalmaz része legyen.
Ha nem írjuk bele a fájlba a párosítandó cikkszámokat, akkor a plugin-ban be kell kapcsolnunk, hogy automatikusan megkeresse az altermékeket („auto match simples skus before configurable”), ilyenkor a cikkszámot a következőképp kell elnevezni:

Magmi CSV konfigurálható auto match

A konfigurálható cikkszáma (pl. testconf) Az altermékek cikkszáma: testconf1*** – a csillag helyére bármi mást be lehet írni, javasolt a konfigurálható jellemző értéke, (pl. testconf1-white-s, testconf1-white-m).

Ha pedig egyedi cikkszámot szeretnénk a termékeknél, akkor a simple_skus oszlopba kell beírni, hogy mely cikkszámok tartoznak alá.
Ha eltér az altermékek ára (pl. az M-es méretű drágább, mint az L-es) akkor a fájlba be kell írnunk a „super_attribute_pricing” oszlopot, amibe a konfigurálhatónál a következőképp kell  megadni:
jellemzőkód::érték:ár;érték:ár, jellemzőkód::érték:ár;érték:ár

vagyis pl. size::L:43;M:55

Ha fix ár helyett százalékos növelést szeretnénk, akkor pedig:
jellemzőkód::érték:ár:százalékos-e;érték:ár:százalékos-e
size::L:15:1;M:20:1 – vagyis, ha 1-es, akkor százalék, ha 0 akkor fix ár.

Ha nem adjuk meg ezt az értéket, a rendszer alapból fix árat fog használni.

Magmi CSV konfigurálható példa

Itt található egy konfigurálható termék import példa: magmi_configurable_example.csv

Kötegelt termék importálása

Ebben a részben azt mutatjuk be, hogy mit kell beállítani az import fájlban annak érdekében, hogy kötegelt termékeket tudjunk importálhassunk.

A Magmi plugin-jai között először is kapcsoljuk be a „Bundle Item processor” plugin-t.
Itt ugyanúgy kell létrehozni és kitölteni a CSV-fájlt, mint az egyszerű terméknél, ezért csupán a két módszer közötti különbséget mutatjuk be.

A következő oszlopokat kell beletennünk:

bundle_options:

Magmi CSV kötegelt opciók

-*;Code,Option name;type:is_required;position

pl.

-*;CPU:Central Processing Unit:radio:1:0;RAM:Random Access Memory:select:1:1;MOUSE:Mouse:checkbox:0:2

Ahol:

  • -* ha ezt az elejére írjuk, akkor a rendszer törli az előzőleg beírt opciókat a Magento-ból. Ha ezt nem írjuk, akkor a meglévőkhöz hozzáteszi a beírtakat.
  • Code: ez lesz a kódja az opciónak, ezt használjuk a bundle_skus-nál az összepárosításra
  • Option name: ez a neve az opciónak, ez a szöveg fog látszódni a terméknél
  • type (radio, checkbox, select, multi): ez az opció típusa
  • is_required: kötelező-e a vásárlónak választani az adott opcióból (1-igen, 0-nem)
  • position: a termék adatlapon milyen sorrendbe jelennek meg (számokat kell írni)
  • bundle_skus:

Magmi CSV kötegelt SKUS

Code:sku:selection_qty:can_change_qty:position:is_default:selection_price_value:selection_price_type
pl.
CPU:cpu1:1:0:1:1:0:0;CPU:cpu2:1:0:0:1:0:0;RAM:ram1;RAM:ram2;MOUSE:mouse1:1:0:0:1:50:1

Ahol:

  • Code: a bundle_options-nál is megadott kód
  • sku: az altermék cikkszáma
  • selection_qty: a kosárba helyezés mennyisége
  • can_change_qty: kiválaszthatja-e a vásárló, hogy az adott opcióból mennyit vásárol
  • position: opciók pozíciója
  • is_default: alapértelmezett-e az adott opció
  • selection_price_value: a kiválasztás ára (ez csak akkor érvényesül, ha a csv-ben a bundle-nél vagy a plugin beállításánál a price_type 1-re (Percent) van állítva
  • selection_price_type: az ár típusa (0 – Fixed, 1 – Percent)
  • price_view: az ár megjelenési típusa, 1 (Legkisebb ár, amelyen megveheti), 0 (ár tartomány, tehát x összegtől y összegig)
  • price_type: ár számítási típusa, 0 – dinamikus, 1 – fix ár
  • options_container: Hol jelenítse meg az opciókat (container1, container2), ez témától függ
  • shipment_type: a kötegelt elemek szállítása, 1 – elkülönítve, 0 – egyben
  • sku_type: cikkszám típusa, 0 – dinamikus, 1 – fix
  • weight_type: súly típusa, 0 – dinamikus, 1 – fix

Magmi CSV kötegelt egyéb

Importálás után csináljunk egy reindexet és cache-frissítést. Ha mindent jó állítottunk be, akkor a képen látható módon kell a termék adatlapnak megjelennie.

16-Magmi-kotegelt-Frontend

Itt található egy kötegelt termék import példa: magmi_bundle_example.csv

Csoportos termék importálása

A csoportos termék beállításai nagyon hasonlóak a konfigurálható termékéhez.
Először is, a Magmi plugin-jai között be kell kapcsolnunk a „Grouped Item processor” plugin-t. Eztuán az import fájlba a grouped_skus oszlopot kell beillesztenünk, amiben az egyszerű altermékek cikkszámai szerepelnek.

17-Magmi-csoportos-pelda

Itt található egy példa a csoportos termék importjára: magmi_grouped_example.csv

Letölthető termék importálása

A letölthető termék importfájlja hasonló az egyszerű termékéhez. A „links” oszlop kell bele, amit a következőképp kell kitölteni:

file:link,sort_order :position,title:file title,sample :example link,is_shareable :config or 0 or 1,number_of_downloads :value

  • file: ide kell a letölthető fájl linkje, url vagy teljes útvonal, ha lokálisan szerepel
  • sort_order: pozíció (ha több links van)
  • title: fájl neve
  • sample: betekintő fájl
  • is_shareable: a vásárló megoszthatja-e mással a fájlt
  • number_of_donwloads: hányszor töltheti le a fájlt

Ha több fájlunk van, akkor csak a fenti sort kell duplázni, pontosvesszővel elválasztva (pl. file:http://aionhill.com/test.zip,sort_order:1,title:Test,sample:,is_shareable:1,number_of_downloads:100;file:http://aionhill.com/test2.zip,sort_order:2,title:Test2,sample:,is_shareable:0,number_of_downloads:1; )

Magmi letölthető példa

Itt található egy letölthető egy példa a letölthető termék importjára: magmi_downloadable_example.csv

Virtuális termék importálása

Virtuális termék importálása ugyanaz, mint az egyszerű terméké, annyi a különbség, hogy a type nem simple, hanem virtual.

Magmi Virtuális példa

Itt található egy példa a virtuális termékimportra: magmi_virtual_example.csv

Jellemző és jellemzőhalmaz importálása

Jellemző vagy jellemzőhalmaz importjához először is be kell kapcsolnunk és beállítanunk az „Attribute Set Importer” plugin-t.
Itt három CSV import fájlt kell létrehozni: egyet a jellemzőkre, egyet a jellemzőhalmazokra és egyet a párosításokra.
A jellemzőnél kötelezően meg kell adnunk az attribute_code-ot, vagyis a jellemző kódját (pl. color).
A többi oszlop megadása nem kötelező, csak akko, ha nem az alapértelmezett értéket szeretnénk használni.

Jellemző, magmi

A jellemzőcsoport esetében meg kell adnunk az attribute_set_name-et, vagyis a jellemzőcsoport nevét (pl. Ruházat).
A többi oszlop megadása nem kötelező, csak akkor szükséges, ha nem az alapértelmezett értéket szeretnénk használni.

Jellemzőhalmaz, Magmi

A jellemző és jellemzőcsoport párosításánál pedig a következőket kell megadnunk:

  • attribute_set_name: jellemzőhalmaz neve
  • attribute_code: jellemző kódja
  • attribute_group_name: melyik jellemzőcsoportba kerüljön a halmazon belül

Jellemzőhalmaz, Magmi, jellemző, párosítás

Termékkategóriák importálása

A termékkategóriák a termék importáláskor jönnek létre, ha a Magmi-ban be van kapcsolva az „On the fly category creator/importer” plugin.
Leggyakrabban a képen látható beállítás alapján használják a plugin-t.

Magmi kategória importer beállítás

Ez alapján a következőképp kell a CSV-ben a kategóriát beállítanunk.

Magmi kategória Importer CSV

A képen látható példában a termék a „Football” főkategóriában szereplő „Ball” és „Accessories” kategóriákba fog bekerülni.

A per (/) jellel lehet az alszinteket megadni, pl. Elsőszintű/Másodszintű/Harmadszintű.
A kettő darab pontosvesszővel tudjuk több kategóriába is besorolni, pl. Elsőszintű/Másodszintű/Harmadszintű;;MásikElsőszintű/MásikMásodszintű/MásikHarmadszintű
Új kategóriáknál megadhatjuk azt, hogy aktív-e, link-e, és hogy a navigációs menüben benne legyen-e, szintakszisa: category name::[is_active]::[is_anchor]::[include_in_menu]
pl. Football/Ball::1::0::0

Többnyelvű importálás

Többnyelvű (ami több store view-t jelent, ahol webáruházunk más-más nyelven jelenik meg) importálásnál minden terméket annyiszor kell a beírnunk az import fájlba, ahány nyelven azt szeretnénk megjeleníteni.

magmi többnyelvű importálás

Ahány nyelv, annyi sor, a store oszlopba kell beírni annak a store_view-nak a kódját amelyik nyelvű boltnézetbe szeretnénk beletenni.

A kategóriáknál sajnos a rendes fordítás nem megoldott, így vagy adminból fordítunk, vagy minden nyelvnek saját kategóriafát hozunk létre, pl.:

  • English Root
    • Ball
  • German Root
    • Ball
  • Hungarian Root
    • Labda

A name, description stb. oszlopba az adott nyelven kell beírni a szövegeket.

A lenyílós jellemzőknél a következőképp:
Adott nyelvű érték::[Admin érték]
Az első elem az adott nyelven megírt fordítása, a kapcsos zárójelbe kell az admin vagyis a default nyelven létező string-et írnunk. (pl. Red::[Red], Piros::[Red] )

Itt található egy példa többnyelvű importra: magmi_multilanguage_example.csv

Összegzés

A Magmi előnyei:

  • Telepítése és beállítása egyszerű
  • Használata felgyorsítja a munkát (egyszerre akár több ezer terméket is pár perc alatt importálhatunk a segítségével)
  • mind a 6 terméktípus importálására képes
  • automatizálható (vagyis automatikusan futó importokat is létrehozhatunk)

A Magmi hátrányai:

  • az importfájlok létrehozása kicsit bonyolult, maximális pontosságot igényel annak érdekében, hogy minden adat megfelelően jelenjen meg
  • mivel nyílt forráskódú, így sajnos akadnak benne apróbb hibák, egyes kiegészítők nem működnek mindig tökéletesen
  • a termék mentésekor futó observerek enm futnak le, mivel direkt SQL-el dolgozik
  • a Magento mellett még egy adminisztrációs felület használatát meg kell tanulnunk

Reméljük, sikerült minden részletre kiterjedően bemutatnunk a Magmi tulajdonságait, beállításait és használatát. Ha bármilyen témába vágó megjegyzésed vagy kérdésed lenne, ne habozz megírni alább, a komment részlegben. Ahol tudunk, segíteni fogunk abban, hogy a Magento és a Magmi segítségével te is kihozhasd saját webáruházadból a maximumot!

 

Tényleg képes a Magento több mint 500 ezer termék kezelésére?

Erre a kérdésre természetesen nehéz határozott és általános érvényű választ adni, de azért tapasztalataink alapján igyekszünk némi támpontot adni és néhány praktikus tanáccsal szolgálni.

 

Ehhez a következő gyakorlati problémákat próbáljuk körbejárni:

 

  • Hány terméket képesek a különféle Magento-verziók egy átlagos szerveren alapesetben, illetve további optimalizáció segítségével kezelni?
  • Mi a különbség  teljesítmény szempontjából az egyes Magento-verziók között?
  • Melyek azok a pontok, melyek egy nagyobb katalógus esetén szűk keresztmetszetet jelentenek? Hogyan lehet a Magentót úgy skálázni, hogy még több terméket lehessen vele kezelni?
  • Milyen gyakori hibákat lehet egy nagy méretű katalógus kezelése esetén a Magentóval elkövetni?

 

Hány terméket képesek a különféle Magento-verziók egy átlagos szerveren alapesetben, illetve további optimalizáció segítségével kezelni?

 

    • A Magento CE 1.9.x ‒ A legtöbb esetben  különösebb finomhangolás nélkül biztonságosan kezel~10 000 25 000 terméket  Széles körű skálázással, megfelelően megemelt szerver-erőforrásokkal és kód szintű optimalizációval viszont akár 100 000 ‒ 200 000 termék kezelésére is képessé tehető.
    • Magento EE 13.x. 14.x ‒ A legtöbb esetben  biztonságosan kezel különösebb finomhangolás nélkül ~100 000 200 000 terméket és akár 400 000 ‒ 500 000 vagy még több terméket megfelelő skálázás, optimalizáció és szerver-erőforrások biztosításával.
    • Magento 2 CE ‒ A legtöbb esetben, különösebb finomhangolás nélkül biztonságosan kezel ~ 100 000 200 000 terméket és akár 400 000 ‒ 500 000 vagy még több terméket megfelelő skálázás, optimalizáció és szerver-erőforrások biztosításával.
    • Magento 2 EE ‒ Úgy tervezték, hogy még több terméket is képes legyen kezelni olyan vállalati szintű megoldások segítségével, mint az adatbázis-szegmentáció, üzenetsorok illetve speciális MYSQL- és alkalmazásszerver-topológiák.

 

A fenti számok természetesen csak hozzávetőlegesek és olyan katalógusokra vonatkoznak, melyek néhány termékjellemzőt, kategóriát és kizárólag egyszerű termékeket tartalmaznak.  Az adatokat a Magento által közzétett teljesítménytesztek és saját tapasztalataink alapján állapítottuk meg és azok  a szerverkonfigurációtól, szerverszoftverektől és -erőforrásoktól függően jelentősen módosulhatnak.

 

Szintén fontos hangsúlyozni, hogy a Magento adatbázis-struktúrájának következtében néhány különösen erőforrás-igényes Magento funkció alkalmazása  megsokszorozza azoknak a termékeknek a számát, melyeket a Magento tulajdonképpen a háttérben kezel.

 

A legfajsúlyosabb funkciók a következők:

  • A Magento „bolt nézetek/nyelvek” száma
  • Termékjellemzők száma
  • Kategóriák száma és a kategóriastruktúra mélysége
  • Konfigurálható/összeállítható termékek száma
  • Különféle termékárakkal rendelkező vásárlói csoportok száma
  • Katalógus-árszabályok száma

 

Mindez adott esetben azt jelenti, hogy egy  olyan Magento webshop, mely mindössze néhány ezer terméket tartalmaz, de a Magento funkcionális lehetőségeit széles körűen kihasználja ‒  pl. 20 nyelvi változatot kezel, rengeteg termékjellemzővel, zömében konfigurálható termékekkel és több felhasználói árcsoporttal ‒ erőforrásigényét  tekintve azonos kategóriába tartozhat egy olyan Magento áruházzal, mely 100 000+ egyszerű terméket kezel egyetlen boltnézetben.

Ezek a funkciók teszik a Magentót igazán rugalmas rendszerré, de megvan a maguk ára a teljesítményoldalon.

 

Mi a különbség  teljesítmény szempontjából az egyes Magento-verziók között?

a magento verziók

 

  • Magento CE 1.x, a 1.9.x verzióval együtt
    • – az indexelés, különösen az URL- és keresés indexek nem optimalizáltak nagyobb katalógusokra (mindez az EE verzióra is érvényes 1.12.x-ig).
    • – Nem érhető el beépített funkcióként a teljes oldali gyorsítótár (Full Page Cache, FPC)
    • + elérhető néhány frontendes optimalizáció, mint például javascript és css összefűzés, CDN támogatás
  • Magento 1.x EE
    • + elérhatő az FPC, mely megfelelően alkalmazva rengeteg szerver-erőforrást képes felszabadítani.
    • +  inkrementált indexelés a 1.13+.x verziótól kezdve, melynek során a termékek indexelését időzített folyamatok végzik a háttérben.
    • + A  1.13+.x verziótól kezdve a teljes reindexelési folyamatok is jelentős optimalizáción estek át, és megfelelően működnek nagyobb katalógusok esetén is.
    • + Beépített lehetőségként tartalmazza a Solr keresőmotort
  • Magento 2 CE
    • + örökölte az inkrementális indexelést a Magento EE 1.13+.x-től.
    • + örökölte az FPC-t az EE 1.13+.x-től  és beépített támogatást tartalmaz Varnish frontend gyorsítótár kezelésére. A Varnish gyorsítótár-szerver legnagyobb előnye, hogy a Varnish által kiszolgált kérések el sem jutnak a Magentóig, így jelentősen csökken a webszerverek terhelése, emellett drámaian lecsökken az oldalbetöltési idő.
    • + A böngésző-gyorsítótárt használja a munkamenet-függő adatok tárolására (pl. kosártartalom)
    • + A pénztári folyamatok jelentős  optimalizáláson estek át
    • + Aszinkron termék- és rendelésmentési folyamatok.
    • + Frontend-optimalizációk széles köre, pl. js/css minifikáció, függőségkezelés, statikus tartalom gyorsítótárazása, képtömörítés.
    • + alapszintű PHP 7-támogatás, mely önmagában is akár 200% teljesítményjavulást eredményezhet a php 5.6.x-hez képest.
  • Magento 2 EE
    • + Rendelkezik a Magento 2 CE minden fentebb felsorolt funkciójával.
    • + Solr (2.0) és Elasticsearch (2.1) keresőmotorok.
    • + Lehetőség van az adatbázis szegmentálására külön szervereken a katalógus, kosárkezelés és pénztári folyamatok adatbázis-tábláit elválasztva.
    • + Mysql klaszter és „multi master” architektúra támogatása
    • + Támogatja a háttérfolyamatok üzenetsorokba való kiszervezését (Rabbit MQ, első megvalósítás a késleltetett készletfrissítés)

 

Melyek azok a pontok, melyek egy nagyobb katalógus esetén szűk keresztmetszetet jelentenek? Hogyan lehet a Magentót úgy skálázni, hogy még több terméket lehessen vele kezelni?

keresztmetszet

 

  • Hoszting ‒ egy nagyobb katalógusnak nyilvánvalóan több erőforrásra van szüksége, alapkövetelmény a VPS szerver elég memóriával és többmagos processzorral, illetve szükség lehet többszerveres elosztott környezet alkalmazására.
  • Szerverszoftverek ‒ erősen javasolt az Nginx webszerver, a  PHP 7 és a  Mysql 5.6  vagy annak megfelelő adatbázisszerver (Percona/MariaDb), még  Magento 1 esetében is. Emellett szintén nagyon fontos ezeknek a szerverszoftvereknek a finomhangolása, fokozottan figyelembe véve a Magento sajátságait.
  • Termékimport ‒ az optimalizált termékimport különösen fontos ebben az esetben, és rendkívül sokat segítenek azok az eszközök, melyek lehetővé teszik a kötegelt adatbázisműveleteket. Minden olyan módszer vagy eszköz, mely teljes, egyenként végrehajtott termékmentéseket  alkalmaz,  könnyen és gyorsan szűk keresztmetszetté válhat. Az egyik legjobb ilyen importot segítő eszköz a Magmi. Néhány további szempont, amit termékimport során érdemes szem előtt tartani.
    • Csak olyan adatokat mentsünk, melyek valóban megváltoztak.
    • Az importáláshoz használjunk dedikált erőforrásokat
    • Lehetőség szerint válasszuk szét az ár-készlet és az alapjellemzők importját
    • Csak azokat a termékeket és termékadatokat indexeljük újra, ahol újraindexelésre van szükség.
  • Indexing  ‒ Az indexelés a Magentóban a termékek mentésének második lépése, és alapvetően a legkényesebb terület, amikor nagy katalógusok kezeléséről van szó. Az indexelés egy sor olyan folyamatból áll, melyek az tárolásra optimalizált adatbázis-táblákból a különféle adatelérési szempontok szerint optimalizált táblákba másolják át az adatok egy részét. Mivel ezekre az indexekre csak a vásárlói (frontend) folyamatokhoz van szükség. Az indexelést a termékmentésről és termékimportról le lehet választani. A Magento 1 EE újabb verzióiban illetve a Magento 2 CE és EE-ben használt inkrementális indexelés nagyban felgyorsítja az adminisztrációs felületen végzett munkát, de bizonyos esetekben még ez sem ideális tömeges termékimport esetén.
    • A Magento 1 CE-ben az indexelés az a folyamat, ami a legtöbb problémát jelenti napi szinten és optimaliziáció szempontjából.
      • Az URL indexelés az egyik legkényesebb művelet, részben mert az index maga képes több milliós rekordszámra felduzzadni, részben mert egyáltalán nincs nagyméretű katalógusokra optimalizálva.
      • Bizonyos katalógusméreten túl, és bizonyos boltnézet-szám fölött az úgynevezett „flat tábla indexek” által nyújtott előnyöket túlszárnyalják a hátrányaik, így ezekben az esetekben érdemesebb őket kikapcsolni.
  • Catalog search
    • A beépített Mysql fulltext kereső indexelés és teljesítmény szempontjából is meglehetősen lassú, ráadásul találati pontossága is gyenge, így még Magento 1 esetén is erősen ajánlott a lecserélése. Számos remek, akár ingyenes modul érhető el Magento 1-hez is, melyek a Solr, Eleasticsearch vagy éppen a Sphinx keresőmotorhoz kapcsolják a katalógust. A Magento 1 Enterprise verziója beépített támogatást nyújt a Solr, illetve Magento 2.1 EE-től az Elasticsearch kezelésére.
  • Full Page Cache
    • A Full Page Cache olyan mechanizmus, melynek során a szerverszoftver által generált html oldalakat egészben eltároljuk. Ha ezután legközelebb azonos az oldalra van szükség, a tárolt változatot szolgáljuk ki anélkül, hogy szükség lenne az oldal újragenerálására és az ezzel járó számítási illetve adatbázis-műveletekre.  Amíg a Magento 1 CE  nem tartalmaz beépített  FPC-t, addig a Magento 1 EE -ben a teljes oldali gyorsítótárazást maga a Magento végzi. Ez utóbbi is sok erőforrást takarít meg és nagyobb oldalbetöltési sebességet eredményez, a cachelést  azonban  a legideálisabb a Magento előtti rétegekben megvalósítani anélkül, hogy ebben aktív szerep hárulna a Magentóra. Ehhez nyújt támogatást a Magento 2-ben a Varnish támogatás. Bár a Magento 1 CE nem tartalmaz beépített FPC-t és Varnish illesztést, megfelelő kiegészítő modulok segítségével hatékonyan ki lehet aknázni ezeket a lehetőségeket.
  • Alkalmazásszintű gyorsítótárazás
    • A Magento erősen támaszkodik a különféle konfigurációs és futás idejű tartalmak elérését gyorsító un. Cache-ekre. A jelenleg elérhető legjobb megoldás a memória alapú és tartalomcímkézést is teljes körűen kezelő Redis illesztés, mely már a Magento 1 CE legújabb változataiban is beépítve elérhető.

 

A különféle Magento-verziókra levetítve megállapíthatjuk a következőket:

 

  • Magas termékszám esetén a legérzékenyebb területek a termékimport és az indexelés a backenden, illetve keresése, termékszűrő és terméklistázás a frontenden. A pénztári funkciók és a rendeléskezelés szintén fontos tényezők, de az utóbbiak inkább függenek az oldal látogatottságától mint a katalógus méretétől.
  • A termékimport jó eséllyel Magento-verziótól függetlenül optimalizálásra szorul – adott esetben még a Maegento 2 EE-ben is.
  • A Magento 1 CE a legkevésbé alkalmas nagy termékkatalógus kezelésére, de kifinomult skálázással, alkalmas szerverháttérrel és az indexelés, keresés és gyorsítótárazás csorbáit kiköszörülő modulokkal jelentősen javítható a teljesítménye. Az indexelés azonban még ebben az esetben is problémákat tartogathat.
  • A Magento 1 EE jelentős optimalizációkat tartalmaz, az ő esetében a Varnish cache bevezetése és a szerverarchitektúra finomhangolása vezethet a legkönnyebben még jobb teljesítményhez.
  • A Magento 2 CE-t a paramétereivel éppúgy a közepes méretű vállalatokat célozza meg, mint a Magento 1EE. Funkcionális szempontból nézve hiányzik belőle néhány olyan vállalati funkció, mint a vásárló hitelrendszer és  jutalompontok kezelése, verziókezelés vagy fejlett tartalomkezelés, de ami a szigorúan vett teljesítményt illeti, egy lapon említhető a Magento 1 EE-vel, sőt a Varnish-támogatás révén még meg is előzi. A teljesítmény növelésére a néhány magától értetődő módszer a már meglévő lehetőségek és beállítások minél teljesebb kiaknázása, a szerverarchitektúra testre szabása vagy akár az Elasticsearch illetve Solr bevezetése.

Magento 2 EE a közepesnél nagyobb vállalatok számára is hatékony alternatívát kíván nyújtani a felhő alapú szervermegoldások és nyújtotta lehetőségek kiaknázásával.

 

Milyen gyakori hibákat lehet egy nagy méretű katalógus kezelése esetén a Magentóval elkövetni?

 

A fentebb  említett szempontokon túl szeretnénk még néhány olyan további körülményt említeni, amelyek  figyelmen kívül hagyása gyakori problémaforrás lehet egy komolyabb forgalmat bonyolító és nagy számú terméket kezelő Magento webshopban.

 

  • Underscaling ‒ Talán a legfontosabb tanács, hogy mindig megfelelő erőforrás tartalék legyen biztosítva a rendszer számára, és fel legyünk arra készülve, hogy szükséges esetben tovább erőforrásokat biztosítsunk. Már a fejlesztés során is célszerű teljesítménytesztekkel meggyőződni arról, hogy a webshop képes az elvárásoknak megfelelni.
  • Túl sok vagy gyenge minőségű külső modul  ‒  tisztában kell lennünk azzal, hogy a harmadik féltől származó modulok nincsenek minden esetben nagy méretű termékkatalógusokra optimalizálva. Egy modul tervezése során akár egy apró figyelmetlenség is katasztrofális lehet egy ilyen webshop teljesítményére nézve.
  • Széles körű és jól beállított  monitorozás hiánya ‒ Megfelelő rendszermonitorozás nélkül lehetetlen időben felismerni és kezelni a rendszer problémás területeit.

Források:

 

Összefoglalás A Magento a kezdetek óta óriási fejlődésen ment keresztül, és mára a Magento 2 megjelenésével eljutott odáig, hogy nemcsak a funkciókban leggazdagabb, de minden bizonnyal a legjobb teljesítményre képes webshop is egyben. Kellő szakértelemmel kezelve és biztosítva számára a megfelelő erőforrásokat, tetemes méretű katalógusokat is képes sikerrel kezelni.

 

Magento frontend sebesség gyorsítás és mérése

Tartalom

  • A gyorsaság arányos a bevétellel
  • Oldalsebesség hatása a keresési helyezésekre
  • Frontend gyorsítás a Magento-ban
    • Szerveroldal
    • Varnish
    • Statikus tartalmak – JavaScript, CSS fájlok és képek
    • Frontend optimalizálása a design függvényében
    • Képek méretének optimalizálása
    • Megjelenítést gátló elemek minimalizálása
    • Szerveroldali tömörítés engedélyezése
    • HTML, CSS, JavaScript lekicsinyítése
  • Befejezés

 

Induljunk ki abból, hogy rákeresel valami kifejezésre a weben, és a kiszemelt oldal, amire rákattintottál lassan töltődik be. A következő kérdésekre kell választ adni magadban:

 

  • Mennyi idő után fogod azt mondani, hogy nem vársz tovább, és inkább visszalépsz a keresőoldalra?
  • Mennyire szívesen látogatsz vissza később a kérdéses oldalra, ha tudod, hogy nagyon lassan töltődik be?
  • Milyen bizalommal ajánlod az ismerőseidnek az adott oldalt?
  • Mi fog akkor történni, ha egy olyan szituációban vagy, ahol kénytelen vagy a mobilodat használni böngészésre és azonnal el kellene intézned az adott dolgot?

 

A válaszok egyértelműek, és mint weboldal, illetve webshop tulajdonos, pontosan ezeket a problémákat kell elkerülnöd azért, hogy több látogató használja a te oldaladat.

A céged presztízse múlik azon, hogy milyen gyorsan töltődik be az oldalad, ráadásul, ha lassú a betöltés, akkor nem is fognak visszatérni, keresnek másik hasonló oldalt, ahol a felhasználói élmény számukra sokkal jobb.

A sebesség a weboldalaknál mindig is nagyon fontos tényező volt, ám az idő előre haladtával az oldalakkal szemben támasztott követelmények is egyre komolyabbak.

A 2011-es adatok például így festettek:

 

oldalsebesség

 

Mára azonban az oldalaknak már sokkal gyorsabban kell betöltődniük.

A Google által a webmestereknek készült videóban kiderül, hogy egy webshopnak 2016-ban elfogadott érték 2 másodperc, viszont a Google-nél a jónak számító idő a 0,5 másodperc.

 

 

A Financial Times idei kimutatása szerint a következő tendencia figyelhető meg a cikkek olvasottságánál:

 

oldalak betöltési ideje

 

Vagyis jól megfigyelhető, hogy ha gyorsabb a konkurenciánál az oldalunk, akkor előnyre tehetünk szert, de ez természetesen fordítva is igaz.

A következő statisztika azt szemlélteti, hogy melyek azok a webshopokban problémás részek, amelyeket az Egyesült Királyságban nehezményeznek (Econsultancy, 2012).

 

területi problémák

 

Tisztán látszik, hogy a betöltési idő a megkérdezettek első számú problémája, mintegy 66,8%-uk nincs vele megelégedve.

Néhány további hasznos tudnivaló az oldal gyorsaságával kapcsolatban:

  • Ha 3 másodpercnél tovább kell várni az oldal betöltésére, akkor a felhasználók 40%-a inkább meg sem várja
  • Egy átlagos felhasználó mindössze 2,078 másodpercet hajlandó várni egy oldal betöltésére
  • Ha az oldal 1-2 másodperc alatt betöltődik, az 2%-os látogatószám növekedést eredményez
  • Ha 1 másodperc alatt teljesül a betöltés, akkor 4,6%-os a javulás

 

A gyorsaság arányos a bevétellel

 

Általánosságban elmondható, hogy 1 másodpercnyi oldal gyorsulás átlagosan 7%-os növekedést eredményez a konverzióban.

Megjegyzés: Akkor történik konverzió, ha valaki a hirdetésre kattint, majd olyan műveletet hajt végre, amelyet Ön a vállalkozás szempontjából értékesnek határozott meg. Ilyen lehet például az online vásárlás vagy a bolt telefonos megkeresése.

 

Ez a webshopok esetében természetesen a számokban is megmutatkozik. Érdekesség, hogy a Walmart és az Amazon egymástól függetlenül, de rájöttek, hogyha 0,1 másodperccel tudnak gyorsítani az oldal betöltésén, akkor az 1%-os növekedést jelent a bevételeikben – ekkora cégeknél az 1% is óriási pénz!

 

Néhány adat a webshopok esetében:

  • a felhasználók 83%-a elvárja, hogy a weboldal 3 másodperc alatt töltődjön be
  • ha 3 másodpercnél többet kell várnia, akkor a felhasználók 44%-a elpártol az oldaltól
  • 79% ezek után megfontolja, hogy egyáltalán visszatérjen-e az oldalra
  • 46% pedig még el is meséli az ismerőseinek az érzéseit ezzel kapcsolatban

 

Érdemes elgondolkodni azon, hogy növeljük az oldalunk sebességét, hiszen, másodpercenként általánosságban 7%-os növekedést érhetünk el, amit ha a napi bevételünk 100 000 Ft, akkor éves szinten megközelítőleg 2 500 000 Ft plusz bevételre tehetünk szert (100 000 * 0,07 * 365).

 

Oldalsebesség hatása a keresési helyezésekre

 

John Mueller SEO szakértő utánajárt a témának, és egyik cikkében kifejtette, hogy a lassú oldalak hátrébb vannak sorolva, viszont a gyors weboldalak között már nem játszik nagy szerepet pár ezredmásodpercnyi különbség.

 

Két fontos tényezőt kell megvizsgálni a weboldalak gyorsaságát illetően:

Az egyik – amit a felhasználó érez, azaz számára milyen gyorsan jelenik meg a tartalom,

A másik – ami a Google számára fontosabb –, hogy meg tudja különböztetni a lassú weboldalakat a normális sebességűektől. Kihangsúlyozta azt is, hogy minél gyorsabb az oldalunk, annál több felhasználó használja, így sokkal több aloldalt tudnak megtekinteni adott idő alatt, így több információt ismernek meg.

 

Frontend gyorsítás a Magento-ban

 

Mivel a legelterjedtebb keresőportál a Google, ezért célszerű az általa támasztott elvárásoknak megfelelni, amit legjobban a saját sebességmérő alkalmazásában lehet kipróbálni, és az ott kapott válaszok alapján javítani rajta: Google PageSpeed

Első projektünk, amiben megvizsgáltuk, hogy mivel tudjuk gyorsítani az oldal betöltési sebességét a Fradi webshop-ja, ezen a példán keresztül mutatom be a lehetőségeket:

 

Szerveroldal

 

Természetesen ahhoz, hogy a frontend tartalmak gyorsabban legyenek láthatóak a böngészőkben, a szerveroldalon is végre kell hajtani bizonyos optimalizálási folyamatokat annak érdekében, hogy a válaszidő a lehető legrövidebb legyen.

 

Varnish

 

Az egyik legelterjedtebb gyorsítótár (cache) megoldás a dinamikus tartalmak kiszolgálására, amiről már egy korábbi cikkünkben részletesen írtunk.

 

Statikus tartalmak – JavaScript, CSS fájlok és képek

 

Ezek gyorsítótárazásához az AWS CDN megoldását használjuk.

 

Frontend optimalizálása a design függvényében

 

A mai trendeknek megfelelően reszponzív design esetén a megjelenő képek mérete a böngésző méretétől függenek. A következő példában szemléltetem is, látszik, hogy a design és a sitebuild eltér az egyes töréspontok után (az AionHill a Bootstrap töréspontjait veszi alapul az általunk készítendő oldalak megvalósításakor):

 

webshop-design-1

1. ábra – minimum szélesség 1200 px

 

webshop-design-2

2. ábra- minimum szélesség 992 px

 

webshop-design-3

3. ábra – minimum szélesség 768 px

webshop-design-4

4. ábra – maximális szélesség 768 px

 

 

Fontos, hogy a megjelenő kép mérete megegyezzen annak a területnek a méretével, ahol azt megjelenítjük. Ez nem jelentene gondot akkor, ha mellőzzük a reszponzivitást, hiszen a Magento-ban le lehet kérdezni a képek átméretezett példányát:

 

$this->helper('catalog/image')->init($_product, 'small_image')->resize(710, 710);

 

Vagyis meg kell oldanunk, hogy mindig az adott böngészőmérethez jelenítse meg az átméretezett képet. Erre a legmegfelelőbb megoldás a <picture> HTML tag

A lényege, hogy meg lehet adni, hogy milyen felbontásoknál melyik kép jelenjen meg, végül pedig magát a kép <img> tag-et, hogyha a böngésző nem támogatná még ezt az új bevezetett szabványt:

<picture>
 <source srcset="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(360, 365); ?>" media="(min-width:1200px)">
 <source srcset="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(293, 297); ?>" media="(min-width:992px)">
 <source srcset="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(710, 710); ?>" media="(min-width:768px)">
<source srcset="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(710, 710); ?>" media="(min-width:300px)">
 <img class="img-responsive"
 src="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(360, 365); ?>"
 alt="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>"/>
</picture>

 

Képek méretének optimalizálása

 

A weboldalakra feltöltött képek túlnyomó többségénél megfigyelhető, hogy minőségromlás nélkül bizonyos programokkal lekicsinyíthető a képek mérete. Erre a Google is figyel, és jelzi a vizsgálatkor, hogy melyek azok a képek, ahol ezt meg kell tenni.

 

webshop-kep-optimalizalas

 

Erre mi nem készítettünk saját modult, mert a piacon fellelhető sok ingyenes Magento bővítménynek köszönhetően ez feladat könnyen megoldható. A választásunk az Image Optimizer for Magento-ra esett, ami egy ingyenes és teljesen jól használható megoldás erre a problémára.

A lényege, hogy a média, skin és frontend mappákban fellelhető képeket kigyűjti, és utána cron segítségével kötegelve optimalizálja a szerveren található képmanipuláló könyvtárak segítségével (jpegoptim, optipng).

 

Megjelenítést gátló elemek minimalizálása

 

Ez a gyakorlatban azt jelenti, hogy ha a JavaScript és CSS fájljaink száma nagy, akkor azoknak a betöltése sokkal több időt vesz igénybe, mert a fájlok betöltésével megvárja a másikra adott választ. Ennek a legmegfelelőbb mérése a Chrome-ban a developer tools, ahol összefűzés nélkül a következő eredményt kapjuk:

 

css-developer-tools-fajl-osszefuzes-nelkul

 

Látszik, hogy rengeteg idő, míg az összes fájl betöltődik. Ha a Magento adminisztrációs felületén bekapcsoljuk a fájlok összefűzését, akkor ugyanez az oldal a következő eredményt adja:

 

fajl-keptomorites-webshop

 

A felhasználó szemszögéből ugyanaz az eredmény, viszont jóval kevesebb fájlból dolgozik. Ez a lehetőség Magento alapfunkcionalitás, és ha jól írták meg a fejlesztők a JavaScript osztályokat, eljárásokat, akkor nem is lehet gond az összefűzésnél.

Bekapcsolni a System/Configuration/Developer menüpontok alatt lehet:

 

magento-developer-menu-fajl-osszefuzes

 

Szerveroldali tömörítés engedélyezése

 

 

A PageSpeed részletesen leírja, hogy egyes webszerverek esetében mi a teendő, milyen modulokat kell telepíteni ahhoz, hogy a tömörítés be legyen kapcsolva

Tesztelni könnyedén lehet, például Chrome esetében inspector módban (Ctrl+Shift+i) a network fülön a HTML oldal header (fejléc) részében megtalálható a következő:

 

szerver-oldali-tomorites-webshop

 

Végezetül a HTML, CSS, JavaScript lekicsinyítése

Távolítsuk el a felesleges karaktereket mindhárom oldalelemből, mert így csökkentjük a válasz méretét, így növeljük a válasz sebességét.

Magento-hoz ismételten az Aptrian termékét választottuk (Minify HTML CSS JS for Magento), ami a feltelepítés után egy egyszerű adminisztrációs beállítás után egy gomb megnyomásával már végre is hajtja azokat a módosításokat a fájlokon, amik növelhetik a méretét.

Fontos megemlítenem, hogy itt nem a javascript kicsinyítéséről/titkosításáról van szó, hanem a felesleges elemek eltávolításáról:

A Magento-s Validator osztály egy kiragadott része:

 

magento-validator-osztaly

 

Ezt a modul átalakítja:

 

magento-validator-osztaly-modul-atalakitas

 

Rövidebb tartalom, kevesebb felesleges karakter, gyorsabb betöltődés.

 

 

Összegzés

Az oldalbetöltési sebesség növelése egyre fontosabb a weboldalak, különösen a webshopok, számára, hiszen a látogatók is egyre többet várnak el, egyre jobb felhasználói élményt szeretnének.

Ebben a cikkben leírtam, hogyan lehet a Magento 1.x-nél javítani az oldalbetöltési sebességet, amely során különböző megoldásokat javasoltam.

Ami a Magento 2 rendszert illeti, úgy tervezem, az ezen a platformon működő webshopok frontend gyorsításával kapcsolatban is megjelentetek egy blogcikket, hogy teljes legyen a kép.

Magento 2.0 modul fejlesztés lépésről lépésre – 4. rész (Knockout JS)

Tartalom:

  • Mi az a Knockout.js?
  • Miért kell / érdemes használni és mire jó?
  • Alap példa modul felépítése
  • Block-ok és layout létrehozása
  • Knockout JS használata PHTML template fájlban
  • Saját CustomerData osztály létrehozása és implementálása
  • Knockout JS használata HTML template fájlként

Mi az a Knockout.js?

A Knockout.js egy nyílt forráskódú egyszerűsített dinamikus javascript, mely egy Model-View-View Model (MVVM) rendszer/framework.

 

Miért kell / érdemes használni és mire jó?

Természetesen nem kell használni, viszont mivel a Magento 2.0 szerves részét képezi a full page cache használata miatt is, így a saját modulunkban megvalósítandó üzleti logika alapján célszerű elgondolkozni a használatán a fejlesztés megkezdése előtt. Anélkül, hogy különálló bonyolult javascript-ek készítenénk saját modulunkban, egy könnyű megoldással férhetünk hozzá customer, product, order stb. adatokhoz a frontenden és kezelhetjük azokat.

Alap példa modul felépítése

 

A jelenlegi cikkben is a már korábban használt alap példa modult fogjuk használni. A Magento 2.0-ban a Knockout JS jelentős szerepet kap, így érdemes vele megismerkedni.

 

Mivel korábbi cikkünk az alap modul felépítésére már kitért, most csak a modul felépítése kerül bemutatásra.

 

magento 2 modul szerkezet

 

Block-ok és layout létrehozása

 

A példához egy block-ot hozunk létre és két külön template fájlt, amiben két különböző módszerrel használjuk a Knockout JS-t. Az első példában magában a template fájlban használjuk a Knockout JS-t, míg a másodikban ennek segítségével egy másik HTML template fájlt implementálunk vagy úgy is fogalmazhatnánk, hogy töltünk be. A két külön példához első lépésben egy layout fájlt hozunk létre, és aszerint, hogy melyik block-ot használjuk, most az egyszerűség kedvéért csak kikommentezzük a megfelelőt.

Ehhez szükségünk lesz egy default.xml fájlra, ami az alábbi helyen található a példa modulunkban: app/code/Aion/Sample/view/frontend/layout/default.xml. A fájl tartalma:

 

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
     <body>
         <referenceBlock name="sidebar.additional">
             <!-- First sample -->
             <block class="Aion\Sample\Block\Sample" name="aion.sample.knockout.sidebar" template="Aion_Sample::sidebar.phtml" after="wishlist_sidebar"/>
             <!-- Second Sample -->
             <!--<block class="Aion\Sample\Block\Sample" name="aion.sample.knockout.sidebar.second" template="Aion_Sample::second-sidebar.phtml" after="wishlist_sidebar"/>-->
         </referenceBlock>
     </body>
 </page>

 

A layout fájlban a példa kedvéért a saját block-unk és a hozzá tartozó template fájl az oldalsáv (sidebar) alatti részen fog megjelenni (<referenceBlock name=”sidebar.additional”>).

 

A következő lépésben a block osztály kerül létrehozásra, ami a fenti layout-ban is látható. Az alábbi helyen található a példa modulunkban: app/code/Aion/Sample/Block/Sample.php. A fájl tartalma:

 

<?php
 namespace Aion\Sample\Block;
 use Magento\Framework\View\Element\Template;
 use Aion\Sample\Helper\Data as DataHelper;
 
 class Sample extends Template
 {
     /**
      * @var DataHelper
      */
     protected $_helper;
 
     /**
      * @param Template\Context $context
      * @param DataHelper $dataHelper
      * @param array $data
      */
     public function __construct(
         Template\Context $context,
         DataHelper $dataHelper,
         array $data = []
     ) {
         $this->_helper = $dataHelper;
         parent::__construct($context, $data);
         $this->_isScopePrivate = true;
     }
 
     /**
      * Get extension helper
      *
      * @return DataHelper
      */
     public function getExtensionHelper()
     {
         return $this->_helper;
     }
 
     /**
      * Sample items for example
      *
      * @return array
      */
     public function getInitSecondItems()
     {
         $sampleData = $this->_helper->getSampleProductNames();
 
         return $sampleData;
     }
 }

 

A block-ban látható getInitSecondItems() függvény a második példában fog szerepet kapni, így erre később térünk ki.

 

Knockout JS használata PHTML template fájlban

 

A Knockout JS bemutatásához szükséges még a megfelelő javascript fájlok elkészítése is. Első lépésben definiáljuk a saját modulunkhoz tartozó javascript fájlt, amit a requirejs-config.js-ban teszünk meg. Ez az alábbi helyen található a példa modulunkban: app/code/Aion/Sample/frontend/requirejs-config.js. A fájl tartalma:

var config = {
     map: {
         '*': {
             sample: 'Aion_Sample/js/view/sample-sidebar'
         }
     }
 };

 

Itt adjunk meg, hogy a modulunkban hol található a saját javascript fájlunk.

 

Természetesen szükség van a sample-sidebar.js fájlra is. Ez az alábbi helyen található a példa modulunkban: app/code/Aion/Sample/frontend/web/js/view/sample-sidebar.js. A fájl tartalma:

 

define([
     'ko',
     'uiComponent',
     'Magento_Customer/js/customer-data',
     'mage/translate'
 ], function (ko, Component, customerData, $t) {
     'use strict';
     return Component.extend({
         // Second example
         defaults: {
             template: 'Aion_Sample/second-sidebar'
         },
         displayContent: ko.observable(true),
         initialize: function () {
             this._super();
             this.sample = customerData.get('sample');
             // Second example
             this.someText = $t('Sample content with template.');
             // Second example. foreach examples
             this._showItems();
             // Second example, foreach example
             this._showMonths();
             // Second example, other foreach example
             this._showCategories();
             // Second example and another foreach example
             this._showMyItems();
         },
         getInfo: function() {
             return this.sample().info || this.initFullname || customerData.get('customer')().fullname;
         },
         getCartItemsCountText: function () {
             return this.sample().cart_items_text;
         },
         getCartItemsCount: function () {
             return this.sample().cart_count;
         },
         getHint: function() {
             return this.sample().hint || this.initHint;
         },
         _showItems: function() {
             var self = this;
             if (typeof this.initSampleData !== "undefined") {
                 self.sampleItems = JSON.parse(this.initSampleData);
             }
         },
         _showMonths: function() {
             var self = this;
             self.months = [ 'Jan', 'Feb', 'Mar', 'etc' ];
         },
         _showCategories: function() {
             var self = this;
             self.categories = [
                 { name: 'Fruit', items: [ 'Apple', 'Orange', 'Banana' ] },
                 { name: 'Vegetables', items: [ 'Celery', 'Corn', 'Spinach' ] }
             ];
         },
         _showMyItems: function() {
             var self = this;
             self.myItems = [ 'First', 'Second', 'Third' ]
         }
     });
 });

 

A példában szereplő függvények előtt jelzésre került, hogy melyek tartoznak a később bemutatandó második példához. Ezen objektumok és függvények előtt a //Second example látható.

Nézzük meg egy kicsit a működést!

A javascript a Magento 2.0-ban lévő uiComponent objektumot terjeszti ki, majd definiálásra kerül a saját sample objektum is, mely a CustomerData része lesz (this.sample = customerData.get (‘sample’);). Még négy függvény kerül a példában definiálásra, melyeket a template fájl fogunk használni.

 

Függvények:

  • getInfo() – a vevő (customer) nevének megjelenítésért felelős.
  • getCartItemsCountText() – string példa szöveggel, melynek része a kosárban lévő termékek száma.
  • getCartItemsCount() – integer, ami a kosárban lévő termékek számát tartalmazza (nem az összmennyiséget, sum qty)
  • getHint() – string, csak információt tartalmaz

 

Az említett függvények által visszaadott adatokat a 4. pontban leírt Sample osztály fogja kezelni.

 

Nézzük a block-hoz tartozó template fájl tartalmát, ami az alábbi helyen található a példa modulunkban: app/code/Aion/Sample/frontend/templates/sidebar.phtml. A fájl tartalma:

 

<?php
 $sampleHelper = $block->getExtensionHelper();
 $initFullName = $sampleHelper->getIsLoggedIn() ? $sampleHelper->getCustomerFullName() : __('You are logged out.');
 ?>
 <?php if ($sampleHelper->isEnabled()) : ?>
     <div class="block block-compare block-aion-sample" data-bind="scope: 'sample'">
         <div class="block-title">
             <strong><?php /* @escapeNotVerified */ echo __('Aion Sample Block'); ?></strong>
         </div>
         <div class="block-content">
             <strong class="subtitle" style="display: inline-block">
                 <?php /* @escapeNotVerified */ echo __('Customer Info:') ?>
             </strong>
             <p class="description">
                 <span data-bind="text: getInfo()"></span><br />
             </p>
             <p class="description">
                 <!-- ko if: getCartItemsCount() -->
                 <strong class="subtitle" style="display: inline-block">
                     <?php /* @escapeNotVerified */ echo __('Cart Info:') ?>
                 </strong>
                 <br />
                 <span data-bind="text: getCartItemsCountText()"></span>
                 <!-- /ko -->
             </p>
             <p class="hint"><small data-bind="text: getHint()"></small></p>
         </div>
     </div>
     <script type="text/x-magento-init">
     { "*": {
             "Magento_Ui/js/core/app": {
                 "components": {
                     "sample": {
                         "component": "Aion_Sample/js/view/sample-sidebar",
                         "initHint": "<?php echo __('(Refresh automatically after cart modification)') ?>",
                         "initFullname": "<?php echo $initFullName ?>"
                     }
                 }
             }
         }
     }
     </script>
 <?php endif; ?>

 

Lényegében itt látható a Knockout JS használata. Nézzük, részletesen hol használjuk, és hogyan működik.

 

<span data-bind=”text: getInfo()”></span>

A javascript fájlban definiált getInfo() függvény által visszaadott string fog megjelenni a <span> tag-ben.

 

Knockout JS:

 

<!– ko if: getCartItemsCount() –>

<strong class=”subtitle” style=”display: inline-block”>

<?php /* @escapeNotVerified */ echo __(‘Cart Info:’) ?>

</strong>

<br />

<span data-bind=”text: getCartItemsCountText()”></span>

<!– /ko –>

 

Amennyiben a javascript fájlban definiált getCartItemsCount() függvény értéke nem 0, akkor megjelenítésre kerül az if szekcióban lévő rész. A getCartItemsCountText() függvény pedig egy string-gel tölti ki a <span> tag-et.

 

<p class=”hint”><small data-bind=”text: getHint()”></small></p>

A getHint() függvény egy string-gel tölti ki a <small> tag-et.

 

Nézzük meg, hogy ezek után hogyan jelenik meg az elkészült block a Magento 2.0 sidebar részében.

 

magento 2 modul fejlesztés sidebar

 

Hogyan módosíthatjuk ezeket az adatokat különböző felhasználói interakciókra? Erre kapunk választ a következő pontban.

 

Saját CustomerData osztály létrehozása és implementálása

 

Ahhoz, hogy a fenti block-unk és annak tartalma interaktívan módosuljon, szükségünk van egy saját CustomerData osztályra, mely a javascript-ben definiált sample osztályt szolgálja ki adatokkal.

Az osztály az alábbi helyen található a példa modulunkban: app/code/Aion/Sample/CustomerData/Sample.php. A fájl tartalma:

 

<?php
 namespace Aion\Sample\CustomerData;
 use Magento\Customer\CustomerData\SectionSourceInterface;
 use Aion\Sample\Helper\Data as DataHelper;
 /**
  * Sample section
  */
 class Sample implements SectionSourceInterface
 {
     /**
      * @var DataHelper
      *
     protected $_helper;
 
     /**
      * @param DataHelper $dataHelper
      */
     public function __construct(
         DataHelper $dataHelper
     ) {
         $this->_helper = $dataHelper;
     }
 
     /**
      * {@inheritdoc}
      */
     public function getSectionData()
     {
         $sampleData = $this->_getSampleData();

         return $sampleData;
     }
 
     /**
      * First sample data example
      *
      * @return array
      */
     protected function _getSampleData()
     {
         $sampleData = [
             'info' => __('You are logged out.')
         ];
         $isLoggedIn = $this->_helper->getIsLoggedIn();
         if ($isLoggedIn) {
             $sampleData = [
                 'info' => __('You are logged in as: %1', $this->_helper->getCustomerFullName())
             ];
         }
 
         $cartItemsCount = $this->_helper->getCartItemCount();
         $sampleData = array_merge(
             $sampleData,
             [
                 'cart_items_text' => __('You have %1 item(s) in your cart', $cartItemsCount),
                 'cart_count' => (int)$cartItemsCount,
                 'hint' => __('(Refresh automatically after cart modification)')
             ]
         );
 
         return $sampleData;
     }
 }

 

Az osztályban a getSectionData() függvény szolgálja ki adatokkal a javascript-ben definiált sample osztályt. Itt fontos megjegyezni, hogy a két osztályt célszerű azonos néven elnevezni a PHP és Javascript kódban.

A _getSampleData egy tömbbel tér vissza, melynek kulcsai megegyeznek a javascript kódban hasznát értékekkel. Itt implementálhatjuk a szükséges üzleti logikát. A példa kedvéért itt csak a customer teljes nevének átadása és kosár elemek számolása történik meg.

Szükséges még definiálni a CustomerData osztályt is, hogy a Magento 2.0 rendszer „tudjon” róla. Ezt a di.xml fájlban kell megadnunk, ami az alábbi helyen található a példa modulunkban: app/code/Aion/Sample/etc/frontend/di.xml. A fájl tartalma:

 

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
     <type name="Magento\Customer\CustomerData\SectionPoolInterface">
         <arguments>
             <argument name="sectionSourceMap" xsi:type="array">
                 <item name="sample" xsi:type="string">Aion\Sample\CustomerData\Sample</item>
             </argument>
         </arguments>
     </type>
 </config>

 

A következő fontos lépés, hogy a Sample osztályban definiált getSectionData() függvény mikor fusson le, milyen felhasználói interakcióra. Ehhez szükséges egy xml fájlban megadni ezen controller-ek listáját.

 

Ezt a sections.xml fájlban kell definiálnunk, ami az alábbi helyen található a példa modulunkban: app/code/Aion/Sample/etc/frontend/sections.xml. A fájl tartalma:

 

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
     <action name="checkout/cart/add">
         <section name="sample"/>
     </action>
     <action name="checkout/cart/delete">
         <section name="sample"/>
     </action>
     <action name="checkout/cart/updatePost">
         <section name="sample"/>
     </action>
     <action name="checkout/cart/updateItemOptions">
         <section name="sample"/>
     </action>
     <action name="checkout/sidebar/removeItem">
         <section name="sample"/>
     </action>
     <action name="checkout/sidebar/updateItemQty">
         <section name="sample"/>
     </action>
 </config>

 

Az xml-ben látható, milyen controller action-öket definiáltunk. Ezek a termék kosárba helyezése, törlése, termék számának frissítése stb.

De mit is jelent pontosan ez?

Miután elkészültünk a fenti Sample osztállyal, az említett getSectionData() függvény le fog futni ezen controller action-ök futása esetén, és a frontend-en megjelenő block-unk automatikusan ajax-szal frissülni fog a getSectionData() függvény által visszaadott adatokkal. Mindez anélkül történik, hogy bármilyen ajax függvényt és kezelést definiáltunk, írtunk volna a javascript fájlunkban.

 

Bejelentkezett felhasználóval így néz ki a block-unk miután egy tetszőleges terméket a kosárba helyeztünk:

 

magento 2 modul fejlesztés kosár

 

 

Az ajax hívásban visszakapott objektum tartalma:

 

magento 2 modul fejlesztés ajax tartalom

 

 

 

Knockout JS használata HTML template file-ként

 

Az előző példában a phtml fájlban használtuk közvetlenül a Knockout JS-t. A második esetben is ezt fogjuk alkalmazni, azonban egy külön html template fájlt használunk az adatok megjelenítésére.

Ehhez első lépésben egy második phtml példa fájlt hozunk létre. A fájl a modulunkban az app/code/Aion/Sample/view/frontend/templates/second-sidebar.phtml. A fájl tartalma:

 

<?php
 $sampleHelper = $block->getExtensionHelper()
 ?>
 <?php if ($sampleHelper->isEnabled()) : ?>
     <div class="block block-compare block-aion-sample" data-bind="scope: 'sample'">
         <div class="block-title">
             <strong><?php /* @escapeNotVerified */ echo __('Aion Second Sample Block'); ?></strong>
         </div>
         <div class="block-content">
             <!-- ko template: getTemplate() -->
             <!-- /ko -->
         </div>
     </div>
     <script type="text/x-magento-init">
     {
         "*": {
             "Magento_Ui/js/core/app": {
                 "components": {
                     "sample": {
                         "component": "Aion_Sample/js/view/sample-sidebar",
                         "initSampleData": "<?php echo addslashes(json_encode($block->getInitSecondItems())) ?>"
                     }
                 }
             }
         }
     }
     </script>
 <?php endif; ?>

 

Az első példában bemutatott phtml fájlhoz képest a különbség jól látható. A tartalmi részben kerül implementálásra a html template behívása:

<!– ko template: getTemplate() –>

<!– /ko –>

 

Itt fontos visszatérni a cikk elején bemutatott sample-sidebar.js fájlra és figyelembe venni a //Second sample kód részeket, mert a második példánkat ezek kezelik. Emellett az 1. pontban részletezett default.xml fájlban a második block-ot használjuk csak:

<block class=”Aion\Sample\Block\Sample” name=”aion.sample.knockout.sidebar.second” template=”Aion_Sample::second-sidebar.phtml” after=”wishlist_sidebar”/>

Az elsőt kikommentezzük.

 

A következő lépésben létrehozzuk a HTML fájlt, ami az app/code/Aion/Sample/view/frontend/web/template/second-sidebar.html. A fájl tartalma:

 

<!-- ko if: displayContent() -->
     <p data-bind="text: someText"></p>
 
     <h4>Items Form Block Class</h4>
     <ul data-bind="foreach: sampleItems">
         <li>
             <span data-bind="text: $data"> </span>
         </li>
     </ul>
 
     <h4>Months</h4>
     <ul data-bind="foreach: months">
         <li>
             <span data-bind="text: $data"> </span>
         </li>
     </ul>
 
     <h4>Categories</h4>
     <ol data-bind="foreach: { data: categories, as: 'category' }">
         <li>
             <ul data-bind="foreach: { data: items, as: 'item' }">
                 <li>
                     <span data-bind="text: category.name"></span>:
                     <span data-bind="text: item"></span>
                 </li>
             </ul>
         </li>
     </ol>
 
     <h4>My Items</h4>
     <ul>
         <!-- ko foreach: myItems -->
         <li>Item name: <span data-bind="text: $data"></span></li>
         <!-- /ko -->
     </ul>
 
 <!-- /ko -->
 <!-- ko ifnot: displayContent() -->
     <p class="empty-text" data-bind="text: $t('Content is empty.')"></p>
 <!-- /ko -->

 

A sample-sidebar.js-t elemezve nézzük át a HTML template fájl működését. Elsőként definiálva maga a template fájl és egy true érték, mely az if feltételben szerepel. Természetesen ezt a szükséges üzleti logika szerint lehet módosítani.

 

// Second example

defaults: {

template: ‘Aion_Sample/second-sidebar’

},

displayContent: ko.observable(true),

 

A példa adatokat szolgáló függvények automatikusan lefutnak az inicializálás során:

 

// Second example

this.someText = $t(‘Sample content with template.’);

// Second example. foreach examples

this._showItems();

// Second example, foreach example

this._showMonths();

// Second example, other foreach example

this._showCategories();

// Second example and another foreach example

this._showMyItems();

 

Ezek közül ‒ a példa céljából ‒ csak egyetlen adatai érkeznek a block osztályból (app/code/Aion/Sample/Block/Sample.php). Az átadása a phtml fájlban történik:

 

“initSampleData”: “<?php echo addslashes(json_encode($block->getInitSecondItems())) ?>”

 

A getInitSecondItems() függvény a helper osztályban van megvalósítva:

 

/**
  * Get sample product names
  *
  * @return array
  */
 public function getSampleProductNames()
 {
     $sampleData = [];
     /* @var $product Product */
     $product = $this->_productFactory->create();
     /* @var $collection Collection */
     $collection = $product->getCollection();
     $collection->setVisibility($this->_catalogProductVisibility->getVisibleInCatalogIds());
     $collection->addStoreFilter()->addAttributeToSelect(
         ['name']
     );
     $collection->getSelect()->orderRand('e.entity_id');
     $collection->setPageSize(
         5
     )->setCurPage(
         1
     )->toArray(['name']);
 
     /* @var $item Product */
     foreach ($collection as $item) {
         $sampleData[] = $item->getName();
     }
 
     return $sampleData;
 }

 

A látható termékek közül véletlenszerűen kiválaszt ötöt és ezek neveit egy tömbként adja át.

 

A sample-sidebar.js fájlban inicializált többi függvény egyszerű példa adatokat hoz létre, hogy a HTML template fájlban ezeken végig iterálva segítse a működés megértését. A második példa block-unk mindezek után így jelenik meg a forntend-en:

 

magento 2 modul fejlesztés frontend

 

ÖsszegzésA cikkben megpróbáltuk bemutatni a Knockout JS használatát egyedi modul fejlesztéshez. A Magento 2.0-ban nagyon sok helyen van alkalmazva customer, order, cart, wishlist és egyéb adatok megjelenítése céljából a frontenden.

 

Magento 2 modul fejlesztés lépésről lépésre – 3. rész (Observer-ek)

Ebben a cikkben az alábbiakról fogok írni:

  • Alap példa modul felépítése
  • Observer-ek létrehozása és implementálása

 

1) Alap példa modul felépítése

 

Az előző cikkekben (1. rész, 2. rész) megismerkedtünk egy példa Magento 2.0 modul elkészítésével, a hozzá tartozó adatbázis táblák, admin táblázat (grid), a modulhoz tartozó adatok létrehozásával, editálásával, mentésével és törlésével. Most egy másik egyszerű Magento 2.0 modulban az Observer-ek működésével foglalkozunk.

Ehhez első lépésben elkészítünk egy alap példa modult. Mivel korábbi cikkünk erre már kitért, most csak a modul felépítése kerül bemutatásra.

 

magento 2 modul szerkezet

 

2) Observer-ek létrehozása és implementálása

 

A Magento 2.0 példa modulban két Observer-t hozunk létre, melyeket két külön eseményre „kötünk” rá. A Magento 1.x modulok esetében egy Observer osztályban kerültek megvalósításra a különböző események során megvalósítandó függvények és azokban történő üzleti logikák. A Magento 2.0-ban minden egyes eseményhez külön saját Observer osztályt kell létrehozni, melyekben az execute(…) függvényben kerül az üzleti logika megvalósításra.

Mielőtt az Observer osztály létrehozásra kerül, definiálni kell, hogy melyik eseményre szeretnénk a saját üzleti logikánkat alkalmazni. Itt fontos eldönteni, hogy a frontend vagy az admin oldalon (adminhtml) szeretnénk használni, így a definíciós xml fájlt a megfelelő helyen kell elhelyezni.

Globálisan is el lehet helyezni, de célszerű ezt mindig külön választani. Első példában egy frontend oldali eseményre, az alap Magento 2.0 contact form (kapcsolat) elküldése után szeretnénk az elküldött adatokat „elkapni” a saját Observer osztályunkkal.

Ehhez szükségünk lesz egy events.xml fájlra, ami az alábbi helyen található a példa modulunkban: app/code/Aion/Sample/etc/frontend/events.xml. A fájl tartalma:

<?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="controller_action_postdispatch_contact_index_post">
        <observer name="aion_sample_post_capture" instance="Aion\Sample\Observer\CapturePost" />
    </event>
</config>

A fájl felépítése nagyon egyszerű. Az event tag-ben lévő name paraméterben kerül meghatározásra, hogy melyik eseményt szeretnénk „elkapni”.

Az esetünkben a Magento 2.0 alap Contact moduljában lévő post controller utáni esemény. Az event tag-en belül pedig definiáljuk az observer tag-ben a saját Observer osztályunkat, ami majd meghívásra kerül és egyedi név paramétert is adunk neki. Az event tag-ben egymás alatt több saját Observer-t is definiálhatunk ugyanezen eseményhez, illetve az xml fájlban több event tag-et is megadhatunk, ha más eseményekhez is szeretnénk további saját Observer-t használni.

Ezt követően a saját Observer osztályunkat kell létrehozni és megvalósítani benne a szükséges üzleti logikát. A fájl az alábbi helyen található a példa modulunkban: app/code/Aion/Sample/Observer/CapturePost.php. A fájl tartalma:

<?php
namespace Aion\Sample\Observer;

use Magento\Framework\Event\ObserverInterface;
use Aion\Sample\Helper\Data as DataHelper;
use Psr\Log\LoggerInterface;
use Magento\Framework\Event\Observer;
use Magento\Customer\Model\Customer;
use Magento\Framework\Exception\LocalizedException;

class CapturePost implements ObserverInterface
{
    /**
     * Aion Sample helper
     *
     * @var DataHelper
     */
    protected $_helper;

    /**
     * @var LoggerInterface
     */
    protected $_logger;

    /**
     * Capture Post Observer constructor
     *
     * @param DataHelper $helper
     * @param LoggerInterface $logger
     */
    public function __construct(
        DataHelper $helper,
        LoggerInterface $logger
    ) {
        $this->_helper = $helper;
        $this->_logger = $logger;
    }

    /**
     * Sample post capture event handler
     *
     * @param Observer $observer
     * @return self
     */
    public function execute(Observer $observer)
    {
        if ($this->_helper->isEnabled()) {

            $controller = $observer->getEvent()->getControllerAction();
            $post = $controller->getRequest()->getPostValue();

            if ($post) {

                try {

                    $this->_logger->debug('CapturePostObserver');
                    $this->_logger->log(100, print_r($post, true));

                    // comment out to check data
                    //\Zend_Debug::dump($post);
                    //die();

                    // do some logic

                } catch (LocalizedException $e) {
                    $this->_logger->error($e->getMessage());
                } catch (\Exception $e) {
                    $this->_logger->critical($e);
                }

            }

        }

        return $this;
    }
}

Amennyiben a fent említett events.xml fájlban definiált esemény megtörténik, a CapturePost osztályban lévő execute függvény hajtódik végre. A függvény első lépésben megvizsgálja, hogy a saját modulunk engedélyezve van-e. Abban az esetben, ha engedélyezve van, az említett Magento 2.0 alap Contact form által elposztolt adatokat „elkapja”. Az egyszerűség kedvéért a példában csak logoljuk a tömböt a debug.log file-ban. Az így megkapott adatokat felhasználva megírhatjuk a saját üzleti logikánkat.

A második példában egy admin oldali eseménynél, az alap Magento 2.0 felhasználó mentés után szeretnénk az felhasználó (customer) objektumot és adatokat „elkapni” a saját Observer osztályunkkal.

Ehhez szükségünk lesz egy events.xml fájlra, ami az alábbi helyen található a példa modulunkban: app/code/Aion/Sample/etc/adminhtml/events.xml. A fájl tartalma:

<?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="controller_action_postdispatch_contact_index_post">
        <observer name="aion_sample_post_capture" instance="Aion\Sample\Observer\CaptureCustomer" />
    </event>
</config>

 

 

 

A fájl felépítése ugyanaz, mint az előző példában említett events.xml esetében, csak ezúttal az adminhtml könyvtár van elhelyezve, így a definiált CaptureCustomer osztály csak az admin scope-ban fog meghívódni a felhasználó mentés utáni eseményre (customer_save_commit_after).

 

Ezt követően az előző példához hasonlóan a saját Observer osztályunkat kell létrehozni és megvalósítani benne a szükséges üzleti logikát. A fájl az alábbi helyen található a példa modulunkban: app/code/Aion/Sample/Observer/CaptureCustomer.php. A fájl tartalma:

 

 

<?php
namespace Aion\Sample\Observer;

use Magento\Framework\Event\ObserverInterface;
use Aion\Sample\Helper\Data as DataHelper;
use Psr\Log\LoggerInterface;
use Magento\Framework\Event\Observer;
use Magento\Customer\Model\Customer;
use Magento\Framework\Exception\LocalizedException;

class CaptureCustomer implements ObserverInterface
{
    /**
     * Aion Sample helper
     *
     * @var DataHelper
     */
    protected $_helper;

    /**
     * @var LoggerInterface
     */
    protected $_logger;

    /**
     * Capture Customer Observer constructor
     *
     * @param DataHelper $helper
     * @param LoggerInterface $logger
     */
    public function __construct(
        DataHelper $helper,
        LoggerInterface $logger
    ) {
        $this->_helper = $helper;
        $this->_logger = $logger;
    }

    /**
     * Sample customer capture event handler
     *
     * @param Observer $observer
     * @return self
     */
    public function execute(Observer $observer)
    {
        if ($this->_helper->isEnabled()) {

            /* @var Customer $customer */
            $customer = $observer->getEvent()->getCustomer();

            if (!is_null($customer) && $customer->getEntityId()) {

                try {

                    $this->_logger->debug('CaptureCustomerObserver');
                    $this->_logger->log(100, print_r($customer->getData(), true));
                    // comment out to check data
                    //\Zend_Debug::dump($customer->getData());
                    //die();

                    // do some logic

                } catch (LocalizedException $e) {
                    $this->_logger->error($e->getMessage());
                } catch (\Exception $e) {
                    $this->_logger->critical($e);
                }

            }

        }

        return $this;
    }
}

 

Amennyiben a fent említett második events.xml file-ban definiált esemény megtörténik, a CaptureCustomer osztályban lévő execute függvény hajtódik végre. A függvény első lépésben megvizsgálja, hogy a saját modulunk engedélyezve van-e.

Abban az esetben, ha engedélyezve van, az említett Magento 2.0 admin felhasználó mentés után „elkapja” a customer objektumot. Az egyszerűség kedvéért a példában csak logoljuk az objektum adatait a debug.log file-ban. Az így megkapott objektumot és adatokat felhasználva megírhatjuk a saját üzleti logikánkat.

 

Összegzés

A cikkben két példával próbáltuk illusztrálni a Magento 2.0 rendszerben, hogyan kell saját egyedi modulunkban Observer-eket definiálni és megvalósítani különböző eseményekre a frontend és az admin oldalon.

 

Kódaudit és kódjavítási szempontok Magento projekteknél

Első lépés a Magento kódaudit során

Érdemes megnézni, történt-e valamilyen hard-kódolás a projektben, találunk-e benne olyan módosításokat, amelyek a core fájlokban lettek kivitelezve, nem pedig config-ban újraírva, vagy community/local codepool-ba áthelyezve, majd ott módosítva. Ehhez arra van szükségünk, hogy legyen egy ugyanolyan típusú (community/enterprise) Magento projektünk (a verziószám is egyezzen), amivel össze tudjuk hasonlítani.

 

Ehhez PHPStorm-ot fogunk használni, de egyéb programokkal is nagyon szépen kivitelezhető az összehasonlítás. Kattintsunk az app/code/core könyvtárra, majd jobb klikk rajta, „Compare With…” (Ctrl + D), majd válasszuk ki a „társ-környezet”-ben ugyanezt a mappát.

 

Miután elfogadtuk (OK), felugrik egy ablak a változásokkal, itt nyugodtan kapcsoljuk ki a „Show new files on left side”, illetve a „Show new files on right side” opciókat, csak összezavarna bennünket. Ezek után, ha minden igaz, csak a „Show difference” lehetőség marad aktív, ami kifejezetten a különbségek listázására való.

Sajnos olyan opciót nem találtam, ami a kommenteket nem veszi figyelembe, így bár a kódrészek megegyeznek, a kommentek miatt több fájlt is feldob, mint különbséget. Ettől eltekintve esetemben nincs különbség a 2 projekt között. Ha ez a te esetedben nem így van, tehát különbségek vannak a rendszerben, azokat a fájlokat, amelyek eltérnek az eredetitől, vissza kell állítani, és a módosításokat át kell helyezni.

tips Ezt többféleképpen is megtehetjük :

 

  1. Core fájl átmásolása az app/code/core/…/File.php elérésről, az app/code/local/…/File.php helyre, majd az eredeti fájl revertálása annak alaphelyzetébe

 

  1. A fájl config-ból való felülírása egy a saját modulunk fájljával, az eredeti fájlt ebben az esetben is alaphelyzetbe kell állítanunk, és azt mint ős-osztályt kiterjeszteni belőle

 

  1. Harmadik lehetőségként Observer-rel megvalósítani a működésbeli különbségeket

 

A fenti listából az első megoldást tartom a leggyorsabbnak, míg az utolsót a legszebbnek.

 

Amennyiben ezek megtörténtek ‒ tehát a capp/code/core fájlok az eredeti állapotukba, az új működések pedig valamilyen módon kiszervezésre kerültek ‒, a következő lépés az app/design/[frontend/adminhtml] mappa(k) tartalmának összehasonlítása. Sajnos gyakran előfordul, hogy a fejlesztő nem hoz létre saját template vagy layout fájlt, hanem a base/default/[template/layout] mappá(k)ban szereplő eredeti fájlokat módosítja.

 

Ennek javítása is hasonlóképpen történik, mint a kód esetében. A módosított fájlokat átmásoljuk a saját témánk alatt ugyanabban a struktúrában, az eredeti fájlokat pedig eredeti állapotukra revertáljuk. pl. az app/design/frontend/base/default/template/catalog/product/list.phtml-t másoljuk az app/design/frontend/rwd/theme/template/catalog/product/list.phtml elérésre, az eredetit pedig visszaállítjuk.

Layout fájlok esetében elég csak a változó részt átmásolni, nem szükséges az egész layout fájlt egy-egy rész miatt mozgatni, illetve még szebb megoldás, ha reference-szel hivatkozunk egy definiált Block-ra.

 

Template-ek esetében is érdemes felmérni annak lehetőségét, hogy tudjuk-e layout-ból számunkra megfelelő módon változtatni, módosítani. Ha layoutból módosítva azonban nem a megfelelő helyen jelennek meg a kérdéses új elemek/blokkok/template-k, a fent említett módszer (template mozgatása, változtatása) biztos megoldást jelent.

 

Tegyük fel, hogy ezeken a helyeken is minden rendben volt, a template és layout fájlok is ott kerültek módosításra, ahol ennek történnie kell (akkor ez egy nagyon szép projekt, valószínűleg a továbbiakban sem lesz vele gond). A meglévő modulok illetve template fájlok minőségét kell ellenőrizni, ezeket az alábbi szempontok alapján tudjuk megtenni, melyekre egyesével kitérünk:

 

  • Kódredundancia – kódismétlés
  • Kódrelevancia – bizonyos kódok megfelelő helyen történő tárolása
  • Installer Scriptek – minőség és megbízhatóság
  • Template fájlok – objektumhívások minimalizálása
  • Block / Controller ellenőrzés – terhelés, megvalósítás

 

 

Kódredundancia – kódismétlés

 

A kódredundancia: alatt az értendő, mikor egy adott modulon ‒ vagy akár több összefüggő modulon keresztül ‒ ugyanazt a működést valósítjuk meg, akár ugyan azzal a módszerrel, de több különböző helyen. Ha a kódban ilyet találunk, biztosan rossz helyen szerepelnek ezek a kódrészek, hiszen ezeknek optimális esetben egy helyen kell lennie, és onnan kerülnek meghívásra.

Sajnos ezt nem olyan könnyű kiszúrni, hiszen a kód nem egzakt, többféleképpen is nekifuthatunk valaminek az ellenőrzésének, így ennek a felmérése, megtalálása több időt vehet el, mint a végén az az idő, amelyet a javítására kell fordítani. Az alapvető szempont, hogy legjobb már az elején, a fejlesztés indításánál, felkészíteni az egységes működésre ezeket a folyamatokat, és ennek szellemében létrehozni a különböző megoldásokat.

 

Kódrelevancia – bizonyos kódok megfelelő helyen történő tárolása

 

Vannak kódok, melyeknek egyértelmű helyeik vannak, ilyen pl. egy új modul aloldala, action-je, aminek egyértelműen controller-be kell kerülnie, hiszen egyéb esetben nem működik. Vannak kódok azonban, amelyek funkciótól függően lehetnek Block-ban, vagy Helper-ben is, sőt, akár még Model-be is kerülhetne, de  ezeknek is megvan a pontos helye. Az általános működéshez kapcsolódó kódok azonban nagy valószínűséggel Helper-be kell, hogy kerüljenek, a keresztfunkcionalitás segítése érdekében. Jellemzően ilyenek az egy-egy modul állapotát ellenőrző kisebb metódusok, és/vagy amelyek közvetve vagy közvetlenül, de a config értékekkel dolgoznak.

 

Ezen felül kerülhetnek ide még az aktuális end user-hez kapcsolódó, de alaphelyzetben még le nem fejlesztett ellenőrzések, mint pl. egy adott típus ellenőrzése egy kiterjesztettebb regisztráció után, stb. $helper->isStudent(); $helper->isTeacher() stb. (Bár ezeket szintén akár observer-rel is meg lehet oldani.)

 

Ide lehet sorolni még bizonyos a Model-ekhez kapcsolódó „működéseket”, melyek néha eltévednek a megvalósítás közben. Jó példának tartom ide a Model exportálandó mezőit, illetve annak CSV header-eit, aminek nem helper-ben vagy block-ban a helye, hiszen bárhol ahol a Model meghívásra kerül, szükség lehet erre, aminek egyszerűbb és logikusabb módja az adott Model-ben tárolni.

Ide raknám még a Model-hez az esetleges parent-child elemek lekérését, tehát ha az egyik adott Model-nek van egy 1-* kapcsolata egy másik Model-el, azt esetleg egy $model->getChildSomethings(); metódussal a „fő” Model-ben elhelyezhető.

cikkgrafika-koderelevancia

Installer Scriptek – minőség és megbízhatóság

 

Az installer script-ek írása közben gyakran megfeledkezünk még mi magunk is arról, hogy valamilyen varázslatos és megmagyarázhatatlan módon (valaki töröl egy jellemzőt, mezőt, értéket, majd újra futtatja a script-et), időnként duplán futnak le, és így nem várt hibába ütközünk.

 

Ennek kiküszöbölése nem annyira időbeli, mint hozzáállásbeli erőfeszítést igényel. Bár valószínűleg saját script-ünk futtatásakor a saját környezetünk adataira támaszkodva készítjük el azt, érdemes ezeket mindenre felkészítve, már eleve egy ellenőrzéssel indítani.

Ha jellemzőt adunk hozzá, akkor a jellemzőt keressük először, és a hozzáadását kössük feltételhez. Tábla mezőinek manipulálásakor is érdemes ellenőrizni annak aktuális állapotát. A $installer->endSetup(); kódot, csak a 100%-ig biztos lefutáshoz illesztjük be, ha try-catch-be rakjuk az installer működését, az endSetup() ne ezen kívül, hanem a try végében helyezkedjen el, így biztosítva, hogy csak a helyes működéssel lép verziószámot modulunk.

 

Template fájlok – objektumhívások minimalizálása

 

A template fájlok (.phtml) írása során is igyekeznünk kell annak azonnali áttekinthetőségére, illetve a kód újrahasznosíthatóságára. Mit jelent ez?

 

  • Nem égetünk bele értékeket
  • Nem valósítunk meg benne működést
  • Nem hívunk a szükségesnél több metódust benne

 

Helyette:

 

  • Az értékeket/beállításokat lehetőleg már (a frontend-es kolléga támogatását elősegítve) layout szinten megadhatónak fejleszteni.
  • Mindennemű működést, ami a lekéréseken felül kerül hívásra, a Block-okban megvalósítani
  • A template-ek bizonyos szintű összetettségétől függően (pl. 2 különböző típus elágazásánál) külön template-ekbe szervezni.

 

Idetartozónak tartom még, bár valójában ez minden részében igaz a fejlesztéseknek, hogy egy-egy értéket (0, 1, 2) soha nem értékével azonosítunk, ezeket érdemes, sőt kötelező valamilyen konstansba helyezni, és így beszédes változónévvel azonnal áttekinthetővé tenni annak értékét. Erre is nagyon jó példák találhatóak a Core Magento-ban, termék Status értékek, xml config path-ek, valamilyen minimum/maximum értékek meghatározása.

cikkgrafika-templates

Azonfelül, hogy ezek sokkal áttekinthetőbbek, beszédesebbek is így, ha mindenhol ezt az értéket használjuk, arra keresni is sokkal egyszerűbb (kevesebb találat), illetve egy helyen tudjuk módosítani adott esetben.

 

Block / Controller ellenőrzés – terhelés, megvalósítás

 

A block-ok és controller-ek ellenőrzésénél két dolgot kell figyelembe venni, és ez a két dolog elég szorosan összefügg. A megvalósítás mikéntje, és a terhelés, amit ki kell állnia. Minél jobb a megvalósítás, annál kisebb a terhelés.

Amennyiben egy template fájlból a block getCollection() metódusa több alkalommal is hívásra kerül, azt jó megoldás cache-elni a block-ban, így valódi adatbázis művelet csak elsőre lesz, minden további csak a cache-elt objektumlistáig jut. Erre találunk egyébként core példákat is, amelyeket minden további nélkül lehet útmutatásként használni.

 

A controllerek esetében érdemes az egyes action-ök méretére egy pillantást vetni. Nem kívánok itt sem fontméretet sem pedig a sorok számát megadni, hogy mekkora terjedelemig megfelelő egy action, de abban azt hiszem, megegyezhetünk, hogy a szemnek kényelmesen áttekinthetőnek kell azt találnia, mind formai mind mennyiségi szempontból.

Amit még a controllerek-hez hozzátennék, hogy véleményem szerint az ezekben elhelyezett block példányosítások sem szükségszerűek, szintén meg lehet oldani a block-on belül. Ezzel máris csökkentjük annak méretét.

 

Összegzés

Ez mennyiségileg nem olyan sok dolog, hiszen mindössze 5 részletesebb és 2(1) ezektől különálló lehetséges problémafaktort tekintettünk át, de ha azt vesszük figyelembe, hogy egy-egy projekten akár nagyobb számú (értsd x > 4) fejlesztő is dolgozhat egymás mellett, modulonként akár egyszerre tízes nagyságrendű fájlokat hoznak létre/módosítanak, már nem is olyan kevés.

Ha minden ilyen fájlban csak egy ilyen apró hiba van, már az is indokolhat egy kisebb refaktorálást a projekt élesítése előtt/után. Illetve a témánkat tekintve, ezeken a pontokon végighaladva, egy részletesebb képet kapunk arról, hogy az új projektünk mennyi, és milyen problémákkal rendelkezik, melyeket meg kell oldanunk.

 

Szükséged van további segítségre? Keress minket azonnal, vagy olvass többet kódaudit szolgáltatásunkról.

 

Problémák a Magento RWD sablonnal és hogyan sikerül ezeket megoldanunk

Bevezetés

Aki már foglalkozott Magento frontend fejlesztéssel, annak nyilván nem kell bemutatnunk az RWD (Responsive Web Design) theme-et. Ez a Magento alapcsomaggal utazó reszponzív template, amellyel már mobile-ready webshopokat építhetünk fel.

Azért írom, hogy mobile-ready, mert nem mobile-first. A mobile-first ugyanis elsődlegesen a mobileszközökön való kifogástalan működést célozza meg, míg a mobile-ready alapvetően desktop funkciójú mobilos „áthallással”.

Projektjeink kapcsán megrendelőik (jogosan) egyre többször azzal a kéréssel fordulnak hozzánk, hogy webshopjukat a desktop nézet mellett a mobilra is 100%-ig optimalizáljuk UI/UX szempontból is.

A 21. század egyik nagy vívmánya az okostelefon, és ezzel együtt az internetezési szokások gyökeres átalakulása. A rohanó világban egyre többen okostelefonjukat, tabletjüket használjak a gyors információszerzés mellett a webes vásárlásokhoz is. Emiatt kiemelten fontos, hogy a mobilon vásárlást gyorsan elvégezhessük, a dizájn pedig letisztult, egyszerűen áttekinthető legyen.

Erre pedig mondjuk ki őszintén, csak bizonyos mértékig használható az RWD theme. Hogy miért is, arra a cikkben részletesebben ki fogok térni. Több projektünk után végül úgy döntöttünk, hogy bár az RWD alapjain, de egy saját template-et építünk fel a Bootstrap framework segítségével.

 

Megvalósítás

Melyek tehát azok a pontok, amelyek alapján az RWD nem megfelelő választás egy 21. századi, mobile-first webshop kialakításához?

 

  • Mobile-ready, nem mobile-first (elsődlegesen a desktop nézetet támogatja)
  • Elavult grid rendszer (az RWD egy jó pár éves, saját fejlesztésű grid rendszert használ, amivel nehézkesen valósíthatók meg egyedi mobil felületek – a NILA ezzel szemben az egyik legkorszerűbb frontend framework-ot, a Bootstrap-et használja – 12 oszlopos grid rendszere, a flex támogatással a legjobb választás gyors fejlesztéshez)
  • Nem moduláris (Nincs lehetőség az aloldalak, layoutok külön módosítására, minden egy CSS fájlból van kezelve)
  • Nincs OOP CSS (Mivel csak egy fordított CSS fájlt tartalmaz az RWD sablon, ezért nehézkesen módosíthatók akár csak az alapbeállítások is – szín, betűtípus stb.)
  • Gyenge böngésző támogatottság (nincs kifejezetten OSX/iOS támogatás)

 

A NILA sablon dizájnja

Grafikusunk az RWD demo alapján alakította ki az Aion NILA sablon megjelenését. Próbáltuk még letisztultabbá és áttekinthetőbbé tenni, valamint, ahogy már említettem, a szemlélet mobile-first alapú. Ez azt jelenti, hogy mind dizájnban, mind megvalósításban lentről építkezünk felfelé. Színvilágban a kékes-szürke irányt választottuk, ettől lett a végeredmény igazán minimalista.

 

Új skin létrehozása

Az első lépésben létrehoztunk egy új skint az RWD csomag alatt. Azért nem egy új csomagot használtunk, mert a NILA template struktúrája az RWD-re támaszkodik, így gyorsabban és egyszerűbben tudtunk haladni a fejlesztéssel.

 

rwd vs nila sablon struktúra

 

 

A gyakorlatban ez úgy nézett ki, hogy a számunkra szükséges template-eket, layoutokat override-oltuk a NILA skin alól, a struktúra többi részét pedig az RWD alól kezeljük a template jelenlegi verziójában.

Ahogy említettem, a megvalósításhoz frontend oldalról a Bootstrap framework legfrissebb verzióját használtuk (3.3.6), a CSS-t pedig LESS-szel valósítottuk meg az objektum orientáltság függvényében. A NILA csomagolt verziója csak a fordított CSS fájlokat fogja tartalmazni.

Frontend oldalról mindegyik oldal és aloldal új csínt kapott, egységes CMS megjelenítést hoztunk létre, valamint kiemelt figyelmet fektettünk az e-mail template-ek, valamint a nyelvesítés megvalósítására is (hu_HU)

 

Mélyvíz – lássuk a kódszintű felépítést!

 

Ugorjunk fejest a mélyvízbe. A teljesség igénye nélkül most bemutatom a NILA felépítését kód szempontból is.

 

Könyvtárszerkezet

 

NILA theme: app/design/frontend/rwd/nila

 

NILA skin:: skin/frontend/rwd/nila

 

A skin mappánk több almappából épül fel.

 

  • aion: a NILA skin saját CSS / JS fájlok, amelyek az oldal megjelenését befolyásolják
  • css: email-inline.less az email template-ekhez használt megjelenés
  • images: alapértelmezett RWD template képek
  • img: a NILA témához tartozó képek
  • vendor: third-party könyvtárak és modulok mappája (Bootstrap, Fontawesome, Owl.Carousel)

 

 

Grid rendszer

Az RWD sablon rendszere egy saját fejlesztésű grid rendszeren alapul, amely csak korlátozottan használható mobile-first oldalak fejlesztéséhez.

 

Példa:

 


@media only screen and (min-width: 480px) {
  .customer-account-login .col2-set .col-1,
  .customer-account-login .col2-set .col-2 {
    padding-top: 0;
    margin-top: 20px;
  }
  .customer-account-login .col2-set .col-1 {
    padding-right: 20px;
  }
  .customer-account-login .col2-set .col-2 {
    padding-left: 20px;
    border-left: 1px solid #ededed;
  }
}
@media only screen and (min-width: 770px) {
  .customer-account-login .col2-set .col-1 {
    padding-right: 0;
  }
  .customer-account-login .col2-set .col-2 {
    padding-left: 60px;
    border-left: 1px solid #ededed;
  }
}
@media only screen and (max-width: 479px) {
  .customer-account-login .col2-set .col-1 {
    padding-bottom: 30px;
  }
  .customer-account-login .col2-set .col-2 {
    padding-top: 30px;
    border-top: 1px solid #ededed;
  }
}

Ahogy láthatjuk, a grid rendszer mobil töréspontok deklarálása nem az elfogadott töréspontokhoz igazodik, hanem egyedi pontokat hoz létre: 479, 770, de a kódot átnézve további idegen töréspontokra is találhatunk:


@media only screen and (max-width: 535px) {...}
@media only screen and (max-width: 525px) {...}
 

 

A NILA grid rendszeréhez a Bootstrap framework-öt választottuk, amely mobile-first szemlélettel készült, és igazodik a szabványos töréspontokhoz, és ezzel az elterjedt felbontások támogatásához:

(http://getbootstrap.com/css/#grid)

 

 


/* Extra small devices (phones, less than 768px) */
/* No media query since this is the default in Bootstrap */
/* Small devices (tablets, 768px and up) */
@media (min-width: @screen-sm-min) { ... }
/* Medium devices (desktops, 992px and up) */
@media (min-width: @screen-md-min) { ... }
/* Large devices (large desktops, 1200px and up) */
@media (min-width: @screen-lg-min) { ... }

 

 

rwd vs nila grid

 

 

Less fájlok

Template-ünket úgy építettük fel, hogy az minél modulárisabb és könnyen módosítható legyen. Minden oldal, CMS oldal saját LESS fájlt kapott, így a template-et moduláris szinten tudjuk módosítani, valamint új projektek eseten nem szükséges az egész template-et felhasználni, csak a módosítandó layoutokat.

A template egységes elemei, így például a fejléc, láblééc, és a gombok megjelenése szintén egy különálló LESS fájlba kerültek, valamint létrehoztunk egy BASE.less fájlt a változók, funkciók, mixinek tárolására.

 

rwd vs nila less fájl

 

A frontendre csak a nila.css fájl kerül ki, ez pedig a fordítás előtt így épül fel a moduláris less fájlokból:

  • Base.less
  • Deafult.less
  • Module.less

 

 

rwd vs nila könyvtár

 

Új oldal esetén csak hozzá kell fűznünk a module_neve.less fájlt a nila.less-hez, és fordítás után már a nila.css tartalmazni fogja az új vagy módosított megjelenést.

 

Javascript

A NILA sablon JS oldalról nem tartalmaz különösebb módosítást az RWD-hez képest, a Bootstrap javascript plugin-jai mellett csupán az OwlCarousel.js-t használtuk fel a főoldali újdonságok slider-hez.

 


   jQuery("#home-products-grid").owlCarousel({
        autoPlay: false,
        items : 5,
        itemsDesktop : [1199,3],
        itemsDesktopSmall : [979,3],
        navigation: true
    });

 

Ahogy láthatjuk, a slider-ben alapesetben 5 terméket jelenítünk meg, ezután pedig a további termékek slide-olással tekinthetők meg. Ha más számú terméket szeretnénk megjeleníteni, azt megtehetjük admin felületről, az alábbi sor módosításával, valamint a javasript „items” értékének módosításával:

 


   $content = '{{widget type="catalog/product_widget_new" display_type="new_products" products_count="5" template="catalog/product/widget/new/content/new_grid.phtml"}}';

 

Template override

 

Mivel a NILA jelenlegi verziója az RWD csomagon alapszik, ezért csak azokat a template-eket / layout fájlokat módosítottuk, amelyekre az egyedi megjelenéshez szükségünk volt. A fejlesztések későbbi szakaszaiban a NILA ki fog válni az RWD csomag alól, és különálló csomagként fog funkcionálni.

 

  • CMS
  • Home
  • Category
  • Product
  • Cart
  • Checkout
  • Wishlist
  • Dashboard
  • Account

 

A NILA sablon egyik legnagyobb előnye tehát a moduláris felépítés. Míg az RWD téma módosítása nehézkes, a NILA template-et percek alatt testre tudjuk szabni a base.less es default.less fájlok módosításával.

 

 

További mobil optimalizációk

Mint említettem, template-ünket mobile-first szemléletben építettük fel, a cél a minél egyszerűbb használhatóság megvalósítása volt mobil eszközökön is. Mivel több elem nem, vagy csak nehézkesen használható mobil nézetben (pl. táblázatok, kosár, checkout, érintési felületek), ezért egy egyedi modul segítségével azonosítani tudjuk a felhasználó eszközét, és ennek megfelelően mobil és desktop blokkokat betölteni.

 

Modulunk alapját a széles körben ismert MobileDetect PHP könyvtár adta.

 


<?xml version="1.0"?>
<config>
    <modules>
        <Aion_MobileDetect>
            <version>0.1.0</version>
        </Aion_MobileDetect>
    </modules>
    <global>
        <helpers>
            <aion_mobiledetect>
                <class>Aion_MobileDetect_Helper</class>
            </aion_mobiledetect>
        </helpers>
    </global>
</config>

 

Mobil detektálása:

 


public function isMobile($userAgent = null, $httpHeaders = null)
{
        if ($httpHeaders) {
            $this->setHttpHeaders($httpHeaders);
        }
        if ($userAgent) {
            $this->setUserAgent($userAgent);
        }
        // Check specifically for cloudfront headers if the useragent === 'Amazon CloudFront'
        if ($this->getUserAgent() === 'Amazon CloudFront') {
            $cfHeaders = $this->getCfHeaders();
            if(array_key_exists('HTTP_CLOUDFRONT_IS_MOBILE_VIEWER', $cfHeaders) && $cfHeaders['HTTP_CLOUDFRONT_IS_MOBILE_VIEWER'] === 'true') {
                return true;
            }
        }
        $this->setDetectionType(self::DETECTION_TYPE_MOBILE);
        if ($this->checkHttpHeadersForMobile()) {
            return true;
        } else {
            return $this->matchDetectionRulesAgainstUA();
        }
}

 

Függvényünket bármelyik templateünkben a következő módon hívhatjuk meg:

 


$helper = Mage::helper('aion_mobiledetect/data');
if($helper->isMobile())
{
  echo “is mobile”;
} 

else 
{
  echo “is not mobile”;
}

 

Ez a megvalósítás lehetőséget ad számunkra, hogy a reszponzív nézetek mellett mobilra egyedi blokkokat is betölthessünk, amelynek teljesen eltérő a szerkezete a desktop felépítéstől. Ezeket a blokkokat a böngészőnk csak akkor fogja letölteni, ha az adott eszközről használjuk az oldalt. Ezzel a módszerrel elkerülhetjük az elemek felesleges betöltését.

 

Safari / iOS támogatás

Az alap RWD téma egy másik nagy hibája, hogy gyenge a böngésző támogatottsága. Megrendelőink egyik igénye, a Windows-os böngészők támogatása mellett (IE10+, Chrome, Firefox, Opera) az OSX-en és iOS-en való Safari böngészőket is támogassuk.

Mivel sajnos a Safari alapértelmezetten több érteket másképp kezel, mint a Chrome, így az általános less fájlok egyszerű módosítása nem oldotta volna meg a problémát.

Egy egyszerű példánál maradva, a Safari a “display: flex” értéket is másképpen kezeli, mint a Chrome vagy Firefox böngészők, ezért a következő módosítást kellett eszközölnünk:

 


.aion-dashboard-wishlist {
 .cart-item {
 display: -webkit-flex;
 -webkit-flex: 1;
 -webkit-box-flex: 1;
 }
}

 

[ Megjegyzés: Safari böngésző esetén további problémát jelent a form-ok formázása, mivel mind az OSX mind az iOS a native form elemeket jelenít meg. Designereinkkel egyeztetve végül úgy döntöttünk, hogy az egyedi / Bootsrap form elemek helyett OSX/iOS renszerek alatt meghagyjuk a form elemek native megjelenését a jobb UX élmény érdekébben. ]

 

A megoldás a fentebb már említett MobileDetect modul volt, melyet kiegészítettünk egy Safari detektálással is:

 


/**
* This method checks if browser is Safari / Desktop
* @return bool
*/
public function isBrowserSafari()
{
    $agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : "";
        if (stripos($agent, 'Safari')
            && stripos($agent, 'iPhone') === false
            && stripos($agent, 'iPod') === false
            && stripos($agent, 'Chrome') === false) {
            $this->setBrowser(self::BROWSER_SAFARI);
            return true;
        }

     return false;
}

 

Ezt az alábbi módon használhatjuk fel:

 


$helper = Mage::helper('aion_mobiledetect/data');

if($helper->isBrowserSafari()) 
{
    $body_class = "__browser_safari";
} 

else
{
    $body_class = "__browser_other";
}

 

Ennek a segítségével lehetőségünk nyílt kifejezetten csak OSX/Safari böngészőkre optimalizált CSS módosításokat végezni, amely módosítások nem befolyásolják a Windows-os böngészők megjelenítését sem.

 


/** This less file support OSX/Safari browser compatibility!*/
@import "base";
.__browser_safari {
 … egyedi customizaciok
}

 

Összegzés

 

A NILA sablon az RWD-hez képest nagyon sok javítást és egyedi megoldást hoz, amivel a Magento webáruházunk igazán sikeres lehet. A template-ünket úgy alakítottuk ki, hogy bármilyen webáruhazat gyorsan és könnyen egyedire szabhassunk használatával.

A NILA sablont jelenleg még fejlesztjük és házon belüli kisebb projektekben teszteljük, de hamarosan dobozos formában is elérhető lesz a nagyközönség számára is. Erről pedig természetesen majd itt a blogon értesülhetsz először!

 

Magento (1.9) EAV a gyakorlatban (frontend)

A Magento alatt ez a következőképpen néz ki: 

  • entity tábla (meghatározza az entity-t)
  • attribute tábla (meghatározza a tulajdonságot, annak típusát, egyéb opciókat, pl.: source model, type, input, label)
  • value tábla (ez valójában típusonként szét van választva, többek között az indexelhetőség, keresés miatt pl.: catalog_product_entity_int, catalog_product_entity_varchar stb.)

A tulajdonságokat tárolhatnánk a fő-táblában is, nem?

Az EAV adatmodellben az elemekhez való új tulajdonságok felvitele során nem kell az eredeti entity táblát módosítani, így egyrészt elkerülhetők a túl nagy táblák, ezzel a lekérdezések sebessége is gyorsabb lesz, másrészt pedig a listáknál a felesleges adatok nem jelennek meg, csak amelyeket mi hozzáadunk a collection-höz. A cikk során egy modult fogunk készíteni, admin és frontend felülettel, EAV megoldással.

Miután a webáruházunkat feltelepítettük a szerverre, és konfiguráltuk azt (base url, database name, database user stb.), minden megjelenik rendeltetésszerűen, elkezdjük a fejlesztést.

Modulunk definilásához, az app/etc/modules könyvtárban kell létrehozni egy a module nevével megjelölt xml fájlt. Az én esetemben ez az Aion_Items.xml, a codePool pedig local, de a community codePool-ban is elhelyezhetnénk.

Az xml a következőképpen néz ki:

 

<?xml version="1.0"?>
<config>
    <modules>
        <Aion_Items>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Mage_Core/>
            </depends>
        </Aion_Items>
    </modules>
</config>

 

Ez még nem elég, a module még cache-ürítés után sem fog megjelenni, az admin-felület modul-listájában sem. A következő lépés, hogy az xml-ben definiált modult, a codePool-ban megadott könyvtárban létrehozzuk. Ez ebben az esetben, az app/code mappában jelent egy local könyvtárat (amennyiben még nem létezik), azon belül egy Aion/Items mappaszerkezetet. Tehát a végső elérésünk ebben az esetben app/code/local/Aion/Items.

module_path

 

A következő lépésekben a fő irányadók az általános modulkészítés szabályai, pár eltéréssel. Ha nem jut eszedbe éppen valami, nem szégyen puskázni a Magento core modulok tartalmából :)

Hozzuk létre a modul config.xml fájlt. Haladjunk lépésről lépésre:

 

<?xml version="1.0" encoding="UTF-8" ?>
<config>
    <modules>
        <Aion_Items>
            <version>0.0.1</version>
        </Aion_Items>
    </modules>
</config>

 

Definiáljuk a modellek, resource modellek elérhetőségét, illetve az entity táblá(ka)t a modulunknak. Folytatólagosan a </config> node elé helyezzük el a következőket, közvetlenül a </modules> node után:

 

<global>
    <models>
        <aion_items>
            <class>Aion_Items_Model</class>
            <resourceModel>aion_items_resource</resourceModel>
        </aion_items>
        <aion_items_resource>
            <class>Aion_Items_Model_Resource</class>
            <entities>
                <article>
                    <table>aion_items_article</table>
                </article>

 

Nem zártuk még le az <entities> node-ot, továbbra is ezen belül maradunk, és meghatározzuk a többi, EAV adattáblát, típusonként:

 

            <article_datetime>
                <table>aion_items_article_datetime</table>
            </article_datetime>
            <article_decimal>
                <table>aion_items_article_decimal</table>
            </article_decimal>
            <article_int>
                <table>aion_items_article_int</table>
            </article_int>
            <article_text>
                <table>aion_items_article_text</table>
            </article_text>
            <article_varchar>
                <table>aion_items_article_varchar</table>
            </article_varchar>
            <article_char>
                <table>aion_items_article_char</table>
            </article_char>
        </entities>
    </aion_items_resource>
</models>

 

Majd pedig a helper-ek, block-ok elérése, definiálása következik:

 

<helpers>
    <aion_items>
        <class>Aion_Items_Helper</class>
    </aion_items>
</helpers>
<blocks>
    <aion_items>
        <class>Aion_Items_Block</class>
    </aion_items>
</blocks>

 

Most, hogy a tábláink létre is jöjjenek, szükség lesz az erőforrások megadására, ami az installer és adatbázis-kapcsolat meghatározását jelenti, folytatólagosan a </blocks> alá tehetjük, de az számít, hogy ezek egy szinten legyenek.

 

        <resources>
            <aion_items_setup>
                <setup>
                    <module>Aion_Items</module>
                    <class>Aion_Items_Model_Resource_Setup</class>
                </setup>
            </aion_items_setup>
        </resources>
    </global>
</config>

 

Láthatóan le is zártam a node-okat, a következő lépések az alap helper (ez nagyon fontos(!), e nélkül nem fog működni a modulunk), majd a modellek létrehozása lesz. Az xml-ben megadottak szerinti helyen kell ezeket létrehozni. A modelleket tehát az Aion/Items/Model, a helper-t pedig az Aion/Items/Helper mappában.

A modulhoz tartozó default helper a Data nevet viseli minden esetben, a

Mage::getHelper(‘aion_items’) ezt próbálja meg példányosítani amely egyenértékű a Mage::getHelper(‘aion_items/data’) hívással.

Helperünk tehát az Aion_Items_Helper_Data osztálynevet, Data fájlnevet viseli, és a Mage_Core_Helper_Abstract osztályból származtatjuk.

Hozzuk létre a modelleket, és resource modelleket!

Az <entities> alatt az article-t határoztuk meg, így legyen a modellünk is ez, hozzuk létre az

  • Aion_Items_Model_Article
  • Aion_Items_Model_Resource_Article
  • Aion_Items_Model_Resource_Article_Collection osztályokat.

Mivel EAV adatmodell mellett döntöttünk, így nem a szokásos Mage_Core_Model_Resource_Abstract, és Mage_Core_Model_Resource_Db_Collection_Abstract osztályokból származtatjuk ezeket, hanem az eddigiek sorrendjében a következő osztályokból:

  • Mage_Eav_Model_Entity_Abstract
  • Mage_Eav_Model_Entity_Collection_Abstract

A resource model-ben van még egy kis változás:

 

class Aion_Items_Model_Resource_Article extends Mage_Eav_Model_Entity_Abstract
{
const ENTITY = ‘aion_items_article’;

public function __construct()
{
$this->setType(self::ENTITY)
->setConnection(‘core_read’, ‘core_write’);
}
}

 

Nem véletlenül maradt ki a felsorolásból az első modell (Aion_Items_Model_Article). Ezt továbbra is a Mage_Core_Model_Abstract osztályból származtatjuk, nincs változás. Ha megvannak a modellek, még az installer osztályt kell létrehozni. Ezt már szintén megadtuk a modul alap-konfigurációs fájljában (Aion_Items_Model_Resource_Setup). Hozzuk létre a megfelelő helyen, tartalma pedig legyen a következő:

 

class Aion_Items_Model_Resource_Setup extends Mage_Eav_Model_Entity_Setup
{
    public function getDefaultEntities()
    {
        $entityAttributes = array(
            Aion_Items_Model_Resource_Article::ENTITY => array(
                'entity_model' => 'aion_items/article',
                'attribute_model' => '',
                'table' => 'aion_items/article',
                'attributes' => array(
                    'name' => array(
                        'type' => 'varchar',
                        'label' => 'Name',
                        'input' => 'text',
                        'global' => 0,
                        //this set the attribute to store entity data separated to every store not globally
                        'visible' => true,
                        'required' => true,
                        'user_defined' => true,
                        'visible_on_front' => true
                    ),
                    'customer_id' => array(
                        'type' => 'integer',
                        'label' => 'Customer',
                        'input' => 'select',
                        'global' => 1,
                        'visible' => false,
                        'required' => true,
                        'user_defined' => true,
                        'visible_on_front' => false,
                        'source' => 'aion_items/article_attribute_source_customer'
                    ),
                ),
            )
        );

        return $entityAttributes;
    }
}

 

Ezeket a tulajdonságokat fogja létrehozni a telepítő lefutáskor az entity típushoz. A fenti tulajdonság opciókon felül, természetesen van más lehetőség is, de mivel ezek jelen esetben nem térnek el default értékeitől, nem szükséges megadni.

A customer_id tulajdonságnál látható, hogy megadtuk a source opciót, így ehhez szükségünk lesz egy source modellre. Hozzuk létre tehát a megadott helyen és néven, az app/code/local/Aion/Items/Model/Article/Attribute/Source mappában a Customer.php fájlt, tartalma pedig legyen a következő:

 

class Aion_Items_Model_Article_Attribute_Source_Customer extends Mage_Eav_Model_Entity_Attribute_Source_Table
{
    public function getAllOptions()
    {
        if (!$this->_options) {
            $customers = Mage::getResourceModel('customer/customer_collection')
                ->addAttributeToSort('lastname', 'ASC')
                ->addAttributeToSort('firstname', 'ASC');
            foreach ($customers as $customer) {
                $name = [$customer->getFirstname(), $customer->getLastname()];
                $this->_options[] = ['value' => $customer->getId(), 'label' => join(' ', $name)];
            }
        }
        return $this->_options;
    }
}

 

Ahhoz, hogy ezek után létrehozzuk a táblánkat, már csupán az installerünk kell létrehozni. Ezt a saját modulunk alatti sql, azon belül pedig a <resources> node alatt definiált mappában kell megtenni. Mivel ebben az esetben ez az <aion_items_setup>, így a mappa is  aion_items_setup lesz.

A modulunk config.xml fájljában korábban megadtuk a verziót, <version> node-ban, ez lesz az installer-ünk verziószáma. Hozzunk létre tehát egy install-0.0.1.php fájlt az app/code/local/Aion/Items/sql/aion_items_setup mappában.

Ennek a tartalma a következő:

 

try {
    $this->startSetup();
    $this->createEntityTables('aion_items/article');
    $this->addEntityType(Aion_Items_Model_Resource_Article::ENTITY, [
        'entity_model' => 'aion_items/article',
        'attribute_model' => '',
        'table' => 'aion_items/article',
        'increment_model' => '',
        'increment_per_store' => '0'
    ]);

    $this->installEntities();
    $this->endSetup();
} catch (Exception $e) {
    Mage::logException($e);
}

 

Ha ezzel megvagyunk, készen áll a modul a telepítésre. Mielőtt azonban lefuttatnánk, nézzük meg a mappa- és fájlszerkezetünket, mely a következőképpen néz ki:

 

files_in_module_1

 

 

Hogy modulunk installer-e lefusson, az admin felületen System -> Cache management menüpont alatt, ürítsük a cache-t. Amennyiben sikeresen lefutott az installer, a következő táblákat kell látnunk az alap táblákon felül az adatbáziskban.

 

eav_tables

 

 

Hogy biztosra menjünk, kapcsoljuk be a logolást az admin-felületen az installer futtatása előtt, illetve utána nézzük meg a var/log mappát, exception.log vagy system.log fájlok találhatóak-e benne. Ezenfelül az eav_attribute táblában az attribute_id szerint csökkenőbe rendezve láthatjuk, hogy a customer_id, és name jellemzőink létrejöttek-e, illetve mellette az entity_id mezőben láthatjuk, hányas ID-t kapta az új entity típusunk. Rákattintva meg is tekinthetjük azt.

Ha eddig minden rendben zajlott, csináljunk egy frontend oldalt a modulunknak, hogy letesztelhessük, minden helyesen működik-e. A <global> node alatt, de még a </config> node előtt helyezzük el a következő kód-blokkot:

 

<frontend>
    <routers>
        <aion_items>
            <use>standard</use>
            <args>
                <module>Aion_Items</module>
                <frontName>aionitems</frontName>
            </args>
        </aion_items>
    </routers>
</frontend>

 

A frontend oldali megjelenítéshez szükségünk van még layout, controller, block, és template fájlra. Ugyan ezen <frontend> node alá helyezzük el a layout fájl definiálását:

 

<layout>
    <updates>
        <aion_items>
            <file>aion/items.xml</file>
        </aion_items>
    </updates>
</layout>

 

Ezek után a fájlt hozzuk létre annak helyén (app/design/frontend/rwd/default/layout). Fontos, hogy a modulunkhoz tartozó alap template fájlokat mindig a témához tartozó default alatti layout könyvtárban hozzuk létre, hogy a későbbi módosításkor annak másolatán, ne pedig az eredeti fájlon hajtsanak végre módosításokat. Ugyanez érvényes a template fájlokra is.

 

<?xml version="1.0"?>
<layout version="0.1.0">
    <aion_items_index_index translate="label">
        <label>Aion Items</label>
        <reference name="root">
            <action method="setTemplate"><template>page/1column.phtml</template></action>
        </reference>
        <reference name="content">
            <block type="aion_items/list" name="aion.items.list" as="aion_items_list" template="aion/items/index.phtml"/>
        </reference>
    </aion_items_index_index>
</layout>

 

Ha ez is megvan, jön a template fájl és a block. Template fájlnak az xml-ben az aion/items/index.phtml-t jelöltük meg, így egy szinttel fentebb, az app/design/frontend/rwd/default/template/aion/items mappában helyezzük el az index.phtml fájlt, majd az app/code/local/Acion/Items/Block könyvtárban helyezzünk el egy List.php fájlt amelynek tartalma a következő legyen:

 

class Aion_Items_Block_List extends Mage_Core_Block_Template
{
    /**
     * @return \Aion_Items_Model_Resource_Article_Collection
     * @throws \Mage_Core_Exception
     */
    public function getArticleCollection()
    {
        $articles = Mage::getModel('aion_items/article')->getCollection()
            ->addAttributeToSelect('*');

        return $articles;
    }
}

 

Most térjünk vissza az index.phtml template fájlra, és egyelőre legyen a következő a tartalma:

/** @var Aion_Items_Block_List $this */
$articles = $this->getArticleCollection();
Zend_Debug::dump($articles->getData(),'articles');

 

Hogy megjelenjen a collection tartalma, már csak egy controller-re van szükségünk, hozzuk létre az IndexController.php fájlt az app/code/local/Aion/Items/controllers mappában, az alábbi tartalommal:

 

class Aion_Items_IndexController extends Mage_Core_Controller_Front_Action
{
    /**
     * @return $this
     */
    public function indexAction()
    {
        $this->loadLayout();
        $this->renderLayout();

        return $this;
    }
}

 

Ezután ismét ürítsük a cache-t az admin-felületről, és a frontenden hívjuk meg a modulunkhoz tartozó url-t (a példabeli esetben ez a /aionitems/ ami egyenértékű a /aionitems/index/index/ hívással). Ha minden jól ment, akkor valami hasonlót kell látnod:

 

frontend_display

 

 

Ez eddig szuper, de semmi sem jelenik meg lényegében, hiszen nincs semmilyen adat a táblában. Hogy szemléletesebb legyen a példa, írjunk még egy data-installer-t, hogy láthassuk, működnek-e a jellemzőink is megfelelően.

Az egyik előző képen látható volt egy data mappa, ennek a mappának pontosan ez a szerepe, a nem rendszer-szintű módosításokat ezeken keresztül tudjuk megoldani. Szerkezetben az sql könyvtárhoz kapcsolódik, így ezen belül is szükség van egy aion_items_setup almappára.

A „sima” installer-script-hez képest még annyi eltérés van a működésben, hogy az ezen struktúra alatt lévő fájlokat a Magento egy data- előtaggal keresi.

Tehát az app/code/local/Aion/Items/data/aion_items_setup mappában hozzunk létre egy (mivel már az install-0.0.1.php lefutott) data-upgrade-0.0.1-0.0.2.php nevű fájlt, és az app/code/local/Aion/Items/sql/ mappában szintén egy upgrade-0.0.1-0.0.2.php nevű fájlt. Ez utóbbiban csak megjelöljük, mi történik és hol. Tehát az upgrade-0.0.1-0.0.2.php a következőt tartalmazza:

 

/** @var Aion_Items_Model_Resource_Setup $this */
try {
    $this->startSetup();
    //app\code\local\Aion\Items\data\aion_items_setup\data-upgrade-0.0.1-0.0.2.php
    $this->endSetup();
} catch (Exception $e) {
    Mage::logException($e);
}

 

Az app/code/local/Aion/Items/data/aion_items_setup/data-upgrade-0.0.1-0.0.2.php pedig a következőket tartalmazza:

 

/** @var Aion_Items_Model_Resource_Setup $this */
try {
    $defaultStoreId = Mage::app()->getDefaultStoreView()->getId();
    $attributeSet = Mage::getResourceModel('eav/entity_attribute_set_collection')
        ->addFieldToFilter(
            'entity_type_id',
            Mage::getModel('eav/entity')
                ->setType(Aion_Items_Model_Resource_Article::ENTITY)
                ->getTypeId()
        )->addFieldToFilter(
            'attribute_set_name',
            'Default'
        )->getFirstItem();
    $articles = [
        [
            'store_id' => $defaultStoreId,
            'name' => 'Article name 1',
            'attribute_set_id' => $attributeSet->getId(),
        ],
        [
            'store_id' => $defaultStoreId,
            'name' => 'Article name 2',
            'attribute_set_id' => $attributeSet->getId(),
        ]
    ];
    foreach ($articles as $article) {
        Mage::getModel('aion_items/article')->setData($article)->save();
    }
} catch (Exception $e) {
    Mage::logException($e);
}

 

Ez még nem elég. Ha frissítünk, nem fut le az új installer, de már le sem kell írnom, hogy a cache-t ürítsük :) Ezenfelül pedig ugye még a modulhoz tartozó config.xml fájlban a <version> node alatt szereplő 0.0.1-et növeljük 0.0.2-re, majd frissítsük az oldalt. Ha minden rendben ment (és reméljük, hogy igen), akkor a következőt kell látnod az adatbázisban:

 

data_installed

 

 

Az aion_items_article_varchar táblában pedig külön szerepelnek a nevek az entitásokhoz tartozóan.

 

data_eav_installed

 

Ha minden rendben ment, a frontenden a frissítést követően a következőt láthatjuk:

 

frontend_display_data

 

Összegzés

Azt hiszem, nem mondok nagy butaságot ha kijelentem, hogy az EAV egy nagyon hasznos ugyanakkor  komplex dolog, amire az esetek nagy részében nincs szükség. A többnyire kis, illetve közepes fejlesztések ‒ mivel általában eleve több, egymáshoz kapcsolódó tábláról van szó ‒ nem indokolják ezt a szerkezeti felépítést.

Érdemes azonban ezt már az elején lefektetni, mivel ‒ ahogy a Magento maga is teszi saját ezen struktúrában tárolt adataival ‒ ezeket lehet egy generált, a szükséges adatokat megjelenítő összesítő táblában tárolni (flat). Igen időigényes és költséges lenne egy már meglévő, nagy számú komoly táblaszerkezetet EAV struktúrába átültetni.

 

Külső adatbázisok elérése és egyedi raktárkészletek kezelése Magento-ban

Miről is lesz szó a cikkben?

  • Mi is az az FMCG?
  • Általánosságban pár szó az adatbázisokról
  • Adatbázisok és a Magento
  • Adatbázis típusok és felhasználásuk az FMCG-hez
  • Készlet változások kezelése a Magentoban, kérdések és javaslatok
  • Middleware: Köztes rétegek, MOM rendszerek

Mi is az az FMCG?

Rövid defíníció:

Fast-moving consumer goods vagy consumer packaged goods (CPG), azaz gyorsan forgó fogyasztási cikkek.

Azokat az árucikkeket értjük ez alatt, amelyek viszonylag gyakran, napi, heti vagy havi rendszerességgel újra megvásárlásra kerülnek és viszonylag alacsony árúak.

Ide tartozik például a borotva, papír zsebkendő vagy kisbabások esetén a nedves törlőkendő és a pelenka, de lehet szó a kötszerekről vagy a ragtapaszról is.

 

 Adatbázisok

Rövid defíníció:

Az adatbázisok azonos minőségű, strukturált információk összessége, amelyet tárolásra, szerkesztésre és lekérdezésre alkalmas adatbázis-kezelő alkalmazás kezel. Az adatbázisok célja az adatok megbízható, hosszú távú tárolása és viszonylag gyors visszakeresés biztosítása.

Az adatbázisokat két nagy csoportba érdemes bontani, a logikai és a fizikai adatbázisokra. A logikai adatbázisokat felépítésük, működésük és sajátosságaik alapján szokás megkülönböztetni a fizikai adatbázisoktól. Adatmodellekkel reprezentáljuk őket és a korszerű adatbázisoknál a fizikai adatbázist több logikai adatbázison keresztül is elérhetjük, mintha egyfajta burkoló rétegeket képeznének a tárolt adatok elé.

A Magento adatmodelljei (model) és gyűjteményei (collection) pontosan egy ilyen logikai adatbázist képeznek le a fizikai adatbázis elé, hogy megkönnyítsék és érthetőbbé tegyék az adatok feldolgozását. Az adatmodellekről, gyűjteményekről részletesebben olvashatsz ebben a cikkünkben: Magento 2 modul fejlesztés lépésről lépésre – 1. rész

 

magento külső adatbázis, modellek közti összefüggés

Fogalmi, logikai és fizikai modell összefüggése

 

Adatbázisok és Magento

A webáruházak és manapság minden alkalmazás egyik legfontosabb része az adatbázis, melyek üzemeltetése, karbantartása és fejlesztése hatalmas összegekbe kerül. Az adatbázisok lehetnek elosztottak is, mivel a Magento webshop logikai adatbázisa beburkolja a kapcsolatot, így csökkenthetjük a költségeinket és a megfelelő adatokat a megfelelő helyeken kezelhetjük.

A Magento emellett képes egyszerre több különböző adatbázist is kezelni, melyekhez a PDO-t használja, így Cubrid, FreeTDS / Microsoft SQL Server / Sybase, Firebird, IBM DB2, IBM Informix Dynamic Server, MySQL 3.x/4.x/5.x, Oracle Call Interface, ODBC v3 (IBM DB2, unixODBC és win32 ODBC), PostgreSQL, SQLite 3 és SQLite 2, Microsoft SQL Server / SQL Azure, 4D alapú kapcsolatokat könnyedén kiépíthetünk benne.

 

Többszörös adatbázis-kezelés

Ahhoz, hogy egyszerre több adatbázist is kezelni tudjon a Magento webáruházunk, csupán elegendő a modulunk config.xml konfigurációs állományba felvenni az új adatbázis elérhetőségének paramétereit (host, username, password, dbname), valamint a connection > use-ban meghatározni a kapcsolat azonosítóját.

Ezzel a kapcsolatnak már nincs szoftveres akadálya, ha a hálózaton keresztül a host elérhető, akkor a kapcsolat létrejön. A fejlesztőknek ezután már csak a logikai adatbázist (model, collection) kell létrehoznia, hogy az adatok áramlása zökkenőmentes legyen.

 

Adatbázisok: Állomány alapú források

A tapasztalatok azt mutatják, hogy a legtöbb esetben egyszerű (csv) vagy összetett (xml, json) forrás állományok állnak a felhasználók birtokában. Ezek az állományok tartalmazzák a teljes termékkínálatot, a felhasználói adatokat vagy akár a rendeléseket is. A Magento is lehetőséget biztosít ezen adatok exportálására, egészen könnyedén az adminisztrációs felületről.

 

magento külső adatbázis, skálázhatóság

 

Előnyei

  • Könnyen kezelhetőek
  • Könnyen módosíthatóak
  • Az ember számára viszonylag könnyen olvasható formátum
  • Exportálási lehetőség elérhető, nem indokol fejlesztést

 

Hátrányai

  • Szerkesztéskor nagy a hibalehetőség, amivel a teljes állomány szerkezete felbomolhat
  • Rekordok szerkesztése nehézkes
  • Az állományok kódlapjának beállítása adattorzulást okozhat
  • Importálásnál a teljes adatmennyiséget feldolgozzuk
  • Nem frissül automatikusan

 

Adatbázis-kezelő rendszerek

Az állomány alapú forrásokhoz képest itt annyi a különbség, hogy egy adatbázis-kezelő rendszeren keresztül érjük el adatainkat. Az adatbázis-kezelő áthidalja az állományok kezelése okozta hátrányokat, hiszen jól értelmezhető logikai adatmodelleket kínál erre. A fizikai adatfüggetlenség biztosítására az adatbázis-kezelő motortól független állományszervezési rendszereket dolgoztak ki, hogy a háttértár szervezése illetve eszköz függetlensége biztosítva legyen.

Az adatmodellek alapján megkülönböztethetünk relációs, objektumorientált, hálós, deduktív, objektumrelációs, deduktív relációs, deduktív objektumorientált adatbázis-kezelőket.

 

Háttértár szervezések

  • Optikai
  • Lyukszalagos
  • Mágnesszalagos
  • Merevlemezes
  • Memória-adatbázis

 

Előnyei

  • Felhasználói felület az adatokhoz
  • SQL általános nyelvből alakultak ki a lekérdező nyelvek
  • Funkcionalitás bővíthető
  • Elosztott rendszerek megvalósíthatóak

 

Hátrányai

  • Bonyolultak: Logikai, halmazkezelési ismeretek szükségesek
  • Lekérdező nyelvet ismerni kell
  • Nő az adattároláshoz és az adatbázis kezelőhöz szükséges tárterület szükséglet.

 

Adatbázisok: Szolgáltatás alapú források

A szolgáltatás alapú források alá tartoznak azok az adatbázis elérések, melyeket egy interfészen keresztül érhetünk el egy másik szerveren, mely akár a világ másik felén is lehet. Még a mai napig is leginkább SOAP protokollon keresztül vagy a fejlesztéseknek hála, valamilyen REST szolgáltatáson keresztül tudjuk az adatokat elérni és manipulálni.

A SOAP interfészen keresztül történő elérés legnagyobb hátránya, hogy az interfész bonyolult és részletes, szemben a REST interfésszel, mely sokkal egyszerűbb és kényelmesebb. A biztonság szempontjából a SOAP kliens volt korábban a megbízhatóbb, azonban az SSL kapcsolatokkal és egyéb titkosítási algoritmusokkal most már azonos megbízhatósági szintre került a két interfész.

A mobil alkalmazások fejlődési iránya azt mutatja, hogy szolgáltatás alapon érik el a távoli adatbázisokat, leginkább REST kliensként, mivel az adatbázisok méretei miatt ezek készüléken elhelyezése és feldolgozása hardver- és szoftverteljesítmény szempontjából sem lenne ideális.

 

Előnyei

  • Teljesítmény: Kisebb teljesítmény is elegendő az alkalmazás futtatásához
  • A REST alapú szolgáltatások interfésze egyszerű (HTTP kérések), jól érthető és kicsi erőforrásigényű a JSON alapú formátum könnyen kezelhető, akár már frontend szinten is.
  • A SOAP protokoll dokumentáltsága és hibajelzése kiforrottabb
  • Az általános biztonság SSL tanúsítványokkal megvásárolható

 

Hátrányai

  • A SOAP alapú szolgáltatások interfésze összetett, bonyolult, a fejlesztések drágák és az XML formátum miatt nehézkes a feldolgozása
  • A hálózati kommunikáció bizonytalanságai miatt lassú, elérhetetlen lehet
  • A hálózati kommunikáció miatt a biztonság nem 100%-os, további titkosítási algoritmusokra lehet szükség

 

 

magento külső adatbázis rest, soap

 

Adatbázisok: Külső alkalmazás források

A vállalatirányítási rendszerek adatbázisai nem különülnek el a külső adatbázisoktól, azonban mégis összetettebbek, nagyobbak (méret) lehetnek, mint más célirányosan összerakott adatbázisok. Mivel ezek az adatbázisok vállalatirányítási feladatokat látnak el, így folyamatosan frissülnek, változnak és bővülnek. Éppen ezért összetett interfészekkel rendelkeznek a külső rendszerek számára, melyek integrációja a közepestől a nagy bonyolultságú feladatig terjedhet.

Szerencsére a legtöbb ERP, CRM és PIM rendszer rendelkezik olyan modullal mely telepítése és minimális konfigurációja révén biztosítja a webáruházunkkal történő összekötést. Nagyon fontos, hogy ezen rendszerek között ajánlott az azonnali, kétirányú kommunikáció kialakítása, hogy a lehető legkevesebb emberi erőforrást kelljen az adminisztrációs munkára fordítani.

 

Előnyei

  • A kommunikáció lehet teljesen automatizált, így az adminisztrációs feladatok jelentősen csökkennek
  • Egy rendszert elegendő megtanulni kezelni és figyelni
  • A legismertebb rendszerekhez történő integráció gyors és zökkenőmentes
  • Fejlett felhasználói interfésszel rendelkeznek
  • Több protokollon vagy interfészen keresztül is képesek kommunikálni

 

Hátrányai

  • A rendszerek közötti kommunikáció keresztmetszete
  • A rendszerek közötti kommunikáció hiánya esetén adatvesztés
  • Kétirányú kapcsolat és/vagy aszinkronitás nélkül túl nagy emberi erőforrásra van szükség

 

Termék- és készletváltozások

Az FMCG esetén kritikus tényező a termék- és készletváltozások azonnali, legalább naprakész frissítése. Hiszen, ha egy új termék érkezik az áruházba, annak nem biztos, hogy fontos azonnal eladhatónak lennie a webáruházban, de ha elfogy egy termék készlete, akkor azt azonnal jelezni kell a vásárló felé vagy leadni a rendelést a beszállító, raktár vagy gyártó felé.

Ez a szinkronizáció ideális esetben kétirányú, azaz mindkét oldal képes jelezni a másik oldalnak, hogy az adatok megváltoztak és automatikusan az üzleti logikának megfelelően frissíteni az adatbázisokat. Ez még két rendszer esetén is bonyolult fejlesztést igényel mind a webáruház, mind az adatbáziskezelő alkalmazás részén, de vannak olyan esetek is, amikor egy ERP, egy PIM és több webáruház összekötése a feladat.

 

Mit lehet ilyenkor tenni?

 

Első és talán legfontosabb kérdés, hogy mekkora adatmennyiségeket szeretnénk mozgatni? A teljes termékkészletet, termékeket, megrendeléseket és vevői információkat frissíteni akarjuk? Elegendő időszakosan, várólistás (queue) megoldással az adott időszakban éppen aktuális változásokat frissíteni? Azonnal frissíteni kell minden változást a rendszerek adatbázisai között?

A fenti kérdések mind-mind kulcsfontosságúak, hogy meghatározzuk, milyen szintű integrációra van szükség. Egy sekély integrációnál lehet, hogy elegendő egy napi csv/xml állomány alapú importálás a külső rendszerből a webáruházba, akár ezt automatizálva futtatni. Közepes szintű bonyolultság a várakozó listás megoldás, ahol egyik vagy másik oldal is egy sor-szervert használ a frissítésre. A mély integrációnál pedig már akár köztes rétegben történik az adatok szinkronizációja.

Az alább felsoroljuk a különbségeket az egyes módszerek között, röviden ismertetve, hogy melyik mivel járhat és mennyire komplex a fejlesztési listában.

 

1.1. Teljes adatok cseréje

Az adat mennyiségek mozgatása és frissítése szempontjából a teljes adatok cseréje az úgynevezett fapados megoldás. A termékek, megrendelések mennyisége fontos szempont ebben az esetben, mivel több tízezer termék esetén az ilyen frissítés már akár percekig is eltarthat, ami kiesést vagy termék elérhetetlenséget jelenthet a webáruházban. Éppen emiatt csak abban az esetben javasoljuk ezt a megoldást, ha a termékek vagy készlet információk frissítése viszonylag rövid ideig tart vagy jól időzíthetően az áruház forgalmához az esetlegesen elhúzódó frissítés.

 

1.2. Részleges adatok csere

A részlegesadat-kommunikáció akkor jöhet szóba, ha többször az áruház működése alatt is frissíteni kell a termék-, készlet- vagy rendelési információkat. Az időzített megoldások mellett, melyek pontatlansága okozhat problémát az azonnali szinkronizáció is szóba jöhet, mivel a kisebb mennyiségű adatkommunikáció gyorsan végrehajtódik a rendszerben.

A készletkezelés és az FMCG típusú áruházak integrációs megoldásai pontosan ide tartoznak, mivel nem a teljes termék, csupán a darabszámok változnak.

 

2.1. Adatok áttöltésének iránya: egyirányú, kétirányú

Viszonylag egyszerű kérdés, azonban ha jobban átgondoljunk, további kérdéseket vet fel, ráadásul az integrációs költségek növekedése mellett az adatkommunikáció mennyiségét is jelentősen növelheti.

Egyirányú adatkommunikációról akkor beszélünk, ha van egy kiválasztott (master) rendszer – mondjuk egy ERP –, amelybe minden másik külső rendszer, azaz például a webáruházunk is beküldi az adatokat. A fő rendszer (ERP) pedig feldolgozza és tárolja őket, az ERP-t használó adminisztrátorok pedig a kapott adatok alapján irányítják a vállalati folyamatokat.

Kétirányú kommunikáció esetén mindkét rendszer kommunikál a másikkal és egymástól függően vagy függetlenül megadott interfészeken keresztül küldik el az adatokat. Itt már nincs alá- és fölérendelt szerep, csupán a prioritásokat kell megfelelően meghatározni vagy sorszerverekkel vezényelni a változások kezelését.

Az ERP integráció megtervezéséről ebben a cikkünkben olvashatsz: Magento ERP integráció: hogyan készítsük elő hibák nélkül

 

3.1. Adatok közvetett áttöltése

Az adatok áttöltését lehet közvetetten (manuális vagy ütemezett módon) vagy közvetlen (API interfészeken keresztül) frissítéssel megoldani. Az időszakos áttöltésnél szóba jöhet az emberi beavatkozás, aki az egyik rendszerből átemeli az adatokat a másik rendszerbe.

Ez történhet egyszerű export-import folyamatként, ahol az adatok egy állományba kerülnek mentésre (export), majd ezt az állományt a másik rendszer erre kialakított interfészén keresztül betölti az adatbázisba (import). Ez a folyamat természetesen automatizálható, ha az adott alkalmazás által kimentett adatokat a másik rendszer meghatározott időközönként (pl. cronjob) automatikusan betölti az adatbázisába.

Láthatjuk, hogy ez a módszer még az emberi tényező kivonása mellett is lassú, pontatlan és emiatt nem eredményes az FMCG szempontjából, azonban más esetekben, ahogy tapasztaltuk, elegendő lehet.

3.2. Közvetlen információcsere

Az adatok közvetett áttöltése nem éppen a legjobb megoldás a raktárkészletek kezelésére, hiszen a termékek darabszámának változását érdemes minél pontosabban szinkronizálni, így a közvetlen információcsere lehet a kézenfekvő megoldás. Ahhoz, hogy ez megvalósuljon, sokféle technológia áll a rendelkezésünkre, a Magento beépített XmlConnect, API (SOAP vagy REST) megoldásai mellett a legtöbb külső alkalmazáshoz már kész modulokat vásárolhatunk a Magento Connect-ből.

Kétségkívül az egyik legjobb megoldás, hiszen az adatok szinkronizálása azonnal, a változások bekövetkezésekor megindul, azonban, ha speciális külső alkalmazásunk van, melyhez még nincs konnektor (Magento modul), akkor az integrációs költségek jelentősen megugranak. Ne feledjük el, hogy az automatikus, azonnali megoldásokhoz az esetek nagyobb hányadában mélyintegrációra van szükség, mely a korábban leírtak szerint mind időben, mind fejlesztési költségekben nagy.

 

3.3. Automatikus vagy kézi szinkronizáció

Az előzőekben már szóba került, hogy emberi erőforrásokkal is megoldható az adatok szinkronizálása az alkalmazásaink között és ennek automatizálása is megoldható, azonban ezek az időszakos adatkommunikációk meglehetősen megnehezítik a készletek szinkronizációját. Automatikus szinkronizáció alatt itt azt az időzített feladatot értjük (pl.: cronjob), amikor a folyamatot a rendszer indítja, de helyette akár egy ember is meg tudja oldani. Ezek a jelentősen olcsóbb megoldások.

 

3.4. Aszinkron, azonnali megoldások

Az aszinkron megoldásokkal jelentősen gördülékenyebbé tehetjük a készlet- és adatszinkronizációt az alkalmazásaink között. A végtelenségig azonban még így sem lehet egyszerűsíteni a folyamatokat, hiszen az üzleti igények kötött függőségei miatt az aszinkronitás csak bizonyos feladatok vagy részfolyamatok esetén vezethet hasznos eredményre. Az azonnali adatkommunikáció pedig pontosan ugyanezen függőségek miatt nem valósítható meg 100%-osan.

A legjobb, legtisztább és egyben a legbonyolultabb megoldások közé tartozik, jelentős fejlesztési idővel és költségekkel, így ezt csak akkor érdemes választanunk, ha valóban indokolt a webáruházaink esetén.

 

Köztes réteg: Middleware, MOM

A köztes réteg (middleware), mint megoldás a készlet- és adatkommunikáció szinkronizációja az egyik leginkább fejlődő és jelenleg a legmodernebb technológiai megoldás, mind hardver, mind szoftver téren. Egy olyan megoldásról (szoftver és hardver) beszélünk, mely az alkalmazásaink közé ékelődve külső beavatkozás nélkül, az előre meghatározott üzleti logika alapján megvalósítja az adatkommunikációt.

 

magento külső adatbázis middleware

 

Tulajdonképpen egy félig intelligens rendszer, melyen keresztül az adatok áramlanak és eljutnak egyik alkalmazásunkból a másikba, attól függően, hogy éppen mely üzleti folyamat, mely részén tartanak.

Tekinthetünk úgy rá, mint egy hatalmas labirintusra, melynek egyes ki- és bejáratainál az alkalmazásaink találhatóak és az adatok a labirintuson keresztül jutnak el a másik alkalmazás kapujához, hogy közben a falakon lévő szabályokat követik. Az áthaladás közben az adatok átalakulnak a kívánt formátumba és a fogadó félnek megfelelő adatstruktúrát veszik fel, így nincs szükség alkalmazásainkban az adatok transzformálására.

Ezek a köztes szoftverek külön szerverekből állnak, olyan kiegészítő technológiákkal, mint az Üzenetorientált köztesréteg (Message Oriented Middleware), Redis memória alapú gyorsítótár és egyéb szoftveres és hardveres megoldások a köztes réteg támogatására. A köztes rétegek ma már a felhőben helyezkednek el, memória-alapú szervereken, melyek API interfészei a legtöbb webáruházhoz illeszkednek. A piacon már elérhetőek kész megoldások, melyekkel könnyedén integrálhatjuk rendszereinket és összehangolhatjuk a folyamatainkat az egyes rendszerekben.

Ezek a megoldások az általános üzleti folyamatokra épülnek, és többé-kevésbé személyre szabhatóak, azaz jól illeszkednek az általános, nem speciális üzleti igényeket kiszolgáló webáruházakhoz. Vegyük azonban figyelembe, hogy ha az üzleti folyamataink speciálisak és eltérnek az adott alkalmazás általános üzleti folyamataitól, akkor az integráció is egyedileg, személyre szabottan fog ideálisan működni.

 

magento external databases connection fmcg infographics

Konklúzió

Az FMCG kezelésére rengeteg megoldás létezik és ezekből a számunkra megfelelő megoldásokat kiválasztva egy olyan optimális rendszert építhetünk fel, mely kiszolgálja Magento webáruházunkat. A döntés szempontjából fontos kritériumokat a fentiek alapján meg tudjuk határozni, így ki tudjuk választani a kézenfekvő megoldást.

Ne feledjük el azonban, hogy a hosszú távú célok és az adott piaci szegmens ismerete nélkül, ha a legegyszerűbb és (nem biztos, hogy) a legolcsóbb megoldás választjuk, könnyen megeshet, hogy az integrációs költségeket többször is meg kell majd fizetnünk.

Ha bizonytalan a döntésben, írjon nekünk vagy hagyjon kommentet, és segítünk kiválasztani a megfelelő technológiát és megoldást, ezzel jelentős költségeket megtakarítva cégének.

 

Magento ERP integráció: hogyan készítsük elő hibák nélkül

 

Egy ilyen rendszer legkritikusabb részei a következők:

  • A) az ERP szoftver
  • B) az e-kereskedelmi platform
  • C) a közöttük felépülő adatáramlási séma
  • D) az adatkapcsolat implementációja

 

Cikkünkben a rendszer-integráció szempontjából a Magento e-kereskedelmi rendszert fogjuk megvizsgálni, amely véleményünk szerint a kis- és középvállalkozások számára az egyik legmegfelelőbb e-kereskedelmi platform. Ezt az alábbiakban számos érvvel igyekszünk majd alátámasztani.

Ami az ERP (Enterprise Resource Planning – Vállalatirányítási információs rendszer) oldalát illeti, itt a megítélés szempontjából az e-kereskedelmi rendszerhez való integrálhatóság csak egy szempont a sok közül, de alapvető elvárásnak tekinthető egy aktívan fejlesztett, moduláris, bővíthető ERP rendszer, amely igazodik a vállalkozás igényeihez és anyagi lehetőségihez, és amely támogatja a más rendszerekkel, különösen az e-kereskedelemmel való integrációt. Külön előny, ha az ERP szoftver megfelelően dokumentált, bővíthető API-val rendelkezik.

 

Az alábbiakban alapvetően a következő kérdést igyekszünk körüljárni:

Milyen folyamatokat, hogyan lehet és érdemes szinkronizálni a Magento és egy ERP rendszer között?

 

A következő témákat fogjuk érinteni:

Üzleti szempont – az e-kereskedelem szerepe a vállalkozásban

  • Integráció – Miért?
  • Központi vezérlés
  • Méretbeli szempontok
  • A növekedés hatásai – egyre inkább középpontban az ERP

 

A webáruház-dilemma – miért a Magento?

  • Számtalan funkció és beállítási lehetőség
  • API (Application Programming Interface)
  • Kulcsra kész integrációs megoldások

 

Az ERP-oldal

  • ERP: belső folyamatok összehangolása
  • A rugalmasság ára
  • ERP – felhő vagy saját szerver?
  • API és ERP

 

Az Integráció

  • Elmélet: Adatfolyam-modell
  • Gyakorlat: Megvalósítási lehetőségek
  • Hogyan válasszunk?

 

Mit kérdezzünk egy rendszerintegrátortól?

  • Megbízhatóság: Hogyan garantált az integráció megbízhatósága?

 

 

 

Üzleti szempont – az e-kereskedelem szerepe a vállalkozásban

 

Integráció – Miért?

Mérettől függetlenül minden vállalkozásnál, akár egy mellékállásban üzemeltetett webshopnál is néhány termékkel, előbb-utóbb felmerül az igény, hogy optimalizáljuk és automatizáljuk a monoton, ismétlődő munkafolyamatokat. Ezzel időt és pénzt takarítunk meg, csökkentjük a hibázás lehetőségét, megsokszorozzuk a képességeinket és sok fejfájástól kímélhetjük meg magunkat és kollegáinkat. Az az egyik ok, amiért célszerű a az általunk használt rendszereket integrálni. A különböző rendszerek különféle feladatokra vannak optimalizálva, erőforrás-kezelési célokra való az ERP-k, kapcsolatkezelésre a CRM-ek, e-mail küldésre az e-mail marketing szoftverek. Ha mindenből a legjobbat szeretnénk használni, nincs más választásunk, mint integrálni.

A integráció óriási előnye, hogy csak egyszer, egy helyen kell egy feladatot elvégezni, és munkánk eredménye a többi kapcsolt rendszerbe automatikusan átkerül.

Az integrációval szemben persze alapvető követelmény, hogy zökkenőmentesen és automatikusan működjön. Talán említeni sem kell, kevéssé hasznos az integráció abban az esetben, ha több problémával jár, mit ha az integrálandó feladatokat külön-külön végeznénk el.

 

Központi vezérlés

A leghatékonyabb megoldás tehát dedikált rendszereket alkalmazni úgy, hogy csak egyetlen központi helyen kelljen egy-egy feladatot elvégezni vagy adatokat kezelni. Bárhol is keletkezzenek például a rendelések, online vagy offline, legjobb, ha mindig az ERP-ben kezeljük őket.

Ugyanígy, ha a termékeket már egyszer már importáltuk, beáraztuk, konfiguráltuk az ERP rendszerünkben, bizonyára nem szeretnénk ugyanezt még egyszer megtenni a webáruházunkban. Mindig lehet persze kompromisszumokat kötni, példálul a termékeket kötegelve importálni az ERP-be majd hasonló képpen a webáruházba, és utána csak a raktárkészletet szinkronizálni az ERP-ből, de ahhoz, hogy megfelelő következtetésekre jussunk, elméletben és gyakorlatban koncentráljunk most csak egyaránt ideális működésre, és tekintsünk el az esetleges implementációs nehézségektől, várható költségektől és technikai problémáktól.

 

Méretbeli szempontok

Könnyű belátni, hogy minél nagyobb egy cég e-kereskedelmen kívüli része, annál több dolgot célszerű elvégezni az ERP rendszerben és az így keletkezett adatokat szinkronizálni a Webáruházba. Ugyanakkor minél kisebb egy vállalkozás nem e-kereskedelemmel foglalkozó része, annál kevesebb dolgot érdemes a Magentón kívül kezelni, hiszen a Magento már eleve rendelkezik alapvető ERP funkciókkal: készletkezeléssel, bizonyos országokban hivatalosan is elfogadott számlázási megoldással, és szállításkezeléssel.

 

magento ERP integráció nagy cégek

 

Egy csupán néhány terméket árusító kezdő vállalkozás például praktikusan először csak a számlázási rendszerét szeretné integrálni: elég a megrendeléseket leszinkronizálni a webshopból és minden mást továbbra is kényelmesen lehet a Magentón belül intézni.

Egy több raktárral és áruházzal rendelkező üzletlánc vagy egy globálisan szállító nagykereskedő viszont adott esetben gyorsan változó raktárkészletét, árazási, számlázási és szállítási adatokat és üzleti folyamatait eleve a maga ERP rendszerben kezeli, így e-elengedhetetlen, hogy az e-kereskedelmi megoldása teljes körűen integrálódjon ahhoz – így adott esetben még arra se legyen szükség, hogy be kelljen lépni az integrált webáruház admin felületére, kivéve esetleg ha a webshop felhasználói felületet, online ajánlórendszer beállításait kell módosítani.

Az ERP szempontjából ugyanez vonatkozik a webshop mellett minden más integrált rendszerre: CRM, BI, e-kereskedelmi marketing, 3PL stb. Minél szerteágazóbb egy kereskedő tevékenysége, annál kevésbé praktikus ezeket a rendszereket — tulajdonképpen áttételesen — az e-kereskedelmi platformmal összekötni, és annál ésszerűbb őket szinkronizációs szempontból az ERP köré építeni, ahol az adatokat tulajdonképpen kezeljük.

 

magento ERP integráció kis cégek

 

A növekedés hatásai – egyre inkább középpontban az ERP

Az e-kereskedelmi integráció, illetve az integráció aranyszabálya az arra való törekvés, hogy egy műveletet a legalkalmasabb, központi helyen végezzünk el, és a változásokat ebből a forrásból terjesszük el a többi kapcsolódó rendszerbe.

 

 

A webáruház-dilemma – miért a Magento?

 

Számtalan funkció és beállítási lehetőség

A Magento-t a kezdetektől fogva arra tervezték, hogy a maximumot nyújtsa mint dedikált e-kereskedelmi platform. A nyílt forráskód, a számtalanféle termékbeállítás, vásárlói csoportok, árszabályok, a szűkítő keresés, fizetési és szállítási integrációk, importálási és exportálási lehetőségek egyedivé teszik a piacon.

 

API (Application Programming Interface)

A Magento talán legkiemelkedőbb előnye, hogy fejlett API-kat tartalmaz, melyek a legtöbb beépített funkcióhoz hozzáférést nyújtanak. Technikai szempontból a Magento a következő API-kkal rendelkezik: SOAP API v1, v2, XML-RPC, REST és XMLConnect mobil alkalmazásokhoz. A Magento API-k jól dokumentáltak, amellett az integráció szempontjából óriási előnyük, hogy bővíthető, moduláris felépítésűek.

 

Kulcsra kész integrációs megoldások

Végül, de nem utolsó sorban, a Magento számtalan rendszerhez már eleve integrálva van. a A piacon több tucatnyi kulcsra kész integráció közül választhatunk, köztük az olyan vállalati szintű rendszerekkel, mint a SAP, Microsoft NAV, Sage, NetSuite stb.

 

 

Az ERP-oldal

 

ERP, a belső folyamatok összehangolása:

Az ERP rendszereket alapvetően olyan üzleti folyamatok összekapcsolására és egységes kezelésére fejlesztették ki, mint a pénzügyek, fizetési műveletek, számvitel, számlázás, gyártás, emberi erőforrások, munkafolyamat-kezelés, minőség-ellenőrzés, beszerzés, ellátási lánc irányítás, raktározás, raktárkészlet-kezelés, ügyfélkapcsolat-kezelés stb.. Az ERP rendszerek, azáltal, hogy összekötik az adatokat és a folyamatokat, javítják a minőséget, hatékonyságot, kollaborációt, monitorozást és döntéshozást a vállalaton belül.

 

A rugalmasság ára

Az ERP rendszereket mindig az adott cég igényeire kell szabni, illetve konfigurálni, így a rugalmasság minden igazi ERP génjeibe van kódolva. Minél rugalmasabb és minél inkább testre szabott azonban egy ERP, annál nehezebb egy másik rendszerrel összekötni. Különösen igaz ez akkor, ha a másik rendszer is olyan összetett, mint amilyen a Magento, és a rendszerek összekötésénél a belső folyamatok sajátságaira is tekintettel kell lenni.

 

ERP – felhő vagy saját szerver?

Napjainkban fénykorukat élik a különféle felhőalapú szolgáltatások, és nincs ez másként az ERP-k világában sem. A felhő alapú szolgáltatások számos nyilvánvaló előnnyel rendelkeznek, melyek közül a legfontosabbak a gyors telepíthetőség, alacsonyabb működtetési összköltség, megbízhatóság, nyílt, átlátható frissítések és fejlett API-interfész. Mindez a felhőalapú ERP rendszereket igen versenyképessé teszik a középvállalatok körében.

A felhő alapú szolgáltatók különös figyelmet fordítanak arra, hogy rugalmas API-felületet biztosítsanak ügyfeleiknek; funkcionális API nélkül nehéz egy felhő alapú szolgáltatást elképzelni, ami remek alapja lehet az e-kereskedelmi integrációnak is.

A saját szerverre telepített ERP-k, közép- és nagyvállalatok számára viszont igen nagy szabadságot, jobb irányítási lehetőséget, adatbiztonságot kínál, valamint az egyedi igények átfogóbb kiszolgálását nyújtja a kereskedőnek.

Egy kisebb vállalkozásnak tökéletesen megfelelő megoldás lehet egy kompakt ERP rendszer is, hozzá tartozó támogatással akár az irodai számítógépeken, akár közeli adatközpontban üzemeltetve. Az e-kereskedelmi integrációhoz ilyen esetben azonban valószínűleg erősen egyénre szabott megoldásra van szükség.

 

API és ERP

Az ERP rendszerek egyik történelmi hiányossága, hogy mivel kifejlesztésükkor az elsődleges szempont a belső modulok integrációja volt, a külső rendszerekkel való szabványos kapcsolódás kérdése gyakran csak a második fázisban került elő.

Ez a trend gyorsan változik, és a napjainkban széles körben alkalmazott felhőalapú szolgáltatások világában a fejlesztő cégek egyre inkább felismerik a teljes körű összekapcsolhatóság értékét.

A teljes körű integrálhatóság jól dokumentált, robusztus, teljesítmény-optimalizált API-t jelent, mely a rendszer funkciónak egészét lefedi. Az API-k két fő működést valósítanik meg:

  • üzleti logika, amely az ellenőrzött adatcserén keresztül lehetővé teszi a belső folyamatok elérését,
  • standard és documentált interfész, amely az üzleti logikára épül.

Mindkettő igen lényeges. A régebbi  ERP rendszerek közül sok csupán adatbázis vagy fájl/dokumentum alapú elérést tesz lehetővé, így ha ilyen rendszereket kell integrálni, maga az adatkapcsolat megvalósítása is nagy kihívást jelenthet.

Néhány ERP saját, integrált webshop modult is tartalmaz. Amennyiben az integrációt valamilyen jól dokumentált API felület segítségével alakították ki, akár az ERP, akár az e-kereskedelmi oldalán, lehetőség nyílhat a beépített webshopot az eredeti API felület megtartása mellett jobbra cserélni.

 

Az Integráció

 

Amint megtaláltuk céljainknak megfelelő ERP rendszert és e-kereskedelmi platformot, nincs más hátra, mint összekötni őket. Itt szeretnénk azért megjegyezni, hogy amikor akár technológiaváltás vagy új üzletág bevezetése miatt új ERP-t (vagy Webshopot) keresünk, érdemes előre meggyőződni arról, hogy a rendszerek megfelelően összekapcsolhatók egy hozzáértő partner és alkalmas technológia segítségével.

 

Elmélet: Adatfolyam-modell

Az ERP-webáruház integrációról, illetve általában a rendszerintegrációról szólva érdemes áttekinteni néhány tervezési szempontot.

 

Adatáramlás – forrás és cél

Ez az adatfolyam-modellezés legkönnyebben megérthető, legáltalánosabb szintje. Az egyik rendszerben keletkezett vagy frissített adatot át akarjuk vinni egy másik rendszerbe. Ezen a szinten mellékes, hogyan végezzük ezt el, van-e különbség az adatformátumban, mellékesek az adatátviteli csatornák, csak annyit tudunk, hogy szükségünk van a műveletre. Ilyen például, hogy ha egy termékjellemző frissül az ERP-ben, akkor ezt a változást át akarjuk vinni a webshopba is.

 

Időzítés – mekkora késés elfogadható?

Miután megterveztük az adatáramlási sémát, vagyis hogy mikor milyen adatokat akarunk A-ból B-be, ill. B-ből A-ba szinkronizálni, fontos felmérni, hol van szükség azonnali – vagy inkább minimális késéssel megvalósított – frissítésre és hol tolerálhatók nagyobb késések.

Néhány rendszerben például a termékkészlet nagyon sűrűn változik; ilyenkor gyakran elvárás, hogy a készletadatok a webshopban is minél frissebbek legyenek. A legoptimálisabb megoldás ilyenkor, ha az a rendszer kezdeményezi közvetlenül a frissítést, ahol a változtatás történik, de bizonyos esetekben az is elfogadható alternatíva, ha a céloldali rendszer gyakori státuszellenőrzéseket végez.

 

magento ERP integráció összekötés

 

Szinkron vagy aszinkron

Az időzítés egy másik szempontja a szinkronicitás. Egy rendszeren belül két művelet szinkron folyamat, ha a rendszernek várnia kell egy hívás – akár helyi, akár pedig távoli hívás, pl. adatátvitel – eredményére vagy befejezésére ahhoz, hogy a következő műveletet elvégezhesse.

Az aszinkron I/O esetében a rendszer tétlen várakozás helyett valami más, hasznos dolgot végezhet, és csak akkor tér vissza az eredeti művelethez, mikor a hívás befejeződött. A blokkoló jellegű függőség bizonyos hívások közt olykor elkerülhetetlen, de az adatáramlási sémában, amikor csak lehetséges, érdemes kiiktatni ezeket a szekvenciális függőségeket, és az adatáramlást alapvetően aszinkronná tenni.

Megfelelően alkalmazva az aszinkron folyamatok sokkal hatékonyabban működnek, és kevésbé hajlamosak szűk keresztmetszeteket, „adatforgalmi dugókat” előidézni. A hibatűrés fokozása és a robusztusság érdekében azonban még az aszinkron folyamatok esetén is ajánlatos a hívások sikeréről visszajelzéseket gyűjteni és azokat monitorozni.

 

Tranzakciós adatok

Bizonyos esetekben az a cél, hogy egy sor művelet két vagy több rendszerben egyaránt végbemenjen, vagy ne menjen végbe egyik rendszerben sem. Az egyik legtriviálisabb példa erre az átutálási tranzakció.

Az átutalandó összeget az egyik helyen a számláról le kell vonni, közben a másik helyen a számla összegéhez hozzá kell adni. Ha ezt bármi megakadályozza, akár a folyamat közepén is, az eredeti állapot vissza kell állítani mindkét helyen.

Egy másik, az e-kereskedelemre jellemző példa a rendeléslétrehozás. Gondoljunk egy webshopra, mely engedményes árú termékeket árul nagyon alacsony készlettel egy olyan raktárból, amely offline rendeléseket is kiszolgál.

Ebben az esetben jogos elvárás lehet, hogy a webshopon kezdeményezett rendelés, ha a raktár aktuális készletadatai lehetővé teszik, egyszerre jöjjön létre az ERP rendszerben és a webshopban, vagy ellenkező esetben ne jöjjön létre egyik rendszerben sem, miközben hibaüzenet tájékoztatja a vevőt a webshopban arról, hogy az adott termék a kívánt mennyiségben már nem áll rendelkezésre.

 

 

Gyakorlat: Megvalósítási lehetőségek

Az eddigiekben átvettük az integráció magas szintű struktúráját, megértettük, mi az adatforrás célja, az időzítés lényege, mit takar a szinkronizálás és aszinkronizálás folyamata és mit kell tudni a tranzakciókról. Eljött az ideje, hogy megnézzük, hogyan alkalmazzuk ezeket a gyakorlatban.

 

Szerver-kliens API

Az adatcsere egyik kulcsfontosságú eleme a szerver-kliens modell, amelyben a kliens oldal kezdeményezi a kommunikációt, aktívan küld, illetve kér le adatokat, vagy parancsot továbbít, míg a kiszolgáló (szerver), ahogy a neve is mutatja, kiszolgálja a kéréseket, adatokat dolgoz fel, ad vissza, vagy feladatokat hajt végre.

A kliens valamilyen csatornán keresztül meghívja a szervert, az pedig feldolgozza a hívást, ideális esetben azonnali választ küldve visszajelzésként. Mindez a kérés/válasz paradigmára épül, amely lehetővé teszi a két vagy több rendszer közti aktív, egyidejű kommunikációt.

Ez a modell ideális olyan aszinkron folyamatok kezelésére is, melyek során a működés sikerességére vonatkozó visszajelzésre van szükség. Egy szerver/kliens felépítés könnyen tudja kezelni a több klienses párhuzamos kapcsolatokat, tehát jól skálázható.

 

Fájlátvitel és adat-közzététel

Ez tulajdonképpen egy protokoll nélküli adatátvitel, melynek során az egyik fél szimplán elérhetővé teszi az adatokat a másik fél számára egyszerű dokumentumként. Ennek leghétköznapibb formája, ha közzétesszük az adatot letölthető formában az interneten, vagy egy FTP szerveren, illetve ha FTP-n keresztül feltöltjük a célszerverre.

Egyszerűségének köszönhetően ez a modell jól működhet olyan körülmények között, ahol a fogadó fél megbízik az adatforrásban, tehát nincs szükség bonyolult hozzáférés-kezelésre, formátum-ellenőrzésre, vagy közvetlen visszajelzésre.

Bár ez a módszer messze nem mondható kifinomultnak és rugalmasnak, tökéletesen illik az adatszolgáltató/fogyasztó paradigma egyirányú információáramlásához, és még ma is rendkívül elterjedt – különösen a termékadatok átvitelében. Ami az átvitt adatokat illeti, természetük szerint aszinkron adatokról van szó, ugyanakkor maga a dokumentum-átadás és -feldolgozás kontrollálható, szabályozható, sorosítható.

Ez a fajta kommunikáció mind a küldő, mind a fogadó fél részéről aktivitást kíván. A küldő félnek aktívan publikálni kell a dokumentumokat, míg a fogadónak aktívan befogadni és feldolgozni. Mindez általában egyedi fejlesztést kíván a fogadó fél oldalán.

 

Közvetlen adatbázis-kapcsolat

A közvetlen adatbázis-kapcsolat hatékony szinkronizálási módszer, a legtöbb esetben azonban sok hibalehetőséget rejt és veszélyes, mivel megkerüli az adatbázis köré épített üzleti logikát.

 

Köztes rendszerek

Külön modell un. köztes rendszerek használata a kommunikációban: ilynkor az összekapcsolt rendszerek közé beékelődik egy harmadik, mely menedzseli, optimalizálja, naplózza, monitorozza, az adatcserét, egymásba alakítja különböző adatformátumokat, vagy akár gyorsítótáraz bizonyos adatokat. Ez a köztes réteg nemcsak két rendszer csatlakozási pontja lehet, hanem alrendszerek egész infrastruktúrájának mindent mindennel összekötő csomópontja.

Ezeket a közbenső szoftvereket gyakran nevezik Vállalati Szolgáltatás Buszoknak (ESB).

Az ilyen szolgáltatási csomópontokra jó példája a Zapier, mely kliensként számtalan különböző rendszer API-jához képes csatlakozni, a forrásrendszerből érkező bemeneti adatokat átalakítja a célrendszer formátumává, és mindezt felhő alapú szolgáltatásként kínálja.

A legizgalmasabb ebben a módszerben, hogy a köztes rendszerben egy bizonyos külső szoftver API-jához csatlakozó klienst csak egyszer kell lefejleszteni, amikor legközelebb egy másik külső rendszert kell illeszteni az eredeti rendszerhez, csak megfelelően le kell képezni közöttük az adatokat.

A köztes rendszert természetesen ki lehet egészíteni saját szerver-végpontokkal illetve  API-val annak érdekében, hogy kívülről aktívan elérhető legyen.

Ugyanennek az elvnek még fejlettebb változata, amikor a bemeneti adatokat egy univerzális belső formátumra fordítják le az API kliensek köré épített kiegészítő rétegben. Ebben az esetben az adatcsomópont különböző szerver/kliens végpontjai ugyanazt a nyelvet beszélik és nincs szükség a rendszeren belül két pont közti közvetlen átalakításra. Az adatokat ilyenkor mindössze megfelelően kell irányítani a különböző végpontok között. Ez persze  erősen idealizált modell, de a komplex adathálózatok népszerű irányzata napjainkban.

Ma már több rendszerintegrátor kihasználja a köztes rendszerek valamilyen formáinak előnyeit; különösen igaz ez azokra az integrátorokra, melyek többféle ERP-t kapcsolnak  össze többféle e-kereskedelmi platformmal, hiszen az egyes rendszerek közt külön-külön lefejlesztett közvetlen integráció többszörös erőfeszítést, potenciális problémákat és költségeket jelent.

 

Közvetlen integráció vagy köztes rendszer

A ponttól pontig integráció azt jelenti, hogy két rendszer közvetlenül kapcsolódik egymáshoz. A P2P kapcsolat szerver-kliens szempontból sokféle lehet. Vannak bizonyos esetek, amelyekben az ERP kapcsolódik kliensként az e-kereskedelmi platformhoz, más esetekben mindez fordítva történik, és vannak helyzetek, amikor ezek kombinációja valósul. Előfordul, hogy az API-kat menet közben, kimondottan a P2P integráció kedvéért építik egyik vagy mindkét végponton.

P2P integráció esetén általában nagyobb a lehetőség a tervezésre és a testre szabásra, és a konkrét üzleti igények szabják meg a fejlesztés irányát.

 

Hogyan válasszunk?

Integráció során a legfontosabb szempont, hogy maradéktalanul kielégítse az üzleti igényeket. A megfelelő adatfolyam-modell és a megvalósított funkciók a legfontosabb tényezők közé tartoznak, de az integrátortól, a választott technológiától és az alkalmazott  technológiát függetlenül egyéb szempontok is rendkívül fontosak lehetnek.

A konkrét technológia vagy technológiák, illetve a rendszerintegrátor kiválasztásakor a megbízhatóság és a célszerűség az elsődleges szempont, miközben meg kell találni az egészséges egyensúlyt költségek, a teljesítmény, a skálázhatóság, a támogatás minősége és egyéb tényezők között. A megrendelő és a rendszerintegrátor közös felelőssége tisztázni a prioritásokat és megérteni a kritikus pontokat.

 

Mit kérdezzünk egy rendszerintegrátortól?

 

Az alábbiakban összegyűjtöttünk néhány kérdést, melyek segíthetnek a különböző megoldások összehasonlításában és kiválasztásában.

 

Megbízhatóság: Hogyan garantált az integráció megbízhatósága?

Ha egy folyamat kritikus az üzletünk számára, például a raktárkészlet frissítése, arra fel kell hívnunk a rendszerintegrátor figyelmét, és különösen fontossá válik a naplózás, monitorozás, az automatikus hibakezelés, az értesítési rendszer és akár folyamatosan elérhető segítségnyújtás.

 

tips Kérdések:

 

Teljesítmény: Hogyan fokozható a teljesítmény? Elérhetők-e teljesítménytesztek vagy összehasonlítások? Mi az integráció szűk keresztmetszete, illetve mik a korlátai? Hogyan küszöbölhető ki a szűk keresztmetszet? Mi az egyes folyamatok teljesítményének felső határa?

Teljesítmény szempontjából érdemes meghatározni a várható legnagyobb terhelést és összevetni a kínált megoldás mutatóival. Meg kell fogalmazni az elvárásainkat, és ha azok nincsenek összhangban az integrátor által szállított megoldás lehetőségeivel, akkor az integráció testre szabására, esetleg alternatív megoldásra lehet szükség.

A kötegelt adatimport és -frissítések okoznak a legkönnyebben teljesítményproblémákat, ezért bárhol, ahol nagy mennyiségű adatot szinkronizálunk egyszerre, különös körültekintésre van szükség.

 

magento ERP integráció kérdések

 

Skálázhatóság: További erőforrások hozzáadásával javítható-e a teljesítmény? Ki lehet a megoldást terjeszteni úgy, hogy további webshopokat tudjon kezelni?

Meg kell győződnünk róla, hogy az integráció képes megfelelni minden jelenlegi, illetve potenciális jövőbeli üzleti elvárásnak.

 

Adatgazda, adatbiztonság és átláthatóság: Kinek a tulajdonában van az adatok? Hogyan garantált az adatbiztonság? A szinkronizálási folyamatok mennyire átláthatók a kereskedő számára?

Ezek lényeges kérdések lehetnek abban az esetben, ha bizalmas adatokat kezelünk, és felhő alapú, illetve szolgáltatott szoftver (SaaS) megoldásban gondolkozunk.

 

Egyedi fejlesztés: Hogyan történik a hibajavítás és az új szoftververziók telepítése? Bővíthető-e az integráció harmadik fél által? A részben vagy egészben nyílt forrású e- a szoftver? Rendelkezésre áll műszaki vagy fejlesztői dokumentáció?

Az integráció során valamilyen szintű testreszabásra a legtöbb esetben szükség van, illetve gyakran új kérések merülnek fel menet közben Nagyobb szabadságot tesz lehetővé a megrendelő számára, ha külső, vagy saját fejlesztőket is be lehet vonni.

 

Kód karbantartás és aktív fejlesztés: A kódot aktívan karbantartják? Milyen gyakran jönnek ki új kiadások? Mennyire egyszerűen tudja a kereskedő az új változatokat vagy frissítéseket telepíteni? Tartalmazza-e a támogatási csomag ezeket a folyamatokat?

 

Költségek és szállítási határidők: Milyen költségei vannak a telepítésnek, a konfigurálásnak, a támogatásnak és a testre szabásnak? Milyen szolgáltatásokat tartalmaz a meghirdetett ár? Mennyire bonyolult a megoldás konfigurálása? Mennyi egyedi fejlesztésre van szükség az alapértelmezett megoldáshoz képest?

Általában minél inkább lefedi egy kulcsra kész megoldás a kereskedő igényeit, annál kevésbé kockázatos annak testreszabása és élesítése. Egy megoldás megvalósításának és üzemeltetésének teljes költségének számos összetevője van, és érdemes minddel tisztában lenni.

 

Támogatás: Milyen támogatást nyújt az integrátor felhasználói kérdések megválaszolásában, sürgős esetben elérhető-e műszaki személyzet, amely azonnal cselekedni tud?

Természetesen az állandóan rendelkezésre álló támogatás a legelőnyösebb, de amennyiben ez nem elérhető, győződjünk meg róla, hogy a szolgáltató reakcióideje megfelelő a számunkra.

 

Konklúzió

A Magento-ERP integráció komplex feladat, rengeteg lehetséges szemponttal, amit figyelembe kell venni. Mielőtt belevágnánk a megvalósításba, még az egyszerűbb esetekben is ajánlott felmérni az üzleti igényeket, számba venni és fontossági sorrendbe állítani a kívánt funkciókat, a teljesítménnyel szembeni elvárásokat és egyéb számunkra lényeges tényezőket.

Szintén hasznos előre tájékozódni a különböző megoldások előnyeiről és hátrányairól – a fenti lista remélhetőleg segítséget nyújt ebben.

Az AionHillnél az évek során számos ERP és egyéb külső rendszert integráltunk sikeresen Magento webshoppal, és készséggel állunk rendelkezésére bárkinek, akinek segítségre van szüksége.

 

Amennyiben bármilyen kérdésed merülne fel a témával kapcsolatban, írd meg kommentben és szívesen válaszolunk.