Drupal i import danych z pliku XML ZAWIERAJĄCEGO KILKADZIESIĄT TYSIĘCY REKORDÓW? CZYLI Z SERII – JAK STWORZYĆ WŁASNY MODUŁ DO… Część II.

 In Firmowo

W ostatniej części pokazałem proces budowania formularza.  Dzisiaj natomiast zajmiemy się obsługą, więc wyjaśnię od strony technicznej w jaki sposób można to wykonać.

Obsługa formularza

Funkcja, która wywoływana jest podczas wysyłania formularza, to “form_id_form_submit()” . Z poprzedniego wpisu wiemy, że id formularza to “import_recommendation“, więc pełna nazwa to “import_recommendation_form_submit”. Możemy również nazwać dowolnie taką funkcję, lecz trzeba takie zdarzenie zarejestrować podczas tworzenia formularza w następujący sposób:
“$form[‘#submit’][] = ‘nazwa_funkcji'”. To samo tyczy się funkcji odpowiedzialnej za walidacje(“form_id_form_validate()”), która wywoływana jest jako pierwsza.

Funkcja odpowiedzialna za obsługę pliku XML:

Wyjaśnijmy co dzieje się w powyższej funkcji…

Za przechowywanie aktualnych wartości, odpowiedzialna jest zmienna “form_state”, dzięki której pobieramy id wczytanego pliku, następnie na podstawie tej wartości tworzymy obiekt typu File, zawierający m.in adres URL. Plik XML jest znaczących rozmiarów i przejście przez całe drzewo może zająć “większa chwilę”, więc ustawiamy czas realizacji skryptów na nieograniczony(set_time_limit(0)), przez co nie pojawi nam się dziwny komunikat typu “Maximum execution time exceeded“:)  Odczytujemy adres pliku i przekazujemy go do parsera.

XMLReader – słów kilka

XMLReader wykorzystywany jest głównie do parsowania dużych dokumentów XML ponieważ  nie wczytuję całej zawartości pliku powodując błąd związany z brakiem pamięci. Zamiast tego dokument jest stream’owany, czyli do pamięci wczytywane są tylko aktualne węzły w drzewie. Jako węzeł rozumiemy każdy element w dokumencie XML. Klasa ta udostępnia wiele pomocniczych metod. W powyższym przykładzie wykorzystywane zostały m.in:

  • “read”, przechodzenie do kolejnego elementu w drzewie
  • “getAttribute”, zwraca nazwę atrybutu przekazanego w parametrze
  • “readString”, zwraca zawartość aktualnego węzła jako tekst
  • next” – przechodzimy do kolejnego węzła na tym samym poziomie pomijając całe poddrzewo

Co tak naprawdę się dzieje?

Plik zawiera listę cech przypisanych do książki.

Głównym zadaniem skryptu jest przeniesienie danych do bazy, mianowicie chodzi o zebranie ośmiu cech odnoszących się do danej książki, następnie przypisaniu ich tejże książce jeśli znajduję się w bazie.

Funkcja rozpoczyna czytanie węzłów, ważna jest informacja, że czytany jest każdy w głąb, aż do ostatniego poziomu. Dopiero po przeszukaniu całego poddrzewa dla głównych węzłów(tych na pierwszym poziomie) parser przechodzi do kolejnego.

Pobierany jest tytuł oraz lista cech(jeśli wartość każdej cechy wynosi pięć oznacza to ze rekomendacja jest pusta). Następnie, znajdowane są różne wersje książek(audiobook, ebook) dla danego tytułu i przypisywana jest do nich lista cech.

Przeszukiwanie oraz zapisywanie informacji w bazie…

Przeszukiwanie

Do przeszukiwania danych w bazie wykorzystana została wbudowana klasa EntityFieldQuery, która umożliwia przeszukiwanie encji na podstawie właściwości(np: daty utworzenia), wartości pól oraz metadanych(np: typ encji). W powyższym przykładzie została wykorzystana metoda count, która zwraca prawdę(1) w przypadku znalezienia węzłów o spełnionych warunkach, w przeciwnym wypadku zwraca fałsz.

Powyższe zapytanie możemy rozumieć następująco:

Znajdź wszystkie węzły(node) typu rekomendacja(recommendation), które przypisane są do węzła książka o id(book_id) oraz, gdzie wartość pola field_feature_1 jest równa pewnej wartości oraz field_feature_1 …, zlicz wystąpienia tych węzłów.

Zapisywanie

Do zapisywania danych zostało wykorzystane również wbudowane API, umożliwiające stworzenie węzła w kodzie.

Na początku wystarczy zadeklarować obiekt pustej klasy oraz zainicjować typ węzła. Funkcja node_object_prepare”  inicjuje kilka podstawowych właściwości m.in datę utworzenia, id użytkownika, który go stworzył oraz sprawia, że węzeł może być dodawany oraz edytowany przez formularz w panelu. Następnie ustawiamy resztę właściwości oraz wartości pól.

Zapisywanie wygląda następująco:

  • jeśli chcemy przypisać wartość: $node->field_nazwa_pola[$node->language][‘value’] = wartosc 
  • jeśli chcemy przypisać referencję do węzła: $node->field_nazwa_pola[$node->language][‘target_id] = id_wezla

node_submit – uzupełnia datę utworzenia oraz autora, jeśli wartości te są puste

node_save – zapisuje węzeł w bazie

To tyle odnośnie zapisywania informacji z pliku XML w bazie. Mam nadzieję, że wpis pomoże osobom chcącym wykonać podobną czynność w Drupalu 7:)

Recent Posts