Installation Add the bundle via Composer:
composer require courtyard/forum-bundle
Enable it in config/bundles.php:
return [
// ...
Courtyard\ForumBundle\CourtyardForumBundle::class => ['all' => true],
];
Database Setup Run migrations (if provided) or manually create tables based on the Courtyard\Forum schema. Example:
php bin/console doctrine:migrations:migrate
First Use Case Create a basic forum controller to list categories:
use Courtyard\ForumBundle\Entity\Category;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class ForumController extends AbstractController
{
#[Route('/forum', name: 'forum_index')]
public function index(): Response
{
$categories = $this->getDoctrine()->getRepository(Category::class)->findAll();
return $this->render('forum/index.html.twig', ['categories' => $categories]);
}
}
Routing
The bundle provides default routes (e.g., /forum/{category}). Override or extend them in config/routes.yaml:
courtyard_forum:
resource: "@CourtyardForumBundle/Resources/config/routing.yml"
prefix: /forum
Entity Management
Use the provided entities (Category, Topic, Post, User) with Doctrine ORM. Example:
// Create a new topic
$topic = new Topic();
$topic->setTitle('Hello World');
$topic->setCategory($category);
$entityManager->persist($topic);
$entityManager->flush();
Services Leverage bundle services for common tasks:
courtyard_forum.manager.topic: Manages topics.courtyard_forum.manager.post: Manages posts.courtyard_forum.security.voter.topic: Security voter for topic access.Example:
$topicManager = $this->get('courtyard_forum.manager.topic');
$topics = $topicManager->findByCategory($category);
Templating
Use Twig templates in templates/forum/ to override default views. Example template structure:
templates/
└── forum/
├── category/
│ └── show.html.twig
└── topic/
└── show.html.twig
Forms The bundle includes form types for entities. Extend them as needed:
use Courtyard\ForumBundle\Form\Type\TopicType;
$form = $this->createForm(TopicType::class, $topic);
Event Listeners
Subscribe to forum events (e.g., TopicCreatedEvent) to extend functionality:
// config/services.yaml
services:
App\EventListener\ForumListener:
tags:
- { name: kernel.event_listener, event: courtyard.forum.topic.created, method: onTopicCreated }
API Integration Use Symfony’s serializers to expose forum data via API:
use Symfony\Component\Serializer\SerializerInterface;
$serializer = $this->container->get(SerializerInterface::class);
$json = $serializer->serialize($topic, 'json', ['groups' => ['forum_api']]);
Authentication Integrate with Symfony’s security system. Example voter for topic access:
use Courtyard\ForumBundle\Security\Voter\TopicVoter;
// config/security.yaml
access_control:
- { path: ^/forum/topic/, roles: ROLE_USER, voter: courtyard_forum.security.voter.topic }
Notifications Extend the bundle to send notifications (e.g., email) on new posts:
use Courtyard\ForumBundle\Event\PostCreatedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ForumNotificationSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
PostCreatedEvent::class => 'onPostCreated',
];
}
public function onPostCreated(PostCreatedEvent $event)
{
// Send email to topic subscribers
}
}
Custom Fields Add custom fields to topics/posts using Doctrine extensions or embeddables:
// src/Entity/TopicExtension.php
#[ORM\Embedded(class: 'App\Entity\TopicExtension')]
private $extension;
Search Integrate with Elasticsearch or Doctrine’s native search:
$topics = $topicManager->findBySearch('laravel', 10);
Database Schema
category, topic, post, user_forum) match the Courtyard\Forum schema.php bin/console doctrine:schema:update --dump-sql to compare schemas.Deprecated Symfony 2.1
Missing Documentation
Routing Conflicts
/forum/{category}) may clash with other bundles.config/routes.yaml or use _controller annotations.Security
TopicVoter) may not cover all edge cases.# config/security.yaml
access_control:
- { path: ^/forum/topic/\d+/edit, roles: ROLE_ADMIN }
Performance
join:
$topics = $topicManager->findByCategory($category, ['posts' => 'ASC']);
Enable Debug Mode
Set APP_DEBUG=true in .env to see detailed errors and SQL queries.
Doctrine Logging Log all SQL queries to identify N+1 issues:
# config/packages/dev/doctrine.yaml
doctrine:
dbal:
logging: true
profiling: true
Event Debugging Dump events to understand the flow:
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
$dispatcher = $this->container->get(EventDispatcherInterface::class);
$dispatcher->addListener(PostCreatedEvent::class, function ($event) {
var_dump($event->getPost());
});
Custom Entities
Extend entities (e.g., Topic) by adding fields or traits:
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class ExtendedTopic extends Topic
{
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $customField;
}
Form Extensions
Override form types in config/services.yaml:
services:
App\Form\Type\ExtendedTopicType:
parent: courtyard_forum.form.type.topic
tags: ['form.type']
Twig Extensions Add custom Twig filters/functions:
// src/Twig/AppExtension.php
class AppExtension extends \Twig\Extension\AbstractExtension
{
public function getFilters()
{
return [
new \Twig\TwigFilter('truncate_post', [$this, 'truncatePost']),
];
}
}
API Serialization Add custom serialization groups to entities:
use Symfony\Component\Serializer\Annotation\Groups;
class Topic
{
#[Groups(['forum_api', 'forum_detail'])]
private $title;
}
How can I help you explore Laravel packages today?