sonata-project/comment-bundle
SonataCommentBundle integrates FOSCommentBundle into the Sonata ecosystem, providing comment management features for Sonata-based Symfony apps. Note: this repository is abandoned and not actively maintained; community help is welcome.
Installation:
composer require sonata-project/comment-bundle
Ensure you have sonata-project/doctrine-orm-admin-bundle installed (required for admin integration).
Enable Bundle:
Add to config/bundles.php:
SonataProject\CommentBundle\SonataCommentBundle::class => ['all' => true],
Database Migration:
Run migrations to create the Comment and CommentThread tables:
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
Basic Configuration:
Update config/packages/sonata_comment.yaml (auto-generated):
sonata_comment:
class:
model_comment: App\Entity\Comment
model_thread: App\Entity\CommentThread
form_type_comment: App\Form\CommentType
admin:
comment:
template: SonataCommentBundle:Comment:admin_list.html.twig
First Use Case:
Enable comments on a Sonata Admin entity (e.g., Post):
// src/Admin/PostAdmin.php
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper->add('comments', 'sonata_type_collection', [
'by_reference' => false,
]);
}
CommentableInterface to your entity (e.g., Post):
use Sonata\CommentBundle\Model\CommentableInterface;
class Post implements CommentableInterface
{
// ...
public function getCommentableSubject(): string
{
return $this->title;
}
}
SonataAdminBundle\Admin\AbstractAdmin and override configureFormFields:
$formMapper->add('comments', 'sonata_type_collection', [
'label' => 'Comments',
'required' => false,
'cascade_validation' => true,
]);
CommentType:
// src/Form/CommentType.php
use Sonata\CommentBundle\Form\Type\CommentType as BaseCommentType;
class CommentType extends BaseCommentType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->add('custom_field', TextType::class);
}
}
sonata_comment.yaml:
sonata_comment:
class:
form_type_comment: App\Form\CommentType
{% for comment in sonata_comment_get_thread(entity).comments %}
<div class="comment">
{{ comment.body }}
<small>{{ comment.createdAt|date('M d, Y') }}</small>
</div>
{% endfor %}
$thread = $commentManager->createThread($entity);
$comment = $commentManager->createComment($thread, $author, $body);
$commentManager->saveComment($comment);
Serializer to expose comments as JSON:
$comments = $commentManager->getThread($entity)->getComments();
return $this->json($comments);
configureListFields to avoid N+1 queries:
$formMapper->add('comments', 'sonata_type_collection', [
'by_reference' => false,
'label' => false,
'sonata_type_collection_allow_add' => false,
'sonata_type_collection_allow_delete' => false,
]);
sonata_comment_get_thread and sonata_comment_get_comments in templates:
{% set thread = sonata_comment_get_thread(app.user.post) %}
{% for comment in sonata_comment_get_comments(thread) %}
{{ comment.body }}
{% endfor %}
# config/packages/security.yaml
access_control:
- { path: ^/comment/new, roles: ROLE_USER }
AppCache:
$cache = $this->get('sonata.cache');
$thread = $cache->get('thread_' . $entity->getId(), function() use ($entity) {
return $commentManager->getThread($entity);
});
Deprecated Dependencies:
SonataEasyExtendsBundle (deprecated in v3.3.0). Use SonataDoctrineBundle instead.SonataEasyExtendsBundle and update Doctrine mappings manually.Symfony Version Mismatch:
composer require symfony/*:^4.4|^5.0
Template Paths:
{# Old (deprecated) #}
SonataCommentBundle:Comment:list.html.twig
{# New #}
@SonataComment/Comment/list.html.twig
Command Failures:
php bin/console cache:clear
Translation Issues:
# config/packages/translation.yaml
frameworks:
translator:
paths:
- '%kernel.project_dir%/vendor/sonata-project/comment-bundle/Resources/translations'
Enable Debug Mode:
# config/packages/dev/sonata_comment.yaml
sonata_comment:
debug: true
Logs SQL queries and template rendering issues.
Check Event Listeners:
sonata.comment.post_create):
// src/EventListener/CommentListener.php
public function onPostCreate(PostCreateEvent $event)
{
$comment = $event->getComment();
// Custom logic
}
services.yaml:
services:
App\EventListener\CommentListener:
tags:
- { name: kernel.event_listener, event: sonata.comment.post_create, method: onPostCreate }
Database Schema:
php bin/console doctrine:schema:validate
Custom Comment Models:
Extend Sonata\CommentBundle\Model\Comment and CommentThread:
class AppComment extends Comment
{
private $customField;
// Add getters/setters
}
Update sonata_comment.yaml:
sonata_comment:
class:
model_comment: App\Entity\AppComment
Dynamic Threads:
Override getCommentableSubject() for dynamic thread subjects:
public function getCommentableSubject(): string
{
return "Post #{$this->id}";
}
API Endpoints: Create a custom controller for comment CRUD:
#[Route('/api/comments', name: 'api_comment_')]
class CommentController extends AbstractController
{
#[Route('/{id}', name: 'read', methods: ['GET'])]
public function read(Comment $comment): JsonResponse
{
return $this->json($comment);
}
}
Notification System: Trigger events on comment creation:
$dispatcher->dispatch(new CommentEvent($comment), 'sonata.comment.post_create');
Parameter Overrides:
Override default parameters in config/packages/sonata_comment.yaml:
sonata_comment:
admin:
comment:
template: custom/path.html.twig
list:
actions:
_delete: { 'attr' => { 'class' => 'btn-danger' } }
Form Theme: Customize form themes by extending the default:
{
How can I help you explore Laravel packages today?