chill-bundles/src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php
2021-11-30 13:54:58 +01:00

589 lines
19 KiB
PHP

<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Chill\MainBundle\Controller;
use Chill\MainBundle\Entity\PermissionsGroup;
use Chill\MainBundle\Entity\RoleScope;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Form\PermissionsGroupType;
use Chill\MainBundle\Form\Type\ComposedRoleScopeType;
use Chill\MainBundle\Security\RoleProvider;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use RuntimeException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Security\Core\Role\RoleHierarchy;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use function array_key_exists;
/**
* Class PermissionsGroupController.
*/
class PermissionsGroupController extends AbstractController
{
/**
* @var RoleHierarchy
*/
private $roleHierarchy;
/**
* @var RoleProvider
*/
private $roleProvider;
/**
* @var TranslatableStringHelper
*/
private $translatableStringHelper;
/**
* @var TranslatorInterface
*/
private $translator;
/**
* @var ValidatorInterface
*/
private $validator;
/**
* PermissionsGroupController constructor.
*/
public function __construct(
TranslatableStringHelper $translatableStringHelper,
RoleProvider $roleProvider,
RoleHierarchy $roleHierarchy,
TranslatorInterface $translator,
ValidatorInterface $validator
) {
$this->translatableStringHelper = $translatableStringHelper;
$this->roleProvider = $roleProvider;
$this->roleHierarchy = $roleHierarchy;
$this->translator = $translator;
$this->validator = $validator;
}
/**
* @param int $id
*
* @throws type
*
* @return Respon
*/
public function addLinkRoleScopeAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$permissionsGroup = $em->getRepository('ChillMainBundle:PermissionsGroup')->find($id);
if (!$permissionsGroup) {
throw $this->createNotFoundException('Unable to find PermissionsGroup entity.');
}
$form = $this->createAddRoleScopeForm($permissionsGroup);
$form->handleRequest($request);
if ($form->isValid()) {
$roleScope = $this->getPersistentRoleScopeBy(
$form['composed_role_scope']->getData()->getRole(),
$form['composed_role_scope']->getData()->getScope()
);
$permissionsGroup->addRoleScope($roleScope);
$violations = $this->validator->validate($permissionsGroup);
if ($violations->count() === 0) {
$em->flush();
$this->addFlash(
'notice',
$this->translator->trans('The permissions have been added')
);
return $this->redirect($this->generateUrl(
'admin_permissionsgroup_edit',
['id' => $id]
));
}
foreach ($violations as $error) {
$this->addFlash('error', $error->getMessage());
}
} else {
foreach ($form->getErrors() as $error) {
$this->addFlash('error', $error->getMessage());
}
}
$editForm = $this->createEditForm($permissionsGroup);
$deleteRoleScopesForm = [];
foreach ($permissionsGroup->getRoleScopes() as $roleScope) {
$deleteRoleScopesForm[$roleScope->getId()] = $this->createDeleteRoleScopeForm(
$permissionsGroup,
$roleScope
);
}
$addRoleScopesForm = $this->createAddRoleScopeForm($permissionsGroup);
// sort role scope by title
$roleProvider = $this->roleProvider;
$roleScopesSorted = [];
foreach ($permissionsGroup->getRoleScopes()->toArray() as $roleScope) {
/** @var RoleScope $roleScope */
$title = $roleProvider->getRoleTitle($roleScope->getRole());
$roleScopesSorted[$title][] = $roleScope;
}
ksort($roleScopesSorted);
return $this->render('@ChillMain/PermissionsGroup/edit.html.twig', [
'entity' => $permissionsGroup,
'edit_form' => $editForm->createView(),
'role_scopes_sorted' => $roleScopesSorted,
'expanded_roles' => $this->getExpandedRoles($permissionsGroup->getRoleScopes()->toArray()),
'delete_role_scopes_form' => array_map(static function ($form) {
return $form->createView();
}, $deleteRoleScopesForm),
'add_role_scopes_form' => $addRoleScopesForm->createView(),
]);
}
/**
* Creates a new PermissionsGroup entity.
*/
public function createAction(Request $request)
{
$permissionsGroup = new PermissionsGroup();
$form = $this->createCreateForm($permissionsGroup);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($permissionsGroup);
$em->flush();
return $this->redirect($this->generateUrl(
'admin_permissionsgroup_edit',
['id' => $permissionsGroup->getId()]
));
}
return $this->render('@ChillMain/PermissionsGroup/new.html.twig', [
'entity' => $permissionsGroup,
'form' => $form->createView(),
]);
}
/**
* remove an association between permissionsGroup and roleScope.
*
* @param int $pgid permissionsGroup id
* @param int $rsid roleScope id
*
* @return redirection to edit form
*/
public function deleteLinkRoleScopeAction($pgid, $rsid)
{
$em = $this->getDoctrine()->getManager();
$permissionsGroup = $em->getRepository('ChillMainBundle:PermissionsGroup')->find($pgid);
$roleScope = $em->getRepository('ChillMainBundle:RoleScope')->find($rsid);
if (!$permissionsGroup) {
throw $this->createNotFoundException('Unable to find PermissionsGroup entity.');
}
if (!$roleScope) {
throw $this->createNotFoundException('Unable to find RoleScope entity');
}
try {
$permissionsGroup->removeRoleScope($roleScope);
} catch (RuntimeException $ex) {
$this->addFlash(
'notice',
$this->translator->trans("The role '%role%' and circle "
. "'%scope%' is not associated with this permission group", [
'%role%' => $this->translator->trans($roleScope->getRole()),
'%scope%' => $this->translatableStringHelper
->localize($roleScope->getScope()->getName()),
])
);
return $this->redirect($this->generateUrl(
'admin_permissionsgroup_edit',
['id' => $pgid]
));
}
$em->flush();
if ($roleScope->getScope() !== null) {
$this->addFlash(
'notice',
$this->translator->trans("The role '%role%' on circle "
. "'%scope%' has been removed", [
'%role%' => $this->translator->trans($roleScope->getRole()),
'%scope%' => $this->translatableStringHelper
->localize($roleScope->getScope()->getName()),
])
);
} else {
$this->addFlash(
'notice',
$this->translator->trans("The role '%role%' has been removed", [
'%role%' => $this->translator->trans($roleScope->getRole()),
])
);
}
return $this->redirect($this->generateUrl(
'admin_permissionsgroup_edit',
['id' => $pgid]
));
}
/**
* Displays a form to edit an existing PermissionsGroup entity.
*
* @param mixed $id
*/
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$permissionsGroup = $em->getRepository('ChillMainBundle:PermissionsGroup')->find($id);
if (!$permissionsGroup) {
throw $this->createNotFoundException('Unable to find PermissionsGroup entity.');
}
// create all the forms
$editForm = $this->createEditForm($permissionsGroup);
$deleteRoleScopesForm = [];
foreach ($permissionsGroup->getRoleScopes() as $roleScope) {
$deleteRoleScopesForm[$roleScope->getId()] = $this->createDeleteRoleScopeForm(
$permissionsGroup,
$roleScope
);
}
$addRoleScopesForm = $this->createAddRoleScopeForm($permissionsGroup);
// sort role scope by title
$roleProvider = $this->roleProvider;
$roleScopesSorted = [];
foreach ($permissionsGroup->getRoleScopes()->toArray() as $roleScope) {
/** @var RoleScope $roleScope */
$title = $roleProvider->getRoleTitle($roleScope->getRole());
$roleScopesSorted[$title][] = $roleScope;
}
ksort($roleScopesSorted);
return $this->render('@ChillMain/PermissionsGroup/edit.html.twig', [
'entity' => $permissionsGroup,
'role_scopes_sorted' => $roleScopesSorted,
'edit_form' => $editForm->createView(),
'expanded_roles' => $this->getExpandedRoles($permissionsGroup->getRoleScopes()->toArray()),
'delete_role_scopes_form' => array_map(static function ($form) {
return $form->createView();
}, $deleteRoleScopesForm),
'add_role_scopes_form' => $addRoleScopesForm->createView(),
]);
}
/**
* Lists all PermissionsGroup entities.
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('ChillMainBundle:PermissionsGroup')->findAll();
return $this->render('@ChillMain/PermissionsGroup/index.html.twig', [
'entities' => $entities,
]);
}
/**
* Displays a form to create a new PermissionsGroup entity.
*/
public function newAction()
{
$permissionsGroup = new PermissionsGroup();
$form = $this->createCreateForm($permissionsGroup);
return $this->render('@ChillMain/PermissionsGroup/new.html.twig', [
'entity' => $permissionsGroup,
'form' => $form->createView(),
]);
}
/**
* Finds and displays a PermissionsGroup entity.
*
* @param mixed $id
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$permissionsGroup = $em->getRepository('ChillMainBundle:PermissionsGroup')->find($id);
if (!$permissionsGroup) {
throw $this->createNotFoundException('Unable to find PermissionsGroup entity.');
}
$translatableStringHelper = $this->translatableStringHelper;
$roleScopes = $permissionsGroup->getRoleScopes()->toArray();
// sort $roleScopes by name
usort(
$roleScopes,
static function (RoleScope $a, RoleScope $b) use ($translatableStringHelper) {
if ($a->getScope() === null) {
return 1;
}
if ($b->getScope() === null) {
return +1;
}
return strcmp(
$translatableStringHelper->localize($a->getScope()->getName()),
$translatableStringHelper->localize($b->getScope()->getName())
);
}
);
// sort role scope by title
$roleProvider = $this->roleProvider;
$roleScopesSorted = [];
foreach ($roleScopes as $roleScope) {
/** @var RoleScope $roleScope */
$title = $roleProvider->getRoleTitle($roleScope->getRole());
$roleScopesSorted[$title][] = $roleScope;
}
ksort($roleScopesSorted);
return $this->render('@ChillMain/PermissionsGroup/show.html.twig', [
'entity' => $permissionsGroup,
'role_scopes_sorted' => $roleScopesSorted,
'expanded_roles' => $this->getExpandedRoles($roleScopes),
]);
}
/**
* Edits an existing PermissionsGroup entity.
*
* @param mixed $id
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$permissionsGroup = $em
->getRepository('ChillMainBundle:PermissionsGroup')
->find($id);
if (!$permissionsGroup) {
throw $this->createNotFoundException('Unable to find Permissions'
. 'Group entity.');
}
$editForm = $this->createEditForm($permissionsGroup);
$editForm->handleRequest($request);
if ($editForm->isValid()) {
$em->flush();
return $this->redirect($this->generateUrl('admin_permissionsgroup_edit', ['id' => $id]));
}
$deleteRoleScopesForm = [];
foreach ($permissionsGroup->getRoleScopes() as $roleScope) {
$deleteRoleScopesForm[$roleScope->getId()] = $this->createDeleteRoleScopeForm(
$permissionsGroup,
$roleScope
);
}
$addRoleScopesForm = $this->createAddRoleScopeForm($permissionsGroup);
// sort role scope by title
$roleProvider = $this->roleProvider;
$roleScopesSorted = [];
foreach ($permissionsGroup->getRoleScopes()->toArray() as $roleScope) {
/** @var RoleScope $roleScope */
$title = $roleProvider->getRoleTitle($roleScope->getRole());
$roleScopesSorted[$title][] = $roleScope;
}
ksort($roleScopesSorted);
return $this->render('@ChillMain/PermissionsGroup/edit.html.twig', [
'entity' => $permissionsGroup,
'role_scopes_sorted' => $roleScopesSorted,
'edit_form' => $editForm->createView(),
'expanded_roles' => $this->getExpandedRoles($permissionsGroup->getRoleScopes()->toArray()),
'delete_role_scopes_form' => array_map(static function ($form) {
return $form->createView();
}, $deleteRoleScopesForm),
'add_role_scopes_form' => $addRoleScopesForm->createView(),
]);
}
/**
* get a role scope by his parameters. The role scope is persisted if it
* doesn't exists in database.
*
* @param Scope $scope
* @param string $role
*
* @return RoleScope
*/
protected function getPersistentRoleScopeBy($role, ?Scope $scope = null)
{
$em = $this->getDoctrine()->getManager();
$roleScope = $em->getRepository('ChillMainBundle:RoleScope')
->findOneBy(['role' => $role, 'scope' => $scope]);
if (null === $roleScope) {
$roleScope = (new RoleScope())
->setRole($role)
->setScope($scope);
$em->persist($roleScope);
}
return $roleScope;
}
/**
* creates a form to add a role scope to permissionsgroup.
*
* @return \Symfony\Component\Form\Form The form
*/
private function createAddRoleScopeForm(PermissionsGroup $permissionsGroup)
{
return $this->createFormBuilder()
->setAction($this->generateUrl(
'admin_permissionsgroup_add_role_scope',
['id' => $permissionsGroup->getId()]
))
->setMethod('PUT')
->add('composed_role_scope', ComposedRoleScopeType::class)
->add('submit', SubmitType::class, ['label' => 'Add permission'])
->getForm();
}
/**
* Creates a form to create a PermissionsGroup entity.
*
* @param PermissionsGroup $permissionsGroup The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(PermissionsGroup $permissionsGroup)
{
$form = $this->createForm(PermissionsGroupType::class, $permissionsGroup, [
'action' => $this->generateUrl('admin_permissionsgroup_create'),
'method' => 'POST',
]);
$form->add('submit', SubmitType::class, ['label' => 'Create']);
return $form;
}
/**
* Creates a form to delete a link to roleScope.
*
* @param mixed $permissionsGroup The entity id
*
* @return \Symfony\Component\Form\Form The form
*/
private function createDeleteRoleScopeForm(
PermissionsGroup $permissionsGroup,
RoleScope $roleScope
) {
return $this->createFormBuilder()
->setAction($this->generateUrl(
'admin_permissionsgroup_delete_role_scope',
['pgid' => $permissionsGroup->getId(), 'rsid' => $roleScope->getId()]
))
->setMethod('DELETE')
->add('submit', SubmitType::class, ['label' => 'Delete'])
->getForm();
}
/**
* Creates a form to edit a PermissionsGroup entity.
*
* @param PermissionsGroup $permissionsGroup The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(PermissionsGroup $permissionsGroup)
{
$form = $this->createForm(PermissionsGroupType::class, $permissionsGroup, [
'action' => $this->generateUrl('admin_permissionsgroup_update', ['id' => $permissionsGroup->getId()]),
'method' => 'PUT',
]);
$form->add('submit', SubmitType::class, ['label' => 'Update']);
return $form;
}
/**
* expand roleScopes to be easily shown in template.
*
* @return array
*/
private function getExpandedRoles(array $roleScopes)
{
$expandedRoles = [];
foreach ($roleScopes as $roleScope) {
if (!array_key_exists($roleScope->getRole(), $expandedRoles)) {
$expandedRoles[$roleScope->getRole()] =
array_map(
static function (Role $role) {
return $role->getRole();
},
$this->roleHierarchy
->getReachableRoles(
[new Role($roleScope->getRole())]
)
);
}
}
return $expandedRoles;
}
}