Tworzenie pola produktu o określonym zakresie z właściwościami PrestaShop 9.2
Przydatna pierwsza integracja Extra Properties polega na prześledzeniu jednego pola od definicji po wszystkie interfejsy, które go używają. Pozwala to wykryć ważniejszą kategorię problemów niż rejestrowanie wielu pól naraz: wartości zapisywane w niewłaściwym sklepie, wyświetlane w nieodpowiednim miejscu lub znikające podczas operacji cyklu życia modułu.
Przykładem jest tutaj data produktu odrębna dla każdego sklepu, używana wewnętrznie przez zespół katalogu. To ograniczone ćwiczenie integracyjne dla wersji 9.2 RC1, a nie pełny samouczek tworzenia modułu. Oficjalne informacje dla programistów określają nowy system jako eksperymentalny, dlatego przed obietnicą długoterminowej zgodności ustal konkretną wersję implementacji i dokładnie ją sprawdź. Informacje dla programistów dotyczące wersji 9.2.
Przed implementacją ustal model danych Extra Properties; poprawny kod integracji nie naprawi niejednoznacznego modelu odpowiedzialności ani tłumaczeń.
Użyj oficjalnego przykładu jako wersjonowanego punktu odniesienia
Zacznij od demoextrafield w oficjalnym repozytorium example-modules. Jego kod pokazuje rejestrację przez registerExtraProperty() i definicje wykorzystujące klasy Extra Property. Domyślna gałąź repozytorium może się zmieniać; zapisz commit użyty w eksperymencie i porównaj argumenty konstruktora z instalacją RC. Kod źródłowy przykładu.
Poniższe polecenia powłoki służą wyłącznie do inspekcji w trybie odczytu w już pobranych kopiach repozytoriów. Nie instalują modułu ani nie zmieniają sklepu:
rg -n 'registerExtraProperty|ExtraPropertyDefinition' demoextrafield
rg -n 'associatedForms|associatedGrids|associatedApis' demoextrafield
rg -n 'unregisterExtraProperty|uninstall' demoextrafield
Przeprowadź podobne wyszukiwanie w rdzeniu wersji kandydującej, aby znaleźć klasę definicji i metodę rejestracji. Przed dostosowaniem przykładu sprawdź sygnaturę, ścieżkę walidacji i zachowanie wartości zwracanej. Jest to szczególnie ważne, gdy przykład zawiera poprawki zgodności nowsze niż testowane archiwum.
Nie modyfikuj klas rdzenia, aby uruchomić niezgodny przykład. Użyj pasującej rewizji przykładu albo po zrozumieniu różnicy dostosuj tylko niewielki obszar integracji.
Opisz kontrakt pola przed rejestracją
Na potrzeby ćwiczenia zdefiniuj datę przeglądu produktu, która może różnić się między sklepami. Jest opcjonalna, wewnętrzna i interpretowana jako data kalendarzowa, a nie moment w określonej strefie czasowej. Brak wartości oznacza, że nie przypisano daty. Nie oznacza dzisiejszej daty.
Ten kontrakt od razu wyznacza przydatne przypadki: zapis daty, jej wyczyszczenie, odrzucenie nieprawidłowej wartości oraz zachowanie innej wartości w drugim sklepie. Zapobiega też zastępowaniu daty znacznikiem czasu podczas importu bez jawnej polityki konwersji.
Poniższa struktura to przykładowa specyfikacja należąca do modułu, a nie API rejestracji PrestaShop. Ma umożliwić przegląd wymagań przed odwzorowaniem ich na zweryfikowany konstruktor:
<?php
return [
'business_name' => 'catalog_review_date',
'entity' => 'product',
'value_semantics' => 'calendar_date',
'varies_by_shop' => true,
'optional' => true,
'public_output' => false,
'owner' => 'catalog_team',
];
Zachowaj to rozróżnienie w implementacji. Skopiowanie do modułu pozornie właściwej tablicy konfiguracyjnej niczego nie rejestruje, chyba że jawnie zaimplementujesz adapter, który ją obsługuje.
Odwzoruj kontrakt na obsługiwaną definicję
Oficjalny kod importuje ExtraPropertyDefinition, ExtraPropertyScope i ExtraPropertyType z PrestaShop\PrestaShop\Core\ExtraProperty\Definition. Jako wzorzec integracji wykorzystaj datę produktu o zakresie sklepu z pasującego przykładu, zamiast wymyślać typ pola lub nazwę metody. Przykład rejestracji.
Dostosowuj po jednej definicji. Wybierz encję, nazwę właściwości, typ i zakres obsługiwane przez wersję kandydującą. Określ planowane powiązania administracyjne i ustawienia widoczności na podstawie zweryfikowanej sygnatury. Przypisz etykietom i opisom domenę tłumaczeń należącą do swojego modułu.
Jawnie obsłuż niepowodzenie rejestracji w istniejącej logice cyklu życia modułu. Częściowa instalacja nie powinna być zgłaszana jako udana tylko dlatego, że istnieje rekord modułu. Ustal, co stanie się z wcześniej zarejestrowanymi definicjami, gdy kolejna rejestracja zawiedzie, i przetestuj ponowną próbę instalacji na jednorazowej bazie danych.
Nie zakładaj, że ogólna lista obsługiwanych encji oznacza automatyczną integrację z każdym formularzem lub siatką danych. Tożsamość encji, identyfikatory formularzy i identyfikatory siatek stanowią odrębne kontrakty. Nieobsługiwane powiązanie wymaga świadomej pracy integracyjnej, a nie zgadywania identyfikatora.
Ukierunkowany fragment rejestracji
Po potwierdzeniu, że konstruktor przykładu pasuje do wersji kandydującej, możesz włączyć ten fragment do istniejącej klasy modułu. Importy umieszcza się na poziomie pliku, a metodę wewnątrz tej klasy. Fragment dostosowuje oficjalny wzorzec pola daty do wewnętrznego pola przeglądu i celowo nie wiąże zasobów API.
use PrestaShop\PrestaShop\Core\ExtraProperty\Definition\ExtraPropertyDefinition;
use PrestaShop\PrestaShop\Core\ExtraProperty\Definition\ExtraPropertyScope;
use PrestaShop\PrestaShop\Core\ExtraProperty\Definition\ExtraPropertyType;
use PrestaShopBundle\Form\Admin\Type\DatePickerType;
use Symfony\Component\Validator\Constraints as Assert;
private function registerCatalogReviewDate(): bool
{
$definition = new ExtraPropertyDefinition(
entityName: 'product',
propertyName: 'catalog_review_date',
type: ExtraPropertyType::DATE,
scope: ExtraPropertyScope::SHOP,
nullable: true,
displayFront: false,
associatedForms: ['product'],
associatedGrids: ['product'],
formType: DatePickerType::class,
constraints: [new Assert\Date()],
labelWording: 'Catalog review date',
labelDomain: 'Modules.Catalogreview.Admin'
);
return $this->registerExtraProperty($definition);
}
Domena tłumaczeń w tym przykładzie należy do modułu o nazwie catalogreview; użyj rzeczywistej domeny swojego modułu. Wywołaj metodę w jego istniejącym procesie instalacji lub aktualizacji i obsłuż wynik false zgodnie z polityką wycofywania tego procesu. Nie przedstawiaj tego fragmentu jako kompletnego modułu gotowego do instalacji.
SHOP określa zakres wartości, a displayFront: false zamiar dotyczący prezentacji. Żadne z nich nie zastępuje opisanych wyżej testów dwóch sklepów ani testów ujawniania danych. Rejestrację trzeba sprawdzić na pasującej wersji kandydującej; ten artykuł nie przedstawia wyników testu wykonania fragmentu.
Sprawdzaj osobno zapis formularza i zachowanie siatki
Utwórz produkt, wybierz sklep A, zapisz datę przeglądu i ponownie otwórz produkt. Odczytana wartość musi odpowiadać przesłanej dacie. Powtórz test z istniejącym produktem i pustą wartością.
Następnie sprawdź nieprawidłowe dane wejściowe przez obsługiwaną ścieżkę zapisu. Przeglądarkowy selektor daty może uniemożliwiać zwykłym użytkownikom wpisanie źle sformatowanej wartości, ale nie dowodzi to walidacji po stronie serwera. Przetestuj obsługiwaną przez moduł ścieżkę przesyłania lub integracji i potwierdź odrzucenie nieprawidłowej wartości bez uszkodzenia poprzedniej.
Jeśli pole jest powiązane z siatką, sprawdź wyświetlanie, filtrowanie i sortowanie tylko tam, gdzie te operacje są rzeczywiście obsługiwane. Widoczna komórka nie dowodzi, że filtrowanie używa tego samego zakresu sklepu co formularz. Użyj dwóch produktów z różnymi datami oraz nieustawionej wartości, aby móc zaobserwować kolejność i zachowanie pustych wartości.
Testuj zmiany języka pracownika niezależnie od zmian zapisanych wartości. Tłumaczenie etykiety nie może zmieniać daty. Jeśli później dodasz właściwość o zakresie języka, przygotuj osobny zestaw testów jej wartości, zamiast uznawać tłumaczenie etykiety za wystarczające pokrycie.
Użyj danych testowych dwóch sklepów, aby wykryć błędy zakresu
Powiąż produkt testowy ze sklepami A i B. Zapisz jedną datę w A, a inną w B. Otwórz ponownie każdy sklep niezależnie i sprawdź każdy mechanizm odczytu API lub eksportu korzystający z tego pola.
Następnie przetestuj produkt powiązany tylko z jednym sklepem. Brak powiązania nie powinien być po cichu traktowany jako pozwolenie na użycie wartości sklepu domyślnego. Udokumentuj reakcję integracji, gdy wywołujący wybiera zakres, który nie ma zastosowania.
Dostępność definicji to kolejny wymiar. Prace nad RC dodają ograniczenia pozwalające udostępniać definicję tylko określonym sklepom. Testuj to niezależnie od wartości dla poszczególnych sklepów: najpierw potwierdź, gdzie pole istnieje, a następnie jaka wartość jest odczytywana w każdym dozwolonym kontekście. Ograniczenia sklepów dla definicji.
Kontekst administracyjny wszystkich sklepów wymaga osobnego przypadku testowego. Nie zakładaj, czy powinien nadpisywać wartości, wyświetlać wspólną wartość czy wymagać jawnego wyboru. Sprawdź zachowanie wersji kandydującej i zdecyduj, czy moduł może bezpiecznie udostępniać tę operację. Jeśli działanie biznesowe ma sens tylko dla jednego sklepu, wymagaj jego wyboru.
Sprawdź udostępnianie przez API jako osobny kontrakt
Pole przeznaczone wyłącznie do użytku wewnętrznego należy sprawdzić w każdym włączonym interfejsie odpowiedzi. Jeśli udostępnianie przez API jest częścią funkcji, sprawdź wygenerowany schemat i rzeczywistą odpowiedź zainstalowanego modułu zasobów. Używaj udokumentowanych tras wersji kandydującej; nie wyprowadzaj punktów końcowych z nazwy właściwości.
Zapisz zachowanie odczytu i zapisu dla wartości prawidłowej, pustej i nieprawidłowej. Sprawdź, czy właściwy kontekst sklepu dociera do operacji na encji. Potwierdź również, że klient bez uprawnienia do operacji nadrzędnej nie może jej wykonać tylko dlatego, że wartość jest dodatkową właściwością.
Nie traktuj odpowiedzi API uzyskanej z innej wersji modułu jako uniwersalnej. Zachowaj niewielki zestaw danych testowych kontraktu wraz z parą wersji i oczekiwaną strukturą. Przy przyszłej aktualizacji porównaj schemat i zachowanie przed ponownym wygenerowaniem klienta.
W przypadku dostępu od strony sklepu udowodnij brak ujawnienia, jeśli pole jest wewnętrzne: sprawdź wyrenderowaną stronę i odpowiednie struktury danych pod kątem przypadkowego udostępnienia. Sam zamiar wykorzystania administracyjnego nie gwarantuje nieobecności we wszystkich ścieżkach prezentacji.
Ograniczenia i usuwanie wymagają testów aktualizacji
W cyklu RC projekt zmienił przechowywanie ograniczeń w kierunku reprezentacji DSL zamiast serializacji PHP. To powód, aby używać natywnego cyklu życia definicji, zamiast utrzymywać w bazie ręcznie przygotowane wartości serializowane. Zmiana utrwalania ograniczeń.
Przetestuj aktualizację modułu z istniejącymi wartościami. Jeśli pole staje się bardziej restrykcyjne, zidentyfikuj rekordy, które nie spełniają nowej reguły, zanim ją wymusisz. Rutynowa edycja produktu nie powinna niespodziewanie zawodzić dlatego, że starej wartości nigdy nie zmigrowano.
Zmiana nazwy właściwości jest migracją danych, a nie tylko zmianą etykiety. Zaplanuj przeniesienie wartości i przejście mechanizmów odczytu. Jeśli z właściwości korzystają zewnętrzni klienci, zmiana wpływa również na ich kontrakt.
Na koniec przetestuj osobno wyłączenie, ponowne włączenie i odinstalowanie. Moduł komercyjny powinien mieć udokumentowaną politykę przechowywania danych. Wyeksportuj wartości testowe, wykonaj planowane usuwanie i sprawdź, co pozostało. Nie kopiuj destrukcyjnego czyszczenia z demonstracji tylko dlatego, że porządkuje instalację testową.
Wynikiem tego ćwiczenia powinna być mała integracja z jawnym zakresem, zweryfikowanym zapisem i znanym cyklem życia. Gdy jedno pole działa poprawnie, kolejne właściwości mogą korzystać z tej samej dyscypliny projektowej bez powtarzania pracy rozpoznawczej ani opierania się na niezweryfikowanych założeniach dotyczących API.
Aby poznać kontekst platformy, zobacz nasz przewodnik tworzenia modułów PrestaShop 9 i zastosuj opisane wyżej kontrole dla konkretnej wersji do ocenianej instalacji.
Wybierając rozszerzenie, przejrzyj moduły PrestaShop 9 od PrestaSuite i porównaj udokumentowaną obsługę wersji oraz wymagania integracyjne z własnymi wynikami testów.