quef/team-bundle
quef/team-bundle provides team and organization management for PHP applications, with entities, membership handling, and role structures to organize users into teams. It integrates cleanly into existing projects, reducing boilerplate for common team-based features and permissions.
The package is a Symfony bundle (quef/team-bundle), so the first thing to establish is whether you're actually working in a Symfony app — if you're on Laravel, this will not drop in without an adapter layer, because it relies on the Symfony bundle registration and DI conventions rather than Laravel service providers.
Minimal steps:
composer require quef/team-bundle
config/bundles.php (Symfony 4+/5+/6+):
return [
// ...
Quef\TeamBundle\QuefTeamBundle::class => ['all' => true],
];
php bin/console config:dump-reference quef_team
If a reference exists, copy the defaults into config/packages/quef_team.yaml. If it errors, the bundle likely has no config surface and works with sensible defaults.php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
Confirm which entities it owns before doing this — you don't want it stepping on your own Team/Membership tables.Where to look first: the bundle's Entity/ and Service/ directories in vendor/quef/team-bundle/. Because the package has no stars and no dependents, treat the source as the primary documentation — there is almost certainly no maintained docs site, and any README is likely a skeleton. Read the service definitions in Resources/config/services.yaml (or config/services.php) to see what's injectable; that tells you the intended public API faster than anything else.
First use case: the natural entry point is creating a team, attaching the current user as owner, and listing a user's teams. Start there and confirm persistence works end-to-end before wiring in invitations or roles — those are usually the parts where an unmaintained bundle diverges from what you'd expect.
Constructor injection over container access. Bundles like this typically expose a TeamManager or similar facade. Inject it rather than pulling services from the container:
public function __construct(private TeamManager $teams) {}
Membership as a first-class join entity. Expect a TeamMembership/TeamUser entity carrying the role. Query through the repository rather than traversing team->getUsers() directly, so you keep role filtering in one place:
$members = $this->teams->getMembers($team, Role::ADMIN);
Current-user resolution via a listener or resolver. Most team bundles need to know "who is acting" for permission checks. If the bundle defines a TeamContextInterface or similar (check DependencyInjection/), implement it in your app and register it as a service — this is the cleanest seam to integrate with your existing auth.
Form types and controllers. If the bundle ships Form/TeamType, extend it rather than rebuilding:
class TeamType extends BaseTeamType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
parent::buildForm($builder, $options);
$builder->add('billingEmail', EmailType::class);
}
}
Events for side effects. Look for dispatched events (TeamCreatedEvent, MemberJoinedEvent). Subscribe with a standard EventSubscriberInterface for notifications, audit logs, or provisioning — this keeps bundle internals untouched while you add cross-cutting behavior.
Testing pattern. The bundle's entities are Doctrine-managed; use a functional test with a real kernel rather than mocking the manager, because bundle logic tends to live in entity callbacks and listeners that mocks won't exercise.
QuefTeamBundle, no description) means you should assume no active maintenance. Pin the version explicitly in composer.json and be prepared to fork. Budget time for reading source rather than searching for answers.composer.json autoload PSR-4 root may not be what the README claims. Verify with composer dump-autoload -o and grep the actual namespace from a class file before writing imports.auto_mapping. Check Resources/config/doctrine/ and consider setting doctrine.orm.mappings for the bundle explicitly, or you'll fight "The association ... refers to the inverse side field ... which does not exist" errors at boot.teams table or a Team entity, the bundle will collide. Alias the bundle's entity in your mapping or rename tables via @Table(name=...) overrides in a subclass — check the bundle's Entity/Team.php annotations first.Cannot autowire service "Quef\TeamBundle\...", the bundle's service config is usually the culprit (missing alias, interface not bound). Fix it in your services.yaml with an explicit alias rather than patching the vendor file:
Quef\TeamBundle\Contract\TeamContextInterface:
'@App\Team\CurrentUserTeamContext'
TreeBuilder with ->canBeUnset() or required nodes that throw at compile time. If the container won't compile, dump the reference (step 3 above) and supply a minimal config, even if it's just an empty quef_team: {} node.TeamManagerInterface in App\. Then swapping or inlining the bundle later is a one-file change instead of a codebase-wide search-and-replace.How can I help you explore Laravel packages today?