Nowy Dla programisty, PrestaShop

Wyświetlenie nazwy przewoźnika na liście zamówień

Ten artykuł dotyczy PrestaShop w wersji 1.7.7 i wyższych.

Lista zamówień w PrestaShop posiada sporo informacji na ich temat, jedną z brakujących w standardzie informacji jest jednak nazwa przewoźnika. W tym artykule omówię moduł, który opublikowałem tutaj:

https://github.com/kpodemski/kporderlistcarrier

Moduł ten pozwala na dodanie nazwy przewoźnika na listę zamówień i filtrowanie po nim. Całość opiera się na Hook, które dostępne są w standardzie PrestaShop ale dotyczą już strony przeniesionej na Symfony, dlatego moduł zadziała tylko dla PrestaShop 1.7.7+.

Jak to działa? Komponent Grid

W tym momencie każda lista elementów pobranych z bazy danych, na stronach które zostały zmigrowane do Symfony w oprogramowaniu PrestaShop, korzysta z nowego komponentu: Grid.

Komponent ten jest podobny do HelperList, którego możecie kojarzyć ze starszych wersji PrestaShop. HelperList nadal jest obecny w silniku, zaleca się jednak by korzystać z nowoczesnej alternatywy, którą jest właśnie Grid. Za pomocą tego komponentu wyświetlimy listę elementów np. z bazy danych. Dodamy opcje wyszukiwania po niej, sortowania, możemy również umożliwić wykonywanie różnych operacji na rekordach, usuwanie, edycja czy inne, które możemy zdefiniować również samemu.

Szczegółowe informacje na temat komponentu są dostępne w dokumentacji dla developerów PrestaShop, możecie tam znaleźć przykłady użycia, domyślne typy danych i wiele więcej na temat tego komponentu.

Przykładowy moduł

Rozwiązanie, do którego link umieściłem wyżej, korzysta z możliwości modyfikacji list stworzonych przez ten komponent, bezpośrednio z poziomu modułu. Jak możecie zauważyć, przypiąłem się do dwóch Hook’ów:

/** @var array */
public const MODULE_HOOKS = [
    'actionOrderGridDefinitionModifier',
    'actionOrderGridQueryBuilderModifier',
];

Nazwy tych Hook są dynamiczne. Możecie zamiast do listy zamówień, przypiąć się do listy klientów zamieniając Order na Customer. Miejsce, w którym jeden z tych Hook się wykonuje to np. plik /src/Core/Grid/GridFactory.php.

/**
 * {@inheritdoc}
 */
public function getGrid(SearchCriteriaInterface $searchCriteria)
{
    $definition = $this->definitionFactory->getDefinition();
    $data = $this->dataFactory->getData($searchCriteria);

    $this->hookDispatcher->dispatchWithParameters('action' . Container::camelize($definition->getId()) . 'GridDataModifier', [
        'data' => &$data,
    ]);

    $filterForm = $this->filterFormFactory->create($definition);
    $filterForm->setData($searchCriteria->getFilters());

    return new Grid(
        $definition,
        $data,
        $searchCriteria,
        $filterForm
    );
}

Nazwa Hook tworzona jest następująco: action<Identyfikator danego kompnentu>GridDataModifier. Identyfikator to np.

const GRID_ID = 'customer';

Stała ta jest zdefiniowana w pliku /src/Core/Grid/Definition/Factory/CustomerGridDefinitionFactory.php

Gdy już jesteśmy przypięci do odpowiednich miejsc w silniku, możemy wykonać nasz kod. Jak to zwykle bywa, w implementacji danego Hook dostajemy w tablicy $params odpowiednie „narzędzia” do tego aby móc zmodyfikować wybrany element oprogramowania.

W przypadku hookActionOrderGridDefinitionModifier mamy dostęp do definicji komponentu Grid, która kryje się za implementacją bazującą na GridDefinitionInterface. Za pomocą zmiennej $definition w kodzie możemy manipulować kolumnami na listingu. W przypadku przykładowego modułu dodajemy kolumnę carrier_name, którą dodajemy za kolumną payment. Skąd wiemy, że kolumna z nazwą płatności to payment? Możemy posłużyć się chociażby narzędziami dla programistów w przeglądarce Chrome:

Dalej, przypisujemy do kolumny filtr, tak abyśmy mogli poszukać zamówień, które powinny zostać wysłane przewoźnikiem, którego szukamy:

$filters = $definition->getFilters();
$filters->add((new Filter(static::CARRIER_FIELD_NAME, TextType::class))
    ->setTypeOptions([
        'required' => false,
    ])
    ->setAssociatedColumn(static::CARRIER_FIELD_NAME)
);

Kod, który pozwala nam pobrać nazwę przewoźnika jest odrobinę bardziej skomplikowany, ale zasada jest ta sama. Dostajemy poprzez argument $params narzędzia do tego by modyfikować pobieranie informacji dla danej listy i robimy z tym to czego potrzebujemy.

Komponent Grid nie operuje na kodzie legacy bazy danych, a Doctrine, dlatego $params[’search_query_builder’] to instancja QueryBuilder’a z Doctrine. W metodzie addSelect możemy… tak, dodać pola, które chcemy pobrać. Działa to bardzo podobnie do klasy DbQuery, którą możecie kojarzyć z niektórych miejsc PrestaShop.

Zagadką dla Was może być to, że w tym miejscu kodu:

$queryBuilder->addSelect(
    'IF(carrier.name = "0", "'.Configuration::get('PS_SHOP_NAME').'", carrier.name) carrier_name'
);

Sprawdzamy czy rekord to nie „0”. Robimy to ponieważ PrestaShop ustawi nam „0” gdy wybierzemy przewoźnika, który jest domyślnie dodawany w instalatorze jako „Odbiór w sklepie”. Jest to relikt przeszłości, który powinien zostać wyprostowany w wersji 8.0 🙂

W następnych fragmentach kodu bazujemy już na kryteriach wyszukiwania, za pomocą tego kodu kontrolujemy to jak sortujemy listing, a także ewentualnie możemy go filtrować.

Dla programistów, którzy pracowali już z Hookami takimi jak actionSomethingListingFieldsModifier cały proces może wydawać się bardzo podobny. I tak oczywiście jest.

Zaawansowane użycie Grid

Oczywiście przykładowy moduł, który daje Wam do dyspozycji to najprostszy przykład tego jak można modyfikować komponent Grid. Jest to bardzo elastyczny mechanizm, który pozwoli Wam dodać własną implementacje różnych działań masowych, które można wykonać na rekordach. Jest też wiele możliwości formatowania danych wyjściowych, itd.

Zachęcam do zapoznania się z dokumentacją dla developerów i sprawdzenia repozytorium z większą ilością przykładowych modułów PrestaShop tutaj.

Zobacz inne