Migracja kursu z WebToLearn na WordPress: hasła i daty dostępu 1:1
Ponad czterysta osób w trakcie kursu i ani jedna nie może tego zauważyć
Kursantka loguje się wieczorem, żeby obejrzeć kolejną lekcję. Nie wie, że od kilku dni jej konto, hasło i data końca dostępu leżą już w innym systemie. Nie dostała maila o resecie hasła, nie musi niczego klikać, a jej dostęp kończy się dokładnie w tym samym dniu co wcześniej. Tak miała wyglądać przeprowadzka z jej perspektywy: nijak.
Tak miała przebiec migracja kursu online na WordPress z platformy WebToLearn. Na starej platformie było 438 kont i 430 dostępów z datą końca, z czego 121 aktywnych. Poniżej cała droga: co da się wyciągnąć z takiej platformy, które założenie okazało się błędne, gdzie były miny i w jakiej kolejności przełącza się sprzedaż, żeby nikt nie został bez dostępu.
Kontekst: kurs w abonamencie, sklep na WordPressie
Klientka to firma szkoląca nauczycieli języków obcych. Sprzedaje kurs wideo z dostępem na 8 miesięcy, dla pojedynczych osób i w pakietach dla szkół. Sklep WooCommerce działał na jej WordPressie (opiekuje się nim inny deweloper), a kurs stał na WebToLearn, w abonamencie. Wtyczka integrująca nadawała dostęp po każdym opłaconym zamówieniu.
Plan: kurs, kursanci, newsletter i sprzedaż w jednym WordPressie. Tutor LMS w wersji darmowej, FluentCRM w wersji darmowej i nasza wtyczka dostępów, która pilnuje dat. Warunki brzegowe były trzy: sprzedaż nie może stanąć ani na godzinę, do kursantów nie wychodzi żaden mail, dopóki sami go nie zaplanujemy, a sklepu nie przebudowujemy.
Eksport: co da się wyciągnąć z platformy abonamentowej
Pierwsza miła niespodzianka: nie musieliśmy prosić klientki o wygenerowanie klucza API. Token siedział już w ustawieniach wtyczki integrującej na jej WordPressie. Napisaliśmy własny skrypt eksportu, który tylko czyta, i ściągnęliśmy:
- 438 kont z adresami e-mail i hashami haseł,
- 430 dostępów z datą końca (121 aktywnych, najdalszy kończy się w lutym 2028),
- strukturę kursu: 10 lekcji w ustalonej kolejności,
- 14 załączników do pobrania, razem 251 MB.
Do tego eksport newslettera z osobnego narzędzia do mailingu: 512 kontaktów. Każda z tych rzeczy ląduje w innym miejscu nowej platformy, więc najpierw rozpisaliśmy mapę.
Miny, na które trafiliśmy po drodze
Filmów nie da się pobrać
Odtwarzacz starej platformy chroni wideo (DRM), więc nie ma uczciwego sposobu, żeby ściągnąć filmy z eksportu. Rozwiązanie było banalne: oryginalne pliki MP4 klientka miała u siebie i przysłała je sama. Trafiły do Bunny Stream, a lekcje w Tutorze dostały nowe odtwarzacze. Jeśli planujesz przeprowadzkę, sprawdź na samym początku, czy masz oryginały. Bez nich migracja kursu wideo zamienia się w nagrywanie od nowa.
Uszkodzony plik był uszkodzony od dawna
Jedno z archiwów ZIP z materiałami nie dało się rozpakować – brakowało w nim około 20 MB. Najpierw podejrzewaliśmy nasz eksport. Okazało się, że plik był uszkodzony już na starej platformie, czyli kursanci od dawna pobierali coś, czego nie dało się otworzyć. Poprosiliśmy klientkę o oryginał. Wniosek: eksport się sprawdza, a nie mu ufa – każdy plik trzeba otworzyć albo porównać rozmiar.
Stara integracja dalej nadaje dostępy
Wtyczka łącząca sklep z WebToLearn przy każdym opłaconym zamówieniu (nawet takim, w którym nie ma kursu) wykonuje 9 zapytań do API, każde z limitem czasu 10 sekund. Sukces nie zostawia żadnej notatki w zamówieniu, tylko błędy. Z tego wynikają dwie rzeczy. Nie wolno jej wyłączyć przed dniem przełączenia, bo kupujący nie dostaną dostępu. I trzeba ją wyłączyć dokładnie w dniu przełączenia, bo inaczej kupujący dostanie dwa dostępy i dwa maile. A przycisku pełnej synchronizacji w jej ustawieniach lepiej nie klikać – pod spodem ponownie przepuszcza zamówienia przez procedurę „opłacone”.
Kopia strony założyła prawdziwe konto
Wszystko testowaliśmy na kopii strony postawionej lokalnie. Testowe zamówienie na kopii przeszło przez aktywną tam starą integrację i założyło prawdziwe konto testowe na produkcyjnej platformie klientki. Sukces nie zostawił śladu w zamówieniu, więc wyszło to dopiero z analizy kodu. Od tego dnia blokada ruchu wychodzącego z kopii działa jako biała lista: wszystko zablokowane poza kilkoma znanymi adresami. Czarna lista zawsze o czymś zapomni.
Planujesz przeprowadzkę kursu i boisz się, że coś zginie po drodze? Takie miny najtaniej znaleźć przed dniem przełączenia, a nie po. Napisz, z jakiej platformy chcesz wyjść, a powiemy, co da się przenieść 1:1.
Moment odkrycia: hasła jednak da się przenieść
W pierwotnym planie stało czarno na białym: hasła nie przechodzą, kursanci ustawią nowe przez „nie pamiętam hasła”, a mail powitalny im to wyjaśni. To typowe założenie przy każdej migracji i zwykle prawdziwe, bo każdy system hashuje hasła po swojemu.
Zanim jednak to zakomunikowaliśmy, zajrzeliśmy w eksport. Stara platforma trzymała hasła jako bcrypt, czyli standardowy algorytm, a nie własny wymysł. Aktualny WordPress sam przeszedł na bcrypt i hash w takim formacie sprawdza standardową funkcją PHP password_verify. Teoria mówiła, że stary hash wpisany do WordPressa po prostu zadziała.
Teorii nie wdrażamy. Założyliśmy na żywym WordPressie konto testowe z hashem bcrypt dla znanego hasła i przepuściliśmy je przez pełną ścieżkę logowania. Dobre hasło wpuszczało, złe było odrzucane. Konto testowe skasowaliśmy. Dopiero wtedy zapadła decyzja: kursanci logują się starym hasłem, a w mailu powitalnym nie piszemy nic o resetowaniu.
Jedna pułapka techniczna: hasha nie wolno przepuszczać przez wp_set_password(), bo ta funkcja zahashuje go drugi raz i nikt się nie zaloguje. Hash trafia do bazy wprost:
// hash z eksportu wpisujemy bez zmian - wp_set_password() zahashowałby go ponownie
$wpdb->update(
$wpdb->users,
array( 'user_pass' => $hash_bcrypt_z_eksportu ),
array( 'ID' => $user_id )
);
clean_user_cache( $user_id );
// kontrola na koncie testowym ze znanym hasłem
var_dump( wp_check_password( 'znane-haslo-testowe', $hash_bcrypt_z_eksportu ) ); // ma być true
Rozwiązanie: konta, zapisy i daty 1:1
Sam import poszedł jednym skryptem, bez wysyłki ani jednego maila (maile były zablokowane na czas migracji):
- 437 kont w WordPressie: 352 nowe i 85, które już istniały, bo te osoby kupowały wcześniej w sklepie. Dopasowanie po adresie e-mail, zero duplikatów.
- 428 zapisów na kurs z datą końca dostępu przepisaną ze starej platformy, przy koncie i przy zapisie.
- Kontrola liczby kursantów funkcją samego Tutora, a nie zapytaniem do bazy. Liczy się to, co widzi wtyczka, a nie to, co sami zapisaliśmy.
- Kurs odtworzony w Tutorze z tą samą kolejnością lekcji, filmy z Bunny Stream, materiały do pobrania w katalogu zamkniętym dla świata i wydawane dopiero po sprawdzeniu zapisu oraz daty końca. Bezpośredni link do pliku zwraca 403.
- Później doszły jeszcze komentarze spod lekcji (107) i daty ostatniego logowania, żeby historia kursantów nie zaczynała się od zera.
Najlepszy test dat przyszedł sam. Następnej nocy zadanie wygaszające dostępy przestawiło 308 z 428 zapisów na wygasłe, dokładnie według dat ze starej platformy. Zostali ci, którzy mieli zostać.
Dzień przełączenia: kolejność ma znaczenie
Nowa wtyczka dostępów ma wbudowany bezpiecznik: bez ustawionej daty startu śpi. Dzięki temu można ją wgrać na żywą stronę na długo przed przełączeniem, a samo wgranie nikomu nie zdubluje dostępu. Do tego tryb podglądu: kurs i panel widzą tylko administratorzy i konta testowe, a wychodzące maile są zatrzymane.
Sam dzień przełączenia to krótka sekwencja, w której kolejność kroków decyduje o tym, czy ktoś zostanie bez dostępu:
Po przełączeniu zostaje delta: osoby, które kupiły kurs między pierwszym importem a dniem przełączenia, dogrywa się tym samym eksportem. A na wypadek kłopotów jest plan cofnięcia na dwie minuty: stara integracja z powrotem włączona (token nie był kasowany), nowa wtyczka znowu uśpiona datą w dalekiej przyszłości. Nikomu nic nie zabieramy.
Efekt: przed i po
Przed: kurs na abonamencie, kursanci w jednym systemie, sklep w drugim, newsletter w trzecim. Po: wszystko w jednym WordPressie, 437 kont ze starymi hasłami, daty dostępu co do dnia, 512 kontaktów newslettera w tym samym CRM co kupujący. W trakcie migracji do kursantów nie wyszedł ani jeden mail. Abonament starej platformy nie będzie odnawiany.
Uczciwie o stanie na dziś: nowa platforma jest wgrana na żywą stronę w trybie podglądu i czeka na zaplanowany dzień przełączenia. Kursanci i dane są już przeniesione, a sprzedaż do tego dnia obsługuje stara integracja.
Jak sprawdzić u siebie – checklista przed migracją kursu
- Eksport z datami dostępu. Czy stara platforma oddaje datę końca przy każdym zapisie, a nie tylko listę osób?
- Hashe haseł. W jakim są formacie? bcrypt da się przenieść do WordPressa, ale sprawdź to testem na jednym koncie.
- Filmy. Czy masz oryginały? Jeśli platforma używa DRM, z eksportu ich nie wyciągniesz.
- Weryfikacja plików. Otwórz każdy załącznik albo porównaj rozmiary. Uszkodzony plik mógł być uszkodzony od lat.
- Co dziś nadaje dostęp. Znajdź integrację i ustal, kiedy dokładnie ją wyłączysz.
- Kolejność dnia przełączenia rozpisana z planem cofnięcia na każdy krok.
- Test bez maili. Kopia strony z blokadą ruchu wychodzącego jako białą listą i zatrzymaną pocztą.
Czego nauczyła nas ta historia
Migracja z zamkniętej platformy to nie przenoszenie plików, tylko trzy osobne decyzje: co z hasłami, co z datami dostępu i kiedy wyłączamy stare. Założenie „hasła nie przechodzą” jest wygodne, ale warto je sprawdzić, bo każdy reset hasła to kursant, który może się zgubić. I druga zasada: kopia strony, która widzi świat, prędzej czy później coś w nim zmieni. Blokada wychodzącego ruchu jest białą listą albo jej nie ma.
Więcej o tym, jak zaplanować całą przeprowadzkę, piszemy w poradniku o migracji platformy kursowej. A jeśli zastanawiasz się, co nowa platforma powinna umieć od pierwszego dnia, zajrzyj do przeglądu funkcji platformy kursowej.
FAQ
Czy przy migracji kursu na WordPress kursanci muszą ustawić nowe hasła?
Nie zawsze. Jeśli stara platforma trzyma hasła jako bcrypt, aktualny WordPress sprawdzi taki hash bez zmian i kursanci zalogują się starym hasłem. Przy innych formatach zwykle zostaje reset przez „nie pamiętam hasła”.
Jak przenieść daty końca dostępu do kursu?
Z eksportu zapisów, przy każdej osobie osobno. U nas data trafiła do konta i do zapisu na kurs, a nocne zadanie wygaszające zamyka dostęp następnego dnia po terminie. Pierwsza noc po imporcie była najlepszym testem.
Co zrobić z filmami, których nie da się pobrać z platformy?
Odzyskać oryginały od autora kursu i wgrać je na nowo do hostingu wideo, np. Bunny Stream. Pobieranie filmów chronionych DRM nie wchodzi w grę.
Czy w trakcie migracji kursanci dostaną maile z WordPressa?
Nie powinni. Na czas importu blokujemy wysyłkę, a nowa platforma działa w trybie podglądu, w którym maile są zatrzymane. U nas w trakcie migracji nie wyszedł do kursantów ani jeden mail.
Kiedy wyłączyć integrację ze starą platformą?
Dokładnie w dniu przełączenia, chwilę po tym, jak nowa wtyczka zacznie obsługiwać zamówienia. Wcześniej kupujący zostaną bez dostępu, później dostaną dwa dostępy i dwa maile.
Ile trwa taka migracja?
Sam import kont i zapisów to najkrótsza część. Najwięcej czasu zajmują eksport, sprawdzenie plików, odtworzenie kursu, testy na kopii strony i zaplanowanie dnia przełączenia. Dlatego zaczynamy od mapy danych, a nie od importu.
Chcesz wyjść z platformy abonamentowej i boisz się o kursantów?
Przenieśliśmy 437 kont tak, że ludzie logują się starym hasłem i mają te same daty dostępu, a sprzedaż nie stanęła ani na chwilę. Zaczniemy od eksportu i mapy danych, żeby było jasne, co przejdzie 1:1, a co wymaga decyzji.
Masz ten sam problem? Napisz do nas i napisz, z jakiej platformy przenosisz kurs.
Planujesz własną platformę kursową? Napisz do mnie
Odpowiem osobiście, zwykle w ciągu kilku godzin.
