ci: Autofix code style.

This commit is contained in:
Pol Dellaiera 2021-05-07 21:48:14 +02:00
parent ce4cbe3b8d
commit ee4e0b86fd
814 changed files with 51175 additions and 54478 deletions

View File

@ -1,123 +1,124 @@
<?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;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\FilterInterface;
use DateTime;
use Doctrine\ORM\Query\Expr;
use Symfony\Component\Form\Extension\Core\Type\DateType;
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
{
// add specific role for this filter
// add specific role for this filter
public function addRole()
{
// we do not need any new role for this filter, so we 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
public function applyOn()
{
return 'person';
}
public function getTitle()
{
return 'Filter by person\'s birthdate';
}
// we build a form to collect some parameters from the users
public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder)
{
$builder->add('date_from', DateType::class, array(
'label' => "Born after this date",
'data' => new \DateTime(),
'attr' => array('class' => 'datepicker'),
'widget'=> 'single_text',
$builder->add('date_from', DateType::class, [
'label' => 'Born after this date',
'data' => new DateTime(),
'attr' => ['class' => 'datepicker'],
'widget' => 'single_text',
'format' => 'dd-MM-yyyy',
));
$builder->add('date_to', DateType::class, array(
'label' => "Born before this date",
'data' => new \DateTime(),
'attr' => array('class' => 'datepicker'),
'widget'=> 'single_text',
]);
$builder->add('date_to', DateType::class, [
'label' => 'Born before this date',
'data' => new DateTime(),
'attr' => ['class' => 'datepicker'],
'widget' => 'single_text',
'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
// the filter in the Response
public function describeAction($data, $format = 'string')
{
return array('Filtered by person\'s birtdate: '
. 'between %date_from% and %date_to%', array(
return ['Filtered by person\'s birtdate: '
. 'between %date_from% and %date_to%', [
'%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,74 +1,74 @@
<?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;
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\PersonBundle\Export\Declarations;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
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
{
/**
*
* @var EntityManagerInterface
*/
protected $entityManager;
public function __construct(
EntityManagerInterface $em
)
{
EntityManagerInterface $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()
{
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()
public function getQueryKeys($data)
{
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;
// this array match the result keys in the query. We have only
// one column.
return ['export_result'];
}
public function getResult($qb, $data)
@ -76,44 +76,42 @@ class CountPerson implements ExportInterface
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
public function getQueryKeys($data)
public function getTitle()
{
// this array match the result keys in the query. We have only
// one column.
return array('export_result');
return 'Count peoples';
}
public function getLabels($key, array $values, $data)
public function getType()
{
// 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;
};
};
return Declarations::PERSON_TYPE;
}
public function getAllowedFormattersTypes()
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{
return array(FormatterInterface::TYPE_TABULAR);
// 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 buildForm(FormBuilderInterface $builder) {
// this export does not add any form
public function requiredRole()
{
return new Role(PersonVoter::STATS);
}
public function supportsModifiers()
{
// 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,20 +1,25 @@
<?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;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class ItemController extends Controller {
class ItemController extends Controller
{
public function yourAction()
{
$em = $this->getDoctrine()->getManager();
// first, get the number of total item are available
$total = $em
->createQuery("SELECT COUNT (item.id) FROM ChillMyBundle:Item item")
->getSingleScalarResult();
->createQuery('SELECT COUNT (item.id) FROM ChillMyBundle:Item item')
->getSingleScalarResult();
// get the PaginatorFactory
$paginatorFactory = $this->get('chill_main.paginator_factory');
@ -25,7 +30,7 @@ class ItemController extends Controller {
// launch your query on item. Limit the query to the results
// 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
->setFirstResult($paginator->getCurrentPage()->getFirstItemNumber())
// use the paginator to get the number of items to display
@ -34,12 +39,10 @@ class ItemController extends Controller {
return $this
->render(
'ChillMyBundle:Item:list.html.twig',
array(
[
'items' => $items,
'paginator' => $paginator
)
'paginator' => $paginator,
]
);
}
}

View File

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

View File

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

View File

@ -1,16 +1,17 @@
<?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;
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\Configuration;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
/**
* This class load config for chillMainExtension.
@ -18,42 +19,42 @@ use Chill\MainBundle\DependencyInjection\Configuration;
class ChillMainExtension extends Extension implements Widget\HasWidgetFactoriesExtensionInterface
{
/**
* widget factory
*
* widget factory.
*
* @var WidgetFactoryInterface[]
*/
protected $widgetFactories = array();
protected $widgetFactories = [];
public function addWidgetFactory(WidgetFactoryInterface $factory)
{
$this->widgetFactories[] = $factory;
}
public function getConfiguration(array $config, ContainerBuilder $container)
{
return new Configuration($this->widgetFactories, $container);
}
/**
*
* @return WidgetFactoryInterface[]
*/
public function getWidgetFactories()
{
return $this->widgetFactories;
}
public function load(array $configs, ContainerBuilder $container)
{
// configuration for main bundle
$configuration = $this->getConfiguration($configs, $container);
$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
# 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;
use Chill\MainBundle\DependencyInjection\Widget\Factory\AbstractWidgetFactory;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\Definition\Builder\NodeBuilder;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* add configuration for the person_list widget.
*/
class PersonListWidgetFactory extends AbstractWidgetFactory
{
/*
* append the option to the configuration
* see http://symfony.com/doc/current/components/config/definition.html
*
*/
/*
* append the option to the configuration
* see http://symfony.com/doc/current/components/config/definition.html
*
*/
public function configureOptions($place, NodeBuilder $node)
{
$node->booleanNode('only_active')
->defaultTrue()
->end();
->defaultTrue()
->end();
$node->integerNode('number_of_items')
->defaultValue(50)
->end();
$node->scalarNode('filtering_class')
->defaultNull()
->end();
->defaultNull()
->end();
}
/*
* return an array with the allowed places where the widget can be rendered
*
* @return string[]
*/
/*
* return an array with the allowed places where the widget can be rendered
*
* @return string[]
*/
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.
*
* 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.
*/
public function getServiceId(ContainerBuilder $containerBuilder, $place, $order, array $config)
{
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
# 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;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
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\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 Chill\PersonBundle\Security\Authorization\PersonVoter;
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`
*/
class PersonListWidget implements WidgetInterface
{
/**
* Repository for persons
*
* @var EntityRepository
* the authorization helper.
*
* @var AuthorizationHelper;
*/
protected $personRepository;
protected $authorizationHelper;
/**
* The entity manager
* The entity manager.
*
* @var EntityManager
*/
protected $entityManager;
/**
* the authorization helper
*
* @var AuthorizationHelper;
*/
protected $authorizationHelper;
/**
* Repository for persons.
*
* @var EntityRepository
*/
protected $personRepository;
/**
* @var TokenStorage
*/
protected $tokenStorage;
/**
*
* @var UserInterface
*/
protected $user;
public function __construct(
EntityRepository $personRepostory,
EntityManager $em,
AuthorizationHelper $authorizationHelper,
TokenStorage $tokenStorage
) {
EntityRepository $personRepostory,
EntityManager $em,
AuthorizationHelper $authorizationHelper,
TokenStorage $tokenStorage
) {
$this->personRepository = $personRepostory;
$this->authorizationHelper = $authorizationHelper;
$this->tokenStorage = $tokenStorage;
@ -68,27 +73,24 @@ class PersonListWidget implements WidgetInterface
}
/**
*
* @param type $place
* @param array $context
* @param array $config
*
* @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
->createQueryBuilder('person');
->createQueryBuilder('person');
// show only the person from the authorized centers
$and = $qb->expr()->andX();
$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'));
$qb->setParameter('centers', $centers);
// add the "only active" where clause
if ($config['only_active'] === true) {
if (true === $config['only_active']) {
$qb->join('person.accompanyingPeriods', 'ap');
$or = new Expr\Orx();
// add the case where closingDate IS NULL
@ -98,32 +100,30 @@ class PersonListWidget implements WidgetInterface
$or->add($andWhenClosingDateIsNull);
// add the case when now is between opening date and closing date
$or->add(
(new Expr())->between(':now', 'ap.openingDate', 'ap.closingDate')
);
(new Expr())->between(':now', 'ap.openingDate', 'ap.closingDate')
);
$and->add($or);
$qb->setParameter('now', new \DateTime(), Type::DATE);
$qb->setParameter('now', new DateTime(), Type::DATE);
}
// adding the where clause to the query
$qb->where($and);
$qb->setFirstResult(0)->setMaxResults($config['number_of_items']);
$persons = $qb->getQuery()->getResult();
return $env->render(
'ChillPersonBundle:Widget:homepage_person_list.html.twig',
array('persons' => $persons)
);
['persons' => $persons]
);
}
/**
*
* @return UserInterface
*/
private function getUser()
{
// return a user
}
}

View File

@ -1,51 +1,46 @@
<?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;
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\MissingBundleException;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
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}
*/
class ChillPersonExtension extends Extension implements PrependExtensionInterface
{
/**
* {@inheritDoc}
*/
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
*/
public function prepend(ContainerBuilder $container)
public function prepend(ContainerBuilder $container)
{
$container->prependExtensionConfig('chill_main', array(
'widgets' => array(
'homepage' => array(
array(
$container->prependExtensionConfig('chill_main', [
'widgets' => [
'homepage' => [
[
'widget_alias' => 'add_person',
'order' => 2
)
)
)
));
'order' => 2,
],
],
],
]);
}
}

View File

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

View File

@ -1,57 +1,41 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Controller;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Form\ActivityType;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\PersonBundle\Privacy\PrivacyEvent;
use DateTime;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Role\Role;
use Chill\ActivityBundle\Entity\Activity;
use Chill\PersonBundle\Entity\Person;
use Chill\ActivityBundle\Form\ActivityType;
/**
* Class ActivityController
*
* @package Chill\ActivityBundle\Controller
* Class ActivityController.
*/
class ActivityController extends AbstractController
{
/**
* @var AuthorizationHelper
*/
protected $authorizationHelper;
/**
* @var EventDispatcherInterface
*/
protected $eventDispatcher;
/**
* @var AuthorizationHelper
*/
protected $authorizationHelper;
/**
* @var LoggerInterface
*/
@ -59,9 +43,6 @@ class ActivityController extends AbstractController
/**
* ActivityController constructor.
*
* @param EventDispatcherInterface $eventDispatcher
* @param AuthorizationHelper $authorizationHelper
*/
public function __construct(
EventDispatcherInterface $eventDispatcher,
@ -73,52 +54,17 @@ class ActivityController extends AbstractController
$this->logger = $logger;
}
/**
* Lists all Activity entities.
*
*/
public function listAction($person_id, Request $request)
{
$em = $this->getDoctrine()->getManager();
$person = $em->getRepository('ChillPersonBundle:Person')->find($person_id);
if ($person === NULL) {
throw $this->createNotFoundException('Person not found');
}
$this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person);
$reachableScopes = $this->authorizationHelper
->getReachableScopes($this->getUser(), new Role('CHILL_ACTIVITY_SEE'),
$person->getCenter());
$activities = $em->getRepository('ChillActivityBundle:Activity')
->findBy(
array('person' => $person, 'scope' => $reachableScopes),
array('date' => 'DESC')
);
$event = new PrivacyEvent($person, array(
'element_class' => Activity::class,
'action' => 'list'
));
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
return $this->render('ChillActivityBundle:Activity:list.html.twig', array(
'activities' => $activities,
'person' => $person
));
}
/**
* Creates a new Activity entity.
*
* @param mixed $person_id
*/
public function createAction($person_id, Request $request)
{
$em = $this->getDoctrine()->getManager();
$person = $em->getRepository('ChillPersonBundle:Person')->find($person_id);
if ($person === NULL) {
if (null === $person) {
throw $this->createNotFoundException('person not found');
}
@ -132,133 +78,115 @@ class ActivityController extends AbstractController
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$this->denyAccessUnlessGranted('CHILL_ACTIVITY_CREATE', $entity,
'creation of this activity not allowed');
$this->denyAccessUnlessGranted(
'CHILL_ACTIVITY_CREATE',
$entity,
'creation of this activity not allowed'
);
$em->persist($entity);
$em->flush();
$this->get('session')
->getFlashBag()
->add('success',
->add(
'success',
$this->get('translator')
->trans('Success : activity created!')
);
return $this->redirect(
$this->generateUrl('chill_activity_activity_show',
array('id' => $entity->getId(), 'person_id' => $person_id)));
$this->generateUrl(
'chill_activity_activity_show',
['id' => $entity->getId(), 'person_id' => $person_id]
)
);
}
$this->get('session')
->getFlashBag()->add('danger',
->getFlashBag()->add(
'danger',
$this->get('translator')
->trans('The form is not valid. The activity has not been created !')
);
return $this->render('ChillActivityBundle:Activity:new.html.twig', array(
return $this->render('ChillActivityBundle:Activity:new.html.twig', [
'entity' => $entity,
'form' => $form->createView(),
'person' => $person
));
'form' => $form->createView(),
'person' => $person,
]);
}
/**
* Creates a form to create a Activity entity.
* Deletes a Activity entity.
*
* @param Activity $entity The entity
*
* @return \Symfony\Component\Form\Form The form
* @param mixed $id
* @param mixed $person_id
*/
private function createCreateForm(Activity $entity)
{
$form = $this->createForm(ActivityType::class, $entity,
array(
'action' => $this->generateUrl('chill_activity_activity_create', [
'person_id' => $entity->getPerson()->getId(),
]),
'method' => 'POST',
'center' => $entity->getCenter(),
'role' => new Role('CHILL_ACTIVITY_CREATE')
)
);
return $form;
}
/**
* Displays a form to create a new Activity entity.
*
*/
public function newAction($person_id)
public function deleteAction(Request $request, $id, $person_id)
{
$em = $this->getDoctrine()->getManager();
$person = $em->getRepository('ChillPersonBundle:Person')->find($person_id);
if ($person === NULL){
throw $this->createNotFoundException('Person not found');
}
/* @var $activity Activity */
$activity = $em->getRepository('ChillActivityBundle:Activity')
->find($id);
$person = $activity->getPerson();
$this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person);
$entity = new Activity();
$entity->setUser($this->get('security.token_storage')->getToken()->getUser());
$entity->setPerson($person);
$entity->setDate(new \DateTime('now'));
$this->denyAccessUnlessGranted('CHILL_ACTIVITY_CREATE', $entity);
$form = $this->createCreateForm($entity, $person);
return $this->render('ChillActivityBundle:Activity:new.html.twig', array(
'person' => $person,
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Finds and displays a Activity entity.
*
*/
public function showAction($person_id, $id)
{
$em = $this->getDoctrine()->getManager();
$person = $em->getRepository('ChillPersonBundle:Person')->find($person_id);
if (!$person) {
throw $this->createNotFoundException('person not found');
}
$this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person);
$entity = $em->getRepository('ChillActivityBundle:Activity')->find($id);
if (!$entity) {
if (!$activity) {
throw $this->createNotFoundException('Unable to find Activity entity.');
}
$this->denyAccessUnlessGranted('CHILL_ACTIVITY_SEE', $entity);
$this->denyAccessUnlessGranted('CHILL_ACTIVITY_DELETE', $activity);
$deleteForm = $this->createDeleteForm($id, $person);
$form = $this->createDeleteForm($id, $person);
$event = new PrivacyEvent($person, array(
'element_class' => Activity::class,
'element_id' => $entity->getId(),
'action' => 'show'
));
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
if ($request->getMethod() === Request::METHOD_DELETE) {
$form->handleRequest($request);
return $this->render('ChillActivityBundle:Activity:show.html.twig', array(
'person' => $person,
'entity' => $entity,
'delete_form' => $deleteForm->createView(),
));
if ($form->isValid()) {
$this->logger->notice('An activity has been removed', [
'by_user' => $this->getUser()->getUsername(),
'activity_id' => $activity->getId(),
'person_id' => $activity->getPerson()->getId(),
'comment' => $activity->getComment()->getComment(),
'scope_id' => $activity->getScope()->getId(),
'reasons_ids' => $activity->getReasons()
->map(function ($ar) {
return $ar->getId();
})
->toArray(),
'type_id' => $activity->getType()->getId(),
'duration' => $activity->getDurationTime()->format('U'),
'date' => $activity->getDate()->format('Y-m-d'),
'attendee' => $activity->getAttendee(),
]);
$em->remove($activity);
$em->flush();
$this->addFlash('success', $this->get('translator')
->trans('The activity has been successfully removed.'));
return $this->redirect($this->generateUrl(
'chill_activity_activity_list',
[
'person_id' => $person_id,
]
));
}
}
return $this->render('ChillActivityBundle:Activity:confirm_delete.html.twig', [
'activity' => $activity,
'delete_form' => $form->createView(),
]);
}
/**
* Displays a form to edit an existing Activity entity.
*
* @param mixed $person_id
* @param mixed $id
*/
public function editAction($person_id, $id)
{
@ -282,46 +210,140 @@ class ActivityController extends AbstractController
$editForm = $this->createEditForm($entity);
$deleteForm = $this->createDeleteForm($id, $person);
$event = new PrivacyEvent($person, array(
$event = new PrivacyEvent($person, [
'element_class' => Activity::class,
'element_id' => $entity->getId(),
'action' => 'edit'
));
'action' => 'edit',
]);
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
return $this->render('ChillActivityBundle:Activity:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
return $this->render('ChillActivityBundle:Activity:edit.html.twig', [
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
'person' => $person
));
'person' => $person,
]);
}
/**
* Creates a form to edit a Activity entity.
*
* @param Activity $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(Activity $entity)
* Lists all Activity entities.
*
* @param mixed $person_id
*/
public function listAction($person_id, Request $request)
{
$form = $this->createForm(ActivityType::class, $entity, array(
'action' => $this->generateUrl('chill_activity_activity_update',
array(
'id' => $entity->getId(),
'person_id' => $entity->getPerson()->getId()
)),
'method' => 'PUT',
'center' => $entity->getCenter(),
'role' => new Role('CHILL_ACTIVITY_UPDATE')
));
$em = $this->getDoctrine()->getManager();
$person = $em->getRepository('ChillPersonBundle:Person')->find($person_id);
return $form;
if (null === $person) {
throw $this->createNotFoundException('Person not found');
}
$this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person);
$reachableScopes = $this->authorizationHelper
->getReachableScopes(
$this->getUser(),
new Role('CHILL_ACTIVITY_SEE'),
$person->getCenter()
);
$activities = $em->getRepository('ChillActivityBundle:Activity')
->findBy(
['person' => $person, 'scope' => $reachableScopes],
['date' => 'DESC']
);
$event = new PrivacyEvent($person, [
'element_class' => Activity::class,
'action' => 'list',
]);
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
return $this->render('ChillActivityBundle:Activity:list.html.twig', [
'activities' => $activities,
'person' => $person,
]);
}
/**
* Displays a form to create a new Activity entity.
*
* @param mixed $person_id
*/
public function newAction($person_id)
{
$em = $this->getDoctrine()->getManager();
$person = $em->getRepository('ChillPersonBundle:Person')->find($person_id);
if (null === $person) {
throw $this->createNotFoundException('Person not found');
}
$this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person);
$entity = new Activity();
$entity->setUser($this->get('security.token_storage')->getToken()->getUser());
$entity->setPerson($person);
$entity->setDate(new DateTime('now'));
$this->denyAccessUnlessGranted('CHILL_ACTIVITY_CREATE', $entity);
$form = $this->createCreateForm($entity, $person);
return $this->render('ChillActivityBundle:Activity:new.html.twig', [
'person' => $person,
'entity' => $entity,
'form' => $form->createView(),
]);
}
/**
* Finds and displays a Activity entity.
*
* @param mixed $person_id
* @param mixed $id
*/
public function showAction($person_id, $id)
{
$em = $this->getDoctrine()->getManager();
$person = $em->getRepository('ChillPersonBundle:Person')->find($person_id);
if (!$person) {
throw $this->createNotFoundException('person not found');
}
$this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person);
$entity = $em->getRepository('ChillActivityBundle:Activity')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Activity entity.');
}
$this->denyAccessUnlessGranted('CHILL_ACTIVITY_SEE', $entity);
$deleteForm = $this->createDeleteForm($id, $person);
$event = new PrivacyEvent($person, [
'element_class' => Activity::class,
'element_id' => $entity->getId(),
'action' => 'show',
]);
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
return $this->render('ChillActivityBundle:Activity:show.html.twig', [
'person' => $person,
'entity' => $entity,
'delete_form' => $deleteForm->createView(),
]);
}
/**
* Edits an existing Activity entity.
*
* @param mixed $person_id
* @param mixed $id
*/
public function updateAction(Request $request, $person_id, $id)
{
@ -340,11 +362,11 @@ class ActivityController extends AbstractController
$editForm = $this->createEditForm($entity);
$editForm->handleRequest($request);
$event = new PrivacyEvent($person, array(
$event = new PrivacyEvent($person, [
'element_class' => Activity::class,
'element_id' => $entity->getId(),
'action' => 'update'
));
'action' => 'update',
]);
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
if ($editForm->isValid()) {
@ -352,95 +374,59 @@ class ActivityController extends AbstractController
$this->get('session')
->getFlashBag()
->add('success',
->add(
'success',
$this->get('translator')
->trans('Success : activity updated!')
);
return $this->redirect($this->generateUrl('chill_activity_activity_show', array('id' => $id, 'person_id' => $person_id)));
return $this->redirect($this->generateUrl('chill_activity_activity_show', ['id' => $id, 'person_id' => $person_id]));
}
$this->get('session')
->getFlashBag()
->add('error',
->add(
'error',
$this->get('translator')
->trans('This form contains errors')
);
return $this->render('ChillActivityBundle:Activity:edit.html.twig', array(
'person' => $entity->getPerson(),
'entity' => $entity,
'edit_form' => $editForm->createView(),
return $this->render('ChillActivityBundle:Activity:edit.html.twig', [
'person' => $entity->getPerson(),
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
]);
}
/**
* Deletes a Activity entity.
* Creates a form to create a Activity entity.
*
* @param Activity $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
public function deleteAction(Request $request, $id, $person_id)
private function createCreateForm(Activity $entity)
{
$em = $this->getDoctrine()->getManager();
/* @var $activity Activity */
$activity = $em->getRepository('ChillActivityBundle:Activity')
->find($id);
$person = $activity->getPerson();
if (!$activity) {
throw $this->createNotFoundException('Unable to find Activity entity.');
}
$this->denyAccessUnlessGranted('CHILL_ACTIVITY_DELETE', $activity);
$form = $this->createDeleteForm($id, $person);
if ($request->getMethod() === Request::METHOD_DELETE) {
$form->handleRequest($request);
if ($form->isValid()) {
$this->logger->notice("An activity has been removed", array(
'by_user' => $this->getUser()->getUsername(),
'activity_id' => $activity->getId(),
'person_id' => $activity->getPerson()->getId(),
'comment' => $activity->getComment()->getComment(),
'scope_id' => $activity->getScope()->getId(),
'reasons_ids' => $activity->getReasons()
->map(function ($ar) { return $ar->getId(); })
->toArray(),
'type_id' => $activity->getType()->getId(),
'duration' => $activity->getDurationTime()->format('U'),
'date' => $activity->getDate()->format('Y-m-d'),
'attendee' => $activity->getAttendee()
));
$em->remove($activity);
$em->flush();
$this->addFlash('success', $this->get('translator')
->trans("The activity has been successfully removed."));
return $this->redirect($this->generateUrl(
'chill_activity_activity_list', array(
'person_id' => $person_id
)));
}
}
return $this->render('ChillActivityBundle:Activity:confirm_delete.html.twig', array(
'activity' => $activity,
'delete_form' => $form->createView()
));
return $this->createForm(
ActivityType::class,
$entity,
[
'action' => $this->generateUrl('chill_activity_activity_create', [
'person_id' => $entity->getPerson()->getId(),
]),
'method' => 'POST',
'center' => $entity->getCenter(),
'role' => new Role('CHILL_ACTIVITY_CREATE'),
]
);
}
/**
* Creates a form to delete a Activity entity by id.
*
* @param mixed $id The entity id
* @param mixed $person
*
* @return \Symfony\Component\Form\Form The form
*/
@ -449,10 +435,33 @@ class ActivityController extends AbstractController
return $this->createFormBuilder()
->setAction($this->generateUrl(
'chill_activity_activity_delete',
array('id' => $id, 'person_id' => $person->getId())))
['id' => $id, 'person_id' => $person->getId()]
))
->setMethod('DELETE')
->add('submit', SubmitType::class, array('label' => 'Delete'))
->getForm()
;
->add('submit', SubmitType::class, ['label' => 'Delete'])
->getForm();
}
/**
* Creates a form to edit a Activity entity.
*
* @param Activity $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(Activity $entity)
{
return $this->createForm(ActivityType::class, $entity, [
'action' => $this->generateUrl(
'chill_activity_activity_update',
[
'id' => $entity->getId(),
'person_id' => $entity->getPerson()->getId(),
]
),
'method' => 'PUT',
'center' => $entity->getCenter(),
'role' => new Role('CHILL_ACTIVITY_UPDATE'),
]);
}
}

View File

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

View File

@ -1,33 +1,18 @@
<?php
/*
/**
* 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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
/**
* Controller for activity configuration
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @author Champs Libres <info@champs-libres.coop>
* Controller for activity configuration.
*/
class AdminController extends AbstractController
{
@ -35,7 +20,7 @@ class AdminController extends AbstractController
{
return $this->render('ChillActivityBundle:Admin:layout_activity.html.twig');
}
public function redirectToAdminIndexAction()
{
return $this->redirectToRoute('chill_main_admin_central');

View File

@ -1,42 +1,25 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\DataFixtures\ORM;
use Chill\ActivityBundle\Entity\Activity;
use Chill\MainBundle\DataFixtures\ORM\LoadScopes;
use Chill\MainBundle\DataFixtures\ORM\LoadUsers;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
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;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
/**
* Load reports into DB
*
* @author Champs-Libres Coop
* Load reports into DB.
*/
class LoadActivity extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface
{
@ -57,30 +40,48 @@ class LoadActivity extends AbstractFixture implements OrderedFixtureInterface, C
return 16400;
}
/**
* Return a random scope
*
* @return \Chill\MainBundle\Entity\Scope
*/
private function getRandomScope()
public function load(ObjectManager $manager)
{
$scopeRef = LoadScopes::$references[array_rand(LoadScopes::$references)];
return $this->getReference($scopeRef);
$persons = $this->container->get('doctrine.orm.entity_manager')
->getRepository('ChillPersonBundle:Person')
->findAll();
foreach ($persons as $person) {
$activityNbr = rand(0, 3);
for ($i = 0; $i < $activityNbr; ++$i) {
echo 'Creating an activity type for : ' . $person . "\n";
$activity = $this->newRandomActivity($person);
$manager->persist($activity);
}
}
$manager->flush();
}
public function newRandomActivity($person)
{
$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());
$usedId = [];
for ($i = 0; rand(0, 4) > $i; ++$i) {
$reason = $this->getRandomActivityReason($usedId);
$usedId[] = $reason->getId();
$activity->addReason($reason);
}
return $activity;
}
/**
* 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 activityReason
* Return a random activityReason.
*
* @return \Chill\ActivityBundle\Entity\ActivityReason
*/
@ -97,52 +98,38 @@ class LoadActivity extends AbstractFixture implements OrderedFixtureInterface, C
}
/**
* 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
*/
private function getRandomUser()
{
$userRef = array_rand(LoadUsers::$refs);
return $this->getReference($userRef);
}
public function newRandomActivity($person)
{
$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())
;
$usedId = array();
for ($i = 0; $i < rand(0, 4); $i++) {
$reason = $this->getRandomActivityReason($usedId);
$usedId[] = $reason->getId();
$activity->addReason($reason);
}
return $activity;
}
public function load(ObjectManager $manager)
{
$persons = $this->container->get('doctrine.orm.entity_manager')
->getRepository('ChillPersonBundle:Person')
->findAll();
foreach($persons as $person) {
$activityNbr = rand(0,3);
for($i = 0; $i < $activityNbr; $i ++) {
print "Creating an activity type for : ".$person."\n";
$activity = $this->newRandomActivity($person);
$manager->persist($activity);
}
}
$manager->flush();
}
}

View File

@ -1,81 +1,66 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\DataFixtures\ORM;
use Chill\ActivityBundle\Entity\ActivityReason;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
use Chill\ActivityBundle\Entity\ActivityReason;
/**
* Description of LoadActivityReason
*
* @author Champs-Libres Coop
* Description of LoadActivityReason.
*/
class LoadActivityReason extends AbstractFixture implements OrderedFixtureInterface
{
public static $references = [];
public function getOrder()
{
return 16300;
}
public static $references = array();
public function load(ObjectManager $manager)
{
$reasons = [
[
'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'],
'category' => 'cat_Housing'],
'category' => 'cat_Housing', ],
[
'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'],
'category' => 'cat_Unemployment procedure'],
'category' => 'cat_Unemployment procedure', ],
[
'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'],
'category' => 'cat_Unemployment procedure']
'category' => 'cat_Unemployment procedure', ],
];
foreach ($reasons as $r) {
print "Creating activity reason : " . $r['name']['en'] . "\n";
echo 'Creating activity reason : ' . $r['name']['en'] . "\n";
$activityReason = (new ActivityReason())
->setName(($r['name']))
->setActive(true)
->setCategory($this->getReference($r['category']));
$manager->persist($activityReason);
$reference = 'activity_reason_'.$r['name']['en'];
$reference = 'activity_reason_' . $r['name']['en'];
$this->addReference($reference, $activityReason);
static::$references[] = $reference;
}
$manager->flush();
}
}

View File

@ -1,35 +1,21 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\DataFixtures\ORM;
use Chill\ActivityBundle\Entity\ActivityReasonCategory;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
use Chill\ActivityBundle\Entity\ActivityReasonCategory;
/**
* Description of LoadActivityReasonCategory
*
* @author Champs-Libres Coop
* Description of LoadActivityReasonCategory.
*/
class LoadActivityReasonCategory extends AbstractFixture implements OrderedFixtureInterface
{
@ -37,27 +23,26 @@ class LoadActivityReasonCategory extends AbstractFixture implements OrderedFixtu
{
return 16200;
}
public function load(ObjectManager $manager)
{
$categs = [
['name' =>
['fr' => 'Logement', 'en' => 'Housing', 'nl' => 'Woning']],
['name' =>
['fr' => 'Démarches chômage', 'en' => 'Unemployment procedure', 'nl' => 'Werkloosheid werkwijze']],
['name' => ['fr' => 'Logement', 'en' => 'Housing', 'nl' => 'Woning']],
['name' => ['fr' => 'Démarches chômage', 'en' => 'Unemployment procedure', 'nl' => 'Werkloosheid werkwijze']],
];
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())
->setName(($c['name']))
->setActive(true);
$manager->persist($activityReasonCategory);
$this->addReference(
'cat_'.$c['name']['en'],
$activityReasonCategory);
'cat_' . $c['name']['en'],
$activityReasonCategory
);
}
$manager->flush();
}
}

View File

@ -1,67 +1,49 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\DataFixtures\ORM;
use Chill\ActivityBundle\Entity\ActivityType;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
use Chill\ActivityBundle\Entity\ActivityType;
/**
* Description of LoadActivityType
*
* @author Champs-Libres Coop
* Description of LoadActivityType.
*/
class LoadActivityType extends AbstractFixture implements OrderedFixtureInterface
{
public static $references = [];
public function getOrder()
{
return 16100;
}
public static $references = array();
public function load(ObjectManager $manager)
{
$types = [
[ 'name' =>
['fr' => 'Appel téléphonique', 'en' => 'Telephone call', 'nl' => 'Telefoon appel']],
[ 'name' =>
['fr' => 'Entretien', 'en' => 'Interview', 'nl' => 'Vraaggesprek']],
[ 'name' =>
['fr' => 'Inspection', 'en' => 'Inspection', 'nl' => 'Inspectie']]
['name' => ['fr' => 'Appel téléphonique', 'en' => 'Telephone call', 'nl' => 'Telefoon appel']],
['name' => ['fr' => 'Entretien', 'en' => 'Interview', 'nl' => 'Vraaggesprek']],
['name' => ['fr' => 'Inspection', 'en' => 'Inspection', 'nl' => 'Inspectie']],
];
foreach ($types as $t) {
print "Creating activity type : " . $t['name']['en'] . "\n";
echo 'Creating activity type : ' . $t['name']['en'] . "\n";
$activityType = (new ActivityType())
->setName(($t['name']));
$manager->persist($activityType);
$reference = 'activity_type_'.$t['name']['en'];
$reference = 'activity_type_' . $t['name']['en'];
$this->addReference($reference, $activityType);
static::$references[] = $reference;
}
$manager->flush();
}
}

View File

@ -1,37 +1,25 @@
<?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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\DataFixtures\ORM;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
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\OrderedFixtureInterface;
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,
* and a role CHILL_ACTIVITY_SEE for administrative
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* and a role CHILL_ACTIVITY_SEE for administrative.
*/
class LoadActivitytACL extends AbstractFixture implements OrderedFixtureInterface
{
@ -40,12 +28,12 @@ class LoadActivitytACL extends AbstractFixture implements OrderedFixtureInterfac
return 16000;
}
public function load(ObjectManager $manager)
{
foreach (LoadPermissionsGroup::$refs as $permissionsGroupRef) {
$permissionsGroup = $this->getReference($permissionsGroupRef);
foreach (LoadScopes::$references as $scopeRef){
foreach (LoadScopes::$references as $scopeRef) {
$scope = $this->getReference($scopeRef);
//create permission group
switch ($permissionsGroup->getName()) {
@ -53,47 +41,49 @@ class LoadActivitytACL extends AbstractFixture implements OrderedFixtureInterfac
if ($scope->getName()['en'] === 'administrative') {
break 2; // we do not want any power on administrative
}
break;
case 'administrative':
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;
}
printf("Adding CHILL_ACTIVITY_UPDATE & CHILL_ACTIVITY_CREATE & CHILL_ACTIVITY_DELETE, and stats and list permissions to %s "
. "permission group, scope '%s' \n",
$permissionsGroup->getName(), $scope->getName()['en']);
printf(
'Adding CHILL_ACTIVITY_UPDATE & CHILL_ACTIVITY_CREATE & CHILL_ACTIVITY_DELETE, and stats and list permissions to %s '
. "permission group, scope '%s' \n",
$permissionsGroup->getName(),
$scope->getName()['en']
);
$roleScopeUpdate = (new RoleScope())
->setRole('CHILL_ACTIVITY_UPDATE')
->setScope($scope);
->setRole('CHILL_ACTIVITY_UPDATE')
->setScope($scope);
$permissionsGroup->addRoleScope($roleScopeUpdate);
$roleScopeCreate = (new RoleScope())
->setRole('CHILL_ACTIVITY_CREATE')
->setScope($scope);
->setRole('CHILL_ACTIVITY_CREATE')
->setScope($scope);
$permissionsGroup->addRoleScope($roleScopeCreate);
$roleScopeDelete = (new RoleScope())
->setRole('CHILL_ACTIVITY_DELETE')
->setScope($scope);
->setRole('CHILL_ACTIVITY_DELETE')
->setScope($scope);
$permissionsGroup->addRoleScope($roleScopeDelete);
$roleScopeList = (new RoleScope())
->setRole(ActivityStatsVoter::LISTS)
;
->setRole(ActivityStatsVoter::LISTS);
$permissionsGroup->addRoleScope($roleScopeList);
$roleScopeStat = (new RoleScope())
->setRole(ActivityStatsVoter::STATS)
;
->setRole(ActivityStatsVoter::STATS);
$permissionsGroup->addRoleScope($roleScopeStat);
$manager->persist($roleScopeUpdate);
$manager->persist($roleScopeCreate);
$manager->persist($roleScopeDelete);
}
}
$manager->flush();
}
}

View File

@ -1,53 +1,36 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
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 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}
*/
class ChillActivityExtension extends Extension implements PrependExtensionInterface
{
/**
* {@inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$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/export.yaml');
$loader->load('services/repositories.yaml');
@ -57,37 +40,37 @@ class ChillActivityExtension extends Extension implements PrependExtensionInterf
$loader->load('services/form.yaml');
$loader->load('services/templating.yaml');
}
public function prepend(ContainerBuilder $container)
{
$this->prependRoutes($container);
$this->prependAuthorization($container);
}
public function prependAuthorization(ContainerBuilder $container)
{
$container->prependExtensionConfig('security', [
'role_hierarchy' => [
ActivityVoter::UPDATE => [ActivityVoter::SEE_DETAILS],
ActivityVoter::CREATE => [ActivityVoter::SEE_DETAILS],
ActivityVoter::DELETE => [ActivityVoter::SEE_DETAILS],
ActivityVoter::SEE_DETAILS => [ActivityVoter::SEE],
],
]);
}
/* (non-PHPdoc)
* @see \Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface::prepend()
*/
public function prependRoutes(ContainerBuilder $container)
public function prependRoutes(ContainerBuilder $container)
{
//add routes for custom bundle
$container->prependExtensionConfig('chill_main', array(
'routing' => array(
'resources' => array(
'@ChillActivityBundle/config/routes.yaml'
)
)
));
}
public function prependAuthorization(ContainerBuilder $container)
{
$container->prependExtensionConfig('security', array(
'role_hierarchy' => array(
ActivityVoter::UPDATE => array(ActivityVoter::SEE_DETAILS),
ActivityVoter::CREATE => array(ActivityVoter::SEE_DETAILS),
ActivityVoter::DELETE => array(ActivityVoter::SEE_DETAILS),
ActivityVoter::SEE_DETAILS => array(ActivityVoter::SEE)
)
));
$container->prependExtensionConfig('chill_main', [
'routing' => [
'resources' => [
'@ChillActivityBundle/config/routes.yaml',
],
],
]);
}
}

View File

@ -1,71 +1,73 @@
<?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;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
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}
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritdoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder('chill_activity');
$rootNode = $treeBuilder->getRootNode('chill_activity');
$rootNode
->children()
->arrayNode('form')
->canBeEnabled()
->children()
->arrayNode('time_duration')
->isRequired()
->requiresAtLeastOneElement()
->defaultValue(
array(
[ 'label' => '5 minutes', 'seconds' => 300],
[ 'label' => '10 minutes', 'seconds' => 600],
[ 'label' => '15 minutes', 'seconds' => 900],
[ 'label' => '20 minutes', 'seconds' => 1200],
[ 'label' => '25 minutes', 'seconds' => 1500],
[ 'label' => '30 minutes', 'seconds' => 1800],
[ 'label' => '45 minutes', 'seconds' => 2700],
[ 'label' => '1 hour', 'seconds' => 3600],
[ 'label' => '1 hour 15', 'seconds' => 4500],
[ 'label' => '1 hour 30', 'seconds' => 5400],
[ 'label' => '1 hour 45', 'seconds' => 6300],
[ 'label' => '2 hours', 'seconds' => 7200],
)
)
->info('The intervals of time to show in activity form')
->prototype('array')
->children()
->scalarNode('seconds')
->info("The number of seconds of this duration. Must be an integer.")
->cannotBeEmpty()
->validate()
->ifTrue(function($data) {
return !is_int($data);
})->thenInvalid("The value %s is not a valid integer")
->end()
->end()
->scalarNode('label')
->cannotBeEmpty()
->info("The label to show into fields")
->end()
->end()
->end()
->children()
->arrayNode('form')
->canBeEnabled()
->children()
->arrayNode('time_duration')
->isRequired()
->requiresAtLeastOneElement()
->defaultValue(
[
['label' => '5 minutes', 'seconds' => 300],
['label' => '10 minutes', 'seconds' => 600],
['label' => '15 minutes', 'seconds' => 900],
['label' => '20 minutes', 'seconds' => 1200],
['label' => '25 minutes', 'seconds' => 1500],
['label' => '30 minutes', 'seconds' => 1800],
['label' => '45 minutes', 'seconds' => 2700],
['label' => '1 hour', 'seconds' => 3600],
['label' => '1 hour 15', 'seconds' => 4500],
['label' => '1 hour 30', 'seconds' => 5400],
['label' => '1 hour 45', 'seconds' => 6300],
['label' => '2 hours', 'seconds' => 7200],
]
)
->info('The intervals of time to show in activity form')
->prototype('array')
->children()
->scalarNode('seconds')
->info('The number of seconds of this duration. Must be an integer.')
->cannotBeEmpty()
->validate()
->ifTrue(function ($data) {
return !is_int($data);
})->thenInvalid('The value %s is not a valid integer')
->end()
->end()
->scalarNode('label')
->cannotBeEmpty()
->info('The label to show into fields')
->end()
->end()
->end()
// ->validate()
//
//
// ->ifTrue(function ($data) {
// // test this is an array
// 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")
// ->end()
->end()
->end()
->end()
->end();
->end()
->end()
->end()
->end();
return $treeBuilder;
}

View File

@ -1,55 +1,65 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2015, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Entity;
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
use Doctrine\ORM\Mapping as ORM;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\Center;
use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\ActivityBundle\Entity\ActivityType;
use Chill\PersonBundle\Entity\Person;
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
use Chill\MainBundle\Entity\HasCenterInterface;
use Chill\MainBundle\Entity\HasScopeInterface;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Validator\Constraints\Entity\UserCircleConsistency;
use Chill\PersonBundle\Entity\Person;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* Class Activity
* Class Activity.
*
* @package Chill\ActivityBundle\Entity
* @ORM\Entity()
* @ORM\Entity
* @ORM\Table(name="activity")
* @ORM\HasLifecycleCallbacks()
* @ORM\HasLifecycleCallbacks
* @UserCircleConsistency(
* "CHILL_ACTIVITY_SEE_DETAILS",
* getUserFunction="getUser",
* path="scope")
* "CHILL_ACTIVITY_SEE_DETAILS",
* getUserFunction="getUser",
* path="scope")
*/
class Activity implements HasCenterInterface, HasScopeInterface
{
/**
* @var integer
* @var bool
* @ORM\Column(type="boolean")
*/
private $attendee;
/**
* @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\CommentEmbeddable", columnPrefix="comment_")
*/
private $comment;
/**
* @var DateTime
* @ORM\Column(type="datetime")
*/
private $date;
/**
* @var DateTime
* @ORM\Column(type="time")
*/
private $durationTime;
/**
* @var int
*
* @ORM\Id
* @ORM\Column(name="id", type="integer")
@ -58,28 +68,10 @@ class Activity implements HasCenterInterface, HasScopeInterface
private $id;
/**
* @var User
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User")
* @var Person
* @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\Person")
*/
private $user;
/**
* @var \DateTime
* @ORM\Column(type="datetime")
*/
private $date;
/**
* @var \DateTime
* @ORM\Column(type="time")
*/
private $durationTime;
/**
* @var boolean
* @ORM\Column(type="boolean")
*/
private $attendee;
private $person;
/**
* @var ActivityReason
@ -87,12 +79,6 @@ class Activity implements HasCenterInterface, HasScopeInterface
*/
private $reasons;
/**
* @var ActivityType
* @ORM\ManyToOne(targetEntity="Chill\ActivityBundle\Entity\ActivityType")
*/
private $type;
/**
* @var Scope
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\Scope")
@ -100,15 +86,16 @@ class Activity implements HasCenterInterface, HasScopeInterface
private $scope;
/**
* @var Person
* @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\Person")
* @var ActivityType
* @ORM\ManyToOne(targetEntity="Chill\ActivityBundle\Entity\ActivityType")
*/
private $person;
private $type;
/**
* @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\CommentEmbeddable", columnPrefix="comment_")
* @var User
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User")
*/
private $comment;
private $user;
/**
* Activity constructor.
@ -120,111 +107,8 @@ class Activity implements HasCenterInterface, HasScopeInterface
}
/**
* Get id
* Add a reason.
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set user
*
* @param User $user
* @return Activity
*/
public function setUser(User $user)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* @return User
*/
public function getUser()
{
return $this->user;
}
/**
* Set date
*
* @param \DateTime $date
* @return Activity
*/
public function setDate($date)
{
$this->date = $date;
return $this;
}
/**
* Get date
*
* @return \DateTime
*/
public function getDate()
{
return $this->date;
}
/**
* Set durationTime
*
* @param \DateTime $durationTime
* @return Activity
*/
public function setDurationTime($durationTime)
{
$this->durationTime = $durationTime;
return $this;
}
/**
* Get durationTime
*
* @return \DateTime
*/
public function getDurationTime()
{
return $this->durationTime;
}
/**
* Set attendee
*
* @param boolean $attendee
* @return Activity
*/
public function setAttendee($attendee)
{
$this->attendee = $attendee;
return $this;
}
/**
* Get attendee
*
* @return boolean
*/
public function getAttendee()
{
return $this->attendee;
}
/**
* Add a reason
*
* @param ActivityReason $reason
* @return Activity
*/
public function addReason(ActivityReason $reason)
@ -235,95 +119,18 @@ class Activity implements HasCenterInterface, HasScopeInterface
}
/**
* @param ActivityReason $reason
*/
public function removeReason(ActivityReason $reason)
{
$this->reasons->removeElement($reason);
}
/**
* Get reasons
* Get attendee.
*
* @return Collection
* @return bool
*/
public function getReasons()
public function getAttendee()
{
return $this->reasons;
}
/**
* Set type
*
* @param ActivityType $type
* @return Activity
*/
public function setType(ActivityType $type)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* @return ActivityType
*/
public function getType()
{
return $this->type;
}
/**
* Set scope
*
* @param Scope $scope
* @return Activity
*/
public function setScope(Scope $scope)
{
$this->scope = $scope;
return $this;
}
/**
* Get scope
*
* @return Scope
*/
public function getScope()
{
return $this->scope;
}
/**
* Set person
*
* @param Person $person
* @return Activity
*/
public function setPerson(Person $person)
{
$this->person = $person;
return $this;
}
/**
* Get person
*
* @return Person
*/
public function getPerson()
{
return $this->person;
return $this->attendee;
}
/**
* get the center
* center is extracted from person
* center is extracted from person.
*
* @return Center
*/
@ -340,6 +147,105 @@ class Activity implements HasCenterInterface, HasScopeInterface
return $this->comment;
}
/**
* Get date.
*
* @return DateTime
*/
public function getDate()
{
return $this->date;
}
/**
* Get durationTime.
*
* @return DateTime
*/
public function getDurationTime()
{
return $this->durationTime;
}
/**
* Get id.
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Get person.
*
* @return Person
*/
public function getPerson()
{
return $this->person;
}
/**
* Get reasons.
*
* @return Collection
*/
public function getReasons()
{
return $this->reasons;
}
/**
* Get scope.
*
* @return Scope
*/
public function getScope()
{
return $this->scope;
}
/**
* Get type.
*
* @return ActivityType
*/
public function getType()
{
return $this->type;
}
/**
* Get user.
*
* @return User
*/
public function getUser()
{
return $this->user;
}
public function removeReason(ActivityReason $reason)
{
$this->reasons->removeElement($reason);
}
/**
* Set attendee.
*
* @param bool $attendee
*
* @return Activity
*/
public function setAttendee($attendee)
{
$this->attendee = $attendee;
return $this;
}
/**
* @param \Chill\MainBundle\Entity\Embeddalbe\CommentEmbeddable $comment
*/
@ -347,5 +253,80 @@ class Activity implements HasCenterInterface, HasScopeInterface
{
$this->comment = $comment;
}
}
/**
* Set date.
*
* @param DateTime $date
*
* @return Activity
*/
public function setDate($date)
{
$this->date = $date;
return $this;
}
/**
* Set durationTime.
*
* @param DateTime $durationTime
*
* @return Activity
*/
public function setDurationTime($durationTime)
{
$this->durationTime = $durationTime;
return $this;
}
/**
* Set person.
*
* @return Activity
*/
public function setPerson(Person $person)
{
$this->person = $person;
return $this;
}
/**
* Set scope.
*
* @return Activity
*/
public function setScope(Scope $scope)
{
$this->scope = $scope;
return $this;
}
/**
* Set type.
*
* @return Activity
*/
public function setType(ActivityType $type)
{
$this->type = $type;
return $this;
}
/**
* Set user.
*
* @return Activity
*/
public function setUser(User $user)
{
$this->user = $user;
return $this;
}
}

View File

@ -1,40 +1,41 @@
<?php
/*
*
* Copyright (C) 2015, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
/**
* 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;
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\HasLifecycleCallbacks()
* @ORM\HasLifecycleCallbacks
*/
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\Column(name="id", type="integer")
@ -49,86 +50,17 @@ class ActivityReason
private $name;
/**
* @var ActivityReasonCategory
* @ORM\ManyToOne(
* targetEntity="Chill\ActivityBundle\Entity\ActivityReasonCategory",
* inversedBy="reasons")
*/
private $category;
/**
* @var boolean
* @ORM\Column(type="boolean")
*/
private $active = true;
/**
* Get id
* Get active.
*
* @return integer
* @return bool
*/
public function getId()
public function getActive()
{
return $this->id;
return $this->active;
}
/**
* Set name
*
* @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
* Get category.
*
* @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
*/
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
/*
* Copyright (C) 2015, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
/**
* 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;
use Doctrine\ORM\Mapping as ORM;
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\HasLifecycleCallbacks()
* @ORM\HasLifecycleCallbacks
*/
class ActivityReasonCategory
{
/**
* @var integer
* @var bool
* @ORM\Column(type="boolean")
*/
private $active = true;
/**
* @var int
*
* @ORM\Id
* @ORM\Column(name="id", type="integer")
@ -48,20 +43,15 @@ class ActivityReasonCategory
private $name;
/**
* @var boolean
* @ORM\Column(type="boolean")
*/
private $active = true;
/**
* Array of ActivityReason
* Array of ActivityReason.
*
* @var ArrayCollection
* @ORM\OneToMany(
* targetEntity="Chill\ActivityBundle\Entity\ActivityReason",
* mappedBy="category")
* mappedBy="category")
*/
private $reasons;
/**
* ActivityReasonCategory constructor.
*/
@ -69,19 +59,29 @@ class ActivityReasonCategory
{
$this->reasons = new ArrayCollection();
}
/**
* @return string
*/
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()
{
@ -89,20 +89,9 @@ class ActivityReasonCategory
}
/**
* Set name
* Get name.
*
* @param array $name
* @return ActivityReasonCategory
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
* @param mixed|null $locale
*
* @return array
*/
@ -111,48 +100,53 @@ class ActivityReasonCategory
if ($locale) {
if (isset($this->name[$locale])) {
return $this->name[$locale];
} else {
foreach ($this->name as $name) {
if (!empty($name)) {
return $name;
}
}
foreach ($this->name as $name) {
if (!empty($name)) {
return $name;
}
}
return '';
} else {
return $this->name;
}
return $this->name;
}
/**
* Declare a category as active (or not). When a category is set
* 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
*/
public function setActive($active)
{
if($this->active !== $active && !$active) {
if ($this->active !== $active && !$active) {
foreach ($this->reasons as $reason) {
$reason->setActive($active);
}
}
$this->active = $active;
return $this;
}
/**
* 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;
}
}

View File

@ -1,21 +1,10 @@
<?php
/*
*
* Copyright (C) 2015, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
/**
* 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;
@ -23,17 +12,22 @@ namespace Chill\ActivityBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Class ActivityType
* Class ActivityType.
*
* @package Chill\ActivityBundle\Entity
* @ORM\Entity()
* @ORM\Entity
* @ORM\Table(name="activitytype")
* @ORM\HasLifecycleCallbacks()
* @ORM\HasLifecycleCallbacks
*/
class ActivityType
{
/**
* @var integer
* @var bool
* @ORM\Column(type="boolean")
*/
private $active = true;
/**
* @var int
*
* @ORM\Id
* @ORM\Column(name="id", type="integer")
@ -46,18 +40,22 @@ class ActivityType
* @ORM\Column(type="json_array")
*/
private $name;
/**
* @var bool
* @ORM\Column(type="boolean")
*/
private $active = true;
/**
* Get id
* Get active
* return true if the type is active.
*
* @return integer
* @return bool
*/
public function getActive()
{
return $this->active;
}
/**
* Get id.
*
* @return int
*/
public function getId()
{
@ -65,20 +63,9 @@ class ActivityType
}
/**
* Set name
* Get name.
*
* @param array $name
* @return ActivityType
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
* @param mixed|null $locale
*
* @return array | string
*/
@ -87,50 +74,57 @@ class ActivityType
if ($locale) {
if (isset($this->name[$locale])) {
return $this->name[$locale];
} else {
foreach ($this->name as $name) {
if (!empty($name)) {
return $name;
}
}
foreach ($this->name as $name) {
if (!empty($name)) {
return $name;
}
}
return '';
} else {
return $this->name;
}
return $this->name;
}
/**
* Get active
* return true if the type is active.
*
* @return boolean
*/
public function getActive() {
return $this->active;
}
/**
* Is active
* return true if the type is active
*
* @return boolean
* return true if the type is active.
*
* @return bool
*/
public function isActive() {
public function isActive()
{
return $this->getActive();
}
/**
* Set active
* set to true if the type is active
*
* @param boolean $active
* set to true if the type is active.
*
* @param bool $active
*
* @return ActivityType
*/
public function setActive($active) {
public function setActive($active)
{
$this->active = $active;
return $this;
}
}
/**
* Set name.
*
* @param array $name
*
* @return ActivityType
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
}

View File

@ -1,107 +1,96 @@
<?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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Aggregator;
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 Doctrine\ORM\EntityRepository;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\Query\Expr\Join;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use RuntimeException;
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;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ActivityReasonAggregator implements AggregatorInterface,
class ActivityReasonAggregator implements
AggregatorInterface,
ExportElementValidatedInterface
{
/**
*
* @var EntityRepository
*/
protected $categoryRepository;
/**
*
* @var EntityRepository
*/
protected $reasonRepository;
/**
*
* @var TranslatableStringHelper
*/
protected $stringHelper;
public function __construct(
EntityRepository $categoryRepository,
EntityRepository $reasonRepository,
TranslatableStringHelper $stringHelper
EntityRepository $categoryRepository,
EntityRepository $reasonRepository,
TranslatableStringHelper $stringHelper
) {
$this->categoryRepository = $categoryRepository;
$this->reasonRepository = $reasonRepository;
$this->stringHelper = $stringHelper;
$this->reasonRepository = $reasonRepository;
$this->stringHelper = $stringHelper;
}
public function addRole()
{
return new Role(ActivityStatsVoter::STATS);
}
public function alterQuery(QueryBuilder $qb, $data)
{
// add select element
if ($data['level'] === 'reasons') {
if ('reasons' === $data['level']) {
$elem = 'reasons.id';
$alias = 'activity_reasons_id';
} elseif ($data['level'] === 'categories') {
} elseif ('categories' === $data['level']) {
$elem = 'category.id';
$alias = 'activity_categories_id';
} 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
$join = $qb->getDQLPart('join');
if (
(array_key_exists('activity', $join)
&&
!$this->checkJoinAlreadyDefined($join['activity'], 'reasons')
(
array_key_exists('activity', $join)
&& !$this->checkJoinAlreadyDefined($join['activity'], 'reasons')
)
OR
(! array_key_exists('activity', $join))
or (!array_key_exists('activity', $join))
) {
$qb->add(
'join',
array('activity' =>
new Join(Join::INNER_JOIN, 'activity.reasons', 'reasons')
),
true);
'join',
['activity' => new Join(Join::INNER_JOIN, 'activity.reasons', 'reasons'),
],
true
);
}
// join category if necessary
if ($alias === 'activity_categories_id') {
if ('activity_categories_id' === $alias) {
// add join only if needed
if (!$this->checkJoinAlreadyDefined($qb->getDQLPart('join')['activity'], 'category')) {
$qb->join('reasons.category', 'category');
@ -118,12 +107,109 @@ class ActivityReasonAggregator implements AggregatorInterface,
}
}
public function applyOn()
{
return 'activity';
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('level', ChoiceType::class, [
'choices' => [
'By reason' => 'reasons',
'By category of reason' => 'categories',
],
'multiple' => false,
'expanded' => true,
'label' => 'Reason\'s level',
]);
}
public function getLabels($key, array $values, $data)
{
// for performance reason, we load data from db only once
switch ($data['level']) {
case 'reasons':
$this->reasonRepository->findBy(['id' => $values]);
break;
case 'categories':
$this->categoryRepository->findBy(['id' => $values]);
break;
default:
throw new RuntimeException(sprintf(
"the level data '%s' is invalid",
$data['level']
));
}
return function ($value) use ($data) {
if ('_header' === $value) {
return 'reasons' === $data['level'] ?
'Group by reasons'
:
'Group by categories of reason';
}
switch ($data['level']) {
case 'reasons':
/* @var $r \Chill\ActivityBundle\Entity\ActivityReason */
$r = $this->reasonRepository->find($value);
return $this->stringHelper->localize($r->getCategory()->getName())
. ' > '
. $this->stringHelper->localize($r->getName());
break;
case 'categories':
$c = $this->categoryRepository->find($value);
return $this->stringHelper->localize($c->getName());
break;
// no need for a default : the default was already set above
}
};
}
public function getQueryKeys($data)
{
// add select element
if ('reasons' === $data['level']) {
return ['activity_reasons_id'];
}
if ('categories' === $data['level']) {
return ['activity_categories_id'];
}
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
* Check if a join between Activity and another alias.
*
* @param Join[] $joins
* @param string $alias the alias to search for
* @return boolean
*
* @return bool
*/
private function checkJoinAlreadyDefined(array $joins, $alias)
{
@ -135,99 +221,4 @@ class ActivityReasonAggregator implements AggregatorInterface,
return false;
}
public function applyOn()
{
return 'activity';
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('level', ChoiceType::class, array(
'choices' => array(
'By reason' => 'reasons',
'By category of reason' => 'categories'
),
'multiple' => false,
'expanded' => true,
'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)
{
// for performance reason, we load data from db only once
switch ($data['level']) {
case 'reasons':
$this->reasonRepository->findBy(array('id' => $values));
break;
case 'categories':
$this->categoryRepository->findBy(array('id' => $values));
break;
default:
throw new \RuntimeException(sprintf("the level data '%s' is invalid",
$data['level']));
}
return function($value) use ($data) {
if ($value === '_header') {
return $data['level'] === 'reasons' ?
'Group by reasons'
:
'Group by categories of reason'
;
}
switch ($data['level']) {
case 'reasons':
/* @var $r \Chill\ActivityBundle\Entity\ActivityReason */
$r = $this->reasonRepository->find($value);
return $this->stringHelper->localize($r->getCategory()->getName())
." > "
. $this->stringHelper->localize($r->getName());
;
break;
case 'categories':
$c = $this->categoryRepository->find($value);
return $this->stringHelper->localize($c->getName());
break;
// no need for a default : the default was already set above
}
};
}
public function getQueryKeys($data)
{
// add select element
if ($data['level'] === 'reasons') {
return array('activity_reasons_id');
} elseif ($data['level'] === 'categories') {
return array ('activity_categories_id');
} else {
throw new \RuntimeException('the data provided are not recognised');
}
}
}

View File

@ -1,89 +1,58 @@
<?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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Aggregator;
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 Doctrine\ORM\EntityRepository;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ActivityTypeAggregator implements AggregatorInterface
{
public const KEY = 'activity_type_aggregator';
/**
*
* @var EntityRepository
*/
protected $typeRepository;
/**
*
* @var TranslatableStringHelper
*/
protected $stringHelper;
const KEY = 'activity_type_aggregator';
/**
* @var EntityRepository
*/
protected $typeRepository;
public function __construct(
EntityRepository $typeRepository,
TranslatableStringHelper $stringHelper
EntityRepository $typeRepository,
TranslatableStringHelper $stringHelper
) {
$this->typeRepository = $typeRepository;
$this->stringHelper = $stringHelper;
$this->typeRepository = $typeRepository;
$this->stringHelper = $stringHelper;
}
public function addRole()
{
return new Role(ActivityStatsVoter::STATS);
}
public function alterQuery(QueryBuilder $qb, $data)
{
// add select element
// add select element
$qb->addSelect(sprintf('IDENTITY(activity.type) AS %s', self::KEY));
// add the "group by" part
$groupBy = $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()
{
@ -95,23 +64,13 @@ class ActivityTypeAggregator implements AggregatorInterface
// no form required for this aggregator
}
public function getTitle()
{
return "Aggregate by activity type";
}
public function addRole()
{
return new Role(ActivityStatsVoter::STATS);
}
public function getLabels($key, array $values, $data)
{
// for performance reason, we load data from db only once
$this->typeRepository->findBy(array('id' => $values));
return function($value) use ($data) {
if ($value === '_header') {
$this->typeRepository->findBy(['id' => $values]);
return function ($value) {
if ('_header' === $value) {
return 'Activity type';
}
@ -120,12 +79,34 @@ class ActivityTypeAggregator implements AggregatorInterface
return $this->stringHelper->localize($t->getName());
};
}
public function getQueryKeys($data)
{
return array(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,51 +1,37 @@
<?php
/*
* Copyright (C) 2019 Champs Libres Cooperative <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\ActivityBundle\Export\Aggregator;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\QueryBuilder;
use Chill\MainBundle\Export\AggregatorInterface;
use Symfony\Component\Security\Core\Role\Role;
use Doctrine\ORM\Query\Expr\Join;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Doctrine\ORM\EntityManagerInterface;
use Chill\MainBundle\Entity\User;
/**
*
* Chill is a software for social workers
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Aggregator;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Export\AggregatorInterface;
use Closure;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
class ActivityUserAggregator implements AggregatorInterface
{
public const KEY = 'activity_user_id';
/**
*
* @var EntityManagerInterface
*/
protected $em;
const KEY = 'activity_user_id';
function __construct(EntityManagerInterface $em)
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
public function addRole()
{
return new Role(ActivityStatsVoter::STATS);
@ -53,9 +39,9 @@ class ActivityUserAggregator implements AggregatorInterface
public function alterQuery(QueryBuilder $qb, $data)
{
// add select element
// add select element
$qb->addSelect(sprintf('IDENTITY(activity.user) AS %s', self::KEY));
// add the "group by" part
$qb->addGroupBy(self::KEY);
}
@ -70,16 +56,17 @@ class ActivityUserAggregator implements AggregatorInterface
// nothing to add
}
public function getLabels($key, $values, $data): \Closure
public function getLabels($key, $values, $data): Closure
{
// preload users at once
$this->em->getRepository(User::class)
->findBy(['id' => $values]);
return function($value) {
return function ($value) {
switch ($value) {
case '_header':
return 'activity user';
default:
return $this->em->getRepository(User::class)->find($value)
->getUsername();
@ -89,11 +76,11 @@ class ActivityUserAggregator implements AggregatorInterface
public function getQueryKeys($data)
{
return [ self::KEY ];
return [self::KEY];
}
public function getTitle(): string
{
return "Aggregate by activity user";
return 'Aggregate by activity user';
}
}

View File

@ -1,121 +1,65 @@
<?php
/*
* Copyright (C) 2015 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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Export;
use Chill\MainBundle\Export\ExportInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Security\Core\Role\Role;
use Doctrine\ORM\Query;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\ExportInterface;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query;
use LogicException;
use Symfony\Component\Security\Core\Role\Role;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class CountActivity implements ExportInterface
{
/**
*
* @var EntityManagerInterface
*/
protected $entityManager;
public function __construct(
EntityManagerInterface $em
)
{
EntityManagerInterface $em
) {
$this->entityManager = $em;
}
public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder)
{
}
public function getDescription()
{
return "Count activities by various parameters.";
}
public function getTitle()
{
return "Count activities";
}
public function getType()
{
return 'activity';
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = array())
{
$qb = $this->entityManager->createQueryBuilder();
$centers = array_map(function($el) { return $el['center']; }, $acl);
$qb->select('COUNT(activity.id) as export_count_activity')
->from('ChillActivityBundle:Activity', 'activity')
->join('activity.person', 'person')
;
$qb->where($qb->expr()->in('person.center', ':centers'))
->setParameter('centers', $centers)
;
return $qb;
}
public function supportsModifiers()
{
return array('person', 'activity');
}
public function requiredRole()
{
return new Role(ActivityStatsVoter::STATS);
}
public function getAllowedFormattersTypes()
{
return array(\Chill\MainBundle\Export\FormatterInterface::TYPE_TABULAR);
return [\Chill\MainBundle\Export\FormatterInterface::TYPE_TABULAR];
}
public function getDescription()
{
return 'Count activities by various parameters.';
}
public function getLabels($key, array $values, $data)
{
if ($key !== 'export_count_activity') {
throw new \LogicException("the key $key is not used by this export");
if ('export_count_activity' !== $key) {
throw new LogicException("the key {$key} is not used by this export");
}
return function($value) {
return $value === '_header' ?
return function ($value) {
return '_header' === $value ?
'Number of activities'
:
$value
;
$value;
};
}
public function getQueryKeys($data)
{
return array('export_count_activity');
return ['export_count_activity'];
}
public function getResult($qb, $data)
@ -123,4 +67,40 @@ class CountActivity implements ExportInterface
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
public function getTitle()
{
return 'Count activities';
}
public function getType()
{
return 'activity';
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{
$qb = $this->entityManager->createQueryBuilder();
$centers = array_map(function ($el) {
return $el['center'];
}, $acl);
$qb->select('COUNT(activity.id) as export_count_activity')
->from('ChillActivityBundle:Activity', 'activity')
->join('activity.person', 'person');
$qb->where($qb->expr()->in('person.center', ':centers'))
->setParameter('centers', $centers);
return $qb;
}
public function requiredRole()
{
return new Role(ActivityStatsVoter::STATS);
}
public function supportsModifiers()
{
return ['person', 'activity'];
}
}

View File

@ -1,69 +1,42 @@
<?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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Export;
use Chill\MainBundle\Export\ListInterface;
use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\Scope;
use Chill\ActivityBundle\Entity\ActivityType;
use Doctrine\ORM\Query\Expr;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Component\Security\Core\Role\Role;
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\TranslatableStringHelper;
use DateTime;
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\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 function array_key_exists;
/**
* Create a list for all activities
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* Create a list for all activities.
*/
class ListActivity implements ListInterface
{
/**
*
* @var EntityManagerInterface
*/
protected $entityManager;
/**
*
* @var TranslatorInterface
*/
protected $translator;
/**
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
protected $fields = array(
protected $fields = [
'id',
'date',
'durationTime',
@ -74,115 +47,131 @@ class ListActivity implements ListInterface
'type_name',
'person_firstname',
'person_lastname',
'person_id'
);
'person_id',
];
/**
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
/**
* @var TranslatorInterface
*/
protected $translator;
public function __construct(
EntityManagerInterface $em,
TranslatorInterface $translator,
TranslatableStringHelper $translatableStringHelper
)
{
EntityManagerInterface $em,
TranslatorInterface $translator,
TranslatableStringHelper $translatableStringHelper
) {
$this->entityManager = $em;
$this->translator = $translator;
$this->translatableStringHelper = $translatableStringHelper;
}
/**
* {@inheritDoc}
*
* @param FormBuilderInterface $builder
*/
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('fields', ChoiceType::class, array(
$builder->add('fields', ChoiceType::class, [
'multiple' => true,
'expanded' => true,
'choices' => array_combine($this->fields, $this->fields),
'label' => 'Fields to include in export',
'constraints' => [new Callback(array(
'callback' => function($selected, ExecutionContextInterface $context) {
'label' => 'Fields to include in export',
'constraints' => [new Callback([
'callback' => function ($selected, ExecutionContextInterface $context) {
if (count($selected) === 0) {
$context->buildViolation('You must select at least one element')
->atPath('fields')
->addViolation();
}
}
))]
));
},
])],
]);
}
/**
* {@inheritDoc}
*
* @return type
*/
public function getAllowedFormattersTypes()
{
return array(FormatterInterface::TYPE_LIST);
return [FormatterInterface::TYPE_LIST];
}
public function getDescription()
{
return "List activities";
return 'List activities';
}
public function getLabels($key, array $values, $data)
{
switch ($key)
{
case 'date' :
return function($value) {
if ($value === '_header') return 'date';
switch ($key) {
case 'date':
return function ($value) {
if ('_header' === $value) {
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');
};
case 'attendee':
return function($value) {
if ($value === '_header') return 'attendee';
return function ($value) {
if ('_header' === $value) {
return 'attendee';
}
return $value ? 1 : 0;
};
case 'list_reasons' :
case 'list_reasons':
/* @var $activityReasonsRepository EntityRepository */
$activityRepository = $this->entityManager
->getRepository('ChillActivityBundle:Activity');
return function($value) use ($activityRepository) {
if ($value === '_header') return 'activity reasons';
return function ($value) use ($activityRepository) {
if ('_header' === $value) {
return 'activity reasons';
}
$activity = $activityRepository
->find($value);
->find($value);
return implode(", ", array_map(function(ActivityReason $r) {
return '"'.
return implode(', ', array_map(function (ActivityReason $r) {
return '"' .
$this->translatableStringHelper->localize($r->getCategory()->getName())
.' > '.
. ' > ' .
$this->translatableStringHelper->localize($r->getName())
.'"';
. '"';
}, $activity->getReasons()->toArray()));
};
case 'circle_name' :
return function($value) {
if ($value === '_header') return 'circle';
case 'circle_name':
return function ($value) {
if ('_header' === $value) {
return 'circle';
}
return $this->translatableStringHelper
->localize(json_decode($value, true));
->localize(json_decode($value, true));
};
case 'type_name' :
return function($value) {
if ($value === '_header') return 'activity type';
case 'type_name':
return function ($value) {
if ('_header' === $value) {
return 'activity type';
}
return $this->translatableStringHelper
->localize(json_decode($value, true));
->localize(json_decode($value, true));
};
default:
return function($value) use ($key) {
if ($value === '_header') return $key;
return function ($value) use ($key) {
if ('_header' === $value) {
return $key;
}
return $value;
};
@ -209,68 +198,83 @@ class ListActivity implements ListInterface
return 'activity';
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = array())
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
if (!\array_key_exists('fields', $data)) {
throw new \Doctrine\DBAL\Exception\InvalidArgumentException("any fields "
. "have been checked");
if (!array_key_exists('fields', $data)) {
throw new \Doctrine\DBAL\Exception\InvalidArgumentException('any fields '
. 'have been checked');
}
$qb = $this->entityManager->createQueryBuilder();
$qb
->from('ChillActivityBundle:Activity', 'activity')
->join('activity.person', 'person')
->join('person.center', 'center')
->andWhere('center IN (:authorized_centers)')
->setParameter('authorized_centers', $centers);
;
->from('ChillActivityBundle:Activity', 'activity')
->join('activity.person', 'person')
->join('person.center', 'center')
->andWhere('center IN (:authorized_centers)')
->setParameter('authorized_centers', $centers);
foreach ($this->fields as $f) {
if (in_array($f, $data['fields'])) {
switch ($f) {
case 'id':
$qb->addSelect('activity.id AS id');
break;
case 'person_firstname':
$qb->addSelect('person.firstName AS person_firstname');
break;
case 'person_lastname':
$qb->addSelect('person.lastName AS person_lastname');
break;
case 'person_id':
$qb->addSelect('person.id AS person_id');
break;
case 'user_username':
$qb->join('activity.user', 'user');
$qb->addSelect('user.username AS user_username');
break;
case 'circle_name':
$qb->join('activity.scope', 'circle');
$qb->addSelect('circle.name AS circle_name');
break;
case 'type_name':
$qb->join('activity.type', 'type');
$qb->addSelect('type.name AS type_name');
break;
case 'list_reasons':
// this is a trick... The reasons is filled with the
// activity id which will be used to load reasons
$qb->addSelect('activity.id AS list_reasons');
break;
default:
$qb->addSelect(sprintf('activity.%s as %s', $f, $f));
break;
}
}
}
return $qb;
}
@ -281,7 +285,6 @@ class ListActivity implements ListInterface
public function supportsModifiers()
{
return array('activity', 'person');
return ['activity', 'person'];
}
}

View File

@ -1,154 +1,93 @@
<?php
/*
* Copyright (C) 2015 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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Export;
use Chill\MainBundle\Export\ExportInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Security\Core\Role\Role;
use Doctrine\ORM\Query;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\ExportInterface;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query;
use LogicException;
use Symfony\Component\Security\Core\Role\Role;
/**
* This export allow to compute stats on activity duration.
*
*
* The desired stat must be given in constructor.
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class StatActivityDuration implements ExportInterface
{
/**
*
* @var EntityManagerInterface
*/
protected $entityManager;
const SUM = 'sum';
public const SUM = 'sum';
/**
* The action for this report.
*
* @var string
*/
protected $action;
/**
* constructor
*
* @param EntityManagerInterface $em
* @var EntityManagerInterface
*/
protected $entityManager;
/**
* constructor.
*
* @param string $action the stat to perform
*/
public function __construct(
EntityManagerInterface $em,
$action = 'sum'
)
{
EntityManagerInterface $em,
$action = 'sum'
) {
$this->entityManager = $em;
$this->action = $action;
}
public function buildForm(\Symfony\Component\Form\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 = array())
{
$centers = array_map(function($el) { return $el['center']; }, $acl);
$qb = $this->entityManager->createQueryBuilder();
if ($this->action === self::SUM) {
$select = "SUM(activity.durationTime) AS export_stat_activity";
}
$qb->select($select)
->from('ChillActivityBundle:Activity', 'activity')
->join('activity.person', 'person')
->join('person.center', 'center')
->where($qb->expr()->in('center', ':centers'))
->setParameter(':centers', $centers)
;
return $qb;
}
public function supportsModifiers()
{
return array('person', 'activity');
}
public function requiredRole()
{
return new Role(ActivityStatsVoter::STATS);
}
public function getAllowedFormattersTypes()
{
return array(\Chill\MainBundle\Export\FormatterInterface::TYPE_TABULAR);
return [\Chill\MainBundle\Export\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)
{
if ($key !== 'export_stat_activity') {
throw new \LogicException("the key $key is not used by this export");
if ('export_stat_activity' !== $key) {
throw new LogicException("the key {$key} is not used by this export");
}
switch ($this->action) {
case self::SUM:
$header = "Sum of activities duration";
$header = 'Sum of activities duration';
}
return function($value) use ($header) {
return $value === '_header' ?
return function ($value) use ($header) {
return '_header' === $value ?
$header
:
$value
;
$value;
};
}
public function getQueryKeys($data)
{
return array('export_stat_activity');
return ['export_stat_activity'];
}
public function getResult($qb, $data)
@ -156,4 +95,46 @@ class StatActivityDuration implements ExportInterface
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(function ($el) {
return $el['center'];
}, $acl);
$qb = $this->entityManager->createQueryBuilder();
if (self::SUM === $this->action) {
$select = 'SUM(activity.durationTime) AS export_stat_activity';
}
$qb->select($select)
->from('ChillActivityBundle:Activity', 'activity')
->join('activity.person', 'person')
->join('person.center', 'center')
->where($qb->expr()->in('center', ':centers'))
->setParameter(':centers', $centers);
return $qb;
}
public function requiredRole()
{
return new Role(ActivityStatsVoter::STATS);
}
public function supportsModifiers()
{
return ['person', 'activity'];
}
}

View File

@ -1,52 +1,36 @@
<?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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Filter;
use Chill\MainBundle\Export\FilterInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Chill\MainBundle\Form\Type\Export\FilterType;
use DateTime;
use Doctrine\ORM\Query\Expr;
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\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Translation\TranslatorInterface;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ActivityDateFilter implements FilterInterface
{
/**
*
* @var TranslatorInterface
*/
protected $translator;
function __construct(TranslatorInterface $translator)
public function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
}
public function addRole()
{
return null;
@ -55,15 +39,18 @@ class ActivityDateFilter implements FilterInterface
public function alterQuery(\Doctrine\ORM\QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->between('activity.date', ':date_from',
':date_to');
$clause = $qb->expr()->between(
'activity.date',
':date_from',
':date_to'
);
if ($where instanceof Expr\Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('date_from', $data['date_from']);
$qb->setParameter('date_to', $data['date_to']);
@ -76,55 +63,58 @@ class ActivityDateFilter implements FilterInterface
public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder)
{
$builder->add('date_from', DateType::class, array(
'label' => "Activities after this date",
'data' => new \DateTime(),
'attr' => array('class' => 'datepicker'),
'widget'=> 'single_text',
$builder->add('date_from', DateType::class, [
'label' => 'Activities after this date',
'data' => new DateTime(),
'attr' => ['class' => 'datepicker'],
'widget' => 'single_text',
'format' => 'dd-MM-yyyy',
));
$builder->add('date_to', DateType::class, array(
'label' => "Activities before this date",
'data' => new \DateTime(),
'attr' => array('class' => 'datepicker'),
'widget'=> 'single_text',
]);
$builder->add('date_to', DateType::class, [
'label' => 'Activities before this date',
'data' => new DateTime(),
'attr' => ['class' => 'datepicker'],
'widget' => 'single_text',
'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 */
$filterForm = $event->getForm()->getParent();
$enabled = $filterForm->get(FilterType::ENABLED_FIELD)->getData();
if ($enabled === true) {
if (true === $enabled) {
// if the filter is enabled, add some validation
$form = $event->getForm();
$form = $event->getForm();
$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
if ($date_from === null) {
if (null === $date_from) {
$form->get('date_from')->addError(new FormError(
$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(
$this->translator->trans('This field '
. 'should not be empty')));
}
. 'should not be empty')
));
}
// check that date_from is before date_to
if (
($date_from !== null && $date_to !== null)
&&
$date_from >= $date_to
(null !== $date_from && null !== $date_to)
&& $date_from >= $date_to
) {
$form->get('date_to')->addError(new FormError(
$this->translator->trans('This date should be after '
. 'the date given in "Implied in an activity after '
. 'this date" field')));
. 'this date" field')
));
}
}
});
@ -132,17 +122,16 @@ class ActivityDateFilter implements FilterInterface
public function describeAction($data, $format = 'string')
{
return array(
"Filtered by date of activity: only between %date_from% and %date_to%",
array(
"%date_from%" => $data['date_from']->format('d-m-Y'),
'%date_to%' => $data['date_to']->format('d-m-Y')
));
return [
'Filtered by date of activity: only between %date_from% and %date_to%',
[
'%date_from%' => $data['date_from']->format('d-m-Y'),
'%date_to%' => $data['date_to']->format('d-m-Y'),
], ];
}
public function getTitle()
{
return "Filtered by date activity";
return 'Filtered by date activity';
}
}

View File

@ -1,88 +1,76 @@
<?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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Filter;
use Chill\MainBundle\Export\FilterInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\Query\Expr;
use Symfony\Component\Security\Core\Role\Role;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\Expr\Join;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\EntityRepository;
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;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ActivityReasonFilter implements FilterInterface,
ExportElementValidatedInterface
class ActivityReasonFilter implements
FilterInterface,
ExportElementValidatedInterface
{
/**
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
/**
* The repository for activity reasons
* The repository for activity reasons.
*
* @var EntityRepository
*/
protected $reasonRepository;
/**
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
public function __construct(
TranslatableStringHelper $helper,
EntityRepository $reasonRepository
TranslatableStringHelper $helper,
EntityRepository $reasonRepository
) {
$this->translatableStringHelper = $helper;
$this->reasonRepository = $reasonRepository;
$this->reasonRepository = $reasonRepository;
}
public function addRole()
{
return new Role(ActivityStatsVoter::STATS);
}
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
$join = $qb->getDQLPart('join');
$join = $qb->getDQLPart('join');
$clause = $qb->expr()->in('reasons', ':selected_activity_reasons');
//dump($join);
// add a join to reasons only if needed
if (
(array_key_exists('activity', $join)
&&
!$this->checkJoinAlreadyDefined($join['activity'], 'reasons')
(
array_key_exists('activity', $join)
&& !$this->checkJoinAlreadyDefined($join['activity'], 'reasons')
)
OR
(! array_key_exists('activity', $join))
or (!array_key_exists('activity', $join))
) {
$qb->add(
'join',
array('activity' => new Join(Join::INNER_JOIN, 'activity.reasons', 'reasons')),
true
);
'join',
['activity' => new Join(Join::INNER_JOIN, 'activity.reasons', 'reasons')],
true
);
}
if ($where instanceof Expr\Andx) {
@ -90,27 +78,10 @@ class ActivityReasonFilter implements FilterInterface,
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('selected_activity_reasons', $data['reasons']);
}
/**
* 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()
{
@ -121,49 +92,63 @@ class ActivityReasonFilter implements FilterInterface,
{
//create a local copy of translatableStringHelper
$helper = $this->translatableStringHelper;
$builder->add('reasons', EntityType::class, array(
$builder->add('reasons', EntityType::class, [
'class' => 'ChillActivityBundle:ActivityReason',
'choice_label' => function (ActivityReason $reason) use ($helper) {
return $helper->localize($reason->getName());
},
'group_by' => function(ActivityReason $reason) use ($helper) {
'group_by' => function (ActivityReason $reason) use ($helper) {
return $helper->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 choosen")
->addViolation();
}
'expanded' => false,
]);
}
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(
function(ActivityReason $r) {
return "\"".$this->translatableStringHelper->localize($r->getName())."\"";
},
$this->reasonRepository->findBy(array('id' => $data['reasons']->toArray()))
);
return array("Filtered by reasons: only %list%",
["%list%" => implode(", ", $reasonsNames)]);
function (ActivityReason $r) {
return '"' . $this->translatableStringHelper->localize($r->getName()) . '"';
},
$this->reasonRepository->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 choosen')
->addViolation();
}
}
/**
* 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)
{
foreach ($joins as $join) {
if ($join->getAlias() === $alias) {
return true;
}
}
return false;
}
}

View File

@ -1,67 +1,57 @@
<?php
/*
* Copyright (C) 2018 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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Filter;
use Chill\MainBundle\Export\FilterInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\Query\Expr;
use Symfony\Component\Security\Core\Role\Role;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\Expr\Join;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\ActivityBundle\Entity\ActivityType;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\EntityRepository;
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 ActivityTypeFilter implements FilterInterface,
ExportElementValidatedInterface
class ActivityTypeFilter implements
FilterInterface,
ExportElementValidatedInterface
{
/**
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
/**
* The repository for activity reasons
* The repository for activity reasons.
*
* @var EntityRepository
*/
protected $typeRepository;
public function __construct(
TranslatableStringHelper $helper,
EntityRepository $typeRepository
TranslatableStringHelper $helper,
EntityRepository $typeRepository
) {
$this->translatableStringHelper = $helper;
$this->typeRepository = $typeRepository;
}
public function addRole()
{
return new Role(ActivityStatsVoter::STATS);
}
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
@ -72,27 +62,10 @@ class ActivityTypeFilter implements FilterInterface,
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$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()
{
@ -103,46 +76,60 @@ class ActivityTypeFilter implements FilterInterface,
{
//create a local copy of translatableStringHelper
$helper = $this->translatableStringHelper;
$builder->add('types', EntityType::class, array(
$builder->add('types', EntityType::class, [
'class' => ActivityType::class,
'choice_label' => function (ActivityType $type) use ($helper) {
return $helper->localize($type->getName());
},
'multiple' => true,
'expanded' => false
));
}
public function validateForm($data, ExecutionContextInterface $context)
{
if ($data['types'] === null || count($data['types']) === 0) {
$context->buildViolation("At least one type must be choosen")
->addViolation();
}
'expanded' => false,
]);
}
public function getTitle()
{
return 'Filter by activity type';
}
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(
function(ActivityType $t) {
return "\"".$this->translatableStringHelper->localize($t->getName())."\"";
},
$this->typeRepository->findBy(array('id' => $data['types']->toArray()))
);
return array("Filtered by activity type: only %list%",
["%list%" => implode(", ", $reasonsNames)]);
function (ActivityType $t) {
return '"' . $this->translatableStringHelper->localize($t->getName()) . '"';
},
$this->typeRepository->findBy(['id' => $data['types']->toArray()])
);
return ['Filtered by activity type: only %list%',
['%list%' => implode(', ', $reasonsNames)], ];
}
public function getTitle()
{
return 'Filter by activity type';
}
public function validateForm($data, ExecutionContextInterface $context)
{
if (null === $data['types'] || count($data['types']) === 0) {
$context->buildViolation('At least one type must be choosen')
->addViolation();
}
}
/**
* 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)
{
foreach ($joins as $join) {
if ($join->getAlias() === $alias) {
return true;
}
}
return false;
}
}

View File

@ -1,79 +1,60 @@
<?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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\FilterInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Chill\MainBundle\Form\Type\Export\FilterType;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Export\Declarations;
use DateTime;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\Expr;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
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 Doctrine\ORM\EntityRepository;
use Doctrine\ORM\EntityManager;
use Chill\PersonBundle\Export\Declarations;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class PersonHavingActivityBetweenDateFilter implements FilterInterface,
class PersonHavingActivityBetweenDateFilter implements
FilterInterface,
ExportElementValidatedInterface
{
/**
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
/**
*
* @var EntityRepository
*/
protected $activityReasonRepository;
/**
*
* @var TranslatorInterface
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
/**
* @var TranslatorInterface
*/
protected $translator;
public function __construct(
TranslatableStringHelper $translatableStringHelper,
EntityRepository $activityReasonRepository,
TranslatorInterface $translator
TranslatableStringHelper $translatableStringHelper,
EntityRepository $activityReasonRepository,
TranslatorInterface $translator
) {
$this->translatableStringHelper = $translatableStringHelper;
$this->activityReasonRepository = $activityReasonRepository;
$this->translator = $translator;
$this->translator = $translator;
}
public function addRole()
{
return null;
@ -83,24 +64,26 @@ class PersonHavingActivityBetweenDateFilter implements FilterInterface,
{
// create a query for activity
$sqb = $qb->getEntityManager()->createQueryBuilder();
$sqb->select("person_person_having_activity.id")
->from("ChillActivityBundle:Activity", "activity_person_having_activity")
->join("activity_person_having_activity.person", "person_person_having_activity")
;
$sqb->select('person_person_having_activity.id')
->from('ChillActivityBundle:Activity', 'activity_person_having_activity')
->join('activity_person_having_activity.person', 'person_person_having_activity');
// add clause between date
$sqb->where("activity_person_having_activity.date BETWEEN "
. ":person_having_activity_between_date_from"
. " AND "
. ":person_having_activity_between_date_to");
$sqb->where('activity_person_having_activity.date BETWEEN '
. ':person_having_activity_between_date_from'
. ' AND '
. ':person_having_activity_between_date_to');
// add clause activity reason
$sqb->join('activity_person_having_activity.reasons',
'reasons_person_having_activity');
$sqb->join(
'activity_person_having_activity.reasons',
'reasons_person_having_activity'
);
$sqb->andWhere(
$sqb->expr()->in(
'reasons_person_having_activity',
":person_having_activity_reasons")
);
$sqb->expr()->in(
'reasons_person_having_activity',
':person_having_activity_reasons'
)
);
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->in('person.id', $sqb->getDQL());
@ -109,12 +92,16 @@ class PersonHavingActivityBetweenDateFilter implements FilterInterface,
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('person_having_activity_between_date_from',
$data['date_from']);
$qb->setParameter('person_having_activity_between_date_to',
$data['date_to']);
$qb->setParameter(
'person_having_activity_between_date_from',
$data['date_from']
);
$qb->setParameter(
'person_having_activity_between_date_to',
$data['date_to']
);
$qb->setParameter('person_having_activity_reasons', $data['reasons']);
}
@ -125,104 +112,107 @@ class PersonHavingActivityBetweenDateFilter implements FilterInterface,
public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder)
{
$builder->add('date_from', DateType::class, array(
'label' => "Implied in an activity after this date",
'data' => new \DateTime(),
'attr' => array('class' => 'datepicker'),
'widget'=> 'single_text',
$builder->add('date_from', DateType::class, [
'label' => 'Implied in an activity after this date',
'data' => new DateTime(),
'attr' => ['class' => 'datepicker'],
'widget' => 'single_text',
'format' => 'dd-MM-yyyy',
));
$builder->add('date_to', DateType::class, array(
'label' => "Implied in an activity before this date",
'data' => new \DateTime(),
'attr' => array('class' => 'datepicker'),
'widget'=> 'single_text',
]);
$builder->add('date_to', DateType::class, [
'label' => 'Implied in an activity before this date',
'data' => new DateTime(),
'attr' => ['class' => 'datepicker'],
'widget' => 'single_text',
'format' => 'dd-MM-yyyy',
));
$builder->add('reasons', EntityType::class, array(
]);
$builder->add('reasons', EntityType::class, [
'class' => 'ChillActivityBundle:ActivityReason',
'choice_label' => function (ActivityReason $reason) {
return $this->translatableStringHelper
->localize($reason->getName());
->localize($reason->getName());
},
'group_by' => function(ActivityReason $reason) {
'group_by' => function (ActivityReason $reason) {
return $this->translatableStringHelper
->localize($reason->getCategory()->getName());
->localize($reason->getCategory()->getName());
},
'data' => $this->activityReasonRepository->findAll(),
'multiple' => true,
'expanded' => false,
'label' => "Activity reasons for those activities"
));
$builder->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event) {
'label' => 'Activity reasons for those activities',
]);
$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
/* @var $filterForm \Symfony\Component\Form\FormInterface */
$filterForm = $event->getForm()->getParent();
$enabled = $filterForm->get(FilterType::ENABLED_FIELD)->getData();
if ($enabled === true) {
if (true === $enabled) {
// if the filter is enabled, add some validation
$form = $event->getForm();
$form = $event->getForm();
$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
if ($date_from === null) {
if (null === $date_from) {
$form->get('date_from')->addError(new FormError(
$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(
$this->translator->trans('This field '
. 'should not be empty')));
}
. 'should not be empty')
));
}
// check that date_from is before date_to
if (
($date_from !== null && $date_to !== null)
&&
$date_from >= $date_to
(null !== $date_from && null !== $date_to)
&& $date_from >= $date_to
) {
$form->get('date_to')->addError(new FormError(
$this->translator->trans('This date '
. '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 choosen")
->addViolation();
}
}
public function describeAction($data, $format = 'string')
{
return array(
"Filtered by person having an activity between %date_from% and "
. "%date_to% with reasons %reasons_name%",
array(
"%date_from%" => $data['date_from']->format('d-m-Y'),
'%date_to%' => $data['date_to']->format('d-m-Y'),
"%reasons_name%" => implode(", ", array_map(
function (ActivityReason $r) {
return '"'.$this->translatableStringHelper->
localize($r->getName()).'"';
},
$data['reasons']))
));
return [
'Filtered by person having an activity between %date_from% and '
. '%date_to% with reasons %reasons_name%',
[
'%date_from%' => $data['date_from']->format('d-m-Y'),
'%date_to%' => $data['date_to']->format('d-m-Y'),
'%reasons_name%' => implode(', ', array_map(
function (ActivityReason $r) {
return '"' . $this->translatableStringHelper->
localize($r->getName()) . '"';
},
$data['reasons']
)),
], ];
}
public function getTitle()
{
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 choosen')
->addViolation();
}
}
}

View File

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

View File

@ -1,37 +1,36 @@
<?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;
use Chill\ActivityBundle\Form\Type\TranslatableActivityReasonCategory;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormBuilderInterface;
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
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TranslatableStringFormType::class)
->add('active', CheckboxType::class, array('required' => false))
->add('category', TranslatableActivityReasonCategory::class)
;
->add('active', CheckboxType::class, ['required' => false])
->add('category', TranslatableActivityReasonCategory::class);
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Chill\ActivityBundle\Entity\ActivityReason'
));
$resolver->setDefaults([
'data_class' => 'Chill\ActivityBundle\Entity\ActivityReason',
]);
}
/**

View File

@ -1,65 +1,72 @@
<?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;
use Chill\MainBundle\Form\Type\CommentType;
use Symfony\Component\Form\AbstractType;
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\ActivityBundle\Form\Type\TranslatableActivityReason;
use Chill\ActivityBundle\Form\Type\TranslatableActivityType;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Form\Type\ChillDateType;
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 DateInterval;
use DateTime;
use DateTimeZone;
use Doctrine\Persistence\ObjectManager;
use RuntimeException;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToTimestampTransformer;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Chill\ActivityBundle\Form\Type\TranslatableActivityType;
use Chill\ActivityBundle\Form\Type\TranslatableActivityReason;
use Chill\MainBundle\Form\Type\UserPickerType;
use Chill\MainBundle\Form\Type\ScopePickerType;
use Chill\MainBundle\Form\Type\ChillDateType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
class ActivityType extends AbstractType
{
/**
* the user running this form
*
* @var User
*/
protected $user;
/**
*
* @var AuthorizationHelper
*/
protected $authorizationHelper;
/**
*
* @var ObjectManager
*/
protected $om;
protected $timeChoices;
/**
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
protected $timeChoices;
/**
* the user running this form.
*
* @var User
*/
protected $user;
public function __construct(
TokenStorageInterface $tokenStorage,
AuthorizationHelper $authorizationHelper, ObjectManager $om,
TranslatableStringHelper $translatableStringHelper,
array $timeChoices
)
{
TokenStorageInterface $tokenStorage,
AuthorizationHelper $authorizationHelper,
ObjectManager $om,
TranslatableStringHelper $translatableStringHelper,
array $timeChoices
) {
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->authorizationHelper = $authorizationHelper;
@ -68,103 +75,98 @@ class ActivityType extends AbstractType
$this->timeChoices = $timeChoices;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
// handle times choices
$timeChoices = array();
$timeChoices = [];
foreach ($this->timeChoices as $e) {
$timeChoices[$e['label']] = $e['seconds'];
};
}
$durationTimeTransformer = new DateTimeToTimestampTransformer('GMT', 'GMT');
$durationTimeOptions = array(
'choices' => $timeChoices,
'placeholder' => 'Choose the duration',
);
$durationTimeOptions = [
'choices' => $timeChoices,
'placeholder' => 'Choose the duration',
];
$builder
->add('date', ChillDateType::class, array(
'required' => true
))
->add('date', ChillDateType::class, [
'required' => true,
])
->add('durationTime', ChoiceType::class, $durationTimeOptions)
->add('attendee', ChoiceType::class, array(
'expanded' => true,
'required' => false,
'choices' => array(
'present' => true,
'not present' => false
)
))
->add('attendee', ChoiceType::class, [
'expanded' => true,
'required' => false,
'choices' => [
'present' => true,
'not present' => false,
],
])
->add('user', UserPickerType::class, [
'center' => $options['center'],
'role' => $options['role']
'role' => $options['role'],
])
->add('scope', ScopePickerType::class, [
'center' => $options['center'],
'role' => $options['role']
'role' => $options['role'],
])
->add('reasons', TranslatableActivityReason::class, array(
->add('reasons', TranslatableActivityReason::class, [
'multiple' => true,
'required' => false,
))
->add('type', TranslatableActivityType::class, array(
])
->add('type', TranslatableActivityType::class, [
'placeholder' => 'Choose a type',
'active_only' => true
))
'active_only' => true,
])
->add('comment', CommentType::class, [
'required' => false,
])
;
]);
$builder->get('durationTime')
->addModelTransformer($durationTimeTransformer);
->addModelTransformer($durationTimeTransformer);
$builder->get('durationTime')
->addEventListener(
FormEvents::PRE_SET_DATA,
function(FormEvent $formEvent) use (
$timeChoices,
$builder,
$durationTimeTransformer,
$durationTimeOptions
)
{
// set the timezone to GMT, and fix the difference between current and GMT
// the datetimetransformer will then handle timezone as GMT
$timezoneUTC = new \DateTimeZone('GMT');
/* @var $data \DateTime */
$data = $formEvent->getData() === NULL ?
\DateTime::createFromFormat('U', 300) :
->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $formEvent) use (
$timeChoices,
$builder,
$durationTimeTransformer,
$durationTimeOptions
) {
// set the timezone to GMT, and fix the difference between current and GMT
// the datetimetransformer will then handle timezone as GMT
$timezoneUTC = new DateTimeZone('GMT');
/* @var $data \DateTime */
$data = $formEvent->getData() === null ?
DateTime::createFromFormat('U', 300) :
$formEvent->getData();
$seconds = $data->getTimezone()->getOffset($data);
$data->setTimeZone($timezoneUTC);
$data->add(new \DateInterval('PT'.$seconds.'S'));
$seconds = $data->getTimezone()->getOffset($data);
$data->setTimeZone($timezoneUTC);
$data->add(new DateInterval('PT' . $seconds . 'S'));
// test if the timestamp is in the choices.
// If not, recreate the field with the new timestamp
if (!in_array($data->getTimestamp(), $timeChoices)) {
// the data are not in the possible values. add them
$timeChoices[$data->format('H:i')] = $data->getTimestamp();
$form = $builder->create(
'durationTime',
ChoiceType::class,
array_merge(
$durationTimeOptions,
array(
'choices' => $timeChoices,
'auto_initialize' => false
)
));
$form->addModelTransformer($durationTimeTransformer);
$formEvent->getForm()->getParent()->add($form->getForm());
}
});
// test if the timestamp is in the choices.
// If not, recreate the field with the new timestamp
if (!in_array($data->getTimestamp(), $timeChoices)) {
// the data are not in the possible values. add them
$timeChoices[$data->format('H:i')] = $data->getTimestamp();
$form = $builder->create(
'durationTime',
ChoiceType::class,
array_merge(
$durationTimeOptions,
[
'choices' => $timeChoices,
'auto_initialize' => false,
]
)
);
$form->addModelTransformer($durationTimeTransformer);
$formEvent->getForm()->getParent()->add($form->getForm());
}
}
);
}
/**
@ -172,15 +174,14 @@ class ActivityType extends AbstractType
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Chill\ActivityBundle\Entity\Activity'
));
$resolver->setDefaults([
'data_class' => 'Chill\ActivityBundle\Entity\Activity',
]);
$resolver
->setRequired(array('center', 'role'))
->setAllowedTypes('center', 'Chill\MainBundle\Entity\Center')
->setAllowedTypes('role', 'Symfony\Component\Security\Core\Role\Role')
;
->setRequired(['center', 'role'])
->setAllowedTypes('center', 'Chill\MainBundle\Entity\Center')
->setAllowedTypes('role', 'Symfony\Component\Security\Core\Role\Role');
}
/**

View File

@ -1,30 +1,33 @@
<?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;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
class ActivityTypeType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TranslatableStringFormType::class)
->add('active', ChoiceType::class, array(
'choices' => array(
->add('active', ChoiceType::class, [
'choices' => [
'Yes' => true,
'No' => false
),
'expanded' => true
));
'No' => false,
],
'expanded' => true,
]);
}
/**
@ -32,9 +35,9 @@ class ActivityTypeType extends AbstractType
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Chill\ActivityBundle\Entity\ActivityType'
));
$resolver->setDefaults([
'data_class' => 'Chill\ActivityBundle\Entity\ActivityType',
]);
}
/**

View File

@ -1,54 +1,37 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2020, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
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\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
{
/**
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
/**
*
* @var ActivityReasonRender
*/
protected $reasonRender;
/**
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
public function __construct(
TranslatableStringHelper $translatableStringHelper,
ActivityReasonRender $reasonRender
@ -57,6 +40,30 @@ class TranslatableActivityReason extends AbstractType
$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()
{
return 'translatable_activity_reason';
@ -66,28 +73,4 @@ class TranslatableActivityReason extends AbstractType
{
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
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
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 Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* Description of TranslatableActivityReasonCategory
*
* @author Champs-Libres Coop
* Description of TranslatableActivityReasonCategory.
*/
class TranslatableActivityReasonCategory extends AbstractType
{
/**
@ -47,6 +30,21 @@ class TranslatableActivityReasonCategory extends AbstractType
$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()
{
return 'translatable_activity_reason_category';
@ -56,19 +54,4 @@ class TranslatableActivityReasonCategory extends AbstractType
{
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,60 +1,67 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
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 Chill\ActivityBundle\Entity\ActivityType;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\EntityRepository;
use Chill\ActivityBundle\Entity\ActivityType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* Description of TranslatableActivityType
*
* @author Champs-Libres Coop
* Description of TranslatableActivityType.
*/
class TranslatableActivityType extends AbstractType
{
protected $activityTypeRepository;
/**
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
protected $activityTypeRepository;
public function __construct(
TranslatableStringHelper $helper,
EntityRepository $activityTypeRepository
)
{
TranslatableStringHelper $helper,
EntityRepository $activityTypeRepository
) {
$this->translatableStringHelper = $helper;
$this->activityTypeRepository = $activityTypeRepository;
}
public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder, array $options)
{
/* @var $qb \Doctrine\ORM\QueryBuilder */
$qb = $options['query_builder'];
if (true === $options['active_only']) {
$qb->where($qb->expr()->eq('at.active', ':active'));
$qb->setParameter('active', true, \Doctrine\DBAL\Types\Type::BOOLEAN);
}
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
[
'class' => 'ChillActivityBundle:ActivityType',
'active_only' => true,
'query_builder' => $this->activityTypeRepository
->createQueryBuilder('at'),
'choice_label' => function (ActivityType $type) {
return $this->translatableStringHelper->localize($type->getName());
},
]
);
}
public function getBlockPrefix()
{
return 'translatable_activity_type';
@ -64,30 +71,4 @@ class TranslatableActivityType extends AbstractType
{
return EntityType::class;
}
public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder, array $options) {
/* @var $qb \Doctrine\ORM\QueryBuilder */
$qb = $options['query_builder'];
if ($options['active_only'] === true) {
$qb->where($qb->expr()->eq('at.active', ':active'));
$qb->setParameter('active', true, \Doctrine\DBAL\Types\Type::BOOLEAN);
}
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
array(
'class' => 'ChillActivityBundle:ActivityType',
'active_only' => true,
'query_builder' => $this->activityTypeRepository
->createQueryBuilder('at'),
'choice_label' => function (ActivityType $type) {
return $this->translatableStringHelper->localize($type->getName());
}
)
);
}
}

View File

@ -1,45 +1,42 @@
<?php
/*
*
*/
namespace Chill\ActivityBundle\Menu;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Knp\Menu\MenuItem;
use Symfony\Component\Security\Core\Role\Role;
use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
/**
*
* Chill is a software for social workers
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Menu;
use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Knp\Menu\MenuItem;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Translation\TranslatorInterface;
class MenuBuilder implements LocalMenuBuilderInterface
{
/**
*
* @var TokenStorageInterface
*/
protected $tokenStorage;
/**
*
* @var TranslatorInterface
*/
protected $translator;
/**
*
* @var AuthorizationHelper
*/
protected $authorizationHelper;
/**
* @var TokenStorageInterface
*/
protected $tokenStorage;
/**
* @var TranslatorInterface
*/
protected $translator;
public function __construct(
TokenStorageInterface $tokenStorage,
TranslatorInterface $translator,
TokenStorageInterface $tokenStorage,
TranslatorInterface $translator,
AuthorizationHelper $authorizationHelper
) {
$this->tokenStorage = $tokenStorage;
@ -47,42 +44,41 @@ class MenuBuilder implements LocalMenuBuilderInterface
$this->authorizationHelper = $authorizationHelper;
}
public function buildMenu($menuId, MenuItem $menu, array $parameters)
{
/* @var $person \Chill\PersonBundle\Entity\Person */
$person = $parameters['person'];
$user = $this->tokenStorage->getToken()->getUser();
$person = $parameters['person'];
$user = $this->tokenStorage->getToken()->getUser();
$roleSee = new Role(ActivityVoter::SEE);
$roleAdd = new Role(ActivityVoter::CREATE);
if ($this->authorizationHelper->userHasAccess($user, $person, $roleSee)) {
$menu->addChild($this->translator->trans('Activity list'), [
'route' => 'chill_activity_activity_list',
'routeParameters' => [
'person_id' => $person->getId()
]
])
'route' => 'chill_activity_activity_list',
'routeParameters' => [
'person_id' => $person->getId(),
],
])
->setExtras([
'order' => 201
'order' => 201,
]);
}
if ($this->authorizationHelper->userHasAccess($user, $person, $roleAdd)) {
$menu->addChild($this->translator->trans('Add a new activity'), [
'route' => 'chill_activity_activity_new',
'routeParameters' => [
'person_id' => $person->getId()
]
])
'route' => 'chill_activity_activity_new',
'routeParameters' => [
'person_id' => $person->getId(),
],
])
->setExtras([
'order' => 200
'order' => 200,
]);
}
}
public static function getMenuIds(): array
{
return [ 'person' ];
return ['person'];
}
}

View File

@ -1,78 +1,65 @@
<?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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Menu;
use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Knp\Menu\MenuItem;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Symfony\Component\Translation\TranslatorInterface;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class PersonMenuBuilder implements LocalMenuBuilderInterface
{
/**
*
* @var TranslatorInterface
*/
protected $translator;
/**
*
* @var AuthorizationCheckerInterface
*/
protected $authorizationChecker;
/**
* @var TranslatorInterface
*/
protected $translator;
public function __construct(
AuthorizationCheckerInterface $authorizationChecker,
TranslatorInterface $translator)
{
TranslatorInterface $translator
) {
$this->translator = $translator;
$this->authorizationChecker = $authorizationChecker;
}
public function buildMenu($menuId, MenuItem $menu, array $parameters)
{
/* @var $person \Chill\PersonBundle\Entity\Person */
$person = $parameters['person'];
if ($this->authorizationChecker->isGranted(ActivityVoter::SEE, $person)) {
$menu->addChild(
$this->translator->trans('Activity list'), [
$this->translator->trans('Activity list'),
[
'route' => 'chill_activity_activity_list',
'routeParameters' => [ 'person_id' => $person->getId() ],
])
->setExtra('order', 201)
;
'routeParameters' => ['person_id' => $person->getId()],
]
)
->setExtra('order', 201);
}
if ($this->authorizationChecker->isGranted(ActivityVoter::CREATE, $person)) {
$menu->addChild(
$this->translator->trans('Add a new activity'), [
$this->translator->trans('Add a new activity'),
[
'route' => 'chill_activity_activity_new',
'routeParameters' => [ 'person_id' => $person->getId() ],
])
->setExtra('order', 200)
;
'routeParameters' => ['person_id' => $person->getId()],
]
)
->setExtra('order', 200);
}
}

View File

@ -1,13 +1,36 @@
<?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\HttpKernel\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()
{
return array(
return [
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new Chill\CustomFieldsBundle\ChillCustomFieldsBundle(),
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
@ -20,28 +43,12 @@ class AppKernel extends Kernel
new \Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(),
new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(),
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)
{
$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';
$loader->load($this->getRootDir() . '/config/config_' . $this->getEnvironment() . '.yml');
}
}

View File

@ -1,11 +1,18 @@
<?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 Doctrine\Common\Annotations\AnnotationRegistry;
/** @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;

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,14 @@
<?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\HttpFoundation\Request;
// 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
@ -9,18 +16,20 @@ use Symfony\Component\Debug\Debug;
// This check prevents access to debug front controllers that are deployed by accident to production servers.
// 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'])
|| !(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');
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();
require_once __DIR__.'/../app/AppKernel.php';
require_once __DIR__ . '/../app/AppKernel.php';
$kernel = new AppKernel('dev', true);
$kernel->loadClassCache();

View File

@ -1,92 +1,80 @@
<?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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Security\Authorization;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
use Chill\MainBundle\Entity\Center;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
use function in_array;
class ActivityStatsVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface
{
const STATS = 'CHILL_ACTIVITY_STATS';
const LISTS = 'CHILL_ACTIVITY_LIST';
public const LISTS = 'CHILL_ACTIVITY_LIST';
public const STATS = 'CHILL_ACTIVITY_STATS';
/**
*
* @var AuthorizationHelper
*/
protected $helper;
public function __construct(AuthorizationHelper $helper)
{
$this->helper = $helper;
}
private function getAttributes()
{
return array(self::STATS, self::LISTS);
}
protected function getSupportedClasses()
{
return array(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)
{
if (!$user instanceof \Symfony\Component\Security\Core\User\UserInterface) {
return false;
}
return $this->helper->userHasAccess($user, $object, $attribute);
}
public function getRoles()
{
return $this->getAttributes();
}
public function getRolesWithHierarchy()
{
return ['Activity' => $this->getRoles()];
}
public function getRolesWithoutScope()
{
return $this->getAttributes();
}
public function getRolesWithHierarchy()
protected function getSupportedClasses()
{
return [ 'Activity' => $this->getRoles() ];
return [Center::class];
}
protected function isGranted($attribute, $object, $user = null)
{
if (!$user instanceof \Symfony\Component\Security\Core\User\UserInterface) {
return false;
}
return $this->helper->userHasAccess($user, $object, $attribute);
}
protected function supports($attribute, $subject)
{
if (
$subject instanceof Center
&& in_array($attribute, $this->getAttributes())
) {
return true;
}
return false;
}
private function getAttributes()
{
return [self::STATS, self::LISTS];
}
}

View File

@ -1,49 +1,38 @@
<?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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Security\Authorization;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Chill\ActivityBundle\Entity\Activity;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
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\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Role\Role;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
use function in_array;
class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface
{
const CREATE = 'CHILL_ACTIVITY_CREATE';
const SEE = 'CHILL_ACTIVITY_SEE';
const SEE_DETAILS = 'CHILL_ACTIVITY_SEE_DETAILS';
const UPDATE = 'CHILL_ACTIVITY_UPDATE';
const DELETE = 'CHILL_ACTIVITY_DELETE';
public const CREATE = 'CHILL_ACTIVITY_CREATE';
public const DELETE = 'CHILL_ACTIVITY_DELETE';
public const SEE = 'CHILL_ACTIVITY_SEE';
public const SEE_DETAILS = 'CHILL_ACTIVITY_SEE_DETAILS';
public const UPDATE = 'CHILL_ACTIVITY_UPDATE';
/**
*
* @var AuthorizationHelper
*/
protected $helper;
@ -53,18 +42,33 @@ class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn
$this->helper = $helper;
}
public function getRoles()
{
return $this->getAttributes();
}
public function getRolesWithHierarchy()
{
return ['Activity' => $this->getRoles()];
}
public function getRolesWithoutScope()
{
return [];
}
protected function supports($attribute, $subject)
{
if ($subject instanceof Activity) {
return \in_array($attribute, $this->getAttributes());
} elseif ($subject instanceof Person) {
return $attribute === self::SEE
||
$attribute === self::CREATE;
} else {
return false;
return in_array($attribute, $this->getAttributes());
}
if ($subject instanceof Person) {
return self::SEE === $attribute
|| self::CREATE === $attribute;
}
return false;
}
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
@ -72,38 +76,20 @@ class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn
if (!$token->getUser() instanceof User) {
return false;
}
if ($subject instanceof Person) {
$centers = $this->helper->getReachableCenters($token->getUser(), new Role($attribute));
return \in_array($subject->getCenter(), $centers);
return in_array($subject->getCenter(), $centers);
}
/* @var $subject Activity */
return $this->helper->userHasAccess($token->getUser(), $subject, $attribute);
}
private function getAttributes()
{
return [ self::CREATE, self::SEE, self::UPDATE, self::DELETE,
self::SEE_DETAILS ];
return [self::CREATE, self::SEE, self::UPDATE, self::DELETE,
self::SEE_DETAILS, ];
}
public function getRoles()
{
return $this->getAttributes();
}
public function getRolesWithoutScope()
{
return array();
}
public function getRolesWithHierarchy()
{
return [ 'Activity' => $this->getRoles() ];
}
}

View File

@ -1,82 +1,65 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2020, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Templating\Entity;
use Chill\MainBundle\Templating\Entity\AbstractChillEntityRender;
use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\MainBundle\Templating\Entity\AbstractChillEntityRender;
use Chill\MainBundle\Templating\TranslatableStringHelper;
/**
* Render activity reason
*
* Render activity reason.
*/
class ActivityReasonRender extends AbstractChillEntityRender
{
/**
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
public function __construct(TranslatableStringHelper $translatableStringHelper)
{
$this->translatableStringHelper = $translatableStringHelper;
}
public function renderBox($entity, array $options): string
{
return
$this->getDefaultOpeningBox('activity-reason').
'<i class="fa fa-question-circle"></i>&nbsp;'.
'<span class="activity-reason__category">'.
$this->getDefaultOpeningBox('activity-reason') .
'<i class="fa fa-question-circle"></i>&nbsp;' .
'<span class="activity-reason__category">' .
$this->translatableStringHelper->localize(
$entity->getCategory()->getName()
).
'</span>'.
'<span class="activity-reason__separator">&nbsp;>&nbsp;</span>'.
'<span class="activity-reason__reason">'.
) .
'</span>' .
'<span class="activity-reason__separator">&nbsp;>&nbsp;</span>' .
'<span class="activity-reason__reason">' .
$this->translatableStringHelper->localize(
$entity->getName()
).
'</span>'.
$this->getDefaultClosingBox()
;
) .
'</span>' .
$this->getDefaultClosingBox();
}
/**
*
* @param ActivityReason $entity
* @param array $options
* @return string
*/
public function renderString($entity, array $options): string
{
$category = '';
if (null !== $entity->getCategory()) {
$category = $this->translatableStringHelper->localize(
$entity->getCategory()->getName()). ' > ';
$entity->getCategory()->getName()
) . ' > ';
}
return $category .
$this->translatableStringHelper->localize(
$entity->getName()

View File

@ -1,20 +1,10 @@
<?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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Test;
@ -24,26 +14,19 @@ use Chill\MainBundle\Entity\Scope;
use Chill\PersonBundle\Entity\Person;
/**
* Prepare entities useful in tests
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* Prepare entities useful in tests.
*/
trait PrepareActivityTrait
{
/**
* Return an activity with a scope and a person inside
*
* @param Scope $scope
* @param Person $person
* Return an activity with a scope and a person inside.
*
* @return Activity
*/
public function prepareActivity(Scope $scope, Person $person)
{
return (new Activity())
->setScope($scope)
->setPerson($person)
;
->setPerson($person);
}
}

View File

@ -1,16 +1,78 @@
<?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;
use RuntimeException;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\HttpFoundation\Response;
/**
* @internal
* @coversNothing
*/
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
*
* @param mixed $url
*/
public function testAccessIsDeniedForUnauthenticated($url)
{
@ -19,13 +81,15 @@ class ActivityControllerTest extends WebTestCase
$client->request('GET', $url);
$this->assertEquals(302, $client->getResponse()->getStatusCode());
$this->assertTrue($client->getResponse()->isRedirect('http://localhost/login'),
sprintf('the page "%s" does not redirect to http://localhost/login', $url));
$this->assertTrue(
$client->getResponse()->isRedirect('http://localhost/login'),
sprintf('the page "%s" does not redirect to http://localhost/login', $url)
);
}
/**
*
* @dataProvider getSecuredPagesAuthenticated
*
* @param type $client
* @param type $url
*/
@ -36,63 +100,6 @@ class ActivityControllerTest extends WebTestCase
$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()
{
// Create a new client to browse the application
@ -100,27 +107,32 @@ class ActivityControllerTest extends WebTestCase
$person = $this->getPersonFromFixtures();
// Create a new entry in the database
$crawler = $client->request('GET', sprintf('en/person/%d/activity/',
$person->getId()));
$this->assertEquals(200, $client->getResponse()->getStatusCode(),
"Unexpected HTTP status code for GET /activity/");
$crawler = $client->request('GET', sprintf(
'en/person/%d/activity/',
$person->getId()
));
$this->assertEquals(
200,
$client->getResponse()->getStatusCode(),
'Unexpected HTTP status code for GET /activity/'
);
$crawler = $client->click($crawler->selectLink('Ajouter une nouvelle activité')
->link());
->link());
$reason1 = $this->getRandomActivityReason();
$reason2 = $this->getRandomActivityReason(array($reason1->getId()));
$reason2 = $this->getRandomActivityReason([$reason1->getId()]);
// Fill in the form and submit it
$form = $crawler->selectButton('Ajouter une nouvelle activité')->form(array(
'chill_activitybundle_activity'=> array(
'date' => '15-01-2015',
'durationTime' => 600,
// 'remark' => 'blabla',
'scope' => $this->getRandomScope('center a_social', 'Center A')->getId(),
'type' => $this->getRandomActivityType()->getId()
)
));
$form['chill_activitybundle_activity[reasons]']->select(array ($reason1->getId(), $reason2->getId()));
$form = $crawler->selectButton('Ajouter une nouvelle activité')->form([
'chill_activitybundle_activity' => [
'date' => '15-01-2015',
'durationTime' => 600,
// 'remark' => 'blabla',
'scope' => $this->getRandomScope('center a_social', 'Center A')->getId(),
'type' => $this->getRandomActivityType()->getId(),
],
]);
$form['chill_activitybundle_activity[reasons]']->select([$reason1->getId(), $reason2->getId()]);
$client->submit($form);
@ -128,18 +140,21 @@ class ActivityControllerTest extends WebTestCase
$crawler = $client->followRedirect();
// Check data in the show view
$this->assertGreaterThan(0, $crawler->filter('dd:contains("January 15, 2015")')->count(),
'Missing element dd:contains("January 15, 2015")');
$this->assertGreaterThan(
0,
$crawler->filter('dd:contains("January 15, 2015")')->count(),
'Missing element dd:contains("January 15, 2015")'
);
// Edit the entity
$crawler = $client->click($crawler->selectLink("Modifier l'activité")->link());
$form = $crawler->selectButton("Sauver l'activité")->form(array(
'chill_activitybundle_activity' => array(
'date' => '25-01-2015',
// 'remark' => 'Foo'
)
));
$form = $crawler->selectButton("Sauver l'activité")->form([
'chill_activitybundle_activity' => [
'date' => '25-01-2015',
// 'remark' => 'Foo'
],
]);
$client->submit($form);
@ -148,164 +163,33 @@ class ActivityControllerTest extends WebTestCase
$crawler = $client->followRedirect();
// check that new data are present
$this->assertGreaterThan(0,
$crawler->filter('dd:contains("January 25, 2015")')->count(),
'Missing element dd:contains("January 25, 2015")');
$this->assertGreaterThan(0,
$crawler->filter('dd:contains("Foo")')->count(),
'Missing element dd:contains("Foo")');
$this->assertGreaterThan(
0,
$crawler->filter('dd:contains("January 25, 2015")')->count(),
'Missing element dd:contains("January 25, 2015")'
);
$this->assertGreaterThan(
0,
$crawler->filter('dd:contains("Foo")')->count(),
'Missing element dd:contains("Foo")'
);
// 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);
$this->assertTrue($client->getResponse()->isRedirect(sprintf('/en/person/%d/activity/',
$person->getId())));
$client->submit($form);
$this->assertTrue($client->getResponse()->isRedirect(sprintf(
'/en/person/%d/activity/',
$person->getId()
)));
$crawler = $client->followRedirect();
$crawler = $client->followRedirect();
$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)];
$this->assertNotContains('January 25, 2015', $crawler->text());
}
/**
@ -321,10 +205,10 @@ class ActivityControllerTest extends WebTestCase
//get the social PermissionGroup, and remove CHILL_ACTIVITY_*
$socialPermissionGroup = $em
->getRepository('ChillMainBundle:PermissionsGroup')
->findOneByName('social');
->getRepository('ChillMainBundle:PermissionsGroup')
->findOneByName('social');
$withoutActivityPermissionGroup = (new \Chill\MainBundle\Entity\PermissionsGroup())
->setName('social without activity');
->setName('social without activity');
//copy role scopes where ACTIVITY is not present
foreach ($socialPermissionGroup->getRoleScopes() as $roleScope) {
if (!strpos($roleScope->getRole(), 'ACTIVITY')) {
@ -334,8 +218,8 @@ class ActivityControllerTest extends WebTestCase
//create groupCenter
$groupCenter = new \Chill\MainBundle\Entity\GroupCenter();
$groupCenter->setCenter($em->getRepository('ChillMainBundle:Center')
->findOneBy(array('name' => 'Center A')))
->setPermissionsGroup($withoutActivityPermissionGroup);
->findOneBy(['name' => 'Center A']))
->setPermissionsGroup($withoutActivityPermissionGroup);
$em->persist($withoutActivityPermissionGroup);
$em->persist($groupCenter);
@ -344,10 +228,10 @@ class ActivityControllerTest extends WebTestCase
$username = $faker->name;
$user = new \Chill\MainBundle\Entity\User();
$user
->setPassword($container->get('security.password_encoder')
->encodePassword($user, 'password'))
->setUsername($username)
->addGroupCenter($groupCenter);
->setPassword($container->get('security.password_encoder')
->encodePassword($user, 'password'))
->setUsername($username)
->addGroupCenter($groupCenter);
$em->persist($user);
@ -355,4 +239,146 @@ class ActivityControllerTest extends WebTestCase
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
/**
* 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;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
/**
* @internal
* @coversNothing
*/
class ActivityReasonCategoryControllerTest extends WebTestCase
{
public function testToWrite()
{
$this->markTestSkipped();
}
/*
public function testCompleteScenario()
{
@ -55,5 +67,5 @@ class ActivityReasonCategoryControllerTest extends WebTestCase
$this->assertNotRegExp('/Foo/', $client->getResponse()->getContent());
}
*/
*/
}

View File

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

View File

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

View File

@ -1,20 +1,10 @@
<?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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Aggregator;
@ -22,59 +12,59 @@ namespace Chill\ActivityBundle\Tests\Aggregator;
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
{
/**
*
* @var \Chill\ActivityBundle\Export\Aggregator\ActivityReasonAggregator
*/
private $aggregator;
public function setUp()
{
static::bootKernel();
$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)
$prophet = new \Prophecy\Prophet;
$prophet = new \Prophecy\Prophet();
$request = $prophet->prophesize();
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
$request->getLocale()->willReturn('fr');
$container->get('request_stack')
->push($request->reveal());
->push($request->reveal());
}
public function getAggregator()
{
return $this->aggregator;
}
public function getFormData()
{
return array(
array('level' => 'reasons'),
array('level' => 'categories')
);
return [
['level' => 'reasons'],
['level' => 'categories'],
];
}
public function getQueryBuilders()
{
if (static::$kernel === null) {
if (null === static::$kernel) {
static::bootKernel();
}
$em = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager');
return array(
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity'),
@ -86,8 +76,7 @@ class ActivityReasonAggregatorTest extends AbstractAggregatorTest
->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity')
->join('activity.reasons', 'reasons')
->join('reasons.category', 'category')
);
->join('reasons.category', 'category'),
];
}
}

View File

@ -1,20 +1,10 @@
<?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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Aggregator;
@ -22,58 +12,58 @@ namespace Chill\ActivityBundle\Tests\Aggregator;
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
{
/**
*
* @var \Chill\ActivityBundle\Export\Aggregator\ActivityReasonAggregator
*/
private $aggregator;
public function setUp()
{
static::bootKernel();
$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)
$prophet = new \Prophecy\Prophet;
$prophet = new \Prophecy\Prophet();
$request = $prophet->prophesize();
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
$request->getLocale()->willReturn('fr');
$container->get('request_stack')
->push($request->reveal());
->push($request->reveal());
}
public function getAggregator()
{
return $this->aggregator;
}
public function getFormData()
{
return array(
array()
);
return [
[],
];
}
public function getQueryBuilders()
{
if (static::$kernel === null) {
if (null === static::$kernel) {
static::bootKernel();
}
$em = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager');
return array(
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity'),
@ -85,8 +75,7 @@ class ActivityTypeAggregatorTest extends AbstractAggregatorTest
->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity')
->join('activity.reasons', 'reasons')
->join('reasons.category', 'category')
);
->join('reasons.category', 'category'),
];
}
}

View File

@ -1,20 +1,10 @@
<?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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Aggregator;
@ -22,57 +12,58 @@ namespace Chill\ActivityBundle\Tests\Aggregator;
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
/**
* Add tests for ActivityUsernAggregator
* Add tests for ActivityUsernAggregator.
*
* @internal
* @coversNothing
*/
class ActivityUserAggregatorTest extends AbstractAggregatorTest
{
/**
*
* @var \Chill\ActivityBundle\Export\Aggregator\ActivityUserAggregator
*/
private $aggregator;
public function setUp()
{
static::bootKernel();
$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)
$prophet = new \Prophecy\Prophet;
$prophet = new \Prophecy\Prophet();
$request = $prophet->prophesize();
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
$request->getLocale()->willReturn('fr');
$container->get('request_stack')
->push($request->reveal());
->push($request->reveal());
}
public function getAggregator()
{
return $this->aggregator;
}
public function getFormData()
{
return array(
array()
);
return [
[],
];
}
public function getQueryBuilders()
{
if (static::$kernel === null) {
if (null === static::$kernel) {
static::bootKernel();
}
$em = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager');
return array(
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity'),
@ -84,8 +75,7 @@ class ActivityUserAggregatorTest extends AbstractAggregatorTest
->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity')
->join('activity.reasons', 'reasons')
->join('reasons.category', 'category')
);
->join('reasons.category', 'category'),
];
}
}

View File

@ -1,32 +1,37 @@
<?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;
use Chill\MainBundle\Test\Export\AbstractExportTest;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @internal
* @coversNothing
*/
class CountActivityTest extends AbstractExportTest
{
/**
*
* @var
* @var
*/
private $export;
public function setUp()
{
static::bootKernel();
/* @var $container \Symfony\Component\DependencyInjection\ContainerInterface */
$container = self::$kernel->getContainer();
$this->export = $container->get('chill.activity.export.count_activity');
}
public function getExport()
{
return $this->export;
@ -34,17 +39,16 @@ class CountActivityTest extends AbstractExportTest
public function getFormData()
{
return array(
array()
);
return [
[],
];
}
public function getModifiersCombination()
{
return array(
array('activity'),
array('activity', 'person')
);
return [
['activity'],
['activity', 'person'],
];
}
}

View File

@ -1,20 +1,10 @@
<?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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Export;
@ -22,67 +12,33 @@ namespace Chill\ActivityBundle\Tests\Export\Export;
use Chill\MainBundle\Test\Export\AbstractExportTest;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @internal
* @coversNothing
*/
class ListActivityTest extends AbstractExportTest
{
/**
*
* @var \Chill\ActivityBundle\Export\Export\ListActivity
*/
private $export;
public function setUp()
{
static::bootKernel();
/* @var $container \Symfony\Component\DependencyInjection\ContainerInterface */
$container = self::$kernel->getContainer();
$this->export = $container->get('chill.activity.export.list_activity');
// add a fake request with a default locale (used in translatable string)
$prophet = new \Prophecy\Prophet;
$prophet = new \Prophecy\Prophet();
$request = $prophet->prophesize();
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
$request->getLocale()->willReturn('fr');
$container->get('request_stack')
->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')
);
->push($request->reveal());
}
public function getExport()
@ -90,4 +46,33 @@ class ListActivityTest extends AbstractExportTest
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
/**
* 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;
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
{
/**
*
* @var \Chill\ActivityBundle\Export\Export\StatActivityDuration
*/
private $export;
public function setUp()
{
static::bootKernel();
/* @var $container \Symfony\Component\DependencyInjection\ContainerInterface */
$container = self::$kernel->getContainer();
$this->export = $container->get('chill.activity.export.sum_activity_duration');
}
public function getExport()
{
return $this->export;
@ -34,17 +41,16 @@ class StatActivityDurationSumTest extends AbstractExportTest
public function getFormData()
{
return array(
array()
);
return [
[],
];
}
public function getModifiersCombination()
{
return array(
array('activity'),
array('activity', 'person')
);
return [
['activity'],
['activity', 'person'],
];
}
}

View File

@ -1,20 +1,10 @@
<?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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Filter;
@ -23,37 +13,34 @@ use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Doctrine\Common\Collections\ArrayCollection;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @internal
* @coversNothing
*/
class ActivityReasonFilterTest extends AbstractFilterTest
{
/**
*
* @var \Chill\PersonBundle\Export\Filter\GenderFilter
*/
private $filter;
public function setUp()
{
static::bootKernel();
$container = static::$kernel->getContainer();
$this->filter = $container->get('chill.activity.export.reason_filter');
// add a fake request with a default locale (used in translatable string)
$prophet = new \Prophecy\Prophet;
$prophet = new \Prophecy\Prophet();
$request = $prophet->prophesize();
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
$request->getLocale()->willReturn('fr');
$container->get('request_stack')
->push($request->reveal());
->push($request->reveal());
}
public function getFilter()
{
return $this->filter;
@ -61,36 +48,35 @@ class ActivityReasonFilterTest extends AbstractFilterTest
public function getFormData()
{
if (static::$kernel === null) {
if (null === static::$kernel) {
static::bootKernel();
}
$em = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager')
;
$reasons = $em->createQuery("SELECT reason "
. "FROM ChillActivityBundle:ActivityReason reason")
->getResult();
->get('doctrine.orm.entity_manager');
$reasons = $em->createQuery('SELECT reason '
. 'FROM ChillActivityBundle:ActivityReason reason')
->getResult();
// generate an array of 5 different combination of results
for ($i=0; $i < 5; $i++) {
$r[] = array('reasons' => new ArrayCollection(array_splice($reasons, ($i + 1) * -1)));
for ($i = 0; 5 > $i; ++$i) {
$r[] = ['reasons' => new ArrayCollection(array_splice($reasons, ($i + 1) * -1))];
}
return $r;
}
public function getQueryBuilders()
{
if (static::$kernel === null) {
if (null === static::$kernel) {
static::bootKernel();
}
$em = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager');
return array(
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity'),
@ -102,8 +88,7 @@ class ActivityReasonFilterTest extends AbstractFilterTest
->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity')
->join('activity.reasons', 'reasons')
->join('reasons.category', 'category')
);
->join('reasons.category', 'category'),
];
}
}

View File

@ -1,56 +1,47 @@
<?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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Filter;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use DateTime;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @internal
* @coversNothing
*/
class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest
{
/**
*
* @var \Chill\PersonBundle\Export\Filter\PersonHavingActivityBetweenDateFilter
*/
private $filter;
public function setUp()
{
static::bootKernel();
$container = static::$kernel->getContainer();
$this->filter = $container->get('chill.activity.export.'
. 'person_having_an_activity_between_date_filter');
// add a fake request with a default locale (used in translatable string)
$prophet = new \Prophecy\Prophet;
$prophet = new \Prophecy\Prophet();
$request = $prophet->prophesize();
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
$request->getLocale()->willReturn('fr');
$container->get('request_stack')
->push($request->reveal());
->push($request->reveal());
}
public function getFilter()
{
return $this->filter;
@ -58,49 +49,33 @@ class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest
public function getFormData()
{
$date_from = \DateTime::createFromFormat('Y-m-d', '2015-01-15');
$date_to = new \DateTime(); // today
$date_from = DateTime::createFromFormat('Y-m-d', '2015-01-15');
$date_to = new DateTime(); // today
$reasons = $this->getActivityReasons();
$data = array();
for ($i = 0; $i < 4; $i++) {
$data[] = array(
$data = [];
for ($i = 0; 4 > $i; ++$i) {
$data[] = [
'date_from' => $date_from,
'date_to' => $date_to,
'reasons' => array_slice($reasons, 0, 1 + $i)
);
'date_to' => $date_to,
'reasons' => array_slice($reasons, 0, 1 + $i),
];
}
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()
{
if (static::$kernel === null) {
if (null === static::$kernel) {
static::bootKernel();
}
$em = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager');
return array(
return [
$em->createQueryBuilder()
->select('count(person.id)')
->from('ChillPersonBundle:Person', 'person')
@ -112,6 +87,22 @@ class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest
->join('activity.person', 'person')
// add a fake where clause
->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
/*
* 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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Form;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Chill\ActivityBundle\Form\ActivityType;
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\Role\Role;
use Symfony\Component\Form\Extension\Core\Type\FormType;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @internal
* @coversNothing
*/
class ActivityTypeTest extends KernelTestCase
{
/**
*
* @var \Symfony\Component\Form\FormBuilderInterface
* @var \Chill\MainBundle\Entity\Center
*/
protected $formBuilder;
protected $center;
/**
*
* @var \Symfony\Component\DependencyInjection\ContainerInterface
*/
protected $container;
/**
*
* @var \Symfony\Component\Form\FormBuilderInterface
*/
protected $formBuilder;
/**
* @var \Symfony\Component\Security\Core\User\UserInterface
*/
protected $user;
/**
*
* @var \Chill\MainBundle\Entity\Center
*/
protected $center;
public function setUp()
{
self::bootKernel();
$this->container = self::$kernel->getContainer();
$prophet = new \Prophecy\Prophet;
$prophet = new \Prophecy\Prophet();
$this->formBuilder = $this->container
->get('form.factory')
->createBuilder(FormType::class, null, array(
'csrf_protection' => false,
'csrf_field_name' => '_token'
));
->get('form.factory')
->createBuilder(FormType::class, null, [
'csrf_protection' => false,
'csrf_field_name' => '_token',
]);
$request = new \Symfony\Component\HttpFoundation\Request();
$request->setLocale('fr');
self::$kernel->getContainer()
->get('request_stack')
->push($request);
->get('request_stack')
->push($request);
$this->user = $this->container->get('doctrine.orm.entity_manager')
->getRepository('ChillMainBundle:User')
->findOneBy(array('username' => 'center a_social'));
->getRepository('ChillMainBundle:User')
->findOneBy(['username' => 'center a_social']);
$this->center = $this->container->get('doctrine.orm.entity_manager')
->getRepository('ChillMainBundle:Center')
->findOneBy(array('name' => 'Center A'));
->getRepository('ChillMainBundle:Center')
->findOneBy(['name' => 'Center A']);
$token = $prophet->prophesize();
$token->willExtend(AbstractToken::class);
$token->getUser()->willReturn($this->user);
$this->container->get('security.token_storage')
->setToken($token->reveal());
->setToken($token->reveal());
}
public function testForm()
{
$form = $this->formBuilder
->add('activity', ActivityType::class, array(
'center' => $this->center,
'role' => new Role('CHILL_ACTIVITY_CREATE')
))
->getForm();
->add('activity', ActivityType::class, [
'center' => $this->center,
'role' => new Role('CHILL_ACTIVITY_CREATE'),
])
->getForm();
$form->submit(array());
$form->submit([]);
$this->assertTrue($form->isSynchronized());
$this->assertTrue($form->isValid());
$this->assertInstanceOf(Activity::class, $form->getData()['activity']);
}
public function testFormSubmitting()
{
$form = $this->formBuilder
->add('activity', ActivityType::class, array(
'center' => $this->center,
'role' => new Role('CHILL_ACTIVITY_CREATE')
))
->getForm();
->add('activity', ActivityType::class, [
'center' => $this->center,
'role' => new Role('CHILL_ACTIVITY_CREATE'),
])
->getForm();
$form->submit(array( 'activity' => array(
$form->submit(['activity' => [
'date' => '9-3-2015',
'durationTime' => 300,
// 'remark' => 'blabla',
'attendee' => true
)));
// 'remark' => 'blabla',
'attendee' => true,
]]);
// var_dump($form->getErrors()->count()); var_dump($form->isValid());
// foreach($form->getErrors() as $e) { fwrite(STDOUT, var_dump($e->getMessage())); }
// var_dump($form->getErrors());
$this->assertTrue($form->isSynchronized(), "Test the form is synchronized");
$this->assertTrue($form->isValid(), "test the form is valid");
$this->assertTrue($form->isSynchronized(), 'Test the form is synchronized');
$this->assertTrue($form->isValid(), 'test the form is valid');
$this->assertInstanceOf(Activity::class, $form->getData()['activity']);
// test the activity
/* @var $activity Activity */
$activity = $form->getData()['activity'];
$this->assertEquals('09-03-2015', $activity->getDate()->format('d-m-Y'),
"Test the date is correct");
$this->assertEquals('00:05', $activity->getDurationTime()->format('H:i'),
"Test the formatted hour is correct");
$this->assertEquals(
'09-03-2015',
$activity->getDate()->format('d-m-Y'),
'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('blabla', $activity->getRemark());
// $this->assertEquals('blabla', $activity->getRemark());
}
/**
* 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()
{
$activity = new Activity();
$activity->setDurationTime(\DateTime::createFromFormat('U', 60));
$activity->setDurationTime(DateTime::createFromFormat('U', 60));
$builder = $this->container
->get('form.factory')
->createBuilder(FormType::class, array('activity' => $activity), array(
'csrf_protection' => false,
'csrf_field_name' => '_token'
));
->get('form.factory')
->createBuilder(FormType::class, ['activity' => $activity], [
'csrf_protection' => false,
'csrf_field_name' => '_token',
]);
$form = $builder
->add('activity', ActivityType::class, array(
'center' => $this->center,
'role' => new Role('CHILL_ACTIVITY_CREATE')
))
->getForm();
->add('activity', ActivityType::class, [
'center' => $this->center,
'role' => new Role('CHILL_ACTIVITY_CREATE'),
])
->getForm();
$form->submit(array( 'activity' => array(
$form->submit(['activity' => [
'date' => '9-3-2015',
'durationTime' => 60,
// 'remark' => 'blabla',
'attendee' => true
)));
// 'remark' => 'blabla',
'attendee' => true,
]]);
$this->assertTrue($form->isSynchronized());
$this->assertTrue($form->isValid());
@ -186,8 +173,11 @@ class ActivityTypeTest extends KernelTestCase
/* @var $activity Activity */
$activity = $form->getData()['activity'];
$this->assertEquals('00:01', $activity->getDurationTime()->format('H:i'),
"Test the formatted hour is correct");
$this->assertEquals(
'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
$view = $form->createView();
@ -195,11 +185,11 @@ class ActivityTypeTest extends KernelTestCase
$this->assertTrue(isset($view['activity']['durationTime']));
// map all the values in an array
$values = array_map(function($choice) { return $choice->value; },
$view['activity']['durationTime']->vars['choices']);
$values = array_map(
function ($choice) { return $choice->value; },
$view['activity']['durationTime']->vars['choices']
);
$this->assertContains(60, $values);
}
}

View File

@ -1,110 +1,96 @@
<?php
/*
/**
* 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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Form\Type;
use Symfony\Component\Form\Test\TypeTestCase;
use Chill\ActivityBundle\Form\Type\TranslatableActivityReason;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Component\Form\PreloadedExtension;
use Symfony\Component\Form\Test\TypeTestCase;
/**
* Test translatableActivityReason
* Test translatableActivityReason.
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @author Champs Libres <info@champs-libres.coop>
* @internal
* @coversNothing
*/
class TranslatableActivityReasonTest extends TypeTestCase
{
/**
*
* @var Prophecy\Prophet
* @var Prophecy\Prophet
*/
private static $prophet;
public function setUp()
{
parent::setUp();
}
protected function getExtensions()
{
$entityType = $this->getEntityType();
return array(new PreloadedExtension(array(
'entity' => $entityType
), array()));
}
public function testSimple()
{
$translatableActivityReasonType = new TranslatableActivityReason(
$this->getTranslatableStringHelper()
);
$this->markTestSkipped("See issue 651");
$this->getTranslatableStringHelper()
);
$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
*/
protected function getEntityType()
{
$managerRegistry = (new \Prophecy\Prophet())->prophesize();
$managerRegistry->willImplement('Doctrine\Common\Persistence\ManagerRegistry');
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
/*
* 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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Form\Type;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Chill\ActivityBundle\Form\Type\TranslatableActivityType;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Form\Extension\Core\Type\FormType;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @internal
* @coversNothing
*/
class TranslatableActivityTypeTest extends KernelTestCase
{
/**
*
* @var \Symfony\Component\Form\FormBuilderInterface
*/
protected $builder;
/**
*
* @var \Symfony\Component\DependencyInjection\ContainerInterface
*/
protected $container;
public function setUp()
{
self::bootKernel();
$this->container = self::$kernel->getContainer();
$this->builder = $this->container
->get('form.factory')
->createBuilder(FormType::class, null, array(
'csrf_protection' => false,
'csrf_field_name' => '_token'
));
->get('form.factory')
->createBuilder(FormType::class, null, [
'csrf_protection' => false,
'csrf_field_name' => '_token',
]);
$request = new \Symfony\Component\HttpFoundation\Request();
$request->setLocale('fr');
$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()
{
$type = $this->getRandomType();
$form = $this->builder->add('type', TranslatableActivityType::class)
->getForm();
$form->submit(array(
'type' => $type->getId()
));
->getForm();
$form->submit([
'type' => $type->getId(),
]);
$this->assertTrue($form->isSynchronized());
$this->assertInstanceOf(\Chill\ActivityBundle\Entity\ActivityType::class,
$form->getData()['type'],
"The data is an instance of Chill\ActivityBundle\Entity\ActivityType");
$this->assertInstanceOf(
\Chill\ActivityBundle\Entity\ActivityType::class,
$form->getData()['type'],
'The data is an instance of Chill\\ActivityBundle\\Entity\\ActivityType'
);
$this->assertEquals($type->getId(), $form->getData()['type']->getId());
// test the ordering of the types in the form
// since 2016-11-14 the types are not alphabetically ordered, skipping
/*$view = $form->createView();
$this->assertGreaterThan(0, count($view['type']->vars['choices']),
"test that there are at least one choice");
foreach($view['type']->vars['choices'] as $choice) {
// initialize the previous value is not set (this is the first)
if (!isset($previous)) {
$previous = $choice->label;
if (!isset($previous)) {
$previous = $choice->label;
} else {
$this->assertTrue($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
/*
* 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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Security\Authorization;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
use Chill\ActivityBundle\Test\PrepareActivityTrait;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Test\PrepareUserTrait;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Test\PrepareCenterTrait;
use Chill\MainBundle\Test\PrepareScopeTrait;
use Chill\MainBundle\Test\PrepareUserTrait;
use Chill\PersonBundle\Test\PreparePersonTrait;
use Chill\ActivityBundle\Test\PrepareActivityTrait;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @internal
* @coversNothing
*/
class ActivityVoterTest extends KernelTestCase
{
use PrepareUserTrait, PrepareCenterTrait, PrepareScopeTrait,
PreparePersonTrait, PrepareActivityTrait;
use PrepareActivityTrait;
use PrepareCenterTrait;
use PreparePersonTrait;
use PrepareScopeTrait;
use PrepareUserTrait;
/**
*
* @var \Chill\PersonBundle\Security\Authorization\PersonVoter
*/
protected $voter;
/**
*
* @var \Prophecy\Prophet
*/
protected $prophet;
/**
* @var \Chill\PersonBundle\Security\Authorization\PersonVoter
*/
protected $voter;
public function setUp()
{
static::bootKernel();
$this->voter = static::$kernel->getContainer()
->get('chill.activity.security.authorization.activity_voter');
->get('chill.activity.security.authorization.activity_voter');
$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()
{
$centerA = $this->prepareCenter(1, 'center A');
@ -105,72 +57,111 @@ class ActivityVoterTest extends KernelTestCase
$scopeA = $this->prepareScope(1, 'scope default');
$scopeB = $this->prepareScope(2, 'scope B');
$scopeC = $this->prepareScope(3, 'scope C');
$userA = $this->prepareUser(array(
array(
'center' => $centerA,
'permissionsGroup' => array(
$userA = $this->prepareUser([
[
'center' => $centerA,
'permissionsGroup' => [
['scope' => $scopeB, 'role' => 'CHILL_ACTIVITY_CREATE'],
['scope' => $scopeA, 'role' => 'CHILL_ACTIVITY_SEE']
)
),
array(
'center' => $centerB,
'permissionsGroup' => array(
['scope' => $scopeA, 'role' => 'CHILL_ACTIVITY_CREATE'],
['scope' => $scopeC, 'role' => 'CHILL_ACTIVITY_CREATE']
)
)
));
return array(
array(
['scope' => $scopeA, 'role' => 'CHILL_ACTIVITY_SEE'],
],
],
[
'center' => $centerB,
'permissionsGroup' => [
['scope' => $scopeA, 'role' => 'CHILL_ACTIVITY_CREATE'],
['scope' => $scopeC, 'role' => 'CHILL_ACTIVITY_CREATE'],
],
],
]);
return [
[
VoterInterface::ACCESS_GRANTED,
$userA,
$scopeB,
$centerA,
'CHILL_ACTIVITY_CREATE',
'assert that a user granted with same rights'
),
array(
'assert that a user granted with same rights',
],
[
VoterInterface::ACCESS_GRANTED,
$userA,
$scopeB,
$centerA,
'CHILL_ACTIVITY_SEE',
'assert that a user granted with inheritance rights'
),
array(
'assert that a user granted with inheritance rights',
],
[
VoterInterface::ACCESS_DENIED,
$userA,
$scopeC,
$centerA,
'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
*
*
* @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
->willImplement('\Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
if ($user === NULL) {
if (null === $user) {
$token->getUser()->willReturn(null);
} else {
$token->getUser()->willReturn($user);
}
return $token->reveal();
}
}

View File

@ -1,20 +1,10 @@
<?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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Timeline;
@ -22,15 +12,13 @@ namespace Chill\ActivityBundle\Tests\Timeline;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @internal
* @coversNothing
*/
class TimelineProviderTest extends WebTestCase
{
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,219 +1,198 @@
<?php
/*
/**
* 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
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Timeline;
use Chill\MainBundle\Timeline\TimelineProviderInterface;
use Doctrine\ORM\EntityManager;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\MainBundle\Timeline\TimelineProviderInterface;
use Chill\PersonBundle\Entity\Person;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\ClassMetadata;
use LogicException;
use RuntimeException;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Role\Role;
use Doctrine\ORM\Mapping\ClassMetadata;
use Chill\PersonBundle\Entity\Person;
use Chill\MainBundle\Entity\Scope;
/**
* Provide activity for inclusion in timeline
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @author Champs Libres <info@champs-libres.coop>
* Provide activity for inclusion in timeline.
*/
class TimelineActivityProvider implements TimelineProviderInterface
{
/**
*
* @var EntityManager
*/
protected $em;
/**
*
* @var AuthorizationHelper
*/
protected $helper;
/**
*
* @var \Chill\MainBundle\Entity\User
* @var \Chill\MainBundle\Entity\User
*/
protected $user;
/**
* TimelineActivityProvider constructor.
*
* @param EntityManager $em
* @param AuthorizationHelper $helper
* @param TokenStorageInterface $storage
*/
public function __construct(
EntityManager $em,
AuthorizationHelper $helper,
TokenStorageInterface $storage
)
{
) {
$this->em = $em;
$this->helper = $helper;
if (!$storage->getToken()->getUser() instanceof \Chill\MainBundle\Entity\User)
{
throw new \RuntimeException('A user should be authenticated !');
if (!$storage->getToken()->getUser() instanceof \Chill\MainBundle\Entity\User) {
throw new RuntimeException('A user should be authenticated !');
}
$this->user = $storage->getToken()->getUser();
}
/**
*
* {@inheritDoc}
*/
public function fetchQuery($context, array $args)
{
$this->checkContext($context);
$metadataActivity = $this->em->getClassMetadata('ChillActivityBundle:Activity');
$metadataPerson = $this->em->getClassMetadata('ChillPersonBundle:Person');
return array(
'id' => $metadataActivity->getTableName()
.'.'.$metadataActivity->getColumnName('id'),
'type' => 'activity',
'date' => $metadataActivity->getTableName()
.'.'.$metadataActivity->getColumnName('date'),
'FROM' => $this->getFromClause($metadataActivity, $metadataPerson),
'WHERE' => $this->getWhereClause($metadataActivity, $metadataPerson,
$args['person'])
);
}
private function getWhereClause(ClassMetadata $metadataActivity,
ClassMetadata $metadataPerson, Person $person)
{
$role = new Role('CHILL_ACTIVITY_SEE');
$reachableCenters = $this->helper->getReachableCenters($this->user,
$role);
$associationMapping = $metadataActivity->getAssociationMapping('person');
if (count($reachableCenters) === 0) {
return 'FALSE = TRUE';
}
// we start with activities having the person_id linked to person
// (currently only context "person" is supported)
$whereClause = sprintf('%s = %d',
$associationMapping['joinColumns'][0]['name'],
$person->getId());
// we add acl (reachable center and scopes)
$centerAndScopeLines = array();
foreach ($reachableCenters as $center) {
$reachablesScopesId = array_map(
function(Scope $scope) { return $scope->getId(); },
$this->helper->getReachableScopes($this->user, $role,
$person->getCenter())
);
$centerAndScopeLines[] = sprintf('(%s = %d AND %s IN (%s))',
$metadataPerson->getTableName().'.'.
$metadataPerson->getAssociationMapping('center')['joinColumns'][0]['name'],
$center->getId(),
$metadataActivity->getTableName().'.'.
$metadataActivity->getAssociationMapping('scope')['joinColumns'][0]['name'],
implode(',', $reachablesScopesId));
}
$whereClause .= ' AND ('.implode(' OR ', $centerAndScopeLines).')';
return $whereClause;
}
private function getFromClause(ClassMetadata $metadataActivity,
ClassMetadata $metadataPerson)
{
$associationMapping = $metadataActivity->getAssociationMapping('person');
return $metadataActivity->getTableName().' JOIN '
.$metadataPerson->getTableName().' ON '
.$metadataPerson->getTableName().'.'.
$associationMapping['joinColumns'][0]['referencedColumnName']
.' = '
.$associationMapping['joinColumns'][0]['name']
;
return [
'id' => $metadataActivity->getTableName()
. '.' . $metadataActivity->getColumnName('id'),
'type' => 'activity',
'date' => $metadataActivity->getTableName()
. '.' . $metadataActivity->getColumnName('date'),
'FROM' => $this->getFromClause($metadataActivity, $metadataPerson),
'WHERE' => $this->getWhereClause(
$metadataActivity,
$metadataPerson,
$args['person']
),
];
}
/**
*
* {@inheritDoc}
*/
public function getEntities(array $ids)
{
$activities = $this->em->getRepository('ChillActivityBundle:Activity')
->findBy(array('id' => $ids));
$result = array();
foreach($activities as $activity) {
->findBy(['id' => $ids]);
$result = [];
foreach ($activities as $activity) {
$result[$activity->getId()] = $activity;
}
return $result;
}
/**
*
* {@inheritDoc}
*/
public function getEntityTemplate($entity, $context, array $args)
{
$this->checkContext($context);
return array(
'template' => 'ChillActivityBundle:Timeline:activity_person_context.html.twig',
'template_data' => array(
'activity' => $entity,
'person' => $args['person'],
'user' => $entity->getUser()
)
);
return [
'template' => 'ChillActivityBundle:Timeline:activity_person_context.html.twig',
'template_data' => [
'activity' => $entity,
'person' => $args['person'],
'user' => $entity->getUser(),
],
];
}
public function supportsType($type)
{
return 'activity' === $type;
}
/**
*
* {@inheritDoc}
*/
public function supportsType($type)
{
return $type === 'activity';
}
/**
* check if the context is supported
*
* check if the context is supported.
*
* @param string $context
* @throws \LogicException if the context is not supported
*
* @throws LogicException if the context is not supported
*/
private function checkContext($context)
{
if ($context !== 'person') {
throw new \LogicException("The context '$context' is not "
if ('person' !== $context) {
throw new LogicException("The context '{$context}' is not "
. "supported. Currently only 'person' is supported");
}
}
private function getFromClause(
ClassMetadata $metadataActivity,
ClassMetadata $metadataPerson
) {
$associationMapping = $metadataActivity->getAssociationMapping('person');
return $metadataActivity->getTableName() . ' JOIN '
. $metadataPerson->getTableName() . ' ON '
. $metadataPerson->getTableName() . '.' .
$associationMapping['joinColumns'][0]['referencedColumnName']
. ' = '
. $associationMapping['joinColumns'][0]['name'];
}
private function getWhereClause(
ClassMetadata $metadataActivity,
ClassMetadata $metadataPerson,
Person $person
) {
$role = new Role('CHILL_ACTIVITY_SEE');
$reachableCenters = $this->helper->getReachableCenters(
$this->user,
$role
);
$associationMapping = $metadataActivity->getAssociationMapping('person');
if (count($reachableCenters) === 0) {
return 'FALSE = TRUE';
}
// we start with activities having the person_id linked to person
// (currently only context "person" is supported)
$whereClause = sprintf(
'%s = %d',
$associationMapping['joinColumns'][0]['name'],
$person->getId()
);
// we add acl (reachable center and scopes)
$centerAndScopeLines = [];
foreach ($reachableCenters as $center) {
$reachablesScopesId = array_map(
function (Scope $scope) {
return $scope->getId();
},
$this->helper->getReachableScopes(
$this->user,
$role,
$person->getCenter()
)
);
$centerAndScopeLines[] = sprintf(
'(%s = %d AND %s IN (%s))',
$metadataPerson->getTableName() . '.' .
$metadataPerson->getAssociationMapping('center')['joinColumns'][0]['name'],
$center->getId(),
$metadataActivity->getTableName() . '.' .
$metadataActivity->getAssociationMapping('scope')['joinColumns'][0]['name'],
implode(',', $reachablesScopesId)
);
}
$whereClause .= ' AND (' . implode(' OR ', $centerAndScopeLines) . ')';
return $whereClause;
}
}

View File

@ -1,38 +1,40 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\Migrations\Activity;
use Doctrine\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
class Version20150701091248 extends AbstractMigration
{
/**
* @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');
}
public function up(Schema $schema): void
{
// 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 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
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\Migrations\Activity;
use Doctrine\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
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
{
// 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 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
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\Migrations\Activity;
use Doctrine\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Db Migration
*
* Db Migration.
*/
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
{
// 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 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
/**
* 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;
use Doctrine\Migrations\AbstractMigration;
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
* migration, the relation will be manyToMany.
*/
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
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql',
'Migration can only be executed safely on \'postgresql\'.');
$this->abortIf(
$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 CONSTRAINT '
@ -63,17 +34,49 @@ class Version20160222103457 extends AbstractMigration
$this->addSql('CREATE INDEX idx_55026b0c59bb1592 ON Activity (reason_id)');
// try to keep at least on activity reason...
$this->addSql('UPDATE activity
$this->addSql(
'UPDATE activity
SET reason_id=rid
FROM (
SELECT activity_id AS aid, MIN(activityreason_id) AS rid
FROM activity_activityreason
GROUP BY activity_id ) AS sb
WHERE sb.aid = activity.id'
);
);
$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
/**
* 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;
use Doctrine\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Types\Type;
use Doctrine\Migrations\AbstractMigration;
/**
* Add an "active" column on activitytype table
* Add an "active" column on activitytype table.
*/
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
{
$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
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Chill\Migrations\Activity;
@ -12,20 +19,7 @@ use Doctrine\Migrations\AbstractMigration;
*/
final class Version20210304154629 extends AbstractMigration
{
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');
}
public function down(Schema $schema) : void
public function down(Schema $schema): void
{
// 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_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
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Chill\Migrations\Activity;
@ -12,21 +19,20 @@ use Doctrine\Migrations\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 '';
}
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->addSql('UPDATE activity SET comment_comment = 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,22 +1,22 @@
<?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\AMLI\BudgetBundle\Calculator;
use Chill\AMLI\BudgetBundle\Entity\AbstractElement;
/**
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
interface CalculatorInterface
{
/**
*
* @param AbstractElement[] $elements
*/
public function calculate(array $elements) : ?CalculatorResult;
public function calculate(array $elements): ?CalculatorResult;
public function getAlias();
}

View File

@ -1,67 +1,72 @@
<?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\AMLI\BudgetBundle\Calculator;
use Chill\AMLI\BudgetBundle\Entity\AbstractElement;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
use OutOfBoundsException;
use function array_key_exists;
use function array_keys;
use function implode;
class CalculatorManager
{
/**
*
* @var CalculatorInterface[]
*/
protected $calculators = [];
protected $defaultCalculator = [];
public function addCalculator(CalculatorInterface $calculator, bool $default)
{
$this->calculators[$calculator::getAlias()] = $calculator;
if ($default) {
$this->defaultCalculator[] = $calculator::getAlias();
}
}
/**
*
* @param string $alias
* @return CalculatorInterface
*/
public function getCalculator($alias)
{
if (FALSE === \array_key_exists($alias, $this->calculators)) {
throw new \OutOfBoundsException("The calculator with alias '$alias' does "
. "not exists. Possible values are ". \implode(", ", \array_keys($this->calculators)));
}
return $this->calculators[$alias];
}
/**
*
* @param AbstractElement[] $elements
*
* @return CalculatorResult[]
*/
public function calculateDefault(array $elements)
{
$results = [];
foreach ($this->defaultCalculator as $alias) {
$calculator = $this->calculators[$alias];
$result = $calculator->calculate($elements);
if ($result !== null) {
if (null !== $result) {
$results[$calculator::getAlias()] = $result;
}
}
return $results;
}
/**
* @param string $alias
*
* @return CalculatorInterface
*/
public function getCalculator($alias)
{
if (false === array_key_exists($alias, $this->calculators)) {
throw new OutOfBoundsException("The calculator with alias '{$alias}' does "
. 'not exists. Possible values are ' . implode(', ', array_keys($this->calculators)));
}
return $this->calculators[$alias];
}
}

View File

@ -1,23 +1,25 @@
<?php
/*
*
*/
namespace Chill\AMLI\BudgetBundle\Calculator;
/**
*
* Chill is a software for social workers
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Calculator;
class CalculatorResult
{
const TYPE_RATE = 'rate';
const TYPE_CURRENCY = 'currency';
const TYPE_PERCENTAGE = 'percentage';
public $type;
public $result;
public const TYPE_CURRENCY = 'currency';
public const TYPE_PERCENTAGE = 'percentage';
public const TYPE_RATE = 'rate';
public $label;
public $result;
public $type;
}

View File

@ -1,16 +1,23 @@
<?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\AMLI\BudgetBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Chill\AMLI\BudgetBundle\DependencyInjection\Compiler\CalculatorCompilerPass;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class ChillAMLIBudgetBundle extends Bundle
{
public function build(\Symfony\Component\DependencyInjection\ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new CalculatorCompilerPass());
}
}

View File

@ -1,72 +1,68 @@
<?php
/*
*/
namespace Chill\AMLI\BudgetBundle\Config;
/**
*
* Chill is a software for social workers
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Config;
class ConfigRepository
{
/**
*
* @var array
*/
protected $resources;
/**
*
* @var array
*/
protected $charges;
/**
* @var array
*/
protected $resources;
public function __construct($resources, $charges)
{
$this->resources = $resources;
$this->charges = $charges;
}
/**
*
* @return array where keys are the resource'key and label the ressource label
*/
public function getResourcesLabels()
{
$resources = array();
foreach ($this->resources as $definition) {
$resources[$definition['key']] = $this->normalizeLabel($definition['labels']);
}
return $resources;
}
/**
*
* @return array where keys are the resource'key and label the ressource label
*/
public function getChargesLabels()
{
$charges = array();
$charges = [];
foreach ($this->charges as $definition) {
$charges[$definition['key']] = $this->normalizeLabel($definition['labels']);
}
return $charges;
}
private function normalizeLabel($labels)
/**
* @return array where keys are the resource'key and label the ressource label
*/
public function getResourcesLabels()
{
$normalizedLabels = array();
$resources = [];
foreach ($this->resources as $definition) {
$resources[$definition['key']] = $this->normalizeLabel($definition['labels']);
}
return $resources;
}
private function normalizeLabel($labels)
{
$normalizedLabels = [];
foreach ($labels as $labelDefinition) {
$normalizedLabels[$labelDefinition['lang']] = $labelDefinition['label'];
}
return $normalizedLabels;
}
}

View File

@ -1,38 +1,42 @@
<?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\AMLI\BudgetBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Chill\PersonBundle\Entity\Person;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\EntityManagerInterface;
use Chill\AMLI\BudgetBundle\Entity\AbstractElement;
use Chill\AMLI\BudgetBundle\Security\Authorization\BudgetElementVoter;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Translation\TranslatorInterface;
use Chill\PersonBundle\Entity\Person;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Translation\TranslatorInterface;
abstract class AbstractElementController extends Controller
{
/**
*
* @var EntityManagerInterface
*/
protected $em;
/**
*
* @var TranslatorInterface
*/
protected $translator;
/**
*
* @var LoggerInterface
*/
protected $chillMainLogger;
/**
* @var EntityManagerInterface
*/
protected $em;
/**
* @var TranslatorInterface
*/
protected $translator;
public function __construct(
EntityManagerInterface $em,
TranslatorInterface $translator,
@ -44,94 +48,14 @@ abstract class AbstractElementController extends Controller
}
/**
* @return AbstractElement the newly created element
*/
abstract protected function createNewElement();
abstract protected function getType();
/**
*
*/
protected function _new(Person $person, Request $request, $template, $flashMessageOnSuccess)
{
/* @var $element \Chill\AMLI\BudgetBundle\Entity\AbstractElement */
$element = $this->createNewElement()
->setPerson($person)
;
$this->denyAccessUnlessGranted(BudgetElementVoter::CREATE, $element);
$form = $this->createForm($this->getType(), $element);
$form->add('submit', SubmitType::class);
$form->handleRequest($request);
if ($form->isSubmitted() and $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($element);
$em->flush();
$this->addFlash('success', $this->translator->trans($flashMessageOnSuccess));
return $this->redirectToRoute('chill_budget_elements_index', [
'id' => $person->getId()
]);
} elseif ($form->isSubmitted()) {
$this->addFlash('error', $this->translator->trans('This form contains errors'));
}
return $this->render($template, array(
'form' => $form->createView(),
'person' => $person,
'element' => $element
));
}
/**
*
* @param AbstractElement $element
* @param Request $request
* @param string $template
* @param string $flashOnSuccess
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function _edit(AbstractElement $element, Request $request, $template, $flashOnSuccess)
{
$this->denyAccessUnlessGranted(BudgetElementVoter::UPDATE, $element);
$form = $this->createForm($this->getType(), $element);
$form->add('submit', SubmitType::class);
$form->handleRequest($request);
if ($form->isSubmitted() and $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->flush();
$this->addFlash('success', $this->translator->trans($flashOnSuccess));
return $this->redirectToRoute('chill_budget_elements_index', [
'id' => $element->getPerson()->getId()
]);
}
return $this->render($template, array(
'element' => $element,
'form' => $form->createView(),
'person' => $element->getPerson()
));
}
/**
*
* Route(
* "{_locale}/family-members/family-members/{id}/delete",
* name="chill_family_members_family_members_delete"
* )
*
* @param AbstractElement $element
* @param Request $request
* ).
*
* @param mixed $template
* @param mixed $flashMessage
*
* @return \Symfony\Component\BrowserKit\Response
*/
protected function _delete(AbstractElement $element, Request $request, $template, $flashMessage)
@ -145,63 +69,140 @@ abstract class AbstractElementController extends Controller
$form->handleRequest($request);
if ($form->isValid()) {
$this->chillMainLogger->notice("A budget element has been removed", array(
'family_element' => get_class($element),
'by_user' => $this->getUser()->getUsername(),
'family_member_id' => $element->getId(),
'amount' => $element->getAmount(),
'type' => $element->getType()
));
$this->chillMainLogger->notice('A budget element has been removed', [
'family_element' => get_class($element),
'by_user' => $this->getUser()->getUsername(),
'family_member_id' => $element->getId(),
'amount' => $element->getAmount(),
'type' => $element->getType(),
]);
$em = $this->getDoctrine()->getManager();
$em->remove($element);
$em->flush();
$this->addFlash('success', $this->translator
->trans($flashMessage));
->trans($flashMessage));
return $this->redirectToRoute('chill_budget_elements_index', array(
'id' => $element->getPerson()->getId()
));
return $this->redirectToRoute('chill_budget_elements_index', [
'id' => $element->getPerson()->getId(),
]);
}
}
return $this->render($template, array(
'element' => $element,
'delete_form' => $form->createView()
));
return $this->render($template, [
'element' => $element,
'delete_form' => $form->createView(),
]);
}
/**
* @param string $template
* @param string $flashOnSuccess
*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function _edit(AbstractElement $element, Request $request, $template, $flashOnSuccess)
{
$this->denyAccessUnlessGranted(BudgetElementVoter::UPDATE, $element);
$form = $this->createForm($this->getType(), $element);
$form->add('submit', SubmitType::class);
$form->handleRequest($request);
if ($form->isSubmitted() and $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->flush();
$this->addFlash('success', $this->translator->trans($flashOnSuccess));
return $this->redirectToRoute('chill_budget_elements_index', [
'id' => $element->getPerson()->getId(),
]);
}
return $this->render($template, [
'element' => $element,
'form' => $form->createView(),
'person' => $element->getPerson(),
]);
}
/**
* @param mixed $template
* @param mixed $flashMessageOnSuccess
*/
protected function _new(Person $person, Request $request, $template, $flashMessageOnSuccess)
{
/* @var $element \Chill\AMLI\BudgetBundle\Entity\AbstractElement */
$element = $this->createNewElement()
->setPerson($person);
$this->denyAccessUnlessGranted(BudgetElementVoter::CREATE, $element);
$form = $this->createForm($this->getType(), $element);
$form->add('submit', SubmitType::class);
$form->handleRequest($request);
if ($form->isSubmitted() and $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($element);
$em->flush();
$this->addFlash('success', $this->translator->trans($flashMessageOnSuccess));
return $this->redirectToRoute('chill_budget_elements_index', [
'id' => $person->getId(),
]);
}
if ($form->isSubmitted()) {
$this->addFlash('error', $this->translator->trans('This form contains errors'));
}
return $this->render($template, [
'form' => $form->createView(),
'person' => $person,
'element' => $element,
]);
}
/**
* Route(
* "{_locale}/family-members/family-members/{id}/view",
* name="chill_family_members_family_members_view"
* )
* ).
*
* @param mixed $template
*/
protected function _view(AbstractElement $element, $template)
{
$this->denyAccessUnlessGranted(BudgetElementVoter::SHOW, $element);
return $this->render($template, array(
'element' => $element
));
return $this->render($template, [
'element' => $element,
]);
}
/**
* @return AbstractElement the newly created element
*/
abstract protected function createNewElement();
abstract protected function getType();
/**
* Creates a form to delete a help request entity by id.
*
* @param mixed $id The entity id
*
* @return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm()
{
return $this->createFormBuilder()
->setMethod(Request::METHOD_DELETE)
->add('submit', SubmitType::class, array('label' => 'Delete'))
->getForm()
;
->add('submit', SubmitType::class, ['label' => 'Delete'])
->getForm();
}
}

View File

@ -1,102 +1,96 @@
<?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\AMLI\BudgetBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Chill\AMLI\BudgetBundle\Controller\AbstractElementController;
use Chill\AMLI\BudgetBundle\Entity\Charge;
use Chill\AMLI\BudgetBundle\Form\ChargeType;
use Chill\PersonBundle\Entity\Person;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ChargeController extends AbstractElementController
{
protected function getType()
{
return ChargeType::class;
}
protected function createNewElement()
{
return new Charge();
}
/**
*
* @Route(
* "{_locale}/budget/charge/{id}/view",
* name="chill_budget_charge_view"
* "{_locale}/budget/charge/{id}/delete",
* name="chill_budget_charge_delete"
* )
* @param Charge $charge
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function deleteAction(Request $request, Charge $charge)
{
return $this->_delete(
$charge,
$request,
'@ChillAMLIBudget/Charge/confirm_delete.html.twig',
'Charge deleted'
);
}
/**
* @Route(
* "{_locale}/budget/charge/{id}/edit",
* name="chill_budget_charge_edit"
* )
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function editAction(Request $request, Charge $charge)
{
return $this->_edit(
$charge,
$request,
'@ChillAMLIBudget/Charge/edit.html.twig',
'Charge updated'
);
}
/**
* @Route(
* "{_locale}/budget/charge/by-person/{id}/new",
* name="chill_budget_charge_new"
* )
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function newAction(Request $request, Person $person)
{
return $this->_new(
$person,
$request,
'@ChillAMLIBudget/Charge/new.html.twig',
'Charge created'
);
}
/**
* @Route(
* "{_locale}/budget/charge/{id}/view",
* name="chill_budget_charge_view"
* )
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function viewAction(Charge $charge)
{
return $this->_view($charge, '@ChillAMLIBudget/Charge/view.html.twig');
}
/**
* @Route(
* "{_locale}/budget/charge/by-person/{id}/new",
* name="chill_budget_charge_new"
* )
*
* @param Request $request
* @param Person $person
* @return \Symfony\Component\HttpFoundation\Response
*/
public function newAction(Request $request, Person $person)
protected function createNewElement()
{
return $this->_new(
$person,
$request,
'@ChillAMLIBudget/Charge/new.html.twig',
'Charge created');
return new Charge();
}
/**
* @Route(
* "{_locale}/budget/charge/{id}/edit",
* name="chill_budget_charge_edit"
* )
*
* @param Request $request
* @param Charge $charge
* @return \Symfony\Component\HttpFoundation\Response
*/
public function editAction(Request $request, Charge $charge)
protected function getType()
{
return $this->_edit(
$charge,
$request,
'@ChillAMLIBudget/Charge/edit.html.twig',
'Charge updated');
}
/**
*
* @Route(
* "{_locale}/budget/charge/{id}/delete",
* name="chill_budget_charge_delete"
* )
*
* @param Request $request
* @param Charge $charge
* @return \Symfony\Component\HttpFoundation\Response
*/
public function deleteAction(Request $request, Charge $charge)
{
return $this->_delete(
$charge,
$request,
'@ChillAMLIBudget/Charge/confirm_delete.html.twig',
'Charge deleted');
return ChargeType::class;
}
}

View File

@ -1,46 +1,50 @@
<?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\AMLI\BudgetBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Chill\PersonBundle\Entity\Person;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Translation\TranslatorInterface;
use Psr\Log\LoggerInterface;
use Chill\AMLI\BudgetBundle\Calculator\CalculatorManager;
use Chill\AMLI\BudgetBundle\Entity\Charge;
use Chill\AMLI\BudgetBundle\Entity\Resource;
use Chill\AMLI\BudgetBundle\Security\Authorization\BudgetElementVoter;
use Chill\AMLI\BudgetBundle\Calculator\CalculatorManager;
use Chill\PersonBundle\Entity\Person;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Translation\TranslatorInterface;
use function array_merge;
class ElementController extends Controller
{
/**
*
* @var EntityManagerInterface
*/
protected $em;
/**
*
* @var TranslatorInterface
*/
protected $translator;
/**
*
* @var LoggerInterface
*/
protected $chillMainLogger;
/**
*
* @var CalculatorManager
*/
protected $calculator;
/**
* @var LoggerInterface
*/
protected $chillMainLogger;
/**
* @var EntityManagerInterface
*/
protected $em;
/**
* @var TranslatorInterface
*/
protected $translator;
public function __construct(
EntityManagerInterface $em,
TranslatorInterface $translator,
@ -52,45 +56,44 @@ class ElementController extends Controller
$this->chillMainLogger = $chillMainLogger;
$this->calculator = $calculator;
}
/**
* @Route(
* "{_locale}/budget/elements/by-person/{id}",
* name="chill_budget_elements_index"
* "{_locale}/budget/elements/by-person/{id}",
* name="chill_budget_elements_index"
* )
*/
public function indexAction(Person $person)
{
$this->denyAccessUnlessGranted(BudgetElementVoter::SHOW, $person);
$charges = $this->em
->getRepository(Charge::class)
->findByPerson($person);
$ressources = $this->em
->getRepository(Resource::class)
->findByPerson($person);
$now = new \DateTime('now');
$now = new DateTime('now');
$actualCharges = $this->em
->getRepository(Charge::class)
->findByPersonAndDate($person, $now);
$actualResources = $this->em
->getRepository(Resource::class)
->findByPersonAndDate($person, $now);
$elements = \array_merge($actualCharges, $actualResources);
$elements = array_merge($actualCharges, $actualResources);
if (count($elements) > 0) {
$results = $this->calculator->calculateDefault($elements);
}
return $this->render('ChillAMLIBudgetBundle:Element:index.html.twig', array(
return $this->render('ChillAMLIBudgetBundle:Element:index.html.twig', [
'person' => $person,
'charges' => $charges,
'resources' => $ressources,
'results' => $results ?? []
));
'results' => $results ?? [],
]);
}
}

View File

@ -1,103 +1,96 @@
<?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\AMLI\BudgetBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Chill\AMLI\BudgetBundle\Controller\AbstractElementController;
use Chill\AMLI\BudgetBundle\Entity\Resource;
use Chill\AMLI\BudgetBundle\Form\ResourceType;
use Chill\PersonBundle\Entity\Person;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ResourceController extends AbstractElementController
{
protected function getType()
{
return ResourceType::class;
}
protected function createNewElement()
{
return new Resource();
}
/**
*
* @Route(
* "{_locale}/budget/resource/{id}/view",
* name="chill_budget_resource_view"
* "{_locale}/budget/resource/{id}/delete",
* name="chill_budget_resource_delete"
* )
* @param Request $request
* @param Resource $resource
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function deleteAction(Request $request, Resource $resource)
{
return $this->_delete(
$resource,
$request,
'@ChillAMLIBudget/Resource/confirm_delete.html.twig',
'Resource deleted'
);
}
/**
* @Route(
* "{_locale}/budget/resource/{id}/edit",
* name="chill_budget_resource_edit"
* )
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function editAction(Request $request, Resource $resource)
{
return $this->_edit(
$resource,
$request,
'@ChillAMLIBudget/Resource/edit.html.twig',
'Resource updated'
);
}
/**
* @Route(
* "{_locale}/budget/resource/by-person/{id}/new",
* name="chill_budget_resource_new"
* )
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function newAction(Request $request, Person $person)
{
return $this->_new(
$person,
$request,
'@ChillAMLIBudget/Resource/new.html.twig',
'Resource created'
);
}
/**
* @Route(
* "{_locale}/budget/resource/{id}/view",
* name="chill_budget_resource_view"
* )
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function viewAction(Resource $resource)
{
return $this->_view($resource, '@ChillAMLIBudget/Resource/view.html.twig');
}
/**
* @Route(
* "{_locale}/budget/resource/by-person/{id}/new",
* name="chill_budget_resource_new"
* )
*
* @param Request $request
* @param Person $person
* @return \Symfony\Component\HttpFoundation\Response
*/
public function newAction(Request $request, Person $person)
protected function createNewElement()
{
return $this->_new(
$person,
$request,
'@ChillAMLIBudget/Resource/new.html.twig',
'Resource created');
return new Resource();
}
/**
* @Route(
* "{_locale}/budget/resource/{id}/edit",
* name="chill_budget_resource_edit"
* )
*
* @param Request $request
* @param Resource $resource
* @return \Symfony\Component\HttpFoundation\Response
*/
public function editAction(Request $request, Resource $resource)
protected function getType()
{
return $this->_edit(
$resource,
$request,
'@ChillAMLIBudget/Resource/edit.html.twig',
'Resource updated');
}
/**
*
* @Route(
* "{_locale}/budget/resource/{id}/delete",
* name="chill_budget_resource_delete"
* )
*
* @param Request $request
* @param Resource $resource
* @return \Symfony\Component\HttpFoundation\Response
*/
public function deleteAction(Request $request, Resource $resource)
{
return $this->_delete($resource,
$request,
'@ChillAMLIBudget/Resource/confirm_delete.html.twig',
'Resource deleted');
return ResourceType::class;
}
}

View File

@ -1,30 +1,34 @@
<?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\AMLI\BudgetBundle\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\AMLI\BudgetBundle\Security\Authorization\BudgetElementVoter;
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.
*
* @link http://symfony.com/doc/current/cookbook/bundles/extension.html
* @see http://symfony.com/doc/current/cookbook/bundles/extension.html
*/
class ChillAMLIBudgetExtension extends Extension implements PrependExtensionInterface
{
/**
* {@inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config'));
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../config'));
$loader->load('services/config.yaml');
$loader->load('services/form.yaml');
$loader->load('services/security.yaml');
@ -32,7 +36,7 @@ class ChillAMLIBudgetExtension extends Extension implements PrependExtensionInte
$loader->load('services/templating.yaml');
$loader->load('services/menu.yaml');
$loader->load('services/calculator.yaml');
$this->storeConfig('resources', $config, $container);
$this->storeConfig('charges', $config, $container);
}
@ -42,36 +46,35 @@ class ChillAMLIBudgetExtension extends Extension implements PrependExtensionInte
$this->prependAuthorization($container);
$this->prependRoutes($container);
}
protected function storeConfig($position, array $config, ContainerBuilder $container)
/* (non-PHPdoc)
* @see \Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface::prepend()
*/
public function prependRoutes(ContainerBuilder $container)
{
$container
->setParameter(sprintf('chill_budget.%s', $position), $config[$position])
;
//add routes for custom bundle
$container->prependExtensionConfig('chill_main', [
'routing' => [
'resources' => [
'@ChillAMLIBudgetBundle/config/routing.yaml',
],
],
]);
}
protected function prependAuthorization(ContainerBuilder $container)
{
$container->prependExtensionConfig('security', array(
'role_hierarchy' => array(
BudgetElementVoter::UPDATE => [ BudgetElementVoter::SHOW ],
BudgetElementVoter::CREATE => [ BudgetElementVoter::SHOW ]
)
));
$container->prependExtensionConfig('security', [
'role_hierarchy' => [
BudgetElementVoter::UPDATE => [BudgetElementVoter::SHOW],
BudgetElementVoter::CREATE => [BudgetElementVoter::SHOW],
],
]);
}
/* (non-PHPdoc)
* @see \Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface::prepend()
*/
public function prependRoutes(ContainerBuilder $container)
protected function storeConfig($position, array $config, ContainerBuilder $container)
{
//add routes for custom bundle
$container->prependExtensionConfig('chill_main', array(
'routing' => array(
'resources' => array(
'@ChillAMLIBudgetBundle/config/routing.yaml'
)
)
));
$container
->setParameter(sprintf('chill_budget.%s', $position), $config[$position]);
}
}

View File

@ -1,29 +1,29 @@
<?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\AMLI\BudgetBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class CalculatorCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$manager = $container->getDefinition('Chill\AMLI\BudgetBundle\Calculator\CalculatorManager');
foreach ($container->findTaggedServiceIds('chill_budget.calculator') as $id => $tags) {
foreach($tags as $tag) {
foreach ($tags as $tag) {
$reference = new Reference($id);
$manager->addMethodCall('addCalculator', [ $reference, $tag['default'] ?? false ]);
$manager->addMethodCall('addCalculator', [$reference, $tag['default'] ?? false]);
}
}
}

View File

@ -1,5 +1,12 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
@ -12,66 +19,61 @@ use Symfony\Component\Config\Definition\ConfigurationInterface;
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritdoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder('chill_amli_budget');
$rootNode = $treeBuilder->getRootNode('chill_amli_budget');
$rootNode
->children()
// ressources
->arrayNode('resources')->isRequired()->requiresAtLeastOneElement()
->arrayPrototype()
->children()
->scalarNode('key')->isRequired()->cannotBeEmpty()
->info('the key stored in database')
->example('salary')
->end()
->arrayNode('labels')->isRequired()->requiresAtLeastOneElement()
->arrayPrototype()
->children()
->scalarNode('lang')->isRequired()->cannotBeEmpty()
->example('fr')
->end()
->scalarNode('label')->isRequired()->cannotBeEmpty()
->example('Salaire')
->end()
->end()
->end()
->end()
->end()
->end()
->end()
->arrayNode('charges')->isRequired()->requiresAtLeastOneElement()
->arrayPrototype()
->children()
->scalarNode('key')->isRequired()->cannotBeEmpty()
->info('the key stored in database')
->example('salary')
->end()
->arrayNode('labels')->isRequired()->requiresAtLeastOneElement()
->arrayPrototype()
->children()
->scalarNode('lang')->isRequired()->cannotBeEmpty()
->example('fr')
->end()
->scalarNode('label')->isRequired()->cannotBeEmpty()
->example('Salaire')
->end()
->end()
->end()
->end()
->end()
->end()
->end()
->arrayNode('resources')->isRequired()->requiresAtLeastOneElement()
->arrayPrototype()
->children()
->scalarNode('key')->isRequired()->cannotBeEmpty()
->info('the key stored in database')
->example('salary')
->end()
;
->arrayNode('labels')->isRequired()->requiresAtLeastOneElement()
->arrayPrototype()
->children()
->scalarNode('lang')->isRequired()->cannotBeEmpty()
->example('fr')
->end()
->scalarNode('label')->isRequired()->cannotBeEmpty()
->example('Salaire')
->end()
->end()
->end()
->end()
->end()
->end()
->end()
->arrayNode('charges')->isRequired()->requiresAtLeastOneElement()
->arrayPrototype()
->children()
->scalarNode('key')->isRequired()->cannotBeEmpty()
->info('the key stored in database')
->example('salary')
->end()
->arrayNode('labels')->isRequired()->requiresAtLeastOneElement()
->arrayPrototype()
->children()
->scalarNode('lang')->isRequired()->cannotBeEmpty()
->example('fr')
->end()
->scalarNode('label')->isRequired()->cannotBeEmpty()
->example('Salaire')
->end()
->end()
->end()
->end()
->end()
->end()
->end()
->end();
return $treeBuilder;
}

View File

@ -1,46 +1,38 @@
<?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\AMLI\BudgetBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Chill\PersonBundle\Entity\Person;
use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* AbstractElement
* AbstractElement.
*
* @ORM\MappedSuperclass()
* @ORM\MappedSuperclass
*/
abstract class AbstractElement
{
/**
*
* @var Person
* @ORM\ManyToOne(
* targetEntity="\Chill\PersonBundle\Entity\Person"
* )
*/
private $person;
/**
* @var string
*
* @ORM\Column(name="type", type="string", length=255)
*/
private $type;
/**
* @var decimal
*
* @ORM\Column(name="amount", type="decimal", precision=10, scale=2)
* @Assert\GreaterThan(
* value=0
* value=0
* )
* @Assert\NotNull(
* message="The amount cannot be empty"
* message="The amount cannot be empty"
* )
*
*/
private $amount;
@ -52,52 +44,82 @@ abstract class AbstractElement
private $comment;
/**
* @var \DateTimeImmutable
* @var DateTimeImmutable|null
*
* @ORM\Column(name="endDate", type="datetime_immutable", nullable=true)
* @Assert\GreaterThan(
* propertyPath="startDate",
* message="The budget element's end date must be after the start date"
* )
*/
private $endDate;
/**
* @var Person
* @ORM\ManyToOne(
* targetEntity="\Chill\PersonBundle\Entity\Person"
* )
*/
private $person;
/**
* @var DateTimeImmutable
*
* @ORM\Column(name="startDate", type="datetime_immutable")
* @Assert\Date()
* @Assert\Date
*/
private $startDate;
/**
* @var \DateTimeImmutable|null
* @var string
*
* @ORM\Column(name="endDate", type="datetime_immutable", nullable=true)
* @Assert\GreaterThan(
* propertyPath="startDate",
* message="The budget element's end date must be after the start date"
* )
* @ORM\Column(name="type", type="string", length=255)
*/
private $endDate;
abstract public function isCharge(): bool;
abstract public function isResource(): bool;
private $type;
/**
* Get amount.
*
* @return float
*/
public function getAmount()
{
return (float) $this->amount;
}
/**
* Get comment.
*
* @return string|null
*/
public function getComment()
{
return $this->comment;
}
/**
* Get endDate.
*
* @return DateTimeImmutable|null
*/
public function getEndDate()
{
return $this->endDate;
}
public function getPerson(): Person
{
return $this->person;
}
public function setPerson(Person $person)
{
$this->person = $person;
return $this;
}
/**
* Set type.
* Get startDate.
*
* @param string $type
*
* @return AbstractElement
* @return DateTimeImmutable
*/
public function setType($type)
public function getStartDate()
{
$this->type = $type;
return $this;
return $this->startDate;
}
/**
@ -110,6 +132,15 @@ abstract class AbstractElement
return $this->type;
}
abstract public function isCharge(): bool;
public function isEmpty()
{
return 0 == $this->amount;
}
abstract public function isResource(): bool;
/**
* Set amount.
*
@ -124,16 +155,6 @@ abstract class AbstractElement
return $this;
}
/**
* Get amount.
*
* @return double
*/
public function getAmount()
{
return (double) $this->amount;
}
/**
* Set comment.
*
@ -149,27 +170,40 @@ abstract class AbstractElement
}
/**
* Get comment.
* Set endDate.
*
* @return string|null
* @return AbstractElement
*/
public function getComment()
public function setEndDate(?DateTimeInterface $endDate = null)
{
return $this->comment;
if ($endDate instanceof DateTime) {
$this->endDate = DateTimeImmutable::createFromMutable($endDate);
} elseif (null === $endDate) {
$this->endDate = null;
} else {
$this->endDate = $endDate;
}
return $this;
}
public function setPerson(Person $person)
{
$this->person = $person;
return $this;
}
/**
* Set startDate.
*
* @param \DateTimeInterface $startDate
*
* @return AbstractElement
*/
public function setStartDate(\DateTimeInterface $startDate)
public function setStartDate(DateTimeInterface $startDate)
{
if ($startDate instanceof \DateTime) {
$this->startDate = \DateTimeImmutable::createFromMutable($startDate);
} elseif (NULL === $startDate) {
if ($startDate instanceof DateTime) {
$this->startDate = DateTimeImmutable::createFromMutable($startDate);
} elseif (null === $startDate) {
$this->startDate = null;
} else {
$this->startDate = $startDate;
@ -179,47 +213,16 @@ abstract class AbstractElement
}
/**
* Get startDate.
* Set type.
*
* @return \DateTimeImmutable
*/
public function getStartDate()
{
return $this->startDate;
}
/**
* Set endDate.
*
* @param \DateTimeInterface|null $endDate
* @param string $type
*
* @return AbstractElement
*/
public function setEndDate(\DateTimeInterface $endDate = null)
public function setType($type)
{
if ($endDate instanceof \DateTime) {
$this->endDate = \DateTimeImmutable::createFromMutable($endDate);
} elseif (NULL === $endDate) {
$this->endDate = null;
} else {
$this->endDate = $endDate;
}
$this->type = $type;
return $this;
}
/**
* Get endDate.
*
* @return \DateTimeImmutable|null
*/
public function getEndDate()
{
return $this->endDate;
}
public function isEmpty()
{
return $this->amount == 0;
}
}

View File

@ -1,18 +1,47 @@
<?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\AMLI\BudgetBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Chill\MainBundle\Entity\HasCenterInterface;
use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM;
/**
* Charge
* Charge.
*
* @ORM\Table(name="chill_budget.charge")
* @ORM\Entity(repositoryClass="Chill\AMLI\BudgetBundle\Repository\ChargeRepository")
*/
class Charge extends AbstractElement implements HasCenterInterface
{
public const HELP_ASKED = 'running';
public const HELP_NO = 'no';
public const HELP_NOT_RELEVANT = 'not-relevant';
public const HELP_YES = 'yes';
public const HELPS = [
self::HELP_ASKED,
self::HELP_NO,
self::HELP_YES,
self::HELP_NOT_RELEVANT,
];
/**
* @var string
* @ORM\Column(name="help", type="string", nullable=true)
*/
private $help = self::HELP_NOT_RELEVANT;
/**
* @var int
*
@ -21,30 +50,20 @@ class Charge extends AbstractElement implements HasCenterInterface
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* @var string
* @ORM\Column(name="help", type="string", nullable=true)
*/
private $help = self::HELP_NOT_RELEVANT;
const HELP_ASKED = 'running';
const HELP_NO = 'no';
const HELP_YES = 'yes';
const HELP_NOT_RELEVANT = 'not-relevant';
const HELPS = [
self::HELP_ASKED,
self::HELP_NO,
self::HELP_YES,
self::HELP_NOT_RELEVANT
];
public function __construct()
{
$this->setStartDate(new \DateTimeImmutable('today'));
$this->setStartDate(new DateTimeImmutable('today'));
}
public function getCenter(): \Chill\MainBundle\Entity\Center
{
return $this->getPerson()->getCenter();
}
public function getHelp()
{
return $this->help;
}
/**
@ -56,23 +75,6 @@ class Charge extends AbstractElement implements HasCenterInterface
{
return $this->id;
}
public function getHelp()
{
return $this->help;
}
public function setHelp($help)
{
$this->help = $help;
return $this;
}
public function getCenter(): \Chill\MainBundle\Entity\Center
{
return $this->getPerson()->getCenter();
}
public function isCharge(): bool
{
@ -83,4 +85,11 @@ class Charge extends AbstractElement implements HasCenterInterface
{
return false;
}
public function setHelp($help)
{
$this->help = $help;
return $this;
}
}

View File

@ -1,12 +1,20 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Chill\MainBundle\Entity\HasCenterInterface;
use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM;
/**
* Resource
* Resource.
*
* @ORM\Table(name="chill_budget.resource")
* @ORM\Entity(repositoryClass="Chill\AMLI\BudgetBundle\Repository\ResourceRepository")
@ -21,13 +29,17 @@ class Resource extends AbstractElement implements HasCenterInterface
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
public function __construct()
{
$this->setStartDate(new \DateTimeImmutable('today'));
$this->setStartDate(new DateTimeImmutable('today'));
}
public function getCenter(): \Chill\MainBundle\Entity\Center
{
return $this->getPerson()->getCenter();
}
/**
* Get id.
*
@ -38,11 +50,6 @@ class Resource extends AbstractElement implements HasCenterInterface
return $this->id;
}
public function getCenter(): \Chill\MainBundle\Entity\Center
{
return $this->getPerson()->getCenter();
}
public function isCharge(): bool
{
return false;

View File

@ -1,124 +1,120 @@
<?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\AMLI\BudgetBundle\Form;
use Chill\AMLI\BudgetBundle\Config\ConfigRepository;
use Chill\AMLI\BudgetBundle\Entity\Charge;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\AMLI\BudgetBundle\Config\ConfigRepository;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\AMLI\BudgetBundle\Entity\Charge;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use function array_flip;
use function asort;
class ChargeType extends AbstractType
{
/**
*
/**
* @var ConfigRepository
*/
protected $configRepository;
/**
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
public function __construct(
ConfigRepository $configRepository,
ConfigRepository $configRepository,
TranslatableStringHelper $translatableStringHelper
) {
$this->configRepository = $configRepository;
$this->translatableStringHelper = $translatableStringHelper;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('type', ChoiceType::class, [
'choices' => $this->getTypes(),
'placeholder' => 'Choose a charge type'
'placeholder' => 'Choose a charge type',
])
->add('amount', MoneyType::class)
->add('comment', TextAreaType::class, [
'required' => false
])
;
'required' => false,
]);
if ($options['show_start_date']) {
$builder->add('startDate', ChillDateType::class, [
'label' => 'Start of validity period'
'label' => 'Start of validity period',
]);
}
if ($options['show_end_date']) {
$builder->add('endDate', ChillDateType::class, [
'required' => false,
'label' => 'End of validity period'
'label' => 'End of validity period',
]);
}
if ($options['show_help']) {
$builder->add('help', ChoiceType::class, [
'choices' => [
'charge.help.running' => Charge::HELP_ASKED,
'charge.help.no' => Charge::HELP_NO,
'charge.help.yes' => Charge::HELP_YES,
'charge.help.not-concerned' => Charge::HELP_NOT_RELEVANT
'charge.help.not-concerned' => Charge::HELP_NOT_RELEVANT,
],
'placeholder' => 'Choose a status',
'required' => false,
'label' => 'Help to pay charges'
'label' => 'Help to pay charges',
]);
}
}
private function getTypes()
{
$charges = $this->configRepository
->getChargesLabels();
// rewrite labels to filter in language
foreach ($charges as $key => $labels) {
$charges[$key] = $this->translatableStringHelper->localize($labels);
}
\asort($charges);
return \array_flip($charges);
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
$resolver->setDefaults([
'data_class' => 'Chill\AMLI\BudgetBundle\Entity\Charge',
'show_start_date' => true,
'show_end_date' => true,
'show_help' => true
));
'show_help' => true,
]);
$resolver
->setAllowedTypes('show_start_date', 'boolean')
->setAllowedTypes('show_end_date', 'boolean')
->setAllowedTypes('show_help', 'boolean')
;
->setAllowedTypes('show_help', 'boolean');
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'chill_amli_budgetbundle_charge';
}
private function getTypes()
{
$charges = $this->configRepository
->getChargesLabels();
// rewrite labels to filter in language
foreach ($charges as $key => $labels) {
$charges[$key] = $this->translatableStringHelper->localize($labels);
}
asort($charges);
return array_flip($charges);
}
}

View File

@ -1,108 +1,104 @@
<?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\AMLI\BudgetBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Chill\AMLI\BudgetBundle\Config\ConfigRepository;
use Chill\AMLI\BudgetBundle\Entity\Resource;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\AMLI\BudgetBundle\Config\ConfigRepository;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use function array_flip;
class ResourceType extends AbstractType
{
/**
*
* @var ConfigRepository
*/
protected $configRepository;
/**
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
public function __construct(
ConfigRepository $configRepository,
ConfigRepository $configRepository,
TranslatableStringHelper $translatableStringHelper
) {
$this->configRepository = $configRepository;
$this->translatableStringHelper = $translatableStringHelper;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('type', ChoiceType::class, [
'choices' => $this->getTypes(),
'placeholder' => 'Choose a resource type',
'label' => 'Resource element type'
'label' => 'Resource element type',
])
->add('amount', MoneyType::class)
->add('comment', TextAreaType::class, [
'required' => false
])
;
'required' => false,
]);
if ($options['show_start_date']) {
$builder->add('startDate', ChillDateType::class, [
'label' => 'Start of validity period'
'label' => 'Start of validity period',
]);
}
if ($options['show_end_date']) {
$builder->add('endDate', ChillDateType::class, [
'required' => false,
'label' => 'End of validity period'
'label' => 'End of validity period',
]);
}
}
private function getTypes()
{
$resources = $this->configRepository
->getResourcesLabels();
// rewrite labels to filter in language
foreach ($resources as $key => $labels) {
$resources[$key] = $this->translatableStringHelper->localize($labels);
}
asort($resources);
return \array_flip($resources);
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
$resolver->setDefaults([
'data_class' => Resource::class,
'show_start_date' => true,
'show_end_date' => true
));
'show_end_date' => true,
]);
$resolver
->setAllowedTypes('show_start_date', 'boolean')
->setAllowedTypes('show_end_date', 'boolean')
;
->setAllowedTypes('show_end_date', 'boolean');
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'chill_amli_budgetbundle_resource';
}
private function getTypes()
{
$resources = $this->configRepository
->getResourcesLabels();
// rewrite labels to filter in language
foreach ($resources as $key => $labels) {
$resources[$key] = $this->translatableStringHelper->localize($labels);
}
asort($resources);
return array_flip($resources);
}
}

View File

@ -1,60 +1,59 @@
<?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\AMLI\BudgetBundle\Menu;
use Chill\AMLI\BudgetBundle\Security\Authorization\BudgetElementVoter;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Knp\Menu\MenuItem;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Chill\AMLI\BudgetBundle\Security\Authorization\BudgetElementVoter;
use Symfony\Component\Translation\TranslatorInterface;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class UserMenuBuilder implements LocalMenuBuilderInterface
{
/**
*
* @var AuthorizationCheckerInterface
*/
protected $authorizationChecker;
/**
*
* @var TranslatorInterface
*/
protected $translator;
public function __construct(
AuthorizationCheckerInterface $authorizationChecker,
AuthorizationCheckerInterface $authorizationChecker,
TranslatorInterface $translator
) {
$this->authorizationChecker = $authorizationChecker;
$this->translator = $translator;
}
public function buildMenu($menuId, MenuItem $menu, array $parameters)
{
/* @var $person \Chill\PersonBundle\Entity\Person */
$person = $parameters['person'];
if ($this->authorizationChecker->isGranted(BudgetElementVoter::SHOW, $person)) {
$menu->addChild(
$this->translator->trans('Budget'), [
$this->translator->trans('Budget'),
[
'route' => 'chill_budget_elements_index',
'routeParameters' => [ 'id' => $person->getId() ],
])
->setExtra('order', 460)
;
'routeParameters' => ['id' => $person->getId()],
]
)
->setExtra('order', 460);
}
}
public static function getMenuIds(): array
{
return [ 'person' ];
return ['person'];
}
}

View File

@ -1,35 +1,42 @@
<?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\AMLI\BudgetBundle\Repository;
use Chill\PersonBundle\Entity\Person;
use DateTime;
/**
* ChargeRepository
* ChargeRepository.
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class ChargeRepository extends \Doctrine\ORM\EntityRepository
{
public function findByPersonAndDate(Person $person, \DateTime $date, $sort = null)
public function findByPersonAndDate(Person $person, DateTime $date, $sort = null)
{
$qb = $this->createQueryBuilder('c');
$qb->where('c.person = :person')
->andWhere('c.startDate < :date')
->andWhere('c.startDate < :date OR c.startDate IS NULL')
;
if ($sort !== null) {
->andWhere('c.startDate < :date OR c.startDate IS NULL');
if (null !== $sort) {
$qb->orderBy($sort);
}
$qb->setParameters([
'person' => $person,
'date' => $date
'date' => $date,
]);
return $qb->getQuery()->getResult();
}
}

View File

@ -1,35 +1,42 @@
<?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\AMLI\BudgetBundle\Repository;
use Chill\PersonBundle\Entity\Person;
use DateTime;
/**
* ResourceRepository
* ResourceRepository.
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class ResourceRepository extends \Doctrine\ORM\EntityRepository
{
public function findByPersonAndDate(Person $person, \DateTime $date, $sort = null)
public function findByPersonAndDate(Person $person, DateTime $date, $sort = null)
{
$qb = $this->createQueryBuilder('c');
$qb->where('c.person = :person')
->andWhere('c.startDate < :date')
->andWhere('c.startDate < :date OR c.startDate IS NULL')
;
if ($sort !== null) {
->andWhere('c.startDate < :date OR c.startDate IS NULL');
if (null !== $sort) {
$qb->orderBy($sort);
}
$qb->setParameters([
'person' => $person,
'date' => $date
'date' => $date,
]);
return $qb->getQuery()->getResult();
}
}

View File

@ -1,4 +1,13 @@
<?php declare(strict_types=1);
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Application\Migrations;
@ -6,10 +15,17 @@ use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
/**
* create schema for chill budget
* create schema for chill budget.
*/
final class Version20180522080432 extends AbstractMigration
{
public function down(Schema $schema)
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('CREATE SCHEMA chill_budget CASCADE');
}
public function up(Schema $schema)
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
@ -28,14 +44,5 @@ final class Version20180522080432 extends AbstractMigration
$this->addSql('COMMENT ON COLUMN chill_budget.charge.endDate IS \'(DC2Type:datetime_immutable)\'');
$this->addSql('ALTER TABLE chill_budget.resource ADD CONSTRAINT FK_5E0A5E97217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE chill_budget.charge ADD CONSTRAINT FK_5C99D2C3217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
}
public function down(Schema $schema)
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('CREATE SCHEMA chill_budget CASCADE');
}
}

View File

@ -1,4 +1,13 @@
<?php declare(strict_types=1);
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Application\Migrations;
@ -6,21 +15,21 @@ use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* autorise les valeurs nulles dans "HELP"
* autorise les valeurs nulles dans "HELP".
*/
final class Version20181219145631 extends AbstractMigration
{
public function up(Schema $schema) : void
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE chill_budget.charge ALTER help DROP NOT NULL');
}
public function down(Schema $schema) : void
public function down(Schema $schema): void
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE chill_budget.charge ALTER help SET NOT NULL');
}
public function up(Schema $schema): void
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE chill_budget.charge ALTER help DROP NOT NULL');
}
}

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