cs: Fix code style (safe rules only).

This commit is contained in:
Pol Dellaiera
2021-11-23 14:06:38 +01:00
parent 149d7ce991
commit 8f96a1121d
1223 changed files with 65199 additions and 64625 deletions

View File

@@ -1,5 +1,12 @@
<?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.
*/
namespace Chill\MainBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;
@@ -12,12 +19,10 @@ use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
class AddressApiController extends ApiController
{
/**
* Duplicate an existing address
* Duplicate an existing address.
*
* @Route("/api/1.0/main/address/{id}/duplicate.json", name="chill_api_main_address_duplicate",
* methods={"POST"})
*
* @param Address $address
* methods={"POST"})
*/
public function duplicate(Address $address): JsonResponse
{
@@ -30,9 +35,7 @@ class AddressApiController extends ApiController
$em->flush();
return $this->json($new, Response::HTTP_OK, [], [
AbstractNormalizer::GROUPS => ['read']
AbstractNormalizer::GROUPS => ['read'],
]);
}
}

View File

@@ -1,5 +1,12 @@
<?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.
*/
namespace Chill\MainBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;
@@ -7,23 +14,16 @@ use Chill\MainBundle\Pagination\PaginatorInterface;
use Symfony\Component\HttpFoundation\Request;
/**
* Class AddressReferenceAPIController
*
* @package Chill\MainBundle\Controller
* @author Champs Libres
* Class AddressReferenceAPIController.
*/
class AddressReferenceAPIController extends ApiController
{
protected function customizeQuery(string $action, Request $request, $qb): void
{
if ($request->query->has('postal_code')) {
$qb->where('e.postcode = :postal_code')
->setParameter('postal_code', $request->query->get('postal_code'));
->setParameter('postal_code', $request->query->get('postal_code'));
}
}
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator, $_format)
@@ -33,5 +33,4 @@ class AddressReferenceAPIController extends ApiController
return $query;
}
}

View File

@@ -1,22 +1,10 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Controller;
@@ -27,7 +15,6 @@ use Symfony\Component\Routing\Annotation\Route;
class AdminController extends AbstractController
{
/**
* @Route("/{_locale}/admin", name="chill_main_admin_central")
*/
@@ -36,14 +23,13 @@ class AdminController extends AbstractController
return $this->render('@ChillMain/Admin/index.html.twig');
}
public function indexPermissionsAction()
{
return $this->render('@ChillMain/Admin/layout_permissions.html.twig');
}
public function indexLocationsAction()
{
return $this->render('@ChillMain/Admin/layout_location.html.twig');
}
public function indexPermissionsAction()
{
return $this->render('@ChillMain/Admin/layout_permissions.html.twig');
}
}

View File

@@ -1,5 +1,12 @@
<?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;
@@ -8,5 +15,4 @@ use Chill\MainBundle\CRUD\Controller\CRUDController;
class AdminCountryCRUDController extends CRUDController
{
}

View File

@@ -1,40 +1,28 @@
<?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.
*/
namespace Chill\MainBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Form\CenterType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request;
/**
* Class CenterController
*
* @package Chill\MainBundle\Controller
* Class CenterController.
*/
class CenterController extends AbstractController
{
/**
* Lists all Center entities.
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('ChillMainBundle:Center')->findAll();
return $this->render('@ChillMain/Center/index.html.twig', array(
'entities' => $entities,
));
}
/**
* Creates a new Center entity.
*
*/
public function createAction(Request $request)
{
@@ -47,71 +35,19 @@ class CenterController extends AbstractController
$em->persist($center);
$em->flush();
return $this->redirect($this->generateUrl('admin_center_show', array('id' => $center->getId())));
return $this->redirect($this->generateUrl('admin_center_show', ['id' => $center->getId()]));
}
return $this->render('@ChillMain/Center/new.html.twig', array(
return $this->render('@ChillMain/Center/new.html.twig', [
'entity' => $center,
'form' => $form->createView(),
));
}
/**
* Creates a form to create a Center entity.
*
* @param Center $center The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(Center $center)
{
$form = $this->createForm(CenterType::class, $center, array(
'action' => $this->generateUrl('admin_center_create'),
'method' => 'POST',
));
$form->add('submit', SubmitType::class, array('label' => 'Create'));
return $form;
}
/**
* Displays a form to create a new Center entity.
*
*/
public function newAction()
{
$center = new Center();
$form = $this->createCreateForm($center);
return $this->render('@ChillMain/Center/new.html.twig', array(
'entity' => $center,
'form' => $form->createView(),
));
}
/**
* Finds and displays a Center entity.
*
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$center = $em->getRepository('ChillMainBundle:Center')->find($id);
if (!$center) {
throw $this->createNotFoundException('Unable to find Center entity.');
}
return $this->render('@ChillMain/Center/show.html.twig', array(
'entity' => $center
));
'form' => $form->createView(),
]);
}
/**
* Displays a form to edit an existing Center entity.
*
* @param mixed $id
*/
public function editAction($id)
{
@@ -124,33 +60,65 @@ class CenterController extends AbstractController
}
$editForm = $this->createEditForm($center);
return $this->render('@ChillMain/Center/edit.html.twig', array(
'entity' => $center,
'edit_form' => $editForm->createView()
));
return $this->render('@ChillMain/Center/edit.html.twig', [
'entity' => $center,
'edit_form' => $editForm->createView(),
]);
}
/**
* Creates a form to edit a Center entity.
*
* @param Center $center The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(Center $center)
* Lists all Center entities.
*/
public function indexAction()
{
$form = $this->createForm(CenterType::class, $center, array(
'action' => $this->generateUrl('admin_center_update', array('id' => $center->getId())),
'method' => 'PUT',
));
$em = $this->getDoctrine()->getManager();
$form->add('submit', SubmitType::class, array('label' => 'Update'));
$entities = $em->getRepository('ChillMainBundle:Center')->findAll();
return $form;
return $this->render('@ChillMain/Center/index.html.twig', [
'entities' => $entities,
]);
}
/**
* Displays a form to create a new Center entity.
*/
public function newAction()
{
$center = new Center();
$form = $this->createCreateForm($center);
return $this->render('@ChillMain/Center/new.html.twig', [
'entity' => $center,
'form' => $form->createView(),
]);
}
/**
* Finds and displays a Center entity.
*
* @param mixed $id
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$center = $em->getRepository('ChillMainBundle:Center')->find($id);
if (!$center) {
throw $this->createNotFoundException('Unable to find Center entity.');
}
return $this->render('@ChillMain/Center/show.html.twig', [
'entity' => $center,
]);
}
/**
* Edits an existing Center entity.
*
* @param mixed $id
*/
public function updateAction(Request $request, $id)
{
@@ -168,12 +136,50 @@ class CenterController extends AbstractController
if ($editForm->isValid()) {
$em->flush();
return $this->redirect($this->generateUrl('admin_center_edit', array('id' => $id)));
return $this->redirect($this->generateUrl('admin_center_edit', ['id' => $id]));
}
return $this->render('@ChillMain/Center/edit.html.twig', array(
'entity' => $center,
'edit_form' => $editForm->createView()
));
return $this->render('@ChillMain/Center/edit.html.twig', [
'entity' => $center,
'edit_form' => $editForm->createView(),
]);
}
/**
* Creates a form to create a Center entity.
*
* @param Center $center The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(Center $center)
{
$form = $this->createForm(CenterType::class, $center, [
'action' => $this->generateUrl('admin_center_create'),
'method' => 'POST',
]);
$form->add('submit', SubmitType::class, ['label' => 'Create']);
return $form;
}
/**
* Creates a form to edit a Center entity.
*
* @param Center $center The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(Center $center)
{
$form = $this->createForm(CenterType::class, $center, [
'action' => $this->generateUrl('admin_center_update', ['id' => $center->getId()]),
'method' => 'PUT',
]);
$form->add('submit', SubmitType::class, ['label' => 'Update']);
return $form;
}
}

View File

@@ -1,23 +1,27 @@
<?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.
*/
namespace Chill\MainBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
/**
* Class DefaultController
*
* @package Chill\MainBundle\Controller
* Class DefaultController.
*/
class DefaultController extends AbstractController
{
public function indexAction()
{
{
if ($this->isGranted('ROLE_ADMIN')) {
return $this->redirectToRoute('chill_main_admin_central', [], 302);
}
return $this->render('@ChillMain/layout.html.twig');
}
@@ -25,62 +29,61 @@ class DefaultController extends AbstractController
{
return $this->redirect($this->generateUrl('chill_main_homepage'));
}
public function testAction()
{
return $this->render('@ChillMain/Tabs/index.html.twig', [
'tabs' => [
'test1' => [
[
'name' => "Link 1",
'content' => "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae auctor eu augue ut. Elementum nisi quis eleifend quam. Faucibus purus in massa tempor nec. Turpis massa sed elementum tempus egestas sed sed risus. Etiam sit amet nisl purus in mollis nunc sed id. Enim nunc faucibus a pellentesque sit amet porttitor eget. Risus nec feugiat in fermentum posuere. Augue mauris augue neque gravida. Sollicitudin aliquam ultrices sagittis orci a scelerisque purus semper eget. Id leo in vitae turpis massa sed elementum tempus egestas. Mauris commodo quis imperdiet massa. Fames ac turpis egestas integer eget aliquet nibh praesent. Urna porttitor rhoncus dolor purus non enim praesent elementum. Donec enim diam vulputate ut pharetra sit. Auctor neque vitae tempus quam. Mattis rhoncus urna neque viverra justo nec ultrices.",
'name' => 'Link 1',
'content' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae auctor eu augue ut. Elementum nisi quis eleifend quam. Faucibus purus in massa tempor nec. Turpis massa sed elementum tempus egestas sed sed risus. Etiam sit amet nisl purus in mollis nunc sed id. Enim nunc faucibus a pellentesque sit amet porttitor eget. Risus nec feugiat in fermentum posuere. Augue mauris augue neque gravida. Sollicitudin aliquam ultrices sagittis orci a scelerisque purus semper eget. Id leo in vitae turpis massa sed elementum tempus egestas. Mauris commodo quis imperdiet massa. Fames ac turpis egestas integer eget aliquet nibh praesent. Urna porttitor rhoncus dolor purus non enim praesent elementum. Donec enim diam vulputate ut pharetra sit. Auctor neque vitae tempus quam. Mattis rhoncus urna neque viverra justo nec ultrices.',
],
[
'name' => "Link 2",
'content' => "Dui sapien eget mi proin sed libero. Neque volutpat ac tincidunt vitae semper quis lectus nulla. Turpis nunc eget lorem dolor. Phasellus egestas tellus rutrum tellus. Diam sit amet nisl suscipit adipiscing bibendum est ultricies integer. Duis ultricies lacus sed turpis tincidunt id. Nisl suscipit adipiscing bibendum est ultricies integer. Elementum nibh tellus molestie nunc non blandit massa enim. Faucibus in ornare quam viverra orci sagittis eu. Neque volutpat ac tincidunt vitae semper quis lectus nulla. Accumsan sit amet nulla facilisi morbi. Leo vel fringilla est ullamcorper eget nulla facilisi etiam dignissim. Amet est placerat in egestas erat imperdiet sed euismod. Quis auctor elit sed vulputate mi. Mauris nunc congue nisi vitae suscipit tellus mauris a diam. At volutpat diam ut venenatis. Facilisis gravida neque convallis a cras semper.",
'name' => 'Link 2',
'content' => 'Dui sapien eget mi proin sed libero. Neque volutpat ac tincidunt vitae semper quis lectus nulla. Turpis nunc eget lorem dolor. Phasellus egestas tellus rutrum tellus. Diam sit amet nisl suscipit adipiscing bibendum est ultricies integer. Duis ultricies lacus sed turpis tincidunt id. Nisl suscipit adipiscing bibendum est ultricies integer. Elementum nibh tellus molestie nunc non blandit massa enim. Faucibus in ornare quam viverra orci sagittis eu. Neque volutpat ac tincidunt vitae semper quis lectus nulla. Accumsan sit amet nulla facilisi morbi. Leo vel fringilla est ullamcorper eget nulla facilisi etiam dignissim. Amet est placerat in egestas erat imperdiet sed euismod. Quis auctor elit sed vulputate mi. Mauris nunc congue nisi vitae suscipit tellus mauris a diam. At volutpat diam ut venenatis. Facilisis gravida neque convallis a cras semper.',
],
[
'name' => "Link 3",
'content' => "In ornare quam viverra orci sagittis eu volutpat. Ac tincidunt vitae semper quis lectus nulla at volutpat. Placerat duis ultricies lacus sed turpis tincidunt. Augue interdum velit euismod in pellentesque. Felis eget nunc lobortis mattis aliquam. Volutpat lacus laoreet non curabitur gravida arcu. Gravida cum sociis natoque penatibus et magnis dis parturient montes. Nisl pretium fusce id velit ut tortor. Nunc scelerisque viverra mauris in aliquam sem fringilla ut. Magna eget est lorem ipsum dolor sit. Non consectetur a erat nam at lectus urna. Eget est lorem ipsum dolor sit amet consectetur adipiscing elit. Sed velit dignissim sodales ut.",
'name' => 'Link 3',
'content' => 'In ornare quam viverra orci sagittis eu volutpat. Ac tincidunt vitae semper quis lectus nulla at volutpat. Placerat duis ultricies lacus sed turpis tincidunt. Augue interdum velit euismod in pellentesque. Felis eget nunc lobortis mattis aliquam. Volutpat lacus laoreet non curabitur gravida arcu. Gravida cum sociis natoque penatibus et magnis dis parturient montes. Nisl pretium fusce id velit ut tortor. Nunc scelerisque viverra mauris in aliquam sem fringilla ut. Magna eget est lorem ipsum dolor sit. Non consectetur a erat nam at lectus urna. Eget est lorem ipsum dolor sit amet consectetur adipiscing elit. Sed velit dignissim sodales ut.',
],
[
'name' => "Link 4",
'content' => "Ut tellus elementum sagittis vitae et. Vitae purus faucibus ornare suspendisse sed nisi lacus sed viverra. Hendrerit gravida rutrum quisque non tellus orci ac auctor augue. Eleifend quam adipiscing vitae proin sagittis nisl rhoncus mattis rhoncus. Dictumst quisque sagittis purus sit. Suspendisse sed nisi lacus sed viverra. Pretium quam vulputate dignissim suspendisse in est ante. Id eu nisl nunc mi ipsum. Ut venenatis tellus in metus vulputate. Ut morbi tincidunt augue interdum velit euismod.",
'name' => 'Link 4',
'content' => 'Ut tellus elementum sagittis vitae et. Vitae purus faucibus ornare suspendisse sed nisi lacus sed viverra. Hendrerit gravida rutrum quisque non tellus orci ac auctor augue. Eleifend quam adipiscing vitae proin sagittis nisl rhoncus mattis rhoncus. Dictumst quisque sagittis purus sit. Suspendisse sed nisi lacus sed viverra. Pretium quam vulputate dignissim suspendisse in est ante. Id eu nisl nunc mi ipsum. Ut venenatis tellus in metus vulputate. Ut morbi tincidunt augue interdum velit euismod.',
],
[
'name' => "Link 5",
'content' => "Vel elit scelerisque mauris pellentesque pulvinar. Ornare suspendisse sed nisi lacus sed viverra tellus. Massa tincidunt dui ut ornare lectus sit. Congue nisi vitae suscipit tellus mauris a diam. At auctor urna nunc id cursus metus aliquam. Viverra accumsan in nisl nisi scelerisque eu ultrices vitae. Mattis aliquam faucibus purus in massa tempor nec feugiat. Et leo duis ut diam quam. Auctor augue mauris augue neque. Purus ut faucibus pulvinar elementum integer enim neque volutpat. Scelerisque felis imperdiet proin fermentum leo. Diam sit amet nisl suscipit adipiscing bibendum est ultricies. Consectetur libero id faucibus nisl tincidunt. Vel fringilla est ullamcorper eget nulla facilisi. Pharetra diam sit amet nisl suscipit adipiscing. Dignissim diam quis enim lobortis. Auctor eu augue ut lectus arcu bibendum at varius.",
]
'name' => 'Link 5',
'content' => 'Vel elit scelerisque mauris pellentesque pulvinar. Ornare suspendisse sed nisi lacus sed viverra tellus. Massa tincidunt dui ut ornare lectus sit. Congue nisi vitae suscipit tellus mauris a diam. At auctor urna nunc id cursus metus aliquam. Viverra accumsan in nisl nisi scelerisque eu ultrices vitae. Mattis aliquam faucibus purus in massa tempor nec feugiat. Et leo duis ut diam quam. Auctor augue mauris augue neque. Purus ut faucibus pulvinar elementum integer enim neque volutpat. Scelerisque felis imperdiet proin fermentum leo. Diam sit amet nisl suscipit adipiscing bibendum est ultricies. Consectetur libero id faucibus nisl tincidunt. Vel fringilla est ullamcorper eget nulla facilisi. Pharetra diam sit amet nisl suscipit adipiscing. Dignissim diam quis enim lobortis. Auctor eu augue ut lectus arcu bibendum at varius.',
],
],
'test2' => [
[
'name' => "Link 1",
'link' => "http://localhost",
'content' => "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae auctor eu augue ut. Elementum nisi quis eleifend quam. Faucibus purus in massa tempor nec. Turpis massa sed elementum tempus egestas sed sed risus. Etiam sit amet nisl purus in mollis nunc sed id. Enim nunc faucibus a pellentesque sit amet porttitor eget. Risus nec feugiat in fermentum posuere. Augue mauris augue neque gravida. Sollicitudin aliquam ultrices sagittis orci a scelerisque purus semper eget. Id leo in vitae turpis massa sed elementum tempus egestas. Mauris commodo quis imperdiet massa. Fames ac turpis egestas integer eget aliquet nibh praesent. Urna porttitor rhoncus dolor purus non enim praesent elementum. Donec enim diam vulputate ut pharetra sit. Auctor neque vitae tempus quam. Mattis rhoncus urna neque viverra justo nec ultrices.",
'name' => 'Link 1',
'link' => 'http://localhost',
'content' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae auctor eu augue ut. Elementum nisi quis eleifend quam. Faucibus purus in massa tempor nec. Turpis massa sed elementum tempus egestas sed sed risus. Etiam sit amet nisl purus in mollis nunc sed id. Enim nunc faucibus a pellentesque sit amet porttitor eget. Risus nec feugiat in fermentum posuere. Augue mauris augue neque gravida. Sollicitudin aliquam ultrices sagittis orci a scelerisque purus semper eget. Id leo in vitae turpis massa sed elementum tempus egestas. Mauris commodo quis imperdiet massa. Fames ac turpis egestas integer eget aliquet nibh praesent. Urna porttitor rhoncus dolor purus non enim praesent elementum. Donec enim diam vulputate ut pharetra sit. Auctor neque vitae tempus quam. Mattis rhoncus urna neque viverra justo nec ultrices.',
],
[
'name' => "Link 2",
'name' => 'Link 2',
//'link' => "http://localhost",
'content' => "Dui sapien eget mi proin sed libero. Neque volutpat ac tincidunt vitae semper quis lectus nulla. Turpis nunc eget lorem dolor. Phasellus egestas tellus rutrum tellus. Diam sit amet nisl suscipit adipiscing bibendum est ultricies integer. Duis ultricies lacus sed turpis tincidunt id. Nisl suscipit adipiscing bibendum est ultricies integer. Elementum nibh tellus molestie nunc non blandit massa enim. Faucibus in ornare quam viverra orci sagittis eu. Neque volutpat ac tincidunt vitae semper quis lectus nulla. Accumsan sit amet nulla facilisi morbi. Leo vel fringilla est ullamcorper eget nulla facilisi etiam dignissim. Amet est placerat in egestas erat imperdiet sed euismod. Quis auctor elit sed vulputate mi. Mauris nunc congue nisi vitae suscipit tellus mauris a diam. At volutpat diam ut venenatis. Facilisis gravida neque convallis a cras semper.",
'content' => 'Dui sapien eget mi proin sed libero. Neque volutpat ac tincidunt vitae semper quis lectus nulla. Turpis nunc eget lorem dolor. Phasellus egestas tellus rutrum tellus. Diam sit amet nisl suscipit adipiscing bibendum est ultricies integer. Duis ultricies lacus sed turpis tincidunt id. Nisl suscipit adipiscing bibendum est ultricies integer. Elementum nibh tellus molestie nunc non blandit massa enim. Faucibus in ornare quam viverra orci sagittis eu. Neque volutpat ac tincidunt vitae semper quis lectus nulla. Accumsan sit amet nulla facilisi morbi. Leo vel fringilla est ullamcorper eget nulla facilisi etiam dignissim. Amet est placerat in egestas erat imperdiet sed euismod. Quis auctor elit sed vulputate mi. Mauris nunc congue nisi vitae suscipit tellus mauris a diam. At volutpat diam ut venenatis. Facilisis gravida neque convallis a cras semper.',
],
[
'name' => "Link 3",
'name' => 'Link 3',
//'link' => "http://localhost",
'content' => "In ornare quam viverra orci sagittis eu volutpat. Ac tincidunt vitae semper quis lectus nulla at volutpat. Placerat duis ultricies lacus sed turpis tincidunt. Augue interdum velit euismod in pellentesque. Felis eget nunc lobortis mattis aliquam. Volutpat lacus laoreet non curabitur gravida arcu. Gravida cum sociis natoque penatibus et magnis dis parturient montes. Nisl pretium fusce id velit ut tortor. Nunc scelerisque viverra mauris in aliquam sem fringilla ut. Magna eget est lorem ipsum dolor sit. Non consectetur a erat nam at lectus urna. Eget est lorem ipsum dolor sit amet consectetur adipiscing elit. Sed velit dignissim sodales ut.",
'content' => 'In ornare quam viverra orci sagittis eu volutpat. Ac tincidunt vitae semper quis lectus nulla at volutpat. Placerat duis ultricies lacus sed turpis tincidunt. Augue interdum velit euismod in pellentesque. Felis eget nunc lobortis mattis aliquam. Volutpat lacus laoreet non curabitur gravida arcu. Gravida cum sociis natoque penatibus et magnis dis parturient montes. Nisl pretium fusce id velit ut tortor. Nunc scelerisque viverra mauris in aliquam sem fringilla ut. Magna eget est lorem ipsum dolor sit. Non consectetur a erat nam at lectus urna. Eget est lorem ipsum dolor sit amet consectetur adipiscing elit. Sed velit dignissim sodales ut.',
],
[
'name' => "Link 4",
'link' => "http://localhost",
'name' => 'Link 4',
'link' => 'http://localhost',
//'content' => "Ut tellus elementum sagittis vitae et. Vitae purus faucibus ornare suspendisse sed nisi lacus sed viverra. Hendrerit gravida rutrum quisque non tellus orci ac auctor augue. Eleifend quam adipiscing vitae proin sagittis nisl rhoncus mattis rhoncus. Dictumst quisque sagittis purus sit. Suspendisse sed nisi lacus sed viverra. Pretium quam vulputate dignissim suspendisse in est ante. Id eu nisl nunc mi ipsum. Ut venenatis tellus in metus vulputate. Ut morbi tincidunt augue interdum velit euismod.",
],
[
'name' => "Link 5",
'name' => 'Link 5',
//'link' => "http://localhost",
'content' => "Vel elit scelerisque mauris pellentesque pulvinar. Ornare suspendisse sed nisi lacus sed viverra tellus. Massa tincidunt dui ut ornare lectus sit. Congue nisi vitae suscipit tellus mauris a diam. At auctor urna nunc id cursus metus aliquam. Viverra accumsan in nisl nisi scelerisque eu ultrices vitae. Mattis aliquam faucibus purus in massa tempor nec feugiat. Et leo duis ut diam quam. Auctor augue mauris augue neque. Purus ut faucibus pulvinar elementum integer enim neque volutpat. Scelerisque felis imperdiet proin fermentum leo. Diam sit amet nisl suscipit adipiscing bibendum est ultricies. Consectetur libero id faucibus nisl tincidunt. Vel fringilla est ullamcorper eget nulla facilisi. Pharetra diam sit amet nisl suscipit adipiscing. Dignissim diam quis enim lobortis. Auctor eu augue ut lectus arcu bibendum at varius.",
]
]
]
'content' => 'Vel elit scelerisque mauris pellentesque pulvinar. Ornare suspendisse sed nisi lacus sed viverra tellus. Massa tincidunt dui ut ornare lectus sit. Congue nisi vitae suscipit tellus mauris a diam. At auctor urna nunc id cursus metus aliquam. Viverra accumsan in nisl nisi scelerisque eu ultrices vitae. Mattis aliquam faucibus purus in massa tempor nec feugiat. Et leo duis ut diam quam. Auctor augue mauris augue neque. Purus ut faucibus pulvinar elementum integer enim neque volutpat. Scelerisque felis imperdiet proin fermentum leo. Diam sit amet nisl suscipit adipiscing bibendum est ultricies. Consectetur libero id faucibus nisl tincidunt. Vel fringilla est ullamcorper eget nulla facilisi. Pharetra diam sit amet nisl suscipit adipiscing. Dignissim diam quis enim lobortis. Auctor eu augue ut lectus arcu bibendum at varius.',
],
],
],
]);
}
}

View File

@@ -1,86 +1,67 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Chill\MainBundle\Export\ExportManager;
use Chill\MainBundle\Form\Type\Export\ExportType;
use Chill\MainBundle\Form\Type\Export\FormatterType;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Chill\MainBundle\Form\Type\Export\PickCenterType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Chill\MainBundle\Export\ExportManager;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Chill\MainBundle\Redis\ChillRedis;
use LogicException;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Translation\TranslatorInterface;
use function serialize;
use function unserialize;
/**
* Class ExportController
* Controller used for exporting data.
*
* @package Chill\MainBundle\Controller
*/
class ExportController extends AbstractController
{
/**
*
* @var ExportManager
*/
protected $exportManager;
/**
*
* @var LoggerInterface
*/
protected $logger;
/**
*
* @var SessionInterface
*/
protected $session;
/**
*
* @var FormFactoryInterface
*/
protected $formFactory;
/**
* @var LoggerInterface
*/
protected $logger;
/**
*
* @var ChillRedis
*/
protected $redis;
/**
* @var SessionInterface
*/
protected $session;
/**
*
* @var TranslatorInterface
*/
protected $translator;
public function __construct(
ChillRedis $chillRedis,
ExportManager $exportManager,
@@ -97,11 +78,63 @@ class ExportController extends AbstractController
$this->translator = $translator;
}
public function downloadResultAction(Request $request, $alias)
{
/* @var $exportManager \Chill\MainBundle\Export\ExportManager */
$exportManager = $this->exportManager;
$key = $request->query->get('key', null);
[$dataCenters, $dataExport, $dataFormatter] = $this->rebuildData($key);
$formatterAlias = $exportManager->getFormatterAlias($dataExport['export']);
if (null !== $formatterAlias) {
$formater = $exportManager->getFormatter($formatterAlias);
} else {
$formater = null;
}
$viewVariables = [
'alias' => $alias,
'export' => $exportManager->getExport($alias),
];
if ($formater instanceof \Chill\MainBundle\Export\Formatter\CSVListFormatter) {
// due to a bug in php, we add the mime type in the download view
$viewVariables['mime_type'] = 'text/csv';
}
return $this->render('@ChillMain/Export/download.html.twig', $viewVariables);
}
/**
* Render the list of available exports
* Generate a report.
*
* This action must work with GET queries.
*
* @param string $alias
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function generateAction(Request $request, $alias)
{
/* @var $exportManager \Chill\MainBundle\Export\ExportManager */
$exportManager = $this->exportManager;
$key = $request->query->get('key', null);
[$dataCenters, $dataExport, $dataFormatter] = $this->rebuildData($key);
return $exportManager->generate(
$alias,
$dataCenters['centers'],
$dataExport['export'],
null !== $dataFormatter ? $dataFormatter['formatter'] : []
);
}
/**
* Render the list of available exports.
*
* @param Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function indexAction(Request $request)
@@ -109,14 +142,14 @@ class ExportController extends AbstractController
$exportManager = $this->exportManager;
$exports = $exportManager->getExportsGrouped(true);
return $this->render('@ChillMain/Export/layout.html.twig', array(
'grouped_exports' => $exports
));
return $this->render('@ChillMain/Export/layout.html.twig', [
'grouped_exports' => $exports,
]);
}
/**
* handle the step to build a query for an export
* handle the step to build a query for an export.
*
* This action has three steps :
*
@@ -129,6 +162,7 @@ class ExportController extends AbstractController
*
* @param string $request
* @param Request $alias
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function newAction(Request $request, $alias)
@@ -137,7 +171,7 @@ class ExportController extends AbstractController
$exportManager = $this->exportManager;
$export = $exportManager->getExport($alias);
if ($exportManager->isGrantedForElement($export) === FALSE) {
if ($exportManager->isGrantedForElement($export) === false) {
throw $this->createAccessDeniedException('The user does not have access to this export');
}
@@ -146,77 +180,86 @@ class ExportController extends AbstractController
switch ($step) {
case 'centers':
return $this->selectCentersStep($request, $export, $alias);
case 'export':
return $this->exportFormStep($request, $export, $alias);
break;
case 'formatter':
return $this->formatterFormStep($request, $export, $alias);
break;
case 'generate':
return $this->forwardToGenerate($request, $export, $alias);
break;
default:
throw $this->createNotFoundException("The given step '$step' is invalid");
throw $this->createNotFoundException("The given step '{$step}' is invalid");
}
}
/**
*
* @param Request $request
* @param \Chill\MainBundle\Export\ExportInterface|\Chill\MainBundle\Export\DirectExportInterface $export
* create a form to show on different steps.
*
* @param string $alias
* @return Response
* @throws type
* @param array $data the data from previous step. Required for steps 'formatter' and 'generate_formatter'
*
* @return \Symfony\Component\Form\Form
*/
protected function selectCentersStep(Request $request, $export, $alias)
protected function createCreateFormExport($alias, $step, $data = [])
{
/* @var $exportManager \Chill\MainBundle\Export\ExportManager */
$exportManager = $this->exportManager;
$isGenerate = strpos($step, 'generate_') === 0;
$form = $this->createCreateFormExport($alias, 'centers');
$builder = $this->formFactory
->createNamedBuilder(null, FormType::class, [], [
'method' => $isGenerate ? 'GET' : 'POST',
'csrf_protection' => $isGenerate ? false : true,
]);
if ($request->getMethod() === 'POST') {
$form->handleRequest($request);
if ($form->isValid()) {
$this->logger->debug('form centers is valid', array(
'location' => __METHOD__));
$data = $form->getData();
// check ACL
if ($exportManager->isGrantedForElement($export, NULL,
$exportManager->getPickedCenters($data['centers'])) === FALSE) {
throw $this->createAccessDeniedException('you do not have '
. 'access to this export for those centers');
}
$this->session->set('centers_step_raw',
$request->request->all());
$this->session->set('centers_step', $data);
return $this->redirectToRoute('chill_main_export_new', array(
'step' => $this->getNextStep('centers', $export),
'alias' => $alias
));
}
if ('centers' === $step or 'generate_centers' === $step) {
$builder->add('centers', PickCenterType::class, [
'export_alias' => $alias,
]);
}
return $this->render('@ChillMain/Export/new_centers_step.html.twig',
array(
'form' => $form->createView(),
'export' => $export
));
if ('export' === $step or 'generate_export' === $step) {
$builder->add('export', ExportType::class, [
'export_alias' => $alias,
'picked_centers' => $exportManager->getPickedCenters($data['centers']),
]);
}
if ('formatter' === $step or 'generate_formatter' === $step) {
$builder->add('formatter', FormatterType::class, [
'formatter_alias' => $exportManager
->getFormatterAlias($data['export']),
'export_alias' => $alias,
'aggregator_aliases' => $exportManager
->getUsedAggregatorsAliases($data['export']),
]);
}
$builder->add('submit', SubmitType::class, [
'label' => 'Generate',
]);
return $builder->getForm();
}
/**
* Render the export form
* Render the export form.
*
* When the method is POST, the form is stored if valid, and a redirection
* is done to next step.
*
* @param string $alias
* @param \Chill\MainBundle\Export\ExportInterface|\Chill\MainBundle\Export\DirectExportInterface $export
* @param \Chill\MainBundle\Export\DirectExportInterface|\Chill\MainBundle\Export\ExportInterface $export
*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function exportFormStep(Request $request, $export, $alias)
@@ -226,12 +269,11 @@ class ExportController extends AbstractController
// check we have data from the previous step (export step)
$data = $this->session->get('centers_step', null);
if ($data === null) {
return $this->redirectToRoute('chill_main_export_new', array(
'step' => $this->getNextStep('export', $export, true),
'alias' => $alias
));
if (null === $data) {
return $this->redirectToRoute('chill_main_export_new', [
'step' => $this->getNextStep('export', $export, true),
'alias' => $alias,
]);
}
$export = $exportManager->getExport($alias);
@@ -240,123 +282,36 @@ class ExportController extends AbstractController
if ($request->getMethod() === 'POST') {
$form->handleRequest($request);
if ($form->isValid()) {
$this->logger->debug('form export is valid', array(
'location' => __METHOD__));
if ($form->isValid()) {
$this->logger->debug('form export is valid', [
'location' => __METHOD__, ]);
// store data for reusing in next steps
$data = $form->getData();
$this->session->set('export_step_raw',
$request->request->all());
$this->session->set(
'export_step_raw',
$request->request->all()
);
$this->session->set('export_step', $data);
//redirect to next step
return $this->redirect(
$this->generateUrl('chill_main_export_new', array(
'step' => $this->getNextStep('export', $export),
'alias' => $alias
)));
} else {
$this->logger->debug('form export is invalid', array(
'location' => __METHOD__));
$this->generateUrl('chill_main_export_new', [
'step' => $this->getNextStep('export', $export),
'alias' => $alias,
])
);
}
$this->logger->debug('form export is invalid', [
'location' => __METHOD__, ]);
}
return $this->render('@ChillMain/Export/new.html.twig', array(
return $this->render('@ChillMain/Export/new.html.twig', [
'form' => $form->createView(),
'export_alias' => $alias,
'export' => $export
));
}
/**
* create a form to show on different steps.
*
* @param string $alias
* @param string $step, can either be 'export', 'formatter', 'generate_export' or 'generate_formatter' (last two are used by generate action)
* @param array $data the data from previous step. Required for steps 'formatter' and 'generate_formatter'
* @return \Symfony\Component\Form\Form
*/
protected function createCreateFormExport($alias, $step, $data = array())
{
/* @var $exportManager \Chill\MainBundle\Export\ExportManager */
$exportManager = $this->exportManager;
$isGenerate = strpos($step, 'generate_') === 0;
$builder = $this->formFactory
->createNamedBuilder(null, FormType::class, array(), array(
'method' => $isGenerate ? 'GET' : 'POST',
'csrf_protection' => $isGenerate ? false : true,
));
if ($step === 'centers' or $step === 'generate_centers') {
$builder->add('centers', PickCenterType::class, array(
'export_alias' => $alias
));
}
if ($step === 'export' or $step === 'generate_export') {
$builder->add('export', ExportType::class, array(
'export_alias' => $alias,
'picked_centers' => $exportManager->getPickedCenters($data['centers'])
));
}
if ($step === 'formatter' or $step === 'generate_formatter') {
$builder->add('formatter', FormatterType::class, array(
'formatter_alias' => $exportManager
->getFormatterAlias($data['export']),
'export_alias' => $alias,
'aggregator_aliases' => $exportManager
->getUsedAggregatorsAliases($data['export'])
));
}
$builder->add('submit', SubmitType::class, array(
'label' => 'Generate'
));
return $builder->getForm();
}
/**
* get the next step. If $reverse === true, the previous step is returned.
*
* This method provides a centralized way of handling next/previous step.
*
* @param string $step the current step
* @param \Chill\MainBundle\Export\ExportInterface|\Chill\MainBundle\Export\DirectExportInterface $export
* @param boolean $reverse set to true to get the previous step
* @return string the next/current step
* @throws \LogicException if there is no step before or after the given step
*/
private function getNextStep($step, $export, $reverse = false)
{
switch($step) {
case 'centers':
if ($reverse !== false) {
throw new \LogicException("there is no step before 'export'");
}
return 'export';
case 'export':
if ($export instanceof \Chill\MainBundle\Export\ExportInterface) {
return $reverse ? 'centers' : 'formatter';
} elseif ($export instanceof \Chill\MainBundle\Export\DirectExportInterface) {
return $reverse ? 'centers' : 'generate';
}
case 'formatter' :
return $reverse ? 'export' : 'generate';
case 'generate' :
if ($reverse === false) {
throw new \LogicException("there is no step after 'generate'");
}
return 'formatter';
default:
throw new \LogicException("the step $step is not defined.");
}
'export' => $export,
]);
}
/**
@@ -365,23 +320,21 @@ class ExportController extends AbstractController
* If the form is posted and valid, store the data in session and
* redirect to the next step.
*
* @param Request $request
* @param \Chill\MainBundle\Export\ExportInterface|\Chill\MainBundle\Export\DirectExportInterface $export
* @param \Chill\MainBundle\Export\DirectExportInterface|\Chill\MainBundle\Export\ExportInterface $export
* @param string $alias
*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function formatterFormStep(Request $request, $export, $alias)
{
// check we have data from the previous step (export step)
$data = $this->session->get('export_step', null);
if ($data === null) {
return $this->redirectToRoute('chill_main_export_new', array(
'step' => $this->getNextStep('formatter', $export, true),
'alias' => $alias
));
if (null === $data) {
return $this->redirectToRoute('chill_main_export_new', [
'step' => $this->getNextStep('formatter', $export, true),
'alias' => $alias,
]);
}
$form = $this->createCreateFormExport($alias, 'formatter', $data);
@@ -392,23 +345,29 @@ class ExportController extends AbstractController
if ($form->isValid()) {
$dataFormatter = $form->getData();
$this->session->set('formatter_step', $dataFormatter);
$this->session->set('formatter_step_raw',
$request->request->all());
$this->session->set(
'formatter_step_raw',
$request->request->all()
);
//redirect to next step
return $this->redirect($this->generateUrl('chill_main_export_new',
array(
'alias' => $alias,
'step' => $this->getNextStep('formatter', $export)
)));
return $this->redirect($this->generateUrl(
'chill_main_export_new',
[
'alias' => $alias,
'step' => $this->getNextStep('formatter', $export),
]
));
}
}
return $this->render('@ChillMain/Export/new_formatter_step.html.twig',
array(
'form' => $form->createView(),
'export' => $export
));
return $this->render(
'@ChillMain/Export/new_formatter_step.html.twig',
[
'form' => $form->createView(),
'export' => $export,
]
);
}
/**
@@ -417,9 +376,9 @@ class ExportController extends AbstractController
*
* The data from previous steps is removed from session.
*
* @param Request $request
* @param \Chill\MainBundle\Export\ExportInterface|\Chill\MainBundle\Export\DirectExportInterface $export
* @param \Chill\MainBundle\Export\DirectExportInterface|\Chill\MainBundle\Export\ExportInterface $export
* @param string $alias
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
protected function forwardToGenerate(Request $request, $export, $alias)
@@ -428,22 +387,22 @@ class ExportController extends AbstractController
$dataFormatter = $this->session->get('formatter_step_raw', null);
$dataExport = $this->session->get('export_step_raw', null);
if ($dataFormatter === NULL and $export instanceof \Chill\MainBundle\Export\ExportInterface) {
return $this->redirectToRoute('chill_main_export_new', array(
'alias' => $alias, 'step' => $this->getNextStep('generate', $export, true)
));
if (null === $dataFormatter and $export instanceof \Chill\MainBundle\Export\ExportInterface) {
return $this->redirectToRoute('chill_main_export_new', [
'alias' => $alias, 'step' => $this->getNextStep('generate', $export, true),
]);
}
$parameters = [
'formatter' => $dataFormatter ?? [],
'export' => $dataExport ?? [],
'centers' => $dataCenters ?? [],
'alias' => $alias
];
'formatter' => $dataFormatter ?? [],
'export' => $dataExport ?? [],
'centers' => $dataCenters ?? [],
'alias' => $alias,
];
unset($parameters['_token']);
$key = md5(uniqid(rand(), false));
$this->redis->setEx($key, 3600, \serialize($parameters));
$this->redis->setEx($key, 3600, serialize($parameters));
// remove data from session
$this->session->remove('export_step_raw');
@@ -451,56 +410,30 @@ class ExportController extends AbstractController
$this->session->remove('formatter_step_raw');
$this->session->remove('formatter_step');
return $this->redirectToRoute('chill_main_export_download', [ 'key' => $key, 'alias' => $alias ]);
return $this->redirectToRoute('chill_main_export_download', ['key' => $key, 'alias' => $alias]);
}
/**
* Generate a report.
*
* This action must work with GET queries.
*
* @param Request $request
* @param string $alias
* @return \Symfony\Component\HttpFoundation\Response
*/
public function generateAction(Request $request, $alias)
{
/* @var $exportManager \Chill\MainBundle\Export\ExportManager */
$exportManager = $this->exportManager;
$key = $request->query->get('key', null);
list($dataCenters, $dataExport, $dataFormatter) = $this->rebuildData($key);
$r = $exportManager->generate(
$alias,
$dataCenters['centers'],
$dataExport['export'],
$dataFormatter !== NULL ? $dataFormatter['formatter'] : []
);
return $r;
}
protected function rebuildData($key)
{
if ($key === NULL) {
throw $this->createNotFoundException("key does not exists");
if (null === $key) {
throw $this->createNotFoundException('key does not exists');
}
if ($this->redis->exists($key) !== 1) {
$this->addFlash('error', $this->translator->trans("This report is not available any more"));
throw $this->createNotFoundException("key does not exists");
$this->addFlash('error', $this->translator->trans('This report is not available any more'));
throw $this->createNotFoundException('key does not exists');
}
$serialized = $this->redis->get($key);
if ($serialized === false) {
throw new \LogicException("the key could not be reached from redis");
if (false === $serialized) {
throw new LogicException('the key could not be reached from redis');
}
$rawData = \unserialize($serialized);
$rawData = unserialize($serialized);
$alias = $rawData['alias'];
$formCenters = $this->createCreateFormExport($alias, 'generate_centers');
$formCenters->submit($rawData['centers']);
$dataCenters = $formCenters->getData();
@@ -510,40 +443,119 @@ class ExportController extends AbstractController
$dataExport = $formExport->getData();
if (count($rawData['formatter']) > 0) {
$formFormatter = $this->createCreateFormExport($alias, 'generate_formatter',
$dataExport);
$formFormatter = $this->createCreateFormExport(
$alias,
'generate_formatter',
$dataExport
);
$formFormatter->submit($rawData['formatter']);
$dataFormatter = $formFormatter->getData();
}
return [$dataCenters, $dataExport, $dataFormatter ?? null];
}
public function downloadResultAction(Request $request, $alias)
{
/**
* @param \Chill\MainBundle\Export\DirectExportInterface|\Chill\MainBundle\Export\ExportInterface $export
* @param string $alias
*
* @throws type
*
* @return Response
*/
protected function selectCentersStep(Request $request, $export, $alias)
{
/* @var $exportManager \Chill\MainBundle\Export\ExportManager */
$exportManager = $this->exportManager;
$key = $request->query->get('key', null);
list($dataCenters, $dataExport, $dataFormatter) = $this->rebuildData($key);
$formatterAlias = $exportManager->getFormatterAlias($dataExport['export']);
if ($formatterAlias !== null) {
$formater = $exportManager->getFormatter($formatterAlias);
} else {
$formater = null;
$form = $this->createCreateFormExport($alias, 'centers');
if ($request->getMethod() === 'POST') {
$form->handleRequest($request);
if ($form->isValid()) {
$this->logger->debug('form centers is valid', [
'location' => __METHOD__, ]);
$data = $form->getData();
// check ACL
if ($exportManager->isGrantedForElement(
$export,
null,
$exportManager->getPickedCenters($data['centers'])
) === false) {
throw $this->createAccessDeniedException('you do not have '
. 'access to this export for those centers');
}
$this->session->set(
'centers_step_raw',
$request->request->all()
);
$this->session->set('centers_step', $data);
return $this->redirectToRoute('chill_main_export_new', [
'step' => $this->getNextStep('centers', $export),
'alias' => $alias,
]);
}
}
$viewVariables = [
'alias' => $alias,
'export' => $exportManager->getExport($alias)
];
if ($formater instanceof \Chill\MainBundle\Export\Formatter\CSVListFormatter) {
// due to a bug in php, we add the mime type in the download view
$viewVariables['mime_type'] = 'text/csv';
return $this->render(
'@ChillMain/Export/new_centers_step.html.twig',
[
'form' => $form->createView(),
'export' => $export,
]
);
}
/**
* get the next step. If $reverse === true, the previous step is returned.
*
* This method provides a centralized way of handling next/previous step.
*
* @param string $step the current step
* @param \Chill\MainBundle\Export\DirectExportInterface|\Chill\MainBundle\Export\ExportInterface $export
* @param bool $reverse set to true to get the previous step
*
* @throws LogicException if there is no step before or after the given step
*
* @return string the next/current step
*/
private function getNextStep($step, $export, $reverse = false)
{
switch ($step) {
case 'centers':
if (false !== $reverse) {
throw new LogicException("there is no step before 'export'");
}
return 'export';
case 'export':
if ($export instanceof \Chill\MainBundle\Export\ExportInterface) {
return $reverse ? 'centers' : 'formatter';
}
if ($export instanceof \Chill\MainBundle\Export\DirectExportInterface) {
return $reverse ? 'centers' : 'generate';
}
// no break
case 'formatter':
return $reverse ? 'export' : 'generate';
case 'generate':
if (false === $reverse) {
throw new LogicException("there is no step after 'generate'");
}
return 'formatter';
default:
throw new LogicException("the step {$step} is not defined.");
}
return $this->render("@ChillMain/Export/download.html.twig", $viewVariables);
}
}

View File

@@ -1,15 +1,21 @@
<?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.
*/
namespace Chill\MainBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;
use DateInterval;
use DateTime;
use Symfony\Component\HttpFoundation\Request;
/**
* Class LocationApiController
*
* @package Chill\MainBundle\Controller
* @author Champs Libres
* Class LocationApiController.
*/
class LocationApiController extends ApiController
{
@@ -27,10 +33,10 @@ class LocationApiController extends ApiController
$query->expr()->neq('e.name', ':emptyString'),
)
))
->setParameters([
'user' => $this->getUser(),
'dateBefore' => (new \DateTime())->sub(new \DateInterval('P6M')),
'emptyString' => '',
]);
->setParameters([
'user' => $this->getUser(),
'dateBefore' => (new DateTime())->sub(new DateInterval('P6M')),
'emptyString' => '',
]);
}
}
}

View File

@@ -1,5 +1,12 @@
<?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.
*/
namespace Chill\MainBundle\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController;
@@ -7,11 +14,6 @@ use Symfony\Component\HttpFoundation\Request;
class LocationController extends CRUDController
{
protected function customizeQuery(string $action, Request $request, $query): void
{
$query->where('e.availableForUsers = true'); //TODO not working
}
protected function createEntity(string $action, Request $request): object
{
$entity = parent::createEntity($action, $request);
@@ -20,4 +22,9 @@ class LocationController extends CRUDController
return $entity;
}
protected function customizeQuery(string $action, Request $request, $query): void
{
$query->where('e.availableForUsers = true'); //TODO not working
}
}

View File

@@ -1,15 +1,19 @@
<?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.
*/
namespace Chill\MainBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;
use Symfony\Component\HttpFoundation\Request;
/**
* Class LocationTypeApiController
*
* @package Chill\MainBundle\Controller
* @author Champs Libres
* Class LocationTypeApiController.
*/
class LocationTypeApiController extends ApiController
{
@@ -22,4 +26,4 @@ class LocationTypeApiController extends ApiController
)
);
}
}
}

View File

@@ -1,10 +1,16 @@
<?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.
*/
namespace Chill\MainBundle\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController;
class LocationTypeController extends CRUDController
{
}
}

View File

@@ -1,5 +1,12 @@
<?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.
*/
namespace Chill\MainBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@@ -8,41 +15,34 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
/**
* Class LoginController
*
* @package Chill\MainBundle\Controller
* Class LoginController.
*/
class LoginController extends AbstractController
{
/**
*
* @var AuthenticationUtils
*/
protected $helper;
public function __construct(AuthenticationUtils $helper)
{
$this->helper = $helper;
}
/**
* Show a login form
*
* @param Request $request
* Show a login form.
*
* @return Response
*/
public function loginAction(Request $request)
{
return $this->render('@ChillMain/Login/login.html.twig', array(
return $this->render('@ChillMain/Login/login.html.twig', [
'last_username' => $this->helper->getLastUsername(),
'error' => $this->helper->getLastAuthenticationError()
));
'error' => $this->helper->getLastAuthenticationError(),
]);
}
public function LoginCheckAction(Request $request)
{
}
}

View File

@@ -1,23 +1,28 @@
<?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.
*/
namespace Chill\MainBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
/**
* Class MenuController
*
* @package Chill\MainBundle\Controller
* Class MenuController.
*/
class MenuController extends AbstractController
{
public function writeMenuAction($menu, $layout, $activeRouteKey = null, array $args = array() )
public function writeMenuAction($menu, $layout, $activeRouteKey = null, array $args = [])
{
return $this->render($layout, array(
return $this->render($layout, [
'menu_composer' => $this->get('chill.main.menu_composer'),
'menu' => $menu,
'args' => $args,
'activeRouteKey' => $activeRouteKey
));
'activeRouteKey' => $activeRouteKey,
]);
}
}

View File

@@ -1,14 +1,20 @@
<?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.
*/
namespace Chill\MainBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Chill\MainBundle\Repository\NotificationRepository;
use Chill\MainBundle\Notification\NotificationRenderer;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Routing\Annotation\Route;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Repository\NotificationRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
/**
* @Route("/{_locale}/notification")
@@ -22,13 +28,14 @@ class NotificationController extends AbstractController
$this->security = $security;
}
/**
* @Route("/show", name="chill_main_notification_show")
*/
public function showAction(
NotificationRepository $notificationRepository, NotificationRenderer $notificationRenderer,
PaginatorFactory $paginatorFactory)
NotificationRepository $notificationRepository,
NotificationRenderer $notificationRenderer,
PaginatorFactory $paginatorFactory
)
{
$currentUser = $this->security->getUser();
@@ -37,15 +44,17 @@ class NotificationController extends AbstractController
$notifications = $notificationRepository->findAllForAttendee(
$currentUser,
$limit=$paginator->getItemsPerPage(),
$offset= $paginator->getCurrentPage()->getFirstItemNumber());
$limit = $paginator->getItemsPerPage(),
$offset = $paginator->getCurrentPage()->getFirstItemNumber()
);
$templateData = [];
$templateData = array();
foreach ($notifications as $notification) {
$data = [
'template' => $notificationRenderer->getTemplate($notification),
'template_data' => $notificationRenderer->getTemplateData($notification),
'notification' => $notification
'notification' => $notification,
];
$templateData[] = $data;
}

View File

@@ -1,72 +1,71 @@
<?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.
*/
namespace Chill\MainBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Chill\MainBundle\Form\UserPasswordType;
use Chill\MainBundle\Entity\User;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Validator\Constraints\Callback;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Chill\MainBundle\Security\PasswordRecover\RecoverPasswordHelper;
use Symfony\Component\HttpFoundation\Response;
use Chill\MainBundle\Security\PasswordRecover\TokenManager;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Chill\MainBundle\Form\UserPasswordType;
use Chill\MainBundle\Security\PasswordRecover\PasswordRecoverEvent;
use Chill\MainBundle\Security\PasswordRecover\PasswordRecoverVoter;
use Chill\MainBundle\Security\PasswordRecover\RecoverPasswordHelper;
use Chill\MainBundle\Security\PasswordRecover\TokenManager;
use DateInterval;
use DateTimeImmutable;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Validator\Constraints\Callback;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
/**
* Class PasswordController
*
* @package Chill\MainBundle\Controller
* Class PasswordController.
*/
class PasswordController extends AbstractController
{
/**
* @var UserPasswordEncoderInterface
*/
protected $passwordEncoder;
/**
* @var TranslatorInterface
*/
protected $translator;
/**
* @var LoggerInterface
*/
protected $chillLogger;
/**
* @var RecoverPasswordHelper
*/
protected $recoverPasswordHelper;
/**
* @var TokenManager
*/
protected $tokenManager;
/**
* @var EventDispatcherInterface
*/
protected $eventDispatcher;
/**
* @var UserPasswordEncoderInterface
*/
protected $passwordEncoder;
/**
* @var RecoverPasswordHelper
*/
protected $recoverPasswordHelper;
/**
* @var TokenManager
*/
protected $tokenManager;
/**
* @var TranslatorInterface
*/
protected $translator;
/**
* PasswordController constructor.
*
* @param LoggerInterface $chillLogger
* @param UserPasswordEncoderInterface $passwordEncoder
* @param RecoverPasswordHelper $recoverPasswordHelper
* @param TokenManager $tokenManager
* @param TranslatorInterface $translator
* @param EventDispatcherInterface $eventDispatcher
*/
public function __construct(
LoggerInterface $chillLogger,
@@ -83,9 +82,163 @@ class PasswordController extends AbstractController
$this->recoverPasswordHelper = $recoverPasswordHelper;
$this->eventDispatcher = $eventDispatcher;
}
/**
* @return Response
*/
public function changeConfirmedAction()
{
return $this->render('@ChillMain/Password/recover_password_changed.html.twig');
}
/**
* @return Response|\Symfony\Component\HttpFoundation\RedirectResponse
*/
public function recoverAction(Request $request)
{
if (false === $this->isGranted(PasswordRecoverVoter::ASK_TOKEN)) {
return new Response($this->translator->trans('You are not allowed '
. 'to try to recover password, due to mitigating possible '
. 'attack. Try to contact your system administrator'), Response::HTTP_FORBIDDEN);
}
$query = $request->query;
$username = $query->get(TokenManager::USERNAME_CANONICAL);
$hash = $query->getAlnum(TokenManager::HASH);
$token = $query->getAlnum(TokenManager::TOKEN);
$timestamp = $query->getInt(TokenManager::TIMESTAMP);
$user = $this->getDoctrine()->getRepository(User::class)
->findOneByUsernameCanonical($username);
if (null === $user) {
$this->eventDispatcher->dispatch(
PasswordRecoverEvent::INVALID_TOKEN,
new PasswordRecoverEvent($token, null, $request->getClientIp())
);
throw $this->createNotFoundException(sprintf('User %s not found', $username));
}
if (true !== $this->tokenManager->verify($hash, $token, $user, $timestamp)) {
$this->eventDispatcher->dispatch(
PasswordRecoverEvent::INVALID_TOKEN,
new PasswordRecoverEvent($token, $user, $request->getClientIp())
);
return new Response('Invalid token', Response::HTTP_FORBIDDEN);
}
$form = $this->passwordForm($user);
$form->remove('actual_password');
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$password = $form->get('new_password')->getData();
$user->setPassword($this->passwordEncoder->encodePassword($user, $password));
// logging for prod
$this
->chillLogger
->notice(
'setting new password for user',
[
'user' => $user->getUsername(),
]
);
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('password_request_recover_changed');
}
return $this->render('@ChillMain/Password/recover_password_form.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*
* @return Response|\Symfony\Component\HttpFoundation\RedirectResponse
*/
public function requestRecoverAction(Request $request)
{
if (false === $this->isGranted(PasswordRecoverVoter::ASK_TOKEN)) {
return new Response($this->translator->trans('You are not allowed '
. 'to try to recover password, due to mitigating possible '
. 'attack. Try to contact your system administrator'), Response::HTTP_FORBIDDEN);
}
$form = $this->requestRecoverForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/* @var $qb \Doctrine\ORM\QueryBuilder */
$qb = $this->getDoctrine()->getManager()
->createQueryBuilder();
$qb->select('u')
->from(User::class, 'u')
->where($qb->expr()->eq('u.usernameCanonical', 'UNACCENT(LOWER(:pattern))'))
->orWhere($qb->expr()->eq('u.emailCanonical', 'UNACCENT(LOWER(:pattern))'))
->setParameter('pattern', $form->get('username_or_email')->getData());
$user = $qb->getQuery()->getSingleResult();
if (empty($user->getEmail())) {
$this->addFlash('error', $this->translator->trans('This account does not have an email address. '
. 'Please ask your administrator to renew your password.'));
} else {
if (false === $this->isGranted(PasswordRecoverVoter::ASK_TOKEN, $user)) {
return new Response($this->translator->trans('You are not allowed '
. 'to try to recover password, due to mitigating possible '
. 'attack. Try to contact your system administrator'), Response::HTTP_FORBIDDEN);
}
$this->recoverPasswordHelper->sendRecoverEmail(
$user,
(new DateTimeImmutable('now'))->add(new DateInterval('PT30M'))
);
// logging for prod
$this
->chillLogger
->notice(
'Sending an email for password recovering',
[
'user' => $user->getUsername(),
]
);
$this->eventDispatcher->dispatch(
PasswordRecoverEvent::ASK_TOKEN_SUCCESS,
new PasswordRecoverEvent(null, $user, $request->getClientIp())
);
return $this->redirectToRoute('password_request_recover_confirm');
}
} elseif ($form->isSubmitted() && false === $form->isValid()) {
$this->eventDispatcher->dispatch(
PasswordRecoverEvent::ASK_TOKEN_INVALID_FORM,
new PasswordRecoverEvent(null, null, $request->getClientIp())
);
}
return $this->render('@ChillMain/Password/request_recover_password.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @return Response
*/
public function requestRecoverConfirmAction()
{
return $this->render('@ChillMain/Password/request_recover_password_confirm.html.twig');
}
/**
* @param Request $request
* @return Response
*/
public function UserPasswordAction(Request $request)
@@ -107,11 +260,11 @@ class PasswordController extends AbstractController
->chillLogger
->notice(
'update password for an user',
array(
'method' => $request->getMethod(),
'user' => $user->getUsername()
)
);
[
'method' => $request->getMethod(),
'user' => $user->getUsername(),
]
);
$user->setPassword($this->passwordEncoder->encodePassword($user, $password));
@@ -119,186 +272,16 @@ class PasswordController extends AbstractController
$em->flush();
$this->addFlash('success', $this->translator->trans('Password successfully updated!'));
return $this->redirectToRoute('change_my_password');
return $this->redirectToRoute('change_my_password');
}
// render into a template
return $this->render('@ChillMain/Password/password.html.twig', array(
'form' => $form->createView()
));
}
/**
* @param User $user
* @return \Symfony\Component\Form\Form
*/
private function passwordForm(User $user)
{
return $this
->createForm(
UserPasswordType::class,
[],
[ 'user' => $user ]
)
->add('submit', SubmitType::class, array('label' => 'Change password'))
;
}
/**
* @param Request $request
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
*/
public function recoverAction(Request $request)
{
if (FALSE === $this->isGranted(PasswordRecoverVoter::ASK_TOKEN)) {
return (new Response($this->translator->trans("You are not allowed "
. "to try to recover password, due to mitigating possible "
. "attack. Try to contact your system administrator"), Response::HTTP_FORBIDDEN));
}
$query = $request->query;
$username = $query->get(TokenManager::USERNAME_CANONICAL);
$hash = $query->getAlnum(TokenManager::HASH);
$token = $query->getAlnum(TokenManager::TOKEN);
$timestamp = $query->getInt(TokenManager::TIMESTAMP);
$user = $this->getDoctrine()->getRepository(User::class)
->findOneByUsernameCanonical($username);
if (NULL === $user) {
$this->eventDispatcher->dispatch(PasswordRecoverEvent::INVALID_TOKEN,
new PasswordRecoverEvent($token, null, $request->getClientIp()));
throw $this->createNotFoundException(sprintf('User %s not found', $username));
}
if (TRUE !== $this->tokenManager->verify($hash, $token, $user, $timestamp)) {
$this->eventDispatcher->dispatch(PasswordRecoverEvent::INVALID_TOKEN,
new PasswordRecoverEvent($token, $user, $request->getClientIp()));
return new Response("Invalid token", Response::HTTP_FORBIDDEN);
}
$form = $this->passwordForm($user);
$form->remove('actual_password');
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$password = $form->get('new_password')->getData();
$user->setPassword($this->passwordEncoder->encodePassword($user, $password));
// logging for prod
$this
->chillLogger
->notice(
'setting new password for user',
array(
'user' => $user->getUsername()
)
);
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('password_request_recover_changed');
}
return $this->render('@ChillMain/Password/recover_password_form.html.twig', [
'form' => $form->createView()
]);
}
/**
* @return Response
*/
public function changeConfirmedAction()
{
return $this->render('@ChillMain/Password/recover_password_changed.html.twig');
}
/**
* @param Request $request
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function requestRecoverAction(Request $request)
{
if (FALSE === $this->isGranted(PasswordRecoverVoter::ASK_TOKEN)) {
return (new Response($this->translator->trans("You are not allowed "
. "to try to recover password, due to mitigating possible "
. "attack. Try to contact your system administrator"), Response::HTTP_FORBIDDEN));
}
$form = $this->requestRecoverForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/* @var $qb \Doctrine\ORM\QueryBuilder */
$qb = $this->getDoctrine()->getManager()
->createQueryBuilder();
$qb->select('u')
->from(User::class, 'u')
->where($qb->expr()->eq('u.usernameCanonical', 'UNACCENT(LOWER(:pattern))'))
->orWhere($qb->expr()->eq('u.emailCanonical', 'UNACCENT(LOWER(:pattern))' ))
->setParameter('pattern', $form->get('username_or_email')->getData())
;
$user = $qb->getQuery()->getSingleResult();
if (empty($user->getEmail())) {
$this->addFlash('error', $this->translator->trans('This account does not have an email address. '
. 'Please ask your administrator to renew your password.'));
} else {
if (FALSE === $this->isGranted(PasswordRecoverVoter::ASK_TOKEN, $user)) {
return (new Response($this->translator->trans("You are not allowed "
. "to try to recover password, due to mitigating possible "
. "attack. Try to contact your system administrator"), Response::HTTP_FORBIDDEN));
}
$this->recoverPasswordHelper->sendRecoverEmail($user,
(new \DateTimeImmutable('now'))->add(new \DateInterval('PT30M')));
// logging for prod
$this
->chillLogger
->notice(
'Sending an email for password recovering',
array(
'user' => $user->getUsername()
)
);
$this->eventDispatcher->dispatch(
PasswordRecoverEvent::ASK_TOKEN_SUCCESS,
new PasswordRecoverEvent(null, $user, $request->getClientIp())
);
return $this->redirectToRoute('password_request_recover_confirm');
}
} elseif ($form->isSubmitted() && FALSE === $form->isValid()) {
$this->eventDispatcher->dispatch(
PasswordRecoverEvent::ASK_TOKEN_INVALID_FORM,
new PasswordRecoverEvent(null, null, $request->getClientIp())
);
}
return $this->render('@ChillMain/Password/request_recover_password.html.twig', [
'form' => $form->createView()
return $this->render('@ChillMain/Password/password.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @return Response
*/
public function requestRecoverConfirmAction()
{
return $this->render('@ChillMain/Password/request_recover_password_confirm.html.twig');
}
/**
* @return \Symfony\Component\Form\FormInterface
*/
@@ -310,27 +293,40 @@ class PasswordController extends AbstractController
'label' => 'Username or email',
'constraints' => [
new Callback([
'callback' => function($pattern, ExecutionContextInterface $context, $payload) {
'callback' => function ($pattern, ExecutionContextInterface $context, $payload) {
$qb = $this->getDoctrine()->getManager()
->createQueryBuilder();
->createQueryBuilder();
$qb->select('COUNT(u)')
->from(User::class, 'u')
->where($qb->expr()->eq('u.usernameCanonical', 'UNACCENT(LOWER(:pattern))'))
->orWhere($qb->expr()->eq('u.emailCanonical', 'UNACCENT(LOWER(:pattern))' ))
->setParameter('pattern', $pattern)
;
->orWhere($qb->expr()->eq('u.emailCanonical', 'UNACCENT(LOWER(:pattern))'))
->setParameter('pattern', $pattern);
if ((int) $qb->getQuery()->getSingleScalarResult() !== 1) {
$context->addViolation('This username or email does not exists');
}
}
])
]
},
]),
],
])
->add('submit', SubmitType::class, [
'label' => 'Request recover'
'label' => 'Request recover',
]);
return $builder->getForm();
}
/**
* @return \Symfony\Component\Form\Form
*/
private function passwordForm(User $user)
{
return $this
->createForm(
UserPasswordType::class,
[],
['user' => $user]
)
->add('submit', SubmitType::class, ['label' => 'Change password']);
}
}

View File

@@ -1,62 +1,62 @@
<?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.
*/
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\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Chill\MainBundle\Entity\RoleScope;
use Chill\MainBundle\Entity\PermissionsGroup;
use Chill\MainBundle\Form\PermissionsGroupType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Security\Core\Role\RoleHierarchy;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Form\Type\ComposedRoleScopeType;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* Class PermissionsGroupController
*
* @package Chill\MainBundle\Controller
* Class PermissionsGroupController.
*/
class PermissionsGroupController extends AbstractController
{
/**
* @var RoleHierarchy
*/
private $roleHierarchy;
/**
* @var RoleProvider
*/
private $roleProvider;
/**
* @var TranslatableStringHelper
*/
private $translatableStringHelper;
/**
* @var RoleProvider $roleProvider
*/
private $roleProvider;
/**
* @var RoleHierarchy $roleHierarchy
*/
private $roleHierarchy;
/**
* @var TranslatorInterface
*/
private $translator;
/**
* @var ValidatorInterface
*/
private $validator;
/**
* PermissionsGroupController constructor.
*
* @param TranslatableStringHelper $translatableStringHelper
* @param RoleProvider $roleProvider
* @param RoleHierarchy $roleHierarchy
* @param TranslatorInterface $translator
* @param ValidatorInterface $validator
*/
public function __construct(
TranslatableStringHelper $translatableStringHelper,
@@ -64,33 +64,105 @@ class PermissionsGroupController extends AbstractController
RoleHierarchy $roleHierarchy,
TranslatorInterface $translator,
ValidatorInterface $validator
)
{
) {
$this->translatableStringHelper = $translatableStringHelper;
$this->roleProvider = $roleProvider;
$this->roleHierarchy = $roleHierarchy;
$this->translator = $translator;
$this->validator = $validator;
}
/**
* Lists all PermissionsGroup entities.
* @param int $id
*
* @throws type
*
* @return Respon
*/
public function indexAction()
public function addLinkRoleScopeAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('ChillMainBundle:PermissionsGroup')->findAll();
$permissionsGroup = $em->getRepository('ChillMainBundle:PermissionsGroup')->find($id);
return $this->render('@ChillMain/PermissionsGroup/index.html.twig', array(
'entities' => $entities,
));
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(function ($form) {
return $form->createView();
}, $deleteRoleScopesForm),
'add_role_scopes_form' => $addRoleScopesForm->createView(),
]);
}
/**
* Creates a new PermissionsGroup entity.
*
*/
public function createAction(Request $request)
{
@@ -103,284 +175,24 @@ class PermissionsGroupController extends AbstractController
$em->persist($permissionsGroup);
$em->flush();
return $this->redirect($this->generateUrl('admin_permissionsgroup_edit',
array('id' => $permissionsGroup->getId())));
return $this->redirect($this->generateUrl(
'admin_permissionsgroup_edit',
['id' => $permissionsGroup->getId()]
));
}
return $this->render('@ChillMain/PermissionsGroup/new.html.twig', array(
return $this->render('@ChillMain/PermissionsGroup/new.html.twig', [
'entity' => $permissionsGroup,
'form' => $form->createView(),
));
'form' => $form->createView(),
]);
}
/**
* 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, array(
'action' => $this->generateUrl('admin_permissionsgroup_create'),
'method' => 'POST',
));
$form->add('submit', SubmitType::class, array('label' => 'Create'));
return $form;
}
/**
* 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', array(
'entity' => $permissionsGroup,
'form' => $form->createView(),
));
}
/**
* Finds and displays a PermissionsGroup entity.
*
*/
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,
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 = array();
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', array(
'entity' => $permissionsGroup,
'role_scopes_sorted' => $roleScopesSorted,
'expanded_roles' => $this->getExpandedRoles($roleScopes)
));
}
/**
* expand roleScopes to be easily shown in template
*
* @param array $roleScopes
* @return array
*/
private function getExpandedRoles(array $roleScopes)
{
$expandedRoles = array();
foreach ($roleScopes as $roleScope) {
if (!array_key_exists($roleScope->getRole(), $expandedRoles)) {
$expandedRoles[$roleScope->getRole()] =
array_map(
function(Role $role) {
return $role->getRole();
},
$this->roleHierarchy
->getReachableRoles(
array(new Role($roleScope->getRole()))
)
);
}
}
return $expandedRoles;
}
/**
* Displays a form to edit an existing PermissionsGroup entity.
*
*/
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 = array();
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 = array();
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', array(
'entity' => $permissionsGroup,
'role_scopes_sorted' => $roleScopesSorted,
'edit_form' => $editForm->createView(),
'expanded_roles' => $this->getExpandedRoles($permissionsGroup->getRoleScopes()->toArray()),
'delete_role_scopes_form' => array_map( function($form) {
return $form->createView();
}, $deleteRoleScopesForm),
'add_role_scopes_form' => $addRoleScopesForm->createView()
));
}
/**
* 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, array(
'action' => $this->generateUrl('admin_permissionsgroup_update', array('id' => $permissionsGroup->getId())),
'method' => 'PUT',
));
$form->add('submit', SubmitType::class, array('label' => 'Update'));
return $form;
}
/**
* Edits an existing PermissionsGroup entity.
*
*/
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', array('id' => $id)));
}
$deleteRoleScopesForm = array();
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 = array();
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', array(
'entity' => $permissionsGroup,
'role_scopes_sorted' => $roleScopesSorted,
'edit_form' => $editForm->createView(),
'expanded_roles' => $this->getExpandedRoles($permissionsGroup->getRoleScopes()->toArray()),
'delete_role_scopes_form' => array_map( 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(array('role' => $role, 'scope' => $scope));
if ($roleScope === NULL) {
$roleScope = (new RoleScope())
->setRole($role)
->setScope($scope)
;
$em->persist($roleScope);
}
return $roleScope;
}
/**
* remove an association between permissionsGroup and roleScope
* 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)
@@ -400,48 +212,56 @@ class PermissionsGroupController extends AbstractController
try {
$permissionsGroup->removeRoleScope($roleScope);
} catch (\RuntimeException $ex) {
$this->addFlash('notice',
} catch (RuntimeException $ex) {
$this->addFlash(
'notice',
$this->translator->trans("The role '%role%' and circle "
. "'%scope%' is not associated with this permission group", array(
. "'%scope%' is not associated with this permission group", [
'%role%' => $this->translator->trans($roleScope->getRole()),
'%scope%' => $this->translatableStringHelper
->localize($roleScope->getScope()->getName())
)));
->localize($roleScope->getScope()->getName()),
])
);
return $this->redirect($this->generateUrl('admin_permissionsgroup_edit',
array('id' => $pgid)));
return $this->redirect($this->generateUrl(
'admin_permissionsgroup_edit',
['id' => $pgid]
));
}
$em->flush();
if ($roleScope->getScope() !== NULL ) {
$this->addFlash('notice',
if ($roleScope->getScope() !== null) {
$this->addFlash(
'notice',
$this->translator->trans("The role '%role%' on circle "
. "'%scope%' has been removed", array(
. "'%scope%' has been removed", [
'%role%' => $this->translator->trans($roleScope->getRole()),
'%scope%' => $this->translatableStringHelper
->localize($roleScope->getScope()->getName())
)));
->localize($roleScope->getScope()->getName()),
])
);
} else {
$this->addFlash('notice',
$this->translator->trans("The role '%role%' has been removed", array(
'%role%' => $this->translator->trans($roleScope->getRole())
)));
$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',
array('id' => $pgid)));
return $this->redirect($this->generateUrl(
'admin_permissionsgroup_edit',
['id' => $pgid]
));
}
/**
* Displays a form to edit an existing PermissionsGroup entity.
*
* @param Request $request
* @param int $id
* @return Respon
* @throws type
* @param mixed $id
*/
public function addLinkRoleScopeAction(Request $request, $id)
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
@@ -451,71 +271,249 @@ class PermissionsGroupController extends AbstractController
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',
array('id' => $id)));
} else {
foreach($violations as $error) {
$this->addFlash('error', $error->getMessage());
}
}
} else {
foreach ($form->getErrors() as $error) {
$this->addFlash('error', $error->getMessage());
}
}
// create all the forms
$editForm = $this->createEditForm($permissionsGroup);
$deleteRoleScopesForm = array();
$deleteRoleScopesForm = [];
foreach ($permissionsGroup->getRoleScopes() as $roleScope) {
$deleteRoleScopesForm[$roleScope->getId()] = $this->createDeleteRoleScopeForm(
$permissionsGroup, $roleScope);
$permissionsGroup,
$roleScope
);
}
$addRoleScopesForm = $this->createAddRoleScopeForm($permissionsGroup);
// sort role scope by title
$roleProvider = $this->roleProvider;
$roleScopesSorted = array();
foreach($permissionsGroup->getRoleScopes()->toArray() as $roleScope) {
$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', array(
'entity' => $permissionsGroup,
'edit_form' => $editForm->createView(),
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( function($form) {
'delete_role_scopes_form' => array_map(function ($form) {
return $form->createView();
}, $deleteRoleScopesForm),
'add_role_scopes_form' => $addRoleScopesForm->createView()
));
'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,
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(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;
}
/**
@@ -525,35 +523,64 @@ class PermissionsGroupController extends AbstractController
*
* @return \Symfony\Component\Form\Form The form
*/
private function createDeleteRoleScopeForm(PermissionsGroup $permissionsGroup,
RoleScope $roleScope)
private function createDeleteRoleScopeForm(
PermissionsGroup $permissionsGroup,
RoleScope $roleScope
)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('admin_permissionsgroup_delete_role_scope',
array('pgid' => $permissionsGroup->getId(), 'rsid' => $roleScope->getId())))
->setAction($this->generateUrl(
'admin_permissionsgroup_delete_role_scope',
['pgid' => $permissionsGroup->getId(), 'rsid' => $roleScope->getId()]
))
->setMethod('DELETE')
->add('submit', SubmitType::class, array('label' => 'Delete'))
->getForm()
;
->add('submit', SubmitType::class, ['label' => 'Delete'])
->getForm();
}
/**
* creates a form to add a role scope to permissionsgroup
* Creates a form to edit a PermissionsGroup entity.
*
* @param PermissionsGroup $permissionsGroup The entity
*
* @param PermissionsGroup $permissionsGroup
* @return \Symfony\Component\Form\Form The form
*/
private function createAddRoleScopeForm(PermissionsGroup $permissionsGroup)
private function createEditForm(PermissionsGroup $permissionsGroup)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('admin_permissionsgroup_add_role_scope',
array('id' => $permissionsGroup->getId())))
->setMethod('PUT')
->add('composed_role_scope', ComposedRoleScopeType::class)
->add('submit', SubmitType::class, array('label' => 'Add permission'))
->getForm()
;
$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(
function (Role $role) {
return $role->getRole();
},
$this->roleHierarchy
->getReachableRoles(
[new Role($roleScope->getRole())]
)
);
}
}
return $expandedRoles;
}
}

View File

@@ -1,27 +1,27 @@
<?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.
*/
namespace Chill\MainBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;
use Symfony\Component\HttpFoundation\Request;
/**
* Class PostalCodeAPIController
*
* @package Chill\MainBundle\Controller
* @author Champs Libres
* Class PostalCodeAPIController.
*/
class PostalCodeAPIController extends ApiController
{
protected function customizeQuery(string $action, Request $request, $qb): void
{
if ($request->query->has('country')) {
$qb->where('e.country = :country')
->setParameter('country', $request->query->get('country'));
->setParameter('country', $request->query->get('country'));
}
}
}

View File

@@ -1,90 +1,76 @@
<?php
/*
* Chill is a software for social workers
*
* Copyright (C) 2018, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Chill\MainBundle\Entity\PostalCode;
use Symfony\Component\HttpFoundation\JsonResponse;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\Query;
/**
* Class PostalCodeController
* Chill is a software for social workers
*
* @package Chill\MainBundle\Controller
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Controller;
use Chill\MainBundle\Entity\PostalCode;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\Query;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use function array_map;
/**
* Class PostalCodeController.
*/
class PostalCodeController extends AbstractController
{
/**
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
public function __construct(TranslatableStringHelper $translatableStringHelper)
{
$this->translatableStringHelper = $translatableStringHelper;
}
/**
*
* @Route(
* "{_locale}/postalcode/search"
* "{_locale}/postalcode/search"
* )
* @param Request $request
*
* @return JsonResponse
*/
public function searchAction(Request $request)
{
$pattern = $request->query->getAlnum('q', '');
if (empty($pattern)) {
return new JsonResponse(["results" => [], "pagination" => [ "more" => false]]);
return new JsonResponse(['results' => [], 'pagination' => ['more' => false]]);
}
$query = $this->getDoctrine()->getManager()
->createQuery(sprintf(
"SELECT p.id AS id, p.name AS name, p.code AS code, "
. "country.name AS country_name, "
. "country.countryCode AS country_code "
. "FROM %s p "
. "JOIN p.country country "
. "WHERE LOWER(p.name) LIKE LOWER(:pattern) OR LOWER(p.code) LIKE LOWER(:pattern) "
. "ORDER BY code"
, PostalCode::class)
)
->setParameter('pattern', '%'.$pattern.'%')
->setMaxResults(30)
;
$results = \array_map(function($row) {
->createQuery(
sprintf(
'SELECT p.id AS id, p.name AS name, p.code AS code, '
. 'country.name AS country_name, '
. 'country.countryCode AS country_code '
. 'FROM %s p '
. 'JOIN p.country country '
. 'WHERE LOWER(p.name) LIKE LOWER(:pattern) OR LOWER(p.code) LIKE LOWER(:pattern) '
. 'ORDER BY code',
PostalCode::class
)
)
->setParameter('pattern', '%' . $pattern . '%')
->setMaxResults(30);
$results = array_map(function ($row) {
$row['country_name'] = $this->translatableStringHelper->localize($row['country_name']);
$row['text'] = $row['code']." ".$row["name"]." (".$row['country_name'].")";
$row['text'] = $row['code'] . ' ' . $row['name'] . ' (' . $row['country_name'] . ')';
return $row;
}, $query->getResult(Query::HYDRATE_ARRAY));
return new JsonResponse([ 'results' => $results, "pagination" => [ "more" => false ] ]);
return new JsonResponse(['results' => $results, 'pagination' => ['more' => false]]);
}
}

View File

@@ -1,38 +1,27 @@
<?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.
*/
namespace Chill\MainBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Form\ScopeType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request;
/**
* Class ScopeController
*
* @package Chill\MainBundle\Controller
* Class ScopeController.
*/
class ScopeController extends AbstractController
{
/**
* Lists all Scope entities.
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('ChillMainBundle:Scope')->findAll();
return $this->render('@ChillMain/Scope/index.html.twig', array(
'entities' => $entities,
));
}
/**
* Creates a new Scope entity.
*
*/
public function createAction(Request $request)
{
@@ -45,71 +34,19 @@ class ScopeController extends AbstractController
$em->persist($scope);
$em->flush();
return $this->redirect($this->generateUrl('admin_scope_show', array('id' => $scope->getId())));
return $this->redirect($this->generateUrl('admin_scope_show', ['id' => $scope->getId()]));
}
return $this->render('@ChillMain/Scope/new.html.twig', array(
return $this->render('@ChillMain/Scope/new.html.twig', [
'entity' => $scope,
'form' => $form->createView(),
));
}
/**
* Creates a form to create a Scope entity.
*
* @param Scope $scope The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(Scope $scope)
{
$form = $this->createForm(ScopeType::class, $scope, array(
'action' => $this->generateUrl('admin_scope_create'),
'method' => 'POST',
));
$form->add('submit', SubmitType::class, array('label' => 'Create'));
return $form;
}
/**
* Displays a form to create a new Scope entity.
*
*/
public function newAction()
{
$scope = new Scope();
$form = $this->createCreateForm($scope);
return $this->render('@ChillMain/Scope/new.html.twig', array(
'entity' => $scope,
'form' => $form->createView(),
));
}
/**
* Finds and displays a Scope entity.
*
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$scope = $em->getRepository('ChillMainBundle:Scope')->find($id);
if (!$scope) {
throw $this->createNotFoundException('Unable to find Scope entity.');
}
return $this->render('@ChillMain/Scope/show.html.twig', array(
'entity' => $scope
));
'form' => $form->createView(),
]);
}
/**
* Displays a form to edit an existing Scope entity.
*
* @param mixed $id
*/
public function editAction($id)
{
@@ -123,33 +60,64 @@ class ScopeController extends AbstractController
$editForm = $this->createEditForm($scope);
return $this->render('@ChillMain/Scope/edit.html.twig', array(
'entity' => $scope,
'edit_form' => $editForm->createView(),
));
return $this->render('@ChillMain/Scope/edit.html.twig', [
'entity' => $scope,
'edit_form' => $editForm->createView(),
]);
}
/**
* Creates a form to edit a Scope entity.
*
* @param Scope $scope The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(Scope $scope)
* Lists all Scope entities.
*/
public function indexAction()
{
$form = $this->createForm(ScopeType::class, $scope, array(
'action' => $this->generateUrl('admin_scope_update', array('id' => $scope->getId())),
'method' => 'PUT',
));
$em = $this->getDoctrine()->getManager();
$form->add('submit', SubmitType::class, array('label' => 'Update'));
$entities = $em->getRepository('ChillMainBundle:Scope')->findAll();
return $form;
return $this->render('@ChillMain/Scope/index.html.twig', [
'entities' => $entities,
]);
}
/**
* Displays a form to create a new Scope entity.
*/
public function newAction()
{
$scope = new Scope();
$form = $this->createCreateForm($scope);
return $this->render('@ChillMain/Scope/new.html.twig', [
'entity' => $scope,
'form' => $form->createView(),
]);
}
/**
* Finds and displays a Scope entity.
*
* @param mixed $id
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$scope = $em->getRepository('ChillMainBundle:Scope')->find($id);
if (!$scope) {
throw $this->createNotFoundException('Unable to find Scope entity.');
}
return $this->render('@ChillMain/Scope/show.html.twig', [
'entity' => $scope,
]);
}
/**
* Edits an existing Scope entity.
*
* @param mixed $id
*/
public function updateAction(Request $request, $id)
{
@@ -167,12 +135,50 @@ class ScopeController extends AbstractController
if ($editForm->isValid()) {
$em->flush();
return $this->redirect($this->generateUrl('admin_scope_edit', array('id' => $id)));
return $this->redirect($this->generateUrl('admin_scope_edit', ['id' => $id]));
}
return $this->render('@ChillMain/Scope/edit.html.twig', array(
'entity' => $scope,
'edit_form' => $editForm->createView()
));
return $this->render('@ChillMain/Scope/edit.html.twig', [
'entity' => $scope,
'edit_form' => $editForm->createView(),
]);
}
/**
* Creates a form to create a Scope entity.
*
* @param Scope $scope The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(Scope $scope)
{
$form = $this->createForm(ScopeType::class, $scope, [
'action' => $this->generateUrl('admin_scope_create'),
'method' => 'POST',
]);
$form->add('submit', SubmitType::class, ['label' => 'Create']);
return $form;
}
/**
* Creates a form to edit a Scope entity.
*
* @param Scope $scope The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(Scope $scope)
{
$form = $this->createForm(ScopeType::class, $scope, [
'action' => $this->generateUrl('admin_scope_update', ['id' => $scope->getId()]),
'method' => 'PUT',
]);
$form->add('submit', SubmitType::class, ['label' => 'Update']);
return $form;
}
}

View File

@@ -1,62 +1,47 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Controller;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Search\ParsingException;
use Chill\MainBundle\Search\SearchApi;
use Chill\MainBundle\Search\SearchApiNoQueryException;
use Chill\MainBundle\Serializer\Model\Collection;
use GuzzleHttp\Psr7\Response;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Chill\MainBundle\Search\SearchInterface;
use Chill\MainBundle\Search\SearchProvider;
use Chill\MainBundle\Search\UnknowSearchDomainException;
use Chill\MainBundle\Search\UnknowSearchNameException;
use Chill\MainBundle\Search\ParsingException;
use Chill\MainBundle\Search\SearchInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\JsonResponse;
use Chill\MainBundle\Search\SearchProvider;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Contracts\Translation\TranslatorInterface;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Search\SearchApi;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use function key;
use function reset;
/**
* Class SearchController
*
* @package Chill\MainBundle\Controller
* Class SearchController.
*/
class SearchController extends AbstractController
{
protected SearchProvider $searchProvider;
protected TranslatorInterface $translator;
protected PaginatorFactory $paginatorFactory;
protected SearchApi $searchApi;
function __construct(
protected SearchProvider $searchProvider;
protected TranslatorInterface $translator;
public function __construct(
SearchProvider $searchProvider,
TranslatorInterface $translator,
PaginatorFactory $paginatorFactory,
@@ -68,127 +53,6 @@ class SearchController extends AbstractController
$this->searchApi = $searchApi;
}
public function searchAction(Request $request, $_format)
{
$pattern = $request->query->get('q', '');
if ($pattern === ''){
switch($_format) {
case 'html':
return $this->render('@ChillMain/Search/error.html.twig',
array(
'message' => $this->translator->trans("Your search is empty. "
. "Please provide search terms."),
'pattern' => $pattern
));
case 'json':
return new JsonResponse([
'results' => [],
'pagination' => [ 'more' => false ]
]);
}
}
$name = $request->query->get('name', NULL);
try {
if ($name === NULL) {
if ($_format === 'json') {
return new JsonResponse('Currently, we still do not aggregate results '
. 'from different providers', JsonResponse::HTTP_BAD_REQUEST);
}
// no specific search selected. Rendering result in "preview" mode
$results = $this->searchProvider
->getSearchResults(
$pattern,
0,
5,
array(SearchInterface::SEARCH_PREVIEW_OPTION => true)
);
} else {
// we want search on a specific search provider. Display full results.
$results = [$this->searchProvider
->getResultByName(
$pattern,
$name,
$this->paginatorFactory->getCurrentPageFirstItemNumber(),
$this->paginatorFactory->getCurrentItemsPerPage(),
array(
SearchInterface::SEARCH_PREVIEW_OPTION => false,
SearchInterface::REQUEST_QUERY_PARAMETERS => $request
->get(SearchInterface::REQUEST_QUERY_KEY_ADD_PARAMETERS, [])
),
$_format
)];
if ($_format === 'json') {
return new JsonResponse(\reset($results));
}
}
} catch (UnknowSearchDomainException $ex) {
return $this->render('@ChillMain/Search/error.html.twig',
array(
"message" => $this->translator->trans("The domain %domain% "
. "is unknow. Please check your search.", array('%domain%' => $ex->getDomain())),
'pattern' => $pattern
));
} catch (UnknowSearchNameException $ex) {
throw $this->createNotFoundException("The name ".$ex->getName()." is not found");
} catch (ParsingException $ex) {
return $this->render('@ChillMain/Search/error.html.twig',
array(
"message" => $this->translator->trans('Invalid terms').
": ".$this->translator->trans($ex->getMessage()),
'pattern' => $pattern
));
}
return $this->render('@ChillMain/Search/list.html.twig',
array('results' => $results, 'pattern' => $pattern)
);
}
public function searchApi(Request $request, $_format): JsonResponse
{
//TODO this is an incomplete implementation
$query = $request->query->get('q', '');
$types = $request->query->get('type', []);
if (count($types) === 0) {
throw new BadRequestException("The request must contains at "
." one type");
}
try {
$collection = $this->searchApi->getResults($query, $types, []);
} catch (SearchApiNoQueryException $e) {
throw new BadRequestHttpException($e->getMessage(), $e);
}
return $this->json($collection, \Symfony\Component\HttpFoundation\Response::HTTP_OK, [], [ "groups" => ["read"]]);
}
public function advancedSearchListAction(Request $request)
{
/* @var $variable Chill\MainBundle\Search\SearchProvider */
$searchProvider = $this->searchProvider;
$advancedSearchProviders = $searchProvider
->getHasAdvancedFormSearchServices();
if(\count($advancedSearchProviders) === 1) {
\reset($advancedSearchProviders);
return $this->redirectToRoute('chill_main_advanced_search', [
'name' => \key($advancedSearchProviders)
]);
}
return $this->render('@ChillMain/Search/choose_list.html.twig');
}
public function advancedSearchAction($name, Request $request)
{
try {
@@ -196,16 +60,16 @@ class SearchController extends AbstractController
$searchProvider = $this->searchProvider;
/* @var $variable Chill\MainBundle\Search\HasAdvancedSearchFormInterface */
$search = $this->searchProvider
->getHasAdvancedFormByName($name);
->getHasAdvancedFormByName($name);
} catch (\Chill\MainBundle\Search\UnknowSearchNameException $e) {
throw $this->createNotFoundException("no advanced search for "
. "$name");
throw $this->createNotFoundException('no advanced search for '
. "{$name}");
}
if ($request->query->has('q')) {
$data = $search->convertTermsToFormData($searchProvider->parse(
$request->query->get('q')));
$request->query->get('q')
));
}
$form = $this->createAdvancedSearchForm($name, $data ?? []);
@@ -219,17 +83,146 @@ class SearchController extends AbstractController
->convertFormDataToQuery($form->getData());
return $this->redirectToRoute('chill_main_search', [
'q' => $pattern, 'name' => $name
'q' => $pattern, 'name' => $name,
]);
}
}
return $this->render('@ChillMain/Search/advanced_search.html.twig',
return $this->render(
'@ChillMain/Search/advanced_search.html.twig',
[
'form' => $form->createView(),
'name' => $name,
'title' => $search->getAdvancedSearchTitle()
'title' => $search->getAdvancedSearchTitle(),
]
);
}
public function advancedSearchListAction(Request $request)
{
/* @var $variable Chill\MainBundle\Search\SearchProvider */
$searchProvider = $this->searchProvider;
$advancedSearchProviders = $searchProvider
->getHasAdvancedFormSearchServices();
if (\count($advancedSearchProviders) === 1) {
reset($advancedSearchProviders);
return $this->redirectToRoute('chill_main_advanced_search', [
'name' => key($advancedSearchProviders),
]);
}
return $this->render('@ChillMain/Search/choose_list.html.twig');
}
public function searchAction(Request $request, $_format)
{
$pattern = $request->query->get('q', '');
if ('' === $pattern) {
switch ($_format) {
case 'html':
return $this->render(
'@ChillMain/Search/error.html.twig',
[
'message' => $this->translator->trans('Your search is empty. '
. 'Please provide search terms.'),
'pattern' => $pattern,
]
);
case 'json':
return new JsonResponse([
'results' => [],
'pagination' => ['more' => false],
]);
}
}
$name = $request->query->get('name', null);
try {
if (null === $name) {
if ('json' === $_format) {
return new JsonResponse('Currently, we still do not aggregate results '
. 'from different providers', JsonResponse::HTTP_BAD_REQUEST);
}
// no specific search selected. Rendering result in "preview" mode
$results = $this->searchProvider
->getSearchResults(
$pattern,
0,
5,
[SearchInterface::SEARCH_PREVIEW_OPTION => true]
);
} else {
// we want search on a specific search provider. Display full results.
$results = [$this->searchProvider
->getResultByName(
$pattern,
$name,
$this->paginatorFactory->getCurrentPageFirstItemNumber(),
$this->paginatorFactory->getCurrentItemsPerPage(),
[
SearchInterface::SEARCH_PREVIEW_OPTION => false,
SearchInterface::REQUEST_QUERY_PARAMETERS => $request
->get(SearchInterface::REQUEST_QUERY_KEY_ADD_PARAMETERS, []),
],
$_format
), ];
if ('json' === $_format) {
return new JsonResponse(reset($results));
}
}
} catch (UnknowSearchDomainException $ex) {
return $this->render(
'@ChillMain/Search/error.html.twig',
[
'message' => $this->translator->trans('The domain %domain% '
. 'is unknow. Please check your search.', ['%domain%' => $ex->getDomain()]),
'pattern' => $pattern,
]
);
} catch (UnknowSearchNameException $ex) {
throw $this->createNotFoundException('The name ' . $ex->getName() . ' is not found');
} catch (ParsingException $ex) {
return $this->render(
'@ChillMain/Search/error.html.twig',
[
'message' => $this->translator->trans('Invalid terms') .
': ' . $this->translator->trans($ex->getMessage()),
'pattern' => $pattern,
]
);
}
return $this->render(
'@ChillMain/Search/list.html.twig',
['results' => $results, 'pattern' => $pattern]
);
}
public function searchApi(Request $request, $_format): JsonResponse
{
//TODO this is an incomplete implementation
$query = $request->query->get('q', '');
$types = $request->query->get('type', []);
if (count($types) === 0) {
throw new BadRequestException('The request must contains at '
. ' one type');
}
try {
$collection = $this->searchApi->getResults($query, $types, []);
} catch (SearchApiNoQueryException $e) {
throw new BadRequestHttpException($e->getMessage(), $e);
}
return $this->json($collection, \Symfony\Component\HttpFoundation\Response::HTTP_OK, [], ['groups' => ['read']]);
}
protected function createAdvancedSearchForm($name, array $data = [])
@@ -240,19 +233,17 @@ class SearchController extends AbstractController
null,
FormType::class,
$data,
[ 'method' => Request::METHOD_POST ]
['method' => Request::METHOD_POST]
);
$this->searchProvider
->getHasAdvancedFormByName($name)
->buildForm($builder)
;
->buildForm($builder);
$builder->add('submit', SubmitType::class, [
'label' => 'Search'
'label' => 'Search',
]);
return $builder->getForm();
}
}

View File

@@ -1,45 +1,29 @@
<?php
/*
* Copyright (C) 2015 Champs-Libres Coopérative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Chill\MainBundle\Timeline\TimelineBuilder;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Symfony\Component\Security\Core\Role\Role;
use Chill\MainBundle\Timeline\TimelineBuilder;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
class TimelineCenterController extends AbstractController
{
protected TimelineBuilder $timelineBuilder;
protected PaginatorFactory $paginatorFactory;
protected TimelineBuilder $timelineBuilder;
private Security $security;
public function __construct(
TimelineBuilder $timelineBuilder,
PaginatorFactory $paginatorFactory,
@@ -52,15 +36,16 @@ class TimelineCenterController extends AbstractController
/**
* @Route("/{_locale}/center/timeline",
* name="chill_center_timeline",
* methods={"GET"}
* )
*/
* name="chill_center_timeline",
* methods={"GET"}
* )
*/
public function centerAction(Request $request)
{
// collect reachable center for each group
$user = $this->security->getUser();
$centers = [];
foreach ($user->getGroupCenters() as $group) {
$centers[] = $group->getCenter();
}
@@ -68,24 +53,26 @@ class TimelineCenterController extends AbstractController
if (0 === count($centers)) {
throw $this->createNotFoundException();
}
$nbItems = $this->timelineBuilder->countItems('center',
[ 'centers' => $centers ]
);
$nbItems = $this->timelineBuilder->countItems(
'center',
['centers' => $centers]
);
$paginator = $this->paginatorFactory->create($nbItems);
return $this->render('@ChillMain/Timeline/index.html.twig', array
(
return $this->render(
'@ChillMain/Timeline/index.html.twig',
[
'timeline' => $this->timelineBuilder->getTimelineHTML(
'center',
[ 'centers' => $centers ],
'center',
['centers' => $centers],
$paginator->getCurrentPage()->getFirstItemNumber(),
$paginator->getItemsPerPage()
),
),
'nb_items' => $nbItems,
'paginator' => $paginator
)
'paginator' => $paginator,
]
);
}
}

View File

@@ -1,30 +1,19 @@
<?php
/*
* Copyright (C) 2018 Champs Libres Cooperative <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Chill\MainBundle\Templating\UI\CountNotificationUser;
/**
* Class UIController
* Chill is a software for social workers
*
* @package Chill\MainBundle\Controller
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Controller;
use Chill\MainBundle\Templating\UI\CountNotificationUser;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
/**
* Class UIController.
*/
class UIController extends AbstractController
{
@@ -32,9 +21,9 @@ class UIController extends AbstractController
CountNotificationUser $counter
) {
$nb = $counter->getSumNotification($this->getUser());
return $this->render('@ChillMain/UI/notification_user_counter.html.twig', [
'nb' => $nb
'nb' => $nb,
]);
}
}

View File

@@ -1,9 +1,15 @@
<?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.
*/
namespace Chill\MainBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
@@ -11,17 +17,22 @@ class UserApiController extends ApiController
{
/**
* @Route(
* "/api/1.0/main/whoami.{_format}",
* name="chill_main_user_whoami",
* requirements={
* "_format": "json"
* }
* )
* "/api/1.0/main/whoami.{_format}",
* name="chill_main_user_whoami",
* requirements={
* "_format": "json"
* }
* )
*
* @param mixed $_format
*/
public function whoami($_format): JsonResponse
{
return $this->json($this->getUser(), JsonResponse::HTTP_OK, [],
[ "groups" => [ "read" ] ]);
return $this->json(
$this->getUser(),
JsonResponse::HTTP_OK,
[],
['groups' => ['read']]
);
}
}

View File

@@ -1,42 +1,46 @@
<?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\CRUD\Controller\AbstractCRUDController;
use Chill\MainBundle\CRUD\Controller\CRUDController;
use Chill\MainBundle\Entity\GroupCenter;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Form\Type\ComposedGroupCenterType;
use Chill\MainBundle\Form\UserCurrentLocationType;
use Chill\MainBundle\Form\UserPasswordType;
use Chill\MainBundle\Form\UserType;
use Chill\MainBundle\Pagination\PaginatorInterface;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use RuntimeException;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Form\UserType;
use Chill\MainBundle\Entity\GroupCenter;
use Chill\MainBundle\Form\Type\ComposedGroupCenterType;
use Chill\MainBundle\Form\UserCurrentLocationType;
use Chill\MainBundle\Form\UserPasswordType;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter;
class UserController extends CRUDController
{
const FORM_GROUP_CENTER_COMPOSED = 'composed_groupcenter';
public const FORM_GROUP_CENTER_COMPOSED = 'composed_groupcenter';
private LoggerInterface $logger;
private ValidatorInterface $validator;
private UserPasswordEncoderInterface $passwordEncoder;
private ValidatorInterface $validator;
public function __construct(
LoggerInterface $chillLogger,
ValidatorInterface $validator,
@@ -47,149 +51,11 @@ class UserController extends CRUDController
$this->passwordEncoder = $passwordEncoder;
}
protected function createFormFor(string $action, $entity, string $formClass = null, array $formOptions = []): FormInterface
{
// for "new", add special config
if ('new' === $action) {
return $this->createForm(UserType::class, $entity, array(
'is_creation' => true
));
}
// default behaviour
return parent::createFormFor($action, $entity, $formClass, $formOptions);
}
protected function onPrePersist(string $action, $entity, FormInterface $form, Request $request)
{
// for "new", encode the password
if ('new' === $action) {
$entity->setPassword($this->passwordEncoder
->encodePassword($entity, $form['plainPassword']->getData()));
}
// default behaviour
parent::onPrePersist($action, $entity, $form, $request);
}
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator)
{
$query->addOrderBy('e.usernameCanonical', 'ASC');
return parent::orderQuery($action, $query, $request, $paginator);
}
protected function generateTemplateParameter(string $action, $entity, Request $request, array $defaultTemplateParameters = [])
{
// add mini-forms for edit action
if ("edit" === $action) {
return array_merge(
$defaultTemplateParameters,
[
'add_groupcenter_form' => $this->createAddLinkGroupCenterForm($entity, $request)->createView(),
'delete_groupcenter_form' => array_map(
function (\Symfony\Component\Form\Form $form) {
return $form->createView();
},
iterator_to_array($this->getDeleteLinkGroupCenterByUser($entity, $request), true)
)
]
);
}
// default behaviour
return parent::generateTemplateParameter($action, $entity, $request, $defaultTemplateParameters);
}
/**
* Displays a form to edit the user password.
*
* @Route("/{_locale}/admin/user/{id}/edit_password", name="admin_user_edit_password")
*/
public function editPasswordAction(User $user, Request $request)
{
$editForm = $this->createEditPasswordForm($user);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$password = $editForm->get('new_password')->getData();
// logging for prod
$this->logger->info('update password for an user', [
'by' => $this->getUser()->getUsername(),
'user' => $user->getUsername()
]);
$user->setPassword($this->passwordEncoder->encodePassword($user, $password));
$this->getDoctrine()->getManager()->flush();
$this->addFlash('success', $this->get('translator')->trans('Password successfully updated!'));
return $this->redirect(
$request->query->has('returnPath') ? $request->query->get('returnPath') :
$this->generateUrl('chill_crud_admin_user_edit', ['id' => $user->getId()])
);
}
return $this->render('@ChillMain/User/edit_password.html.twig', [
'entity' => $user,
'edit_form' => $editForm->createView()
]);
}
private function createEditPasswordForm(User $user): FormInterface
{
return $this->createForm(
UserPasswordType::class,
null,
[
'user' => $user
]
)
->add('submit', SubmitType::class, array('label' => 'Change password'))
->remove('actual_password');
}
/**
* @Route("/{_locale}/admin/main/user/{uid}/delete_link_groupcenter/{gcid}",
* name="admin_user_delete_groupcenter")
*/
public function deleteLinkGroupCenterAction($uid, $gcid, Request $request): RedirectResponse
{
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository('ChillMainBundle:User')->find($uid);
if (!$user) {
throw $this->createNotFoundException('Unable to find User entity.');
}
$groupCenter = $em->getRepository('ChillMainBundle:GroupCenter')
->find($gcid);
if (!$groupCenter) {
throw $this->createNotFoundException('Unable to find groupCenter entity');
}
try {
$user->removeGroupCenter($groupCenter);
} catch (\RuntimeException $ex) {
$this->addFlash('error', $this->get('translator')->trans($ex->getMessage()));
return $this->redirect($this->generateUrl('chill_crud_admin_user_edit', array('id' => $uid)));
}
$em->flush();
$this->addFlash('success', $this->get('translator')
->trans('The permissions where removed.'));
return $this->redirect($this->generateUrl('chill_crud_admin_user_edit', array('id' => $uid)));
}
/**
* @Route("/{_locale}/admin/main/user/{uid}/add_link_groupcenter",
* name="admin_user_add_groupcenter")
* name="admin_user_add_groupcenter")
*
* @param mixed $uid
*/
public function addLinkGroupCenterAction(Request $request, $uid): Response
{
@@ -231,76 +97,54 @@ class UserController extends CRUDController
}
return $this->render('@ChillMain/User/edit.html.twig', [
'entity' => $user,
'edit_form' => $this->createEditForm($user)->createView(),
'entity' => $user,
'edit_form' => $this->createEditForm($user)->createView(),
'add_groupcenter_form' => $this->createAddLinkGroupCenterForm($user, $request)->createView(),
'delete_groupcenter_form' => array_map(
static fn (Form $form) => $form->createView(),
iterator_to_array($this->getDeleteLinkGroupCenterByUser($user, $request), true)
)
),
]);
}
private function getPersistedGroupCenter(GroupCenter $groupCenter)
/**
* @Route("/{_locale}/admin/main/user/{uid}/delete_link_groupcenter/{gcid}",
* name="admin_user_delete_groupcenter")
*
* @param mixed $uid
* @param mixed $gcid
*/
public function deleteLinkGroupCenterAction($uid, $gcid, Request $request): RedirectResponse
{
$em = $this->getDoctrine()->getManager();
$groupCenterManaged = $em->getRepository('ChillMainBundle:GroupCenter')
->findOneBy(array(
'center' => $groupCenter->getCenter(),
'permissionsGroup' => $groupCenter->getPermissionsGroup()
));
$user = $em->getRepository('ChillMainBundle:User')->find($uid);
if (!$groupCenterManaged) {
$em->persist($groupCenter);
return $groupCenter;
if (!$user) {
throw $this->createNotFoundException('Unable to find User entity.');
}
return $groupCenterManaged;
}
$groupCenter = $em->getRepository('ChillMainBundle:GroupCenter')
->find($gcid);
/**
* Creates a form to delete a link to a GroupCenter
*
* @param mixed $permissionsGroup The entity id
*/
private function createDeleteLinkGroupCenterForm(User $user, GroupCenter $groupCenter, $request): FormInterface
{
$returnPathParams = $request->query->has('returnPath') ? ['returnPath' => $request->query->get('returnPath')] : [];
return $this->createFormBuilder()
->setAction($this->generateUrl(
'admin_user_delete_groupcenter',
array_merge($returnPathParams, ['uid' => $user->getId(), 'gcid' => $groupCenter->getId()])
))
->setMethod('DELETE')
->add('submit', SubmitType::class, array('label' => 'Delete'))
->getForm();
}
/**
* Create a form to add a link to a groupcenter.
*/
private function createAddLinkGroupCenterForm(User $user, Request $request): FormInterface
{
$returnPathParams = $request->query->has('returnPath') ? ['returnPath' => $request->query->get('returnPath')] : [];
return $this->createFormBuilder()
->setAction($this->generateUrl(
'admin_user_add_groupcenter',
array_merge($returnPathParams, ['uid' => $user->getId()])
))
->setMethod('POST')
->add(self::FORM_GROUP_CENTER_COMPOSED, ComposedGroupCenterType::class)
->add('submit', SubmitType::class, array('label' => 'Add a new groupCenter'))
->getForm();
}
private function getDeleteLinkGroupCenterByUser(User $user, Request $request)
{
foreach ($user->getGroupCenters() as $groupCenter) {
yield $groupCenter->getId() => $this->createDeleteLinkGroupCenterForm($user, $groupCenter, $request);
if (!$groupCenter) {
throw $this->createNotFoundException('Unable to find groupCenter entity');
}
try {
$user->removeGroupCenter($groupCenter);
} catch (RuntimeException $ex) {
$this->addFlash('error', $this->get('translator')->trans($ex->getMessage()));
return $this->redirect($this->generateUrl('chill_crud_admin_user_edit', ['id' => $uid]));
}
$em->flush();
$this->addFlash('success', $this->get('translator')
->trans('The permissions where removed.'));
return $this->redirect($this->generateUrl('chill_crud_admin_user_edit', ['id' => $uid]));
}
/**
@@ -312,8 +156,8 @@ class UserController extends CRUDController
{
$user = $this->getUser();
$form = $this->createForm(UserCurrentLocationType::class, $user)
->add('submit', SubmitType::class, ['label' => 'Save'])
->handleRequest($request);
->add('submit', SubmitType::class, ['label' => 'Save'])
->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$currentLocation = $form->get('currentLocation')->getData();
@@ -330,8 +174,174 @@ class UserController extends CRUDController
}
return $this->render('@ChillMain/User/edit_current_location.html.twig', [
'entity' => $user,
'edit_form' => $form->createView()
'entity' => $user,
'edit_form' => $form->createView(),
]);
}
/**
* Displays a form to edit the user password.
*
* @Route("/{_locale}/admin/user/{id}/edit_password", name="admin_user_edit_password")
*/
public function editPasswordAction(User $user, Request $request)
{
$editForm = $this->createEditPasswordForm($user);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$password = $editForm->get('new_password')->getData();
// logging for prod
$this->logger->info('update password for an user', [
'by' => $this->getUser()->getUsername(),
'user' => $user->getUsername(),
]);
$user->setPassword($this->passwordEncoder->encodePassword($user, $password));
$this->getDoctrine()->getManager()->flush();
$this->addFlash('success', $this->get('translator')->trans('Password successfully updated!'));
return $this->redirect(
$request->query->has('returnPath') ? $request->query->get('returnPath') :
$this->generateUrl('chill_crud_admin_user_edit', ['id' => $user->getId()])
);
}
return $this->render('@ChillMain/User/edit_password.html.twig', [
'entity' => $user,
'edit_form' => $editForm->createView(),
]);
}
protected function createFormFor(string $action, $entity, ?string $formClass = null, array $formOptions = []): FormInterface
{
// for "new", add special config
if ('new' === $action) {
return $this->createForm(UserType::class, $entity, [
'is_creation' => true,
]);
}
// default behaviour
return parent::createFormFor($action, $entity, $formClass, $formOptions);
}
protected function generateTemplateParameter(string $action, $entity, Request $request, array $defaultTemplateParameters = [])
{
// add mini-forms for edit action
if ('edit' === $action) {
return array_merge(
$defaultTemplateParameters,
[
'add_groupcenter_form' => $this->createAddLinkGroupCenterForm($entity, $request)->createView(),
'delete_groupcenter_form' => array_map(
function (Form $form) {
return $form->createView();
},
iterator_to_array($this->getDeleteLinkGroupCenterByUser($entity, $request), true)
),
]
);
}
// default behaviour
return parent::generateTemplateParameter($action, $entity, $request, $defaultTemplateParameters);
}
protected function onPrePersist(string $action, $entity, FormInterface $form, Request $request)
{
// for "new", encode the password
if ('new' === $action) {
$entity->setPassword($this->passwordEncoder
->encodePassword($entity, $form['plainPassword']->getData()));
}
// default behaviour
parent::onPrePersist($action, $entity, $form, $request);
}
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator)
{
$query->addOrderBy('e.usernameCanonical', 'ASC');
return parent::orderQuery($action, $query, $request, $paginator);
}
/**
* Create a form to add a link to a groupcenter.
*/
private function createAddLinkGroupCenterForm(User $user, Request $request): FormInterface
{
$returnPathParams = $request->query->has('returnPath') ? ['returnPath' => $request->query->get('returnPath')] : [];
return $this->createFormBuilder()
->setAction($this->generateUrl(
'admin_user_add_groupcenter',
array_merge($returnPathParams, ['uid' => $user->getId()])
))
->setMethod('POST')
->add(self::FORM_GROUP_CENTER_COMPOSED, ComposedGroupCenterType::class)
->add('submit', SubmitType::class, ['label' => 'Add a new groupCenter'])
->getForm();
}
/**
* Creates a form to delete a link to a GroupCenter.
*
* @param mixed $request
*/
private function createDeleteLinkGroupCenterForm(User $user, GroupCenter $groupCenter, $request): FormInterface
{
$returnPathParams = $request->query->has('returnPath') ? ['returnPath' => $request->query->get('returnPath')] : [];
return $this->createFormBuilder()
->setAction($this->generateUrl(
'admin_user_delete_groupcenter',
array_merge($returnPathParams, ['uid' => $user->getId(), 'gcid' => $groupCenter->getId()])
))
->setMethod('DELETE')
->add('submit', SubmitType::class, ['label' => 'Delete'])
->getForm();
}
private function createEditPasswordForm(User $user): FormInterface
{
return $this->createForm(
UserPasswordType::class,
null,
[
'user' => $user,
]
)
->add('submit', SubmitType::class, ['label' => 'Change password'])
->remove('actual_password');
}
private function getDeleteLinkGroupCenterByUser(User $user, Request $request)
{
foreach ($user->getGroupCenters() as $groupCenter) {
yield $groupCenter->getId() => $this->createDeleteLinkGroupCenterForm($user, $groupCenter, $request);
}
}
private function getPersistedGroupCenter(GroupCenter $groupCenter)
{
$em = $this->getDoctrine()->getManager();
$groupCenterManaged = $em->getRepository('ChillMainBundle:GroupCenter')
->findOneBy([
'center' => $groupCenter->getCenter(),
'permissionsGroup' => $groupCenter->getPermissionsGroup(),
]);
if (!$groupCenterManaged) {
$em->persist($groupCenter);
return $groupCenter;
}
return $groupCenterManaged;
}
}