person-using-credit-card

Drupal Commerce - Sprzedawaj produkty elektroniczne

Drupal Commerce to kompleksowe narzędzie do sprzedaży produktów fizycznych przez internet. W tym wpisie przedstawię, w jaki sposób niewielkim nakładem pracy skonfigurować sklep tak, aby sprzedawać produkty elektroniczne: ebooki, muzykę czy jakiekolwiek inne pliki.

W poprzednim wpisie dotyczącym budowania sklepu w Drupalu pokazaliśmy, jak opracować moduł Commerce, żeby zacząć sprzedawać różnego rodzaju towary. Ten cel na pewno można osiągnąć na kilka sposobów, a jednym z nich jest połączenie mocy Commerce i modułu Group.

Dlaczego ten sposób?

  • Mało kodowania.
  • Uprawnienia załatwione przez system i moduł Group.
  • Sprzedajesz dostęp do prywatnej grupy, w której klient widzi jej zawartość.
  • Łatwe rozszerzenie systemu do sprzedaży np. kursów wideo składających się z wielu części.
  • Pliki ładowane są poprzez pole uploadu, dołączone do rodzaju zawartości. 
  • Produkt zawiera prostą referencję (pole) do grupy, do której po opłaceniu ma nadawać dostępny.

Jak to działa od strony admina

  1. Sprzedajesz dostęp do grupy gdzie dostępne są pliki do pobrania
  2. Do treści powiązanej z grupą dodajesz prywatny plik
  3. Tworzysz produkt (Commerce) i jako referencje podajesz wybraną grupę

Jak to działa od strony klienta

  1. Produkt dodany do koszyka.
  2. Tworzenie konta klientowi podczas procesu zakupu.
    Trzeba ustawić to w konfiguracji Commerce. Posiadanie konta jest konieczne do tego, aby przypisać klienta do grupy gdzie dodane są pliki, do których ma otrzymać dostęp po udanej płatności.
  3. Przekierowanie na płatność.
  4. Po zakończonej płatności nadawane są dostępy do grupy.
    Dodawanie klienta do grupy działa z automatu i realizowane jest przez dodatkowy kod, który trzeba dopisać.
  5. Użytkownik jest przekierowany na profil, gdzie ma dostęp do plików oraz grup.

Konfiguracja

Zainstaluj moduły Commerce i Group wraz zależnościami. 

Group

Oprócz samego modułu Group włącz moduł Group Node (jest częścią modułu Group), dzięki niemu będzie można ustalić, który rodzaj zawartości będzie powiązany z daną grupą.

Dodaj typ grupy - podstrona admin/group/types

Na tym etapie, w edycji typu, możesz dodać pola, ustawić jej uprawnienia, role oraz określić rodzaj zawartości powiązany z grupą.

group type

Dodaj nową grupę - podstrona admin/group

group add


Jeżeli stworzony jest tylko jeden typ grupy, to każda grupa będzie tworzona właśnie w tym typie. Jeżeli jest więcej, to podczas dodawania grupy wybierz, do którego typu ma należeć.

Na stronie admin/structure/types dodaj rodzaj zawartości, który będzie wykorzystany jako typ zawartości w grupie. 

Dodaj do niego prywatne pole pliku.

Upewnij się, że masz poprawnie skonfigurowany prywatny system plików w swoim Drupalu. Wtedy w konfiguracji pola ustaw, aby plik był przechowywany jako prywatny, dzięki temu nie będzie widoczny dla osób bez uprawnień.

private files

Stwórz typ zawartości powiązany z grupą.

Na stronie admin/group/types/manage/GROUPTYPENAME/content znajduje się lista rodzajów zawartości, które możesz powiązać z danym typem grupy.

Zrobisz to poprzez przycisk Instaluj

Dzięki temu będzie możliwe tworzenie treści przeznaczonej tylko dla członków danej grupy. Tym samym każdy plik połączony z treścią też będzie do wglądu wyłącznie dla osób w grupie.

group install node

Dodaj do grupy treść z plikiem.

Edytuj grupę i wejdź w zakładkę Nodes.

Tutaj możesz dodać do grupy istniejącą treść lub stworzyć nową. 
Tworząc nowy wpis dodaj do niego plik. Teraz możesz przetestować, czy rzeczywiście do pliku w grupie mają dostęp tylko jej członkowie. 

Commerce

Dodaj nowy typ produktu, który będzie służył do sprzedaży produktów elektronicznych. Szczegółowy opis jak to zrobić, znajdziesz w poprzedniej części dot. konfiguracji Commerce.

W typie produktu dodaj nowe pole, które będzie referencją do utworzonej grupy. 

Typ pola: Reference -> Other…
Typ pozycji: Group

Pole może być jedno lub wielowartościowe.

W ustawieniach pola zaznacz typy grup, do których ma odnosić się referencja.

group types

W Commerce powinieneś mieć skonfigurowaną co najmniej jedną metodę płatności.

To właśnie po udanym procesie zakupu, gdy zamówienie przejdzie w status completed zostanie przyznane członkostwo do wybranej grupy.

Kod

Główna funkcjonalność, czyli przypisanie klienta do wybranej grupy z plikiem odbywa się przy pomocy kodu php, który trzeba samodzielnie napisać np. w nowym module.

Przykładowy kod, który przypisuje klienta do grup z pola referencji, zbudowany jest przy pomocy EventSubscriber ponieważ nasz system ma nasłuchiwać i reagować, gdy zamówienie jest opłacone.

Rozwiązanie jakie zastosowałem.

Stworzyłem nowy moduł commerce_groups
W module dodany jest service - plik commerce_groups.services.yml

services:
  commerce_groups:
    class: '\Drupal\commerce_groups\EventSubscriber\AttachUserToGroup'
    arguments: ['@entity_type.manager']
    tags:
      - { name: 'event_subscriber' }

Service jest zdefiniowany w klasie AttachUserToGroup

Dodany jest jeden argument - entity_type.manager, gdyż potrzebowałem wstrzyknąć go jako zależność w konstruktorze obiektu (Dependency Injection)

Tag event_subscriber mówi Drupalowi, że klasa chce rejestrować zdarzenia wywołane przez inne moduły. 

Zdarzenie, które chcemy rejestrować, definiuje się w metodzie getSubscribedEvents w klasie AttachUserToGroup, która dziedziczy po EventSubscriberInterface
 

static function getSubscribedEvents() {
  $events['commerce_order.place.post_transition'] = ['orderCompleteHandler'];

  return $events;
}

commerce_order.place.post_transition jest zdarzeniem (event) wywołanym po udanej płatności za produkt.

orderCompleteHandler to metoda, która zawiera całą logikę tego co ma się dziać gdy dane zdarzenie nastąpi. 

Poniżej znajduje się przykładowy, działający kod, który po udanej transakcji przypisuje klienta do wszystkich grup z pola referencji field_group_ref.

    /**
     * Add customer to group.
     *
     * @param WorkflowTransitionEvent $event
     * @throws \Drupal\Core\Entity\EntityStorageException
     */
    public function orderCompleteHandler(WorkflowTransitionEvent $event) {
      /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
      $order = $event->getEntity();
      $uid_value = $order->get('uid')->getValue();

      $gids = [];
      foreach ($order->getItems() as $order_item) {
        /** @var \Drupal\commerce_product\Entity\ProductVariation $product_variation */
        $product_variation = $order_item->getPurchasedEntity();
        $product = $product_variation->getProduct();
        $group_value = $product->get('field_group_ref')->getValue();
        foreach ($group_value as $group) {
          $gids[] = $group['target_id'];
        }
      }

      /** @var \Drupal\user\Entity\User $account */
      $account = User::load($uid_value[0]['target_id']);

      foreach ($gids as $gid) {
        /** @var \Drupal\group\Entity\Group $group */
        $group = Group::load($gid);
        if ($group) {
          $group->addMember($account);
          $group->save();
        }
      }
    }

Wyświetlanie plików na grupie.

Najszybszą metodą jest stworzenie widoku (Views), który na stronie głównej grupy wyświetli wszystkie pliki dodane w treści powiązanej z grupą.
 

file list

Podsumowanie

Commerce i Group to dwa duże, aktywnie wspierane moduły, które w połączeniu ze sobą pokazują prawdziwą moc Drupala. W łatwy sposób, z minimalną ilością kodowania, jesteśmy w stanie zbudować skomplikowany i rozszerzalny system do sprzedaży produktów fizycznych jak i elektronicznych. Oba moduły będą dostępne w Drupal 9, najnowszej wersji systemu.

3. Najlepsze praktyki zespołów programistycznych