forumify/forumify-platform
Forumify Platform is an extensible Symfony/PHP forum and community platform with customizable themes, plugins, permissions, moderation tools, and an admin panel for building and managing discussion boards and member communities.
forumify is a Symfony application/bundle stack rather than a drop-in library: you install it into a Symfony project and it brings its own routes, entities, templates, admin UI, ACL, and plugin system. Expect to spend the first hour in vendor/forumify/ reading service definitions and Twig templates — the public docs are thin relative to the surface area.
Minimal install flow (adapt to the Symfony version the release targets):
composer create-project symfony/skeleton my-community
cd my-community
composer require forumify/forumify-platform
# configure the DB
echo 'DATABASE_URL="mysql://user:[email protected]:3306/forumify?serverVersion=8.0"' >> .env.local
bin/console doctrine:database:create
bin/console doctrine:migrations:migrate -n
bin/console cache:clear
Then confirm the bundles are registered (config/bundles.php), check config/routes/forumify.yaml exists (or import the bundle routes manually), and boot symfony server:start. The first use case to validate the install end-to-end is: create an admin user, log into /admin, create a forum category, post a topic, and reply from a second account. That exercises ACL, the admin UI, the front-end controllers, and the notification/mailer wiring in one pass.
Where to look first:
config/packages/forumify*.yaml — settings that are actually consumed by the bundle.vendor/forumify/forumify-platform/src/ — controllers, entities, and the service tags that form the extension points.bin/console debug:router | grep forumify and bin/console debug:container --tag=forumify — these list the real hooks in your installed version rather than the ones in blog posts.Plugin bundles instead of forking. The intended day-to-day pattern is to keep the platform vendored and add a small local bundle (e.g. src/CommunityExtras/) for custom entities, controllers, and Twig overrides. Register it in config/bundles.php, give it a DependencyInjection/Extension, and load routes via attributes. This keeps composer update viable.
Template overrides over class overrides. Forumify follows Symfony bundle template precedence. Copy the template you want to change from vendor/forumify/.../templates/ into templates/bundles/Forumify.../ in your app and edit it. This is the cheapest customisation path and survives patch releases. For anything that must be programmatic, look for the event classes in the bundle and subscribe:
#[AsEventListener(event: SomeForumifyEvent::class)]
final class MyListener
{
public function __invoke(SomeForumifyEvent $event): void
{
// enrich, veto, dispatch a notification, etc.
}
}
ACL and groups as the backbone. Roles, groups, and permissions are first-class entities. Wire new features through the same ACL services rather than adding ad-hoc isGranted checks with hard-coded role strings — the admin UI assumes ACL is the source of truth. Seed permissions/migrations alongside your entities so a fresh install and an upgraded install converge.
Entity extension. The common pattern is Doctrine inheritance (#[ORM\Entity] extending a forumify base entity, with the discriminator configured) or association tables pointing at forumify entities. Prefer association over inheritance for anything that isn't conceptually a subtype — inheritance forces a schema change in the platform tables and complicates migrations.
Admin screens. For custom entities, either register a Symfony UX/EasyAdmin-style CRUD route that mirrors the platform's admin controllers, or reuse the platform's admin base controller and Twig layout so navigation and permissions line up. Register menu items through whatever menu/extension service the installed version exposes (check debug:container --tag=...); do not hardcode links into the platform template.
Async and notifications. If the platform ships Messenger transports for mail and notifications, consume them:
bin/console messenger:consume async -vv
In dev, run workers in a separate terminal — otherwise notifications silently queue and you'll chase a non-bug.
Migrations and fixtures. Treat the platform's migrations as read-only. Your bundle gets its own migration namespace (doctrine:migrations:diff --namespace=...), and you should run doctrine:schema:validate after upgrades to catch divergence.
"forumify/forumify-platform": "~0.x.y") and read the diff of every minor bump before merging. Public classes may rename between releases.debug:container --tag and debug:router are more reliable than any README. When a hook is unclear, grep the bundle for dispatch( and for ->tag( in services.yaml.bin/console cache:clear is often required — the admin UI and menu builders cache aggressively. If permissions "don't apply," clear cache and re-login before debugging code.asset-map:compile step; a composer install alone won't produce them.MAILER_DSN. In dev, point at Mailpit/Mailhog; in prod, verify both the synchronous and Messenger-queued paths.composer.json and avoid relying on alphabetical bundles.php ordering.bin/console debug:event-dispatcher shows which listeners are actually registered; most "my listener never fires" issues are a missing autoconfigure or a wrong event class from a version mismatch.composer update.How can I help you explore Laravel packages today?