Poznaj nowość Syliusa 1.13 – atrybuty – i sprawdź, jak wpływają na wygodę pracy programistów.
UWAGA! Ten tekst został napisany przez dewelopera dla deweloperów. Jeśli nie znasz podstaw PHP, możesz mieć trudność ze zrozumieniem treści. 😉
W zmieniającym się świecie web developmentu Sylius od dawna stara się ułatwiać życie programistom. Wprowadzenie atrybutów to kolejny krok w dobrym kierunku. Profit? Mniej błędów, mniej przeklikiwania się przez pliki konfiguracyjne i więcej logiki tam, gdzie jej miejsce: w kodzie.
Sylius od lat pozwalał korzystać z adnotacji Symfony / Doctrine do definiowania metadanych usług i encji. Problem w tym, że domyślnie opierał się na YAML-u, a do reszty konfiguracji używał XML-a. Efekt? Kod jedno, konfiguracja drugie. Trzeba było utrzymywać osobne pliki, przełączać się między nimi, a błędy wynikające z niespójności były na porządku dziennym. Na dodatek format notacji w kodzie źródłowym (XML) często różnił się od tego, którego używało się w projekcie (YAML). Istny chaos.
Żeby to ogarnąć, można było przenieść metadane bliżej kodu – z pomocą adnotacji albo atrybutów. Oba rozwiązania ułatwiają zawodowe życie: mniej skakania między kontekstami, mniejsze obciążenie poznawcze, lepszy DX. Adnotacje służyły nam przez lata, ale dziś to już przeszłość. PHP 8 gwarantuje natywną obsługę atrybutów, czyli możliwość definiowania metadanych bezpośrednio w kodzie, dokładnie tam, gdzie są potrzebne.
Atrybuty przypisujemy bezpośrednio do klasy, metody lub właściwości. Dzięki temu kod jest czytelniejszy, mniej podatny na błędy i łatwiejszy do ogarnięcia – także dla IDE, bo atrybuty są częścią samego języka, nie tylko frameworkowym dodatkiem.
To przekłada się na lepszą jakość i łatwiejsze utrzymanie kodu. Metadane są pod ręką, nie trzeba ich szukać w plikach konfiguracyjnych. Ten kierunek doskonale wpisuje się w aktualne trendy PHP i dobre praktyki programistyczne.
Atrybuty to też większe bezpieczeństwo. Widać od razu, co się dzieje, bez domysłów i czasochłonnego przekopywania przez YAML-e czy XML-e. Mniej miejsca na błąd, szybsze debugowanie, krótszy czas developmentu. Same plusy.
Wprowadzenie atrybutów w Syliusie to duży krok naprzód w kontekście personalizacji działania frameworka. Dzięki temu rozszerzeniu konfiguracja trafia dokładnie tam, gdzie jej miejsce, tj. bezpośrednio do kodu, którego dotyczy. To znacząco upraszcza proces developmentu i eliminuje zbędne przełączanie się między klasami a plikami konfiguracyjnymi.
Spójrzmy na przykład. Tak wygląda niestandardowa akcja promocyjna w Syliusie w wersji przed atrybutami:
// src/Promotion/Action/FreeItemPromotionActionCommand.php
<?php
declare(strict_types=1);
namespace App\Promotion\Action;
use Sylius\Component\Promotion\Action\PromotionActionCommandInterface;
use Sylius\Component\Promotion\Model\PromotionInterface;
use Sylius\Component\Promotion\Model\PromotionSubjectInterface;
final class FreeItemPromotionActionCommand implements PromotionActionCommandInterface
{
public function execute(PromotionSubjectInterface $subject, array $configuration, PromotionInterface $promotion): bool
{
// Promotion logic
}
public function revert(PromotionSubjectInterface $subject, array $configuration, PromotionInterface $promotion): void
{
// Promotion reverting logic
}
}
# services.yaml
services:
# other definitions
App\Promotion\Action\FreeItemPromotionActionCommand:
tags:
- {
name: sylius.promotion_action,
type: free_item,
label: 'app.form.promotion_action.free_item',
form_type: App\Form\Type\Promotion\Action\FreeItemConfigurationType
}
Wygląda znajomo? Do działania wymagane są konkretne tagi – nawet jeśli autowiring działa, Sylius i tak nie wie, jak je ustawić. A teraz dorzućmy do tego XML, bo niektórzy wolą tę drogę:
# services.xml
<service id="App\Promotion\Action\FreeItemPromotionActionCommand">
<tag name="sylius.promotion_action" type="free_item" label="app.form.promotion_action.free_item" form-type="App\Form\Type\Promotion\Action\FreeItemConfigurationType" />
</service>
# services.yaml
App\Promotion\Action\FreeItemPromotionActionCommand:
tags:
- {
name: sylius.promotion_action,
type: free_item,
label: 'app.form.promotion_action.free_item',
form_type: App\Form\Type\Promotion\Action\FreeItemConfigurationType
}
I tu robi się nieciekawie, bo np. form-type w XML to form_type w YAML. Mała różnica, a wystarczy, żeby stracić godziny na debugging.
A teraz wersja z nowymi atrybutami Syliusa:
// src/Promotion/Action/FreeItemPromotionActionCommand.php
<?php
declare(strict_types=1);
namespace App\Promotion\Action;
use Sylius\Bundle\PromotionBundle\Attribute\AsPromotionAction;
use Sylius\Component\Promotion\Action\PromotionActionCommandInterface;
use Sylius\Component\Promotion\Model\PromotionInterface;
use Sylius\Component\Promotion\Model\PromotionSubjectInterface;
use App\Form\Type\Promotion\Action\FreeItemConfigurationType;
#[AsPromotionAction(type: 'free_item', label: 'app.form.promotion_action.free_item', formType: FreeItemConfigurationType::class)]
final class FreeItemPromotionActionCommand implements PromotionActionCommandInterface
{
public function execute(PromotionSubjectInterface $subject, array $configuration, PromotionInterface $promotion): bool
{
// Promotion logic
}
public function revert(PromotionSubjectInterface $subject, array $configuration, PromotionInterface $promotion): void
{
// Promotion reverting logic
}
}
Proste, prawda?
Atrybuty w praktyce – mniej chaosu, więcej kontroli
Powyższy kod świetnie pokazuje, co tak naprawdę zyskujemy dzięki atrybutom w Syliusie. To zupełnie inne, deklaratywne podejście, które upraszcza strukturę projektu. Zamiast rozrzucać metadane po plikach YAML czy XML, dodajemy je tam, gdzie mają sens — bezpośrednio do klas, metod czy właściwości. Taki sposób pracy nie tylko przyspiesza development, ale też sprawia, że konfiguracja staje się bardziej intuicyjna, łatwiejsza do znalezienia i mniej podatna na błędy. Przykład? Routing. Dzięki Symfony możemy powiązać atrybutami konkretne ścieżki z kontrolerami bez konieczności “grzebania” w osobnych plikach konfiguracyjnych. Wszystko to idzie w parze z aktualnymi standardami w świecie PHP: mniej “boilerplate’u”, więcej przejrzystości. Uporządkowana baza kodu to szybsze wdrożenie nowych osób, mniej problemów w utrzymaniu i mniejsze ryzyko bugów.
Krótko mówiąc: atrybuty w Syliusie to realny upgrade dla każdego dewelopera. Mniej frustracji, więcej konkretów. Dokładnie tak, jak powinno być w narzędziu tworzonym przez programistów dla programistów.
#[AsCommandDataTransformer]
#[AsDocumentationModifier]
#[AsPaymentConfigurationProvider]
#[AsOrderProcessor]
#[AsCartContext]
#[AsCatalogPromotionApplicatorCriteria]
#[AsCatalogPromotionPriceCalculator]
#[AsEntityObserver]
#[AsOrderItemUnitsTaxesApplicator]
#[AsProductVariantMapProvider]
#[AsTaxCalculationStrategy]
#[AsUriBasedSectionResolver]
#[AsLocaleContext]
#[AsCurrencyContext]
#[AsProductVariantResolver]
#[AsTaxCalculator]
#[AsShippingCalculator]
#[AsShippingMethodResolver]
#[AsShippingMethodRuleChecker]
#[AsPromotionAction]
#[AsPromotionCouponEligibilityChecker]
#[AsPromotionEligibilityChecker]
#[AsPromotionRuleChecker]
#[AsAttributeType]
#[AsChannelContext]
#[AsRequestBasedChannelResolver]
#[AsOrderItemsTaxesApplicator]
#[AsOrdersTotalsProvider]
#[AsPaymentMethodsResolver]
#[AsGatewayConfigurationType]
Nowa składnia w Syliusie to nie tylko kosmetyczna zmiana, ale konkretne korzyści dla devów:
Zintegrowanie metadanych bezpośrednio z kodem zmniejsza ryzyko błędów związanych z zewnętrznymi plikami konfiguracyjnymi.
Atrybuty poprawiają wykrywalność konfiguracji, ponieważ znajdują się bezpośrednio w kodzie, którego dotyczą.
Większa kontrola – atrybuty dają pełną swobodę definiowania niestandardowych zachowań (jak własne procesory zamówień czy reguły promocji) bez konieczności przedzierania się przez złożoną dokumentację.
Wprowadzenie atrybutów do Syliusa to nie była decyzja odgórna, ale efekt świetnej współpracy całej społeczności. Na szczególne wyróżnienie zasługują: Jakub Tobiasz, Félix Fouillet, Jan Góralski i Kamil Grygierzec. Wielkie dzięki za Wasz wkład!
Choć Sylius nadal pozwala konfigurować wszystko po staremu, przez YAML czy XML, to atrybuty dają realną alternatywę. I właśnie o to chodzi w dobrym DX: o wybór. Możesz pracować tak, jak Ci wygodnie — bez narzucania konkretnego stylu.
Od wersji 1.13 atrybuty to już nie ciekawostka, tylko konkretne ułatwienie. Więcej kontroli, większa przejrzystość, mniej klikania i przeklikiwania. A Sylius rozwija się dalej, więc możesz być pewien, że nie powiedzieliśmy jeszcze ostatniego słowa.
PS. Atrybuty to dopiero początek — wrócimy do nich jeszcze nie raz. Stay tuned ;)