ekyna/commerce
Ekyna Commerce is a PHP/Symfony commerce component providing the foundations for catalog, orders, customers, taxes, and related domain logic. Work in progress with planned cleanup (bundles removal, naming, Doctrine mappings/embeddables) and EU VAT resources.
Installation
composer require ekyna/commerce
Add to composer.json under require if not using Composer directly.
Basic Usage
Initialize a Commerce instance (check for updated class names post-rename):
use Ekyna\Commerce\Commerce;
$commerce = new Commerce();
First Use Case: Product Creation
$product = $commerce->createProduct('Laptop', 999.99);
$product->addAttribute('color', 'black');
$product->addVariant(['size' => '15"']);
Key Files to Explore
src/Ekyna/Commerce/ – Core classes (e.g., Product, Order, Customer).tests/ – Real-world usage examples (if tests exist).README.md – TODO list hints at active development (e.g., Doctrine integration).Product Management
createProduct(), addAttribute(), addVariant().$products = [];
foreach ($skus as $sku) {
$products[] = $commerce->createProduct($sku, $price);
}
Order Processing
$order = $commerce->createOrder($customer);
$order->addItem($product, 2);
$order->calculateTax(); // Hypothetical; check for `TaxResolver`
Customer Segmentation
ManyToOne).
$customer->setGroup($commerce->createCustomerGroup('Premium'));
Doctrine Integration (Future)
Doctrine\Common\Collections for nested objects (e.g., addresses).
// Example (post-rename to `is` getters)
$address = $commerce->createAddress();
$address->setStreet('123 Main St');
$product->setShippingAddress($address);
OrderCreated, InventoryUpdated.class ProductResource extends JsonResource {
public function toArray($request) {
return [
'name' => $this->resource->getName(),
'price' => $this->resource->getPrice(),
'attributes' => $this->resource->getAttributes()->toArray(),
];
}
}
Commerce for unit tests (e.g., createProduct() returns stubs).Naming Inconsistencies
getIsActive() → isActive() (see TODO).setXXXs() clears existing items; use addXXX() for appends.Doctrine Quirks
position indexes for variants).Tax Logic
TaxResolverInterface.
$order->setTaxResolver(new EuTaxResolver());
Attribute Sets
dump($product->getAttributes()) to inspect collections.setXXXs() to prevent silent overwrites.
public function setAttributes(array $attributes) {
if (!empty($this->attributes)) {
throw new \RuntimeException('Use addAttribute() to modify collections.');
}
$this->attributes = $attributes;
}
Custom Resolvers
TaxResolverInterface for region-specific rules.class UsTaxResolver implements TaxResolverInterface {
public function resolve(Order $order) { ... }
}
Attribute Types
Attribute class for custom validation (e.g., ColorAttribute).class ColorAttribute extends Attribute {
public function isValid($value) {
return in_array($value, ['red', 'green', 'blue']);
}
}
Print Catalog
Product::toString() or create a CatalogPrinter service.$catalog = new CatalogPrinter();
echo $catalog->render($products);
bind()).
$app->bind(TaxResolverInterface::class, function ($app) {
return new EuTaxResolver();
});
How can I help you explore Laravel packages today?