nowo-tech/user-kit-bundle
Nowo Tech User Kit Bundle provides a ready-to-use foundation for user management in PHP applications, including registration, authentication, profiles, roles, and account administration. Integrate quickly and customize its building blocks to fit your project.
First, the compatibility reality check. nowo-tech/user-kit-bundle is a Symfony bundle (PHP >=8.2, Symfony 7/8 per the project rules). It is not installable into a Laravel app: there is no service provider, no Blade views, no Eloquent models, no config/user-kit.php publish tag. As a Laravel developer you have two honest options:
Where to look first (in the repo, in this order):
| File | Why |
|---|---|
README.md |
Only source of install/config instructions; read before anything else |
composer.json |
Real PHP/Symfony constraints, require/require-dev, autoload namespace |
src/DependencyInjection/*Extension.php |
The authoritative list of config keys and defaults |
src/Resources/config/services.php (or .yaml) |
Public vs private service IDs — the actual API surface |
src/Resources/config/doctrine/*.xml or entity classes |
Fields added to the user table and their nullability |
src/EventSubscriber/, src/Security/ |
Where the "is the account enabled" and "touch last activity" hooks live |
Minimal first use case — "green dot for online users + block disabled accounts":
composer require nowo-tech/user-kit-bundle (pin the exact version; see Gotchas).config/bundles.php.User entity and run the migration the bundle ships (or copy its columns).user_kit: root key) and confirm the name from the DI extension, not from blog posts.lastActivityAt.If step 4 or 5 is undocumented in the README, treat the DI extension and the service definitions as the documentation — that is normal for a 0-star bundle and the only reliable source.
Pattern 1 — Trait on the user entity. The bundle almost certainly expects a specific interface + trait pair on your user class. Keep that wiring in the entity only; put business rules in a service, not in the entity, so the same logic ports to Laravel later.
Pattern 2 — Throttled activity touch. Last-activity writes on every request will dominate your write load. Wrap the update in a "write at most once per N minutes" guard:
// conceptually: only persist if the stored value is stale
if ($user->getLastActivityAt() < $now->modify('-2 minutes')) {
$user->setLastActivityAt($now); // let the unit-of-work flush it
}
In Laravel the equivalent is a TouchLastActivity middleware with the same guard, using last_activity_at and a cached "already touched this session/minute" flag so you skip the UPDATE entirely.
Pattern 3 — Presence as a derived query, never a stored boolean. "Online" should be last_activity_at >= now() - window. Store only the timestamp; compute presence at read time. A stored is_online column requires a cron to clear it and is always wrong for a few minutes.
Pattern 4 — Enforcement in the authentication path, not the controller. In Symfony that is a user checker on the firewall; in Laravel it is a guard check or a middleware on the authenticated group. Enforcing in one controller means every new route is a hole.
Pattern 5 — Admin toggle as a form type action. The bundle's enable/disable methods are the seam; expose them through your own admin controller and fire a domain event (UserDisabled) for audit logging. Do not let the admin UI write the column directly.
Pattern 6 — Scheduled pruning/counting. Run a daily job to null-out ancient activity timestamps and a cached "users online now" counter (5-minute TTL) so a dashboard does not run COUNT(*) on every page view.
Laravel portability note: every one of these maps cleanly — middleware for the touch and the enabled check, a scheduled command for pruning, a cached count, and a last_activity_at indexed column. Keep that mapping in mind while reading the Symfony code; it is a weekend of work, not a rewrite.
"nowo-tech/user-kit-bundle": "x.y.z" exactly — ^ on an unvetted bundle is how you get a surprise major.composer show and matches what composer.json constraints allow before assuming the version you want is installable.UPGRADING/CHANGELOG and diff the mapping files on every bump.flush() inside the request listener. Touching the entity and letting Doctrine's unit of work flush at the end of the request is one query; a manual flush inside a kernel listener on every request is how you double your DB round-trips.new \DateTimeImmutable() buried in a service makes presence tests flaky at window boundaries.last_activity_at. Presence queries are WHERE last_activity_at > ? and will table-scan without it.templates/bundles/UserKitBundle/ path; keep config overrides in config/packages/user_kit.yaml.src/Resources/public/build, never patch it — rebuild from src/Resources/assets or override in your app.How can I help you explore Laravel packages today?