sylius/contact
Sylius Contact plugin adds a configurable contact form and message management to Sylius stores, letting customers send inquiries while administrators review, organize, and respond to submissions from the admin panel.
sylius/contact is a split read-only subpackage of the Sylius monorepo — it ships only the domain model for a contact request (a ContactRequest entity with firstName, lastName, email, message, createdAt, plus ContactRequestInterface and a ContactRequestRepositoryInterface). There is no controller, no form type, no route, and no DI extension here.
Minimal steps:
composer require this directly. It is archived and marked read-only; the canonical dependency is sylius/sylius or, if you're building standalone, sylius/contact-bundle. The component is pulled in transitively.src/Model/ContactRequest.php and src/Model/ContactRequestInterface.php. That's essentially the whole surface area. Read the interface first, then the concrete class to see default property initialization.sylius.contact.repository.contact_request (or similar) available through the resource system — retrieve the repository from the container and call add() / flush() (from Sylius\Resource\Doctrine\ORM\EntityRepository) with a ContactRequest you construct manually or via the resource factory.$contactRequest = new ContactRequest();
$contactRequest->setFirstName('Ada');
$contactRequest->setEmail('[email protected]');
$contactRequest->setMessage('Hello');
$repository = $container->get('sylius.contact.repository.contact_request');
$repository->add($contactRequest);
If you're on a recent Sylius version, prefer sylius/contact-bundle + the ContactRequest resource alias in config/packages/_sylius.yaml so the factory and repository are wired for you.
Treat this as a model-only package in a larger stack. The realistic patterns are:
ContactRequest is a Sylius Resource. Configure or override the resource alias (sylius.contact.contact_request) to swap in your own class, repository, or factory. This is the standard Sylius extension point and the one you'll use most days.Sylius\Component\Contact\Model\ContactRequest (or better, implement ContactRequestInterface) and override the resource's classes.model in YAML. This is how you add fields like subject, phone, or a consent boolean without forking the component.classes.repository to add domain methods (findByEmailSince(), countSince()) instead of leaking QueryBuilder logic into services.sylius/contact-bundle, which registers the resource, the form type, and the controller. The component is the DTO/entity you actually write assertions against in tests.ContactRequestRepositoryInterface, never the concrete class, and let Sylius's resource registry resolve the implementation.A common pattern is to keep the component untouched and wrap the submission flow in your own service:
final class SubmitContactRequest
{
public function __construct(
private ContactRequestRepositoryInterface $requests,
) {}
public function __invoke(ContactRequestInterface $request): void
{
$this->requests->add($request);
}
}
Sylius/Sylius, not here. Don't pin your project to this repo intentionally — pin sylius/sylius or the bundle.composer require sylius/contact to give you a working contact page will disappoint. Only the bundle provides that wiring.ContactRequestInterface is the contract; the concrete ContactRequest has nullable/?string typed properties and defaults set in the constructor. If you override, your subclass must remain compatible (return types, nullable signatures).createdAt is not auto-populated by the component. You either set it manually or rely on the bundle's factory / Doctrine lifecycle callbacks you configure yourself. This is a classic silent bug — requests land with null timestamps.bin/console debug:container sylius.contact and bin/console debug:config sylius_resource contact_request in a Sylius app reveal the resolved classes. If the wrong model is being persisted, your resource override YAML isn't loaded (check bundle order).classes.model, classes.repository, classes.factory, and (in the bundle) classes.form under sylius_resource. These are your levers — you should never need to touch the component's source.sylius/sylius version you actually run.How can I help you explore Laravel packages today?