Domain Facades
Facades in Thelia 3 are the main entry point for business logic. They coordinate several services and expose a single API for common operations.
Purpose
A facade does four things:
- Combines several service calls into a single method, so a controller does not have to wire them together.
- Holds the business rules for its domain: validation, authorization, and side effects.
- Gives easy access to session state, such as the current cart or customer.
- Acts as the single source of truth for its domain operations.
Available facades
These are the four facades you will use most often in a front office.
| Facade | Namespace | Purpose |
|---|---|---|
CartFacade | Thelia\Domain\Cart | Cart operations, items, addresses |
CustomerFacade | Thelia\Domain\Customer | Authentication, registration, profile |
OrderFacade | Thelia\Domain\Order | Order creation |
CheckoutFacade | Thelia\Domain\Checkout | Checkout process orchestration |
These four are the most common front-office facades, but they are not the only ones. The core ships around sixteen domain facades. The others are organized by domain under Thelia\Domain\:
AddressFacadeinThelia\Domain\AddressingShippingFacadeinThelia\Domain\ShippingProductFacadeandPSEFacadeinThelia\Domain\Catalog\ProductCategoryFacadeinThelia\Domain\Catalog\CategoryBrandFacadeinThelia\Domain\Catalog\BrandCurrencyFacadeinThelia\Domain\Catalog\CurrencyTaxFacadeinThelia\Domain\Catalog\TaxMediaFacadeinThelia\Domain\MediaContentFacadeinThelia\Domain\CMS\ContentLocalizationFacadeinThelia\Domain\Localization
Some catalog facades are nested deeper than the top-level domain, such as Thelia\Domain\Catalog\Product, so confirm the exact namespace against the class file before importing it.
CartFacade
Manages shopping cart operations.
Location: core/lib/Thelia/Domain/Cart/CartFacade.php
Usage
<?php
declare(strict_types=1);
use Thelia\Domain\Cart\CartFacade;
use Thelia\Domain\Cart\DTO\CartItemAddDTO;
use Thelia\Domain\Cart\DTO\CartItemDeleteDTO;
use Thelia\Domain\Cart\DTO\CartItemUpdateQuantityDTO;
final readonly class CartController
{
public function __construct(
private CartFacade $cartFacade,
) {}
public function addToCart(int $productId, int $productSaleElementId, int $quantity): void
{
$cart = $this->cartFacade->getOrCreateFromSession();
$dto = new CartItemAddDTO(
cart: $cart,
productId: $productId,
productSaleElementId: $productSaleElementId,
quantity: $quantity,
);
$cartItem = $this->cartFacade->addItem($dto);
}
public function removeFromCart(Cart $cart, int $cartItemId): void
{
$dto = new CartItemDeleteDTO(cart: $cart, cartItemId: $cartItemId);
$this->cartFacade->removeItem($dto);
}
public function updateQuantity(Cart $cart, int $cartItemId, int $newQuantity): void
{
$dto = new CartItemUpdateQuantityDTO(
cart: $cart,
cartItemId: $cartItemId,
quantity: $newQuantity,
);
$cartItem = $this->cartFacade->updateItemQuantity($dto);
}
}
Methods
| Method | Description |
|---|---|
addItem(CartItemAddDTO) | Add product to cart |
removeItem(CartItemDeleteDTO) | Remove item from cart |
updateItemQuantity(CartItemUpdateQuantityDTO) | Update item quantity |
setDeliveryAddress(CheckoutDTO) | Set delivery address |
setInvoiceAddress(CheckoutDTO) | Set invoice address |
setDeliveryModule(CheckoutDTO) | Select shipping method |
setPaymentModule(CheckoutDTO) | Select payment method |
recalculatePostage(Cart) | Force shipping recalculation |
reset(bool) | Reset cart data |
getCartFromSession() | Get current cart (nullable) |
getOrCreateForCustomer(Customer) | Get or create a cart for a given customer |
getOrCreateFromSession() | Get or create cart from the current session |
getDeliveryAddressId() | Get selected delivery address |
getInvoiceAddressId() | Get selected invoice address |
getDeliveryModuleId() | Get selected shipping module |
getPaymentModuleId() | Get selected payment module |
CustomerFacade
Manages customer authentication and account operations.
Location: core/lib/Thelia/Domain/Customer/CustomerFacade.php
Usage
<?php
declare(strict_types=1);
use Thelia\Domain\Customer\CustomerFacade;
use Thelia\Domain\Customer\DTO\CustomerRegisterDTO;
final readonly class AccountController
{
public function __construct(
private CustomerFacade $customerFacade,
) {}
public function getCurrentUser(): ?Customer
{
return $this->customerFacade->getCurrentCustomer();
}
public function isAuthenticated(): bool
{
return $this->customerFacade->isLoggedIn();
}
public function register(CustomerRegisterDTO $dto): Customer
{
return $this->customerFacade->register($dto);
}
public function logout(): void
{
$this->customerFacade->logout();
}
}