Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Customer Bundle Laravel Package

monofony/customer-bundle

Monofony Customer Bundle provides customer management for Symfony e-commerce applications, including customer entities, profiles, repositories, factories, and related services for integrating account, registration, and address workflows into a storefront.

View on GitHub
Deep Wiki
Context7

Getting Started

Requirements and install. This is a Symfony bundle from the Sylius lineage (Monofony split the customer model out of the user/security model). As of v1.10.0 it explicitly supports PHP 8; earlier releases targeted PHP 7.4+. The Symfony constraint is unchanged by that release, so budget for Symfony 4.4/5.x — PHP 8 support here means "runs on a modern runtime", not "Symfony 6 ready". Install with composer require monofony/customer-bundle, then register the bundle class in config/bundles.php. Confirm the exact FQCN first — ls vendor/monofony/customer-bundle/src — rather than trusting docs written for Sylius.

Where to look first. Read these four files before writing anything:

  1. src/Entity/Customer.php and src/Entity/CustomerInterface.php — the fields you get for free (email, first/last name, gender, birthday, phone, newsletter flag, groups collection) and the methods you're expected to implement.
  2. src/Provider/CustomerProvider.php (and the Context directory if present) — how the "current customer" is resolved from the security token.
  3. DependencyInjection/Configuration.php and Resources/config/services.xml — the semantic config tree (often empty in these bundles) and the real service IDs.
  4. Form/Type/CustomerProfileType.php and CustomerType.php — the ready-made forms you'll embed.

Run bin/console debug:container | grep -i customer immediately afterwards. Service IDs typically follow monofony.repository.customer, monofony.factory.customer, monofony.manager.customer — but the prefix is the single most common source of copy-paste errors from Sylius tutorials.

First use case: profile editing. The bundle is model + forms + services only; it ships no controllers or templates. Wire a small controller that loads the current customer from the provider, creates a form with CustomerProfileType, and flushes via the entity manager. That single flow exercises the entity, the provider, the form, and the mapping — it's the fastest way to validate the install end to end.

Implementation Patterns

Extend the entity, don't use it raw. Real applications need extra columns. Create App\Entity\Customer extends Monofony\...\Entity\Customer and map the base class as a MappedSuperclass, or keep single-table inheritance if you prefer. Then point the bundle at your class with doctrine.orm.resolve_target_entities (the CustomerInterface → App\Entity\Customer mapping). Skipping this step means the bundle's factory keeps instantiating its own class and your custom fields never persist.

Always go through the factory. Use monofony.factory.customer rather than new Customer(). With target-entity resolution in place, the factory returns your subclass; direct instantiation does not. This is the pattern most likely to bite you months later when a custom field mysteriously stays null.

Hooking the customer to your user. If your User entity has a customer association, create the customer in a Doctrine prePersist listener on the user, or in your registration handler, and call setCustomer(). For reading the current one, prefer the bundle's provider over hand-rolling $this->getUser()->getCustomer(), so guest/anonymous flows behave consistently.

Repository queries. The shipped repository exposes email lookups (findOneByEmail, findByEmail). For anything else, extend it, register your class as the repository on the entity mapping, and use createQueryBuilder('o'). Do not add findBy wrappers around the base class — you'll lose the paginator helpers if they exist.

Forms. Embed CustomerProfileType inside your own form type rather than duplicating fields; use CustomerGroupChoiceType for admin assignment and CustomerType for a back-office CRUD screen. Attach your extra validation either in config/validator/ on App\Entity\Customer or via constraints on the extended form. Watch the validation groups — these bundles often validate on the default group only.

Guest checkout and duplicate emails. The registration path is email-only customer → attach credentials later. Guard with a repository lookup and a database unique index on email; under concurrency only the index is reliable. Catch UniqueConstraintViolationException and convert it to a form error rather than letting it 500.

Admin CRUD. The bundle gives you the entity, repository, group choice, and forms — the list/create/edit controllers, routes, and templates are yours. Expect roughly a day of work for a functional back-office screen, plus translations.

Gotchas and Tips

PHP 8 is supported; PHP 8.x is not a blanket guarantee. v1.10.0 is a single-line release adding PHP 8 compatibility — the code was not rewritten for it. Pin the exact version, run your test suite on the specific minor you deploy (8.0/8.1 are the realistic targets; 8.2+ dynamic-property and deprecation behaviour is untested territory here), and expect deprecation notices rather than hard failures. If you were previously holding the project back on PHP 7.4 purely for this bundle, the upgrade is now viable — but treat PHP 8 support as "installable", not "actively maintained".

This package is effectively frozen. One star, zero dependents, and the only release in years adds a compatibility flag. Treat it as a vendored dependency: pin the exact version, expect no security backports, and be prepared to fork it into your own namespace. It is not a reasonable choice for a greenfield project unless you're already committed to the Monofony stack.

Docs are Sylius docs. Roughly 90% of what you'll find online is written for sylius/customer-bundle. The entities and form types transfer; the service IDs, parameter names, and translation domains generally do not. Verify every constructor argument against services.xml before trusting a snippet.

Mapping collisions. If both the bundle and your application map the same table, Doctrine throws at cache warmup. Either disable auto_mapping and declare mappings explicitly, or fully override via resolve_target_entities with a MappedSuperclass base. Half-finished overrides are the number one time sink here.

Form type aliases are deprecated. Older bundle code references string aliases like monofony_customer_profile. On Symfony 5.2+ these emit deprecations; register or inject FQCNs instead and you'll silence the noise before it becomes a hard error on the next major.

Events fire inside the flush cycle. CustomerEvents::PRE_CREATE and friends dispatch while the unit of work is open. Modifying the customer is fine; persisting unrelated entities or sending mail inside a PRE_* listener is not. Do side effects in POST_CREATE/POST_UPDATE, ideally by dispatching a domain event and handling it after postFlush.

CustomerProvider fails silently. If your user class doesn't implement the interface the provider expects, or the token is missing (CLI commands, message consumers), it returns null with no warning. Guard every consumer with a null check and log rather than assuming a customer exists.

No migrations ship with the bundle. Generate your own after the mapping settles, and review the generated SQL — column lengths for email and unique indexes are frequently wrong on the first pass.

Empty configuration tree. If Configuration.php defines no root node but you write monofony_customer: ... in config/packages/, Symfony rejects it. Read the file before configuring anything.

Features you will build yourself: address management UI, GDPR export/erasure, customer merging (guest checkouts produce duplicates), and any soft-delete/anonymization support. Each of these is a real project-sized task; scope accordingly when estimating adoption.

Debugging tip. When something "doesn't persist," dump get_class($customer) at runtime. Nine times out of ten it's the bundle's base class rather than your extended one, which means target-entity resolution didn't take.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle