After looking into the FOSCommentBundle
, I have found a solution for my problem :
1. first, you have to override the RoleCommentAcl
:
by creating a folder named Acl into MyBundle. Inside this folder I create a php class named RoleCommentAcl :
namespace MyProject\MyBundle\Acl;
use FOS\CommentBundle\Acl\RoleCommentAcl as BaseRoleCommentAcl;
use FOS\CommentBundle\Model\CommentInterface;
use FOS\CommentBundle\Model\SignedCommentInterface;
use Symfony\Component\Security\Core\SecurityContextInterface;
class RoleCommentAcl extends BaseRoleCommentAcl {
/**
* The current Security Context.
*
* @var SecurityContextInterface
*/
private $securityContext;
/**
* Constructor.
*
* @param SecurityContextInterface $securityContext
* @param string $createRole
* @param string $viewRole
* @param string $editRole
* @param string $deleteRole
* @param string $commentClass
*/
public function __construct(SecurityContextInterface $securityContext, $createRole, $viewRole, $editRole, $deleteRole, $commentClass
) {
parent::__construct(
$securityContext, $createRole, $viewRole, $editRole, $deleteRole, $commentClass);
$this->securityContext = $securityContext;
}
/**
* Checks if the Security token has an appropriate role to edit the supplied Comment.
*
* @param CommentInterface $comment
* @return boolean
*/
public function canEdit(CommentInterface $comment) {
// the comment owner can edit the comment whenever he want.
if ($comment instanceof SignedCommentInterface) {
if ($comment->getAuthor() == $this->securityContext->getToken()->getUser()) {
return true;
}
}
return parent::canEdit($comment);
}
/**
* Checks if the Security token is allowed to delete a specific Comment.
*
* @param CommentInterface $comment
* @return boolean
*/
public function canDelete(CommentInterface $comment) {
// the comment owner can delete the comment
if ($comment instanceof SignedCommentInterface) {
if ($comment->getAuthor() == $this->securityContext->getToken()->getUser()) {
return true;
}
}
return parent::canDelete($comment);
}
/**
* Checks if the Security token is allowed to reply to a parent comment.
*
* @param CommentInterface|null $parent
* @return boolean
*/
public function canReply(CommentInterface $parent = null) {
if ($parent instanceof SignedCommentInterface) {
//only the comment owner or the admin can reply to the comment.
if ($parent->getAuthor() == $this->securityContext->getToken()->getUser() ||
$this->securityContext->isGranted('ROLE_ADMIN')) {
return true;
}
}
if($parent !=null) {
// if the user have no access to reply then return false.
return false;
}
//this ligne allow all users to post new comments.
return parent::canCreate();
}
}
2. Then you have to add into services.xml the access permissions:
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="myproject.name_bundle.acl.comment.roles" class="MyProject\MyBundle\Acl\RoleCommentAcl" public="false">
<argument type="service" id="security.context" />
<argument>IS_AUTHENTICATED_ANONYMOUSLY</argument> <!-- Create role -->
<argument>IS_AUTHENTICATED_ANONYMOUSLY</argument> <!-- View role -->
<argument>ROLE_ADMIN</argument> <!-- Edit role -->
<argument>ROLE_ADMIN</argument> <!-- Delete role -->
<argument>%fos_comment.model.comment.class%</argument>
</service>
</services> </container>
PS: If you are using service.yml you can translate this xml file into yaml but if you want to use the services.xml
you have to change the configuration sets into the DependencyInjection of your bundle:
$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('services.xml');
Open your page and you will notice that the reply will be accessed just by comment owner and admin users.Also the delete and Edit can be shown just for comment owner and admin.