solidworx/platform
SolidWorx Platform provides a modular foundation for Laravel applications, letting you register self-contained modules, organize service providers and configuration, and assemble large platforms from reusable components while keeping bootstrapping and dependencies manageable.
0.4.0 is a milestone release, not a patch. It adds three features that change how you'll integrate the package (multi-tenancy, Tiptap editor type, menu-driven user dropdown) plus a stack of dependency majors (Symfony 8, jQuery 4, Webpack Encore 7, Babel 8, Tiptap 3, PHPUnit 13). Budget an upgrade session rather than a composer update.
First steps:
config/packages/*.yaml instead of config/*.php, service autowiring instead of the container's facades, Doctrine entities instead of Eloquent, Twig instead of Blade. The bundle gives you a user/auth foundation, an admin UI, and a form layer — roughly the role Breeze/Filament play in Laravel.config/bundles.php and import its routing, then run the Doctrine migrations for the user tables.User class implements the bundle's user interface, and your templates override the UI bundle's Twig namespace.TenantInterface-style isolation onto an existing schema is much more expensive than adopting it at the start.Extend the user entity, don't fight it. Subclass the bundle's base user, add your domain fields, and keep the bundle's interfaces intact — the registration and access-control listeners type-hint against them.
Registration hardening is now free — and configurable. Disposable-domain blocking ships on by default at registration. In practice you'll want to subtract from the blocklist for internal/staging domains (e.g. @example.test, your own QA domains) rather than disabling the check wholesale. Wrap it in a config flag per environment so dev and test suites aren't fighting the blocklist.
Rich text with TextEditorType. Use it as a drop-in form type wherever you'd otherwise reach for a TextareaType, then be deliberate about persistence: Tiptap emits HTML or JSON depending on config. Pick HTML if you need to render server-side with minimal ceremony, JSON if you want structure for downstream processing. Either way, sanitize on output — an editor widget is not a sanitizer.
Multi-tenancy: resolve once, early, and thread it through. The workable pattern is a listener or middleware that resolves the tenant (subdomain, header, or authenticated user's tenant) before controllers run, storing it in a request-scoped context service. Repositories then filter by the context service rather than re-deriving the tenant in each query. Treat any code path that touches the DB outside a request — console commands, queue workers, scheduled jobs — as needing an explicit tenant binding, because there's no request to resolve from.
Customize the user dropdown via KnpMenu, not template surgery. The dropdown is now driven by a user_menu menu, so add or reorder items by decorating that menu in a MenuBuilder event subscriber. This is the intended extension point and keeps you off the template-override treadmill.
Override Tabler layouts by template inheritance. Register your Twig path ahead of the bundle's, extend the base layout, and override individual blocks. Don't copy the whole layout file — you'll be re-diffing it every release.
Integration tip: keep your app's own controllers thin and let bundle-provided base controllers handle the plumbing (forms, flash messages, redirects). Overriding a base controller method is safer than cloning the action.
composer.json constraints rather than assuming..bind()/.delegate() shims), Encore 7 changes config contracts, and Babel 8 changes preset behavior. Any custom JS in your UI bundle overrides is the most likely thing to break, silently, in the browser. Rebuild and click through every form.TextEditorType existed, migrate to the shipped type rather than maintaining your own — but re-test extensions, since the v3 extension API changed.user_menu is a quiet breaking change for anyone who overrode the dropdown template. If your custom links vanished after upgrading, this is why.find() by primary key, cache keys, queued job payloads, and file storage paths. A missing scope is a data-leak bug, not a display bug. Write a test that asserts tenant A cannot read tenant B's records through every repository.monolog dev bump to ^3.12 and phpunit to ^13.3 can conflict with your app's own dev constraints; sort dev deps in a separate commit from the feature upgrade so you can revert cleanly.How can I help you explore Laravel packages today?