Dlaczego migracja stron i bloków CMS w Magento 2 bywa drogą przez mękę?
Scenariusz powtarza się w niemal każdym sklepie: marketing lub agencja contentowa pieczołowicie układa rozbudowany landing page na środowisku stagingowym. Jest nowy layout, kilkanaście bloków statycznych, banery, zagnieżdżone widgety i precyzyjnie skonfigurowane wersje pod trzy różne widoki sklepowe (Store Views). Strona wygląda doskonale, dostaje akcept zarządu i ma ruszyć na produkcji za godzinę. W tym momencie zaczyna się nerwowe przeklejanie kodu przez panel administracyjny albo paniczne kombinowanie z bazą danych.
Ręczne kopiowanie treści HTML i bloków to prosta droga do katastrofy. Edytor WYSIWYG potrafi samowolnie wyciścić fragmenty kodu, relatywne ścieżki do obrazków w katalogu pub/media przestają działać, a przypisania do odpowiednich Store Views trzeba mozolnie klikać od nowa. Z kolei próba wykonania prostego zrzutu tabel cms_page, cms_block oraz ich powiązań ze stagingu i wgrania ich na produkcję niemal natychmiast wywołuje błędy kluczy obcych i konfliktów AUTO_INCREMENT. Na produkcji istnieją już przecież inne strony o tych samych identyfikatorach liczbowych.
W codziennej pracy przy projektach e-commerce wykorzystujemy narzędzie CMS Import/Export, które rozwiązuje ten problem systemowo: pakuje całą strukturę treści, metadane, layouty i fizyczne pliki graficzne do jednego archiwum ZIP, gotowego do wdrożenia na produkcji przez panel lub z poziomu konsoli.
Co dokładnie psuje się przy zrzutach bazy danych tabel CMS?
Pokusa wykonania szybkiego mysqldump na tabelach CMS jest zrozumiała, ale w architekturze Magento 2 struktura treści nie jest płaska. Zależności między tabelami sprawiają, że surowy eksport SQL tworzy więcej problemów, niż rozwiązuje:
- Konflikty kluczy głównych (page_id i block_id): Jeśli na produkcji powstała w międzyczasie jakakolwiek nowa strona (np. zaktualizowany regulamin), jej identyfikator ID w bazie zablokuje import rekordu ze stagingu o tym samym numerze.
- Rozłączenie tabel relacyjnych: Tabele
cms_page_storeicms_block_storemapują treść do konkretnych widoków sklepu na podstawie wewnętrznychstore_id. Jeśli środowisko developerskie lub staging ma inną historię migracji i odmienne ID widoków niż produkcja, treść trafi w próżnię lub wyświetli się w niewłaściwej wersji językowej. - Brakujące zasoby graficzne: Baza danych przechowuje jedynie tekstowe odwołania do plików, np.
{{media url="wysiwyg/promo/baner.webp"}}. Zrzut SQL nie przenosi samych plików z serwera, co kończy się wyświetlaniem pustych ramek po stronie klienta.
Przenoszenie treści CMS na poziomie bazy danych w środowisku produkcyjnym przypomina operację na otwartym sercu bez znieczulenia. Wystarczy jeden niespójny klucz obcy, aby unieważnić powiązania w wielu widokach sklepu.
Jak działa bezstratny transfer treści do pliku ZIP?
Prawidłowe przeniesienie zawartości CMS między instancjami Magento 2 wymaga operowania na unikalnych identyfikatorach tekstowych (tzw. identifiers lub URL keys), a nie na technicznych identyfikatorach numerycznych z bazy danych.
Rozwiązanie oparte o paczki ZIP realizuje proces w kilku krokach:
- Selekcja elementów: Z poziomu siatki (Grid) w panelu administracyjnym wybierasz dokładnie te strony lub bloki, które chcesz zmigrować. Nie musisz przenosić całego CMS-a.
- Parsowanie zawartości i wykrywanie mediów: Skrypt analizuje treść HTML oraz pola formularzy w poszukiwaniu dyrektyw
{{media url=...}}oraz standardowych ścieżek do katalogu mediów. - Pakowanie do ZIP: Moduł tworzy archiwum zawierające plik manifestu (z metadanymi SEO, konfiguracją layoutu, tytułami i kodami Store View) oraz komplet fizycznych plików graficznych wyciągniętych z
pub/media. - Import z walidacją: Na środowisku docelowym archiwum jest rozpakowywane. Jeśli strona o danym identyfikatorze już istnieje, zostaje zaktualizowana; jeśli nie – utworzona. Obrazy trafiają do odpowiednich katalogów mediów, a uprawnienia i widoki sklepowe zostają sparowane po kodach (np.
default,pl_PL), a nie po numerach ID.
Dlaczego oryginalny moduł przestał działać i potrzebny był fork?
Przez lata standardem w społeczności Magento było rozszerzenie MSP_CmsImportExport stworzone przez włoski zespół MageSpecialist. Było to proste, niezawodne narzędzie, które uratowało setki wdrożeń przed żmudnym ręcznym kopiowaniem treści.
Niestety, rozwój oryginalnego repozytorium zakończył się definitywnie w okolicach 2023 roku. Wraz z nadejściem Magento 2.4.6, 2.4.7 oraz kolejnych wydań opartych na PHP 8.2, 8.3 i nadchodzącym PHP 8.4, porzucony kod przestał działać. Przestarzałe deklaracje typów, niezgodności z nowymi mechanizmami PageBuildera i błędy serializacji danych uniemożliwiły korzystanie z modułu w nowoczesnych projektach.
Jako studio realizujące wdrożenia i stałe utrzymanie sklepów Magento nie mogliśmy pozwolić sobie na powrót do ręcznego przeklejania bloków. Przejęliśmy kod, zrefaktoryzowaliśmy go pod kątem najnowszych standardów platformy i utrzymujemy publiczny fork na GitHubie: SISL magento2-cms-import-export. Moduł przeszedł pełne testy typu round-trip (eksport ze starszych wersji, import na najnowsze środowiska i odwrotnie).
Jak zainstalować moduł przez Composer krok po kroku?
Instalacja forka odbywa się w pełni przez Composera, z zachowaniem oryginalnych przestrzeni nazw, co gwarantuje kompatybilność wsteczną, jeśli w projekcie istniały już wcześniejsze konfiguracje.
W głównym katalogu swojej instalacji Magento 2 wykonaj następujące polecenia:
composer config repositories.sisl-msp-common vcs https://github.com/SISL-source/magento2-msp-common
composer config repositories.sisl-cmsie vcs https://github.com/SISL-source/magento2-cms-import-export
composer require msp/cmsimportexport:dev-main
bin/magento module:enable MSP_Common MSP_CmsImportExport && bin/magento setup:upgradePo zakończeniu kompilacji DI i wyczyszczeniu cache w panelu administracyjnym w sekcjach Content > Pages oraz Content > Blocks pojawi się opcja masowego eksportu do pliku ZIP, a także dedykowany formularz importu.
Jak wygląda import w procesach CI/CD oraz z poziomu CLI?
Dla zespołów deweloperskich i sklepów zarządzanych w modelu Continuous Delivery klikanie w panelu administracyjnym bywa zbędnym krokiem. Moduł dostarcza natywną komendę konsolową Symfony/Magento, którą można wpiąć bezpośrednio w skrypt wdrożeniowy lub uruchomić na serwerze przez SSH:
bin/magento cms:import /sciezka/do/paczki/landing_black_friday.zipKomenda automatycznie przetwarza zawartość archiwum, wgrywa pliki graficzne na właściwe miejsca w strukturze pub/media/wysiwyg, aktualizuje strukturę bazy danych i czyści odpowiednie tagi w pamięci podręcznej (full_page, block_html). Całość trwa ułamek sekundy i nie wymaga angażowania administratora do ponownego ustawiania metadanych czy mapowania widoków.
Kiedy warto zrezygnować z ręcznego zarządzania treścią?
Jeśli w Twoim sklepie zmiany w treściach ograniczają się do poprawienia jednej literówki w regulaminie raz na pół roku, ręczna edycja na produkcji wystarczy. Jeśli jednak prowadzisz regularne kampanie promocyjne, budujesz rozbudowane landing page dla produktów, testujesz kreacje na stagingu przed publikacją lub zarządzasz sklepem typu multi-store z wieloma wersjami językowymi – automatyzacja tego procesu jest koniecznością.
Oszczędza to dziesiątki godzin pracy zespołu, eliminuje ryzyko wdrożenia wybrakowanych stron bez grafik i zdejmuje z deweloperów obowiązek ręcznego pisania skryptów migracyjnych DataPatchInterface pod zwykłe zmiany marketingowe. Jeśli potrzebujesz wsparcia w audycie, optymalizacji lub automatyzacji procesów w Twoim sklepie, napisz do nas – w SISL na co dzień projektujemy, wdrażamy i utrzymujemy stabilne instalacje Magento dla e-commerce.