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,123 +1,124 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Export\Filter; namespace Chill\PersonBundle\Export\Filter;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Export\FilterInterface;
use DateTime;
use Doctrine\ORM\Query\Expr;
use Symfony\Component\Form\Extension\Core\Type\DateType; use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Validator\Constraints;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Doctrine\ORM\Query\Expr;
use Chill\MainBundle\Form\Type\Export\FilterType;
use Symfony\Component\Form\FormError;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
class BirthdateFilter implements FilterInterface, ExportElementValidatedInterface class BirthdateFilter implements FilterInterface, ExportElementValidatedInterface
{ {
// add specific role for this filter // add specific role for this filter
public function addRole() public function addRole()
{ {
// we do not need any new role for this filter, so we return null // we do not need any new role for this filter, so we return null
return null; return null;
} }
// here, we alter the query created by Export
public function alterQuery(\Doctrine\ORM\QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
// we create the clause here
$clause = $qb->expr()->between(
'person.birthdate',
':date_from',
':date_to'
);
// we have to take care **not to** remove previous clauses...
if ($where instanceof Expr\Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
// we add parameters from $data. $data contains the parameters from the form
$qb->setParameter('date_from', $data['date_from']);
$qb->setParameter('date_to', $data['date_to']);
}
// we give information on which type of export this filter applies // we give information on which type of export this filter applies
public function applyOn() public function applyOn()
{ {
return 'person'; return 'person';
} }
public function getTitle()
{
return 'Filter by person\'s birthdate';
}
// we build a form to collect some parameters from the users // we build a form to collect some parameters from the users
public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder) public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder)
{ {
$builder->add('date_from', DateType::class, array( $builder->add('date_from', DateType::class, [
'label' => "Born after this date", 'label' => 'Born after this date',
'data' => new \DateTime(), 'data' => new DateTime(),
'attr' => array('class' => 'datepicker'), 'attr' => ['class' => 'datepicker'],
'widget'=> 'single_text', 'widget' => 'single_text',
'format' => 'dd-MM-yyyy', 'format' => 'dd-MM-yyyy',
)); ]);
$builder->add('date_to', DateType::class, array( $builder->add('date_to', DateType::class, [
'label' => "Born before this date", 'label' => 'Born before this date',
'data' => new \DateTime(), 'data' => new DateTime(),
'attr' => array('class' => 'datepicker'), 'attr' => ['class' => 'datepicker'],
'widget'=> 'single_text', 'widget' => 'single_text',
'format' => 'dd-MM-yyyy', 'format' => 'dd-MM-yyyy',
)); ]);
}
// the form created above must be validated. The process of validation
// is executed here. This function is added by the interface
// `ExportElementValidatedInterface`, and can be ignore if there is
// no need for a validation
public function validateForm($data, ExecutionContextInterface $context)
{
$date_from = $data['date_from'];
$date_to = $data['date_to'];
if ($date_from === null) {
$context->buildViolation('The "date from" should not be empty')
//->atPath('date_from')
->addViolation();
}
if ($date_to === null) {
$context->buildViolation('The "date to" should not be empty')
//->atPath('date_to')
->addViolation();
}
if (
($date_from !== null && $date_to !== null)
&&
$date_from >= $date_to
) {
$context->buildViolation('The date "date to" should be after the '
. 'date given in "date from" field')
->addViolation();
}
}
// here, we alter the query created by Export
public function alterQuery(\Doctrine\ORM\QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
// we create the clause here
$clause = $qb->expr()->between('person.birthdate', ':date_from',
':date_to');
// we have to take care **not to** remove previous clauses...
if ($where instanceof Expr\Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
// we add parameters from $data. $data contains the parameters from the form
$qb->setParameter('date_from', $data['date_from']);
$qb->setParameter('date_to', $data['date_to']);
} }
// here, we create a simple string which will describe the action of // here, we create a simple string which will describe the action of
// the filter in the Response // the filter in the Response
public function describeAction($data, $format = 'string') public function describeAction($data, $format = 'string')
{ {
return array('Filtered by person\'s birtdate: ' return ['Filtered by person\'s birtdate: '
. 'between %date_from% and %date_to%', array( . 'between %date_from% and %date_to%', [
'%date_from%' => $data['date_from']->format('d-m-Y'), '%date_from%' => $data['date_from']->format('d-m-Y'),
'%date_to%' => $data['date_to']->format('d-m-Y') '%date_to%' => $data['date_to']->format('d-m-Y'),
)); ], ];
} }
public function getTitle()
{
return 'Filter by person\'s birthdate';
}
// the form created above must be validated. The process of validation
// is executed here. This function is added by the interface
// `ExportElementValidatedInterface`, and can be ignore if there is
// no need for a validation
public function validateForm($data, ExecutionContextInterface $context)
{
$date_from = $data['date_from'];
$date_to = $data['date_to'];
if (null === $date_from) {
$context->buildViolation('The "date from" should not be empty')
//->atPath('date_from')
->addViolation();
}
if (null === $date_to) {
$context->buildViolation('The "date to" should not be empty')
//->atPath('date_to')
->addViolation();
}
if (
(null !== $date_from && null !== $date_to)
&& $date_from >= $date_to
) {
$context->buildViolation('The date "date to" should be after the '
. 'date given in "date from" field')
->addViolation();
}
}
} }

View File

@@ -1,118 +1,115 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Export\Export; namespace Chill\PersonBundle\Export\Export;
use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\ExportInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\Query;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Symfony\Component\Security\Core\Role\Role;
use Chill\PersonBundle\Export\Declarations;
use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\FormatterInterface;
use Chill\PersonBundle\Export\Declarations;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class CountPerson implements ExportInterface class CountPerson implements ExportInterface
{ {
/** /**
*
* @var EntityManagerInterface * @var EntityManagerInterface
*/ */
protected $entityManager; protected $entityManager;
public function __construct( public function __construct(
EntityManagerInterface $em EntityManagerInterface $em
) ) {
{
$this->entityManager = $em; $this->entityManager = $em;
} }
public function getType() public function buildForm(FormBuilderInterface $builder)
{ {
return Declarations::PERSON_TYPE; // this export does not add any form
} }
public function getAllowedFormattersTypes()
{
return [FormatterInterface::TYPE_TABULAR];
}
public function getDescription() public function getDescription()
{ {
return "Count peoples by various parameters."; return 'Count peoples by various parameters.';
} }
public function getTitle() public function getLabels($key, array $values, $data)
{ {
return "Count peoples"; // the Closure which will be executed by the formatter.
return function ($value) {
switch ($value) {
case '_header':
// we have to process specifically the '_header' string,
// which will be used by the formatter to show a column title
return $this->getTitle();
default:
// for all value, we do not process them and return them
// immediatly
return $value;
}
};
} }
public function requiredRole()
{
return new Role(PersonVoter::STATS);
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = array())
{
// we gather all center the user choose.
$centers = array_map(function($el) { return $el['center']; }, $acl);
$qb = $this->entityManager->createQueryBuilder();
$qb->select('COUNT(person.id) AS export_result')
->from('ChillPersonBundle:Person', 'person')
->join('person.center', 'center')
->andWhere('center IN (:authorized_centers)')
->setParameter('authorized_centers', $centers);
;
return $qb;
}
public function getResult($qb, $data)
{
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
public function getQueryKeys($data) public function getQueryKeys($data)
{ {
// this array match the result keys in the query. We have only // this array match the result keys in the query. We have only
// one column. // one column.
return array('export_result'); return ['export_result'];
} }
public function getLabels($key, array $values, $data) public function getResult($qb, $data)
{ {
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
// the Closure which will be executed by the formatter.
return function($value) {
switch($value) {
case '_header':
// we have to process specifically the '_header' string,
// which will be used by the formatter to show a column title
return $this->getTitle();
default:
// for all value, we do not process them and return them
// immediatly
return $value;
};
} }
public function getAllowedFormattersTypes() public function getTitle()
{ {
return array(FormatterInterface::TYPE_TABULAR); return 'Count peoples';
} }
public function buildForm(FormBuilderInterface $builder) { public function getType()
// this export does not add any form {
return Declarations::PERSON_TYPE;
} }
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{
// we gather all center the user choose.
$centers = array_map(function ($el) { return $el['center']; }, $acl);
$qb = $this->entityManager->createQueryBuilder();
$qb->select('COUNT(person.id) AS export_result')
->from('ChillPersonBundle:Person', 'person')
->join('person.center', 'center')
->andWhere('center IN (:authorized_centers)')
->setParameter('authorized_centers', $centers);
return $qb;
}
public function requiredRole()
{
return new Role(PersonVoter::STATS);
}
public function supportsModifiers() public function supportsModifiers()
{ {
// explain the export manager which formatters and filters are allowed // explain the export manager which formatters and filters are allowed
return array(Declarations::PERSON_TYPE, Declarations::PERSON_IMPLIED_IN); return [Declarations::PERSON_TYPE, Declarations::PERSON_IMPLIED_IN];
} }
} }

View File

@@ -1,42 +1,47 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MyBundle\Controller; namespace Chill\MyBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class ItemController extends Controller
class ItemController extends Controller { {
public function yourAction()
public function yourAction()
{ {
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
// first, get the number of total item are available // first, get the number of total item are available
$total = $em $total = $em
->createQuery("SELECT COUNT (item.id) FROM ChillMyBundle:Item item") ->createQuery('SELECT COUNT (item.id) FROM ChillMyBundle:Item item')
->getSingleScalarResult(); ->getSingleScalarResult();
// get the PaginatorFactory // get the PaginatorFactory
$paginatorFactory = $this->get('chill_main.paginator_factory'); $paginatorFactory = $this->get('chill_main.paginator_factory');
// create a pagination instance. This instance is only valid for // create a pagination instance. This instance is only valid for
// the current route and parameters // the current route and parameters
$paginator = $paginatorFactory->create($total); $paginator = $paginatorFactory->create($total);
// launch your query on item. Limit the query to the results // launch your query on item. Limit the query to the results
// for the current page using the paginator // for the current page using the paginator
$items = $em->createQuery("SELECT item FROM ChillMyBundle:Item item WHERE <your clause>") $items = $em->createQuery('SELECT item FROM ChillMyBundle:Item item WHERE <your clause>')
// use the paginator to get the first item number // use the paginator to get the first item number
->setFirstResult($paginator->getCurrentPage()->getFirstItemNumber()) ->setFirstResult($paginator->getCurrentPage()->getFirstItemNumber())
// use the paginator to get the number of items to display // use the paginator to get the number of items to display
->setMaxResults($paginator->getItemsPerPage()); ->setMaxResults($paginator->getItemsPerPage());
return $this->render('ChillMyBundle:Item:list.html.twig', array( return $this->render(
'ChillMyBundle:Item:list.html.twig',
[
'items' => $items, 'items' => $items,
'paginator' => $paginator 'paginator' => $paginator,
); ]
);
} }
} }

View File

@@ -1,43 +1,51 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\HealthBundle\Controller; namespace Chill\HealthBundle\Controller;
use Chill\HealthBundle\Security\Authorization\ConsultationVoter; use Chill\HealthBundle\Security\Authorization\ConsultationVoter;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Chill\PersonBundle\Security\Authorization\PersonVoter; use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\Role;
class ConsultationController extends Controller class ConsultationController extends Controller
{ {
/** /**
*
* @param int $id personId * @param int $id personId
* @return \Symfony\Component\HttpFoundation\Response *
* @throws type * @throws type
*
* @return \Symfony\Component\HttpFoundation\Response
*/ */
public function listAction($id) public function listAction($id)
{ {
/* @var $person \Chill\PersonBundle\Entity\Person */ /* @var $person \Chill\PersonBundle\Entity\Person */
$person = $this->get('chill.person.repository.person') $person = $this->get('chill.person.repository.person')
->find($id); ->find($id);
if ($person === null) { if (null === $person) {
throw $this->createNotFoundException("The person is not found"); throw $this->createNotFoundException('The person is not found');
} }
$this->denyAccessUnlessGranted(PersonVoter::SEE, $person); $this->denyAccessUnlessGranted(PersonVoter::SEE, $person);
/* @var $authorizationHelper \Chill\MainBundle\Security\Authorization\AuthorizationHelper */ /* @var $authorizationHelper \Chill\MainBundle\Security\Authorization\AuthorizationHelper */
$authorizationHelper = $this->get('chill.main.security.' $authorizationHelper = $this->get('chill.main.security.'
. 'authorization.helper'); . 'authorization.helper');
$circles = $authorizationHelper->getReachableCircles( $circles = $authorizationHelper->getReachableCircles(
$this->getUser(), $this->getUser(),
new Role(ConsultationVoter::SEE), new Role(ConsultationVoter::SEE),
$person->getCenter() $person->getCenter()
); );
// create a query which take circles into account // create a query which take circles into account
$consultations = $this->getDoctrine()->getManager() $consultations = $this->getDoctrine()->getManager()
->createQuery('SELECT c FROM ChillHealthBundle:Consultation c ' ->createQuery('SELECT c FROM ChillHealthBundle:Consultation c '
. 'WHERE c.patient = :person AND c.circle IN(:circles) ' . 'WHERE c.patient = :person AND c.circle IN(:circles) '
@@ -45,11 +53,10 @@ class ConsultationController extends Controller
->setParameter('person', $person) ->setParameter('person', $person)
->setParameter('circles', $circles) ->setParameter('circles', $circles)
->getResult(); ->getResult();
return $this->render('ChillHealthBundle:Consultation:list.html.twig', array( return $this->render('ChillHealthBundle:Consultation:list.html.twig', [
'person' => $person, 'person' => $person,
'consultations' => $consultations 'consultations' => $consultations,
)); ]);
} }
} }

View File

@@ -1,64 +1,62 @@
<?php <?php
# Chill\MainBundle\DependencyInjection\Configuration.php
namespace Chill\MainBundle\DependencyInjection;
/**
* 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\DependencyInjection;
use Chill\MainBundle\DependencyInjection\Widget\AddWidgetConfigurationTrait;
use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface; use Symfony\Component\Config\Definition\ConfigurationInterface;
use Chill\MainBundle\DependencyInjection\Widget\AddWidgetConfigurationTrait;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
/** /**
* Configure the main bundle * Configure the main bundle.
*/ */
class Configuration implements ConfigurationInterface class Configuration implements ConfigurationInterface
{ {
use AddWidgetConfigurationTrait; use AddWidgetConfigurationTrait;
/** /**
* * @var ContainerBuilder
* @var ContainerBuilder */
*/
private $containerBuilder; private $containerBuilder;
public function __construct(
public function __construct(array $widgetFactories = array(), array $widgetFactories = [],
ContainerBuilder $containerBuilder) ContainerBuilder $containerBuilder
)
{ {
// we register here widget factories (see below) // we register here widget factories (see below)
$this->setWidgetFactories($widgetFactories); $this->setWidgetFactories($widgetFactories);
// we will need the container builder later... // we will need the container builder later...
$this->containerBuilder = $containerBuilder; $this->containerBuilder = $containerBuilder;
} }
/**
* {@inheritDoc}
*/
public function getConfigTreeBuilder() public function getConfigTreeBuilder()
{ {
$treeBuilder = new TreeBuilder(); $treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('chill_main'); $rootNode = $treeBuilder->root('chill_main');
$rootNode $rootNode
->children() ->children()
// ... // ...
->arrayNode('widgets')
->arrayNode('widgets') ->canBeDisabled()
->canBeDisabled() ->children()
->children()
// we declare here all configuration for homepage place // we declare here all configuration for homepage place
->append($this->addWidgetsConfiguration('homepage', $this->containerBuilder)) ->append($this->addWidgetsConfiguration('homepage', $this->containerBuilder))
->end() // end of widgets/children ->end() // end of widgets/children
->end() // end of widgets ->end() // end of widgets
->end() // end of root/children ->end() // end of root/children
->end() // end of root ->end() // end of root
; ;
return $treeBuilder;
return $treeBuilder;
} }
} }

View File

@@ -1,16 +1,17 @@
<?php <?php
#Chill\MainBundle\DependencyInjection\ChillMainExtension.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\DependencyInjection; namespace Chill\MainBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Chill\MainBundle\DependencyInjection\Widget\Factory\WidgetFactoryInterface; use Chill\MainBundle\DependencyInjection\Widget\Factory\WidgetFactoryInterface;
use Chill\MainBundle\DependencyInjection\Configuration; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
/** /**
* This class load config for chillMainExtension. * This class load config for chillMainExtension.
@@ -18,42 +19,42 @@ use Chill\MainBundle\DependencyInjection\Configuration;
class ChillMainExtension extends Extension implements Widget\HasWidgetFactoriesExtensionInterface class ChillMainExtension extends Extension implements Widget\HasWidgetFactoriesExtensionInterface
{ {
/** /**
* widget factory * widget factory.
* *
* @var WidgetFactoryInterface[] * @var WidgetFactoryInterface[]
*/ */
protected $widgetFactories = array(); protected $widgetFactories = [];
public function addWidgetFactory(WidgetFactoryInterface $factory) public function addWidgetFactory(WidgetFactoryInterface $factory)
{ {
$this->widgetFactories[] = $factory; $this->widgetFactories[] = $factory;
} }
public function getConfiguration(array $config, ContainerBuilder $container)
{
return new Configuration($this->widgetFactories, $container);
}
/** /**
*
* @return WidgetFactoryInterface[] * @return WidgetFactoryInterface[]
*/ */
public function getWidgetFactories() public function getWidgetFactories()
{ {
return $this->widgetFactories; return $this->widgetFactories;
} }
public function load(array $configs, ContainerBuilder $container) public function load(array $configs, ContainerBuilder $container)
{ {
// configuration for main bundle // configuration for main bundle
$configuration = $this->getConfiguration($configs, $container); $configuration = $this->getConfiguration($configs, $container);
$config = $this->processConfiguration($configuration, $configs); $config = $this->processConfiguration($configuration, $configs);
// add the key 'widget' without the key 'enable'
$container->setParameter('chill_main.widgets',
array('homepage' => $config['widgets']['homepage']));
// ... // add the key 'widget' without the key 'enable'
$container->setParameter(
'chill_main.widgets',
['homepage' => $config['widgets']['homepage']]
);
// ...
} }
public function getConfiguration(array $config, ContainerBuilder $container)
{
return new Configuration($this->widgetFactories, $container);
}
} }

View File

@@ -1,69 +1,71 @@
<?php <?php
# Chill/PersonBundle/Widget/PersonListWidgetFactory /**
* 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\PersonBundle\Widget; namespace Chill\PersonBundle\Widget;
use Chill\MainBundle\DependencyInjection\Widget\Factory\AbstractWidgetFactory; use Chill\MainBundle\DependencyInjection\Widget\Factory\AbstractWidgetFactory;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\Definition\Builder\NodeBuilder; use Symfony\Component\Config\Definition\Builder\NodeBuilder;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/** /**
* add configuration for the person_list widget. * add configuration for the person_list widget.
*/ */
class PersonListWidgetFactory extends AbstractWidgetFactory class PersonListWidgetFactory extends AbstractWidgetFactory
{ {
/* /*
* append the option to the configuration * append the option to the configuration
* see http://symfony.com/doc/current/components/config/definition.html * see http://symfony.com/doc/current/components/config/definition.html
* *
*/ */
public function configureOptions($place, NodeBuilder $node) public function configureOptions($place, NodeBuilder $node)
{ {
$node->booleanNode('only_active') $node->booleanNode('only_active')
->defaultTrue() ->defaultTrue()
->end(); ->end();
$node->integerNode('number_of_items') $node->integerNode('number_of_items')
->defaultValue(50) ->defaultValue(50)
->end(); ->end();
$node->scalarNode('filtering_class') $node->scalarNode('filtering_class')
->defaultNull() ->defaultNull()
->end(); ->end();
} }
/* /*
* return an array with the allowed places where the widget can be rendered * return an array with the allowed places where the widget can be rendered
* *
* @return string[] * @return string[]
*/ */
public function getAllowedPlaces() public function getAllowedPlaces()
{ {
return array('homepage'); return ['homepage'];
} }
/*
* return the widget alias
*
* @return string
*/
public function getWidgetAlias()
{
return 'person_list';
}
/* /*
* return the service id for the service which will render the widget. * return the service id for the service which will render the widget.
* *
* this service must implements `Chill\MainBundle\Templating\Widget\WidgetInterface` * this service must implements `Chill\MainBundle\Templating\Widget\WidgetInterface`
* *
* the service must exists in the container, and it is not required that the service * the service must exists in the container, and it is not required that the service
* has the `chill_main` tag. * has the `chill_main` tag.
*/ */
public function getServiceId(ContainerBuilder $containerBuilder, $place, $order, array $config) public function getServiceId(ContainerBuilder $containerBuilder, $place, $order, array $config)
{ {
return 'chill_person.widget.person_list'; return 'chill_person.widget.person_list';
} }
}
/*
* return the widget alias
*
* @return string
*/
public function getWidgetAlias()
{
return 'person_list';
}
}

View File

@@ -1,66 +1,71 @@
<?php <?php
# Chill/PersonBundle/Widget/PersonListWidget.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\PersonBundle\Widget; namespace Chill\PersonBundle\Widget;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\MainBundle\Templating\Widget\WidgetInterface; use Chill\MainBundle\Templating\Widget\WidgetInterface;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use DateTime;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository; use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr;
use Doctrine\DBAL\Types\Type;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\Role;
use Doctrine\ORM\EntityManager; use Symfony\Component\Security\Core\User\UserInterface;
use Twig_Environment;
/** /**
* add a widget with person list. * add a widget with person list.
* *
* The configuration is defined by `PersonListWidgetFactory` * The configuration is defined by `PersonListWidgetFactory`
*/ */
class PersonListWidget implements WidgetInterface class PersonListWidget implements WidgetInterface
{ {
/** /**
* Repository for persons * the authorization helper.
* *
* @var EntityRepository * @var AuthorizationHelper;
*/ */
protected $personRepository; protected $authorizationHelper;
/** /**
* The entity manager * The entity manager.
* *
* @var EntityManager * @var EntityManager
*/ */
protected $entityManager; protected $entityManager;
/**
* the authorization helper
*
* @var AuthorizationHelper;
*/
protected $authorizationHelper;
/** /**
* Repository for persons.
* *
* @var EntityRepository
*/
protected $personRepository;
/**
* @var TokenStorage * @var TokenStorage
*/ */
protected $tokenStorage; protected $tokenStorage;
/** /**
*
* @var UserInterface * @var UserInterface
*/ */
protected $user; protected $user;
public function __construct( public function __construct(
EntityRepository $personRepostory, EntityRepository $personRepostory,
EntityManager $em, EntityManager $em,
AuthorizationHelper $authorizationHelper, AuthorizationHelper $authorizationHelper,
TokenStorage $tokenStorage TokenStorage $tokenStorage
) { ) {
$this->personRepository = $personRepostory; $this->personRepository = $personRepostory;
$this->authorizationHelper = $authorizationHelper; $this->authorizationHelper = $authorizationHelper;
$this->tokenStorage = $tokenStorage; $this->tokenStorage = $tokenStorage;
@@ -68,27 +73,24 @@ class PersonListWidget implements WidgetInterface
} }
/** /**
*
* @param type $place * @param type $place
* @param array $context *
* @param array $config
* @return string * @return string
*/ */
public function render(\Twig_Environment $env, $place, array $context, array $config) public function render(Twig_Environment $env, $place, array $context, array $config)
{ {
$qb = $this->personRepository $qb = $this->personRepository
->createQueryBuilder('person'); ->createQueryBuilder('person');
// show only the person from the authorized centers // show only the person from the authorized centers
$and = $qb->expr()->andX(); $and = $qb->expr()->andX();
$centers = $this->authorizationHelper $centers = $this->authorizationHelper
->getReachableCenters($this->getUser(), new Role(PersonVoter::SEE)); ->getReachableCenters($this->getUser(), new Role(PersonVoter::SEE));
$and->add($qb->expr()->in('person.center', ':centers')); $and->add($qb->expr()->in('person.center', ':centers'));
$qb->setParameter('centers', $centers); $qb->setParameter('centers', $centers);
// add the "only active" where clause // add the "only active" where clause
if ($config['only_active'] === true) { if (true === $config['only_active']) {
$qb->join('person.accompanyingPeriods', 'ap'); $qb->join('person.accompanyingPeriods', 'ap');
$or = new Expr\Orx(); $or = new Expr\Orx();
// add the case where closingDate IS NULL // add the case where closingDate IS NULL
@@ -98,32 +100,30 @@ class PersonListWidget implements WidgetInterface
$or->add($andWhenClosingDateIsNull); $or->add($andWhenClosingDateIsNull);
// add the case when now is between opening date and closing date // add the case when now is between opening date and closing date
$or->add( $or->add(
(new Expr())->between(':now', 'ap.openingDate', 'ap.closingDate') (new Expr())->between(':now', 'ap.openingDate', 'ap.closingDate')
); );
$and->add($or); $and->add($or);
$qb->setParameter('now', new \DateTime(), Type::DATE); $qb->setParameter('now', new DateTime(), Type::DATE);
} }
// adding the where clause to the query // adding the where clause to the query
$qb->where($and); $qb->where($and);
$qb->setFirstResult(0)->setMaxResults($config['number_of_items']); $qb->setFirstResult(0)->setMaxResults($config['number_of_items']);
$persons = $qb->getQuery()->getResult(); $persons = $qb->getQuery()->getResult();
return $env->render( return $env->render(
'ChillPersonBundle:Widget:homepage_person_list.html.twig', 'ChillPersonBundle:Widget:homepage_person_list.html.twig',
array('persons' => $persons) ['persons' => $persons]
); );
} }
/** /**
*
* @return UserInterface * @return UserInterface
*/ */
private function getUser() private function getUser()
{ {
// return a user // return a user
} }
} }

View File

@@ -1,51 +1,46 @@
<?php <?php
# Chill/PersonBundle/DependencyInjection/ChillPersonExtension.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\PersonBundle\DependencyInjection; namespace Chill\PersonBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Chill\MainBundle\DependencyInjection\MissingBundleException; use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
/** /**
* This is the class that loads and manages your bundle configuration * This is the class that loads and manages your bundle configuration.
* *
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html} * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
*/ */
class ChillPersonExtension extends Extension implements PrependExtensionInterface class ChillPersonExtension extends Extension implements PrependExtensionInterface
{ {
/**
* {@inheritDoc}
*/
public function load(array $configs, ContainerBuilder $container) public function load(array $configs, ContainerBuilder $container)
{ {
// ... // ...
} }
/** /**
* * Add a widget "add a person" on the homepage, automatically.
* Add a widget "add a person" on the homepage, automatically *
*
* @param \Chill\PersonBundle\DependencyInjection\containerBuilder $container * @param \Chill\PersonBundle\DependencyInjection\containerBuilder $container
*/ */
public function prepend(ContainerBuilder $container) public function prepend(ContainerBuilder $container)
{ {
$container->prependExtensionConfig('chill_main', array( $container->prependExtensionConfig('chill_main', [
'widgets' => array( 'widgets' => [
'homepage' => array( 'homepage' => [
array( [
'widget_alias' => 'add_person', 'widget_alias' => 'add_person',
'order' => 2 'order' => 2,
) ],
) ],
) ],
)); ]);
} }
} }

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle; namespace Chill\ActivityBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle; use Symfony\Component\HttpKernel\Bundle\Bundle;

View File

@@ -1,15 +1,25 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Controller; namespace Chill\ActivityBundle\Controller;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Entity\ActivityReason; use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\ActivityBundle\Form\ActivityType;
use Chill\ActivityBundle\Repository\ActivityACLAwareRepositoryInterface; use Chill\ActivityBundle\Repository\ActivityACLAwareRepositoryInterface;
use Chill\ActivityBundle\Repository\ActivityRepository; use Chill\ActivityBundle\Repository\ActivityRepository;
use Chill\ActivityBundle\Repository\ActivityTypeCategoryRepository; use Chill\ActivityBundle\Repository\ActivityTypeCategoryRepository;
use Chill\ActivityBundle\Repository\ActivityTypeRepository; use Chill\ActivityBundle\Repository\ActivityTypeRepository;
use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
use Chill\MainBundle\Repository\LocationRepository; use Chill\MainBundle\Repository\LocationRepository;
use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\Person;
@@ -17,45 +27,44 @@ use Chill\PersonBundle\Privacy\PrivacyEvent;
use Chill\PersonBundle\Repository\AccompanyingPeriodRepository; use Chill\PersonBundle\Repository\AccompanyingPeriodRepository;
use Chill\PersonBundle\Repository\PersonRepository; use Chill\PersonBundle\Repository\PersonRepository;
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository; use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
use DateTime;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use InvalidArgumentException;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\Role;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Form\ActivityType;
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
use Symfony\Component\Serializer\SerializerInterface; use Symfony\Component\Serializer\SerializerInterface;
final class ActivityController extends AbstractController final class ActivityController extends AbstractController
{ {
private EventDispatcherInterface $eventDispatcher; private AccompanyingPeriodRepository $accompanyingPeriodRepository;
private LoggerInterface $logger;
private SerializerInterface $serializer;
private ActivityACLAwareRepositoryInterface $activityACLAwareRepository; private ActivityACLAwareRepositoryInterface $activityACLAwareRepository;
private ActivityRepository $activityRepository;
private ActivityTypeCategoryRepository $activityTypeCategoryRepository;
private ActivityTypeRepository $activityTypeRepository; private ActivityTypeRepository $activityTypeRepository;
private ThirdPartyRepository $thirdPartyRepository;
private PersonRepository $personRepository;
private LocationRepository $locationRepository;
private EntityManagerInterface $entityManager; private EntityManagerInterface $entityManager;
private ActivityRepository $activityRepository; private EventDispatcherInterface $eventDispatcher;
private AccompanyingPeriodRepository $accompanyingPeriodRepository; private LocationRepository $locationRepository;
private ActivityTypeCategoryRepository $activityTypeCategoryRepository; private LoggerInterface $logger;
private PersonRepository $personRepository;
private SerializerInterface $serializer;
private ThirdPartyRepository $thirdPartyRepository;
public function __construct( public function __construct(
ActivityACLAwareRepositoryInterface $activityACLAwareRepository, ActivityACLAwareRepositoryInterface $activityACLAwareRepository,
@@ -85,6 +94,150 @@ final class ActivityController extends AbstractController
$this->serializer = $serializer; $this->serializer = $serializer;
} }
/**
* Deletes a Activity entity.
*
* @param mixed $id
*/
public function deleteAction(Request $request, $id)
{
$view = null;
[$person, $accompanyingPeriod] = $this->getEntity($request);
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$view = 'ChillActivityBundle:Activity:confirm_deleteAccompanyingCourse.html.twig';
} elseif ($person instanceof Person) {
$view = 'ChillActivityBundle:Activity:confirm_deletePerson.html.twig';
}
$activity = $this->activityRepository->find($id);
if (!$activity) {
throw $this->createNotFoundException('Unable to find Activity entity.');
}
// TODO
// $this->denyAccessUnlessGranted('CHILL_ACTIVITY_DELETE', $activity);
$form = $this->createDeleteForm($activity->getId(), $person, $accompanyingPeriod);
if ($request->getMethod() === Request::METHOD_DELETE) {
$form->handleRequest($request);
if ($form->isValid()) {
$this->logger->notice('An activity has been removed', [
'by_user' => $this->getUser()->getUsername(),
'activity_id' => $activity->getId(),
'person_id' => $activity->getPerson() ? $activity->getPerson()->getId() : null,
'comment' => $activity->getComment()->getComment(),
'scope_id' => $activity->getScope() ? $activity->getScope()->getId() : null,
'reasons_ids' => $activity->getReasons()
->map(
static fn (ActivityReason $ar): int => $ar->getId()
)
->toArray(),
'type_id' => $activity->getType()->getId(),
'duration' => $activity->getDurationTime() ? $activity->getDurationTime()->format('U') : null,
'date' => $activity->getDate()->format('Y-m-d'),
'attendee' => $activity->getAttendee(),
]);
$this->entityManager->remove($activity);
$this->entityManager->flush();
$this->addFlash('success', $this->get('translator')
->trans('The activity has been successfully removed.'));
$params = $this->buildParamsToUrl($person, $accompanyingPeriod);
return $this->redirectToRoute('chill_activity_activity_list', $params);
}
}
if (null === $view) {
throw $this->createNotFoundException('Template not found');
}
return $this->render($view, [
'activity' => $activity,
'delete_form' => $form->createView(),
'person' => $person,
'accompanyingCourse' => $accompanyingPeriod,
]);
}
/**
* Displays a form to edit an existing Activity entity.
*/
public function editAction(int $id, Request $request): Response
{
$view = null;
[$person, $accompanyingPeriod] = $this->getEntity($request);
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$view = 'ChillActivityBundle:Activity:editAccompanyingCourse.html.twig';
} elseif ($person instanceof Person) {
$view = 'ChillActivityBundle:Activity:editPerson.html.twig';
}
$entity = $this->activityRepository->find($id);
if (null === $entity) {
throw $this->createNotFoundException('Unable to find Activity entity.');
}
// TODO
// $this->denyAccessUnlessGranted('CHILL_ACTIVITY_UPDATE', $entity);
$form = $this->createForm(ActivityType::class, $entity, [
'center' => $entity->getCenter(),
'role' => new Role('CHILL_ACTIVITY_UPDATE'),
'activityType' => $entity->getType(),
'accompanyingPeriod' => $accompanyingPeriod,
])->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->entityManager->persist($entity);
$this->entityManager->flush();
$this->addFlash('success', $this->get('translator')->trans('Success : activity updated!'));
$params = $this->buildParamsToUrl($person, $accompanyingPeriod);
$params['id'] = $entity->getId();
return $this->redirectToRoute('chill_activity_activity_show', $params);
}
$deleteForm = $this->createDeleteForm($entity->getId(), $person, $accompanyingPeriod);
/*
* TODO
$event = new PrivacyEvent($person, array(
'element_class' => Activity::class,
'element_id' => $entity->getId(),
'action' => 'edit'
));
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
*/
if (null === $view) {
throw $this->createNotFoundException('Template not found');
}
$activity_array = $this->serializer->normalize($entity, 'json', ['groups' => 'read']);
return $this->render($view, [
'entity' => $entity,
'edit_form' => $form->createView(),
'delete_form' => $deleteForm->createView(),
'person' => $person,
'accompanyingCourse' => $accompanyingPeriod,
'activity_json' => $activity_array,
]);
}
/** /**
* Lists all Activity entities. * Lists all Activity entities.
*/ */
@@ -103,7 +256,7 @@ final class ActivityController extends AbstractController
$event = new PrivacyEvent($person, [ $event = new PrivacyEvent($person, [
'element_class' => Activity::class, 'element_class' => Activity::class,
'action' => 'list' 'action' => 'list',
]); ]);
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event); $this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
@@ -121,12 +274,152 @@ final class ActivityController extends AbstractController
$view, $view,
[ [
'activities' => $activities, 'activities' => $activities,
'person' => $person, 'person' => $person,
'accompanyingCourse' => $accompanyingPeriod, 'accompanyingCourse' => $accompanyingPeriod,
] ]
); );
} }
public function newAction(Request $request): Response
{
$view = null;
[$person, $accompanyingPeriod] = $this->getEntity($request);
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$view = 'ChillActivityBundle:Activity:newAccompanyingCourse.html.twig';
} elseif ($person instanceof Person) {
$view = 'ChillActivityBundle:Activity:newPerson.html.twig';
}
$activityType_id = $request->get('activityType_id', 0);
$activityType = $this->activityTypeRepository->find($activityType_id);
if (isset($activityType) && !$activityType->isActive()) {
throw new InvalidArgumentException('Activity type must be active');
}
$activityData = null;
if ($request->query->has('activityData')) {
$activityData = $request->query->get('activityData');
}
if (!$activityType instanceof \Chill\ActivityBundle\Entity\ActivityType
|| !$activityType->isActive()) {
$params = $this->buildParamsToUrl($person, $accompanyingPeriod);
if (null !== $activityData) {
$params['activityData'] = $activityData;
}
return $this->redirectToRoute('chill_activity_activity_select_type', $params);
}
$entity = new Activity();
$entity->setUser($this->getUser());
if ($person instanceof Person) {
$entity->setPerson($person);
}
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$entity->setAccompanyingPeriod($accompanyingPeriod);
}
$entity->setType($activityType);
$entity->setDate(new DateTime('now'));
if ($request->query->has('activityData')) {
$activityData = $request->query->get('activityData');
if (array_key_exists('durationTime', $activityData)) {
$durationTimeInMinutes = $activityData['durationTime'];
$hours = floor($durationTimeInMinutes / 60);
$minutes = $durationTimeInMinutes % 60;
$duration = DateTime::createFromFormat('H:i', $hours . ':' . $minutes);
if ($duration) {
$entity->setDurationTime($duration);
}
}
if (array_key_exists('date', $activityData)) {
$date = DateTime::createFromFormat('Y-m-d', $activityData['date']);
if ($date) {
$entity->setDate($date);
}
}
if (array_key_exists('personsId', $activityData)) {
foreach ($activityData['personsId'] as $personId) {
$concernedPerson = $this->personRepository->find($personId);
$entity->addPerson($concernedPerson);
}
}
if (array_key_exists('professionalsId', $activityData)) {
foreach ($activityData['professionalsId'] as $professionalsId) {
$professional = $this->thirdPartyRepository->find($professionalsId);
$entity->addThirdParty($professional);
}
}
if (array_key_exists('location', $activityData)) {
$location = $this->locationRepository->find($activityData['location']);
$entity->setLocation($location);
}
if (array_key_exists('comment', $activityData)) {
$comment = new CommentEmbeddable();
$comment->setComment($activityData['comment']);
$comment->setUserId($this->getUser()->getid());
$comment->setDate(new DateTime('now'));
$entity->setComment($comment);
}
}
$this->denyAccessUnlessGranted(ActivityVoter::CREATE, $entity);
$form = $this->createForm(ActivityType::class, $entity, [
'center' => $entity->getCenter(),
'role' => new Role('CHILL_ACTIVITY_CREATE'),
'activityType' => $entity->getType(),
'accompanyingPeriod' => $accompanyingPeriod,
])->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->entityManager->persist($entity);
$this->entityManager->flush();
$this->addFlash('success', $this->get('translator')->trans('Success : activity created!'));
$params = $this->buildParamsToUrl($person, $accompanyingPeriod);
$params['id'] = $entity->getId();
return $this->redirectToRoute('chill_activity_activity_show', $params);
}
if (null === $view) {
throw $this->createNotFoundException('Template not found');
}
$activity_array = $this->serializer->normalize($entity, 'json', ['groups' => 'read']);
$defaultLocationId = $this->getUser()->getCurrentLocation()->getId();
return $this->render($view, [
'person' => $person,
'accompanyingCourse' => $accompanyingPeriod,
'entity' => $entity,
'form' => $form->createView(),
'activity_json' => $activity_array,
'default_location_id' => $defaultLocationId,
]);
}
public function selectTypeAction(Request $request): Response public function selectTypeAction(Request $request): Response
{ {
$view = null; $view = null;
@@ -159,7 +452,7 @@ final class ActivityController extends AbstractController
]; ];
} }
if ($view === null) { if (null === $view) {
throw $this->createNotFoundException('Template not found'); throw $this->createNotFoundException('Template not found');
} }
@@ -171,144 +464,6 @@ final class ActivityController extends AbstractController
]); ]);
} }
public function newAction(Request $request): Response
{
$view = null;
[$person, $accompanyingPeriod] = $this->getEntity($request);
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$view = 'ChillActivityBundle:Activity:newAccompanyingCourse.html.twig';
} elseif ($person instanceof Person) {
$view = 'ChillActivityBundle:Activity:newPerson.html.twig';
}
$activityType_id = $request->get('activityType_id', 0);
$activityType = $this->activityTypeRepository->find($activityType_id);
if (isset($activityType) && !$activityType->isActive()) {
throw new \InvalidArgumentException('Activity type must be active');
}
$activityData = null;
if ($request->query->has('activityData')) {
$activityData = $request->query->get('activityData');
}
if (!$activityType instanceof \Chill\ActivityBundle\Entity\ActivityType ||
!$activityType->isActive()) {
$params = $this->buildParamsToUrl($person, $accompanyingPeriod);
if (null !== $activityData) {
$params['activityData'] = $activityData;
}
return $this->redirectToRoute('chill_activity_activity_select_type', $params);
}
$entity = new Activity();
$entity->setUser($this->getUser());
if ($person instanceof Person) {
$entity->setPerson($person);
}
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$entity->setAccompanyingPeriod($accompanyingPeriod);
}
$entity->setType($activityType);
$entity->setDate(new \DateTime('now'));
if ($request->query->has('activityData')) {
$activityData = $request->query->get('activityData');
if (array_key_exists('durationTime', $activityData)) {
$durationTimeInMinutes = $activityData['durationTime'];
$hours = floor($durationTimeInMinutes / 60);
$minutes = $durationTimeInMinutes % 60;
$duration = \DateTime::createFromFormat("H:i", $hours.':'.$minutes);
if ($duration) {
$entity->setDurationTime($duration);
}
}
if (array_key_exists('date', $activityData)) {
$date = \DateTime::createFromFormat('Y-m-d', $activityData['date']);
if ($date) {
$entity->setDate($date);
}
}
if (array_key_exists('personsId', $activityData)) {
foreach($activityData['personsId'] as $personId){
$concernedPerson = $this->personRepository->find($personId);
$entity->addPerson($concernedPerson);
}
}
if (array_key_exists('professionalsId', $activityData)) {
foreach($activityData['professionalsId'] as $professionalsId){
$professional = $this->thirdPartyRepository->find($professionalsId);
$entity->addThirdParty($professional);
}
}
if (array_key_exists('location', $activityData)) {
$location = $this->locationRepository->find($activityData['location']);
$entity->setLocation($location);
}
if (array_key_exists('comment', $activityData)) {
$comment = new CommentEmbeddable();
$comment->setComment($activityData['comment']);
$comment->setUserId($this->getUser()->getid());
$comment->setDate(new \DateTime('now'));
$entity->setComment($comment);
}
}
$this->denyAccessUnlessGranted(ActivityVoter::CREATE, $entity);
$form = $this->createForm(ActivityType::class, $entity, [
'center' => $entity->getCenter(),
'role' => new Role('CHILL_ACTIVITY_CREATE'),
'activityType' => $entity->getType(),
'accompanyingPeriod' => $accompanyingPeriod,
])->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->entityManager->persist($entity);
$this->entityManager->flush();
$this->addFlash('success', $this->get('translator')->trans('Success : activity created!'));
$params = $this->buildParamsToUrl($person, $accompanyingPeriod);
$params['id'] = $entity->getId();
return $this->redirectToRoute('chill_activity_activity_show', $params);
}
if ($view === null) {
throw $this->createNotFoundException('Template not found');
}
$activity_array = $this->serializer->normalize($entity, 'json', ['groups' => 'read']);
$defaultLocationId = $this->getUser()->getCurrentLocation()->getId();
return $this->render($view, [
'person' => $person,
'accompanyingCourse' => $accompanyingPeriod,
'entity' => $entity,
'form' => $form->createView(),
'activity_json' => $activity_array,
'default_location_id' => $defaultLocationId
]);
}
public function showAction(Request $request, int $id): Response public function showAction(Request $request, int $id): Response
{ {
$view = null; $view = null;
@@ -329,8 +484,8 @@ final class ActivityController extends AbstractController
if (null !== $accompanyingPeriod) { if (null !== $accompanyingPeriod) {
// @TODO: Properties created dynamically. // @TODO: Properties created dynamically.
$entity->personsAssociated = $entity->getPersonsAssociated(); $entity->personsAssociated = $entity->getPersonsAssociated();
$entity->personsNotAssociated = $entity->getPersonsNotAssociated(); $entity->personsNotAssociated = $entity->getPersonsNotAssociated();
} }
// TODO revoir le Voter de Activity pour tenir compte qu'une activité peut appartenir a une période // TODO revoir le Voter de Activity pour tenir compte qu'une activité peut appartenir a une période
@@ -346,160 +501,33 @@ final class ActivityController extends AbstractController
'action' => 'show' 'action' => 'show'
)); ));
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event); $this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
*/ */
if ($view === null) { if (null === $view) {
throw $this->createNotFoundException('Template not found'); throw $this->createNotFoundException('Template not found');
} }
return $this->render($view, [ return $this->render($view, [
'person' => $person,
'accompanyingCourse' => $accompanyingPeriod,
'entity' => $entity,
'delete_form' => $deleteForm->createView(),
]);
}
/**
* Displays a form to edit an existing Activity entity.
*/
public function editAction(int $id, Request $request): Response
{
$view = null;
[$person, $accompanyingPeriod] = $this->getEntity($request);
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$view = 'ChillActivityBundle:Activity:editAccompanyingCourse.html.twig';
} elseif ($person instanceof Person) {
$view = 'ChillActivityBundle:Activity:editPerson.html.twig';
}
$entity = $this->activityRepository->find($id);
if (null === $entity) {
throw $this->createNotFoundException('Unable to find Activity entity.');
}
// TODO
// $this->denyAccessUnlessGranted('CHILL_ACTIVITY_UPDATE', $entity);
$form = $this->createForm(ActivityType::class, $entity, [
'center' => $entity->getCenter(),
'role' => new Role('CHILL_ACTIVITY_UPDATE'),
'activityType' => $entity->getType(),
'accompanyingPeriod' => $accompanyingPeriod,
])->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->entityManager->persist($entity);
$this->entityManager->flush();
$this->addFlash('success', $this->get('translator')->trans('Success : activity updated!'));
$params = $this->buildParamsToUrl($person, $accompanyingPeriod);
$params['id'] = $entity->getId();
return $this->redirectToRoute('chill_activity_activity_show', $params);
}
$deleteForm = $this->createDeleteForm($entity->getId(), $person, $accompanyingPeriod);
/*
* TODO
$event = new PrivacyEvent($person, array(
'element_class' => Activity::class,
'element_id' => $entity->getId(),
'action' => 'edit'
));
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
*/
if ($view === null) {
throw $this->createNotFoundException('Template not found');
}
$activity_array = $this->serializer->normalize($entity, 'json', ['groups' => 'read']);
return $this->render($view, [
'entity' => $entity,
'edit_form' => $form->createView(),
'delete_form' => $deleteForm->createView(),
'person' => $person, 'person' => $person,
'accompanyingCourse' => $accompanyingPeriod, 'accompanyingCourse' => $accompanyingPeriod,
'activity_json' => $activity_array 'entity' => $entity,
'delete_form' => $deleteForm->createView(),
]); ]);
} }
/** private function buildParamsToUrl(?Person $person, ?AccompanyingPeriod $accompanyingPeriod): array
* Deletes a Activity entity.
*/
public function deleteAction(Request $request, $id)
{ {
$view = null; $params = [];
[$person, $accompanyingPeriod] = $this->getEntity($request); if (null !== $person) {
$params['person_id'] = $person->getId();
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$view = 'ChillActivityBundle:Activity:confirm_deleteAccompanyingCourse.html.twig';
} elseif ($person instanceof Person) {
$view = 'ChillActivityBundle:Activity:confirm_deletePerson.html.twig';
} }
$activity = $this->activityRepository->find($id); if (null !== $accompanyingPeriod) {
$params['accompanying_period_id'] = $accompanyingPeriod->getId();
if (!$activity) {
throw $this->createNotFoundException('Unable to find Activity entity.');
} }
// TODO return $params;
// $this->denyAccessUnlessGranted('CHILL_ACTIVITY_DELETE', $activity);
$form = $this->createDeleteForm($activity->getId(), $person, $accompanyingPeriod);
if ($request->getMethod() === Request::METHOD_DELETE) {
$form->handleRequest($request);
if ($form->isValid()) {
$this->logger->notice("An activity has been removed", [
'by_user' => $this->getUser()->getUsername(),
'activity_id' => $activity->getId(),
'person_id' => $activity->getPerson() ? $activity->getPerson()->getId() : null,
'comment' => $activity->getComment()->getComment(),
'scope_id' => $activity->getScope() ? $activity->getScope()->getId() : null,
'reasons_ids' => $activity->getReasons()
->map(
static fn (ActivityReason $ar): int => $ar->getId()
)
->toArray(),
'type_id' => $activity->getType()->getId(),
'duration' => $activity->getDurationTime() ? $activity->getDurationTime()->format('U') : null,
'date' => $activity->getDate()->format('Y-m-d'),
'attendee' => $activity->getAttendee()
]);
$this->entityManager->remove($activity);
$this->entityManager->flush();
$this->addFlash('success', $this->get('translator')
->trans("The activity has been successfully removed."));
$params = $this->buildParamsToUrl($person, $accompanyingPeriod);
return $this->redirectToRoute('chill_activity_activity_list', $params);
}
}
if ($view === null) {
throw $this->createNotFoundException('Template not found');
}
return $this->render($view, [
'activity' => $activity,
'delete_form' => $form->createView(),
'person' => $person,
'accompanyingCourse' => $accompanyingPeriod,
]);
} }
/** /**
@@ -519,13 +547,13 @@ final class ActivityController extends AbstractController
private function getEntity(Request $request): array private function getEntity(Request $request): array
{ {
$person = $accompanyingPeriod = null; $person = $accompanyingPeriod = null;
if ($request->query->has('person_id')) { if ($request->query->has('person_id')) {
$person_id = $request->get('person_id'); $person_id = $request->get('person_id');
$person = $this->personRepository->find($person_id); $person = $this->personRepository->find($person_id);
if ($person === null) { if (null === $person) {
throw $this->createNotFoundException('Person not found'); throw $this->createNotFoundException('Person not found');
} }
@@ -534,34 +562,19 @@ final class ActivityController extends AbstractController
$accompanying_period_id = $request->get('accompanying_period_id'); $accompanying_period_id = $request->get('accompanying_period_id');
$accompanyingPeriod = $this->accompanyingPeriodRepository->find($accompanying_period_id); $accompanyingPeriod = $this->accompanyingPeriodRepository->find($accompanying_period_id);
if ($accompanyingPeriod === null) { if (null === $accompanyingPeriod) {
throw $this->createNotFoundException('Accompanying Period not found'); throw $this->createNotFoundException('Accompanying Period not found');
} }
// TODO Add permission // TODO Add permission
// $this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person); // $this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person);
} else { } else {
throw $this->createNotFoundException("Person or Accompanying Period not found"); throw $this->createNotFoundException('Person or Accompanying Period not found');
} }
return [ return [
$person, $person,
$accompanyingPeriod $accompanyingPeriod,
]; ];
} }
private function buildParamsToUrl(?Person $person, ?AccompanyingPeriod $accompanyingPeriod): array
{
$params = [];
if (null !== $person) {
$params['person_id'] = $person->getId();
}
if (null !== $accompanyingPeriod) {
$params['accompanying_period_id'] = $accompanyingPeriod->getId();
}
return $params;
}
} }

View File

@@ -1,38 +1,28 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Controller; namespace Chill\ActivityBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Chill\ActivityBundle\Entity\ActivityReasonCategory; use Chill\ActivityBundle\Entity\ActivityReasonCategory;
use Chill\ActivityBundle\Form\ActivityReasonCategoryType; use Chill\ActivityBundle\Form\ActivityReasonCategoryType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request;
/** /**
* ActivityReasonCategory controller. * ActivityReasonCategory controller.
*
*/ */
class ActivityReasonCategoryController extends AbstractController class ActivityReasonCategoryController extends AbstractController
{ {
/**
* Lists all ActivityReasonCategory entities.
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('ChillActivityBundle:ActivityReasonCategory')->findAll();
return $this->render('ChillActivityBundle:ActivityReasonCategory:index.html.twig', array(
'entities' => $entities,
));
}
/** /**
* Creates a new ActivityReasonCategory entity. * Creates a new ActivityReasonCategory entity.
*
*/ */
public function createAction(Request $request) public function createAction(Request $request)
{ {
@@ -45,71 +35,19 @@ class ActivityReasonCategoryController extends AbstractController
$em->persist($entity); $em->persist($entity);
$em->flush(); $em->flush();
return $this->redirect($this->generateUrl('chill_activity_activityreasoncategory_show', array('id' => $entity->getId()))); return $this->redirect($this->generateUrl('chill_activity_activityreasoncategory_show', ['id' => $entity->getId()]));
} }
return $this->render('ChillActivityBundle:ActivityReasonCategory:new.html.twig', array( return $this->render('ChillActivityBundle:ActivityReasonCategory:new.html.twig', [
'entity' => $entity, 'entity' => $entity,
'form' => $form->createView(), 'form' => $form->createView(),
)); ]);
}
/**
* Creates a form to create a ActivityReasonCategory entity.
*
* @param ActivityReasonCategory $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(ActivityReasonCategory $entity)
{
$form = $this->createForm(ActivityReasonCategoryType::class, $entity, array(
'action' => $this->generateUrl('chill_activity_activityreasoncategory_create'),
'method' => 'POST',
));
$form->add('submit', SubmitType::class, array('label' => 'Create'));
return $form;
}
/**
* Displays a form to create a new ActivityReasonCategory entity.
*
*/
public function newAction()
{
$entity = new ActivityReasonCategory();
$form = $this->createCreateForm($entity);
return $this->render('ChillActivityBundle:ActivityReasonCategory:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Finds and displays a ActivityReasonCategory entity.
*
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ChillActivityBundle:ActivityReasonCategory')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find ActivityReasonCategory entity.');
}
return $this->render('ChillActivityBundle:ActivityReasonCategory:show.html.twig', array(
'entity' => $entity,
));
} }
/** /**
* Displays a form to edit an existing ActivityReasonCategory entity. * Displays a form to edit an existing ActivityReasonCategory entity.
* *
* @param mixed $id
*/ */
public function editAction($id) public function editAction($id)
{ {
@@ -123,33 +61,64 @@ class ActivityReasonCategoryController extends AbstractController
$editForm = $this->createEditForm($entity); $editForm = $this->createEditForm($entity);
return $this->render('ChillActivityBundle:ActivityReasonCategory:edit.html.twig', array( return $this->render('ChillActivityBundle:ActivityReasonCategory:edit.html.twig', [
'entity' => $entity, 'entity' => $entity,
'edit_form' => $editForm->createView(), 'edit_form' => $editForm->createView(),
)); ]);
} }
/** /**
* Creates a form to edit a ActivityReasonCategory entity. * Lists all ActivityReasonCategory entities.
* */
* @param ActivityReasonCategory $entity The entity public function indexAction()
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(ActivityReasonCategory $entity)
{ {
$form = $this->createForm(ActivityReasonCategoryType::class, $entity, array( $em = $this->getDoctrine()->getManager();
'action' => $this->generateUrl('chill_activity_activityreasoncategory_update', array('id' => $entity->getId())),
'method' => 'PUT',
));
$form->add('submit', SubmitType::class, array('label' => 'Update')); $entities = $em->getRepository('ChillActivityBundle:ActivityReasonCategory')->findAll();
return $form; return $this->render('ChillActivityBundle:ActivityReasonCategory:index.html.twig', [
'entities' => $entities,
]);
} }
/**
* Displays a form to create a new ActivityReasonCategory entity.
*/
public function newAction()
{
$entity = new ActivityReasonCategory();
$form = $this->createCreateForm($entity);
return $this->render('ChillActivityBundle:ActivityReasonCategory:new.html.twig', [
'entity' => $entity,
'form' => $form->createView(),
]);
}
/**
* Finds and displays a ActivityReasonCategory entity.
*
* @param mixed $id
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ChillActivityBundle:ActivityReasonCategory')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find ActivityReasonCategory entity.');
}
return $this->render('ChillActivityBundle:ActivityReasonCategory:show.html.twig', [
'entity' => $entity,
]);
}
/** /**
* Edits an existing ActivityReasonCategory entity. * Edits an existing ActivityReasonCategory entity.
* *
* @param mixed $id
*/ */
public function updateAction(Request $request, $id) public function updateAction(Request $request, $id)
{ {
@@ -167,12 +136,50 @@ class ActivityReasonCategoryController extends AbstractController
if ($editForm->isValid()) { if ($editForm->isValid()) {
$em->flush(); $em->flush();
return $this->redirect($this->generateUrl('chill_activity_activityreasoncategory_edit', array('id' => $id))); return $this->redirect($this->generateUrl('chill_activity_activityreasoncategory_edit', ['id' => $id]));
} }
return $this->render('ChillActivityBundle:ActivityReasonCategory:edit.html.twig', array( return $this->render('ChillActivityBundle:ActivityReasonCategory:edit.html.twig', [
'entity' => $entity, 'entity' => $entity,
'edit_form' => $editForm->createView(), 'edit_form' => $editForm->createView(),
)); ]);
}
/**
* Creates a form to create a ActivityReasonCategory entity.
*
* @param ActivityReasonCategory $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(ActivityReasonCategory $entity)
{
$form = $this->createForm(ActivityReasonCategoryType::class, $entity, [
'action' => $this->generateUrl('chill_activity_activityreasoncategory_create'),
'method' => 'POST',
]);
$form->add('submit', SubmitType::class, ['label' => 'Create']);
return $form;
}
/**
* Creates a form to edit a ActivityReasonCategory entity.
*
* @param ActivityReasonCategory $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(ActivityReasonCategory $entity)
{
$form = $this->createForm(ActivityReasonCategoryType::class, $entity, [
'action' => $this->generateUrl('chill_activity_activityreasoncategory_update', ['id' => $entity->getId()]),
'method' => 'PUT',
]);
$form->add('submit', SubmitType::class, ['label' => 'Update']);
return $form;
} }
} }

View File

@@ -1,38 +1,28 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Controller; namespace Chill\ActivityBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Chill\ActivityBundle\Entity\ActivityReason; use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\ActivityBundle\Form\ActivityReasonType; use Chill\ActivityBundle\Form\ActivityReasonType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request;
/** /**
* ActivityReason controller. * ActivityReason controller.
*
*/ */
class ActivityReasonController extends AbstractController class ActivityReasonController extends AbstractController
{ {
/**
* Lists all ActivityReason entities.
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('ChillActivityBundle:ActivityReason')->findAll();
return $this->render('ChillActivityBundle:ActivityReason:index.html.twig', array(
'entities' => $entities,
));
}
/** /**
* Creates a new ActivityReason entity. * Creates a new ActivityReason entity.
*
*/ */
public function createAction(Request $request) public function createAction(Request $request)
{ {
@@ -45,71 +35,19 @@ class ActivityReasonController extends AbstractController
$em->persist($entity); $em->persist($entity);
$em->flush(); $em->flush();
return $this->redirect($this->generateUrl('chill_activity_activityreason', array('id' => $entity->getId()))); return $this->redirect($this->generateUrl('chill_activity_activityreason', ['id' => $entity->getId()]));
} }
return $this->render('ChillActivityBundle:ActivityReason:new.html.twig', array( return $this->render('ChillActivityBundle:ActivityReason:new.html.twig', [
'entity' => $entity, 'entity' => $entity,
'form' => $form->createView(), 'form' => $form->createView(),
)); ]);
}
/**
* Creates a form to create a ActivityReason entity.
*
* @param ActivityReason $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(ActivityReason $entity)
{
$form = $this->createForm(ActivityReasonType::class, $entity, array(
'action' => $this->generateUrl('chill_activity_activityreason_create'),
'method' => 'POST',
));
$form->add('submit', SubmitType::class, array('label' => 'Create'));
return $form;
}
/**
* Displays a form to create a new ActivityReason entity.
*
*/
public function newAction()
{
$entity = new ActivityReason();
$form = $this->createCreateForm($entity);
return $this->render('ChillActivityBundle:ActivityReason:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Finds and displays a ActivityReason entity.
*
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ChillActivityBundle:ActivityReason')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find ActivityReason entity.');
}
return $this->render('ChillActivityBundle:ActivityReason:show.html.twig', array(
'entity' => $entity,
));
} }
/** /**
* Displays a form to edit an existing ActivityReason entity. * Displays a form to edit an existing ActivityReason entity.
* *
* @param mixed $id
*/ */
public function editAction($id) public function editAction($id)
{ {
@@ -123,33 +61,64 @@ class ActivityReasonController extends AbstractController
$editForm = $this->createEditForm($entity); $editForm = $this->createEditForm($entity);
return $this->render('ChillActivityBundle:ActivityReason:edit.html.twig', array( return $this->render('ChillActivityBundle:ActivityReason:edit.html.twig', [
'entity' => $entity, 'entity' => $entity,
'edit_form' => $editForm->createView() 'edit_form' => $editForm->createView(),
)); ]);
} }
/** /**
* Creates a form to edit a ActivityReason entity. * Lists all ActivityReason entities.
* */
* @param ActivityReason $entity The entity public function indexAction()
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(ActivityReason $entity)
{ {
$form = $this->createForm(ActivityReasonType::class, $entity, array( $em = $this->getDoctrine()->getManager();
'action' => $this->generateUrl('chill_activity_activityreason_update', array('id' => $entity->getId())),
'method' => 'PUT',
));
$form->add('submit', SubmitType::class, array('label' => 'Update')); $entities = $em->getRepository('ChillActivityBundle:ActivityReason')->findAll();
return $form; return $this->render('ChillActivityBundle:ActivityReason:index.html.twig', [
'entities' => $entities,
]);
} }
/**
* Displays a form to create a new ActivityReason entity.
*/
public function newAction()
{
$entity = new ActivityReason();
$form = $this->createCreateForm($entity);
return $this->render('ChillActivityBundle:ActivityReason:new.html.twig', [
'entity' => $entity,
'form' => $form->createView(),
]);
}
/**
* Finds and displays a ActivityReason entity.
*
* @param mixed $id
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ChillActivityBundle:ActivityReason')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find ActivityReason entity.');
}
return $this->render('ChillActivityBundle:ActivityReason:show.html.twig', [
'entity' => $entity,
]);
}
/** /**
* Edits an existing ActivityReason entity. * Edits an existing ActivityReason entity.
* *
* @param mixed $id
*/ */
public function updateAction(Request $request, $id) public function updateAction(Request $request, $id)
{ {
@@ -167,12 +136,50 @@ class ActivityReasonController extends AbstractController
if ($editForm->isValid()) { if ($editForm->isValid()) {
$em->flush(); $em->flush();
return $this->redirect($this->generateUrl('chill_activity_activityreason', array('id' => $id))); return $this->redirect($this->generateUrl('chill_activity_activityreason', ['id' => $id]));
} }
return $this->render('ChillActivityBundle:ActivityReason:edit.html.twig', array( return $this->render('ChillActivityBundle:ActivityReason:edit.html.twig', [
'entity' => $entity, 'entity' => $entity,
'edit_form' => $editForm->createView() 'edit_form' => $editForm->createView(),
)); ]);
}
/**
* Creates a form to create a ActivityReason entity.
*
* @param ActivityReason $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(ActivityReason $entity)
{
$form = $this->createForm(ActivityReasonType::class, $entity, [
'action' => $this->generateUrl('chill_activity_activityreason_create'),
'method' => 'POST',
]);
$form->add('submit', SubmitType::class, ['label' => 'Create']);
return $form;
}
/**
* Creates a form to edit a ActivityReason entity.
*
* @param ActivityReason $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(ActivityReason $entity)
{
$form = $this->createForm(ActivityReasonType::class, $entity, [
'action' => $this->generateUrl('chill_activity_activityreason_update', ['id' => $entity->getId()]),
'method' => 'PUT',
]);
$form->add('submit', SubmitType::class, ['label' => 'Update']);
return $form;
} }
} }

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Controller; namespace Chill\ActivityBundle\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController; use Chill\MainBundle\CRUD\Controller\CRUDController;
@@ -9,10 +16,8 @@ use Symfony\Component\HttpFoundation\Request;
class AdminActivityPresenceController extends CRUDController class AdminActivityPresenceController extends CRUDController
{ {
/** /**
* @param string $action
* @param \Doctrine\ORM\QueryBuilder|mixed $query * @param \Doctrine\ORM\QueryBuilder|mixed $query
* @param Request $request *
* @param PaginatorInterface $paginator
* @return \Doctrine\ORM\QueryBuilder|mixed * @return \Doctrine\ORM\QueryBuilder|mixed
*/ */
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator)

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Controller; namespace Chill\ActivityBundle\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController; use Chill\MainBundle\CRUD\Controller\CRUDController;
@@ -9,10 +16,8 @@ use Symfony\Component\HttpFoundation\Request;
class AdminActivityTypeCategoryController extends CRUDController class AdminActivityTypeCategoryController extends CRUDController
{ {
/** /**
* @param string $action
* @param \Doctrine\ORM\QueryBuilder|mixed $query * @param \Doctrine\ORM\QueryBuilder|mixed $query
* @param Request $request *
* @param PaginatorInterface $paginator
* @return \Doctrine\ORM\QueryBuilder|mixed * @return \Doctrine\ORM\QueryBuilder|mixed
*/ */
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator)

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Controller; namespace Chill\ActivityBundle\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController; use Chill\MainBundle\CRUD\Controller\CRUDController;
@@ -9,10 +16,8 @@ use Symfony\Component\HttpFoundation\Request;
class AdminActivityTypeController extends CRUDController class AdminActivityTypeController extends CRUDController
{ {
/** /**
* @param string $action
* @param \Doctrine\ORM\QueryBuilder|mixed $query * @param \Doctrine\ORM\QueryBuilder|mixed $query
* @param Request $request *
* @param PaginatorInterface $paginator
* @return \Doctrine\ORM\QueryBuilder|mixed * @return \Doctrine\ORM\QueryBuilder|mixed
*/ */
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator)

View File

@@ -1,33 +1,18 @@
<?php <?php
/* /**
* Chill is a software for social workers * Chill is a software for social workers
* Copyright (C) 2015 Champs Libres <info@champs-libres.coop>
* *
* This program is free software: you can redistribute it and/or modify * For the full copyright and license information, please view
* it under the terms of the GNU Affero General Public License as published by * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\Controller; namespace Chill\ActivityBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
/** /**
* Controller for activity configuration * Controller for activity configuration.
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @author Champs Libres <info@champs-libres.coop>
*/ */
class AdminController extends AbstractController class AdminController extends AbstractController
{ {
@@ -35,7 +20,7 @@ class AdminController extends AbstractController
{ {
return $this->render('ChillActivityBundle:Admin:layout_activity.html.twig'); return $this->render('ChillActivityBundle:Admin:layout_activity.html.twig');
} }
public function redirectToAdminIndexAction() public function redirectToAdminIndexAction()
{ {
return $this->redirectToRoute('chill_main_admin_central'); return $this->redirectToRoute('chill_main_admin_central');

View File

@@ -1,48 +1,34 @@
<?php <?php
/* /**
* Chill is a software for social workers * Chill is a software for social workers
* *
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, * For the full copyright and license information, please view
* <http://www.champs-libres.coop>, <info@champs-libres.coop> * the LICENSE file that was distributed with this source code.
*
* 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\ActivityBundle\DataFixtures\ORM; namespace Chill\ActivityBundle\DataFixtures\ORM;
use Chill\ActivityBundle\Entity\Activity;
use Chill\MainBundle\DataFixtures\ORM\LoadScopes;
use Chill\MainBundle\DataFixtures\ORM\LoadUsers;
use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\Person;
use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface; use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ObjectManager; use Doctrine\Persistence\ObjectManager;
use Faker\Factory as FakerFactory; use Faker\Factory as FakerFactory;
use Chill\ActivityBundle\Entity\Activity;
use Chill\MainBundle\DataFixtures\ORM\LoadUsers;
use Chill\ActivityBundle\DataFixtures\ORM\LoadActivityReason;
use Chill\ActivityBundle\DataFixtures\ORM\LoadActivityType;
use Chill\MainBundle\DataFixtures\ORM\LoadScopes;
class LoadActivity extends AbstractFixture implements OrderedFixtureInterface class LoadActivity extends AbstractFixture implements OrderedFixtureInterface
{ {
use \Symfony\Component\DependencyInjection\ContainerAwareTrait; use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
private EntityManagerInterface $em;
/** /**
* @var \Faker\Generator * @var \Faker\Generator
*/ */
private $faker; private $faker;
private EntityManagerInterface $em;
public function __construct(EntityManagerInterface $em) public function __construct(EntityManagerInterface $em)
{ {
@@ -55,30 +41,53 @@ class LoadActivity extends AbstractFixture implements OrderedFixtureInterface
return 16400; return 16400;
} }
/** public function load(ObjectManager $manager)
* Return a random scope
*
* @return \Chill\MainBundle\Entity\Scope
*/
private function getRandomScope()
{ {
$scopeRef = LoadScopes::$references[array_rand(LoadScopes::$references)]; $persons = $this->em
return $this->getReference($scopeRef); ->getRepository(Person::class)
->findAll();
foreach ($persons as $person) {
$activityNbr = rand(0, 3);
for ($i = 0; $i < $activityNbr; ++$i ) {
$activity = $this->newRandomActivity($person);
if (null !== $activity) {
$manager->persist($activity);
}
}
}
$manager->flush();
}
public function newRandomActivity($person): ?Activity
{
$activity = (new Activity())
->setUser($this->getRandomUser())
->setPerson($person)
->setDate($this->faker->dateTimeThisYear())
->setDurationTime($this->faker->dateTime(36000))
->setType($this->getRandomActivityType())
->setScope($this->getRandomScope());
// ->setAttendee($this->faker->boolean())
for ($i = 0; rand(0, 4) > $i; ++$i) {
$reason = $this->getRandomActivityReason();
if (null !== $reason) {
$activity->addReason($reason);
} else {
return null;
}
}
return $activity;
} }
/** /**
* Return a random activityType * Return a random activityReason.
*
* @return \Chill\ActivityBundle\Entity\ActivityType
*/
private function getRandomActivityType()
{
$typeRef = LoadActivityType::$references[array_rand(LoadActivityType::$references)];
return $this->getReference($typeRef);
}
/**
* Return a random activityReason
* *
* @return \Chill\ActivityBundle\Entity\ActivityReason * @return \Chill\ActivityBundle\Entity\ActivityReason
*/ */
@@ -90,57 +99,38 @@ class LoadActivity extends AbstractFixture implements OrderedFixtureInterface
} }
/** /**
* Return a random user * Return a random activityType.
*
* @return \Chill\ActivityBundle\Entity\ActivityType
*/
private function getRandomActivityType()
{
$typeRef = LoadActivityType::$references[array_rand(LoadActivityType::$references)];
return $this->getReference($typeRef);
}
/**
* Return a random scope.
*
* @return \Chill\MainBundle\Entity\Scope
*/
private function getRandomScope()
{
$scopeRef = LoadScopes::$references[array_rand(LoadScopes::$references)];
return $this->getReference($scopeRef);
}
/**
* Return a random user.
* *
* @return \Chill\MainBundle\Entity\User * @return \Chill\MainBundle\Entity\User
*/ */
private function getRandomUser() private function getRandomUser()
{ {
$userRef = array_rand(LoadUsers::$refs); $userRef = array_rand(LoadUsers::$refs);
return $this->getReference($userRef); return $this->getReference($userRef);
} }
public function newRandomActivity($person): ?Activity
{
$activity = (new Activity())
->setUser($this->getRandomUser())
->setPerson($person)
->setDate($this->faker->dateTimeThisYear())
->setDurationTime($this->faker->dateTime(36000))
->setType($this->getRandomActivityType())
->setScope($this->getRandomScope())
;
// ->setAttendee($this->faker->boolean())
for ($i = 0; $i < rand(0, 4); $i++) {
$reason = $this->getRandomActivityReason();
if (null !== $reason) {
$activity->addReason($reason);
} else {
return null;
}
}
return $activity;
}
public function load(ObjectManager $manager)
{
$persons = $this->em
->getRepository(Person::class)
->findAll();
foreach ($persons as $person) {
$activityNbr = rand(0,3);
for ($i = 0; $i < $activityNbr; $i ++) {
$activity = $this->newRandomActivity($person);
if (null !== $activity) {
$manager->persist($activity);
}
}
}
$manager->flush();
}
} }

View File

@@ -1,15 +1,21 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\DataFixtures\ORM; namespace Chill\ActivityBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\Activity;
use Chill\MainBundle\DataFixtures\ORM\LoadAbstractNotificationsTrait; use Chill\MainBundle\DataFixtures\ORM\LoadAbstractNotificationsTrait;
use Chill\ActivityBundle\DataFixtures\ORM\LoadActivity; use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
/** /**
* Load notififications into database * Load notififications into database.
*/ */
class LoadActivityNotifications extends AbstractFixture implements DependentFixtureInterface class LoadActivityNotifications extends AbstractFixture implements DependentFixtureInterface
{ {
@@ -25,9 +31,9 @@ class LoadActivityNotifications extends AbstractFixture implements DependentFixt
'center a_social', 'center a_social',
'center a_administrative', 'center a_administrative',
'center a_direction', 'center a_direction',
'multi_center' 'multi_center',
], ],
] ],
]; ];
public function getDependencies() public function getDependencies()

View File

@@ -1,81 +1,66 @@
<?php <?php
/* /**
* Chill is a software for social workers * Chill is a software for social workers
* *
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, * For the full copyright and license information, please view
* <http://www.champs-libres.coop>, <info@champs-libres.coop> * the LICENSE file that was distributed with this source code.
*
* 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\ActivityBundle\DataFixtures\ORM; namespace Chill\ActivityBundle\DataFixtures\ORM;
use Chill\ActivityBundle\Entity\ActivityReason;
use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface; use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager; use Doctrine\Persistence\ObjectManager;
use Chill\ActivityBundle\Entity\ActivityReason;
/** /**
* Description of LoadActivityReason * Description of LoadActivityReason.
*
* @author Champs-Libres Coop
*/ */
class LoadActivityReason extends AbstractFixture implements OrderedFixtureInterface class LoadActivityReason extends AbstractFixture implements OrderedFixtureInterface
{ {
public static $references = [];
public function getOrder() public function getOrder()
{ {
return 16300; return 16300;
} }
public static $references = array();
public function load(ObjectManager $manager) public function load(ObjectManager $manager)
{ {
$reasons = [ $reasons = [
[ [
'name' => ['fr' => 'Recherche logement', 'en' => 'Housing research', 'nl' => 'Woning zoektoch'], 'name' => ['fr' => 'Recherche logement', 'en' => 'Housing research', 'nl' => 'Woning zoektoch'],
'category' => 'cat_Housing'], 'category' => 'cat_Housing', ],
[ [
'name' => ['fr' => 'Problème avec propriétaire', 'en' => 'Landlord problems', 'nl' => 'Huisbaas problemen'], 'name' => ['fr' => 'Problème avec propriétaire', 'en' => 'Landlord problems', 'nl' => 'Huisbaas problemen'],
'category' => 'cat_Housing'], 'category' => 'cat_Housing', ],
[ [
'name' => ['fr' => 'Retard de payement', 'en' => 'Payement problems', 'nl' => 'Betalings vertragingen'], 'name' => ['fr' => 'Retard de payement', 'en' => 'Payement problems', 'nl' => 'Betalings vertragingen'],
'category' => 'cat_Housing'], 'category' => 'cat_Housing', ],
[ [
'name' => ['fr' => 'Explication législation', 'en' => 'Legislation explanation', 'nl' => 'Legislative uitleg'], 'name' => ['fr' => 'Explication législation', 'en' => 'Legislation explanation', 'nl' => 'Legislative uitleg'],
'category' => 'cat_Unemployment procedure'], 'category' => 'cat_Unemployment procedure', ],
[ [
'name' => ['fr' => 'Coaching entretien d\'activation', 'en' => 'Interview coaching', 'nl' => 'Interview coaching'], 'name' => ['fr' => 'Coaching entretien d\'activation', 'en' => 'Interview coaching', 'nl' => 'Interview coaching'],
'category' => 'cat_Unemployment procedure'], 'category' => 'cat_Unemployment procedure', ],
[ [
'name' => ['fr' => 'Récupération des allocations', 'en' => 'Allowance recovery', 'nl' => 'Terugwinning van de uitkeringen'], 'name' => ['fr' => 'Récupération des allocations', 'en' => 'Allowance recovery', 'nl' => 'Terugwinning van de uitkeringen'],
'category' => 'cat_Unemployment procedure'] 'category' => 'cat_Unemployment procedure', ],
]; ];
foreach ($reasons as $r) { foreach ($reasons as $r) {
print "Creating activity reason : " . $r['name']['en'] . "\n"; echo 'Creating activity reason : ' . $r['name']['en'] . "\n";
$activityReason = (new ActivityReason()) $activityReason = (new ActivityReason())
->setName(($r['name'])) ->setName(($r['name']))
->setActive(true) ->setActive(true)
->setCategory($this->getReference($r['category'])); ->setCategory($this->getReference($r['category']));
$manager->persist($activityReason); $manager->persist($activityReason);
$reference = 'activity_reason_'.$r['name']['en']; $reference = 'activity_reason_' . $r['name']['en'];
$this->addReference($reference, $activityReason); $this->addReference($reference, $activityReason);
static::$references[] = $reference; static::$references[] = $reference;
} }
$manager->flush(); $manager->flush();
} }
} }

View File

@@ -1,35 +1,21 @@
<?php <?php
/* /**
* Chill is a software for social workers * Chill is a software for social workers
* *
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, * For the full copyright and license information, please view
* <http://www.champs-libres.coop>, <info@champs-libres.coop> * the LICENSE file that was distributed with this source code.
*
* 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\ActivityBundle\DataFixtures\ORM; namespace Chill\ActivityBundle\DataFixtures\ORM;
use Chill\ActivityBundle\Entity\ActivityReasonCategory;
use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface; use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager; use Doctrine\Persistence\ObjectManager;
use Chill\ActivityBundle\Entity\ActivityReasonCategory;
/** /**
* Description of LoadActivityReasonCategory * Description of LoadActivityReasonCategory.
*
* @author Champs-Libres Coop
*/ */
class LoadActivityReasonCategory extends AbstractFixture implements OrderedFixtureInterface class LoadActivityReasonCategory extends AbstractFixture implements OrderedFixtureInterface
{ {
@@ -37,27 +23,26 @@ class LoadActivityReasonCategory extends AbstractFixture implements OrderedFixtu
{ {
return 16200; return 16200;
} }
public function load(ObjectManager $manager) public function load(ObjectManager $manager)
{ {
$categs = [ $categs = [
['name' => ['name' => ['fr' => 'Logement', 'en' => 'Housing', 'nl' => 'Woning']],
['fr' => 'Logement', 'en' => 'Housing', 'nl' => 'Woning']], ['name' => ['fr' => 'Démarches chômage', 'en' => 'Unemployment procedure', 'nl' => 'Werkloosheid werkwijze']],
['name' =>
['fr' => 'Démarches chômage', 'en' => 'Unemployment procedure', 'nl' => 'Werkloosheid werkwijze']],
]; ];
foreach ($categs as $c) { foreach ($categs as $c) {
print "Creating activity reason category : " . $c['name']['en'] . "\n"; echo 'Creating activity reason category : ' . $c['name']['en'] . "\n";
$activityReasonCategory = (new ActivityReasonCategory()) $activityReasonCategory = (new ActivityReasonCategory())
->setName(($c['name'])) ->setName(($c['name']))
->setActive(true); ->setActive(true);
$manager->persist($activityReasonCategory); $manager->persist($activityReasonCategory);
$this->addReference( $this->addReference(
'cat_'.$c['name']['en'], 'cat_' . $c['name']['en'],
$activityReasonCategory); $activityReasonCategory
);
} }
$manager->flush(); $manager->flush();
} }
} }

View File

@@ -1,86 +1,65 @@
<?php <?php
/* /**
* Chill is a software for social workers * Chill is a software for social workers
* *
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, * For the full copyright and license information, please view
* <http://www.champs-libres.coop>, <info@champs-libres.coop> * the LICENSE file that was distributed with this source code.
*
* 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\ActivityBundle\DataFixtures\ORM; namespace Chill\ActivityBundle\DataFixtures\ORM;
use Chill\ActivityBundle\Entity\ActivityType;
use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface; use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager; use Doctrine\Persistence\ObjectManager;
use Chill\ActivityBundle\Entity\ActivityType;
/** /**
* Description of LoadActivityType * Description of LoadActivityType.
*
* @author Champs-Libres Coop
*/ */
class LoadActivityType extends Fixture implements OrderedFixtureInterface class LoadActivityType extends Fixture implements OrderedFixtureInterface
{ {
public static $references = [];
public function getOrder() public function getOrder()
{ {
return 16100; return 16100;
} }
public static $references = array();
public function load(ObjectManager $manager) public function load(ObjectManager $manager)
{ {
$types = [ $types = [
# Exange // Exange
[ [
'name' => 'name' => ['fr' => 'Entretien physique avec l\'usager'],
['fr' => 'Entretien physique avec l\'usager'], 'category' => 'exchange', ],
'category' => 'exchange' ],
[ [
'name' => 'name' => ['fr' => 'Appel téléphonique', 'en' => 'Telephone call', 'nl' => 'Telefoon appel'],
['fr' => 'Appel téléphonique', 'en' => 'Telephone call', 'nl' => 'Telefoon appel'], 'category' => 'exchange', ],
'category' => 'exchange' ],
[ [
'name' => 'name' => ['fr' => 'Courriel', 'en' => 'Email', 'nl' => 'Email'],
['fr' => 'Courriel', 'en' => 'Email', 'nl' => 'Email'], 'category' => 'exchange', ],
'category' => 'exchange' ], // Meeting
# Meeting
[ [
'name' => 'name' => ['fr' => 'Point technique encadrant'],
['fr' => 'Point technique encadrant'], 'category' => 'meeting', ],
'category' => 'meeting' ],
[ [
'name' => 'name' => ['fr' => 'Réunion avec des partenaires'],
['fr' => 'Réunion avec des partenaires'], 'category' => 'meeting', ],
'category' => 'meeting' ],
[ [
'name' => 'name' => ['fr' => 'Commission pluridisciplinaire et pluri-institutionnelle'],
['fr' => 'Commission pluridisciplinaire et pluri-institutionnelle'], 'category' => 'meeting', ],
'category' => 'meeting' ],
]; ];
foreach ($types as $t) { foreach ($types as $t) {
print "Creating activity type : " . $t['name']['fr'] . " (cat:". $t['category'] . " \n"; echo 'Creating activity type : ' . $t['name']['fr'] . ' (cat:' . $t['category'] . " \n";
$activityType = (new ActivityType()) $activityType = (new ActivityType())
->setName(($t['name'])) ->setName(($t['name']))
->setCategory($this->getReference('activity_type_cat_'.$t['category'])) ->setCategory($this->getReference('activity_type_cat_' . $t['category']))
->setSocialIssuesVisible(1) ->setSocialIssuesVisible(1)
->setSocialActionsVisible(1); ->setSocialActionsVisible(1);
$manager->persist($activityType); $manager->persist($activityType);
$reference = 'activity_type_'.$t['name']['fr']; $reference = 'activity_type_' . $t['name']['fr'];
$this->addReference($reference, $activityType); $this->addReference($reference, $activityType);
static::$references[] = $reference; static::$references[] = $reference;
} }

View File

@@ -1,40 +1,25 @@
<?php <?php
/* /**
* Chill is a software for social workers * Chill is a software for social workers
* *
* Copyright (C) 2014-2021, Champs Libres Cooperative SCRLFS, * For the full copyright and license information, please view
* <http://www.champs-libres.coop>, <info@champs-libres.coop> * the LICENSE file that was distributed with this source code.
*
* 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\ActivityBundle\DataFixtures\ORM; namespace Chill\ActivityBundle\DataFixtures\ORM;
use Chill\ActivityBundle\Entity\ActivityTypeCategory;
use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface; use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager; use Doctrine\Persistence\ObjectManager;
use Chill\ActivityBundle\Entity\ActivityTypeCategory;
/** /**
* Fixtures for ActivityTypeCategory * Fixtures for ActivityTypeCategory.
*
* @author Champs-Libres Coop
*/ */
class LoadActivityTypeCategory extends Fixture implements OrderedFixtureInterface class LoadActivityTypeCategory extends Fixture implements OrderedFixtureInterface
{ {
public static $references = array(); public static $references = [];
public function getOrder() public function getOrder()
{ {
@@ -55,13 +40,13 @@ class LoadActivityTypeCategory extends Fixture implements OrderedFixtureInterfac
]; ];
foreach ($categories as $cat) { foreach ($categories as $cat) {
print "Creating activity type category : " . $cat['ref'] . "\n"; echo 'Creating activity type category : ' . $cat['ref'] . "\n";
$newCat = (new ActivityTypeCategory()) $newCat = (new ActivityTypeCategory())
->setName(($cat['name'])); ->setName(($cat['name']));
$manager->persist($newCat); $manager->persist($newCat);
$reference = 'activity_type_cat_'.$cat['ref']; $reference = 'activity_type_cat_' . $cat['ref'];
$this->addReference($reference, $newCat); $this->addReference($reference, $newCat);
static::$references[] = $reference; static::$references[] = $reference;

View File

@@ -1,38 +1,26 @@
<?php <?php
/* /**
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop> * Chill is a software for social workers
* *
* This program is free software: you can redistribute it and/or modify * For the full copyright and license information, please view
* it under the terms of the GNU Affero General Public License as published by * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\DataFixtures\ORM; namespace Chill\ActivityBundle\DataFixtures\ORM;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Chill\MainBundle\DataFixtures\ORM\LoadPermissionsGroup;
use Chill\MainBundle\DataFixtures\ORM\LoadScopes;
use Chill\MainBundle\Entity\RoleScope;
use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface; use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager; use Doctrine\Persistence\ObjectManager;
use Chill\MainBundle\DataFixtures\ORM\LoadPermissionsGroup;
use Chill\MainBundle\Entity\RoleScope;
use Chill\MainBundle\DataFixtures\ORM\LoadScopes;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
/** /**
* Add a role CHILL_ACTIVITY_UPDATE & CHILL_ACTIVITY_CREATE for all groups except administrative, * Add a role CHILL_ACTIVITY_UPDATE & CHILL_ACTIVITY_CREATE for all groups except administrative,
* and a role CHILL_ACTIVITY_SEE for administrative * and a role CHILL_ACTIVITY_SEE for administrative.
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/ */
class LoadActivitytACL extends AbstractFixture implements OrderedFixtureInterface class LoadActivitytACL extends AbstractFixture implements OrderedFixtureInterface
{ {
@@ -41,12 +29,12 @@ class LoadActivitytACL extends AbstractFixture implements OrderedFixtureInterfac
return 16000; return 16000;
} }
public function load(ObjectManager $manager) public function load(ObjectManager $manager)
{ {
foreach (LoadPermissionsGroup::$refs as $permissionsGroupRef) { foreach (LoadPermissionsGroup::$refs as $permissionsGroupRef) {
$permissionsGroup = $this->getReference($permissionsGroupRef); $permissionsGroup = $this->getReference($permissionsGroupRef);
foreach (LoadScopes::$references as $scopeRef){
foreach (LoadScopes::$references as $scopeRef) {
$scope = $this->getReference($scopeRef); $scope = $this->getReference($scopeRef);
//create permission group //create permission group
switch ($permissionsGroup->getName()) { switch ($permissionsGroup->getName()) {
@@ -54,50 +42,52 @@ class LoadActivitytACL extends AbstractFixture implements OrderedFixtureInterfac
if ($scope->getName()['en'] === 'administrative') { if ($scope->getName()['en'] === 'administrative') {
break 2; // we do not want any power on administrative break 2; // we do not want any power on administrative
} }
break; break;
case 'administrative': case 'administrative':
case 'direction': case 'direction':
if (in_array($scope->getName()['en'], array('administrative', 'social'))) { if (in_array($scope->getName()['en'], ['administrative', 'social'])) {
break 2; // we do not want any power on social or administrative break 2; // we do not want any power on social or administrative
} }
break; break;
} }
printf("Adding CHILL_ACTIVITY_UPDATE & CHILL_ACTIVITY_CREATE & CHILL_ACTIVITY_DELETE, and stats and list permissions to %s " printf(
'Adding CHILL_ACTIVITY_UPDATE & CHILL_ACTIVITY_CREATE & CHILL_ACTIVITY_DELETE, and stats and list permissions to %s '
. "permission group, scope '%s' \n", . "permission group, scope '%s' \n",
$permissionsGroup->getName(), $scope->getName()['en']); $permissionsGroup->getName(),
$scope->getName()['en']
);
$roleScopeUpdate = (new RoleScope()) $roleScopeUpdate = (new RoleScope())
->setRole('CHILL_ACTIVITY_UPDATE') ->setRole('CHILL_ACTIVITY_UPDATE')
->setScope($scope); ->setScope($scope);
$permissionsGroup->addRoleScope($roleScopeUpdate); $permissionsGroup->addRoleScope($roleScopeUpdate);
$roleScopeCreate = (new RoleScope()) $roleScopeCreate = (new RoleScope())
->setRole(ActivityVoter::CREATE_ACCOMPANYING_COURSE) ->setRole(ActivityVoter::CREATE_ACCOMPANYING_COURSE)
->setScope($scope); ->setScope($scope);
$roleScopeCreate = (new RoleScope()) $roleScopeCreate = (new RoleScope())
->setRole(ActivityVoter::CREATE_PERSON) ->setRole(ActivityVoter::CREATE_PERSON)
->setScope($scope); ->setScope($scope);
$permissionsGroup->addRoleScope($roleScopeCreate); $permissionsGroup->addRoleScope($roleScopeCreate);
$roleScopeDelete = (new RoleScope()) $roleScopeDelete = (new RoleScope())
->setRole('CHILL_ACTIVITY_DELETE') ->setRole('CHILL_ACTIVITY_DELETE')
->setScope($scope); ->setScope($scope);
$permissionsGroup->addRoleScope($roleScopeDelete); $permissionsGroup->addRoleScope($roleScopeDelete);
$roleScopeList = (new RoleScope()) $roleScopeList = (new RoleScope())
->setRole(ActivityStatsVoter::LISTS) ->setRole(ActivityStatsVoter::LISTS);
;
$permissionsGroup->addRoleScope($roleScopeList); $permissionsGroup->addRoleScope($roleScopeList);
$roleScopeStat = (new RoleScope()) $roleScopeStat = (new RoleScope())
->setRole(ActivityStatsVoter::STATS) ->setRole(ActivityStatsVoter::STATS);
;
$permissionsGroup->addRoleScope($roleScopeStat); $permissionsGroup->addRoleScope($roleScopeStat);
$manager->persist($roleScopeUpdate); $manager->persist($roleScopeUpdate);
$manager->persist($roleScopeCreate); $manager->persist($roleScopeCreate);
$manager->persist($roleScopeDelete); $manager->persist($roleScopeDelete);
} }
} }
$manager->flush(); $manager->flush();
} }
} }

View File

@@ -1,45 +1,28 @@
<?php <?php
/* /**
* Chill is a software for social workers * Chill is a software for social workers
* *
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, * For the full copyright and license information, please view
* <http://www.champs-libres.coop>, <info@champs-libres.coop> * the LICENSE file that was distributed with this source code.
*
* 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\ActivityBundle\DependencyInjection; namespace Chill\ActivityBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
/** /**
* This is the class that loads and manages your bundle configuration * This is the class that loads and manages your bundle configuration.
* *
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html} * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
*/ */
class ChillActivityExtension extends Extension implements PrependExtensionInterface class ChillActivityExtension extends Extension implements PrependExtensionInterface
{ {
/**
* {@inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container) public function load(array $configs, ContainerBuilder $container)
{ {
$configuration = new Configuration(); $configuration = new Configuration();
@@ -47,7 +30,7 @@ class ChillActivityExtension extends Extension implements PrependExtensionInterf
$container->setParameter('chill_activity.form.time_duration', $config['form']['time_duration']); $container->setParameter('chill_activity.form.time_duration', $config['form']['time_duration']);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config')); $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../config'));
$loader->load('services.yaml'); $loader->load('services.yaml');
$loader->load('services/export.yaml'); $loader->load('services/export.yaml');
$loader->load('services/repositories.yaml'); $loader->load('services/repositories.yaml');
@@ -65,38 +48,38 @@ class ChillActivityExtension extends Extension implements PrependExtensionInterf
$this->prependCruds($container); $this->prependCruds($container);
} }
public function prependAuthorization(ContainerBuilder $container)
{
$container->prependExtensionConfig('security', [
'role_hierarchy' => [
ActivityVoter::UPDATE => [ActivityVoter::SEE_DETAILS],
ActivityVoter::CREATE_PERSON => [ActivityVoter::SEE_DETAILS],
ActivityVoter::CREATE_ACCOMPANYING_COURSE => [ActivityVoter::SEE_DETAILS],
ActivityVoter::DELETE => [ActivityVoter::SEE_DETAILS],
ActivityVoter::SEE_DETAILS => [ActivityVoter::SEE],
ActivityVoter::FULL => [
ActivityVoter::CREATE_PERSON,
ActivityVoter::CREATE_ACCOMPANYING_COURSE,
ActivityVoter::DELETE,
ActivityVoter::UPDATE,
],
],
]);
}
/* (non-PHPdoc) /* (non-PHPdoc)
* @see \Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface::prepend() * @see \Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface::prepend()
*/ */
public function prependRoutes(ContainerBuilder $container) public function prependRoutes(ContainerBuilder $container)
{ {
//add routes for custom bundle //add routes for custom bundle
$container->prependExtensionConfig('chill_main', array( $container->prependExtensionConfig('chill_main', [
'routing' => array( 'routing' => [
'resources' => array( 'resources' => [
'@ChillActivityBundle/config/routes.yaml' '@ChillActivityBundle/config/routes.yaml',
) ],
) ],
)); ]);
}
public function prependAuthorization(ContainerBuilder $container)
{
$container->prependExtensionConfig('security', array(
'role_hierarchy' => array(
ActivityVoter::UPDATE => array(ActivityVoter::SEE_DETAILS),
ActivityVoter::CREATE_PERSON => array(ActivityVoter::SEE_DETAILS),
ActivityVoter::CREATE_ACCOMPANYING_COURSE => array(ActivityVoter::SEE_DETAILS),
ActivityVoter::DELETE => array(ActivityVoter::SEE_DETAILS),
ActivityVoter::SEE_DETAILS => array(ActivityVoter::SEE),
ActivityVoter::FULL => [
ActivityVoter::CREATE_PERSON,
ActivityVoter::CREATE_ACCOMPANYING_COURSE,
ActivityVoter::DELETE,
ActivityVoter::UPDATE
],
)
));
} }
protected function prependCruds(ContainerBuilder $container) protected function prependCruds(ContainerBuilder $container)
@@ -112,17 +95,17 @@ class ChillActivityExtension extends Extension implements PrependExtensionInterf
'actions' => [ 'actions' => [
'index' => [ 'index' => [
'template' => '@ChillActivity/ActivityType/index.html.twig', 'template' => '@ChillActivity/ActivityType/index.html.twig',
'role' => 'ROLE_ADMIN' 'role' => 'ROLE_ADMIN',
], ],
'new' => [ 'new' => [
'role' => 'ROLE_ADMIN', 'role' => 'ROLE_ADMIN',
'template' => '@ChillActivity/ActivityType/new.html.twig', 'template' => '@ChillActivity/ActivityType/new.html.twig',
], ],
'edit' => [ 'edit' => [
'role' => 'ROLE_ADMIN', 'role' => 'ROLE_ADMIN',
'template' => '@ChillActivity/ActivityType/edit.html.twig', 'template' => '@ChillActivity/ActivityType/edit.html.twig',
] ],
] ],
], ],
[ [
'class' => \Chill\ActivityBundle\Entity\ActivityTypeCategory::class, 'class' => \Chill\ActivityBundle\Entity\ActivityTypeCategory::class,
@@ -133,17 +116,17 @@ class ChillActivityExtension extends Extension implements PrependExtensionInterf
'actions' => [ 'actions' => [
'index' => [ 'index' => [
'template' => '@ChillActivity/ActivityTypeCategory/index.html.twig', 'template' => '@ChillActivity/ActivityTypeCategory/index.html.twig',
'role' => 'ROLE_ADMIN' 'role' => 'ROLE_ADMIN',
], ],
'new' => [ 'new' => [
'role' => 'ROLE_ADMIN', 'role' => 'ROLE_ADMIN',
'template' => '@ChillActivity/ActivityTypeCategory/new.html.twig', 'template' => '@ChillActivity/ActivityTypeCategory/new.html.twig',
], ],
'edit' => [ 'edit' => [
'role' => 'ROLE_ADMIN', 'role' => 'ROLE_ADMIN',
'template' => '@ChillActivity/ActivityTypeCategory/edit.html.twig', 'template' => '@ChillActivity/ActivityTypeCategory/edit.html.twig',
] ],
] ],
], ],
[ [
'class' => \Chill\ActivityBundle\Entity\ActivityPresence::class, 'class' => \Chill\ActivityBundle\Entity\ActivityPresence::class,
@@ -154,19 +137,19 @@ class ChillActivityExtension extends Extension implements PrependExtensionInterf
'actions' => [ 'actions' => [
'index' => [ 'index' => [
'template' => '@ChillActivity/ActivityPresence/index.html.twig', 'template' => '@ChillActivity/ActivityPresence/index.html.twig',
'role' => 'ROLE_ADMIN' 'role' => 'ROLE_ADMIN',
], ],
'new' => [ 'new' => [
'role' => 'ROLE_ADMIN', 'role' => 'ROLE_ADMIN',
'template' => '@ChillActivity/ActivityPresence/new.html.twig', 'template' => '@ChillActivity/ActivityPresence/new.html.twig',
], ],
'edit' => [ 'edit' => [
'role' => 'ROLE_ADMIN', 'role' => 'ROLE_ADMIN',
'template' => '@ChillActivity/ActivityPresence/edit.html.twig', 'template' => '@ChillActivity/ActivityPresence/edit.html.twig',
] ],
] ],
], ],
] ],
]); ]);
} }
} }

View File

@@ -1,71 +1,73 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\DependencyInjection; namespace Chill\ActivityBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface; use Symfony\Component\Config\Definition\ConfigurationInterface;
/** /**
* This is the class that validates and merges configuration from your app/config files * This is the class that validates and merges configuration from your app/config files.
* *
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class} * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
*/ */
class Configuration implements ConfigurationInterface class Configuration implements ConfigurationInterface
{ {
/**
* {@inheritdoc}
*/
public function getConfigTreeBuilder() public function getConfigTreeBuilder()
{ {
$treeBuilder = new TreeBuilder('chill_activity'); $treeBuilder = new TreeBuilder('chill_activity');
$rootNode = $treeBuilder->getRootNode('chill_activity'); $rootNode = $treeBuilder->getRootNode('chill_activity');
$rootNode $rootNode
->children() ->children()
->arrayNode('form') ->arrayNode('form')
->canBeEnabled() ->canBeEnabled()
->children() ->children()
->arrayNode('time_duration') ->arrayNode('time_duration')
->isRequired() ->isRequired()
->requiresAtLeastOneElement() ->requiresAtLeastOneElement()
->defaultValue( ->defaultValue(
array( [
[ 'label' => '5 minutes', 'seconds' => 300], ['label' => '5 minutes', 'seconds' => 300],
[ 'label' => '10 minutes', 'seconds' => 600], ['label' => '10 minutes', 'seconds' => 600],
[ 'label' => '15 minutes', 'seconds' => 900], ['label' => '15 minutes', 'seconds' => 900],
[ 'label' => '20 minutes', 'seconds' => 1200], ['label' => '20 minutes', 'seconds' => 1200],
[ 'label' => '25 minutes', 'seconds' => 1500], ['label' => '25 minutes', 'seconds' => 1500],
[ 'label' => '30 minutes', 'seconds' => 1800], ['label' => '30 minutes', 'seconds' => 1800],
[ 'label' => '45 minutes', 'seconds' => 2700], ['label' => '45 minutes', 'seconds' => 2700],
[ 'label' => '1 hour', 'seconds' => 3600], ['label' => '1 hour', 'seconds' => 3600],
[ 'label' => '1 hour 15', 'seconds' => 4500], ['label' => '1 hour 15', 'seconds' => 4500],
[ 'label' => '1 hour 30', 'seconds' => 5400], ['label' => '1 hour 30', 'seconds' => 5400],
[ 'label' => '1 hour 45', 'seconds' => 6300], ['label' => '1 hour 45', 'seconds' => 6300],
[ 'label' => '2 hours', 'seconds' => 7200], ['label' => '2 hours', 'seconds' => 7200],
) ]
) )
->info('The intervals of time to show in activity form') ->info('The intervals of time to show in activity form')
->prototype('array')
->prototype('array') ->children()
->children() ->scalarNode('seconds')
->scalarNode('seconds') ->info('The number of seconds of this duration. Must be an integer.')
->info("The number of seconds of this duration. Must be an integer.") ->cannotBeEmpty()
->cannotBeEmpty() ->validate()
->validate() ->ifTrue(function ($data) {
->ifTrue(function($data) {
return !is_int($data); return !is_int($data);
})->thenInvalid("The value %s is not a valid integer") })->thenInvalid('The value %s is not a valid integer')
->end() ->end()
->end() ->end()
->scalarNode('label') ->scalarNode('label')
->cannotBeEmpty() ->cannotBeEmpty()
->info("The label to show into fields") ->info('The label to show into fields')
->end() ->end()
->end() ->end()
->end()
->end()
// ->validate() // ->validate()
// //
// ->ifTrue(function ($data) { // ->ifTrue(function ($data) {
// // test this is an array // // test this is an array
// if (!is_array($data)) { // if (!is_array($data)) {
@@ -84,11 +86,10 @@ class Configuration implements ConfigurationInterface
// }) // })
// ->thenInvalid("The data are invalid. The keys must be a string and the value integers") // ->thenInvalid("The data are invalid. The keys must be a string and the value integers")
// ->end() // ->end()
->end() ->end()
->end() ->end()
->end()
->end() ->end();
->end();
return $treeBuilder; return $treeBuilder;
} }

View File

@@ -1,39 +1,46 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Entity; namespace Chill\ActivityBundle\Entity;
use Chill\DocStoreBundle\Entity\Document; use Chill\DocStoreBundle\Entity\Document;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable; use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
use Chill\MainBundle\Entity\HasCenterInterface;
use Chill\MainBundle\Entity\HasScopeInterface;
use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\Location;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\AccompanyingPeriod\SocialIssueConsistency\AccompanyingPeriodLinkedWithSocialIssuesEntityInterface; use Chill\PersonBundle\AccompanyingPeriod\SocialIssueConsistency\AccompanyingPeriodLinkedWithSocialIssuesEntityInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\SocialWork\SocialAction; use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue; use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Chill\ThirdPartyBundle\Entity\ThirdParty; use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Doctrine\ORM\Mapping as ORM; use DateTime;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\Center;
use Chill\PersonBundle\Entity\Person;
use Chill\MainBundle\Entity\HasCenterInterface;
use Chill\MainBundle\Entity\HasScopeInterface;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap; use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Annotation\SerializedName; use Symfony\Component\Serializer\Annotation\SerializedName;
/** /**
* Class Activity * Class Activity.
* *
* @package Chill\ActivityBundle\Entity
* @ORM\Entity(repositoryClass="Chill\ActivityBundle\Repository\ActivityRepository") * @ORM\Entity(repositoryClass="Chill\ActivityBundle\Repository\ActivityRepository")
* @ORM\Table(name="activity") * @ORM\Table(name="activity")
* @ORM\HasLifecycleCallbacks() * @ORM\HasLifecycleCallbacks
* @DiscriminatorMap(typeProperty="type", mapping={ * @DiscriminatorMap(typeProperty="type", mapping={
* "activity"=Activity::class * "activity": Activity::class
* }) * })
*/ */
/* /*
@@ -46,60 +53,15 @@ use Symfony\Component\Serializer\Annotation\SerializedName;
class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPeriodLinkedWithSocialIssuesEntityInterface class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPeriodLinkedWithSocialIssuesEntityInterface
{ {
const SENTRECEIVED_SENT = 'sent'; public const SENTRECEIVED_RECEIVED = 'received';
const SENTRECEIVED_RECEIVED = 'received';
public const SENTRECEIVED_SENT = 'sent';
/** /**
* @ORM\Id * @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod")
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
* @Groups({"read"}) * @Groups({"read"})
*/ */
private ?int $id = null; private ?AccompanyingPeriod $accompanyingPeriod = null;
/**
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User")
*/
private User $user;
/**
* @ORM\Column(type="datetime")
*/
private \DateTime $date;
/**
* @ORM\Column(type="time", nullable=true)
*/
private ?\DateTime $durationTime = null;
/**
* @ORM\Column(type="time", nullable=true)
*/
private ?\DateTime $travelTime = null;
/**
* @ORM\ManyToOne(targetEntity="Chill\ActivityBundle\Entity\ActivityPresence")
*/
private ?ActivityPresence $attendee = null;
/**
* @ORM\ManyToMany(targetEntity="Chill\ActivityBundle\Entity\ActivityReason")
*/
private Collection $reasons;
/**
* @ORM\ManyToMany(targetEntity="Chill\PersonBundle\Entity\SocialWork\SocialIssue")
* @ORM\JoinTable(name="chill_activity_activity_chill_person_socialissue")
* @Groups({"read"})
*/
private Collection $socialIssues;
/**
* @ORM\ManyToMany(targetEntity="Chill\PersonBundle\Entity\SocialWork\SocialAction")
* @ORM\JoinTable(name="chill_activity_activity_chill_person_socialaction")
* @Groups({"read"})
*/
private Collection $socialActions;
/** /**
* @ORM\ManyToOne(targetEntity="Chill\ActivityBundle\Entity\ActivityType") * @ORM\ManyToOne(targetEntity="Chill\ActivityBundle\Entity\ActivityType")
@@ -110,32 +72,89 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer
private ActivityType $activityType; private ActivityType $activityType;
/** /**
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\Scope") * @ORM\ManyToOne(targetEntity="Chill\ActivityBundle\Entity\ActivityPresence")
*/ */
private ?Scope $scope = null; private ?ActivityPresence $attendee = null;
/**
* @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\Person")
*/
private ?Person $person = null;
/**
* @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod")
* @Groups({"read"})
*/
private ?AccompanyingPeriod $accompanyingPeriod = null;
/** /**
* @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\CommentEmbeddable", columnPrefix="comment_") * @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\CommentEmbeddable", columnPrefix="comment_")
*/ */
private CommentEmbeddable $comment; private CommentEmbeddable $comment;
/**
* @ORM\Column(type="datetime")
*/
private DateTime $date;
/**
* @ORM\ManyToMany(targetEntity="Chill\DocStoreBundle\Entity\StoredObject", cascade={"persist"})
*/
private Collection $documents;
/**
* @ORM\Column(type="time", nullable=true)
*/
private ?DateTime $durationTime = null;
/**
* @ORM\Column(type="boolean", options={"default": false})
*/
private bool $emergency = false;
/**
* @ORM\Id
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
* @Groups({"read"})
*/
private ?int $id = null;
/**
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\Location")
* @groups({"read"})
*/
private ?Location $location = null;
/**
* @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\Person")
*/
private ?Person $person = null;
/** /**
* @ORM\ManyToMany(targetEntity="Chill\PersonBundle\Entity\Person") * @ORM\ManyToMany(targetEntity="Chill\PersonBundle\Entity\Person")
* @Groups({"read"}) * @Groups({"read"})
*/ */
private ?Collection $persons = null; private ?Collection $persons = null;
/**
* @ORM\ManyToMany(targetEntity="Chill\ActivityBundle\Entity\ActivityReason")
*/
private Collection $reasons;
/**
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\Scope")
*/
private ?Scope $scope = null;
/**
* @ORM\Column(type="string", options={"default": ""})
*/
private string $sentReceived = '';
/**
* @ORM\ManyToMany(targetEntity="Chill\PersonBundle\Entity\SocialWork\SocialAction")
* @ORM\JoinTable(name="chill_activity_activity_chill_person_socialaction")
* @Groups({"read"})
*/
private Collection $socialActions;
/**
* @ORM\ManyToMany(targetEntity="Chill\PersonBundle\Entity\SocialWork\SocialIssue")
* @ORM\JoinTable(name="chill_activity_activity_chill_person_socialissue")
* @Groups({"read"})
*/
private Collection $socialIssues;
/** /**
* @ORM\ManyToMany(targetEntity="Chill\ThirdPartyBundle\Entity\ThirdParty") * @ORM\ManyToMany(targetEntity="Chill\ThirdPartyBundle\Entity\ThirdParty")
* @Groups({"read"}) * @Groups({"read"})
@@ -143,9 +162,14 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer
private ?Collection $thirdParties = null; private ?Collection $thirdParties = null;
/** /**
* @ORM\ManyToMany(targetEntity="Chill\DocStoreBundle\Entity\StoredObject", cascade={"persist"}) * @ORM\Column(type="time", nullable=true)
*/ */
private Collection $documents; private ?DateTime $travelTime = null;
/**
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User")
*/
private User $user;
/** /**
* @ORM\ManyToMany(targetEntity="Chill\MainBundle\Entity\User") * @ORM\ManyToMany(targetEntity="Chill\MainBundle\Entity\User")
@@ -153,23 +177,6 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer
*/ */
private ?Collection $users = null; private ?Collection $users = null;
/**
* @ORM\Column(type="boolean", options={"default"=false})
*/
private bool $emergency = false;
/**
* @ORM\Column(type="string", options={"default"=""})
*/
private string $sentReceived = '';
/**
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\Location")
* @groups({"read"})
*/
private ?Location $location = null;
public function __construct() public function __construct()
{ {
$this->reasons = new ArrayCollection(); $this->reasons = new ArrayCollection();
@@ -182,71 +189,25 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer
$this->socialActions = new ArrayCollection(); $this->socialActions = new ArrayCollection();
} }
public function getId(): ?int public function addDocument(Document $document): self
{ {
return $this->id; $this->documents[] = $document;
}
public function setUser(UserInterface $user): self
{
$this->user = $user;
return $this; return $this;
} }
public function getUser(): User /**
* Add a person to the person list.
*/
public function addPerson(?Person $person): self
{ {
return $this->user; if (null !== $person) {
} $this->persons[] = $person;
}
public function setDate(\DateTime $date): self
{
$this->date = $date;
return $this; return $this;
} }
public function getDate(): \DateTime
{
return $this->date;
}
public function setDurationTime(?\DateTime $durationTime): self
{
$this->durationTime = $durationTime;
return $this;
}
public function getDurationTime(): ?\DateTime
{
return $this->durationTime;
}
public function setTravelTime(\DateTime $travelTime): self
{
$this->travelTime = $travelTime;
return $this;
}
public function getTravelTime(): ?\DateTime
{
return $this->travelTime;
}
public function setAttendee(ActivityPresence $attendee): self
{
$this->attendee = $attendee;
return $this;
}
public function getAttendee(): ?ActivityPresence
{
return $this->attendee;
}
public function addReason(ActivityReason $reason): self public function addReason(ActivityReason $reason): self
{ {
$this->reasons->add($reason); $this->reasons->add($reason);
@@ -254,49 +215,6 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer
return $this; return $this;
} }
public function removeReason(ActivityReason $reason): void
{
$this->reasons->removeElement($reason);
}
public function getReasons(): Collection
{
return $this->reasons;
}
public function setReasons(?ArrayCollection $reasons): self
{
$this->reasons = $reasons;
return $this;
}
public function getSocialIssues(): Collection
{
return $this->socialIssues;
}
public function addSocialIssue(SocialIssue $socialIssue): self
{
if (!$this->socialIssues->contains($socialIssue)) {
$this->socialIssues[] = $socialIssue;
}
return $this;
}
public function removeSocialIssue(SocialIssue $socialIssue): self
{
$this->socialIssues->removeElement($socialIssue);
return $this;
}
public function getSocialActions(): Collection
{
return $this->socialActions;
}
public function addSocialAction(SocialAction $socialAction): self public function addSocialAction(SocialAction $socialAction): self
{ {
if (!$this->socialActions->contains($socialAction)) { if (!$this->socialActions->contains($socialAction)) {
@@ -306,82 +224,51 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer
return $this; return $this;
} }
public function removeSocialAction(SocialAction $socialAction): self public function addSocialIssue(SocialIssue $socialIssue): self
{ {
$this->socialActions->removeElement($socialAction); if (!$this->socialIssues->contains($socialIssue)) {
$this->socialIssues[] = $socialIssue;
}
return $this; return $this;
} }
public function setActivityType(ActivityType $activityType): self public function addThirdParty(?ThirdParty $thirdParty): self
{ {
$this->activityType = $activityType; if (null !== $thirdParty) {
$this->thirdParties[] = $thirdParty;
}
return $this; return $this;
} }
public function getActivityType(): ActivityType public function addUser(?User $user): self
{ {
return $this->activityType; if (null !== $user) {
} $this->users[] = $user;
}
/**
* @deprecated
*/
public function setType(ActivityType $activityType): self
{
$this->activityType = $activityType;
return $this; return $this;
} }
/**
* @deprecated
*/
public function getType(): ActivityType
{
return $this->activityType;
}
public function setScope(Scope $scope): self
{
$this->scope = $scope;
return $this;
}
public function getScope(): ?Scope
{
return $this->scope;
}
public function setPerson(?Person $person): self
{
$this->person = $person;
return $this;
}
public function getPerson(): ?Person
{
return $this->person;
}
public function getAccompanyingPeriod(): ?AccompanyingPeriod public function getAccompanyingPeriod(): ?AccompanyingPeriod
{ {
return $this->accompanyingPeriod; return $this->accompanyingPeriod;
} }
public function setAccompanyingPeriod(?AccompanyingPeriod $accompanyingPeriod): self public function getActivityType(): ActivityType
{ {
$this->accompanyingPeriod = $accompanyingPeriod; return $this->activityType;
}
return $this; public function getAttendee(): ?ActivityPresence
{
return $this->attendee;
} }
/** /**
* get the center * get the center
* center is extracted from person * center is extracted from person.
*/ */
public function getCenter(): ?Center public function getCenter(): ?Center
{ {
@@ -397,28 +284,39 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer
return $this->comment; return $this->comment;
} }
public function setComment(CommentEmbeddable $comment): self public function getDate(): DateTime
{ {
$this->comment = $comment; return $this->date;
return $this;
} }
/** public function getDocuments(): Collection
* Add a person to the person list
*/
public function addPerson(?Person $person): self
{ {
if (null !== $person) { return $this->documents;
$this->persons[] = $person;
}
return $this;
} }
public function removePerson(Person $person): void public function getDurationTime(): ?DateTime
{ {
$this->persons->removeElement($person); return $this->durationTime;
}
public function getEmergency(): bool
{
return $this->emergency;
}
public function getId(): ?int
{
return $this->id;
}
public function getLocation(): ?Location
{
return $this->location;
}
public function getPerson(): ?Person
{
return $this->person;
} }
public function getPersons(): Collection public function getPersons(): Collection
@@ -430,13 +328,16 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer
{ {
if (null !== $this->accompanyingPeriod) { if (null !== $this->accompanyingPeriod) {
$personsAssociated = []; $personsAssociated = [];
foreach ($this->accompanyingPeriod->getParticipations() as $participation) { foreach ($this->accompanyingPeriod->getParticipations() as $participation) {
if ($this->persons->contains($participation->getPerson())) { if ($this->persons->contains($participation->getPerson())) {
$personsAssociated[] = $participation->getPerson(); $personsAssociated[] = $participation->getPerson();
} }
} }
return $personsAssociated; return $personsAssociated;
} }
return []; return [];
} }
@@ -444,28 +345,103 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer
{ {
if (null !== $this->accompanyingPeriod) { if (null !== $this->accompanyingPeriod) {
$personsNotAssociated = []; $personsNotAssociated = [];
foreach ($this->persons as $person) { foreach ($this->persons as $person) {
if (!in_array($person, $this->getPersonsAssociated())) { if (!in_array($person, $this->getPersonsAssociated())) {
$personsNotAssociated[] = $person; $personsNotAssociated[] = $person;
} }
} }
return $personsNotAssociated; return $personsNotAssociated;
} }
return []; return [];
} }
public function setPersons(?Collection $persons): self public function getReasons(): Collection
{ {
$this->persons = $persons; return $this->reasons;
}
public function getScope(): ?Scope
{
return $this->scope;
}
public function getSentReceived(): string
{
return $this->sentReceived;
}
public function getSocialActions(): Collection
{
return $this->socialActions;
}
public function getSocialIssues(): Collection
{
return $this->socialIssues;
}
public function getThirdParties(): Collection
{
return $this->thirdParties;
}
public function getTravelTime(): ?DateTime
{
return $this->travelTime;
}
/**
* @deprecated
*/
public function getType(): ActivityType
{
return $this->activityType;
}
public function getUser(): User
{
return $this->user;
}
public function getUsers(): Collection
{
return $this->users;
}
public function isEmergency(): bool
{
return $this->getEmergency();
}
public function removeDocument(Document $document): void
{
$this->documents->removeElement($document);
}
public function removePerson(Person $person): void
{
$this->persons->removeElement($person);
}
public function removeReason(ActivityReason $reason): void
{
$this->reasons->removeElement($reason);
}
public function removeSocialAction(SocialAction $socialAction): self
{
$this->socialActions->removeElement($socialAction);
return $this; return $this;
} }
public function addThirdParty(?ThirdParty $thirdParty): self public function removeSocialIssue(SocialIssue $socialIssue): self
{ {
if (null !== $thirdParty) { $this->socialIssues->removeElement($socialIssue);
$this->thirdParties[] = $thirdParty;
}
return $this; return $this;
} }
@@ -474,33 +450,44 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer
$this->thirdParties->removeElement($thirdParty); $this->thirdParties->removeElement($thirdParty);
} }
public function getThirdParties(): Collection public function removeUser(User $user): void
{ {
return $this->thirdParties; $this->users->removeElement($user);
} }
public function setThirdParties(?Collection $thirdParties): self public function setAccompanyingPeriod(?AccompanyingPeriod $accompanyingPeriod): self
{ {
$this->thirdParties = $thirdParties; $this->accompanyingPeriod = $accompanyingPeriod;
return $this; return $this;
} }
public function addDocument(Document $document): self public function setActivityType(ActivityType $activityType): self
{ {
$this->documents[] = $document; $this->activityType = $activityType;
return $this; return $this;
} }
public function removeDocument(Document $document): void public function setAttendee(ActivityPresence $attendee): self
{ {
$this->documents->removeElement($document); $this->attendee = $attendee;
return $this;
} }
public function getDocuments(): Collection public function setComment(CommentEmbeddable $comment): self
{ {
return $this->documents; $this->comment = $comment;
return $this;
}
public function setDate(DateTime $date): self
{
$this->date = $date;
return $this;
} }
public function setDocuments(Collection $documents): self public function setDocuments(Collection $documents): self
@@ -510,41 +497,13 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer
return $this; return $this;
} }
public function addUser(?User $user): self public function setDurationTime(?DateTime $durationTime): self
{ {
if (null !== $user) { $this->durationTime = $durationTime;
$this->users[] = $user;
}
return $this;
}
public function removeUser(User $user): void
{
$this->users->removeElement($user);
}
public function getUsers(): Collection
{
return $this->users;
}
public function setUsers(?Collection $users): self
{
$this->users = $users;
return $this; return $this;
} }
public function isEmergency(): bool
{
return $this->getEmergency();
}
public function getEmergency(): bool
{
return $this->emergency;
}
public function setEmergency(bool $emergency): self public function setEmergency(bool $emergency): self
{ {
$this->emergency = $emergency; $this->emergency = $emergency;
@@ -552,9 +511,39 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer
return $this; return $this;
} }
public function getSentReceived(): string public function setLocation(?Location $location): Activity
{ {
return $this->sentReceived; $this->location = $location;
return $this;
}
public function setPerson(?Person $person): self
{
$this->person = $person;
return $this;
}
public function setPersons(?Collection $persons): self
{
$this->persons = $persons;
return $this;
}
public function setReasons(?ArrayCollection $reasons): self
{
$this->reasons = $reasons;
return $this;
}
public function setScope(Scope $scope): self
{
$this->scope = $scope;
return $this;
} }
public function setSentReceived(?string $sentReceived): self public function setSentReceived(?string $sentReceived): self
@@ -564,21 +553,41 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer
return $this; return $this;
} }
/** public function setThirdParties(?Collection $thirdParties): self
* @return Location|null
*/
public function getLocation(): ?Location
{ {
return $this->location; $this->thirdParties = $thirdParties;
return $this;
}
public function setTravelTime(DateTime $travelTime): self
{
$this->travelTime = $travelTime;
return $this;
} }
/** /**
* @param Location|null $location * @deprecated
* @return Activity
*/ */
public function setLocation(?Location $location): Activity public function setType(ActivityType $activityType): self
{ {
$this->location = $location; $this->activityType = $activityType;
return $this;
}
public function setUser(UserInterface $user): self
{
$this->user = $user;
return $this;
}
public function setUsers(?Collection $users): self
{
$this->users = $users;
return $this; return $this;
} }
} }

View File

@@ -1,21 +1,10 @@
<?php <?php
/* /**
* Chill is a software for social workers
* *
* Copyright (C) 2015, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop> * For the full copyright and license information, please view
* * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\Entity; namespace Chill\ActivityBundle\Entity;
@@ -23,15 +12,19 @@ namespace Chill\ActivityBundle\Entity;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
/** /**
* Class ActivityPresence * Class ActivityPresence.
* *
* @package Chill\ActivityBundle\Entity * @ORM\Entity
* @ORM\Entity()
* @ORM\Table(name="activitytpresence") * @ORM\Table(name="activitytpresence")
* @ORM\HasLifecycleCallbacks() * @ORM\HasLifecycleCallbacks
*/ */
class ActivityPresence class ActivityPresence
{ {
/**
* @ORM\Column(type="boolean")
*/
private bool $active = true;
/** /**
* @ORM\Id * @ORM\Id
* @ORM\Column(name="id", type="integer") * @ORM\Column(name="id", type="integer")
@@ -44,28 +37,6 @@ class ActivityPresence
*/ */
private array $name = []; private array $name = [];
/**
* @ORM\Column(type="boolean")
*/
private bool $active = true;
public function getId(): int
{
return $this->id;
}
public function setName(array $name): self
{
$this->name = $name;
return $this;
}
public function getName(): array
{
return $this->name;
}
/** /**
* Get active * Get active
* return true if the category type is active. * return true if the category type is active.
@@ -75,9 +46,19 @@ class ActivityPresence
return $this->active; return $this->active;
} }
public function getId(): int
{
return $this->id;
}
public function getName(): array
{
return $this->name;
}
/** /**
* Is active * Is active
* return true if the category type is active * return true if the category type is active.
*/ */
public function isActive(): bool public function isActive(): bool
{ {
@@ -86,7 +67,7 @@ class ActivityPresence
/** /**
* Set active * Set active
* set to true if the category type is active * set to true if the category type is active.
*/ */
public function setActive(bool $active): self public function setActive(bool $active): self
{ {
@@ -94,4 +75,11 @@ class ActivityPresence
return $this; return $this;
} }
public function setName(array $name): self
{
$this->name = $name;
return $this;
}
} }

View File

@@ -1,40 +1,41 @@
<?php <?php
/* /**
* Chill is a software for social workers
* *
* Copyright (C) 2015, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop> * For the full copyright and license information, please view
* * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\Entity; namespace Chill\ActivityBundle\Entity;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Chill\ActivityBundle\Entity\ActivityReasonCategory;
/** /**
* Class ActivityReason * Class ActivityReason.
* *
* @package Chill\ActivityBundle\Entity * @ORM\Entity
* @ORM\Entity()
* @ORM\Table(name="activityreason") * @ORM\Table(name="activityreason")
* @ORM\HasLifecycleCallbacks() * @ORM\HasLifecycleCallbacks
*/ */
class ActivityReason class ActivityReason
{ {
/** /**
* @var integer * @var bool
* @ORM\Column(type="boolean")
*/
private $active = true;
/**
* @var ActivityReasonCategory
* @ORM\ManyToOne(
* targetEntity="Chill\ActivityBundle\Entity\ActivityReasonCategory",
* inversedBy="reasons")
*/
private $category;
/**
* @var int
* *
* @ORM\Id * @ORM\Id
* @ORM\Column(name="id", type="integer") * @ORM\Column(name="id", type="integer")
@@ -49,86 +50,17 @@ class ActivityReason
private $name; private $name;
/** /**
* @var ActivityReasonCategory * Get active.
* @ORM\ManyToOne(
* targetEntity="Chill\ActivityBundle\Entity\ActivityReasonCategory",
* inversedBy="reasons")
*/
private $category;
/**
* @var boolean
* @ORM\Column(type="boolean")
*/
private $active = true;
/**
* Get id
* *
* @return integer * @return bool
*/ */
public function getId() public function getActive()
{ {
return $this->id; return $this->active;
} }
/** /**
* Set name * Get category.
*
* @param array $name
* @return ActivityReason
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return array | string
*/
public function getName($locale = null)
{
if ($locale) {
if (isset($this->name[$locale])) {
return $this->name[$locale];
} else {
foreach ($this->name as $name) {
if (!empty($name)) {
return $name;
}
}
}
return '';
} else {
return $this->name;
}
}
/**
* Set category of the reason. If you set to the reason an inactive
* category, the reason will become inactive
*
* @param ActivityReasonCategory $category
* @return ActivityReason
*/
public function setCategory(ActivityReasonCategory $category)
{
if($this->category !== $category && ! $category->getActive()) {
$this->setActive(False);
}
$this->category = $category;
return $this;
}
/**
* Get category
* *
* @return ActivityReasonCategory * @return ActivityReasonCategory
*/ */
@@ -138,9 +70,46 @@ class ActivityReason
} }
/** /**
* Set active * Get id.
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Get name.
*
* @param mixed|null $locale
*
* @return array | string
*/
public function getName($locale = null)
{
if ($locale) {
if (isset($this->name[$locale])) {
return $this->name[$locale];
}
foreach ($this->name as $name) {
if (!empty($name)) {
return $name;
}
}
return '';
}
return $this->name;
}
/**
* Set active.
*
* @param bool $active
* *
* @param boolean $active
* @return ActivityReason * @return ActivityReason
*/ */
public function setActive($active) public function setActive($active)
@@ -151,13 +120,33 @@ class ActivityReason
} }
/** /**
* Get active * Set category of the reason. If you set to the reason an inactive
* category, the reason will become inactive.
* *
* @return boolean * @return ActivityReason
*/ */
public function getActive() public function setCategory(ActivityReasonCategory $category)
{ {
return $this->active; if ($this->category !== $category && !$category->getActive()) {
$this->setActive(false);
}
$this->category = $category;
return $this;
}
/**
* Set name.
*
* @param array $name
*
* @return ActivityReason
*/
public function setName($name)
{
$this->name = $name;
return $this;
} }
} }

View File

@@ -1,39 +1,34 @@
<?php <?php
/* /**
* Copyright (C) 2015, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop> * Chill is a software for social workers
* *
* This program is free software: you can redistribute it and/or modify * For the full copyright and license information, please view
* it under the terms of the GNU Affero General Public License as * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\Entity; namespace Chill\ActivityBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/** /**
* Class ActivityReasonCategory * Class ActivityReasonCategory.
* *
* @package Chill\ActivityBundle\Entity * @ORM\Entity
* @ORM\Entity()
* @ORM\Table(name="activityreasoncategory") * @ORM\Table(name="activityreasoncategory")
* @ORM\HasLifecycleCallbacks() * @ORM\HasLifecycleCallbacks
*/ */
class ActivityReasonCategory class ActivityReasonCategory
{ {
/** /**
* @var integer * @var bool
* @ORM\Column(type="boolean")
*/
private $active = true;
/**
* @var int
* *
* @ORM\Id * @ORM\Id
* @ORM\Column(name="id", type="integer") * @ORM\Column(name="id", type="integer")
@@ -48,17 +43,12 @@ class ActivityReasonCategory
private $name; private $name;
/** /**
* @var boolean * Array of ActivityReason.
* @ORM\Column(type="boolean") *
*/
private $active = true;
/**
* Array of ActivityReason
* @var ArrayCollection * @var ArrayCollection
* @ORM\OneToMany( * @ORM\OneToMany(
* targetEntity="Chill\ActivityBundle\Entity\ActivityReason", * targetEntity="Chill\ActivityBundle\Entity\ActivityReason",
* mappedBy="category") * mappedBy="category")
*/ */
private $reasons; private $reasons;
@@ -75,13 +65,23 @@ class ActivityReasonCategory
*/ */
public function __toString() public function __toString()
{ {
return 'ActivityReasonCategory('.$this->getName('x').')'; return 'ActivityReasonCategory(' . $this->getName('x') . ')';
} }
/** /**
* Get id * Get active.
* *
* @return integer * @return bool
*/
public function getActive()
{
return $this->active;
}
/**
* Get id.
*
* @return int
*/ */
public function getId() public function getId()
{ {
@@ -89,20 +89,9 @@ class ActivityReasonCategory
} }
/** /**
* Set name * Get name.
* *
* @param array $name * @param mixed|null $locale
* @return ActivityReasonCategory
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
* *
* @return array * @return array
*/ */
@@ -111,30 +100,32 @@ class ActivityReasonCategory
if ($locale) { if ($locale) {
if (isset($this->name[$locale])) { if (isset($this->name[$locale])) {
return $this->name[$locale]; return $this->name[$locale];
} else { }
foreach ($this->name as $name) {
if (!empty($name)) { foreach ($this->name as $name) {
return $name; if (!empty($name)) {
} return $name;
} }
} }
return ''; return '';
} else {
return $this->name;
} }
return $this->name;
} }
/** /**
* Declare a category as active (or not). When a category is set * Declare a category as active (or not). When a category is set
* as unactive, all the reason have this entity as category is also * as unactive, all the reason have this entity as category is also
* set as unactive * set as unactive.
*
* @param bool $active
* *
* @param boolean $active
* @return ActivityReasonCategory * @return ActivityReasonCategory
*/ */
public function setActive($active) public function setActive($active)
{ {
if($this->active !== $active && !$active) { if ($this->active !== $active && !$active) {
foreach ($this->reasons as $reason) { foreach ($this->reasons as $reason) {
$reason->setActive($active); $reason->setActive($active);
} }
@@ -146,13 +137,16 @@ class ActivityReasonCategory
} }
/** /**
* Get active * Set name.
* *
* @return boolean * @param array $name
*
* @return ActivityReasonCategory
*/ */
public function getActive() public function setName($name)
{ {
return $this->active; $this->name = $name;
return $this;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Entity; namespace Chill\ActivityBundle\Entity;
@@ -7,12 +14,17 @@ namespace Chill\ActivityBundle\Entity;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
/** /**
* @ORM\Entity() * @ORM\Entity
* @ORM\Table(name="activitytypecategory") * @ORM\Table(name="activitytypecategory")
* @ORM\HasLifecycleCallbacks() * @ORM\HasLifecycleCallbacks
*/ */
class ActivityTypeCategory class ActivityTypeCategory
{ {
/**
* @ORM\Column(type="boolean")
*/
private bool $active = true;
/** /**
* @ORM\Id * @ORM\Id
* @ORM\Column(name="id", type="integer") * @ORM\Column(name="id", type="integer")
@@ -26,38 +38,10 @@ class ActivityTypeCategory
private array $name = []; private array $name = [];
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="float", options={"default": "0.0"})
*/
private bool $active = true;
/**
* @ORM\Column(type="float", options={"default"="0.0"})
*/ */
private float $ordering = 0.0; private float $ordering = 0.0;
public function getId(): ?int
{
return $this->id;
}
/**
* Set name
*/
public function setName(array $name): self
{
$this->name = $name;
return $this;
}
/**
* Get name
*/
public function getName(): array
{
return $this->name;
}
/** /**
* Get active * Get active
* return true if the category type is active. * return true if the category type is active.
@@ -67,9 +51,27 @@ class ActivityTypeCategory
return $this->active; return $this->active;
} }
public function getId(): ?int
{
return $this->id;
}
/**
* Get name.
*/
public function getName(): array
{
return $this->name;
}
public function getOrdering(): float
{
return $this->ordering;
}
/** /**
* Is active * Is active
* return true if the category type is active * return true if the category type is active.
*/ */
public function isActive(): bool public function isActive(): bool
{ {
@@ -78,7 +80,7 @@ class ActivityTypeCategory
/** /**
* Set active * Set active
* set to true if the category type is active * set to true if the category type is active.
*/ */
public function setActive(bool $active): self public function setActive(bool $active): self
{ {
@@ -87,9 +89,14 @@ class ActivityTypeCategory
return $this; return $this;
} }
public function getOrdering(): float /**
* Set name.
*/
public function setName(array $name): self
{ {
return $this->ordering; $this->name = $name;
return $this;
} }
public function setOrdering(float $ordering): self public function setOrdering(float $ordering): self

View File

@@ -1,22 +1,30 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Aggregator; namespace Chill\ActivityBundle\Export\Aggregator;
use Chill\ActivityBundle\Repository\ActivityReasonCategoryRepository; use Chill\ActivityBundle\Repository\ActivityReasonCategoryRepository;
use Chill\ActivityBundle\Repository\ActivityReasonRepository; use Chill\ActivityBundle\Repository\ActivityReasonRepository;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\QueryBuilder;
use Chill\MainBundle\Export\AggregatorInterface;
use Symfony\Component\Security\Core\Role\Role;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\MainBundle\Export\AggregatorInterface;
use Doctrine\ORM\Query\Expr\Join;
use Chill\MainBundle\Export\ExportElementValidatedInterface; use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface; use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use RuntimeException;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
class ActivityReasonAggregator implements AggregatorInterface, ExportElementValidatedInterface class ActivityReasonAggregator implements AggregatorInterface, ExportElementValidatedInterface
{ {
@@ -36,42 +44,47 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali
$this->translatableStringHelper = $translatableStringHelper; $this->translatableStringHelper = $translatableStringHelper;
} }
public function addRole()
{
return new Role(ActivityStatsVoter::STATS);
}
public function alterQuery(QueryBuilder $qb, $data) public function alterQuery(QueryBuilder $qb, $data)
{ {
// add select element // add select element
if ($data['level'] === 'reasons') { if ('reasons' === $data['level']) {
$elem = 'reasons.id'; $elem = 'reasons.id';
$alias = 'activity_reasons_id'; $alias = 'activity_reasons_id';
} elseif ($data['level'] === 'categories') { } elseif ('categories' === $data['level']) {
$elem = 'category.id'; $elem = 'category.id';
$alias = 'activity_categories_id'; $alias = 'activity_categories_id';
} else { } else {
throw new \RuntimeException('The data provided are not recognized.'); throw new RuntimeException('The data provided are not recognized.');
} }
$qb->addSelect($elem.' as '.$alias); $qb->addSelect($elem . ' as ' . $alias);
// make a jointure only if needed // make a jointure only if needed
$join = $qb->getDQLPart('join'); $join = $qb->getDQLPart('join');
if ( if (
(array_key_exists('activity', $join) (
&& array_key_exists('activity', $join)
!$this->checkJoinAlreadyDefined($join['activity'], 'reasons') && !$this->checkJoinAlreadyDefined($join['activity'], 'reasons')
) )
OR or (!array_key_exists('activity', $join))
(! array_key_exists('activity', $join))
) { ) {
$qb->add( $qb->add(
'join', 'join',
[ [
'activity' => new Join(Join::INNER_JOIN, 'activity.reasons', 'reasons') 'activity' => new Join(Join::INNER_JOIN, 'activity.reasons', 'reasons'),
], ],
true true
); );
} }
// join category if necessary // join category if necessary
if ($alias === 'activity_categories_id') { if ('activity_categories_id' === $alias) {
// add join only if needed // add join only if needed
if (!$this->checkJoinAlreadyDefined($qb->getDQLPart('join')['activity'], 'category')) { if (!$this->checkJoinAlreadyDefined($qb->getDQLPart('join')['activity'], 'category')) {
$qb->join('reasons.category', 'category'); $qb->join('reasons.category', 'category');
@@ -88,24 +101,6 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali
} }
} }
/**
* Check if a join between Activity and another alias
*
* @param Join[] $joins
* @param string $alias the alias to search for
* @return boolean
*/
private function checkJoinAlreadyDefined(array $joins, $alias)
{
foreach ($joins as $join) {
if ($join->getAlias() === $alias) {
return true;
}
}
return false;
}
public function applyOn() public function applyOn()
{ {
return 'activity'; return 'activity';
@@ -118,52 +113,37 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali
ChoiceType::class, ChoiceType::class,
[ [
'choices' => [ 'choices' => [
'By reason' => 'reasons', 'By reason' => 'reasons',
'By category of reason' => 'categories' 'By category of reason' => 'categories',
], ],
'multiple' => false, 'multiple' => false,
'expanded' => true, 'expanded' => true,
'label' => "Reason's level" 'label' => "Reason's level",
] ]
); );
} }
public function validateForm($data, ExecutionContextInterface $context)
{
if ($data['level'] === null) {
$context
->buildViolation("The reasons's level should not be empty.")
->addViolation();
}
}
public function getTitle()
{
return 'Aggregate by activity reason';
}
public function addRole()
{
return new Role(ActivityStatsVoter::STATS);
}
public function getLabels($key, array $values, $data) public function getLabels($key, array $values, $data)
{ {
// for performance reason, we load data from db only once // for performance reason, we load data from db only once
switch ($data['level']) { switch ($data['level']) {
case 'reasons': case 'reasons':
$this->activityReasonRepository->findBy(['id' => $values]); $this->activityReasonRepository->findBy(['id' => $values]);
break; break;
case 'categories': case 'categories':
$this->activityReasonCategoryRepository->findBy(['id' => $values]); $this->activityReasonCategoryRepository->findBy(['id' => $values]);
break; break;
default: default:
throw new \RuntimeException(sprintf("The level data '%s' is invalid.", $data['level'])); throw new RuntimeException(sprintf("The level data '%s' is invalid.", $data['level']));
} }
return function($value) use ($data) { return function ($value) use ($data) {
if ($value === '_header') { if ('_header' === $value) {
return $data['level'] === 'reasons' ? 'Group by reasons' : 'Group by categories of reason'; return 'reasons' === $data['level'] ? 'Group by reasons' : 'Group by categories of reason';
} }
switch ($data['level']) { switch ($data['level']) {
@@ -171,32 +151,63 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali
$r = $this->activityReasonRepository->find($value); $r = $this->activityReasonRepository->find($value);
return sprintf( return sprintf(
"%s > %s", '%s > %s',
$this->translatableStringHelper->localize($r->getCategory()->getName()), $this->translatableStringHelper->localize($r->getCategory()->getName()),
$this->translatableStringHelper->localize($r->getName()) $this->translatableStringHelper->localize($r->getName())
); );
case 'categories': case 'categories':
$c = $this->activityReasonCategoryRepository->find($value); $c = $this->activityReasonCategoryRepository->find($value);
return $this->translatableStringHelper->localize($c->getName()); return $this->translatableStringHelper->localize($c->getName());
} }
}; };
} }
public function getQueryKeys($data) public function getQueryKeys($data)
{ {
// add select element // add select element
if ($data['level'] === 'reasons') { if ('reasons' === $data['level']) {
return array('activity_reasons_id'); return ['activity_reasons_id'];
} }
if ($data['level'] === 'categories') { if ('categories' === $data['level']) {
return array ('activity_categories_id'); return ['activity_categories_id'];
} }
throw new \RuntimeException('The data provided are not recognised.'); throw new RuntimeException('The data provided are not recognised.');
} }
public function getTitle()
{
return 'Aggregate by activity reason';
}
public function validateForm($data, ExecutionContextInterface $context)
{
if (null === $data['level']) {
$context
->buildViolation("The reasons's level should not be empty.")
->addViolation();
}
}
/**
* Check if a join between Activity and another alias.
*
* @param Join[] $joins
* @param string $alias the alias to search for
*
* @return bool
*/
private function checkJoinAlreadyDefined(array $joins, $alias)
{
foreach ($joins as $join) {
if ($join->getAlias() === $alias) {
return true;
}
}
return false;
}
} }

View File

@@ -1,26 +1,34 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Aggregator; namespace Chill\ActivityBundle\Export\Aggregator;
use Chill\ActivityBundle\Repository\ActivityTypeRepository; use Chill\ActivityBundle\Repository\ActivityTypeRepository;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\QueryBuilder;
use Chill\MainBundle\Export\AggregatorInterface;
use Symfony\Component\Security\Core\Role\Role;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Closure;
use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
class ActivityTypeAggregator implements AggregatorInterface class ActivityTypeAggregator implements AggregatorInterface
{ {
public const KEY = 'activity_type_aggregator';
protected ActivityTypeRepository $activityTypeRepository; protected ActivityTypeRepository $activityTypeRepository;
protected TranslatableStringHelperInterface $translatableStringHelper; protected TranslatableStringHelperInterface $translatableStringHelper;
public const KEY = 'activity_type_aggregator';
public function __construct( public function __construct(
ActivityTypeRepository $activityTypeRepository, ActivityTypeRepository $activityTypeRepository,
TranslatableStringHelperInterface $translatableStringHelper TranslatableStringHelperInterface $translatableStringHelper
@@ -29,6 +37,11 @@ class ActivityTypeAggregator implements AggregatorInterface
$this->translatableStringHelper = $translatableStringHelper; $this->translatableStringHelper = $translatableStringHelper;
} }
public function addRole()
{
return new Role(ActivityStatsVoter::STATS);
}
public function alterQuery(QueryBuilder $qb, $data) public function alterQuery(QueryBuilder $qb, $data)
{ {
// add select element // add select element
@@ -38,24 +51,6 @@ class ActivityTypeAggregator implements AggregatorInterface
$qb->addGroupBy(self::KEY); $qb->addGroupBy(self::KEY);
} }
/**
* Check if a join between Activity and another alias
*
* @param Join[] $joins
* @param string $alias the alias to search for
* @return boolean
*/
private function checkJoinAlreadyDefined(array $joins, $alias)
{
foreach ($joins as $join) {
if ($join->getAlias() === $alias) {
return true;
}
}
return false;
}
public function applyOn() public function applyOn()
{ {
return 'activity'; return 'activity';
@@ -66,23 +61,13 @@ class ActivityTypeAggregator implements AggregatorInterface
// no form required for this aggregator // no form required for this aggregator
} }
public function getTitle() public function getLabels($key, array $values, $data): Closure
{
return 'Aggregate by activity type';
}
public function addRole()
{
return new Role(ActivityStatsVoter::STATS);
}
public function getLabels($key, array $values, $data): \Closure
{ {
// for performance reason, we load data from db only once // for performance reason, we load data from db only once
$this->activityTypeRepository->findBy(['id' => $values]); $this->activityTypeRepository->findBy(['id' => $values]);
return function($value): string { return function ($value): string {
if ($value === '_header') { if ('_header' === $value) {
return 'Activity type'; return 'Activity type';
} }
@@ -97,4 +82,27 @@ class ActivityTypeAggregator implements AggregatorInterface
return [self::KEY]; return [self::KEY];
} }
public function getTitle()
{
return 'Aggregate by activity type';
}
/**
* Check if a join between Activity and another alias.
*
* @param Join[] $joins
* @param string $alias the alias to search for
*
* @return bool
*/
private function checkJoinAlreadyDefined(array $joins, $alias)
{
foreach ($joins as $join) {
if ($join->getAlias() === $alias) {
return true;
}
}
return false;
}
} }

View File

@@ -1,13 +1,21 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Aggregator; namespace Chill\ActivityBundle\Export\Aggregator;
use Chill\MainBundle\Repository\UserRepository;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\QueryBuilder;
use Chill\MainBundle\Export\AggregatorInterface;
use Symfony\Component\Security\Core\Role\Role;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Repository\UserRepository;
use Closure;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
class ActivityUserAggregator implements AggregatorInterface class ActivityUserAggregator implements AggregatorInterface
{ {
@@ -45,13 +53,13 @@ class ActivityUserAggregator implements AggregatorInterface
// nothing to add // nothing to add
} }
public function getLabels($key, $values, $data): \Closure public function getLabels($key, $values, $data): Closure
{ {
// preload users at once // preload users at once
$this->userRepository->findBy(['id' => $values]); $this->userRepository->findBy(['id' => $values]);
return function($value) { return function ($value) {
if ($value === '_header') { if ('_header' === $value) {
return 'activity user'; return 'activity user';
} }
@@ -61,7 +69,7 @@ class ActivityUserAggregator implements AggregatorInterface
public function getQueryKeys($data) public function getQueryKeys($data)
{ {
return [ self::KEY ]; return [self::KEY];
} }
public function getTitle(): string public function getTitle(): string

View File

@@ -1,16 +1,24 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Export; namespace Chill\ActivityBundle\Export\Export;
use Chill\ActivityBundle\Repository\ActivityRepository; use Chill\ActivityBundle\Repository\ActivityRepository;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\ExportInterface;
use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\FormatterInterface;
use Doctrine\ORM\Query;
use LogicException;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\Role;
use Doctrine\ORM\Query;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
class CountActivity implements ExportInterface class CountActivity implements ExportInterface
{ {
@@ -24,7 +32,11 @@ class CountActivity implements ExportInterface
public function buildForm(FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder)
{ {
}
public function getAllowedFormattersTypes()
{
return [FormatterInterface::TYPE_TABULAR];
} }
public function getDescription() public function getDescription()
@@ -32,6 +44,25 @@ class CountActivity implements ExportInterface
return 'Count activities by various parameters.'; return 'Count activities by various parameters.';
} }
public function getLabels($key, array $values, $data)
{
if ('export_count_activity' !== $key) {
throw new LogicException("the key {$key} is not used by this export");
}
return static fn ($value) => '_header' === $value ? 'Number of activities' : $value;
}
public function getQueryKeys($data)
{
return ['export_count_activity'];
}
public function getResult($qb, $data)
{
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
public function getTitle() public function getTitle()
{ {
return 'Count activities'; return 'Count activities';
@@ -42,9 +73,9 @@ class CountActivity implements ExportInterface
return 'activity'; return 'activity';
} }
public function initiateQuery(array $requiredModifiers, array $acl, array $data = array()) public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{ {
$centers = array_map(static fn($el) => $el['center'], $acl); $centers = array_map(static fn ($el) => $el['center'], $acl);
$qb = $this $qb = $this
->activityRepository ->activityRepository
@@ -59,38 +90,13 @@ class CountActivity implements ExportInterface
return $qb; return $qb;
} }
public function supportsModifiers()
{
return ['person', 'activity'];
}
public function requiredRole() public function requiredRole()
{ {
return new Role(ActivityStatsVoter::STATS); return new Role(ActivityStatsVoter::STATS);
} }
public function getAllowedFormattersTypes() public function supportsModifiers()
{ {
return [FormatterInterface::TYPE_TABULAR]; return ['person', 'activity'];
} }
public function getLabels($key, array $values, $data)
{
if ($key !== 'export_count_activity') {
throw new \LogicException("the key $key is not used by this export");
}
return static fn($value) => $value === '_header' ? 'Number of activities' : $value;
}
public function getQueryKeys($data)
{
return ['export_count_activity'];
}
public function getResult($qb, $data)
{
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
} }

View File

@@ -1,35 +1,38 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Export; namespace Chill\ActivityBundle\Export\Export;
use Chill\ActivityBundle\Repository\ActivityRepository;
use Chill\MainBundle\Export\ListInterface;
use Chill\ActivityBundle\Entity\ActivityReason; use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\ActivityBundle\Repository\ActivityRepository;
use Doctrine\DBAL\Exception\InvalidArgumentException;
use Symfony\Component\Security\Core\Role\Role;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Symfony\Component\Form\FormBuilderInterface; use Chill\MainBundle\Export\FormatterInterface;
use Chill\MainBundle\Export\ListInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use DateTime;
use Doctrine\DBAL\Exception\InvalidArgumentException;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Translation\TranslatorInterface; use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Validator\Constraints\Callback; use Symfony\Component\Validator\Constraints\Callback;
use Doctrine\ORM\Query;
use Chill\MainBundle\Export\FormatterInterface;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface;
use function array_key_exists;
class ListActivity implements ListInterface class ListActivity implements ListInterface
{ {
private ActivityRepository $activityRepository;
protected EntityManagerInterface $entityManager; protected EntityManagerInterface $entityManager;
protected TranslatorInterface $translator;
protected TranslatableStringHelperInterface $translatableStringHelper;
protected array $fields = [ protected array $fields = [
'id', 'id',
'date', 'date',
@@ -41,9 +44,15 @@ class ListActivity implements ListInterface
'type_name', 'type_name',
'person_firstname', 'person_firstname',
'person_lastname', 'person_lastname',
'person_id' 'person_id',
]; ];
protected TranslatableStringHelperInterface $translatableStringHelper;
protected TranslatorInterface $translator;
private ActivityRepository $activityRepository;
public function __construct( public function __construct(
EntityManagerInterface $em, EntityManagerInterface $em,
TranslatorInterface $translator, TranslatorInterface $translator,
@@ -62,18 +71,17 @@ class ListActivity implements ListInterface
'multiple' => true, 'multiple' => true,
'expanded' => true, 'expanded' => true,
'choices' => array_combine($this->fields, $this->fields), 'choices' => array_combine($this->fields, $this->fields),
'label' => 'Fields to include in export', 'label' => 'Fields to include in export',
'constraints' => [new Callback([ 'constraints' => [new Callback([
'callback' => function($selected, ExecutionContextInterface $context) { 'callback' => function ($selected, ExecutionContextInterface $context) {
if (count($selected) === 0) { if (count($selected) === 0) {
$context->buildViolation('You must select at least one element') $context->buildViolation('You must select at least one element')
->atPath('fields') ->atPath('fields')
->addViolation(); ->addViolation();
} }
} },
])] ])],
]); ]);
} }
public function getAllowedFormattersTypes() public function getAllowedFormattersTypes()
@@ -83,69 +91,72 @@ class ListActivity implements ListInterface
public function getDescription() public function getDescription()
{ {
return "List activities"; return 'List activities';
} }
public function getLabels($key, array $values, $data) public function getLabels($key, array $values, $data)
{ {
switch ($key) switch ($key) {
{ case 'date':
case 'date' : return static function ($value) {
return static function($value) { if ('_header' === $value) {
if ($value === '_header') {
return 'date'; return 'date';
} }
$date = \DateTime::createFromFormat('Y-m-d H:i:s', $value); $date = DateTime::createFromFormat('Y-m-d H:i:s', $value);
return $date->format('d-m-Y'); return $date->format('d-m-Y');
}; };
case 'attendee': case 'attendee':
return static function($value) { return static function ($value) {
if ($value === '_header') { if ('_header' === $value) {
return 'attendee'; return 'attendee';
} }
return $value ? 1 : 0; return $value ? 1 : 0;
}; };
case 'list_reasons' :
case 'list_reasons':
$activityRepository = $this->activityRepository; $activityRepository = $this->activityRepository;
return function($value) use ($activityRepository): string { return function ($value) use ($activityRepository): string {
if ($value === '_header') { if ('_header' === $value) {
return 'activity reasons'; return 'activity reasons';
} }
$activity = $activityRepository->find($value); $activity = $activityRepository->find($value);
return implode(", ", array_map(function(ActivityReason $r) { return implode(', ', array_map(function (ActivityReason $r) {
return '"' .
return '"'.
$this->translatableStringHelper->localize($r->getCategory()->getName()) $this->translatableStringHelper->localize($r->getCategory()->getName())
.' > '. . ' > ' .
$this->translatableStringHelper->localize($r->getName()) $this->translatableStringHelper->localize($r->getName())
.'"'; . '"';
}, $activity->getReasons()->toArray())); }, $activity->getReasons()->toArray()));
}; };
case 'circle_name' :
return function($value) { case 'circle_name':
if ($value === '_header') { return function ($value) {
if ('_header' === $value) {
return 'circle'; return 'circle';
} }
return $this->translatableStringHelper->localize(json_decode($value, true)); return $this->translatableStringHelper->localize(json_decode($value, true));
}; };
case 'type_name' :
return function($value) { case 'type_name':
if ($value === '_header') { return function ($value) {
if ('_header' === $value) {
return 'activity type'; return 'activity type';
} }
return $this->translatableStringHelper->localize(json_decode($value, true)); return $this->translatableStringHelper->localize(json_decode($value, true));
}; };
default: default:
return static function($value) use ($key) { return static function ($value) use ($key) {
if ($value === '_header') { if ('_header' === $value) {
return $key; return $key;
} }
@@ -176,59 +187,75 @@ class ListActivity implements ListInterface
public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{ {
$centers = array_map(function($el) { return $el['center']; }, $acl); $centers = array_map(function ($el) { return $el['center']; }, $acl);
// throw an error if any fields are present // throw an error if any fields are present
if (!\array_key_exists('fields', $data)) { if (!array_key_exists('fields', $data)) {
throw new InvalidArgumentException('Any fields have been checked.'); throw new InvalidArgumentException('Any fields have been checked.');
} }
$qb = $this->entityManager->createQueryBuilder(); $qb = $this->entityManager->createQueryBuilder();
$qb $qb
->from('ChillActivityBundle:Activity', 'activity') ->from('ChillActivityBundle:Activity', 'activity')
->join('activity.person', 'person') ->join('activity.person', 'person')
->join('person.center', 'center') ->join('person.center', 'center')
->andWhere('center IN (:authorized_centers)') ->andWhere('center IN (:authorized_centers)')
->setParameter('authorized_centers', $centers); ->setParameter('authorized_centers', $centers);
foreach ($this->fields as $f) { foreach ($this->fields as $f) {
if (in_array($f, $data['fields'])) { if (in_array($f, $data['fields'])) {
switch ($f) { switch ($f) {
case 'id': case 'id':
$qb->addSelect('activity.id AS id'); $qb->addSelect('activity.id AS id');
break; break;
case 'person_firstname': case 'person_firstname':
$qb->addSelect('person.firstName AS person_firstname'); $qb->addSelect('person.firstName AS person_firstname');
break; break;
case 'person_lastname': case 'person_lastname':
$qb->addSelect('person.lastName AS person_lastname'); $qb->addSelect('person.lastName AS person_lastname');
break; break;
case 'person_id': case 'person_id':
$qb->addSelect('person.id AS person_id'); $qb->addSelect('person.id AS person_id');
break; break;
case 'user_username': case 'user_username':
$qb->join('activity.user', 'user'); $qb->join('activity.user', 'user');
$qb->addSelect('user.username AS user_username'); $qb->addSelect('user.username AS user_username');
break; break;
case 'circle_name': case 'circle_name':
$qb->join('activity.scope', 'circle'); $qb->join('activity.scope', 'circle');
$qb->addSelect('circle.name AS circle_name'); $qb->addSelect('circle.name AS circle_name');
break; break;
case 'type_name': case 'type_name':
$qb->join('activity.type', 'type'); $qb->join('activity.type', 'type');
$qb->addSelect('type.name AS type_name'); $qb->addSelect('type.name AS type_name');
break; break;
case 'list_reasons': case 'list_reasons':
// this is a trick... The reasons is filled with the // this is a trick... The reasons is filled with the
// activity id which will be used to load reasons // activity id which will be used to load reasons
$qb->addSelect('activity.id AS list_reasons'); $qb->addSelect('activity.id AS list_reasons');
break; break;
default: default:
$qb->addSelect(sprintf('activity.%s as %s', $f, $f)); $qb->addSelect(sprintf('activity.%s as %s', $f, $f));
break; break;
} }
} }
} }
@@ -244,5 +271,4 @@ class ListActivity implements ListInterface
{ {
return ['activity', 'person']; return ['activity', 'person'];
} }
} }

View File

@@ -1,16 +1,24 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Export; namespace Chill\ActivityBundle\Export\Export;
use Chill\ActivityBundle\Repository\ActivityRepository; use Chill\ActivityBundle\Repository\ActivityRepository;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\ExportInterface;
use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\FormatterInterface;
use Doctrine\ORM\Query;
use LogicException;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\Role;
use Doctrine\ORM\Query;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
/** /**
* This export allow to compute stats on activity duration. * This export allow to compute stats on activity duration.
@@ -19,8 +27,6 @@ use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
*/ */
class StatActivityDuration implements ExportInterface class StatActivityDuration implements ExportInterface
{ {
private ActivityRepository $activityRepository;
public const SUM = 'sum'; public const SUM = 'sum';
/** /**
@@ -28,6 +34,8 @@ class StatActivityDuration implements ExportInterface
*/ */
protected string $action; protected string $action;
private ActivityRepository $activityRepository;
/** /**
* @param string $action the stat to perform * @param string $action the stat to perform
*/ */
@@ -41,59 +49,6 @@ class StatActivityDuration implements ExportInterface
public function buildForm(FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder)
{ {
}
public function getDescription()
{
if ($this->action === self::SUM) {
return 'Sum activities duration by various parameters.';
}
}
public function getTitle()
{
if ($this->action === self::SUM) {
return 'Sum activity duration';
}
}
public function getType()
{
return 'activity';
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{
$centers = array_map(
static fn(array $el): string => $el['center'],
$acl
);
$qb = $this->activityRepository->createQueryBuilder('activity');
$select = null;
if ($this->action === self::SUM) {
$select = 'SUM(activity.durationTime) AS export_stat_activity';
}
return $qb->select($select)
->join('activity.person', 'person')
->join('person.center', 'center')
->where($qb->expr()->in('center', ':centers'))
->setParameter(':centers', $centers);
}
public function supportsModifiers()
{
return ['person', 'activity'];
}
public function requiredRole()
{
return new Role(ActivityStatsVoter::STATS);
} }
public function getAllowedFormattersTypes() public function getAllowedFormattersTypes()
@@ -101,15 +56,22 @@ class StatActivityDuration implements ExportInterface
return [FormatterInterface::TYPE_TABULAR]; return [FormatterInterface::TYPE_TABULAR];
} }
public function getDescription()
{
if (self::SUM === $this->action) {
return 'Sum activities duration by various parameters.';
}
}
public function getLabels($key, array $values, $data) public function getLabels($key, array $values, $data)
{ {
if ($key !== 'export_stat_activity') { if ('export_stat_activity' !== $key) {
throw new \LogicException(sprintf('The key %s is not used by this export', $key)); throw new LogicException(sprintf('The key %s is not used by this export', $key));
} }
$header = $this->action === self::SUM ? 'Sum of activities duration' : false; $header = self::SUM === $this->action ? 'Sum of activities duration' : false;
return static fn(string $value) => $value === '_header' ? $header : $value; return static fn (string $value) => '_header' === $value ? $header : $value;
} }
public function getQueryKeys($data) public function getQueryKeys($data)
@@ -122,4 +84,47 @@ class StatActivityDuration implements ExportInterface
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR); return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
} }
public function getTitle()
{
if (self::SUM === $this->action) {
return 'Sum activity duration';
}
}
public function getType()
{
return 'activity';
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{
$centers = array_map(
static fn (array $el): string => $el['center'],
$acl
);
$qb = $this->activityRepository->createQueryBuilder('activity');
$select = null;
if (self::SUM === $this->action) {
$select = 'SUM(activity.durationTime) AS export_stat_activity';
}
return $qb->select($select)
->join('activity.person', 'person')
->join('person.center', 'center')
->where($qb->expr()->in('center', ':centers'))
->setParameter(':centers', $centers);
}
public function requiredRole()
{
return new Role(ActivityStatsVoter::STATS);
}
public function supportsModifiers()
{
return ['person', 'activity'];
}
} }

View File

@@ -1,25 +1,33 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter; namespace Chill\ActivityBundle\Export\Filter;
use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\Export\FilterType;
use DateTime;
use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents; use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\FormError;
use Chill\MainBundle\Form\Type\Export\FilterType;
use Doctrine\ORM\Query\Expr;
use Symfony\Component\Translation\TranslatorInterface; use Symfony\Component\Translation\TranslatorInterface;
class ActivityDateFilter implements FilterInterface class ActivityDateFilter implements FilterInterface
{ {
protected TranslatorInterface $translator; protected TranslatorInterface $translator;
function __construct(TranslatorInterface $translator) public function __construct(TranslatorInterface $translator)
{ {
$this->translator = $translator; $this->translator = $translator;
} }
@@ -32,8 +40,11 @@ class ActivityDateFilter implements FilterInterface
public function alterQuery(QueryBuilder $qb, $data) public function alterQuery(QueryBuilder $qb, $data)
{ {
$where = $qb->getDQLPart('where'); $where = $qb->getDQLPart('where');
$clause = $qb->expr()->between('activity.date', ':date_from', $clause = $qb->expr()->between(
':date_to'); 'activity.date',
':date_from',
':date_to'
);
if ($where instanceof Expr\Andx) { if ($where instanceof Expr\Andx) {
$where->add($clause); $where->add($clause);
@@ -58,9 +69,9 @@ class ActivityDateFilter implements FilterInterface
DateType::class, DateType::class,
[ [
'label' => 'Activities after this date', 'label' => 'Activities after this date',
'data' => new \DateTime(), 'data' => new DateTime(),
'attr' => ['class' => 'datepicker'], 'attr' => ['class' => 'datepicker'],
'widget'=> 'single_text', 'widget' => 'single_text',
'format' => 'dd-MM-yyyy', 'format' => 'dd-MM-yyyy',
] ]
); );
@@ -70,46 +81,49 @@ class ActivityDateFilter implements FilterInterface
DateType::class, DateType::class,
[ [
'label' => 'Activities before this date', 'label' => 'Activities before this date',
'data' => new \DateTime(), 'data' => new DateTime(),
'attr' => ['class' => 'datepicker'], 'attr' => ['class' => 'datepicker'],
'widget'=> 'single_text', 'widget' => 'single_text',
'format' => 'dd-MM-yyyy', 'format' => 'dd-MM-yyyy',
] ]
); );
$builder->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event) { $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
/* @var $filterForm \Symfony\Component\Form\FormInterface */ /* @var $filterForm \Symfony\Component\Form\FormInterface */
$filterForm = $event->getForm()->getParent(); $filterForm = $event->getForm()->getParent();
$enabled = $filterForm->get(FilterType::ENABLED_FIELD)->getData(); $enabled = $filterForm->get(FilterType::ENABLED_FIELD)->getData();
if ($enabled === true) { if (true === $enabled) {
// if the filter is enabled, add some validation // if the filter is enabled, add some validation
$form = $event->getForm(); $form = $event->getForm();
$date_from = $form->get('date_from')->getData(); $date_from = $form->get('date_from')->getData();
$date_to = $form->get('date_to')->getData(); $date_to = $form->get('date_to')->getData();
// check that fields are not empty // check that fields are not empty
if ($date_from === null) { if (null === $date_from) {
$form->get('date_from')->addError(new FormError( $form->get('date_from')->addError(new FormError(
$this->translator->trans('This field ' $this->translator->trans('This field '
. 'should not be empty'))); . 'should not be empty')
));
} }
if ($date_to === null) {
if (null === $date_to) {
$form->get('date_to')->addError(new FormError( $form->get('date_to')->addError(new FormError(
$this->translator->trans('This field ' $this->translator->trans('This field '
. 'should not be empty'))); . 'should not be empty')
));
} }
// check that date_from is before date_to // check that date_from is before date_to
if ( if (
($date_from !== null && $date_to !== null) (null !== $date_from && null !== $date_to)
&& && $date_from >= $date_to
$date_from >= $date_to
) { ) {
$form->get('date_to')->addError(new FormError( $form->get('date_to')->addError(new FormError(
$this->translator->trans('This date should be after ' $this->translator->trans('This date should be after '
. 'the date given in "Implied in an activity after ' . 'the date given in "Implied in an activity after '
. 'this date" field'))); . 'this date" field')
));
} }
} }
}); });
@@ -121,8 +135,8 @@ class ActivityDateFilter implements FilterInterface
'Filtered by date of activity: only between %date_from% and %date_to%', 'Filtered by date of activity: only between %date_from% and %date_to%',
[ [
'%date_from%' => $data['date_from']->format('d-m-Y'), '%date_from%' => $data['date_from']->format('d-m-Y'),
'%date_to%' => $data['date_to']->format('d-m-Y') '%date_to%' => $data['date_to']->format('d-m-Y'),
] ],
]; ];
} }
@@ -130,5 +144,4 @@ class ActivityDateFilter implements FilterInterface
{ {
return 'Filtered by date activity'; return 'Filtered by date activity';
} }
} }

View File

@@ -1,30 +1,37 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter; namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Repository\ActivityReasonRepository;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Chill\ActivityBundle\Entity\ActivityReason; use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\ActivityBundle\Repository\ActivityReasonRepository;
use Doctrine\ORM\Query\Expr;
use Symfony\Component\Security\Core\Role\Role;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Doctrine\ORM\Query\Expr\Join;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Chill\MainBundle\Export\ExportElementValidatedInterface; use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
class ActivityReasonFilter implements FilterInterface, ExportElementValidatedInterface class ActivityReasonFilter implements FilterInterface, ExportElementValidatedInterface
{ {
protected TranslatableStringHelperInterface $translatableStringHelper;
protected ActivityReasonRepository $activityReasonRepository; protected ActivityReasonRepository $activityReasonRepository;
protected TranslatableStringHelperInterface $translatableStringHelper;
public function __construct( public function __construct(
TranslatableStringHelper $helper, TranslatableStringHelper $helper,
ActivityReasonRepository $activityReasonRepository ActivityReasonRepository $activityReasonRepository
@@ -33,26 +40,30 @@ class ActivityReasonFilter implements FilterInterface, ExportElementValidatedInt
$this->activityReasonRepository = $activityReasonRepository; $this->activityReasonRepository = $activityReasonRepository;
} }
public function addRole()
{
return new Role(ActivityStatsVoter::STATS);
}
public function alterQuery(QueryBuilder $qb, $data) public function alterQuery(QueryBuilder $qb, $data)
{ {
$where = $qb->getDQLPart('where'); $where = $qb->getDQLPart('where');
$join = $qb->getDQLPart('join'); $join = $qb->getDQLPart('join');
$clause = $qb->expr()->in('reasons', ':selected_activity_reasons'); $clause = $qb->expr()->in('reasons', ':selected_activity_reasons');
//dump($join); //dump($join);
// add a join to reasons only if needed // add a join to reasons only if needed
if ( if (
(array_key_exists('activity', $join) (
&& array_key_exists('activity', $join)
!$this->checkJoinAlreadyDefined($join['activity'], 'reasons') && !$this->checkJoinAlreadyDefined($join['activity'], 'reasons')
) )
|| || (!array_key_exists('activity', $join))
(! array_key_exists('activity', $join))
) { ) {
$qb->add( $qb->add(
'join', 'join',
array('activity' => new Join(Join::INNER_JOIN, 'activity.reasons', 'reasons')), ['activity' => new Join(Join::INNER_JOIN, 'activity.reasons', 'reasons')],
true true
); );
} }
if ($where instanceof Expr\Andx) { if ($where instanceof Expr\Andx) {
@@ -65,11 +76,57 @@ class ActivityReasonFilter implements FilterInterface, ExportElementValidatedInt
$qb->setParameter('selected_activity_reasons', $data['reasons']); $qb->setParameter('selected_activity_reasons', $data['reasons']);
} }
public function applyOn()
{
return 'activity';
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('reasons', EntityType::class, [
'class' => ActivityReason::class,
'choice_label' => fn (ActivityReason $reason) => $this->translatableStringHelper->localize($reason->getName()),
'group_by' => fn (ActivityReason $reason) => $this->translatableStringHelper->localize($reason->getCategory()->getName()),
'multiple' => true,
'expanded' => false,
]);
}
public function describeAction($data, $format = 'string')
{
// collect all the reasons'name used in this filter in one array
$reasonsNames = array_map(
fn (ActivityReason $r): string => '"' . $this->translatableStringHelper->localize($r->getName()) . '"',
$this->activityReasonRepository->findBy(['id' => $data['reasons']->toArray()])
);
return [
'Filtered by reasons: only %list%',
[
'%list%' => implode(', ', $reasonsNames),
],
];
}
public function getTitle()
{
return 'Filter by reason';
}
public function validateForm($data, ExecutionContextInterface $context)
{
if (null === $data['reasons'] || count($data['reasons']) === 0) {
$context
->buildViolation('At least one reason must be chosen')
->addViolation();
}
}
/** /**
* Check if a join between Activity and Reason is already defined * Check if a join between Activity and Reason is already defined.
* *
* @param Join[] $joins * @param Join[] $joins
* @return boolean * @param mixed $alias
*/ */
private function checkJoinAlreadyDefined(array $joins, $alias): bool private function checkJoinAlreadyDefined(array $joins, $alias): bool
{ {
@@ -81,55 +138,4 @@ class ActivityReasonFilter implements FilterInterface, ExportElementValidatedInt
return false; return false;
} }
public function applyOn()
{
return 'activity';
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('reasons', EntityType::class, [
'class' => ActivityReason::class,
'choice_label' => fn(ActivityReason $reason) => $this->translatableStringHelper->localize($reason->getName()),
'group_by' => fn(ActivityReason $reason) => $this->translatableStringHelper->localize($reason->getCategory()->getName()),
'multiple' => true,
'expanded' => false
]);
}
public function validateForm($data, ExecutionContextInterface $context)
{
if ($data['reasons'] === null || count($data['reasons']) === 0) {
$context
->buildViolation('At least one reason must be chosen')
->addViolation();
}
}
public function getTitle()
{
return 'Filter by reason';
}
public function addRole()
{
return new Role(ActivityStatsVoter::STATS);
}
public function describeAction($data, $format = 'string')
{
// collect all the reasons'name used in this filter in one array
$reasonsNames = array_map(
fn(ActivityReason $r): string => '"' . $this->translatableStringHelper->localize($r->getName()) . '"',
$this->activityReasonRepository->findBy(array('id' => $data['reasons']->toArray()))
);
return [
'Filtered by reasons: only %list%',
[
'%list%' => implode(", ", $reasonsNames),
]
];
}
} }

View File

@@ -1,29 +1,36 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter; namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Entity\ActivityType;
use Chill\ActivityBundle\Repository\ActivityTypeRepository; use Chill\ActivityBundle\Repository\ActivityTypeRepository;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr;
use Symfony\Component\Security\Core\Role\Role;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\ActivityBundle\Entity\ActivityType;
class ActivityTypeFilter implements FilterInterface, ExportElementValidatedInterface class ActivityTypeFilter implements FilterInterface, ExportElementValidatedInterface
{ {
protected TranslatableStringHelperInterface $translatableStringHelper;
protected ActivityTypeRepository $activityTypeRepository; protected ActivityTypeRepository $activityTypeRepository;
protected TranslatableStringHelperInterface $translatableStringHelper;
public function __construct( public function __construct(
TranslatableStringHelperInterface $translatableStringHelper, TranslatableStringHelperInterface $translatableStringHelper,
ActivityTypeRepository $activityTypeRepository ActivityTypeRepository $activityTypeRepository
@@ -32,6 +39,11 @@ class ActivityTypeFilter implements FilterInterface, ExportElementValidatedInter
$this->activityTypeRepository = $activityTypeRepository; $this->activityTypeRepository = $activityTypeRepository;
} }
public function addRole()
{
return new Role(ActivityStatsVoter::STATS);
}
public function alterQuery(QueryBuilder $qb, $data) public function alterQuery(QueryBuilder $qb, $data)
{ {
$where = $qb->getDQLPart('where'); $where = $qb->getDQLPart('where');
@@ -47,23 +59,6 @@ class ActivityTypeFilter implements FilterInterface, ExportElementValidatedInter
$qb->setParameter('selected_activity_types', $data['types']); $qb->setParameter('selected_activity_types', $data['types']);
} }
/**
* Check if a join between Activity and Reason is already defined
*
* @param Join[] $joins
* @return boolean
*/
private function checkJoinAlreadyDefined(array $joins, $alias)
{
foreach ($joins as $join) {
if ($join->getAlias() === $alias) {
return true;
}
}
return false;
}
public function applyOn() public function applyOn()
{ {
return 'activity'; return 'activity';
@@ -76,20 +71,27 @@ class ActivityTypeFilter implements FilterInterface, ExportElementValidatedInter
EntityType::class, EntityType::class,
[ [
'class' => ActivityType::class, 'class' => ActivityType::class,
'choice_label' => fn(ActivityType $type) => $this->translatableStringHelper->localize($type->getName()), 'choice_label' => fn (ActivityType $type) => $this->translatableStringHelper->localize($type->getName()),
'multiple' => true, 'multiple' => true,
'expanded' => false 'expanded' => false,
] ]
); );
} }
public function validateForm($data, ExecutionContextInterface $context) public function describeAction($data, $format = 'string')
{ {
if ($data['types'] === null || count($data['types']) === 0) { // collect all the reasons'name used in this filter in one array
$context $reasonsNames = array_map(
->buildViolation('At least one type must be chosen') fn (ActivityType $t): string => '"' . $this->translatableStringHelper->localize($t->getName()) . '"',
->addViolation(); $this->activityTypeRepository->findBy(['id' => $data['types']->toArray()])
} );
return [
'Filtered by activity type: only %list%',
[
'%list%' => implode(', ', $reasonsNames),
],
];
} }
public function getTitle() public function getTitle()
@@ -97,24 +99,31 @@ class ActivityTypeFilter implements FilterInterface, ExportElementValidatedInter
return 'Filter by activity type'; return 'Filter by activity type';
} }
public function addRole() public function validateForm($data, ExecutionContextInterface $context)
{ {
return new Role(ActivityStatsVoter::STATS); if (null === $data['types'] || count($data['types']) === 0) {
$context
->buildViolation('At least one type must be chosen')
->addViolation();
}
} }
public function describeAction($data, $format = 'string') /**
* Check if a join between Activity and Reason is already defined.
*
* @param Join[] $joins
* @param mixed $alias
*
* @return bool
*/
private function checkJoinAlreadyDefined(array $joins, $alias)
{ {
// collect all the reasons'name used in this filter in one array foreach ($joins as $join) {
$reasonsNames = array_map( if ($join->getAlias() === $alias) {
fn(ActivityType $t): string => '"' . $this->translatableStringHelper->localize($t->getName()) . '"', return true;
$this->activityTypeRepository->findBy(['id' => $data['types']->toArray()]) }
); }
return [ return false;
'Filtered by activity type: only %list%',
[
'%list%' => implode(", ", $reasonsNames),
]
];
} }
} }

View File

@@ -1,35 +1,43 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter; namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\ActivityBundle\Repository\ActivityReasonRepository; use Chill\ActivityBundle\Repository\ActivityReasonRepository;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\Export\FilterType;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Chill\PersonBundle\Export\Declarations;
use DateTime;
use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents; use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\FormError;
use Chill\MainBundle\Form\Type\Export\FilterType;
use Doctrine\ORM\Query\Expr;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\PersonBundle\Export\Declarations;
use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormInterface;
use Symfony\Component\Translation\TranslatorInterface; use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
class PersonHavingActivityBetweenDateFilter implements FilterInterface, ExportElementValidatedInterface class PersonHavingActivityBetweenDateFilter implements FilterInterface, ExportElementValidatedInterface
{ {
protected TranslatableStringHelperInterface $translatableStringHelper;
protected ActivityReasonRepository $activityReasonRepository; protected ActivityReasonRepository $activityReasonRepository;
protected TranslatableStringHelperInterface $translatableStringHelper;
protected TranslatorInterface $translator; protected TranslatorInterface $translator;
public function __construct( public function __construct(
@@ -66,7 +74,8 @@ class PersonHavingActivityBetweenDateFilter implements FilterInterface, ExportEl
$sqb->andWhere( $sqb->andWhere(
$sqb->expr()->in( $sqb->expr()->in(
'reasons_person_having_activity', ':person_having_activity_reasons' 'reasons_person_having_activity',
':person_having_activity_reasons'
) )
); );
@@ -80,10 +89,14 @@ class PersonHavingActivityBetweenDateFilter implements FilterInterface, ExportEl
} }
$qb->add('where', $where); $qb->add('where', $where);
$qb->setParameter('person_having_activity_between_date_from', $qb->setParameter(
$data['date_from']); 'person_having_activity_between_date_from',
$qb->setParameter('person_having_activity_between_date_to', $data['date_from']
$data['date_to']); );
$qb->setParameter(
'person_having_activity_between_date_to',
$data['date_to']
);
$qb->setParameter('person_having_activity_reasons', $data['reasons']); $qb->setParameter('person_having_activity_reasons', $data['reasons']);
} }
@@ -96,76 +109,71 @@ class PersonHavingActivityBetweenDateFilter implements FilterInterface, ExportEl
{ {
$builder->add('date_from', DateType::class, [ $builder->add('date_from', DateType::class, [
'label' => 'Implied in an activity after this date', 'label' => 'Implied in an activity after this date',
'data' => new \DateTime(), 'data' => new DateTime(),
'attr' => ['class' => 'datepicker'], 'attr' => ['class' => 'datepicker'],
'widget'=> 'single_text', 'widget' => 'single_text',
'format' => 'dd-MM-yyyy', 'format' => 'dd-MM-yyyy',
]); ]);
$builder->add('date_to', DateType::class, [ $builder->add('date_to', DateType::class, [
'label' => 'Implied in an activity before this date', 'label' => 'Implied in an activity before this date',
'data' => new \DateTime(), 'data' => new DateTime(),
'attr' => ['class' => 'datepicker'], 'attr' => ['class' => 'datepicker'],
'widget'=> 'single_text', 'widget' => 'single_text',
'format' => 'dd-MM-yyyy', 'format' => 'dd-MM-yyyy',
]); ]);
$builder->add('reasons', EntityType::class, [ $builder->add('reasons', EntityType::class, [
'class' => ActivityReason::class, 'class' => ActivityReason::class,
'choice_label' => fn (ActivityReason $reason): ?string => $this->translatableStringHelper->localize($reason->getName()), 'choice_label' => fn (ActivityReason $reason): ?string => $this->translatableStringHelper->localize($reason->getName()),
'group_by' => fn(ActivityReason $reason): ?string => $this->translatableStringHelper->localize($reason->getCategory()->getName()), 'group_by' => fn (ActivityReason $reason): ?string => $this->translatableStringHelper->localize($reason->getCategory()->getName()),
'data' => $this->activityReasonRepository->findAll(), 'data' => $this->activityReasonRepository->findAll(),
'multiple' => true, 'multiple' => true,
'expanded' => false, 'expanded' => false,
'label' => 'Activity reasons for those activities' 'label' => 'Activity reasons for those activities',
]); ]);
$builder->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event) { $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
/* @var FormInterface $filterForm */ /* @var FormInterface $filterForm */
$filterForm = $event->getForm()->getParent(); $filterForm = $event->getForm()->getParent();
$enabled = $filterForm->get(FilterType::ENABLED_FIELD)->getData(); $enabled = $filterForm->get(FilterType::ENABLED_FIELD)->getData();
if ($enabled === true) { if (true === $enabled) {
// if the filter is enabled, add some validation // if the filter is enabled, add some validation
$form = $event->getForm(); $form = $event->getForm();
$date_from = $form->get('date_from')->getData(); $date_from = $form->get('date_from')->getData();
$date_to = $form->get('date_to')->getData(); $date_to = $form->get('date_to')->getData();
// check that fields are not empty // check that fields are not empty
if ($date_from === null) { if (null === $date_from) {
$form->get('date_from')->addError(new FormError( $form->get('date_from')->addError(new FormError(
$this->translator->trans('This field ' $this->translator->trans('This field '
. 'should not be empty'))); . 'should not be empty')
));
} }
if ($date_to === null) {
if (null === $date_to) {
$form->get('date_to')->addError(new FormError( $form->get('date_to')->addError(new FormError(
$this->translator->trans('This field ' $this->translator->trans('This field '
. 'should not be empty'))); . 'should not be empty')
));
} }
// check that date_from is before date_to // check that date_from is before date_to
if ( if (
($date_from !== null && $date_to !== null) (null !== $date_from && null !== $date_to)
&& && $date_from >= $date_to
$date_from >= $date_to
) { ) {
$form->get('date_to')->addError(new FormError( $form->get('date_to')->addError(new FormError(
$this->translator->trans('This date ' $this->translator->trans('This date '
. 'should be after the date given in "Implied in an ' . 'should be after the date given in "Implied in an '
. 'activity after this date" field'))); . 'activity after this date" field')
));
} }
} }
}); });
} }
public function validateForm($data, ExecutionContextInterface $context)
{
if ($data['reasons'] === null || count($data['reasons']) === 0) {
$context->buildViolation('At least one reason must be chosen')
->addViolation();
}
}
public function describeAction($data, $format = 'string') public function describeAction($data, $format = 'string')
{ {
return [ return [
@@ -173,15 +181,15 @@ class PersonHavingActivityBetweenDateFilter implements FilterInterface, ExportEl
. '%date_to% with reasons %reasons_name%', . '%date_to% with reasons %reasons_name%',
[ [
'%date_from%' => $data['date_from']->format('d-m-Y'), '%date_from%' => $data['date_from']->format('d-m-Y'),
'%date_to%' => $data['date_to']->format('d-m-Y'), '%date_to%' => $data['date_to']->format('d-m-Y'),
'%reasons_name%' => implode( '%reasons_name%' => implode(
", ", ', ',
array_map( array_map(
fn(ActivityReason $r): string => '"' . $this->translatableStringHelper->localize($r->getName()) . '"', fn (ActivityReason $r): string => '"' . $this->translatableStringHelper->localize($r->getName()) . '"',
$data['reasons'] $data['reasons']
) )
) ),
] ],
]; ];
} }
@@ -190,4 +198,11 @@ class PersonHavingActivityBetweenDateFilter implements FilterInterface, ExportEl
return 'Filtered by person having an activity in a period'; return 'Filtered by person having an activity in a period';
} }
public function validateForm($data, ExecutionContextInterface $context)
{
if (null === $data['reasons'] || count($data['reasons']) === 0) {
$context->buildViolation('At least one reason must be chosen')
->addViolation();
}
}
} }

View File

@@ -1,13 +1,20 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Form; namespace Chill\ActivityBundle\Form;
use Chill\ActivityBundle\Entity\ActivityPresence; use Chill\ActivityBundle\Entity\ActivityPresence;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
class ActivityPresenceType extends AbstractType class ActivityPresenceType extends AbstractType
{ {
@@ -15,19 +22,19 @@ class ActivityPresenceType extends AbstractType
{ {
$builder $builder
->add('name', TranslatableStringFormType::class) ->add('name', TranslatableStringFormType::class)
->add('active', ChoiceType::class, array( ->add('active', ChoiceType::class, [
'choices' => array( 'choices' => [
'Yes' => true, 'Yes' => true,
'No' => false 'No' => false,
), ],
'expanded' => true 'expanded' => true,
)); ]);
} }
public function configureOptions(OptionsResolver $resolver): void public function configureOptions(OptionsResolver $resolver): void
{ {
$resolver->setDefaults(array( $resolver->setDefaults([
'data_class' => ActivityPresence::class 'data_class' => ActivityPresence::class,
)); ]);
} }
} }

View File

@@ -1,25 +1,27 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Form; namespace Chill\ActivityBundle\Form;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
class ActivityReasonCategoryType extends AbstractType class ActivityReasonCategoryType extends AbstractType
{ {
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
{ {
$builder $builder
->add('name', TranslatableStringFormType::class) ->add('name', TranslatableStringFormType::class)
->add('active', CheckboxType::class, array('required' => false)) ->add('active', CheckboxType::class, ['required' => false]);
;
} }
/** /**
@@ -27,9 +29,9 @@ class ActivityReasonCategoryType extends AbstractType
*/ */
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
{ {
$resolver->setDefaults(array( $resolver->setDefaults([
'data_class' => 'Chill\ActivityBundle\Entity\ActivityReasonCategory' 'data_class' => 'Chill\ActivityBundle\Entity\ActivityReasonCategory',
)); ]);
} }
/** /**

View File

@@ -1,37 +1,36 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Form; namespace Chill\ActivityBundle\Form;
use Chill\ActivityBundle\Form\Type\TranslatableActivityReasonCategory;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
use Chill\ActivityBundle\Form\Type\TranslatableActivityReasonCategory;
class ActivityReasonType extends AbstractType class ActivityReasonType extends AbstractType
{ {
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
{ {
$builder $builder
->add('name', TranslatableStringFormType::class) ->add('name', TranslatableStringFormType::class)
->add('active', CheckboxType::class, array('required' => false)) ->add('active', CheckboxType::class, ['required' => false])
->add('category', TranslatableActivityReasonCategory::class) ->add('category', TranslatableActivityReasonCategory::class);
;
} }
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
{ {
$resolver->setDefaults(array( $resolver->setDefaults([
'data_class' => 'Chill\ActivityBundle\Entity\ActivityReason' 'data_class' => 'Chill\ActivityBundle\Entity\ActivityReason',
)); ]);
} }
/** /**

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Form; namespace Chill\ActivityBundle\Form;
use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\Activity;
@@ -7,54 +14,56 @@ use Chill\ActivityBundle\Entity\ActivityPresence;
use Chill\ActivityBundle\Entity\ActivityReason; use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\DocStoreBundle\Form\StoredObjectType; use Chill\DocStoreBundle\Form\StoredObjectType;
use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\Location;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Form\Type\ChillCollectionType; use Chill\MainBundle\Form\Type\ChillCollectionType;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Form\Type\CommentType; use Chill\MainBundle\Form\Type\CommentType;
use Chill\MainBundle\Form\Type\ScopePickerType;
use Chill\MainBundle\Form\Type\UserPickerType;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Chill\PersonBundle\Entity\SocialWork\SocialAction; use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
use Chill\ThirdPartyBundle\Entity\ThirdParty; use Chill\ThirdPartyBundle\Entity\ThirdParty;
use DateInterval;
use DateTime;
use DateTimeZone;
use Doctrine\ORM\EntityRepository; use Doctrine\ORM\EntityRepository;
use Doctrine\Persistence\ObjectManager;
use RuntimeException;
use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Doctrine\Persistence\ObjectManager;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Chill\MainBundle\Entity\User;
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToTimestampTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToTimestampTransformer;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents; use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\OptionsResolver\OptionsResolver;
use Chill\MainBundle\Form\Type\UserPickerType; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Chill\MainBundle\Form\Type\ScopePickerType;
use Chill\MainBundle\Form\Type\ChillDateType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\CallbackTransformer;
use Chill\PersonBundle\Form\DataTransformer\PersonToIdTransformer;
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
class ActivityType extends AbstractType class ActivityType extends AbstractType
{ {
protected User $user;
protected AuthorizationHelper $authorizationHelper; protected AuthorizationHelper $authorizationHelper;
protected ObjectManager $om; protected ObjectManager $om;
protected TranslatableStringHelper $translatableStringHelper; protected SocialActionRender $socialActionRender;
protected SocialIssueRender $socialIssueRender; protected SocialIssueRender $socialIssueRender;
protected SocialActionRender $socialActionRender;
protected array $timeChoices; protected array $timeChoices;
public function __construct ( protected TranslatableStringHelper $translatableStringHelper;
protected User $user;
public function __construct(
TokenStorageInterface $tokenStorage, TokenStorageInterface $tokenStorage,
AuthorizationHelper $authorizationHelper, AuthorizationHelper $authorizationHelper,
ObjectManager $om, ObjectManager $om,
@@ -64,7 +73,7 @@ class ActivityType extends AbstractType
SocialActionRender $socialActionRender SocialActionRender $socialActionRender
) { ) {
if (!$tokenStorage->getToken()->getUser() instanceof User) { if (!$tokenStorage->getToken()->getUser() instanceof User) {
throw new \RuntimeException("you should have a valid user"); throw new RuntimeException('you should have a valid user');
} }
$this->user = $tokenStorage->getToken()->getUser(); $this->user = $tokenStorage->getToken()->getUser();
@@ -100,12 +109,13 @@ class ActivityType extends AbstractType
'center' => $options['center'], 'center' => $options['center'],
'role' => $options['role'], 'role' => $options['role'],
// TODO make required again once scope and rights are fixed // TODO make required again once scope and rights are fixed
'required' => false 'required' => false,
]); ]);
} }
/** @var ? \Chill\PersonBundle\Entity\AccompanyingPeriod $accompanyingPeriod */ /** @var ? \Chill\PersonBundle\Entity\AccompanyingPeriod $accompanyingPeriod */
$accompanyingPeriod = NULL; $accompanyingPeriod = null;
if ($options['accompanyingPeriod']) { if ($options['accompanyingPeriod']) {
$accompanyingPeriod = $options['accompanyingPeriod']; $accompanyingPeriod = $options['accompanyingPeriod'];
} }
@@ -113,49 +123,53 @@ class ActivityType extends AbstractType
if ($activityType->isVisible('socialIssues') && $accompanyingPeriod) { if ($activityType->isVisible('socialIssues') && $accompanyingPeriod) {
$builder->add('socialIssues', HiddenType::class); $builder->add('socialIssues', HiddenType::class);
$builder->get('socialIssues') $builder->get('socialIssues')
->addModelTransformer(new CallbackTransformer( ->addModelTransformer(new CallbackTransformer(
function (iterable $socialIssuesAsIterable): string { function (iterable $socialIssuesAsIterable): string {
$socialIssueIds = []; $socialIssueIds = [];
foreach ($socialIssuesAsIterable as $value) { foreach ($socialIssuesAsIterable as $value) {
$socialIssueIds[] = $value->getId(); $socialIssueIds[] = $value->getId();
} }
return implode(',', $socialIssueIds); return implode(',', $socialIssueIds);
}, },
function (?string $socialIssuesAsString): array { function (?string $socialIssuesAsString): array {
if (null === $socialIssuesAsString) { if (null === $socialIssuesAsString) {
return []; return [];
} }
return array_map( return array_map(
fn(string $id): ?SocialIssue => $this->om->getRepository(SocialIssue::class)->findOneBy(['id' => (int) $id]), fn (string $id): ?SocialIssue => $this->om->getRepository(SocialIssue::class)->findOneBy(['id' => (int) $id]),
explode(',', $socialIssuesAsString) explode(',', $socialIssuesAsString)
); );
} }
)) ));
;
} }
if ($activityType->isVisible('socialActions') && $accompanyingPeriod) { if ($activityType->isVisible('socialActions') && $accompanyingPeriod) {
$builder->add('socialActions', HiddenType::class); $builder->add('socialActions', HiddenType::class);
$builder->get('socialActions') $builder->get('socialActions')
->addModelTransformer(new CallbackTransformer( ->addModelTransformer(new CallbackTransformer(
function (iterable $socialActionsAsIterable): string { function (iterable $socialActionsAsIterable): string {
$socialActionIds = []; $socialActionIds = [];
foreach ($socialActionsAsIterable as $value) { foreach ($socialActionsAsIterable as $value) {
$socialActionIds[] = $value->getId(); $socialActionIds[] = $value->getId();
} }
return implode(',', $socialActionIds); return implode(',', $socialActionIds);
}, },
function (?string $socialActionsAsString): array { function (?string $socialActionsAsString): array {
if (null === $socialActionsAsString) { if (null === $socialActionsAsString) {
return []; return [];
} }
return array_map( return array_map(
fn(string $id): ?SocialAction => $this->om->getRepository(SocialAction::class)->findOneBy(['id' => (int) $id]), fn (string $id): ?SocialAction => $this->om->getRepository(SocialAction::class)->findOneBy(['id' => (int) $id]),
explode(',', $socialActionsAsString) explode(',', $socialActionsAsString)
); );
} }
)) ));
;
} }
if ($activityType->isVisible('date')) { if ($activityType->isVisible('date')) {
@@ -200,7 +214,7 @@ class ActivityType extends AbstractType
'label' => $activityType->getLabel('user'), 'label' => $activityType->getLabel('user'),
'required' => $activityType->isRequired('user'), 'required' => $activityType->isRequired('user'),
'center' => $options['center'], 'center' => $options['center'],
'role' => $options['role'] 'role' => $options['role'],
]); ]);
} }
@@ -213,7 +227,7 @@ class ActivityType extends AbstractType
'choice_label' => function (ActivityReason $activityReason) { 'choice_label' => function (ActivityReason $activityReason) {
return $this->translatableStringHelper->localize($activityReason->getName()); return $this->translatableStringHelper->localize($activityReason->getName());
}, },
'attr' => array('class' => 'select2 '), 'attr' => ['class' => 'select2 '],
'query_builder' => function (EntityRepository $er) { 'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('a') return $er->createQueryBuilder('a')
->where('a.active = true'); ->where('a.active = true');
@@ -232,43 +246,45 @@ class ActivityType extends AbstractType
if ($activityType->isVisible('persons')) { if ($activityType->isVisible('persons')) {
$builder->add('persons', HiddenType::class); $builder->add('persons', HiddenType::class);
$builder->get('persons') $builder->get('persons')
->addModelTransformer(new CallbackTransformer( ->addModelTransformer(new CallbackTransformer(
function (iterable $personsAsIterable): string { function (iterable $personsAsIterable): string {
$personIds = []; $personIds = [];
foreach ($personsAsIterable as $value) { foreach ($personsAsIterable as $value) {
$personIds[] = $value->getId(); $personIds[] = $value->getId();
} }
return implode(',', $personIds); return implode(',', $personIds);
}, },
function (?string $personsAsString): array { function (?string $personsAsString): array {
return array_map( return array_map(
fn(string $id): ?Person => $this->om->getRepository(Person::class)->findOneBy(['id' => (int) $id]), fn (string $id): ?Person => $this->om->getRepository(Person::class)->findOneBy(['id' => (int) $id]),
explode(',', $personsAsString) explode(',', $personsAsString)
); );
} }
)) ));
;
} }
if ($activityType->isVisible('thirdParties')) { if ($activityType->isVisible('thirdParties')) {
$builder->add('thirdParties', HiddenType::class); $builder->add('thirdParties', HiddenType::class);
$builder->get('thirdParties') $builder->get('thirdParties')
->addModelTransformer(new CallbackTransformer( ->addModelTransformer(new CallbackTransformer(
function (iterable $thirdpartyAsIterable): string { function (iterable $thirdpartyAsIterable): string {
$thirdpartyIds = []; $thirdpartyIds = [];
foreach ($thirdpartyAsIterable as $value) { foreach ($thirdpartyAsIterable as $value) {
$thirdpartyIds[] = $value->getId(); $thirdpartyIds[] = $value->getId();
} }
return implode(',', $thirdpartyIds); return implode(',', $thirdpartyIds);
}, },
function (?string $thirdpartyAsString): array { function (?string $thirdpartyAsString): array {
return array_map( return array_map(
fn(string $id): ?ThirdParty => $this->om->getRepository(ThirdParty::class)->findOneBy(['id' => (int) $id]), fn (string $id): ?ThirdParty => $this->om->getRepository(ThirdParty::class)->findOneBy(['id' => (int) $id]),
explode(',', $thirdpartyAsString) explode(',', $thirdpartyAsString)
); );
} }
)) ));
;
} }
if ($activityType->isVisible('documents')) { if ($activityType->isVisible('documents')) {
@@ -278,29 +294,30 @@ class ActivityType extends AbstractType
'required' => $activityType->isRequired('documents'), 'required' => $activityType->isRequired('documents'),
'allow_add' => true, 'allow_add' => true,
'button_add_label' => 'activity.Insert a document', 'button_add_label' => 'activity.Insert a document',
'button_remove_label' => 'activity.Remove a document' 'button_remove_label' => 'activity.Remove a document',
]); ]);
} }
if ($activityType->isVisible('users')) { if ($activityType->isVisible('users')) {
$builder->add('users', HiddenType::class); $builder->add('users', HiddenType::class);
$builder->get('users') $builder->get('users')
->addModelTransformer(new CallbackTransformer( ->addModelTransformer(new CallbackTransformer(
function (iterable $usersAsIterable): string { function (iterable $usersAsIterable): string {
$userIds = []; $userIds = [];
foreach ($usersAsIterable as $value) { foreach ($usersAsIterable as $value) {
$userIds[] = $value->getId(); $userIds[] = $value->getId();
} }
return implode(',', $userIds); return implode(',', $userIds);
}, },
function (?string $usersAsString): array { function (?string $usersAsString): array {
return array_map( return array_map(
fn(string $id): ?User => $this->om->getRepository(User::class)->findOneBy(['id' => (int) $id]), fn (string $id): ?User => $this->om->getRepository(User::class)->findOneBy(['id' => (int) $id]),
explode(',', $usersAsString) explode(',', $usersAsString)
); );
} }
)) ));
;
} }
if ($activityType->isVisible('location')) { if ($activityType->isVisible('location')) {
@@ -311,13 +328,13 @@ class ActivityType extends AbstractType
if (null === $location) { if (null === $location) {
return ''; return '';
} }
return $location->getId(); return $location->getId();
}, },
function (?string $id): ?Location { function (?string $id): ?Location {
return $this->om->getRepository(Location::class)->findOneBy(['id' => (int) $id]); return $this->om->getRepository(Location::class)->findOneBy(['id' => (int) $id]);
} }
)) ));
;
} }
if ($activityType->isVisible('emergency')) { if ($activityType->isVisible('emergency')) {
@@ -347,7 +364,7 @@ class ActivityType extends AbstractType
->addModelTransformer($durationTimeTransformer); ->addModelTransformer($durationTimeTransformer);
$builder->get($fieldName) $builder->get($fieldName)
->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $formEvent) use ( ->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $formEvent) use (
$timeChoices, $timeChoices,
$builder, $builder,
$durationTimeTransformer, $durationTimeTransformer,
@@ -356,14 +373,14 @@ class ActivityType extends AbstractType
) { ) {
// set the timezone to GMT, and fix the difference between current and GMT // set the timezone to GMT, and fix the difference between current and GMT
// the datetimetransformer will then handle timezone as GMT // the datetimetransformer will then handle timezone as GMT
$timezoneUTC = new \DateTimeZone('GMT'); $timezoneUTC = new DateTimeZone('GMT');
/* @var $data \DateTime */ /* @var $data \DateTime */
$data = $formEvent->getData() === NULL ? $data = $formEvent->getData() === null ?
\DateTime::createFromFormat('U', 300) : DateTime::createFromFormat('U', 300) :
$formEvent->getData(); $formEvent->getData();
$seconds = $data->getTimezone()->getOffset($data); $seconds = $data->getTimezone()->getOffset($data);
$data->setTimeZone($timezoneUTC); $data->setTimeZone($timezoneUTC);
$data->add(new \DateInterval('PT'.$seconds.'S')); $data->add(new DateInterval('PT' . $seconds . 'S'));
// test if the timestamp is in the choices. // test if the timestamp is in the choices.
// If not, recreate the field with the new timestamp // If not, recreate the field with the new timestamp
@@ -371,9 +388,10 @@ class ActivityType extends AbstractType
// the data are not in the possible values. add them // the data are not in the possible values. add them
$timeChoices[$data->format('H:i')] = $data->getTimestamp(); $timeChoices[$data->format('H:i')] = $data->getTimestamp();
$form = $builder->create($fieldName, ChoiceType::class, array_merge( $form = $builder->create($fieldName, ChoiceType::class, array_merge(
$durationTimeOptions, [ $durationTimeOptions,
[
'choices' => $timeChoices, 'choices' => $timeChoices,
'auto_initialize' => false 'auto_initialize' => false,
] ]
)); ));
$form->addModelTransformer($durationTimeTransformer); $form->addModelTransformer($durationTimeTransformer);
@@ -383,12 +401,10 @@ class ActivityType extends AbstractType
} }
} }
public function configureOptions(OptionsResolver $resolver): void public function configureOptions(OptionsResolver $resolver): void
{ {
$resolver->setDefaults([ $resolver->setDefaults([
'data_class' => Activity::class 'data_class' => Activity::class,
]); ]);
$resolver $resolver
@@ -396,8 +412,7 @@ class ActivityType extends AbstractType
->setAllowedTypes('center', ['null', 'Chill\MainBundle\Entity\Center']) ->setAllowedTypes('center', ['null', 'Chill\MainBundle\Entity\Center'])
->setAllowedTypes('role', 'Symfony\Component\Security\Core\Role\Role') ->setAllowedTypes('role', 'Symfony\Component\Security\Core\Role\Role')
->setAllowedTypes('activityType', \Chill\ActivityBundle\Entity\ActivityType::class) ->setAllowedTypes('activityType', \Chill\ActivityBundle\Entity\ActivityType::class)
->setAllowedTypes('accompanyingPeriod', [\Chill\PersonBundle\Entity\AccompanyingPeriod::class, 'null']) ->setAllowedTypes('accompanyingPeriod', [\Chill\PersonBundle\Entity\AccompanyingPeriod::class, 'null']);
;
} }
public function getBlockPrefix(): string public function getBlockPrefix(): string

View File

@@ -1,14 +1,21 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Form; namespace Chill\ActivityBundle\Form;
use Chill\ActivityBundle\Entity\ActivityTypeCategory; use Chill\ActivityBundle\Entity\ActivityTypeCategory;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\NumberType; use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
class ActivityTypeCategoryType extends AbstractType class ActivityTypeCategoryType extends AbstractType
{ {
@@ -16,24 +23,23 @@ class ActivityTypeCategoryType extends AbstractType
{ {
$builder $builder
->add('name', TranslatableStringFormType::class) ->add('name', TranslatableStringFormType::class)
->add('active', ChoiceType::class, array( ->add('active', ChoiceType::class, [
'choices' => array( 'choices' => [
'Yes' => true, 'Yes' => true,
'No' => false 'No' => false,
), ],
'expanded' => true 'expanded' => true,
)) ])
->add('ordering', NumberType::class, [ ->add('ordering', NumberType::class, [
'required' => true, 'required' => true,
'scale' => 5 'scale' => 5,
]) ]);
;
} }
public function configureOptions(OptionsResolver $resolver): void public function configureOptions(OptionsResolver $resolver): void
{ {
$resolver->setDefaults(array( $resolver->setDefaults([
'data_class' => ActivityTypeCategory::class 'data_class' => ActivityTypeCategory::class,
)); ]);
} }
} }

View File

@@ -1,18 +1,25 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Form; namespace Chill\ActivityBundle\Form;
use Chill\ActivityBundle\Entity\ActivityTypeCategory; use Chill\ActivityBundle\Entity\ActivityTypeCategory;
use Chill\ActivityBundle\Form\Type\ActivityFieldPresence; use Chill\ActivityBundle\Form\Type\ActivityFieldPresence;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\NumberType; use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
class ActivityTypeType extends AbstractType class ActivityTypeType extends AbstractType
{ {
@@ -30,9 +37,9 @@ class ActivityTypeType extends AbstractType
->add('active', ChoiceType::class, [ ->add('active', ChoiceType::class, [
'choices' => [ 'choices' => [
'Yes' => true, 'Yes' => true,
'No' => false 'No' => false,
], ],
'expanded' => true 'expanded' => true,
]) ])
->add('category', EntityType::class, [ ->add('category', EntityType::class, [
'class' => ActivityTypeCategory::class, 'class' => ActivityTypeCategory::class,
@@ -42,20 +49,20 @@ class ActivityTypeType extends AbstractType
]) ])
->add('ordering', NumberType::class, [ ->add('ordering', NumberType::class, [
'required' => true, 'required' => true,
'scale' => 5 'scale' => 5,
]) ]);
;
$fields = [ $fields = [
'persons', 'user', 'date', 'place', 'persons', 'persons', 'user', 'date', 'place', 'persons',
'thirdParties', 'durationTime', 'travelTime', 'attendee', 'thirdParties', 'durationTime', 'travelTime', 'attendee',
'reasons', 'comment', 'sentReceived', 'documents', 'reasons', 'comment', 'sentReceived', 'documents',
'emergency', 'accompanyingPeriod', 'socialData', 'users' 'emergency', 'accompanyingPeriod', 'socialData', 'users',
]; ];
foreach ($fields as $field) { foreach ($fields as $field) {
$builder $builder
->add($field.'Visible', ActivityFieldPresence::class) ->add($field . 'Visible', ActivityFieldPresence::class)
->add($field.'Label', TextType::class, [ ->add($field . 'Label', TextType::class, [
'required' => false, 'required' => false,
'empty_data' => '', 'empty_data' => '',
]); ]);
@@ -64,8 +71,8 @@ class ActivityTypeType extends AbstractType
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
{ {
$resolver->setDefaults(array( $resolver->setDefaults([
'data_class' => \Chill\ActivityBundle\Entity\ActivityType::class 'data_class' => \Chill\ActivityBundle\Entity\ActivityType::class,
)); ]);
} }
} }

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Form\Type; namespace Chill\ActivityBundle\Form\Type;
use Chill\ActivityBundle\Entity\ActivityType; use Chill\ActivityBundle\Entity\ActivityType;
@@ -9,21 +16,21 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
class ActivityFieldPresence extends AbstractType class ActivityFieldPresence extends AbstractType
{ {
public function getParent()
{
return ChoiceType::class;
}
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
{ {
$resolver->setDefaults( $resolver->setDefaults(
array( [
'choices' => [ 'choices' => [
'Invisible' => ActivityType::FIELD_INVISIBLE, 'Invisible' => ActivityType::FIELD_INVISIBLE,
'Optional' => ActivityType::FIELD_OPTIONAL, 'Optional' => ActivityType::FIELD_OPTIONAL,
'Required' => ActivityType::FIELD_REQUIRED, 'Required' => ActivityType::FIELD_REQUIRED,
], ],
) ]
); );
} }
public function getParent()
{
return ChoiceType::class;
}
} }

View File

@@ -1,54 +1,37 @@
<?php <?php
/* /**
* Chill is a software for social workers * Chill is a software for social workers
* *
* Copyright (C) 2014-2020, Champs Libres Cooperative SCRLFS, * For the full copyright and license information, please view
* <http://www.champs-libres.coop>, <info@champs-libres.coop> * the LICENSE file that was distributed with this source code.
*
* 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\ActivityBundle\Form\Type; namespace Chill\ActivityBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\EntityRepository;
use Chill\ActivityBundle\Entity\ActivityReason; use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\ActivityBundle\Templating\Entity\ActivityReasonRender; use Chill\ActivityBundle\Templating\Entity\ActivityReasonRender;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
/** /**
* FormType to choose amongst activity reasons * FormType to choose amongst activity reasons.
*
*/ */
class TranslatableActivityReason extends AbstractType class TranslatableActivityReason extends AbstractType
{ {
/** /**
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
/**
*
* @var ActivityReasonRender * @var ActivityReasonRender
*/ */
protected $reasonRender; protected $reasonRender;
/**
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
public function __construct( public function __construct(
TranslatableStringHelper $translatableStringHelper, TranslatableStringHelper $translatableStringHelper,
ActivityReasonRender $reasonRender ActivityReasonRender $reasonRender
@@ -57,6 +40,30 @@ class TranslatableActivityReason extends AbstractType
$this->reasonRender = $reasonRender; $this->reasonRender = $reasonRender;
} }
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
[
'class' => 'ChillActivityBundle:ActivityReason',
'choice_label' => function (ActivityReason $choice) {
return $this->reasonRender->renderString($choice, []);
},
'group_by' => function (ActivityReason $choice): ?string {
if (null !== $category = $choice->getCategory()) {
return $this->translatableStringHelper->localize($category->getName());
}
return null;
},
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('r')
->where('r.active = true');
},
'attr' => ['class' => ' select2 '],
]
);
}
public function getBlockPrefix() public function getBlockPrefix()
{ {
return 'translatable_activity_reason'; return 'translatable_activity_reason';
@@ -66,28 +73,4 @@ class TranslatableActivityReason extends AbstractType
{ {
return EntityType::class; return EntityType::class;
} }
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
array(
'class' => 'ChillActivityBundle:ActivityReason',
'choice_label' => function(ActivityReason $choice) {
return $this->reasonRender->renderString($choice, []);
},
'group_by' => function(ActivityReason $choice): ?string {
if (null !== $category = $choice->getCategory()) {
return $this->translatableStringHelper->localize($category->getName());
}
return null;
},
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('r')
->where('r.active = true');
},
'attr' => [ 'class' => ' select2 ']
)
);
}
} }

View File

@@ -1,40 +1,23 @@
<?php <?php
/* /**
* Chill is a software for social workers * Chill is a software for social workers
* *
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, * For the full copyright and license information, please view
* <http://www.champs-libres.coop>, <info@champs-libres.coop> * the LICENSE file that was distributed with this source code.
*
* 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\ActivityBundle\Form\Type; namespace Chill\ActivityBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository; use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\OptionsResolver\OptionsResolver;
/** /**
* Description of TranslatableActivityReasonCategory * Description of TranslatableActivityReasonCategory.
*
* @author Champs-Libres Coop
*/ */
class TranslatableActivityReasonCategory extends AbstractType class TranslatableActivityReasonCategory extends AbstractType
{ {
/** /**
@@ -47,6 +30,21 @@ class TranslatableActivityReasonCategory extends AbstractType
$this->requestStack = $requestStack; $this->requestStack = $requestStack;
} }
public function configureOptions(OptionsResolver $resolver)
{
$locale = $this->requestStack->getCurrentRequest()->getLocale();
$resolver->setDefaults(
[
'class' => 'ChillActivityBundle:ActivityReasonCategory',
'choice_label' => 'name[' . $locale . ']',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('c')
->where('c.active = true');
},
]
);
}
public function getBlockPrefix() public function getBlockPrefix()
{ {
return 'translatable_activity_reason_category'; return 'translatable_activity_reason_category';
@@ -56,19 +54,4 @@ class TranslatableActivityReasonCategory extends AbstractType
{ {
return EntityType::class; return EntityType::class;
} }
public function configureOptions(OptionsResolver $resolver)
{
$locale = $this->requestStack->getCurrentRequest()->getLocale();
$resolver->setDefaults(
array(
'class' => 'ChillActivityBundle:ActivityReasonCategory',
'choice_label' => 'name['.$locale.']',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('c')
->where('c.active = true');
}
)
);
}
} }

View File

@@ -1,25 +1,32 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Form\Type; namespace Chill\ActivityBundle\Form\Type;
use Chill\ActivityBundle\Entity\ActivityType;
use Chill\ActivityBundle\Repository\ActivityTypeRepository; use Chill\ActivityBundle\Repository\ActivityTypeRepository;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Doctrine\DBAL\Types\Types; use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Chill\ActivityBundle\Entity\ActivityType;
class TranslatableActivityType extends AbstractType class TranslatableActivityType extends AbstractType
{ {
protected TranslatableStringHelperInterface $translatableStringHelper;
protected ActivityTypeRepository $activityTypeRepository; protected ActivityTypeRepository $activityTypeRepository;
protected TranslatableStringHelperInterface $translatableStringHelper;
public function __construct( public function __construct(
TranslatableStringHelperInterface $helper, TranslatableStringHelperInterface $helper,
ActivityTypeRepository $activityTypeRepository ActivityTypeRepository $activityTypeRepository
@@ -28,6 +35,32 @@ class TranslatableActivityType extends AbstractType
$this->activityTypeRepository = $activityTypeRepository; $this->activityTypeRepository = $activityTypeRepository;
} }
public function buildForm(FormBuilderInterface $builder, array $options)
{
/* @var QueryBuilder $qb */
$qb = $options['query_builder'];
if (true === $options['active_only']) {
$qb->where($qb->expr()->eq('at.active', ':active'));
$qb->setParameter('active', true, Types::BOOLEAN);
}
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
[
'class' => ActivityType::class,
'active_only' => true,
'query_builder' => $this->activityTypeRepository
->createQueryBuilder('at'),
'choice_label' => function (ActivityType $type) {
return $this->translatableStringHelper->localize($type->getName());
},
]
);
}
public function getBlockPrefix() public function getBlockPrefix()
{ {
return 'translatable_activity_type'; return 'translatable_activity_type';
@@ -37,29 +70,4 @@ class TranslatableActivityType extends AbstractType
{ {
return EntityType::class; return EntityType::class;
} }
public function buildForm(FormBuilderInterface $builder, array $options) {
/* @var QueryBuilder $qb */
$qb = $options['query_builder'];
if ($options['active_only'] === true) {
$qb->where($qb->expr()->eq('at.active', ':active'));
$qb->setParameter('active', true, Types::BOOLEAN);
}
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
array(
'class' => ActivityType::class,
'active_only' => true,
'query_builder' => $this->activityTypeRepository
->createQueryBuilder('at'),
'choice_label' => function (ActivityType $type) {
return $this->translatableStringHelper->localize($type->getName());
}
)
);
}
} }

View File

@@ -1,22 +1,27 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Menu; namespace Chill\ActivityBundle\Menu;
use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface; use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Knp\Menu\MenuItem; use Knp\Menu\MenuItem;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
{ {
protected TranslatorInterface $translator;
protected Security $security; protected Security $security;
protected TranslatorInterface $translator;
public function __construct( public function __construct(
Security $security, Security $security,
TranslatorInterface $translator TranslatorInterface $translator
@@ -24,10 +29,6 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
$this->security = $security; $this->security = $security;
$this->translator = $translator; $this->translator = $translator;
} }
public static function getMenuIds(): array
{
return ['accompanyingCourse'];
}
public function buildMenu($menuId, MenuItem $menu, array $parameters) public function buildMenu($menuId, MenuItem $menu, array $parameters)
{ {
@@ -39,8 +40,13 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
'route' => 'chill_activity_activity_list', 'route' => 'chill_activity_activity_list',
'routeParameters' => [ 'routeParameters' => [
'accompanying_period_id' => $period->getId(), 'accompanying_period_id' => $period->getId(),
]]) ], ])
->setExtras(['order' => 40]); ->setExtras(['order' => 40]);
} }
} }
public static function getMenuIds(): array
{
return ['accompanyingCourse'];
}
} }

View File

@@ -1,4 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Menu; namespace Chill\ActivityBundle\Menu;
@@ -16,11 +24,6 @@ final class AdminMenuBuilder implements LocalMenuBuilderInterface
$this->security = $security; $this->security = $security;
} }
public static function getMenuIds(): array
{
return ['admin_index', 'admin_section', 'admin_activity'];
}
public function buildMenu($menuId, MenuItem $menu, array $parameters) public function buildMenu($menuId, MenuItem $menu, array $parameters)
{ {
if (!$this->security->isGranted('ROLE_ADMIN')) { if (!$this->security->isGranted('ROLE_ADMIN')) {
@@ -29,20 +32,25 @@ final class AdminMenuBuilder implements LocalMenuBuilderInterface
if (in_array($menuId, ['admin_index', 'admin_section'])) { if (in_array($menuId, ['admin_index', 'admin_section'])) {
$menu->addChild('Activities', [ $menu->addChild('Activities', [
'route' => 'chill_admin_activity_index' 'route' => 'chill_admin_activity_index',
]) ])
->setExtras([ ->setExtras([
'order' => 2000, 'order' => 2000,
'explain' => "Activity configuration" 'explain' => 'Activity configuration',
]); ]);
} else { } else {
$menu $menu
->addChild('Activities', [ ->addChild('Activities', [
'route' => 'chill_admin_activity_index' 'route' => 'chill_admin_activity_index',
]) ])
->setExtras([ ->setExtras([
'order' => '60' 'order' => '60',
]); ]);
} }
} }
}
public static function getMenuIds(): array
{
return ['admin_index', 'admin_section', 'admin_activity'];
}
}

View File

@@ -1,68 +1,55 @@
<?php <?php
/*
* Copyright (C) 2018 Julien Fastré <julien.fastre@champs-libres.coop> /**
* Chill is a software for social workers
* *
* This program is free software: you can redistribute it and/or modify * For the full copyright and license information, please view
* it under the terms of the GNU Affero General Public License as published by * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\Menu;
namespace Chill\ActivityBundle\Menu;
use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface; use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Knp\Menu\MenuItem; use Knp\Menu\MenuItem;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Symfony\Component\Translation\TranslatorInterface; use Symfony\Component\Translation\TranslatorInterface;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class PersonMenuBuilder implements LocalMenuBuilderInterface class PersonMenuBuilder implements LocalMenuBuilderInterface
{ {
/** /**
*
* @var TranslatorInterface
*/
protected $translator;
/**
*
* @var AuthorizationCheckerInterface * @var AuthorizationCheckerInterface
*/ */
protected $authorizationChecker; protected $authorizationChecker;
/**
* @var TranslatorInterface
*/
protected $translator;
public function __construct( public function __construct(
AuthorizationCheckerInterface $authorizationChecker, AuthorizationCheckerInterface $authorizationChecker,
TranslatorInterface $translator) TranslatorInterface $translator
)
{ {
$this->translator = $translator; $this->translator = $translator;
$this->authorizationChecker = $authorizationChecker; $this->authorizationChecker = $authorizationChecker;
} }
public function buildMenu($menuId, MenuItem $menu, array $parameters) public function buildMenu($menuId, MenuItem $menu, array $parameters)
{ {
/* @var $person \Chill\PersonBundle\Entity\Person */ /* @var $person \Chill\PersonBundle\Entity\Person */
$person = $parameters['person']; $person = $parameters['person'];
if ($this->authorizationChecker->isGranted(ActivityVoter::SEE, $person)) { if ($this->authorizationChecker->isGranted(ActivityVoter::SEE, $person)) {
$menu->addChild( $menu->addChild(
$this->translator->trans('Activity list'), [ $this->translator->trans('Activity list'),
[
'route' => 'chill_activity_activity_list', 'route' => 'chill_activity_activity_list',
'routeParameters' => [ 'person_id' => $person->getId() ], 'routeParameters' => ['person_id' => $person->getId()],
]) ]
->setExtra('order', 201) )
; ->setExtra('order', 201);
} }
} }

View File

@@ -1,17 +1,19 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Notification; namespace Chill\ActivityBundle\Notification;
use Chill\MainBundle\Entity\Notification;
use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\Activity;
use Chill\MainBundle\Entity\Notification;
final class ActivityNotificationRenderer final class ActivityNotificationRenderer
{ {
public function supports(Notification $notification, array $options = []): bool
{
return $notification->getRelatedEntityClass() == Activity::class;
}
public function getTemplate() public function getTemplate()
{ {
return '@ChillActivity/Activity/showInNotification.html.twig'; return '@ChillActivity/Activity/showInNotification.html.twig';
@@ -21,4 +23,9 @@ final class ActivityNotificationRenderer
{ {
return ['notification' => $notification]; return ['notification' => $notification];
} }
public function supports(Notification $notification, array $options = []): bool
{
return $notification->getRelatedEntityClass() == Activity::class;
}
} }

View File

@@ -1,35 +1,42 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Repository; namespace Chill\ActivityBundle\Repository;
use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\Activity;
use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper; use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\Role;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use function in_array;
final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInterface final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInterface
{ {
private AuthorizationHelper $authorizationHelper; private AuthorizationHelper $authorizationHelper;
private TokenStorageInterface $tokenStorage; private CenterResolverDispatcherInterface $centerResolverDispatcher;
private ActivityRepository $repository;
private EntityManagerInterface $em; private EntityManagerInterface $em;
private ActivityRepository $repository;
private Security $security; private Security $security;
private CenterResolverDispatcherInterface $centerResolverDispatcher; private TokenStorageInterface $tokenStorage;
public function __construct( public function __construct(
AuthorizationHelper $authorizationHelper, AuthorizationHelper $authorizationHelper,
@@ -47,34 +54,11 @@ final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInte
$this->security = $security; $this->security = $security;
} }
/**
* @param Person $person
* @param string $role
* @param int|null $start
* @param int|null $limit
* @param array $orderBy
* @return array|Activity[]
*/
public function findByPerson(Person $person, string $role, ?int $start = 0, ?int $limit = 1000, ?array $orderBy = []): array
{
$user = $this->security->getUser();
$center = $this->centerResolverDispatcher->resolveCenter($person);
if (0 === count($orderBy)) {
$orderBy = ['date' => 'DESC'];
}
$reachableScopes = $this->authorizationHelper
->getReachableCircles($user, $role, $center);
return $this->em->getRepository(Activity::class)
->findByPersonImplied($person, $reachableScopes, $orderBy, $limit, $start);
;
}
public function findByAccompanyingPeriod(AccompanyingPeriod $period, string $role, ?int $start = 0, ?int $limit = 1000, ?array $orderBy = []): array public function findByAccompanyingPeriod(AccompanyingPeriod $period, string $role, ?int $start = 0, ?int $limit = 1000, ?array $orderBy = []): array
{ {
$user = $this->security->getUser(); $user = $this->security->getUser();
$center = $this->centerResolverDispatcher->resolveCenter($period); $center = $this->centerResolverDispatcher->resolveCenter($period);
if (0 === count($orderBy)) { if (0 === count($orderBy)) {
$orderBy = ['date' => 'DESC']; $orderBy = ['date' => 'DESC'];
} }
@@ -86,6 +70,27 @@ final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInte
->findByAccompanyingPeriod($period, $scopes, true, $limit, $start, $orderBy); ->findByAccompanyingPeriod($period, $scopes, true, $limit, $start, $orderBy);
} }
/**
* @param array $orderBy
*
* @return Activity[]|array
*/
public function findByPerson(Person $person, string $role, ?int $start = 0, ?int $limit = 1000, ?array $orderBy = []): array
{
$user = $this->security->getUser();
$center = $this->centerResolverDispatcher->resolveCenter($person);
if (0 === count($orderBy)) {
$orderBy = ['date' => 'DESC'];
}
$reachableScopes = $this->authorizationHelper
->getReachableCircles($user, $role, $center);
return $this->em->getRepository(Activity::class)
->findByPersonImplied($person, $reachableScopes, $orderBy, $limit, $start);
}
public function queryTimelineIndexer(string $context, array $args = []): array public function queryTimelineIndexer(string $context, array $args = []): array
{ {
$metadataActivity = $this->em->getClassMetadata(Activity::class); $metadataActivity = $this->em->getClassMetadata(Activity::class);
@@ -94,15 +99,15 @@ final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInte
[$where, $parameters] = $this->getWhereClause($context, $args); [$where, $parameters] = $this->getWhereClause($context, $args);
return [ return [
'id' => $metadataActivity->getTableName() 'id' => $metadataActivity->getTableName()
.'.'.$metadataActivity->getColumnName('id'), . '.' . $metadataActivity->getColumnName('id'),
'type' => 'activity', 'type' => 'activity',
'date' => $metadataActivity->getTableName() 'date' => $metadataActivity->getTableName()
.'.'.$metadataActivity->getColumnName('date'), . '.' . $metadataActivity->getColumnName('date'),
'FROM' => $from, 'FROM' => $from,
'WHERE' => $where, 'WHERE' => $where,
'parameters' => $parameters 'parameters' => $parameters,
]; ];
} }
private function getFromClauseCenter(array $args): string private function getFromClauseCenter(array $args): string
@@ -111,13 +116,12 @@ final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInte
$metadataPerson = $this->em->getClassMetadata(Person::class); $metadataPerson = $this->em->getClassMetadata(Person::class);
$associationMapping = $metadataActivity->getAssociationMapping('person'); $associationMapping = $metadataActivity->getAssociationMapping('person');
return $metadataActivity->getTableName().' JOIN ' return $metadataActivity->getTableName() . ' JOIN '
.$metadataPerson->getTableName().' ON ' . $metadataPerson->getTableName() . ' ON '
.$metadataPerson->getTableName().'.'. . $metadataPerson->getTableName() . '.' .
$associationMapping['joinColumns'][0]['referencedColumnName'] $associationMapping['joinColumns'][0]['referencedColumnName']
.' = ' . ' = '
.$associationMapping['joinColumns'][0]['name'] . $associationMapping['joinColumns'][0]['name'];
;
} }
private function getWhereClause(string $context, array $args): array private function getWhereClause(string $context, array $args): array
@@ -128,21 +132,22 @@ final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInte
$metadataActivity = $this->em->getClassMetadata(Activity::class); $metadataActivity = $this->em->getClassMetadata(Activity::class);
$metadataPerson = $this->em->getClassMetadata(Person::class); $metadataPerson = $this->em->getClassMetadata(Person::class);
$activityToPerson = $metadataActivity->getAssociationMapping('person')['joinColumns'][0]['name']; $activityToPerson = $metadataActivity->getAssociationMapping('person')['joinColumns'][0]['name'];
$activityToScope = $metadataActivity->getAssociationMapping('scope')['joinColumns'][0]['name']; $activityToScope = $metadataActivity->getAssociationMapping('scope')['joinColumns'][0]['name'];
$personToCenter = $metadataPerson->getAssociationMapping('center')['joinColumns'][0]['name']; $personToCenter = $metadataPerson->getAssociationMapping('center')['joinColumns'][0]['name'];
// acls: // acls:
$role = new Role(ActivityVoter::SEE); $role = new Role(ActivityVoter::SEE);
$reachableCenters = $this->authorizationHelper->getReachableCenters($this->tokenStorage->getToken()->getUser(), $reachableCenters = $this->authorizationHelper->getReachableCenters(
$role); $this->tokenStorage->getToken()->getUser(),
$role
);
if (count($reachableCenters) === 0) { if (count($reachableCenters) === 0) {
// insert a dummy condition // insert a dummy condition
return 'FALSE = TRUE'; return 'FALSE = TRUE';
} }
if ($context === 'person') { if ('person' === $context) {
// we start with activities having the person_id linked to person // we start with activities having the person_id linked to person
$where .= sprintf('%s = ? AND ', $activityToPerson); $where .= sprintf('%s = ? AND ', $activityToPerson);
$parameters[] = $person->getId(); $parameters[] = $person->getId();
@@ -151,21 +156,22 @@ final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInte
// we add acl (reachable center and scopes) // we add acl (reachable center and scopes)
$where .= '('; // first loop for the for centers $where .= '('; // first loop for the for centers
$centersI = 0; // like centers#i $centersI = 0; // like centers#i
foreach ($reachableCenters as $center) { foreach ($reachableCenters as $center) {
// we pass if not in centers // we pass if not in centers
if (!\in_array($center, $args['centers'])) { if (!in_array($center, $args['centers'])) {
continue; continue;
} }
// we get all the reachable scopes for this center // we get all the reachable scopes for this center
$reachableScopes = $this->authorizationHelper->getReachableScopes($this->tokenStorage->getToken()->getUser(), $role, $center); $reachableScopes = $this->authorizationHelper->getReachableScopes($this->tokenStorage->getToken()->getUser(), $role, $center);
// we get the ids for those scopes // we get the ids for those scopes
$reachablesScopesId = array_map( $reachablesScopesId = array_map(
function(Scope $scope) { return $scope->getId(); }, function (Scope $scope) { return $scope->getId(); },
$reachableScopes $reachableScopes
); );
// if not the first center // if not the first center
if ($centersI > 0) { if (0 < $centersI) {
$where .= ') OR ('; $where .= ') OR (';
} }
@@ -178,21 +184,20 @@ final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInte
$scopesI = 0; //like scope#i $scopesI = 0; //like scope#i
foreach ($reachablesScopesId as $scopeId) { foreach ($reachablesScopesId as $scopeId) {
if ($scopesI > 0) { if (0 < $scopesI) {
$where .= ' OR '; $where .= ' OR ';
} }
$where .= sprintf(' %s.%s = ? ', $metadataActivity->getTableName(), $activityToScope); $where .= sprintf(' %s.%s = ? ', $metadataActivity->getTableName(), $activityToScope);
$parameters[] = $scopeId; $parameters[] = $scopeId;
$scopesI ++; ++$scopesI;
} }
// close loop for scopes // close loop for scopes
$where .= ') '; $where .= ') ';
$centersI++; ++$centersI;
} }
// close loop for centers // close loop for centers
$where .= ')'; $where .= ')';
return [$where, $parameters]; return [$where, $parameters];
} }
} }

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Repository; namespace Chill\ActivityBundle\Repository;
use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod;
@@ -8,12 +15,12 @@ use Chill\PersonBundle\Entity\Person;
interface ActivityACLAwareRepositoryInterface interface ActivityACLAwareRepositoryInterface
{ {
/** /**
* @return array|Activity[] * @return Activity[]|array
*/
public function findByPerson(Person $person, string $role, ?int $start = 0, ?int $limit = 1000, ?array $orderBy = []): array;
/**
* @return array|Activity[]
*/ */
public function findByAccompanyingPeriod(AccompanyingPeriod $period, string $role, ?int $start = 0, ?int $limit = 1000, ?array $orderBy = []): array; public function findByAccompanyingPeriod(AccompanyingPeriod $period, string $role, ?int $start = 0, ?int $limit = 1000, ?array $orderBy = []): array;
/**
* @return Activity[]|array
*/
public function findByPerson(Person $person, string $role, ?int $start = 0, ?int $limit = 1000, ?array $orderBy = []): array;
} }

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Repository; namespace Chill\ActivityBundle\Repository;

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Repository; namespace Chill\ActivityBundle\Repository;

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Repository; namespace Chill\ActivityBundle\Repository;
@@ -23,34 +30,6 @@ class ActivityRepository extends ServiceEntityRepository
parent::__construct($registry, Activity::class); parent::__construct($registry, Activity::class);
} }
/**
* @return Activity[]
*/
public function findByPersonImplied(Person $person, array $scopes, ?array $orderBy = [ 'date' => 'DESC'], ?int $limit = 100, ?int $offset = 0): array
{
$qb = $this->createQueryBuilder('a');
$qb->select('a');
$qb
->where($qb->expr()->in('a.scope', ':scopes'))
->setParameter('scopes', $scopes)
->andWhere(
$qb->expr()->orX(
$qb->expr()->eq('a.person', ':person'),
':person MEMBER OF a.persons'
)
)
->setParameter('person', $person);
foreach ($orderBy as $k => $dir) {
$qb->addOrderBy('a.'.$k, $dir);
}
$qb->setMaxResults($limit)->setFirstResult($offset);
return $qb->getQuery()->getResult();
}
/** /**
* @return Activity[] * @return Activity[]
*/ */
@@ -81,7 +60,35 @@ class ActivityRepository extends ServiceEntityRepository
->setParameter('period', $period); ->setParameter('period', $period);
foreach ($orderBy as $k => $dir) { foreach ($orderBy as $k => $dir) {
$qb->addOrderBy('a.'.$k, $dir); $qb->addOrderBy('a.' . $k, $dir);
}
$qb->setMaxResults($limit)->setFirstResult($offset);
return $qb->getQuery()->getResult();
}
/**
* @return Activity[]
*/
public function findByPersonImplied(Person $person, array $scopes, ?array $orderBy = ['date' => 'DESC'], ?int $limit = 100, ?int $offset = 0): array
{
$qb = $this->createQueryBuilder('a');
$qb->select('a');
$qb
->where($qb->expr()->in('a.scope', ':scopes'))
->setParameter('scopes', $scopes)
->andWhere(
$qb->expr()->orX(
$qb->expr()->eq('a.person', ':person'),
':person MEMBER OF a.persons'
)
)
->setParameter('person', $person);
foreach ($orderBy as $k => $dir) {
$qb->addOrderBy('a.' . $k, $dir);
} }
$qb->setMaxResults($limit)->setFirstResult($offset); $qb->setMaxResults($limit)->setFirstResult($offset);

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Repository; namespace Chill\ActivityBundle\Repository;

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Repository; namespace Chill\ActivityBundle\Repository;

View File

@@ -1,13 +1,36 @@
<?php <?php
use Symfony\Component\HttpKernel\Kernel; /**
* 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.
*/
use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\HttpKernel\Kernel;
class AppKernel extends Kernel class AppKernel extends Kernel
{ {
/**
* @return string
*/
public function getCacheDir()
{
return sys_get_temp_dir() . '/ActivityBundle/cache';
}
/**
* @return string
*/
public function getLogDir()
{
return sys_get_temp_dir() . '/ActivityBundle/logs';
}
public function registerBundles() public function registerBundles()
{ {
return array( return [
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new Chill\CustomFieldsBundle\ChillCustomFieldsBundle(), new Chill\CustomFieldsBundle\ChillCustomFieldsBundle(),
new Symfony\Bundle\SecurityBundle\SecurityBundle(), new Symfony\Bundle\SecurityBundle\SecurityBundle(),
@@ -20,28 +43,12 @@ class AppKernel extends Kernel
new \Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(), new \Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(),
new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(), new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(),
new Symfony\Bundle\MonologBundle\MonologBundle(), new Symfony\Bundle\MonologBundle\MonologBundle(),
#add here all the required bundle (some bundle are not required) //add here all the required bundle (some bundle are not required)
); ];
} }
public function registerContainerConfiguration(LoaderInterface $loader) public function registerContainerConfiguration(LoaderInterface $loader)
{ {
$loader->load($this->getRootDir().'/config/config_'.$this->getEnvironment().'.yml'); $loader->load($this->getRootDir() . '/config/config_' . $this->getEnvironment() . '.yml');
}
/**
* @return string
*/
public function getCacheDir()
{
return sys_get_temp_dir().'/ActivityBundle/cache';
}
/**
* @return string
*/
public function getLogDir()
{
return sys_get_temp_dir().'/ActivityBundle/logs';
} }
} }

View File

@@ -1,11 +1,18 @@
<?php <?php
use Doctrine\Common\Annotations\AnnotationRegistry; /**
* 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.
*/
use Composer\Autoload\ClassLoader; use Composer\Autoload\ClassLoader;
use Doctrine\Common\Annotations\AnnotationRegistry;
/** @var ClassLoader $loader */ /** @var ClassLoader $loader */
$loader = require __DIR__.'/../../../../../vendor/autoload.php'; $loader = require __DIR__ . '/../../../../../vendor/autoload.php';
AnnotationRegistry::registerLoader(array($loader, 'loadClass')); AnnotationRegistry::registerLoader([$loader, 'loadClass']);
return $loader; return $loader;

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,14 @@
<?php <?php
use Symfony\Component\HttpFoundation\Request; /**
* 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.
*/
use Symfony\Component\Debug\Debug; use Symfony\Component\Debug\Debug;
use Symfony\Component\HttpFoundation\Request;
// If you don't want to setup permissions the proper way, just uncomment the following PHP line // If you don't want to setup permissions the proper way, just uncomment the following PHP line
// read http://symfony.com/doc/current/book/installation.html#configuration-and-setup for more information // read http://symfony.com/doc/current/book/installation.html#configuration-and-setup for more information
@@ -11,16 +18,17 @@ use Symfony\Component\Debug\Debug;
// Feel free to remove this, extend it, or make something more sophisticated. // Feel free to remove this, extend it, or make something more sophisticated.
if (isset($_SERVER['HTTP_CLIENT_IP']) if (isset($_SERVER['HTTP_CLIENT_IP'])
|| isset($_SERVER['HTTP_X_FORWARDED_FOR']) || isset($_SERVER['HTTP_X_FORWARDED_FOR'])
|| !(in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1')) || php_sapi_name() === 'cli-server') || !(in_array(@$_SERVER['REMOTE_ADDR'], ['127.0.0.1', 'fe80::1', '::1']) || php_sapi_name() === 'cli-server')
) { ) {
header('HTTP/1.0 403 Forbidden'); header('HTTP/1.0 403 Forbidden');
exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
exit('You are not allowed to access this file. Check ' . basename(__FILE__) . ' for more information.');
} }
$loader = require_once __DIR__.'/../app/bootstrap.php.cache'; $loader = require_once __DIR__ . '/../app/bootstrap.php.cache';
Debug::enable(); Debug::enable();
require_once __DIR__.'/../app/AppKernel.php'; require_once __DIR__ . '/../app/AppKernel.php';
$kernel = new AppKernel('dev', true); $kernel = new AppKernel('dev', true);
$kernel->loadClassCache(); $kernel->loadClassCache();

View File

@@ -1,41 +1,27 @@
<?php <?php
/* /**
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop> * Chill is a software for social workers
* *
* This program is free software: you can redistribute it and/or modify * For the full copyright and license information, please view
* it under the terms of the GNU Affero General Public License as published by * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\Security\Authorization; namespace Chill\ActivityBundle\Security\Authorization;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Security\Authorization\AbstractChillVoter; use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper; use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface; use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
use Chill\MainBundle\Entity\Center; use function in_array;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ActivityStatsVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface class ActivityStatsVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface
{ {
const STATS = 'CHILL_ACTIVITY_STATS'; public const LISTS = 'CHILL_ACTIVITY_LIST';
const LISTS = 'CHILL_ACTIVITY_LIST';
public const STATS = 'CHILL_ACTIVITY_STATS';
/** /**
*
* @var AuthorizationHelper * @var AuthorizationHelper
*/ */
protected $helper; protected $helper;
@@ -45,25 +31,24 @@ class ActivityStatsVoter extends AbstractChillVoter implements ProvideRoleHierar
$this->helper = $helper; $this->helper = $helper;
} }
private function getAttributes() public function getRoles(): array
{ {
return array(self::STATS, self::LISTS); return $this->getAttributes();
}
public function getRolesWithHierarchy(): array
{
return ['Activity' => $this->getRoles()];
}
public function getRolesWithoutScope(): array
{
return $this->getAttributes();
} }
protected function getSupportedClasses() protected function getSupportedClasses()
{ {
return array(Center::class); return [Center::class];
}
protected function supports($attribute, $subject)
{
if ($subject instanceof Center
&& \in_array($attribute, $this->getAttributes())) {
return true;
}
return false;
} }
protected function isGranted($attribute, $object, $user = null) protected function isGranted($attribute, $object, $user = null)
@@ -75,18 +60,18 @@ class ActivityStatsVoter extends AbstractChillVoter implements ProvideRoleHierar
return $this->helper->userHasAccess($user, $object, $attribute); return $this->helper->userHasAccess($user, $object, $attribute);
} }
public function getRoles(): array protected function supports($attribute, $subject)
{ {
return $this->getAttributes(); if ($subject instanceof Center
&& in_array($attribute, $this->getAttributes())) {
return true;
}
return false;
} }
public function getRolesWithoutScope(): array private function getAttributes()
{ {
return $this->getAttributes(); return [self::STATS, self::LISTS];
}
public function getRolesWithHierarchy(): array
{
return ['Activity' => $this->getRoles()];
} }
} }

View File

@@ -1,21 +1,30 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Security\Authorization; namespace Chill\ActivityBundle\Security\Authorization;
use Chill\ActivityBundle\Entity\Activity;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface; use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface;
use Chill\MainBundle\Security\Authorization\VoterHelperInterface; use Chill\MainBundle\Security\Authorization\VoterHelperInterface;
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Chill\PersonBundle\Security\Authorization\PersonVoter; use Chill\PersonBundle\Security\Authorization\PersonVoter;
use RuntimeException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
use Chill\MainBundle\Entity\User;
use Chill\ActivityBundle\Entity\Activity;
use Chill\PersonBundle\Entity\Person;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use function in_array;
class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface
{ {
@@ -30,40 +39,44 @@ class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn
/** /**
* role to allow to create an activity associated win an accompanying course. * role to allow to create an activity associated win an accompanying course.
* *
* Before using this, check if @link{self::CREATE} is not sufficiant * Before using this, check if @see{self::CREATE} is not sufficiant
* *
* @internal * @internal
*/ */
public const CREATE_ACCOMPANYING_COURSE = 'CHILL_ACTIVITY_CREATE_ACCOMPANYING_COURSE'; public const CREATE_ACCOMPANYING_COURSE = 'CHILL_ACTIVITY_CREATE_ACCOMPANYING_COURSE';
/** /**
* role to allow to create an activity associated with a person * role to allow to create an activity associated with a person.
* *
* Before using this, check if @link{self::CREATE} is not sufficiant * Before using this, check if @see{self::CREATE} is not sufficiant
* *
* @internal * @internal
*/ */
public const CREATE_PERSON = 'CHILL_ACTIVITY_CREATE_PERSON'; public const CREATE_PERSON = 'CHILL_ACTIVITY_CREATE_PERSON';
public const SEE = 'CHILL_ACTIVITY_SEE';
public const SEE_DETAILS = 'CHILL_ACTIVITY_SEE_DETAILS';
public const UPDATE = 'CHILL_ACTIVITY_UPDATE';
public const DELETE = 'CHILL_ACTIVITY_DELETE'; public const DELETE = 'CHILL_ACTIVITY_DELETE';
public const FULL = 'CHILL_ACTIVITY_FULL'; public const FULL = 'CHILL_ACTIVITY_FULL';
public const SEE = 'CHILL_ACTIVITY_SEE';
public const SEE_DETAILS = 'CHILL_ACTIVITY_SEE_DETAILS';
public const UPDATE = 'CHILL_ACTIVITY_UPDATE';
private const ALL = [ private const ALL = [
self::CREATE, self::CREATE,
self::SEE, self::SEE,
self::UPDATE, self::UPDATE,
self::DELETE, self::DELETE,
self::SEE_DETAILS, self::SEE_DETAILS,
self::FULL self::FULL,
]; ];
protected VoterHelperInterface $voterHelper;
protected Security $security; protected Security $security;
protected VoterHelperInterface $voterHelper;
public function __construct( public function __construct(
Security $security, Security $security,
VoterHelperFactoryInterface $voterHelperFactory VoterHelperFactoryInterface $voterHelperFactory
@@ -76,6 +89,27 @@ class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn
->build(); ->build();
} }
public function getRoles(): array
{
return [
self::CREATE_PERSON,
self::CREATE_ACCOMPANYING_COURSE,
self::UPDATE,
self::DELETE,
self::FULL,
];
}
public function getRolesWithHierarchy(): array
{
return ['Activity' => $this->getRoles()];
}
public function getRolesWithoutScope(): array
{
return [];
}
protected function supports($attribute, $subject): bool protected function supports($attribute, $subject): bool
{ {
return $this->voterHelper->supports($attribute, $subject); return $this->voterHelper->supports($attribute, $subject);
@@ -110,11 +144,11 @@ class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn
$attribute = self::CREATE_ACCOMPANYING_COURSE; $attribute = self::CREATE_ACCOMPANYING_COURSE;
} }
} else { } else {
throw new \RuntimeException('Could not determine context of activity.'); throw new RuntimeException('Could not determine context of activity.');
} }
} elseif ($subject instanceof AccompanyingPeriod) { } elseif ($subject instanceof AccompanyingPeriod) {
if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) { if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) {
if (\in_array($attribute, [self::UPDATE, self::CREATE, self::DELETE], true)) { if (in_array($attribute, [self::UPDATE, self::CREATE, self::DELETE], true)) {
return false; return false;
} }
} }
@@ -132,26 +166,4 @@ class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn
return $this->voterHelper->voteOnAttribute($attribute, $subject, $token); return $this->voterHelper->voteOnAttribute($attribute, $subject, $token);
} }
public function getRoles(): array
{
return [
self::CREATE_PERSON,
self::CREATE_ACCOMPANYING_COURSE,
self::UPDATE,
self::DELETE,
self::FULL
];
}
public function getRolesWithoutScope(): array
{
return [];
}
public function getRolesWithHierarchy(): array
{
return ['Activity' => $this->getRoles()];
}
} }

View File

@@ -1,37 +1,24 @@
<?php <?php
/*
/**
* Chill is a software for social workers * Chill is a software for social workers
* *
* Copyright (C) 2014-2020, Champs Libres Cooperative SCRLFS, * For the full copyright and license information, please view
* <http://www.champs-libres.coop>, <info@champs-libres.coop> * the LICENSE file that was distributed with this source code.
*
* 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\ActivityBundle\Templating\Entity; namespace Chill\ActivityBundle\Templating\Entity;
use Chill\MainBundle\Templating\Entity\AbstractChillEntityRender;
use Chill\ActivityBundle\Entity\ActivityReason; use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\MainBundle\Templating\Entity\AbstractChillEntityRender;
use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\MainBundle\Templating\TranslatableStringHelper;
/** /**
* Render activity reason * Render activity reason.
*
*/ */
class ActivityReasonRender extends AbstractChillEntityRender class ActivityReasonRender extends AbstractChillEntityRender
{ {
/** /**
*
* @var TranslatableStringHelper * @var TranslatableStringHelper
*/ */
protected $translatableStringHelper; protected $translatableStringHelper;
@@ -41,34 +28,29 @@ class ActivityReasonRender extends AbstractChillEntityRender
$this->translatableStringHelper = $translatableStringHelper; $this->translatableStringHelper = $translatableStringHelper;
} }
public function renderBox($entity, array $options): string public function renderBox($entity, array $options): string
{ {
return return
$this->getDefaultOpeningBox('activity-reason'). $this->getDefaultOpeningBox('activity-reason') .
'<span class="badge bg-chill-pink">'. '<span class="badge bg-chill-pink">' .
'<i class="fa fa-question-circle"></i>&nbsp;'. '<i class="fa fa-question-circle"></i>&nbsp;' .
'<span class="category">'. '<span class="category">' .
$this->translatableStringHelper->localize( $this->translatableStringHelper->localize(
$entity->getCategory()->getName() $entity->getCategory()->getName()
). ) .
'</span>'. '</span>' .
'<span class="separator">&nbsp;>&nbsp;</span>'. '<span class="separator">&nbsp;>&nbsp;</span>' .
'<span class="reason">'. '<span class="reason">' .
$this->translatableStringHelper->localize( $this->translatableStringHelper->localize(
$entity->getName() $entity->getName()
). ) .
'</span>'. '</span>' .
'</span>'. '</span>' .
$this->getDefaultClosingBox() $this->getDefaultClosingBox();
;
} }
/** /**
*
* @param ActivityReason $entity * @param ActivityReason $entity
* @param array $options
* @return string
*/ */
public function renderString($entity, array $options): string public function renderString($entity, array $options): string
{ {
@@ -76,7 +58,8 @@ class ActivityReasonRender extends AbstractChillEntityRender
if (null !== $entity->getCategory()) { if (null !== $entity->getCategory()) {
$category = $this->translatableStringHelper->localize( $category = $this->translatableStringHelper->localize(
$entity->getCategory()->getName()). ' > '; $entity->getCategory()->getName()
) . ' > ';
} }
return $category . return $category .

View File

@@ -1,20 +1,10 @@
<?php <?php
/* /**
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop> * Chill is a software for social workers
* *
* This program is free software: you can redistribute it and/or modify * For the full copyright and license information, please view
* it under the terms of the GNU Affero General Public License as published by * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\Test; namespace Chill\ActivityBundle\Test;
@@ -24,26 +14,19 @@ use Chill\MainBundle\Entity\Scope;
use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\Person;
/** /**
* Prepare entities useful in tests * Prepare entities useful in tests.
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/ */
trait PrepareActivityTrait trait PrepareActivityTrait
{ {
/** /**
* Return an activity with a scope and a person inside * Return an activity with a scope and a person inside.
* *
* @param Scope $scope
* @param Person $person
* @return Activity * @return Activity
*/ */
public function prepareActivity(Scope $scope, Person $person) public function prepareActivity(Scope $scope, Person $person)
{ {
return (new Activity()) return (new Activity())
->setScope($scope) ->setScope($scope)
->setPerson($person) ->setPerson($person);
;
} }
} }

View File

@@ -1,16 +1,78 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Controller; namespace Chill\ActivityBundle\Tests\Controller;
use RuntimeException;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\HttpFoundation\Response;
/**
* @internal
* @coversNothing
*/
class ActivityControllerTest extends WebTestCase class ActivityControllerTest extends WebTestCase
{ {
public function getSecuredPagesAuthenticated()
{
static::bootKernel();
$person = $this->getPersonFromFixtures();
$activities = $this->getActivitiesForPerson($person);
$user = $this->createFakeUser();
return [
[
$this->getAuthenticatedClient('center b_social'),
sprintf('fr/person/%d/activity/', $person->getId()),
],
[
$this->getAuthenticatedClient('center b_social'),
sprintf('fr/person/%d/activity/new', $person->getId()),
],
[
$this->getAuthenticatedClient('center b_social'),
sprintf('fr/person/%d/activity/%d/show', $person->getId(), $activities[0]->getId()),
],
[
$this->getAuthenticatedClient('center b_social'),
sprintf('fr/person/%d/activity/%d/edit', $person->getId(), $activities[0]->getId()),
],
[
$this->getAuthenticatedClient($user->getUsername()),
sprintf('fr/person/%d/activity/new', $person->getId()),
],
];
}
/**
* Provide a client unauthenticated and.
*/
public function getSecuredPagesUnauthenticated()
{
static::bootKernel();
$person = $this->getPersonFromFixtures();
$activities = $this->getActivitiesForPerson($person);
return [
[sprintf('fr/person/%d/activity/', $person->getId())],
[sprintf('fr/person/%d/activity/new', $person->getId())],
[sprintf('fr/person/%d/activity/%d/show', $person->getId(), $activities[0]->getId())],
[sprintf('fr/person/%d/activity/%d/edit', $person->getId(), $activities[0]->getId())],
];
}
/** /**
* @dataProvider getSecuredPagesUnauthenticated * @dataProvider getSecuredPagesUnauthenticated
*
* @param mixed $url
*/ */
public function testAccessIsDeniedForUnauthenticated($url) public function testAccessIsDeniedForUnauthenticated($url)
{ {
@@ -19,13 +81,15 @@ class ActivityControllerTest extends WebTestCase
$client->request('GET', $url); $client->request('GET', $url);
$this->assertEquals(302, $client->getResponse()->getStatusCode()); $this->assertEquals(302, $client->getResponse()->getStatusCode());
$this->assertTrue($client->getResponse()->isRedirect('http://localhost/login'), $this->assertTrue(
sprintf('the page "%s" does not redirect to http://localhost/login', $url)); $client->getResponse()->isRedirect('http://localhost/login'),
sprintf('the page "%s" does not redirect to http://localhost/login', $url)
);
} }
/** /**
*
* @dataProvider getSecuredPagesAuthenticated * @dataProvider getSecuredPagesAuthenticated
*
* @param type $client * @param type $client
* @param type $url * @param type $url
*/ */
@@ -36,63 +100,6 @@ class ActivityControllerTest extends WebTestCase
$this->assertEquals(403, $client->getResponse()->getStatusCode()); $this->assertEquals(403, $client->getResponse()->getStatusCode());
} }
public function getSecuredPagesAuthenticated()
{
static::bootKernel();
$person = $this->getPersonFromFixtures();
$activities = $this->getActivitiesForPerson($person);
$user = $this->createFakeUser();
return array(
array(
$this->getAuthenticatedClient('center b_social'),
sprintf('fr/person/%d/activity/', $person->getId())
),
array(
$this->getAuthenticatedClient('center b_social'),
sprintf('fr/person/%d/activity/new', $person->getId())
),
array(
$this->getAuthenticatedClient('center b_social'),
sprintf('fr/person/%d/activity/%d/show', $person->getId(), $activities[0]->getId())
),
array(
$this->getAuthenticatedClient('center b_social'),
sprintf('fr/person/%d/activity/%d/edit', $person->getId(), $activities[0]->getId())
),
array(
$this->getAuthenticatedClient($user->getUsername()),
sprintf('fr/person/%d/activity/new', $person->getId())
)
);
}
/**
* Provide a client unauthenticated and
*
*/
public function getSecuredPagesUnauthenticated()
{
static::bootKernel();
$person = $this->getPersonFromFixtures();
$activities = $this->getActivitiesForPerson($person);
return array(
[ sprintf('fr/person/%d/activity/', $person->getId()) ],
[ sprintf('fr/person/%d/activity/new', $person->getId()) ],
[ sprintf('fr/person/%d/activity/%d/show', $person->getId(), $activities[0]->getId()) ],
[ sprintf('fr/person/%d/activity/%d/edit', $person->getId(), $activities[0]->getId()) ],
);
}
public function testCompleteScenario() public function testCompleteScenario()
{ {
// Create a new client to browse the application // Create a new client to browse the application
@@ -100,27 +107,32 @@ class ActivityControllerTest extends WebTestCase
$person = $this->getPersonFromFixtures(); $person = $this->getPersonFromFixtures();
// Create a new entry in the database // Create a new entry in the database
$crawler = $client->request('GET', sprintf('en/person/%d/activity/', $crawler = $client->request('GET', sprintf(
$person->getId())); 'en/person/%d/activity/',
$this->assertEquals(200, $client->getResponse()->getStatusCode(), $person->getId()
"Unexpected HTTP status code for GET /activity/"); ));
$this->assertEquals(
200,
$client->getResponse()->getStatusCode(),
'Unexpected HTTP status code for GET /activity/'
);
$crawler = $client->click($crawler->selectLink('Ajouter une nouvelle activité') $crawler = $client->click($crawler->selectLink('Ajouter une nouvelle activité')
->link()); ->link());
$reason1 = $this->getRandomActivityReason(); $reason1 = $this->getRandomActivityReason();
$reason2 = $this->getRandomActivityReason(array($reason1->getId())); $reason2 = $this->getRandomActivityReason([$reason1->getId()]);
// Fill in the form and submit it // Fill in the form and submit it
$form = $crawler->selectButton('Ajouter une nouvelle activité')->form(array( $form = $crawler->selectButton('Ajouter une nouvelle activité')->form([
'chill_activitybundle_activity'=> array( 'chill_activitybundle_activity' => [
'date' => '15-01-2015', 'date' => '15-01-2015',
'durationTime' => 600, 'durationTime' => 600,
// 'remark' => 'blabla', // 'remark' => 'blabla',
'scope' => $this->getRandomScope('center a_social', 'Center A')->getId(), 'scope' => $this->getRandomScope('center a_social', 'Center A')->getId(),
'type' => $this->getRandomActivityType()->getId() 'type' => $this->getRandomActivityType()->getId(),
) ],
)); ]);
$form['chill_activitybundle_activity[reasons]']->select(array ($reason1->getId(), $reason2->getId())); $form['chill_activitybundle_activity[reasons]']->select([$reason1->getId(), $reason2->getId()]);
$client->submit($form); $client->submit($form);
@@ -128,18 +140,21 @@ class ActivityControllerTest extends WebTestCase
$crawler = $client->followRedirect(); $crawler = $client->followRedirect();
// Check data in the show view // Check data in the show view
$this->assertGreaterThan(0, $crawler->filter('dd:contains("January 15, 2015")')->count(), $this->assertGreaterThan(
'Missing element dd:contains("January 15, 2015")'); 0,
$crawler->filter('dd:contains("January 15, 2015")')->count(),
'Missing element dd:contains("January 15, 2015")'
);
// Edit the entity // Edit the entity
$crawler = $client->click($crawler->selectLink("Modifier l'activité")->link()); $crawler = $client->click($crawler->selectLink("Modifier l'activité")->link());
$form = $crawler->selectButton("Sauver l'activité")->form(array( $form = $crawler->selectButton("Sauver l'activité")->form([
'chill_activitybundle_activity' => array( 'chill_activitybundle_activity' => [
'date' => '25-01-2015', 'date' => '25-01-2015',
// 'remark' => 'Foo' // 'remark' => 'Foo'
) ],
)); ]);
$client->submit($form); $client->submit($form);
@@ -148,164 +163,33 @@ class ActivityControllerTest extends WebTestCase
$crawler = $client->followRedirect(); $crawler = $client->followRedirect();
// check that new data are present // check that new data are present
$this->assertGreaterThan(0, $this->assertGreaterThan(
$crawler->filter('dd:contains("January 25, 2015")')->count(), 0,
'Missing element dd:contains("January 25, 2015")'); $crawler->filter('dd:contains("January 25, 2015")')->count(),
$this->assertGreaterThan(0, 'Missing element dd:contains("January 25, 2015")'
$crawler->filter('dd:contains("Foo")')->count(), );
'Missing element dd:contains("Foo")'); $this->assertGreaterThan(
0,
$crawler->filter('dd:contains("Foo")')->count(),
'Missing element dd:contains("Foo")'
);
// delete the actvity // delete the actvity
$crawler = $client->click($crawler->selectLink("Supprimer")->link()); $crawler = $client->click($crawler->selectLink('Supprimer')->link());
$button = $crawler->selectButton('Supprimer'); $button = $crawler->selectButton('Supprimer');
$form = $button->form(); $form = $button->form();
$client->submit($form); $client->submit($form);
$this->assertTrue($client->getResponse()->isRedirect(sprintf('/en/person/%d/activity/', $this->assertTrue($client->getResponse()->isRedirect(sprintf(
$person->getId()))); '/en/person/%d/activity/',
$person->getId()
)));
$crawler = $client->followRedirect(); $crawler = $client->followRedirect();
$this->assertNotContains('January 25, 2015', $crawler->text()); $this->assertNotContains('January 25, 2015', $crawler->text());
}
/**
*
* @return \Symfony\Component\BrowserKit\Client
*/
private function getAuthenticatedClient($username = 'center a_social')
{
return static::createClient(array(), array(
'PHP_AUTH_USER' => $username,
'PHP_AUTH_PW' => 'password',
));
}
/**
*
* @return \Chill\PersonBundle\Entity\Person
*/
private function getPersonFromFixtures()
{
$em = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager');
$person = $em->getRepository('ChillPersonBundle:Person')
->findOneBy(array(
'firstName' => 'Depardieu',
'lastName' => 'Gérard'
));
if ($person === NULL) {
throw new \RuntimeException("We need a person with firstname Gérard and"
. " lastname Depardieu. Did you add fixtures ?");
}
return $person;
}
private function getActivitiesForPerson(\Chill\PersonBundle\Entity\Person $person)
{
$em = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager');
$activities = $em->getRepository('ChillActivityBundle:Activity')
->findBy(array('person' => $person));
if (count($activities) === 0) {
throw new \RuntimeException("We need activities associated with this "
. "person. Did you forget to add fixtures ?");
}
return $activities;
}
/**
*
* @param string $username
* @param string $centerName
* @return \Chill\MainBundle\Entity\Scope
*/
private function getRandomScope($username, $centerName)
{
$user = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('ChillMainBundle:User')
->findOneByUsername($username);
if ($user === NULL) {
throw new \RuntimeException("The user with username $username "
. "does not exists in database. Did you add fixtures ?");
}
$center = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('ChillMainBundle:Center')
->findOneByName($centerName);
// get scope reachable by both role UPDATE and DELETE
$reachableScopesUpdate = static::$kernel->getContainer()
->get('chill.main.security.authorization.helper')
->getReachableScopes($user, new Role('CHILL_ACTIVITY_UPDATE'),
$center);
$reachableScopesDelete = static::$kernel->getContainer()
->get('chill.main.security.authorization.helper')
->getReachableScopes($user, new Role('CHILL_ACTIVITY_DELETE'),
$center);
$reachableScopesId = array_intersect(
array_map(function ($s) { return $s->getId(); }, $reachableScopesDelete),
array_map(function ($s) { return $s->getId(); }, $reachableScopesUpdate)
);
if (count($reachableScopesId) === 0) {
throw new \RuntimeException("there are not scope reachable for "
. "both CHILL_ACTIVITY_UPDATE and CHILL_ACTIVITY_DELETE");
}
foreach($reachableScopesUpdate as $scope) {
if (in_array($scope->getId(), $reachableScopesId)) {
$reachableScopes[] = $scope;
}
}
return $reachableScopes[array_rand($reachableScopes)];
}
/**
*
* @param int[] $excludeIds An array of id to exclude
* @return \Chill\ActivityBundle\Entity\ActivityReason
*/
private function getRandomActivityReason(array $excludeIds = array())
{
$reasons = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('ChillActivityBundle:ActivityReason')
->findAll();
$reason = $reasons[array_rand($reasons)];
if (in_array($reason->getId(), $excludeIds)) {
return $this->getRandomActivityReason($excludeIds);
}
return $reason;
}
/**
*
* @return \Chill\ActivityBundle\Entity\ActivityType
*/
private function getRandomActivityType()
{
$types = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('ChillActivityBundle:ActivityType')
->findAll();
return $types[array_rand($types)];
} }
/** /**
@@ -321,10 +205,10 @@ class ActivityControllerTest extends WebTestCase
//get the social PermissionGroup, and remove CHILL_ACTIVITY_* //get the social PermissionGroup, and remove CHILL_ACTIVITY_*
$socialPermissionGroup = $em $socialPermissionGroup = $em
->getRepository('ChillMainBundle:PermissionsGroup') ->getRepository('ChillMainBundle:PermissionsGroup')
->findOneByName('social'); ->findOneByName('social');
$withoutActivityPermissionGroup = (new \Chill\MainBundle\Entity\PermissionsGroup()) $withoutActivityPermissionGroup = (new \Chill\MainBundle\Entity\PermissionsGroup())
->setName('social without activity'); ->setName('social without activity');
//copy role scopes where ACTIVITY is not present //copy role scopes where ACTIVITY is not present
foreach ($socialPermissionGroup->getRoleScopes() as $roleScope) { foreach ($socialPermissionGroup->getRoleScopes() as $roleScope) {
if (!strpos($roleScope->getRole(), 'ACTIVITY')) { if (!strpos($roleScope->getRole(), 'ACTIVITY')) {
@@ -334,8 +218,8 @@ class ActivityControllerTest extends WebTestCase
//create groupCenter //create groupCenter
$groupCenter = new \Chill\MainBundle\Entity\GroupCenter(); $groupCenter = new \Chill\MainBundle\Entity\GroupCenter();
$groupCenter->setCenter($em->getRepository('ChillMainBundle:Center') $groupCenter->setCenter($em->getRepository('ChillMainBundle:Center')
->findOneBy(array('name' => 'Center A'))) ->findOneBy(['name' => 'Center A']))
->setPermissionsGroup($withoutActivityPermissionGroup); ->setPermissionsGroup($withoutActivityPermissionGroup);
$em->persist($withoutActivityPermissionGroup); $em->persist($withoutActivityPermissionGroup);
$em->persist($groupCenter); $em->persist($groupCenter);
@@ -344,10 +228,10 @@ class ActivityControllerTest extends WebTestCase
$username = $faker->name; $username = $faker->name;
$user = new \Chill\MainBundle\Entity\User(); $user = new \Chill\MainBundle\Entity\User();
$user $user
->setPassword($container->get('security.password_encoder') ->setPassword($container->get('security.password_encoder')
->encodePassword($user, 'password')) ->encodePassword($user, 'password'))
->setUsername($username) ->setUsername($username)
->addGroupCenter($groupCenter); ->addGroupCenter($groupCenter);
$em->persist($user); $em->persist($user);
@@ -355,4 +239,146 @@ class ActivityControllerTest extends WebTestCase
return $user; return $user;
} }
private function getActivitiesForPerson(\Chill\PersonBundle\Entity\Person $person)
{
$em = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager');
$activities = $em->getRepository('ChillActivityBundle:Activity')
->findBy(['person' => $person]);
if (count($activities) === 0) {
throw new RuntimeException('We need activities associated with this '
. 'person. Did you forget to add fixtures ?');
}
return $activities;
}
/**
* @param mixed $username
*
* @return \Symfony\Component\BrowserKit\Client
*/
private function getAuthenticatedClient($username = 'center a_social')
{
return static::createClient([], [
'PHP_AUTH_USER' => $username,
'PHP_AUTH_PW' => 'password',
]);
}
/**
* @return \Chill\PersonBundle\Entity\Person
*/
private function getPersonFromFixtures()
{
$em = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager');
$person = $em->getRepository('ChillPersonBundle:Person')
->findOneBy([
'firstName' => 'Depardieu',
'lastName' => 'Gérard',
]);
if (null === $person) {
throw new RuntimeException('We need a person with firstname Gérard and'
. ' lastname Depardieu. Did you add fixtures ?');
}
return $person;
}
/**
* @param int[] $excludeIds An array of id to exclude
*
* @return \Chill\ActivityBundle\Entity\ActivityReason
*/
private function getRandomActivityReason(array $excludeIds = [])
{
$reasons = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('ChillActivityBundle:ActivityReason')
->findAll();
$reason = $reasons[array_rand($reasons)];
if (in_array($reason->getId(), $excludeIds)) {
return $this->getRandomActivityReason($excludeIds);
}
return $reason;
}
/**
* @return \Chill\ActivityBundle\Entity\ActivityType
*/
private function getRandomActivityType()
{
$types = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('ChillActivityBundle:ActivityType')
->findAll();
return $types[array_rand($types)];
}
/**
* @param string $username
* @param string $centerName
*
* @return \Chill\MainBundle\Entity\Scope
*/
private function getRandomScope($username, $centerName)
{
$user = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('ChillMainBundle:User')
->findOneByUsername($username);
if (null === $user) {
throw new RuntimeException("The user with username {$username} "
. 'does not exists in database. Did you add fixtures ?');
}
$center = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('ChillMainBundle:Center')
->findOneByName($centerName);
// get scope reachable by both role UPDATE and DELETE
$reachableScopesUpdate = static::$kernel->getContainer()
->get('chill.main.security.authorization.helper')
->getReachableScopes(
$user,
new Role('CHILL_ACTIVITY_UPDATE'),
$center
);
$reachableScopesDelete = static::$kernel->getContainer()
->get('chill.main.security.authorization.helper')
->getReachableScopes(
$user,
new Role('CHILL_ACTIVITY_DELETE'),
$center
);
$reachableScopesId = array_intersect(
array_map(function ($s) { return $s->getId(); }, $reachableScopesDelete),
array_map(function ($s) { return $s->getId(); }, $reachableScopesUpdate)
);
if (count($reachableScopesId) === 0) {
throw new RuntimeException('there are not scope reachable for '
. 'both CHILL_ACTIVITY_UPDATE and CHILL_ACTIVITY_DELETE');
}
foreach ($reachableScopesUpdate as $scope) {
if (in_array($scope->getId(), $reachableScopesId)) {
$reachableScopes[] = $scope;
}
}
return $reachableScopes[array_rand($reachableScopes)];
}
} }

View File

@@ -1,15 +1,27 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Controller; namespace Chill\ActivityBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
/**
* @internal
* @coversNothing
*/
class ActivityReasonCategoryControllerTest extends WebTestCase class ActivityReasonCategoryControllerTest extends WebTestCase
{ {
public function testToWrite() public function testToWrite()
{ {
$this->markTestSkipped(); $this->markTestSkipped();
} }
/* /*
public function testCompleteScenario() public function testCompleteScenario()
{ {
@@ -55,5 +67,5 @@ class ActivityReasonCategoryControllerTest extends WebTestCase
$this->assertNotRegExp('/Foo/', $client->getResponse()->getContent()); $this->assertNotRegExp('/Foo/', $client->getResponse()->getContent());
} }
*/ */
} }

View File

@@ -1,15 +1,27 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Controller; namespace Chill\ActivityBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
/**
* @internal
* @coversNothing
*/
class ActivityReasonControllerTest extends WebTestCase class ActivityReasonControllerTest extends WebTestCase
{ {
public function testToWrite() public function testToWrite()
{ {
$this->markTestSkipped(); $this->markTestSkipped();
} }
/* /*
public function testCompleteScenario() public function testCompleteScenario()
{ {
@@ -55,5 +67,5 @@ class ActivityReasonControllerTest extends WebTestCase
$this->assertNotRegExp('/Foo/', $client->getResponse()->getContent()); $this->assertNotRegExp('/Foo/', $client->getResponse()->getContent());
} }
*/ */
} }

View File

@@ -1,15 +1,27 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Controller; namespace Chill\ActivityBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
/**
* @internal
* @coversNothing
*/
class ActivityTypeControllerTest extends WebTestCase class ActivityTypeControllerTest extends WebTestCase
{ {
public function testToWrite() public function testToWrite()
{ {
$this->markTestSkipped(); $this->markTestSkipped();
} }
/* /*
public function testCompleteScenario() public function testCompleteScenario()
{ {
@@ -55,5 +67,5 @@ class ActivityTypeControllerTest extends WebTestCase
$this->assertNotRegExp('/Foo/', $client->getResponse()->getContent()); $this->assertNotRegExp('/Foo/', $client->getResponse()->getContent());
} }
*/ */
} }

View File

@@ -1,20 +1,10 @@
<?php <?php
/* /**
* Copyright (C) 2017 Champs-Libres <info@champs-libres.coop> * Chill is a software for social workers
* *
* This program is free software: you can redistribute it and/or modify * For the full copyright and license information, please view
* it under the terms of the GNU Affero General Public License as published by * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\Tests\Aggregator; namespace Chill\ActivityBundle\Tests\Aggregator;
@@ -22,59 +12,59 @@ namespace Chill\ActivityBundle\Tests\Aggregator;
use Chill\MainBundle\Test\Export\AbstractAggregatorTest; use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
/** /**
* Add tests for ActivityReasonAggregator * Add tests for ActivityReasonAggregator.
* *
* @author Julien Fastré <julien.fastre@champs-libres.coop> * @internal
* @coversNothing
*/ */
class ActivityReasonAggregatorTest extends AbstractAggregatorTest class ActivityReasonAggregatorTest extends AbstractAggregatorTest
{ {
/** /**
*
* @var \Chill\ActivityBundle\Export\Aggregator\ActivityReasonAggregator * @var \Chill\ActivityBundle\Export\Aggregator\ActivityReasonAggregator
*/ */
private $aggregator; private $aggregator;
public function setUp() public function setUp()
{ {
static::bootKernel(); static::bootKernel();
$container = static::$kernel->getContainer(); $container = static::$kernel->getContainer();
$this->aggregator = $container->get('chill.activity.export.reason_aggregator'); $this->aggregator = $container->get('chill.activity.export.reason_aggregator');
// add a fake request with a default locale (used in translatable string) // add a fake request with a default locale (used in translatable string)
$prophet = new \Prophecy\Prophet; $prophet = new \Prophecy\Prophet();
$request = $prophet->prophesize(); $request = $prophet->prophesize();
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class); $request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
$request->getLocale()->willReturn('fr'); $request->getLocale()->willReturn('fr');
$container->get('request_stack') $container->get('request_stack')
->push($request->reveal()); ->push($request->reveal());
} }
public function getAggregator() public function getAggregator()
{ {
return $this->aggregator; return $this->aggregator;
} }
public function getFormData() public function getFormData()
{ {
return array( return [
array('level' => 'reasons'), ['level' => 'reasons'],
array('level' => 'categories') ['level' => 'categories'],
); ];
} }
public function getQueryBuilders() public function getQueryBuilders()
{ {
if (static::$kernel === null) { if (null === static::$kernel) {
static::bootKernel(); static::bootKernel();
} }
$em = static::$kernel->getContainer() $em = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager'); ->get('doctrine.orm.entity_manager');
return array( return [
$em->createQueryBuilder() $em->createQueryBuilder()
->select('count(activity.id)') ->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity'), ->from('ChillActivityBundle:Activity', 'activity'),
@@ -86,8 +76,7 @@ class ActivityReasonAggregatorTest extends AbstractAggregatorTest
->select('count(activity.id)') ->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity') ->from('ChillActivityBundle:Activity', 'activity')
->join('activity.reasons', 'reasons') ->join('activity.reasons', 'reasons')
->join('reasons.category', 'category') ->join('reasons.category', 'category'),
); ];
} }
} }

View File

@@ -1,20 +1,10 @@
<?php <?php
/* /**
* Copyright (C) 2017 Champs-Libres <info@champs-libres.coop> * Chill is a software for social workers
* *
* This program is free software: you can redistribute it and/or modify * For the full copyright and license information, please view
* it under the terms of the GNU Affero General Public License as published by * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\Tests\Aggregator; namespace Chill\ActivityBundle\Tests\Aggregator;
@@ -22,58 +12,58 @@ namespace Chill\ActivityBundle\Tests\Aggregator;
use Chill\MainBundle\Test\Export\AbstractAggregatorTest; use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
/** /**
* Add tests for ActivityTypeAggregator * Add tests for ActivityTypeAggregator.
* *
* @author Julien Fastré <julien.fastre@champs-libres.coop> * @internal
* @coversNothing
*/ */
class ActivityTypeAggregatorTest extends AbstractAggregatorTest class ActivityTypeAggregatorTest extends AbstractAggregatorTest
{ {
/** /**
*
* @var \Chill\ActivityBundle\Export\Aggregator\ActivityReasonAggregator * @var \Chill\ActivityBundle\Export\Aggregator\ActivityReasonAggregator
*/ */
private $aggregator; private $aggregator;
public function setUp() public function setUp()
{ {
static::bootKernel(); static::bootKernel();
$container = static::$kernel->getContainer(); $container = static::$kernel->getContainer();
$this->aggregator = $container->get('chill.activity.export.type_aggregator'); $this->aggregator = $container->get('chill.activity.export.type_aggregator');
// add a fake request with a default locale (used in translatable string) // add a fake request with a default locale (used in translatable string)
$prophet = new \Prophecy\Prophet; $prophet = new \Prophecy\Prophet();
$request = $prophet->prophesize(); $request = $prophet->prophesize();
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class); $request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
$request->getLocale()->willReturn('fr'); $request->getLocale()->willReturn('fr');
$container->get('request_stack') $container->get('request_stack')
->push($request->reveal()); ->push($request->reveal());
} }
public function getAggregator() public function getAggregator()
{ {
return $this->aggregator; return $this->aggregator;
} }
public function getFormData() public function getFormData()
{ {
return array( return [
array() [],
); ];
} }
public function getQueryBuilders() public function getQueryBuilders()
{ {
if (static::$kernel === null) { if (null === static::$kernel) {
static::bootKernel(); static::bootKernel();
} }
$em = static::$kernel->getContainer() $em = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager'); ->get('doctrine.orm.entity_manager');
return array( return [
$em->createQueryBuilder() $em->createQueryBuilder()
->select('count(activity.id)') ->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity'), ->from('ChillActivityBundle:Activity', 'activity'),
@@ -85,8 +75,7 @@ class ActivityTypeAggregatorTest extends AbstractAggregatorTest
->select('count(activity.id)') ->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity') ->from('ChillActivityBundle:Activity', 'activity')
->join('activity.reasons', 'reasons') ->join('activity.reasons', 'reasons')
->join('reasons.category', 'category') ->join('reasons.category', 'category'),
); ];
} }
} }

View File

@@ -1,20 +1,10 @@
<?php <?php
/* /**
* Copyright (C) 2017 Champs-Libres <info@champs-libres.coop> * Chill is a software for social workers
* *
* This program is free software: you can redistribute it and/or modify * For the full copyright and license information, please view
* it under the terms of the GNU Affero General Public License as published by * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\Tests\Aggregator; namespace Chill\ActivityBundle\Tests\Aggregator;
@@ -22,57 +12,58 @@ namespace Chill\ActivityBundle\Tests\Aggregator;
use Chill\MainBundle\Test\Export\AbstractAggregatorTest; use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
/** /**
* Add tests for ActivityUsernAggregator * Add tests for ActivityUsernAggregator.
* *
* @internal
* @coversNothing
*/ */
class ActivityUserAggregatorTest extends AbstractAggregatorTest class ActivityUserAggregatorTest extends AbstractAggregatorTest
{ {
/** /**
*
* @var \Chill\ActivityBundle\Export\Aggregator\ActivityUserAggregator * @var \Chill\ActivityBundle\Export\Aggregator\ActivityUserAggregator
*/ */
private $aggregator; private $aggregator;
public function setUp() public function setUp()
{ {
static::bootKernel(); static::bootKernel();
$container = static::$kernel->getContainer(); $container = static::$kernel->getContainer();
$this->aggregator = $container->get('chill.activity.export.user_aggregator'); $this->aggregator = $container->get('chill.activity.export.user_aggregator');
// add a fake request with a default locale (used in translatable string) // add a fake request with a default locale (used in translatable string)
$prophet = new \Prophecy\Prophet; $prophet = new \Prophecy\Prophet();
$request = $prophet->prophesize(); $request = $prophet->prophesize();
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class); $request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
$request->getLocale()->willReturn('fr'); $request->getLocale()->willReturn('fr');
$container->get('request_stack') $container->get('request_stack')
->push($request->reveal()); ->push($request->reveal());
} }
public function getAggregator() public function getAggregator()
{ {
return $this->aggregator; return $this->aggregator;
} }
public function getFormData() public function getFormData()
{ {
return array( return [
array() [],
); ];
} }
public function getQueryBuilders() public function getQueryBuilders()
{ {
if (static::$kernel === null) { if (null === static::$kernel) {
static::bootKernel(); static::bootKernel();
} }
$em = static::$kernel->getContainer() $em = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager'); ->get('doctrine.orm.entity_manager');
return array( return [
$em->createQueryBuilder() $em->createQueryBuilder()
->select('count(activity.id)') ->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity'), ->from('ChillActivityBundle:Activity', 'activity'),
@@ -84,8 +75,7 @@ class ActivityUserAggregatorTest extends AbstractAggregatorTest
->select('count(activity.id)') ->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity') ->from('ChillActivityBundle:Activity', 'activity')
->join('activity.reasons', 'reasons') ->join('activity.reasons', 'reasons')
->join('reasons.category', 'category') ->join('reasons.category', 'category'),
); ];
} }
} }

View File

@@ -1,32 +1,37 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Export; namespace Chill\ActivityBundle\Tests\Export\Export;
use Chill\MainBundle\Test\Export\AbstractExportTest; use Chill\MainBundle\Test\Export\AbstractExportTest;
/** /**
* * @internal
* * @coversNothing
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/ */
class CountActivityTest extends AbstractExportTest class CountActivityTest extends AbstractExportTest
{ {
/** /**
* * @var
* @var
*/ */
private $export; private $export;
public function setUp() public function setUp()
{ {
static::bootKernel(); static::bootKernel();
/* @var $container \Symfony\Component\DependencyInjection\ContainerInterface */ /* @var $container \Symfony\Component\DependencyInjection\ContainerInterface */
$container = self::$kernel->getContainer(); $container = self::$kernel->getContainer();
$this->export = $container->get('chill.activity.export.count_activity'); $this->export = $container->get('chill.activity.export.count_activity');
} }
public function getExport() public function getExport()
{ {
return $this->export; return $this->export;
@@ -34,17 +39,16 @@ class CountActivityTest extends AbstractExportTest
public function getFormData() public function getFormData()
{ {
return array( return [
array() [],
); ];
} }
public function getModifiersCombination() public function getModifiersCombination()
{ {
return array( return [
array('activity'), ['activity'],
array('activity', 'person') ['activity', 'person'],
); ];
} }
} }

View File

@@ -1,20 +1,10 @@
<?php <?php
/* /**
* Copyright (C) 2017 Champs-Libres <info@champs-libres.coop> * Chill is a software for social workers
* *
* This program is free software: you can redistribute it and/or modify * For the full copyright and license information, please view
* it under the terms of the GNU Affero General Public License as published by * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\Tests\Export\Export; namespace Chill\ActivityBundle\Tests\Export\Export;
@@ -22,67 +12,33 @@ namespace Chill\ActivityBundle\Tests\Export\Export;
use Chill\MainBundle\Test\Export\AbstractExportTest; use Chill\MainBundle\Test\Export\AbstractExportTest;
/** /**
* * @internal
* * @coversNothing
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/ */
class ListActivityTest extends AbstractExportTest class ListActivityTest extends AbstractExportTest
{ {
/** /**
*
* @var \Chill\ActivityBundle\Export\Export\ListActivity * @var \Chill\ActivityBundle\Export\Export\ListActivity
*/ */
private $export; private $export;
public function setUp() public function setUp()
{ {
static::bootKernel(); static::bootKernel();
/* @var $container \Symfony\Component\DependencyInjection\ContainerInterface */ /* @var $container \Symfony\Component\DependencyInjection\ContainerInterface */
$container = self::$kernel->getContainer(); $container = self::$kernel->getContainer();
$this->export = $container->get('chill.activity.export.list_activity'); $this->export = $container->get('chill.activity.export.list_activity');
// add a fake request with a default locale (used in translatable string) // add a fake request with a default locale (used in translatable string)
$prophet = new \Prophecy\Prophet; $prophet = new \Prophecy\Prophet();
$request = $prophet->prophesize(); $request = $prophet->prophesize();
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class); $request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
$request->getLocale()->willReturn('fr'); $request->getLocale()->willReturn('fr');
$container->get('request_stack') $container->get('request_stack')
->push($request->reveal()); ->push($request->reveal());
}
public function getFormData()
{
return array(
array('fields' => array(
'id',
'date',
'durationTime',
'attendee',
'user_username',
'circle_name',
'type_name',
'person_firstname',
'person_lastname',
'person_id'
)),
array('fields' => array(
'id',
'list_reasons'
)),
);
}
public function getModifiersCombination()
{
return array(
array('activity'),
array('activity', 'person')
);
} }
public function getExport() public function getExport()
@@ -90,4 +46,33 @@ class ListActivityTest extends AbstractExportTest
return $this->export; return $this->export;
} }
public function getFormData()
{
return [
['fields' => [
'id',
'date',
'durationTime',
'attendee',
'user_username',
'circle_name',
'type_name',
'person_firstname',
'person_lastname',
'person_id',
]],
['fields' => [
'id',
'list_reasons',
]],
];
}
public function getModifiersCombination()
{
return [
['activity'],
['activity', 'person'],
];
}
} }

View File

@@ -1,32 +1,39 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Export; namespace Chill\ActivityBundle\Tests\Export\Export;
use Chill\MainBundle\Test\Export\AbstractExportTest; use Chill\MainBundle\Test\Export\AbstractExportTest;
/** /**
* Test the "sum" part of StatActivityDuration * Test the "sum" part of StatActivityDuration.
* *
* @author Julien Fastré <julien.fastre@champs-libres.coop> * @internal
* @coversNothing
*/ */
class StatActivityDurationSumTest extends AbstractExportTest class StatActivityDurationSumTest extends AbstractExportTest
{ {
/** /**
*
* @var \Chill\ActivityBundle\Export\Export\StatActivityDuration * @var \Chill\ActivityBundle\Export\Export\StatActivityDuration
*/ */
private $export; private $export;
public function setUp() public function setUp()
{ {
static::bootKernel(); static::bootKernel();
/* @var $container \Symfony\Component\DependencyInjection\ContainerInterface */ /* @var $container \Symfony\Component\DependencyInjection\ContainerInterface */
$container = self::$kernel->getContainer(); $container = self::$kernel->getContainer();
$this->export = $container->get('chill.activity.export.sum_activity_duration'); $this->export = $container->get('chill.activity.export.sum_activity_duration');
} }
public function getExport() public function getExport()
{ {
return $this->export; return $this->export;
@@ -34,17 +41,16 @@ class StatActivityDurationSumTest extends AbstractExportTest
public function getFormData() public function getFormData()
{ {
return array( return [
array() [],
); ];
} }
public function getModifiersCombination() public function getModifiersCombination()
{ {
return array( return [
array('activity'), ['activity'],
array('activity', 'person') ['activity', 'person'],
); ];
} }
} }

View File

@@ -1,20 +1,10 @@
<?php <?php
/* /**
* Copyright (C) 2017 Champs-Libres <info@champs-libres.coop> * Chill is a software for social workers
* *
* This program is free software: you can redistribute it and/or modify * For the full copyright and license information, please view
* it under the terms of the GNU Affero General Public License as published by * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\Tests\Filter; namespace Chill\ActivityBundle\Tests\Filter;
@@ -23,37 +13,34 @@ use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
/** /**
* * @internal
* * @coversNothing
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/ */
class ActivityReasonFilterTest extends AbstractFilterTest class ActivityReasonFilterTest extends AbstractFilterTest
{ {
/** /**
*
* @var \Chill\PersonBundle\Export\Filter\GenderFilter * @var \Chill\PersonBundle\Export\Filter\GenderFilter
*/ */
private $filter; private $filter;
public function setUp() public function setUp()
{ {
static::bootKernel(); static::bootKernel();
$container = static::$kernel->getContainer(); $container = static::$kernel->getContainer();
$this->filter = $container->get('chill.activity.export.reason_filter'); $this->filter = $container->get('chill.activity.export.reason_filter');
// add a fake request with a default locale (used in translatable string) // add a fake request with a default locale (used in translatable string)
$prophet = new \Prophecy\Prophet; $prophet = new \Prophecy\Prophet();
$request = $prophet->prophesize(); $request = $prophet->prophesize();
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class); $request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
$request->getLocale()->willReturn('fr'); $request->getLocale()->willReturn('fr');
$container->get('request_stack') $container->get('request_stack')
->push($request->reveal()); ->push($request->reveal());
} }
public function getFilter() public function getFilter()
{ {
return $this->filter; return $this->filter;
@@ -61,36 +48,35 @@ class ActivityReasonFilterTest extends AbstractFilterTest
public function getFormData() public function getFormData()
{ {
if (static::$kernel === null) { if (null === static::$kernel) {
static::bootKernel(); static::bootKernel();
} }
$em = static::$kernel->getContainer() $em = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager') ->get('doctrine.orm.entity_manager');
;
$reasons = $em->createQuery('SELECT reason '
$reasons = $em->createQuery("SELECT reason " . 'FROM ChillActivityBundle:ActivityReason reason')
. "FROM ChillActivityBundle:ActivityReason reason") ->getResult();
->getResult();
// generate an array of 5 different combination of results // generate an array of 5 different combination of results
for ($i=0; $i < 5; $i++) { for ($i = 0; 5 > $i; ++$i) {
$r[] = array('reasons' => new ArrayCollection(array_splice($reasons, ($i + 1) * -1))); $r[] = ['reasons' => new ArrayCollection(array_splice($reasons, ($i + 1) * -1))];
} }
return $r; return $r;
} }
public function getQueryBuilders() public function getQueryBuilders()
{ {
if (static::$kernel === null) { if (null === static::$kernel) {
static::bootKernel(); static::bootKernel();
} }
$em = static::$kernel->getContainer() $em = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager'); ->get('doctrine.orm.entity_manager');
return array( return [
$em->createQueryBuilder() $em->createQueryBuilder()
->select('count(activity.id)') ->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity'), ->from('ChillActivityBundle:Activity', 'activity'),
@@ -102,8 +88,7 @@ class ActivityReasonFilterTest extends AbstractFilterTest
->select('count(activity.id)') ->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity') ->from('ChillActivityBundle:Activity', 'activity')
->join('activity.reasons', 'reasons') ->join('activity.reasons', 'reasons')
->join('reasons.category', 'category') ->join('reasons.category', 'category'),
); ];
} }
} }

View File

@@ -1,56 +1,47 @@
<?php <?php
/*
* Copyright (C) 2017 Champs Libres Cooperative <info@champs-libres.coop> /**
* Chill is a software for social workers
* *
* This program is free software: you can redistribute it and/or modify * For the full copyright and license information, please view
* it under the terms of the GNU Affero General Public License as published by * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\Tests\Filter; namespace Chill\ActivityBundle\Tests\Filter;
use Chill\MainBundle\Test\Export\AbstractFilterTest; use Chill\MainBundle\Test\Export\AbstractFilterTest;
use DateTime;
/** /**
* * @internal
* * @coversNothing
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/ */
class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest
{ {
/** /**
*
* @var \Chill\PersonBundle\Export\Filter\PersonHavingActivityBetweenDateFilter * @var \Chill\PersonBundle\Export\Filter\PersonHavingActivityBetweenDateFilter
*/ */
private $filter; private $filter;
public function setUp() public function setUp()
{ {
static::bootKernel(); static::bootKernel();
$container = static::$kernel->getContainer(); $container = static::$kernel->getContainer();
$this->filter = $container->get('chill.activity.export.' $this->filter = $container->get('chill.activity.export.'
. 'person_having_an_activity_between_date_filter'); . 'person_having_an_activity_between_date_filter');
// add a fake request with a default locale (used in translatable string) // add a fake request with a default locale (used in translatable string)
$prophet = new \Prophecy\Prophet; $prophet = new \Prophecy\Prophet();
$request = $prophet->prophesize(); $request = $prophet->prophesize();
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class); $request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
$request->getLocale()->willReturn('fr'); $request->getLocale()->willReturn('fr');
$container->get('request_stack') $container->get('request_stack')
->push($request->reveal()); ->push($request->reveal());
} }
public function getFilter() public function getFilter()
{ {
return $this->filter; return $this->filter;
@@ -58,49 +49,33 @@ class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest
public function getFormData() public function getFormData()
{ {
$date_from = \DateTime::createFromFormat('Y-m-d', '2015-01-15'); $date_from = DateTime::createFromFormat('Y-m-d', '2015-01-15');
$date_to = new \DateTime(); // today $date_to = new DateTime(); // today
$reasons = $this->getActivityReasons(); $reasons = $this->getActivityReasons();
$data = [];
$data = array();
for ($i = 0; $i < 4; $i++) { for ($i = 0; 4 > $i; ++$i) {
$data[] = array( $data[] = [
'date_from' => $date_from, 'date_from' => $date_from,
'date_to' => $date_to, 'date_to' => $date_to,
'reasons' => array_slice($reasons, 0, 1 + $i) 'reasons' => array_slice($reasons, 0, 1 + $i),
); ];
} }
return $data; return $data;
} }
/**
* Return all activity reasons
*
* @return \Chill\ActivityBundle\Entity\ActivityReason[]
*/
private function getActivityReasons()
{
if (static::$kernel === null) {
static::bootKernel();
}
return static::$kernel->getContainer()
->get('chill_activity.repository.reason')
->findAll();
}
public function getQueryBuilders() public function getQueryBuilders()
{ {
if (static::$kernel === null) { if (null === static::$kernel) {
static::bootKernel(); static::bootKernel();
} }
$em = static::$kernel->getContainer() $em = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager'); ->get('doctrine.orm.entity_manager');
return array( return [
$em->createQueryBuilder() $em->createQueryBuilder()
->select('count(person.id)') ->select('count(person.id)')
->from('ChillPersonBundle:Person', 'person') ->from('ChillPersonBundle:Person', 'person')
@@ -112,6 +87,22 @@ class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest
->join('activity.person', 'person') ->join('activity.person', 'person')
// add a fake where clause // add a fake where clause
->where('person.id > 0'), ->where('person.id > 0'),
); ];
}
/**
* Return all activity reasons.
*
* @return \Chill\ActivityBundle\Entity\ActivityReason[]
*/
private function getActivityReasons()
{
if (null === static::$kernel) {
static::bootKernel();
}
return static::$kernel->getContainer()
->get('chill_activity.repository.reason')
->findAll();
} }
} }

View File

@@ -1,183 +1,170 @@
<?php <?php
/* /**
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop> * Chill is a software for social workers
* *
* This program is free software: you can redistribute it and/or modify * For the full copyright and license information, please view
* it under the terms of the GNU Affero General Public License as published by * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\Tests\Form; namespace Chill\ActivityBundle\Tests\Form;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Chill\ActivityBundle\Form\ActivityType;
use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Form\ActivityType;
use DateTime;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken; use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Form\Extension\Core\Type\FormType;
/** /**
* * @internal
* * @coversNothing
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/ */
class ActivityTypeTest extends KernelTestCase class ActivityTypeTest extends KernelTestCase
{ {
/** /**
* * @var \Chill\MainBundle\Entity\Center
* @var \Symfony\Component\Form\FormBuilderInterface
*/ */
protected $formBuilder; protected $center;
/** /**
*
* @var \Symfony\Component\DependencyInjection\ContainerInterface * @var \Symfony\Component\DependencyInjection\ContainerInterface
*/ */
protected $container; protected $container;
/** /**
* * @var \Symfony\Component\Form\FormBuilderInterface
*/
protected $formBuilder;
/**
* @var \Symfony\Component\Security\Core\User\UserInterface * @var \Symfony\Component\Security\Core\User\UserInterface
*/ */
protected $user; protected $user;
/**
*
* @var \Chill\MainBundle\Entity\Center
*/
protected $center;
public function setUp() public function setUp()
{ {
self::bootKernel(); self::bootKernel();
$this->container = self::$kernel->getContainer(); $this->container = self::$kernel->getContainer();
$prophet = new \Prophecy\Prophet; $prophet = new \Prophecy\Prophet();
$this->formBuilder = $this->container $this->formBuilder = $this->container
->get('form.factory') ->get('form.factory')
->createBuilder(FormType::class, null, array( ->createBuilder(FormType::class, null, [
'csrf_protection' => false, 'csrf_protection' => false,
'csrf_field_name' => '_token' 'csrf_field_name' => '_token',
)); ]);
$request = new \Symfony\Component\HttpFoundation\Request(); $request = new \Symfony\Component\HttpFoundation\Request();
$request->setLocale('fr'); $request->setLocale('fr');
self::$kernel->getContainer() self::$kernel->getContainer()
->get('request_stack') ->get('request_stack')
->push($request); ->push($request);
$this->user = $this->container->get('doctrine.orm.entity_manager') $this->user = $this->container->get('doctrine.orm.entity_manager')
->getRepository('ChillMainBundle:User') ->getRepository('ChillMainBundle:User')
->findOneBy(array('username' => 'center a_social')); ->findOneBy(['username' => 'center a_social']);
$this->center = $this->container->get('doctrine.orm.entity_manager') $this->center = $this->container->get('doctrine.orm.entity_manager')
->getRepository('ChillMainBundle:Center') ->getRepository('ChillMainBundle:Center')
->findOneBy(array('name' => 'Center A')); ->findOneBy(['name' => 'Center A']);
$token = $prophet->prophesize(); $token = $prophet->prophesize();
$token->willExtend(AbstractToken::class); $token->willExtend(AbstractToken::class);
$token->getUser()->willReturn($this->user); $token->getUser()->willReturn($this->user);
$this->container->get('security.token_storage') $this->container->get('security.token_storage')
->setToken($token->reveal()); ->setToken($token->reveal());
} }
public function testForm() public function testForm()
{ {
$form = $this->formBuilder $form = $this->formBuilder
->add('activity', ActivityType::class, array( ->add('activity', ActivityType::class, [
'center' => $this->center, 'center' => $this->center,
'role' => new Role('CHILL_ACTIVITY_CREATE') 'role' => new Role('CHILL_ACTIVITY_CREATE'),
)) ])
->getForm(); ->getForm();
$form->submit(array()); $form->submit([]);
$this->assertTrue($form->isSynchronized()); $this->assertTrue($form->isSynchronized());
$this->assertTrue($form->isValid()); $this->assertTrue($form->isValid());
$this->assertInstanceOf(Activity::class, $form->getData()['activity']); $this->assertInstanceOf(Activity::class, $form->getData()['activity']);
} }
public function testFormSubmitting() public function testFormSubmitting()
{ {
$form = $this->formBuilder $form = $this->formBuilder
->add('activity', ActivityType::class, array( ->add('activity', ActivityType::class, [
'center' => $this->center, 'center' => $this->center,
'role' => new Role('CHILL_ACTIVITY_CREATE') 'role' => new Role('CHILL_ACTIVITY_CREATE'),
)) ])
->getForm(); ->getForm();
$form->submit(array( 'activity' => array( $form->submit(['activity' => [
'date' => '9-3-2015', 'date' => '9-3-2015',
'durationTime' => 300, 'durationTime' => 300,
// 'remark' => 'blabla', // 'remark' => 'blabla',
'attendee' => true 'attendee' => true,
))); ]]);
// var_dump($form->getErrors()->count()); var_dump($form->isValid()); // var_dump($form->getErrors()->count()); var_dump($form->isValid());
// foreach($form->getErrors() as $e) { fwrite(STDOUT, var_dump($e->getMessage())); } // foreach($form->getErrors() as $e) { fwrite(STDOUT, var_dump($e->getMessage())); }
// var_dump($form->getErrors()); // var_dump($form->getErrors());
$this->assertTrue($form->isSynchronized(), "Test the form is synchronized"); $this->assertTrue($form->isSynchronized(), 'Test the form is synchronized');
$this->assertTrue($form->isValid(), "test the form is valid"); $this->assertTrue($form->isValid(), 'test the form is valid');
$this->assertInstanceOf(Activity::class, $form->getData()['activity']); $this->assertInstanceOf(Activity::class, $form->getData()['activity']);
// test the activity // test the activity
/* @var $activity Activity */ /* @var $activity Activity */
$activity = $form->getData()['activity']; $activity = $form->getData()['activity'];
$this->assertEquals('09-03-2015', $activity->getDate()->format('d-m-Y'), $this->assertEquals(
"Test the date is correct"); '09-03-2015',
$this->assertEquals('00:05', $activity->getDurationTime()->format('H:i'), $activity->getDate()->format('d-m-Y'),
"Test the formatted hour is correct"); 'Test the date is correct'
);
$this->assertEquals(
'00:05',
$activity->getDurationTime()->format('H:i'),
'Test the formatted hour is correct'
);
$this->assertEquals(true, $activity->getAttendee()); $this->assertEquals(true, $activity->getAttendee());
// $this->assertEquals('blabla', $activity->getRemark()); // $this->assertEquals('blabla', $activity->getRemark());
} }
/** /**
* Test that the form correctly build even with a durationTime which is not in * Test that the form correctly build even with a durationTime which is not in
* the listed in the possible durationTime * the listed in the possible durationTime.
*/ */
public function testFormWithActivityHavingDifferentTime() public function testFormWithActivityHavingDifferentTime()
{ {
$activity = new Activity(); $activity = new Activity();
$activity->setDurationTime(\DateTime::createFromFormat('U', 60)); $activity->setDurationTime(DateTime::createFromFormat('U', 60));
$builder = $this->container $builder = $this->container
->get('form.factory') ->get('form.factory')
->createBuilder(FormType::class, array('activity' => $activity), array( ->createBuilder(FormType::class, ['activity' => $activity], [
'csrf_protection' => false, 'csrf_protection' => false,
'csrf_field_name' => '_token' 'csrf_field_name' => '_token',
)); ]);
$form = $builder $form = $builder
->add('activity', ActivityType::class, array( ->add('activity', ActivityType::class, [
'center' => $this->center, 'center' => $this->center,
'role' => new Role('CHILL_ACTIVITY_CREATE') 'role' => new Role('CHILL_ACTIVITY_CREATE'),
)) ])
->getForm(); ->getForm();
$form->submit(['activity' => [
$form->submit(array( 'activity' => array(
'date' => '9-3-2015', 'date' => '9-3-2015',
'durationTime' => 60, 'durationTime' => 60,
// 'remark' => 'blabla', // 'remark' => 'blabla',
'attendee' => true 'attendee' => true,
))); ]]);
$this->assertTrue($form->isSynchronized()); $this->assertTrue($form->isSynchronized());
$this->assertTrue($form->isValid()); $this->assertTrue($form->isValid());
@@ -186,8 +173,11 @@ class ActivityTypeTest extends KernelTestCase
/* @var $activity Activity */ /* @var $activity Activity */
$activity = $form->getData()['activity']; $activity = $form->getData()['activity'];
$this->assertEquals('00:01', $activity->getDurationTime()->format('H:i'), $this->assertEquals(
"Test the formatted hour is correct"); '00:01',
$activity->getDurationTime()->format('H:i'),
'Test the formatted hour is correct'
);
// test the view : we want to be sure that the entry with 60 seconds exists // test the view : we want to be sure that the entry with 60 seconds exists
$view = $form->createView(); $view = $form->createView();
@@ -195,11 +185,11 @@ class ActivityTypeTest extends KernelTestCase
$this->assertTrue(isset($view['activity']['durationTime'])); $this->assertTrue(isset($view['activity']['durationTime']));
// map all the values in an array // map all the values in an array
$values = array_map(function($choice) { return $choice->value; }, $values = array_map(
$view['activity']['durationTime']->vars['choices']); function ($choice) { return $choice->value; },
$view['activity']['durationTime']->vars['choices']
);
$this->assertContains(60, $values); $this->assertContains(60, $values);
} }
} }

View File

@@ -1,110 +1,97 @@
<?php <?php
/* /**
* Chill is a software for social workers * Chill is a software for social workers
* Copyright (C) 2015 Champs Libres <info@champs-libres.coop>
* *
* This program is free software: you can redistribute it and/or modify * For the full copyright and license information, please view
* it under the terms of the GNU Affero General Public License as published by * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\Tests\Form\Type; namespace Chill\ActivityBundle\Tests\Form\Type;
use Symfony\Component\Form\Test\TypeTestCase;
use Chill\ActivityBundle\Form\Type\TranslatableActivityReason; use Chill\ActivityBundle\Form\Type\TranslatableActivityReason;
use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Component\Form\PreloadedExtension; use Symfony\Component\Form\PreloadedExtension;
use Symfony\Component\Form\Test\TypeTestCase;
/** /**
* Test translatableActivityReason * Test translatableActivityReason.
* *
* @author Julien Fastré <julien.fastre@champs-libres.coop> * @internal
* @author Champs Libres <info@champs-libres.coop> * @coversNothing
*/ */
class TranslatableActivityReasonTest extends TypeTestCase class TranslatableActivityReasonTest extends TypeTestCase
{ {
/** /**
* * @var Prophecy\Prophet
* @var Prophecy\Prophet
*/ */
private static $prophet; private static $prophet;
public function setUp() public function setUp()
{ {
parent::setUp(); parent::setUp();
} }
protected function getExtensions()
{
$entityType = $this->getEntityType();
return array(new PreloadedExtension(array(
'entity' => $entityType
), array()));
}
public function testSimple() public function testSimple()
{ {
$translatableActivityReasonType = new TranslatableActivityReason( $translatableActivityReasonType = new TranslatableActivityReason(
$this->getTranslatableStringHelper() $this->getTranslatableStringHelper()
); );
$this->markTestSkipped("See issue 651"); $this->markTestSkipped('See issue 651');
} }
/** /**
*
* @param string $locale
* @param string $fallbackLocale
* @return TranslatableStringHelper
*/
protected function getTranslatableStringHelper($locale = 'en',
$fallbackLocale = 'en')
{
$prophet = new \Prophecy\Prophet;
$requestStack = $prophet->prophesize();
$request = $prophet->prophesize();
$translator = $prophet->prophesize();
$request->willExtend('Symfony\Component\HttpFoundation\Request');
$request->getLocale()->willReturn($fallbackLocale);
$requestStack->willExtend('Symfony\Component\HttpFoundation\RequestStack');
$requestStack->getCurrentRequest()->will(function () use ($request) {
return $request;
});
$translator->willExtend('Symfony\Component\Translation\Translator');
$translator->getFallbackLocales()->willReturn($locale);
return new TranslatableStringHelper($requestStack->reveal(),
$translator->reveal());
}
/**
*
* @return \Symfony\Bridge\Doctrine\Form\Type\EntityType * @return \Symfony\Bridge\Doctrine\Form\Type\EntityType
*/ */
protected function getEntityType() protected function getEntityType()
{ {
$managerRegistry = (new \Prophecy\Prophet())->prophesize(); $managerRegistry = (new \Prophecy\Prophet())->prophesize();
$managerRegistry->willImplement('Doctrine\Common\Persistence\ManagerRegistry'); $managerRegistry->willImplement('Doctrine\Common\Persistence\ManagerRegistry');
return new \Symfony\Bridge\Doctrine\Form\Type\EntityType($managerRegistry->reveal()); return new \Symfony\Bridge\Doctrine\Form\Type\EntityType($managerRegistry->reveal());
} }
protected function getExtensions()
{
$entityType = $this->getEntityType();
return [new PreloadedExtension([
'entity' => $entityType,
], [])];
}
/**
* @param string $locale
* @param string $fallbackLocale
*
* @return TranslatableStringHelper
*/
protected function getTranslatableStringHelper(
$locale = 'en',
$fallbackLocale = 'en'
)
{
$prophet = new \Prophecy\Prophet();
$requestStack = $prophet->prophesize();
$request = $prophet->prophesize();
$translator = $prophet->prophesize();
$request->willExtend('Symfony\Component\HttpFoundation\Request');
$request->getLocale()->willReturn($fallbackLocale);
$requestStack->willExtend('Symfony\Component\HttpFoundation\RequestStack');
$requestStack->getCurrentRequest()->will(function () use ($request) {
return $request;
});
$translator->willExtend('Symfony\Component\Translation\Translator');
$translator->getFallbackLocales()->willReturn($locale);
return new TranslatableStringHelper(
$requestStack->reveal(),
$translator->reveal()
);
}
} }

View File

@@ -1,116 +1,101 @@
<?php <?php
/* /**
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop> * Chill is a software for social workers
* *
* This program is free software: you can redistribute it and/or modify * For the full copyright and license information, please view
* it under the terms of the GNU Affero General Public License as published by * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\Tests\Form\Type; namespace Chill\ActivityBundle\Tests\Form\Type;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Chill\ActivityBundle\Form\Type\TranslatableActivityType; use Chill\ActivityBundle\Form\Type\TranslatableActivityType;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\Form\Extension\Core\Type\FormType;
/** /**
* * @internal
* * @coversNothing
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/ */
class TranslatableActivityTypeTest extends KernelTestCase class TranslatableActivityTypeTest extends KernelTestCase
{ {
/** /**
*
* @var \Symfony\Component\Form\FormBuilderInterface * @var \Symfony\Component\Form\FormBuilderInterface
*/ */
protected $builder; protected $builder;
/** /**
*
* @var \Symfony\Component\DependencyInjection\ContainerInterface * @var \Symfony\Component\DependencyInjection\ContainerInterface
*/ */
protected $container; protected $container;
public function setUp() public function setUp()
{ {
self::bootKernel(); self::bootKernel();
$this->container = self::$kernel->getContainer(); $this->container = self::$kernel->getContainer();
$this->builder = $this->container $this->builder = $this->container
->get('form.factory') ->get('form.factory')
->createBuilder(FormType::class, null, array( ->createBuilder(FormType::class, null, [
'csrf_protection' => false, 'csrf_protection' => false,
'csrf_field_name' => '_token' 'csrf_field_name' => '_token',
)); ]);
$request = new \Symfony\Component\HttpFoundation\Request(); $request = new \Symfony\Component\HttpFoundation\Request();
$request->setLocale('fr'); $request->setLocale('fr');
$this->container->get('request_stack') $this->container->get('request_stack')
->push($request); ->push($request);
} }
/**
*
* @return \Chill\ActivityBundle\Entity\ActivityType
*/
protected function getRandomType($active = true)
{
$types = $this->container->get('doctrine.orm.entity_manager')
->getRepository('ChillActivityBundle:ActivityType')
->findBy(array('active' => $active));
return $types[array_rand($types)];
}
public function testForm() public function testForm()
{ {
$type = $this->getRandomType(); $type = $this->getRandomType();
$form = $this->builder->add('type', TranslatableActivityType::class) $form = $this->builder->add('type', TranslatableActivityType::class)
->getForm(); ->getForm();
$form->submit(array( $form->submit([
'type' => $type->getId() 'type' => $type->getId(),
)); ]);
$this->assertTrue($form->isSynchronized()); $this->assertTrue($form->isSynchronized());
$this->assertInstanceOf(\Chill\ActivityBundle\Entity\ActivityType::class, $this->assertInstanceOf(
$form->getData()['type'], \Chill\ActivityBundle\Entity\ActivityType::class,
"The data is an instance of Chill\ActivityBundle\Entity\ActivityType"); $form->getData()['type'],
'The data is an instance of Chill\\ActivityBundle\\Entity\\ActivityType'
);
$this->assertEquals($type->getId(), $form->getData()['type']->getId()); $this->assertEquals($type->getId(), $form->getData()['type']->getId());
// test the ordering of the types in the form // test the ordering of the types in the form
// since 2016-11-14 the types are not alphabetically ordered, skipping // since 2016-11-14 the types are not alphabetically ordered, skipping
/*$view = $form->createView(); /*$view = $form->createView();
$this->assertGreaterThan(0, count($view['type']->vars['choices']), $this->assertGreaterThan(0, count($view['type']->vars['choices']),
"test that there are at least one choice"); "test that there are at least one choice");
foreach($view['type']->vars['choices'] as $choice) { foreach($view['type']->vars['choices'] as $choice) {
// initialize the previous value is not set (this is the first) // initialize the previous value is not set (this is the first)
if (!isset($previous)) { if (!isset($previous)) {
$previous = $choice->label; $previous = $choice->label;
} else { } else {
$this->assertTrue($previous < $choice->label); $this->assertTrue($previous < $choice->label);
$previous = $choice->label; $previous = $choice->label;
} }
}*/ }*/
} }
/**
* @param mixed $active
*
* @return \Chill\ActivityBundle\Entity\ActivityType
*/
protected function getRandomType($active = true)
{
$types = $this->container->get('doctrine.orm.entity_manager')
->getRepository('ChillActivityBundle:ActivityType')
->findBy(['active' => $active]);
return $types[array_rand($types)];
}
} }

View File

@@ -1,103 +1,55 @@
<?php <?php
/* /**
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop> * Chill is a software for social workers
* *
* This program is free software: you can redistribute it and/or modify * For the full copyright and license information, please view
* it under the terms of the GNU Affero General Public License as published by * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\Tests\Security\Authorization; namespace Chill\ActivityBundle\Tests\Security\Authorization;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Chill\ActivityBundle\Test\PrepareActivityTrait;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Test\PrepareUserTrait; use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Test\PrepareCenterTrait; use Chill\MainBundle\Test\PrepareCenterTrait;
use Chill\MainBundle\Test\PrepareScopeTrait; use Chill\MainBundle\Test\PrepareScopeTrait;
use Chill\MainBundle\Test\PrepareUserTrait;
use Chill\PersonBundle\Test\PreparePersonTrait; use Chill\PersonBundle\Test\PreparePersonTrait;
use Chill\ActivityBundle\Test\PrepareActivityTrait; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
/** /**
* * @internal
* * @coversNothing
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/ */
class ActivityVoterTest extends KernelTestCase class ActivityVoterTest extends KernelTestCase
{ {
use PrepareUserTrait, PrepareCenterTrait, PrepareScopeTrait, use PrepareUserTrait;
PreparePersonTrait, PrepareActivityTrait; use PrepareCenterTrait;
use PrepareScopeTrait;
use PreparePersonTrait;
use PrepareActivityTrait;
/** /**
*
* @var \Chill\PersonBundle\Security\Authorization\PersonVoter
*/
protected $voter;
/**
*
* @var \Prophecy\Prophet * @var \Prophecy\Prophet
*/ */
protected $prophet; protected $prophet;
/**
* @var \Chill\PersonBundle\Security\Authorization\PersonVoter
*/
protected $voter;
public function setUp() public function setUp()
{ {
static::bootKernel(); static::bootKernel();
$this->voter = static::$kernel->getContainer() $this->voter = static::$kernel->getContainer()
->get('chill.activity.security.authorization.activity_voter'); ->get('chill.activity.security.authorization.activity_voter');
$this->prophet = new \Prophecy\Prophet(); $this->prophet = new \Prophecy\Prophet();
} }
public function testNullUser()
{
$token = $this->prepareToken();
$center = $this->prepareCenter(1, 'center');
$person = $this->preparePerson($center);
$scope = $this->prepareScope(1, 'default');
$activity = $this->prepareActivity($scope, $person);
$this->assertEquals(
VoterInterface::ACCESS_DENIED,
$this->voter->vote($token, $activity, array('CHILL_ACTIVITY_SEE')),
"assert that a null user is not allowed to see"
);
}
/**
*
* @dataProvider dataProvider_testVoteAction
* @param type $expectedResult
* @param User $user
* @param Scope $scope
* @param Center $center
* @param string $attribute
* @param string $message
*/
public function testVoteAction($expectedResult, User $user, Scope $scope,
Center $center, $attribute, $message)
{
$token = $this->prepareToken($user);
$activity = $this->prepareActivity($scope, $this->preparePerson($center));
$this->assertEquals(
$expectedResult,
$this->voter->vote($token, $activity, array($attribute)),
$message
);
}
public function dataProvider_testVoteAction() public function dataProvider_testVoteAction()
{ {
$centerA = $this->prepareCenter(1, 'center A'); $centerA = $this->prepareCenter(1, 'center A');
@@ -105,72 +57,112 @@ class ActivityVoterTest extends KernelTestCase
$scopeA = $this->prepareScope(1, 'scope default'); $scopeA = $this->prepareScope(1, 'scope default');
$scopeB = $this->prepareScope(2, 'scope B'); $scopeB = $this->prepareScope(2, 'scope B');
$scopeC = $this->prepareScope(3, 'scope C'); $scopeC = $this->prepareScope(3, 'scope C');
$userA = $this->prepareUser(array( $userA = $this->prepareUser([
array( [
'center' => $centerA, 'center' => $centerA,
'permissionsGroup' => array( 'permissionsGroup' => [
['scope' => $scopeB, 'role' => 'CHILL_ACTIVITY_CREATE'], ['scope' => $scopeB, 'role' => 'CHILL_ACTIVITY_CREATE'],
['scope' => $scopeA, 'role' => 'CHILL_ACTIVITY_SEE'] ['scope' => $scopeA, 'role' => 'CHILL_ACTIVITY_SEE'],
) ],
), ],
array( [
'center' => $centerB, 'center' => $centerB,
'permissionsGroup' => array( 'permissionsGroup' => [
['scope' => $scopeA, 'role' => 'CHILL_ACTIVITY_CREATE'], ['scope' => $scopeA, 'role' => 'CHILL_ACTIVITY_CREATE'],
['scope' => $scopeC, 'role' => 'CHILL_ACTIVITY_CREATE'] ['scope' => $scopeC, 'role' => 'CHILL_ACTIVITY_CREATE'],
) ],
) ],
]);
));
return [
return array( [
array(
VoterInterface::ACCESS_GRANTED, VoterInterface::ACCESS_GRANTED,
$userA, $userA,
$scopeB, $scopeB,
$centerA, $centerA,
'CHILL_ACTIVITY_CREATE', 'CHILL_ACTIVITY_CREATE',
'assert that a user granted with same rights' 'assert that a user granted with same rights',
), ],
array( [
VoterInterface::ACCESS_GRANTED, VoterInterface::ACCESS_GRANTED,
$userA, $userA,
$scopeB, $scopeB,
$centerA, $centerA,
'CHILL_ACTIVITY_SEE', 'CHILL_ACTIVITY_SEE',
'assert that a user granted with inheritance rights' 'assert that a user granted with inheritance rights',
), ],
array( [
VoterInterface::ACCESS_DENIED, VoterInterface::ACCESS_DENIED,
$userA, $userA,
$scopeC, $scopeC,
$centerA, $centerA,
'CHILL_ACTIVITY_SEE', 'CHILL_ACTIVITY_SEE',
'assert that a suer is denied if he is not granted right on this center' 'assert that a suer is denied if he is not granted right on this center',
],
) ];
}
public function testNullUser()
{
$token = $this->prepareToken();
$center = $this->prepareCenter(1, 'center');
$person = $this->preparePerson($center);
$scope = $this->prepareScope(1, 'default');
$activity = $this->prepareActivity($scope, $person);
$this->assertEquals(
VoterInterface::ACCESS_DENIED,
$this->voter->vote($token, $activity, ['CHILL_ACTIVITY_SEE']),
'assert that a null user is not allowed to see'
); );
} }
/** /**
* prepare a token interface with correct rights * @dataProvider dataProvider_testVoteAction
* *
* @param type $expectedResult
* @param string $attribute
* @param string $message
*/
public function testVoteAction(
$expectedResult,
User $user,
Scope $scope,
Center $center,
$attribute,
$message
)
{
$token = $this->prepareToken($user);
$activity = $this->prepareActivity($scope, $this->preparePerson($center));
$this->assertEquals(
$expectedResult,
$this->voter->vote($token, $activity, [$attribute]),
$message
);
}
/**
* prepare a token interface with correct rights.
*
* if $permissions = null, user will be null (no user associated with token * if $permissions = null, user will be null (no user associated with token
* *
* @return \Symfony\Component\Security\Core\Authentication\Token\TokenInterface * @return \Symfony\Component\Security\Core\Authentication\Token\TokenInterface
*/ */
protected function prepareToken(User $user = null) protected function prepareToken(?User $user = null)
{ {
$token = $this->prophet->prophesize(); $token = $this->prophet->prophesize();
$token $token
->willImplement('\Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); ->willImplement('\Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
if ($user === NULL) {
if (null === $user) {
$token->getUser()->willReturn(null); $token->getUser()->willReturn(null);
} else { } else {
$token->getUser()->willReturn($user); $token->getUser()->willReturn($user);
} }
return $token->reveal(); return $token->reveal();
} }
} }

View File

@@ -1,20 +1,10 @@
<?php <?php
/* /**
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop> * Chill is a software for social workers
* *
* This program is free software: you can redistribute it and/or modify * For the full copyright and license information, please view
* it under the terms of the GNU Affero General Public License as published by * the LICENSE file that was distributed with this source code.
* 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\ActivityBundle\Tests\Timeline; namespace Chill\ActivityBundle\Tests\Timeline;
@@ -22,15 +12,13 @@ namespace Chill\ActivityBundle\Tests\Timeline;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
/** /**
* * @internal
* * @coversNothing
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/ */
class TimelineProviderTest extends WebTestCase class TimelineProviderTest extends WebTestCase
{ {
public function testAnActivityIsShownOnTimeline() public function testAnActivityIsShownOnTimeline()
{ {
$this->markTestSkipped("we have to write fixtures before writing this tests"); $this->markTestSkipped('we have to write fixtures before writing this tests');
} }
} }

View File

@@ -1,33 +1,45 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Timeline; namespace Chill\ActivityBundle\Timeline;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Repository\ActivityACLAwareRepository;
use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
use Chill\MainBundle\Timeline\TimelineProviderInterface; use Chill\MainBundle\Timeline\TimelineProviderInterface;
use Chill\ActivityBundle\Repository\ActivityACLAwareRepository; use Chill\MainBundle\Timeline\TimelineSingleQuery;
use Chill\PersonBundle\Entity\Person;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use LogicException;
use RuntimeException;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\Role;
use Chill\PersonBundle\Entity\Person;
use Chill\ActivityBundle\Entity\Activity;
use Chill\MainBundle\Timeline\TimelineSingleQuery;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
use function implode;
use function in_array;
use function strtr;
class TimelineActivityProvider implements TimelineProviderInterface class TimelineActivityProvider implements TimelineProviderInterface
{ {
private const SUPPORTED_CONTEXTS = ['center', 'person'];
protected ActivityACLAwareRepository $aclAwareRepository;
protected EntityManagerInterface $em; protected EntityManagerInterface $em;
protected AuthorizationHelperInterface $helper; protected AuthorizationHelperInterface $helper;
protected UserInterface $user; protected UserInterface $user;
protected ActivityACLAwareRepository $aclAwareRepository;
private const SUPPORTED_CONTEXTS = [ 'center', 'person'];
public function __construct( public function __construct(
EntityManagerInterface $em, EntityManagerInterface $em,
AuthorizationHelperInterface $helper, AuthorizationHelperInterface $helper,
@@ -38,18 +50,13 @@ class TimelineActivityProvider implements TimelineProviderInterface
$this->helper = $helper; $this->helper = $helper;
$this->aclAwareRepository = $aclAwareRepository; $this->aclAwareRepository = $aclAwareRepository;
if (!$storage->getToken()->getUser() instanceof User) if (!$storage->getToken()->getUser() instanceof User) {
{ throw new RuntimeException('A user should be authenticated !');
throw new \RuntimeException('A user should be authenticated !');
} }
$this->user = $storage->getToken()->getUser(); $this->user = $storage->getToken()->getUser();
} }
/**
*
* {@inheritDoc}
*/
public function fetchQuery($context, array $args) public function fetchQuery($context, array $args)
{ {
if ('center' === $context) { if ('center' === $context) {
@@ -59,80 +66,28 @@ class TimelineActivityProvider implements TimelineProviderInterface
$metadataActivity = $this->em->getClassMetadata(Activity::class); $metadataActivity = $this->em->getClassMetadata(Activity::class);
[$where, $parameters] = $this->getWhereClauseForPerson($args['person']); [$where, $parameters] = $this->getWhereClauseForPerson($args['person']);
return TimelineSingleQuery::fromArray([ return TimelineSingleQuery::fromArray([
'id' => $metadataActivity->getTableName() 'id' => $metadataActivity->getTableName()
.'.'.$metadataActivity->getColumnName('id'), . '.' . $metadataActivity->getColumnName('id'),
'type' => 'activity', 'type' => 'activity',
'date' => $metadataActivity->getTableName() 'date' => $metadataActivity->getTableName()
.'.'.$metadataActivity->getColumnName('date'), . '.' . $metadataActivity->getColumnName('date'),
'FROM' => $this->getFromClausePerson(), 'FROM' => $this->getFromClausePerson(),
'WHERE' => $where, 'WHERE' => $where,
'parameters' => $parameters 'parameters' => $parameters,
]); ]);
}
private function getWhereClauseForPerson(Person $person)
{
$parameters = [];
$metadataActivity = $this->em->getClassMetadata(Activity::class);
$associationMapping = $metadataActivity->getAssociationMapping('person');
$role = new Role('CHILL_ACTIVITY_SEE');
$reachableScopes = $this->helper->getReachableScopes($this->user, $role->getRole(), $person->getCenter());
$whereClause = sprintf(' {activity.person_id} = ? AND {activity.scope_id} IN ({scopes_ids}) ');
$scopes_ids = [];
// first parameter: activity.person_id
$parameters[] = $person->getId();
// loop on reachable scopes
foreach ($reachableScopes as $scope) {
if (\in_array($scope->getId(), $scopes_ids)) {
continue;
}
$scopes_ids[] = '?';
$parameters[] = $scope->getId();
}
return [
\strtr(
$whereClause,
[
'{activity.person_id}' => $associationMapping['joinColumns'][0]['name'],
'{activity.scope_id}' => $metadataActivity->getTableName().'.'.
$metadataActivity->getAssociationMapping('scope')['joinColumns'][0]['name'],
'{scopes_ids}' => \implode(", ", $scopes_ids)
,
]
),
$parameters
];
}
private function getFromClausePerson(): string
{
$metadataActivity = $this->em->getClassMetadata(Activity::class);
$metadataPerson = $this->em->getClassMetadata(Person::class);
$associationMapping = $metadataActivity->getAssociationMapping('person');
return sprintf(
"%s JOIN %s ON %s.%s = %s",
$metadataActivity->getTableName(),
$metadataPerson->getTableName(),
$metadataPerson->getTableName(),
$associationMapping['joinColumns'][0]['referencedColumnName'],
$associationMapping['joinColumns'][0]['name']
);
} }
public function getEntities(array $ids): array public function getEntities(array $ids): array
{ {
$activities = $this->em->getRepository(Activity::class) $activities = $this->em->getRepository(Activity::class)
->findBy(array('id' => $ids)); ->findBy(['id' => $ids]);
$result = array(); $result = [];
foreach($activities as $activity) {
foreach ($activities as $activity) {
$result[$activity->getId()] = $activity; $result[$activity->getId()] = $activity;
} }
@@ -144,28 +99,28 @@ class TimelineActivityProvider implements TimelineProviderInterface
$this->checkContext($context); $this->checkContext($context);
return [ return [
'template' => 'ChillActivityBundle:Timeline:activity_person_context.html.twig', 'template' => 'ChillActivityBundle:Timeline:activity_person_context.html.twig',
'template_data' => [ 'template_data' => [
'activity' => $entity, 'activity' => $entity,
'context' => $context 'context' => $context,
] ],
]; ];
} }
public function supportsType($type): bool public function supportsType($type): bool
{ {
return $type === 'activity'; return 'activity' === $type;
} }
/** /**
* Check if the context is supported. * Check if the context is supported.
* *
* @throws \LogicException if the context is not supported * @throws LogicException if the context is not supported
*/ */
private function checkContext(string $context) private function checkContext(string $context)
{ {
if (FALSE === \in_array($context, self::SUPPORTED_CONTEXTS)) { if (false === in_array($context, self::SUPPORTED_CONTEXTS)) {
throw new \LogicException( throw new LogicException(
sprintf( sprintf(
"The context '%s' is not supported. Currently only 'person' is supported", "The context '%s' is not supported. Currently only 'person' is supported",
$context $context
@@ -174,4 +129,55 @@ class TimelineActivityProvider implements TimelineProviderInterface
} }
} }
private function getFromClausePerson(): string
{
$metadataActivity = $this->em->getClassMetadata(Activity::class);
$metadataPerson = $this->em->getClassMetadata(Person::class);
$associationMapping = $metadataActivity->getAssociationMapping('person');
return sprintf(
'%s JOIN %s ON %s.%s = %s',
$metadataActivity->getTableName(),
$metadataPerson->getTableName(),
$metadataPerson->getTableName(),
$associationMapping['joinColumns'][0]['referencedColumnName'],
$associationMapping['joinColumns'][0]['name']
);
}
private function getWhereClauseForPerson(Person $person)
{
$parameters = [];
$metadataActivity = $this->em->getClassMetadata(Activity::class);
$associationMapping = $metadataActivity->getAssociationMapping('person');
$role = new Role('CHILL_ACTIVITY_SEE');
$reachableScopes = $this->helper->getReachableScopes($this->user, $role->getRole(), $person->getCenter());
$whereClause = sprintf(' {activity.person_id} = ? AND {activity.scope_id} IN ({scopes_ids}) ');
$scopes_ids = [];
// first parameter: activity.person_id
$parameters[] = $person->getId();
// loop on reachable scopes
foreach ($reachableScopes as $scope) {
if (in_array($scope->getId(), $scopes_ids)) {
continue;
}
$scopes_ids[] = '?';
$parameters[] = $scope->getId();
}
return [
strtr(
$whereClause,
[
'{activity.person_id}' => $associationMapping['joinColumns'][0]['name'],
'{activity.scope_id}' => $metadataActivity->getTableName() . '.' .
$metadataActivity->getAssociationMapping('scope')['joinColumns'][0]['name'],
'{scopes_ids}' => implode(', ', $scopes_ids),
]
),
$parameters,
];
}
} }

View File

@@ -1,38 +1,40 @@
<?php <?php
/* /**
* Chill is a software for social workers * Chill is a software for social workers
* *
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, * For the full copyright and license information, please view
* <http://www.champs-libres.coop>, <info@champs-libres.coop> * the LICENSE file that was distributed with this source code.
*
* 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\Migrations\Activity; namespace Chill\Migrations\Activity;
use Doctrine\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/** /**
* Auto-generated Migration: Please modify to your needs! * Auto-generated Migration: Please modify to your needs!
*/ */
class Version20150701091248 extends AbstractMigration class Version20150701091248 extends AbstractMigration
{ {
/** public function down(Schema $schema): void
* @param Schema $schema {
*/ // this down() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE Activity DROP CONSTRAINT FK_55026B0C59BB1592');
$this->addSql('ALTER TABLE ActivityReason DROP CONSTRAINT FK_654A2FCD12469DE2');
$this->addSql('ALTER TABLE Activity DROP CONSTRAINT FK_55026B0CC54C8C93');
$this->addSql('DROP SEQUENCE Activity_id_seq CASCADE');
$this->addSql('DROP SEQUENCE ActivityReason_id_seq CASCADE');
$this->addSql('DROP SEQUENCE ActivityReasonCategory_id_seq CASCADE');
$this->addSql('DROP SEQUENCE ActivityType_id_seq CASCADE');
$this->addSql('DROP TABLE Activity');
$this->addSql('DROP TABLE ActivityReason');
$this->addSql('DROP TABLE ActivityReasonCategory');
$this->addSql('DROP TABLE ActivityType');
}
public function up(Schema $schema): void public function up(Schema $schema): void
{ {
// this up() migration is auto-generated, please modify it to your needs // this up() migration is auto-generated, please modify it to your needs
@@ -59,25 +61,4 @@ class Version20150701091248 extends AbstractMigration
$this->addSql('ALTER TABLE Activity ADD CONSTRAINT FK_55026B0C217BBB47 FOREIGN KEY (person_id) REFERENCES Person (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); $this->addSql('ALTER TABLE Activity ADD CONSTRAINT FK_55026B0C217BBB47 FOREIGN KEY (person_id) REFERENCES Person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE ActivityReason ADD CONSTRAINT FK_654A2FCD12469DE2 FOREIGN KEY (category_id) REFERENCES ActivityReasonCategory (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); $this->addSql('ALTER TABLE ActivityReason ADD CONSTRAINT FK_654A2FCD12469DE2 FOREIGN KEY (category_id) REFERENCES ActivityReasonCategory (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
} }
}
/**
* @param Schema $schema
*/
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE Activity DROP CONSTRAINT FK_55026B0C59BB1592');
$this->addSql('ALTER TABLE ActivityReason DROP CONSTRAINT FK_654A2FCD12469DE2');
$this->addSql('ALTER TABLE Activity DROP CONSTRAINT FK_55026B0CC54C8C93');
$this->addSql('DROP SEQUENCE Activity_id_seq CASCADE');
$this->addSql('DROP SEQUENCE ActivityReason_id_seq CASCADE');
$this->addSql('DROP SEQUENCE ActivityReasonCategory_id_seq CASCADE');
$this->addSql('DROP SEQUENCE ActivityType_id_seq CASCADE');
$this->addSql('DROP TABLE Activity');
$this->addSql('DROP TABLE ActivityReason');
$this->addSql('DROP TABLE ActivityReasonCategory');
$this->addSql('DROP TABLE ActivityType');
}
}

View File

@@ -1,54 +1,22 @@
<?php <?php
/* /**
* Chill is a software for social workers * Chill is a software for social workers
* *
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, * For the full copyright and license information, please view
* <http://www.champs-libres.coop>, <info@champs-libres.coop> * the LICENSE file that was distributed with this source code.
*
* 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\Migrations\Activity; namespace Chill\Migrations\Activity;
use Doctrine\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/** /**
* Auto-generated Migration: Please modify to your needs! * Auto-generated Migration: Please modify to your needs!
*/ */
class Version20150702093317 extends AbstractMigration class Version20150702093317 extends AbstractMigration
{ {
/**
* @param Schema $schema
*/
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE ActivityReasonCategory DROP COLUMN label;');
$this->addSql('ALTER TABLE ActivityReasonCategory ADD COLUMN name JSON;');
$this->addSql('ALTER TABLE ActivityReason DROP COLUMN label;');
$this->addSql('ALTER TABLE ActivityReason ADD COLUMN name JSON;');
$this->addSql('ALTER TABLE ActivityType DROP COLUMN name;');
$this->addSql('ALTER TABLE ActivityType ADD COLUMN name JSON;');
}
/**
* @param Schema $schema
*/
public function down(Schema $schema): void public function down(Schema $schema): void
{ {
// this down() migration is auto-generated, please modify it to your needs // this down() migration is auto-generated, please modify it to your needs
@@ -61,4 +29,17 @@ class Version20150702093317 extends AbstractMigration
$this->addSql('ALTER TABLE ActivityType DROP COLUMN name;'); $this->addSql('ALTER TABLE ActivityType DROP COLUMN name;');
$this->addSql('ALTER TABLE ActivityType ADD COLUMN name VARCHAR(255) NOT NULL;'); $this->addSql('ALTER TABLE ActivityType ADD COLUMN name VARCHAR(255) NOT NULL;');
} }
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE ActivityReasonCategory DROP COLUMN label;');
$this->addSql('ALTER TABLE ActivityReasonCategory ADD COLUMN name JSON;');
$this->addSql('ALTER TABLE ActivityReason DROP COLUMN label;');
$this->addSql('ALTER TABLE ActivityReason ADD COLUMN name JSON;');
$this->addSql('ALTER TABLE ActivityType DROP COLUMN name;');
$this->addSql('ALTER TABLE ActivityType ADD COLUMN name JSON;');
}
}

View File

@@ -1,51 +1,22 @@
<?php <?php
/* /**
* Chill is a software for social workers * Chill is a software for social workers
* *
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, * For the full copyright and license information, please view
* <http://www.champs-libres.coop>, <info@champs-libres.coop> * the LICENSE file that was distributed with this source code.
*
* 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\Migrations\Activity; namespace Chill\Migrations\Activity;
use Doctrine\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/** /**
* Db Migration * Db Migration.
*
*/ */
class Version20150704091347 extends AbstractMigration class Version20150704091347 extends AbstractMigration
{ {
/**
* @param Schema $schema
*/
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE Activity ALTER COLUMN remark DROP NOT NULL;');
$this->addSql('ALTER TABLE Activity ALTER COLUMN attendee DROP NOT NULL;');
}
/**
* @param Schema $schema
*/
public function down(Schema $schema): void public function down(Schema $schema): void
{ {
// this down() migration is auto-generated, please modify it to your needs // this down() migration is auto-generated, please modify it to your needs
@@ -54,4 +25,13 @@ class Version20150704091347 extends AbstractMigration
$this->addSql('ALTER TABLE Activity ALTER COLUMN remark SET NOT NULL;'); $this->addSql('ALTER TABLE Activity ALTER COLUMN remark SET NOT NULL;');
$this->addSql('ALTER TABLE Activity ALTER COLUMN attendee DROP NOT NULL;'); $this->addSql('ALTER TABLE Activity ALTER COLUMN attendee DROP NOT NULL;');
} }
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE Activity ALTER COLUMN remark DROP NOT NULL;');
$this->addSql('ALTER TABLE Activity ALTER COLUMN attendee DROP NOT NULL;');
}
} }

View File

@@ -1,60 +1,31 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\Migrations\Activity; namespace Chill\Migrations\Activity;
use Doctrine\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/** /**
* Migrate schema to allow multiple or empty reasons on an activity. * Migrate schema to allow multiple or empty reasons on an activity.
* *
* The relation between the activity and reason **was** oneToMany. After this * The relation between the activity and reason **was** oneToMany. After this
* migration, the relation will be manyToMany. * migration, the relation will be manyToMany.
*/ */
class Version20160222103457 extends AbstractMigration class Version20160222103457 extends AbstractMigration
{ {
/**
* @param Schema $schema
*/
public function up(Schema $schema): void
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql',
'Migration can only be executed safely on \'postgresql\'.');
// create the new table activity reason
$this->addSql('CREATE TABLE activity_activityreason ('
. 'activity_id INT NOT NULL, '
. 'activityreason_id INT NOT NULL, '
. 'PRIMARY KEY(activity_id, activityreason_id))'
);
$this->addSql('CREATE INDEX IDX_338A864381C06096 ON activity_activityreason (activity_id)');
$this->addSql('CREATE INDEX IDX_338A8643D771E0FC ON activity_activityreason (activityreason_id)');
$this->addSql('ALTER TABLE activity_activityreason '
. 'ADD CONSTRAINT FK_338A864381C06096 FOREIGN KEY (activity_id) '
. 'REFERENCES Activity (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE activity_activityreason '
. 'ADD CONSTRAINT FK_338A8643D771E0FC FOREIGN KEY (activityreason_id) '
. 'REFERENCES ActivityReason (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
// migrate old data to new table
$this->addSql('INSERT INTO activity_activityreason (activity_id, activityreason_id) '
. 'SELECT id, reason_id FROM activity WHERE reason_id IS NOT NULL');
// remove old column
$this->addSql('ALTER TABLE activity DROP CONSTRAINT fk_55026b0c59bb1592');
$this->addSql('DROP INDEX idx_55026b0c59bb1592');
$this->addSql('ALTER TABLE activity DROP reason_id');
}
/**
* @param Schema $schema
*/
public function down(Schema $schema): void public function down(Schema $schema): void
{ {
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', $this->abortIf(
'Migration can only be executed safely on \'postgresql\'.'); $this->connection->getDatabasePlatform()->getName() != 'postgresql',
'Migration can only be executed safely on \'postgresql\'.'
);
$this->addSql('ALTER TABLE Activity ADD reason_id INT DEFAULT NULL'); $this->addSql('ALTER TABLE Activity ADD reason_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE Activity ADD CONSTRAINT ' $this->addSql('ALTER TABLE Activity ADD CONSTRAINT '
@@ -63,17 +34,49 @@ class Version20160222103457 extends AbstractMigration
$this->addSql('CREATE INDEX idx_55026b0c59bb1592 ON Activity (reason_id)'); $this->addSql('CREATE INDEX idx_55026b0c59bb1592 ON Activity (reason_id)');
// try to keep at least on activity reason... // try to keep at least on activity reason...
$this->addSql('UPDATE activity $this->addSql(
'UPDATE activity
SET reason_id=rid SET reason_id=rid
FROM ( FROM (
SELECT activity_id AS aid, MIN(activityreason_id) AS rid SELECT activity_id AS aid, MIN(activityreason_id) AS rid
FROM activity_activityreason FROM activity_activityreason
GROUP BY activity_id ) AS sb GROUP BY activity_id ) AS sb
WHERE sb.aid = activity.id' WHERE sb.aid = activity.id'
); );
$this->addSql('DROP TABLE activity_activityreason'); $this->addSql('DROP TABLE activity_activityreason');
}
public function up(Schema $schema): void
{
$this->abortIf(
$this->connection->getDatabasePlatform()->getName() != 'postgresql',
'Migration can only be executed safely on \'postgresql\'.'
);
// create the new table activity reason
$this->addSql(
'CREATE TABLE activity_activityreason ('
. 'activity_id INT NOT NULL, '
. 'activityreason_id INT NOT NULL, '
. 'PRIMARY KEY(activity_id, activityreason_id))'
);
$this->addSql('CREATE INDEX IDX_338A864381C06096 ON activity_activityreason (activity_id)');
$this->addSql('CREATE INDEX IDX_338A8643D771E0FC ON activity_activityreason (activityreason_id)');
$this->addSql('ALTER TABLE activity_activityreason '
. 'ADD CONSTRAINT FK_338A864381C06096 FOREIGN KEY (activity_id) '
. 'REFERENCES Activity (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE activity_activityreason '
. 'ADD CONSTRAINT FK_338A8643D771E0FC FOREIGN KEY (activityreason_id) '
. 'REFERENCES ActivityReason (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
// migrate old data to new table
$this->addSql('INSERT INTO activity_activityreason (activity_id, activityreason_id) '
. 'SELECT id, reason_id FROM activity WHERE reason_id IS NOT NULL');
// remove old column
$this->addSql('ALTER TABLE activity DROP CONSTRAINT fk_55026b0c59bb1592');
$this->addSql('DROP INDEX idx_55026b0c59bb1592');
$this->addSql('ALTER TABLE activity DROP reason_id');
} }
} }

View File

@@ -1,29 +1,29 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\Migrations\Activity; namespace Chill\Migrations\Activity;
use Doctrine\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Types\Types; use Doctrine\Migrations\AbstractMigration;
/** /**
* Add an "active" column on activitytype table * Add an "active" column on activitytype table.
*/ */
class Version20161114085659 extends AbstractMigration class Version20161114085659 extends AbstractMigration
{ {
/**
* @param Schema $schema
*/
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE activitytype ADD active BOOLEAN NOT NULL DEFAULT \'t\'');
}
/**
* @param Schema $schema
*/
public function down(Schema $schema): void public function down(Schema $schema): void
{ {
$this->addSql('ALTER TABLE ActivityType DROP active'); $this->addSql('ALTER TABLE ActivityType DROP active');
} }
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE activitytype ADD active BOOLEAN NOT NULL DEFAULT \'t\'');
}
} }

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\Migrations\Activity; namespace Chill\Migrations\Activity;
@@ -12,20 +19,7 @@ use Doctrine\Migrations\AbstractMigration;
*/ */
final class Version20210304154629 extends AbstractMigration final class Version20210304154629 extends AbstractMigration
{ {
public function getDescription() : string public function down(Schema $schema): void
{
return '';
}
public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE activity ADD comment_comment TEXT DEFAULT NULL');
$this->addSql('ALTER TABLE activity ADD comment_userId INT DEFAULT NULL');
$this->addSql('ALTER TABLE activity ADD comment_date TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL');
}
public function down(Schema $schema) : void
{ {
// this down() migration is auto-generated, please modify it to your needs // this down() migration is auto-generated, please modify it to your needs
@@ -33,4 +27,17 @@ final class Version20210304154629 extends AbstractMigration
$this->addSql('ALTER TABLE activity DROP comment_userId'); $this->addSql('ALTER TABLE activity DROP comment_userId');
$this->addSql('ALTER TABLE activity DROP comment_date'); $this->addSql('ALTER TABLE activity DROP comment_date');
} }
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE activity ADD comment_comment TEXT DEFAULT NULL');
$this->addSql('ALTER TABLE activity ADD comment_userId INT DEFAULT NULL');
$this->addSql('ALTER TABLE activity ADD comment_date TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL');
}
} }

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\Migrations\Activity; namespace Chill\Migrations\Activity;
@@ -12,21 +19,20 @@ use Doctrine\Migrations\AbstractMigration;
*/ */
final class Version20210311114250 extends AbstractMigration final class Version20210311114250 extends AbstractMigration
{ {
public function getDescription() : string public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
}
public function getDescription(): string
{ {
return ''; return '';
} }
public function up(Schema $schema) : void public function up(Schema $schema): void
{ {
// this up() migration is auto-generated, please modify it to your needs // this up() migration is auto-generated, please modify it to your needs
$this->addSql('UPDATE activity SET comment_comment = remark'); $this->addSql('UPDATE activity SET comment_comment = remark');
$this->addSql('ALTER TABLE activity DROP remark'); $this->addSql('ALTER TABLE activity DROP remark');
} }
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
}
} }

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\Migrations\Activity; namespace Chill\Migrations\Activity;
@@ -12,24 +19,23 @@ use Doctrine\Migrations\AbstractMigration;
*/ */
final class Version20210401090853 extends AbstractMigration final class Version20210401090853 extends AbstractMigration
{ {
public function getDescription() : string public function down(Schema $schema): void
{
return '';
}
public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SEQUENCE activitytypecategory_id_seq INCREMENT BY 1 MINVALUE 1 START 1000');
$this->addSql('CREATE TABLE activitytypecategory (id INT NOT NULL, name JSON NOT NULL, active BOOLEAN NOT NULL, PRIMARY KEY(id))');
$this->addSql('INSERT INTO activitytypecategory VALUES(1, \'{"fr": "Défaut", "en": "Default"}\', true)');
}
public function down(Schema $schema) : void
{ {
// this down() migration is auto-generated, please modify it to your needs // this down() migration is auto-generated, please modify it to your needs
$this->addSql('DROP SEQUENCE activitytypecategory_id_seq CASCADE'); $this->addSql('DROP SEQUENCE activitytypecategory_id_seq CASCADE');
$this->addSql('DROP TABLE activitytypecategory'); $this->addSql('DROP TABLE activitytypecategory');
} }
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SEQUENCE activitytypecategory_id_seq INCREMENT BY 1 MINVALUE 1 START 1000');
$this->addSql('CREATE TABLE activitytypecategory (id INT NOT NULL, name JSON NOT NULL, active BOOLEAN NOT NULL, PRIMARY KEY(id))');
$this->addSql('INSERT INTO activitytypecategory VALUES(1, \'{"fr": "Défaut", "en": "Default"}\', true)');
}
} }

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\Migrations\Activity; namespace Chill\Migrations\Activity;
@@ -12,48 +19,7 @@ use Doctrine\Migrations\AbstractMigration;
*/ */
final class Version20210408122329 extends AbstractMigration final class Version20210408122329 extends AbstractMigration
{ {
public function getDescription() : string public function down(Schema $schema): void
{
return '';
}
public function up(Schema $schema) : void
{
$this->addSql('ALTER TABLE activitytype ADD personVisible SMALLINT DEFAULT 2 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD personLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD userVisible SMALLINT DEFAULT 2 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD userLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD dateVisible SMALLINT DEFAULT 2 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD dateLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD placeVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD placeLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD personsVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD personsLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD thirdpartyVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD thirdpartyLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD durationTimeVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD durationTimeLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD attendeeVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD attendeeLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD reasonsVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD reasonsLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD commentVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD commentLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD sentReceivedVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD sentReceivedLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD documentVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD documentLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD emergencyVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD emergencyLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD accompanyingPeriodVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD accompanyingPeriodLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD socialDataVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD socialDataLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ALTER name SET NOT NULL');
$this->addSql('ALTER TABLE activitytype ALTER active DROP DEFAULT');
}
public function down(Schema $schema) : void
{ {
$this->addSql('ALTER TABLE activitytype DROP personVisible'); $this->addSql('ALTER TABLE activitytype DROP personVisible');
$this->addSql('ALTER TABLE activitytype DROP personLabel'); $this->addSql('ALTER TABLE activitytype DROP personLabel');
@@ -89,4 +55,45 @@ final class Version20210408122329 extends AbstractMigration
$this->addSql('ALTER TABLE activitytype ALTER active SET DEFAULT \'true\''); $this->addSql('ALTER TABLE activitytype ALTER active SET DEFAULT \'true\'');
$this->addSql('COMMENT ON COLUMN activitytype.name IS NULL'); $this->addSql('COMMENT ON COLUMN activitytype.name IS NULL');
} }
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE activitytype ADD personVisible SMALLINT DEFAULT 2 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD personLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD userVisible SMALLINT DEFAULT 2 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD userLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD dateVisible SMALLINT DEFAULT 2 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD dateLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD placeVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD placeLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD personsVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD personsLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD thirdpartyVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD thirdpartyLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD durationTimeVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD durationTimeLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD attendeeVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD attendeeLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD reasonsVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD reasonsLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD commentVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD commentLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD sentReceivedVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD sentReceivedLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD documentVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD documentLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD emergencyVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD emergencyLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD accompanyingPeriodVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD accompanyingPeriodLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD socialDataVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD socialDataLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ALTER name SET NOT NULL');
$this->addSql('ALTER TABLE activitytype ALTER active DROP DEFAULT');
}
} }

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\Migrations\Activity; namespace Chill\Migrations\Activity;
@@ -12,24 +19,7 @@ use Doctrine\Migrations\AbstractMigration;
*/ */
final class Version20210415113216 extends AbstractMigration final class Version20210415113216 extends AbstractMigration
{ {
public function getDescription() : string public function down(Schema $schema): void
{
return '';
}
public function up(Schema $schema) : void
{
$this->addSql('ALTER TABLE activitytype ADD thirdPartiesVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD thirdPartiesLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD documentsVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD documentsLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype DROP thirdpartyvisible');
$this->addSql('ALTER TABLE activitytype DROP thirdpartylabel');
$this->addSql('ALTER TABLE activitytype DROP documentvisible');
$this->addSql('ALTER TABLE activitytype DROP documentlabel');
}
public function down(Schema $schema) : void
{ {
$this->addSql('ALTER TABLE activitytype ADD thirdpartyvisible SMALLINT DEFAULT 1 NOT NULL'); $this->addSql('ALTER TABLE activitytype ADD thirdpartyvisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD thirdpartylabel VARCHAR(255) DEFAULT \'\' NOT NULL'); $this->addSql('ALTER TABLE activitytype ADD thirdpartylabel VARCHAR(255) DEFAULT \'\' NOT NULL');
@@ -40,4 +30,21 @@ final class Version20210415113216 extends AbstractMigration
$this->addSql('ALTER TABLE activitytype DROP documentsVisible'); $this->addSql('ALTER TABLE activitytype DROP documentsVisible');
$this->addSql('ALTER TABLE activitytype DROP documentsLabel'); $this->addSql('ALTER TABLE activitytype DROP documentsLabel');
} }
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE activitytype ADD thirdPartiesVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD thirdPartiesLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD documentsVisible SMALLINT DEFAULT 1 NOT NULL');
$this->addSql('ALTER TABLE activitytype ADD documentsLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
$this->addSql('ALTER TABLE activitytype DROP thirdpartyvisible');
$this->addSql('ALTER TABLE activitytype DROP thirdpartylabel');
$this->addSql('ALTER TABLE activitytype DROP documentvisible');
$this->addSql('ALTER TABLE activitytype DROP documentlabel');
}
} }

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1); declare(strict_types=1);
namespace Chill\Migrations\Activity; namespace Chill\Migrations\Activity;
@@ -12,33 +19,7 @@ use Doctrine\Migrations\AbstractMigration;
*/ */
final class Version20210422073711 extends AbstractMigration final class Version20210422073711 extends AbstractMigration
{ {
public function getDescription() : string public function down(Schema $schema): void
{
return '';
}
public function up(Schema $schema) : void
{
$this->addSql('CREATE SEQUENCE activitytpresence_id_seq INCREMENT BY 1 MINVALUE 1 START 6');
$this->addSql('CREATE TABLE activitytpresence (id INT NOT NULL, name JSON NOT NULL, active BOOLEAN NOT NULL, PRIMARY KEY(id))');
$list = [
'Usager pésent', "Absence de l''usager",
"Refus de visite ou d''entretien", 'Domicile non trouvé',
'Domicile erronéee'
];
for ($i = 1; $i <= count($list); $i++) {
$this->addSql("INSERT INTO activitytpresence VALUES(".$i.", json_build_object('fr', '".$list[$i-1]."'), true)");
}
$this->addSql('ALTER TABLE activity ADD emergency BOOLEAN NOT NULL DEFAULT false');
$this->addSql('ALTER TABLE activity ADD sentReceived VARCHAR(255) NOT NULL DEFAULT \'\' ');
$this->addSql('ALTER TABLE activity ALTER attendee TYPE INT USING CASE WHEN attendee is false THEN 2 WHEN attendee is true THEN 1 ELSE null END');
$this->addSql('ALTER TABLE activity RENAME COLUMN attendee TO attendee_id');
$this->addSql('ALTER TABLE activity ADD CONSTRAINT FK_AC74095ABCFD782A FOREIGN KEY (attendee_id) REFERENCES activitytpresence (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
}
public function down(Schema $schema) : void
{ {
$this->addSql('ALTER TABLE activity DROP emergency'); $this->addSql('ALTER TABLE activity DROP emergency');
$this->addSql('ALTER TABLE activity DROP CONSTRAINT FK_AC74095ABCFD782A'); $this->addSql('ALTER TABLE activity DROP CONSTRAINT FK_AC74095ABCFD782A');
@@ -49,4 +30,31 @@ final class Version20210422073711 extends AbstractMigration
$this->addSql('DROP SEQUENCE activitytpresence_id_seq CASCADE'); $this->addSql('DROP SEQUENCE activitytpresence_id_seq CASCADE');
$this->addSql('DROP TABLE activitytpresence'); $this->addSql('DROP TABLE activitytpresence');
} }
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
$this->addSql('CREATE SEQUENCE activitytpresence_id_seq INCREMENT BY 1 MINVALUE 1 START 6');
$this->addSql('CREATE TABLE activitytpresence (id INT NOT NULL, name JSON NOT NULL, active BOOLEAN NOT NULL, PRIMARY KEY(id))');
$list = [
'Usager pésent', "Absence de l''usager",
"Refus de visite ou d''entretien", 'Domicile non trouvé',
'Domicile erronéee',
];
for ($i = 1; count($list) >= $i; ++$i) {
$this->addSql('INSERT INTO activitytpresence VALUES(' . $i . ", json_build_object('fr', '" . $list[$i - 1] . "'), true)");
}
$this->addSql('ALTER TABLE activity ADD emergency BOOLEAN NOT NULL DEFAULT false');
$this->addSql('ALTER TABLE activity ADD sentReceived VARCHAR(255) NOT NULL DEFAULT \'\' ');
$this->addSql('ALTER TABLE activity ALTER attendee TYPE INT USING CASE WHEN attendee is false THEN 2 WHEN attendee is true THEN 1 ELSE null END');
$this->addSql('ALTER TABLE activity RENAME COLUMN attendee TO attendee_id');
$this->addSql('ALTER TABLE activity ADD CONSTRAINT FK_AC74095ABCFD782A FOREIGN KEY (attendee_id) REFERENCES activitytpresence (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
}
} }

Some files were not shown because too many files have changed in this diff Show More