737 lines
33 KiB
PHP

<?php
/*
* Copyright (C) 2014-2016 Julien Fastré <julien.fastre@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\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 Chill\MainBundle\Security\Authorization\ChillExportVoter;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Symfony\Component\HttpFoundation\Request;
/**
* Class ChillPersonExtension
* Loads and manages your bundle configuration
*
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
* @package Chill\PersonBundle\DependencyInjection
*/
class ChillPersonExtension extends Extension implements PrependExtensionInterface
{
/**
* {@inheritDoc}
* @param array $configs
* @param ContainerBuilder $container
* @throws \Exception
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
// set configuration for validation
$container->setParameter('chill_person.validation.birtdate_not_before',
$config['validation']['birthdate_not_after']);
$this->handlePersonFieldsParameters($container, $config['person_fields']);
$this->handleAccompanyingPeriodsFieldsParameters($container, $config['accompanying_periods_fields']);
$container->setParameter('chill_person.allow_multiple_simultaneous_accompanying_periods',
$config['allow_multiple_simultaneous_accompanying_periods']);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config'));
$loader->load('services.yaml');
$loader->load('services/widgets.yaml');
$loader->load('services/exports.yaml');
$loader->load('services/fixtures.yaml');
$loader->load('services/controller.yaml');
$loader->load('services/search.yaml');
$loader->load('services/menu.yaml');
$loader->load('services/privacyEvent.yaml');
$loader->load('services/command.yaml');
$loader->load('services/actions.yaml');
$loader->load('services/form.yaml');
$loader->load('services/alt_names.yaml');
$loader->load('services/household.yaml');
// We can get rid of this file when the service 'chill.person.repository.person' is no more used.
// We should use the PersonRepository service instead of a custom service name.
$loader->load('services/repository.yaml');
$loader->load('services/serializer.yaml');
$loader->load('services/security.yaml');
// load service advanced search only if configure
if ($config['search']['search_by_phone'] != 'never') {
$loader->load('services/search_by_phone.yaml');
$container->setParameter('chill_person.search.search_by_phone',
$config['search']['search_by_phone']);
}
if ($container->getParameter('chill_person.accompanying_period') !== 'hidden') {
$loader->load('services/exports_accompanying_period.yaml');
}
}
/**
* @param ContainerBuilder $container
* @param $config
*/
private function handlePersonFieldsParameters(ContainerBuilder $container, $config)
{
if (array_key_exists('enabled', $config)) {
unset($config['enabled']);
}
$container->setParameter('chill_person.person_fields', $config);
foreach ($config as $key => $value) {
switch($key) {
case 'accompanying_period':
$container->setParameter('chill_person.accompanying_period', $value);
break;
default:
$container->setParameter('chill_person.person_fields.'.$key, $value);
break;
}
}
}
/**
* @param ContainerBuilder $container
* @param $config
*/
private function handleAccompanyingPeriodsFieldsParameters(ContainerBuilder $container, $config)
{
$container->setParameter('chill_person.accompanying_period_fields', $config);
foreach ($config as $key => $value) {
switch($key) {
case 'enabled':
break;
default:
$container->setParameter('chill_person.accompanying_period_fields.'.$key, $value);
break;
}
}
}
/**
* @param ContainerBuilder $container
* @throws MissingBundleException
*/
private function declarePersonAsCustomizable (ContainerBuilder $container)
{
$bundles = $container->getParameter('kernel.bundles');
if (!isset($bundles['ChillCustomFieldsBundle'])) {
throw new MissingBundleException('ChillCustomFieldsBundle');
}
$container->prependExtensionConfig('chill_custom_fields',
array('customizables_entities' =>
array(
array('class' => 'Chill\PersonBundle\Entity\Person', 'name' => 'PersonEntity')
)
)
);
}
/**
* @param ContainerBuilder $container
* @throws MissingBundleException
*/
public function prepend(ContainerBuilder $container)
{
$this->prependRoleHierarchy($container);
$this->prependHomepageWidget($container);
$this->prependDoctrineDQL($container);
$this->prependCruds($container);
$this->prependWorkflows($container);
//add person_fields parameter as global
$chillPersonConfig = $container->getExtensionConfig($this->getAlias());
$config = $this->processConfiguration(new Configuration(), $chillPersonConfig);
$twigConfig = array(
'globals' => array(
'chill_person' => array(
'fields' => $config['person_fields']
),
'chill_accompanying_periods' => [
'fields' => $config['accompanying_periods_fields']
]
),
'form_themes' => array('ChillPersonBundle:Export:ListPersonFormFields.html.twig')
);
$container->prependExtensionConfig('twig', $twigConfig);
$this-> declarePersonAsCustomizable($container);
//declare routes for person bundle
$container->prependExtensionConfig('chill_main', array(
'routing' => array(
'resources' => array(
'@ChillPersonBundle/config/routes.yaml'
)
)
));
}
protected function prependWorkflows(ContainerBuilder $container)
{
$container->prependExtensionConfig('framework', [
'workflows' => [
'accompanying_period_lifecycle' => [
'type' => 'state_machine',
'audit_trail' => [
'enabled' => true
],
'marking_store' => [
'type' => 'method',
'property' => 'step',
],
'supports' => [
'Chill\PersonBundle\Entity\AccompanyingPeriod'
],
'initial_marking' => 'DRAFT',
'places' => [
'DRAFT',
'CONFIRMED',
],
'transitions' => [
'confirm' => [
'from' => 'DRAFT',
'to' => 'CONFIRMED'
],
],
],
]
]);
}
/**
* Add a widget "add a person" on the homepage, automatically
*
* @param \Chill\PersonBundle\DependencyInjection\containerBuilder $container
*/
protected function prependHomepageWidget(containerBuilder $container)
{
$container->prependExtensionConfig('chill_main', array(
'widgets' => array(
'homepage' => array(
array(
'widget_alias' => 'add_person',
'order' => 2
)
)
)
));
}
/**
* Add role hierarchy.
*
* @param ContainerBuilder $container
*/
protected function prependRoleHierarchy(ContainerBuilder $container)
{
$container->prependExtensionConfig('security', array(
'role_hierarchy' => array(
'CHILL_PERSON_UPDATE' => array('CHILL_PERSON_SEE'),
'CHILL_PERSON_CREATE' => array('CHILL_PERSON_SEE'),
PersonVoter::LISTS => [ ChillExportVoter::EXPORT ],
PersonVoter::STATS => [ ChillExportVoter::EXPORT ]
)
));
}
/**
* Add DQL function linked with person
*
* @param ContainerBuilder $container
*/
protected function prependDoctrineDQL(ContainerBuilder $container)
{
//add DQL function to ORM (default entity_manager)
$container->prependExtensionConfig('doctrine', array(
'orm' => array(
'dql' => array(
'string_functions' => array(
'GET_PERSON_ADDRESS_ADDRESS_ID' => AddressPart\AddressPartAddressId::class,
'GET_PERSON_ADDRESS_STREET_ADDRESS_1' => AddressPart\AddressPartStreetAddress1::class,
'GET_PERSON_ADDRESS_STREET_ADDRESS_2' => AddressPart\AddressPartStreetAddress2::class,
'GET_PERSON_ADDRESS_VALID_FROM' => AddressPart\AddressPartValidFrom::class,
'GET_PERSON_ADDRESS_POSTCODE_LABEL' => AddressPart\AddressPartPostCodeLabel::class,
'GET_PERSON_ADDRESS_POSTCODE_CODE' => AddressPart\AddressPartPostCodeCode::class,
'GET_PERSON_ADDRESS_POSTCODE_ID' => AddressPart\AddressPartPostCodeId::class,
'GET_PERSON_ADDRESS_COUNTRY_NAME' => AddressPart\AddressPartCountryName::class,
'GET_PERSON_ADDRESS_COUNTRY_CODE' => AddressPart\AddressPartCountryCode::class,
'GET_PERSON_ADDRESS_COUNTRY_ID' => AddressPart\AddressPartCountryId::class,
),
'numeric_functions' => [
'GET_PERSON_ADDRESS_ISNOADDRESS' => AddressPart\AddressPartIsNoAddress::class,
]
)
)
));
}
/**
* @param ContainerBuilder $container
*/
protected function prependCruds(ContainerBuilder $container)
{
$container->prependExtensionConfig('chill_main', [
'cruds' => [
[
'class' => \Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive::class,
'name' => 'closing_motive',
'base_path' => '/admin/closing-motive',
'form_class' => \Chill\PersonBundle\Form\ClosingMotiveType::class,
'controller' => \Chill\PersonBundle\Controller\AdminClosingMotiveController::class,
'actions' => [
'index' => [
'template' => '@ChillPerson/ClosingMotive/index.html.twig',
'role' => 'ROLE_ADMIN'
],
'new' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/ClosingMotive/new.html.twig',
],
'edit' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/ClosingMotive/edit.html.twig',
]
]
],
[
'class' => \Chill\PersonBundle\Entity\MaritalStatus::class,
'name' => 'marital_status',
'base_path' => '/admin/marital-status',
'form_class' => \Chill\PersonBundle\Form\MaritalStatusType::class,
'controller' => \Chill\PersonBundle\Controller\AdminMaritalStatusController::class,
'actions' => [
'index' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/MaritalStatus/index.html.twig',
],
'new' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/MaritalStatus/new.html.twig',
],
'edit' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/MaritalStatus/edit.html.twig',
]
]
],
],
'apis' => [
[
'class' => \Chill\PersonBundle\Entity\AccompanyingPeriod::class,
'name' => 'accompanying_course',
'base_path' => '/api/1.0/person/accompanying-course',
'controller' => \Chill\PersonBundle\Controller\AccompanyingCourseApiController::class,
'actions' => [
'_entity' => [
'roles' => [
Request::METHOD_GET => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_PATCH => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_PUT => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
],
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_PUT => true,
Request::METHOD_PATCH => true,
]
],
'participation' => [
'methods' => [
Request::METHOD_POST => true,
Request::METHOD_DELETE => true,
Request::METHOD_GET => false,
Request::METHOD_HEAD => false,
],
'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
]
],
'resource' => [
'methods' => [
Request::METHOD_POST => true,
Request::METHOD_DELETE => true,
Request::METHOD_GET => false,
Request::METHOD_HEAD => false,
],
'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
]
],
'comment' => [
'methods' => [
Request::METHOD_POST => true,
Request::METHOD_DELETE => true,
Request::METHOD_GET => false,
Request::METHOD_HEAD => false,
],
'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
]
],
'requestor' => [
'methods' => [
Request::METHOD_POST => true,
Request::METHOD_DELETE => true,
Request::METHOD_GET => false,
Request::METHOD_HEAD => false,
],
'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
]
],
'scope' => [
'methods' => [
Request::METHOD_POST => true,
Request::METHOD_DELETE => true,
Request::METHOD_GET => false,
Request::METHOD_HEAD => false,
],
'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
]
],
'socialissue' => [
'methods' => [
Request::METHOD_POST => true,
Request::METHOD_DELETE => true,
Request::METHOD_GET => false,
Request::METHOD_HEAD => false,
],
'controller_action' => 'socialIssueApi',
'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
]
],
'work' => [
'methods' => [
Request::METHOD_POST => true,
Request::METHOD_DELETE => false,
Request::METHOD_GET => false,
Request::METHOD_HEAD => false,
],
'controller_action' => 'workApi',
'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE => 'ALWAYS_FAILS',
]
],
'confirm' => [
'methods' => [
Request::METHOD_POST => true,
Request::METHOD_GET => false,
Request::METHOD_HEAD => false,
],
'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
]
],
]
],
[
'class' => \Chill\PersonBundle\Entity\AccompanyingPeriod\Origin::class,
'name' => 'accompanying_period_origin',
'base_path' => '/api/1.0/person/accompanying-period/origin',
'controller' => \Chill\PersonBundle\Controller\OpeningApiController::class,
'base_role' => 'ROLE_USER',
'actions' => [
'_index' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true
],
],
'_entity' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true
]
],
]
],
[
'class' => \Chill\PersonBundle\Entity\SocialWork\SocialIssue::class,
'name' => 'social_work_social_issue',
'base_path' => '/api/1.0/person/social-work/social-issue',
'base_role' => 'ROLE_USER',
'actions' => [
'_index' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true
],
],
'_entity' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true
]
],
]
],
[
'class' => \Chill\PersonBundle\Entity\Person::class,
'name' => 'person',
'base_path' => '/api/1.0/person/person',
'base_role' => \Chill\PersonBundle\Security\Authorization\PersonVoter::SEE,
'controller' => \Chill\PersonBundle\Controller\PersonApiController::class,
'actions' => [
'_entity' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
Request::METHOD_POST=> true,
],
'roles' => [
Request::METHOD_GET => \Chill\PersonBundle\Security\Authorization\PersonVoter::SEE,
Request::METHOD_HEAD => \Chill\PersonBundle\Security\Authorization\PersonVoter::SEE,
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\PersonVoter::CREATE,
],
],
'address' => [
'methods' => [
Request::METHOD_POST => true,
Request::METHOD_DELETE => true,
Request::METHOD_GET => false,
Request::METHOD_HEAD => false,
],
'controller_action' => 'personAddressApi'
],
]
],
[
'class' => \Chill\PersonBundle\Entity\Household\Household::class,
'controller' => \Chill\PersonBundle\Controller\HouseholdApiController::class,
'name' => 'household',
'base_path' => '/api/1.0/person/household',
'base_role' => 'ROLE_USER',
'actions' => [
'_index' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
],
],
'_entity' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
]
],
'address' => [
'methods' => [
Request::METHOD_POST => true,
Request::METHOD_DELETE => true,
Request::METHOD_GET => false,
Request::METHOD_HEAD => false,
],
'controller_action' => 'householdAddressApi'
],
]
],
[
'class' => \Chill\PersonBundle\Entity\SocialWork\SocialAction::class,
'name' => 'social_action',
'base_path' => '/api/1.0/person/social/social-action',
'controller' => \Chill\PersonBundle\Controller\SocialWorkSocialActionApiController::class,
// TODO: acl
'base_role' => 'ROLE_USER',
'actions' => [
'_entity' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
],
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
'_index' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
],
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
'listBySocialIssue' => [
'single-collection' => 'collection',
'path' => '/by-social-issue/{id}.{_format}',
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
],
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
]
]
],
[
'class' => \Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork::class,
'name' => 'accompanying_period_work',
'base_path' => '/api/1.0/person/accompanying-course/work',
'controller' => \Chill\PersonBundle\Controller\AccompanyingCourseWorkApiController::class,
// TODO: acl
'base_role' => 'ROLE_USER',
'actions' => [
'_entity' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
Request::METHOD_PATCH => true,
Request::METHOD_PUT => true,
],
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
Request::METHOD_PATCH => 'ROLE_USER',
Request::METHOD_PUT => 'ROLE_USER',
]
],
]
],
[
'class' => \Chill\PersonBundle\Entity\SocialWork\Result::class,
'controller' => \Chill\PersonBundle\Controller\SocialWorkResultApiController::class,
'name' => 'social_work_result',
'base_path' => '/api/1.0/person/social-work/result',
'base_role' => 'ROLE_USER',
'actions' => [
'_entity' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
],
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
'_index' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
],
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
'by-social-action' => [
'single-collection' => 'collection',
'path' => '/by-social-action/{id}.{_format}',
'controller_action' => 'listBySocialAction',
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
],
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
'by-goal' => [
'single-collection' => 'collection',
'path' => '/by-goal/{id}.{_format}',
'controller_action' => 'listByGoal',
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
],
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
]
],
[
'class' => \Chill\PersonBundle\Entity\SocialWork\Goal::class,
'controller' => \Chill\PersonBundle\Controller\SocialWorkGoalApiController::class,
'name' => 'social_work_goal',
'base_path' => '/api/1.0/person/social-work/goal',
'base_role' => 'ROLE_USER',
'actions' => [
'_entity' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
],
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
'_index' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
],
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
'by-social-action' => [
'single-collection' => 'collection',
'path' => '/by-social-action/{id}.{_format}',
'controller_action' => 'listBySocialAction',
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
],
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
]
],
]
]);
}
}